Merge branch 'master' of github.com:dgiot/dgiot

This commit is contained in:
U-JOHNLIU\jonhl 2022-03-22 18:29:36 +08:00
commit ad362b1424
8 changed files with 355 additions and 141 deletions

View File

@ -39,75 +39,6 @@
}).
%%
-params(#{
<<"header">> => #{
order => 1,
type => object,
allowCreate => true,
required => true,
default => [
#{<<"value">> => "lable", <<"name">> => <<"key">>}
],
title => #{
zh => <<"数据标识"/utf8>>
},
description => #{
zh => <<"数据标识"/utf8>>
},
<<"table">> => #{
<<"key">> => #{
key => <<"key">>,
order => 1,
type => string,
required => true,
default => <<"数据标识"/utf8>>,
title => #{
zh => <<"数据标识"/utf8>>
},
description => #{
zh => <<"数据标识"/utf8>>
}
},
<<"value">> => #{
key => <<"value">>,
order => 2,
type => string,
required => true,
default => <<"0000"/utf8>>,
title => #{
zh => <<"数据内容"/utf8>>
},
description => #{
zh => <<"数据内容"/utf8>>
}
},
<<"type">> => #{
key => <<"type">>,
order => 3,
type => string,
required => true,
default => #{<<"value">> => <<"bit">>, <<"label">> => <<""/utf8>>},
enum => [
#{<<"value">> => <<"bit">>, <<"label">> => <<""/utf8>>},
#{<<"value">> => <<"short16_AB">>, <<"label">> => <<"16位 有符号(AB)"/utf8>>},
#{<<"value">> => <<"short16_BA">>, <<"label">> => <<"16位 有符号(BA)"/utf8>>},
#{<<"value">> => <<"ushort16_AB">>, <<"label">> => <<"16位 无符号(AB)"/utf8>>},
#{<<"value">> => <<"ushort16_BA">>, <<"label">> => <<"16位 无符号(BA)"/utf8>>},
#{<<"value">> => <<"long32_ABCD">>, <<"label">> => <<"32位 有符号(ABCD)"/utf8>>},
#{<<"value">> => <<"long32_CDAB">>, <<"label">> => <<"32位 有符号(CDAB)"/utf8>>},
#{<<"value">> => <<"ulong32_ABCD">>, <<"label">> => <<"32位 无符号(ABCD)"/utf8>>},
#{<<"value">> => <<"ulong32_CDAB">>, <<"label">> => <<"32位 无符号(CDAB)"/utf8>>},
#{<<"value">> => <<"float32_ABCD">>, <<"label">> => <<"32位 浮点数(ABCD)"/utf8>>},
#{<<"value">> => <<"float32_CDAB">>, <<"label">> => <<"32位 浮点数(CDAB)"/utf8>>}
],
title => #{
zh => <<"数据格式"/utf8>>
},
description => #{
zh => <<"数据格式"/utf8>>
}
}
}
},
<<"port">> => #{
order => 1,
type => integer,

View File

@ -52,8 +52,128 @@
zh => <<"服务器地址"/utf8>>
}
},
<<"page_index">> => #{
<<"header">> => #{
order => 2,
type => object,
allowCreate => true,
required => true,
default => [
#{<<"value">> => "lable", <<"name">> => <<"key">>}
],
title => #{
zh => <<"请求头"/utf8>>
},
description => #{
zh => <<"请求头"/utf8>>
},
<<"table">> => #{
<<"key">> => #{
key => <<"type">>,
order => 1,
type => string,
required => true,
default => #{<<"value">> => <<"Content-Type">>, <<"label">> => <<"Content-Type"/utf8>>},
enum => [
#{<<"value">> => <<"accept">>, <<"label">> => <<"accept"/utf8>>},
#{<<"value">> => <<"Content-Type">>, <<"label">> => <<"Content-Type"/utf8>>}
],
title => #{
zh => <<"请求头"/utf8>>
},
description => #{
zh => <<"请求头"/utf8>>
}
},
<<"value">> => #{
key => <<"value">>,
order => 2,
type => string,
required => true,
default => #{<<"value">> => <<"accept">>, <<"label">> => <<"application/json"/utf8>>},
enum => [
#{<<"value">> => <<"application/json">>, <<"label">> => <<"application/json"/utf8>>},
#{<<"value">> => <<"text/plain">>, <<"label">> => <<"text/plain"/utf8>>}
],
title => #{
zh => <<"请求头参数"/utf8>>
},
description => #{
zh => <<"请求头参数"/utf8>>
}
}
}
},
<<"method">> => #{
order => 3,
type => string,
required => true,
enum => [
#{<<"value">> => <<"GET">>, <<"label">> => <<"GET"/utf8>>},
#{<<"value">> => <<"POST">>, <<"label">> => <<"POST"/utf8>>},
#{<<"value">> => <<"PUT">>, <<"label">> => <<"PUT"/utf8>>},
#{<<"value">> => <<"PATCH">>, <<"label">> => <<"PATCH"/utf8>>},
#{<<"value">> => <<"DELETE">>, <<"label">> => <<"DELETE"/utf8>>},
#{<<"value">> => <<"HARD">>, <<"label">> => <<"HARD"/utf8>>},
#{<<"value">> => <<"CONNECT">>, <<"label">> => <<"CONNECT"/utf8>>},
#{<<"value">> => <<"OPTIONS">>, <<"label">> => <<"OPTIONS"/utf8>>},
#{<<"value">> => <<"TRACE">>, <<"label">> => <<"TRACE"/utf8>>},
#{<<"value">> => <<"CUSTON">>, <<"label">> => <<"CUSTON"/utf8>>}
],
default => [
#{<<"value">> => "GET", <<"name">> => <<"GET">>}
],
title => #{
zh => <<"请求方法"/utf8>>
},
description => #{
zh => <<"请求方法"/utf8>>
}
},
<<"body">> => #{
order => 4,
type => object,
allowCreate => true,
required => true,
default => [
#{<<"value">> => "lable", <<"name">> => <<"key">>}
],
title => #{
zh => <<"请求参数"/utf8>>
},
description => #{
zh => <<"请求参数"/utf8>>
},
<<"table">> => #{
<<"key">> => #{
key => <<"key">>,
order => 1,
type => string,
required => true,
default => <<"">>,
title => #{
zh => <<"参数名称"/utf8>>
},
description => #{
zh => <<"参数名称"/utf8>>
}
},
<<"value">> => #{
key => <<"value">>,
order => 2,
type => string,
required => true,
default => <<"">>,
title => #{
zh => <<"参数值"/utf8>>
},
description => #{
zh => <<"参数值"/utf8>>
}
}
}
},
<<"page_index">> => #{
order => 7,
type => integer,
required => false,
default => 1,
@ -65,7 +185,7 @@
}
},
<<"page_size">> => #{
order => 4,
order => 8,
type => integer,
required => false,
default => 1,
@ -77,7 +197,7 @@
}
},
<<"total">> => #{
order => 5,
order => 9,
type => integer,
required => false,
default => 1,
@ -156,4 +276,4 @@ start_client(ChannelId, ProductId, Url, #{<<"page_index">> := PageIndex,
Query = #{
<<"where">> => #{<<"product">> => ProductId}
},
dgiot_parse_loader:start(<<"Device">>, Query, PageIndex, PageSize, Total, Success).
dgiot_parse_loader:start(<<"Device">>, Query, PageIndex, PageSize, Total, Success).

View File

@ -39,7 +39,6 @@
-define(CHILD(I, Type, Args), {I, {I, start_link, Args}, permanent, 5000, Type, [I]}).
-record(state, {tid, id, page = 1, token, refreshtoken, sleep = 12}).
%%%===================================================================
%%% API
%%%===================================================================
@ -72,7 +71,10 @@ init([#{
DeviceId = dgiot_parse:get_deviceid(ProductId, DevAddr),
dgiot_data:insert({ChannelId, DeviceId, httpc}, self()),
erlang:send_after(10000, self(), start),
{ok, #state{tid = ChannelId, id = DeviceId}}.
{ok, #state{tid = ChannelId, id = DeviceId}};
init(Args) ->
io:format("dgiot_httpc_worker:init:~p~n", [Args]).
handle_call(_Request, _From, State) ->
{reply, ok, State}.

View File

@ -0,0 +1,124 @@
[
"WWW-Authenticate",
"Authorization",
"Proxy-Authenticate",
"Proxy-Authorization",
"Age",
"Cache-Control",
"Clear-Site-Data",
"Expires",
"Pragma",
"Warning",
"Accept-CH",
"Accept-CH-Lifetime",
"Early-Data",
"Content-DPR",
"DPR",
"Device-Memory",
"Save-Data",
"Viewport-Width",
"Width",
"Last-Modified",
"ETag",
"If-Match",
"If-None-Match",
"If-Modified-Since",
"If-Unmodified-Since",
"Vary",
"Connection",
"Keep-Alive",
"Accept",
"Accept-Charset",
"Accept-Encoding",
"Accept-Language",
"Expect",
"Max-Forwards",
"Cookie",
"Set-Cookie",
"Cookie2",
"Set-Cookie2",
"Access-Control-Allow-Origin",
"Access-Control-Allow-Credentials",
"Access-Control-Allow-Headers",
"Access-Control-Allow-Methods",
"Access-Control-Expose-Headers",
"Access-Control-Max-Age",
"Access-Control-Request-Headers",
"Access-Control-Request-Method",
"Origin",
"Service-Worker-Allowed",
"Timing-Allow-Origin",
"X-Permitted-Cross-Domain-Policies",
"DNT",
"Tk",
"Content-Disposition",
"Content-Length",
"Content-Type",
"Content-Encoding",
"Content-Language",
"Content-Location",
"Forwarded",
"X-Forwarded-For",
"X-Forwarded-Host",
"X-Forwarded-Proto",
"Via",
"Location",
"From",
"Host",
"Referer",
"Referrer-Policy",
"User-Agent",
"Allow",
"Server",
"Accept-Ranges",
"Range",
"If-Range",
"Content-Range",
"Cross-Origin-Opener-Policy",
"Cross-Origin-Resource-Policy",
"Content-Security-Policy",
"Content-Security-Policy-Report-Only",
"Expect-CT",
"Feature-Policy",
"Public-Key-Pins",
"Public-Key-Pins-Report-Only",
"Strict-Transport-Security",
"Upgrade-Insecure-Requests",
"X-Content-Type-Options",
"X-Download-Options",
"X-Frame-Options",
"X-Powered-By",
"X-XSS-Protection",
"Last-Event-ID",
"NEL",
"Ping-From",
"Ping-To",
"Report-To",
"Transfer-Encoding",
"TE",
"Trailer",
"Sec-WebSocket-Key",
"Sec-WebSocket-Extensions",
"Sec-WebSocket-Accept",
"Sec-WebSocket-Protocol",
"Sec-WebSocket-Version",
"Accept-Push-Policy",
"Accept-Signature",
"Alt-Svc",
"Date",
"Large-Allocation",
"Link",
"Push-Policy",
"Retry-After",
"Signature",
"Signed-Headers",
"Server-Timing",
"SourceMap",
"Upgrade",
"X-DNS-Prefetch-Control",
"X-Firefox-Spdy",
"X-Pingback",
"X-Requested-With",
"X-Robots-Tag",
"X-UA-Compatible",
]

View File

@ -45,7 +45,7 @@
allowCreate => true,
required => true,
default => [
#{<<"value">> => "lable", <<"name">> => <<"key">>}
#{<<"value">> => <<"lable">>, <<"name">> => <<"key">>}
],
title => #{
zh => <<"数据标识"/utf8>>

View File

@ -6,12 +6,12 @@ parse.delete_field = ACL,objectId,updatedAt,createdAt
##--------------------------------------------------------------------
## parse config
##--------------------------------------------------------------------
parse.parse_server = http://prod.iotn2n.com:1337
parse.parse_server = http://cad.iotn2n.com:1337
parse.parse_path = /parse/
parse.parse_appid = d3300b6f53d7ee7da766142f2f7050eb
parse.parse_master_key = 3d9707db9414c4e398c5036ddb1b2b62
parse.parse_js_key = fc8f19e9dcc4b8b7848aed1f8dcda317
parse.parse_rest_key = 7957b8a5923c8be145b317521b922b18
parse.parse_appid = 6613a6869ae3113a7e49f1b2cda365be
parse.parse_master_key = 86fef7a7df25837ba7731ae8e22b6b62
parse.parse_js_key = beb3ef6c5a638779aac441a0bb8b2b5d
parse.parse_rest_key = 4c8e71e8fcc18f010482987ccfefe488
##--------------------------------------------------------------------
## parse cache
@ -23,4 +23,4 @@ parse.cache.max_size = 100000
## max_memory 最大内存数单位byte
parse.cache.max_memory = 1024000
## max_time 最大时间间隔,单位秒
parse.cache.max_time = 60
parse.cache.max_time = 60

View File

@ -372,9 +372,9 @@ save_pnque(DtuProductId, DtuAddr, ProductId, DevAddr) ->
case dgiot_data:get({task_args, DtuProductId}) of
not_find ->
pass;
Args ->
#{<<"channel">> := Channel} = Args ->
%% io:format("Args ~p.~n", [Args]),
supervisor:start_child(dgiot_task, [Args#{<<"dtuid">> => DtuId}])
supervisor:start_child(?TASK_SUP(Channel), [Args#{<<"dtuid">> => DtuId}])
end.

View File

@ -368,72 +368,109 @@ get_app(ProductId, Results, DeviceId, Args) ->
Props = get_Props(ProductId, Keys),
lists:foldl(fun(X, Acc) ->
case X of
#{<<"name">> := Name, <<"identifier">> := Identifier, <<"isshow">> := true, <<"dataType">> := #{<<"type">> := Typea} = DataType} ->
#{<<"name">> := Name, <<"identifier">> := Identifier, <<"dataForm">> := #{<<"protocol">> := Protocol}, <<"dataSource">> := DataSource, <<"dataType">> := #{<<"type">> := Typea} = DataType} ->
Time = maps:get(<<"createdat">>, Result, dgiot_datetime:now_secs()),
NewTime = dgiot_tdengine_handler:get_time(dgiot_utils:to_binary(Time), <<"111">>),
Devicetype = maps:get(<<"devicetype">>, X, <<"others">>),
Ico = maps:get(<<"ico">>, X, <<"">>),
Specs = maps:get(<<"specs">>, DataType, #{}),
Unit = maps:get(<<"unit">>, Specs, <<"">>),
NewV =
case maps:find(Identifier, Result) of
error ->
<<"--">>;
{ok, V} ->
case Typea of
Type1 when Type1 == <<"enum">>; Type1 == <<"bool">> ->
Value = maps:get(dgiot_utils:to_binary(V), Specs, V),
Value;
Type2 when Type2 == <<"struct">> ->
V;
Type3 when Type3 == <<"geopoint">> ->
BinV = dgiot_utils:to_binary(V),
case binary:split(BinV, <<$_>>, [global, trim]) of
[Longitude, Latitude] ->
case dgiot_gps:get_baidu_addr(Longitude, Latitude) of
#{<<"baiduaddr">> := #{<<"formatted_address">> := FormattedAddress}} ->
case dgiot_parse:get_object(<<"Device">>, DeviceId) of
{ok, #{<<"location">> := #{<<"__type">> := <<"GeoPoint">>, <<"longitude">> := Longitude, <<"latitude">> := Latitude}}} ->
pass;
{ok, #{<<"detail">> := Detail}} ->
dgiot_parse:update_object(<<"Device">>, DeviceId, #{
<<"location">> => #{<<"__type">> => <<"GeoPoint">>, <<"longitude">> => Longitude, <<"latitude">> => Latitude},
<<"detail">> => Detail#{<<"address">> => FormattedAddress}});
_ ->
pass
end,
FormattedAddress;
_ ->
<<"[", BinV/binary, "]经纬度解析错误"/utf8>>
end;
_ ->
<<"无GPS信息"/utf8>>
end;
Type4 when Type4 == <<"float">>; Type4 == <<"double">> ->
Precision = maps:get(<<"precision">>, Specs, 3),
dgiot_utils:to_float(V, Precision);
Type5 when Type5 == <<"image">> ->
AppName = dgiot_device:get_appname(DeviceId),
Url = dgiot_device:get_url(AppName),
Imagevalue = maps:get(<<"imagevalue">>, DataType, <<"">>),
BinV = dgiot_utils:to_binary(V),
<<Url/binary, "/dgiot_file/", DeviceId/binary, "/", BinV/binary, ".", Imagevalue/binary>>;
Type6 when Type6 == <<"date">> ->
case V of
<<"1970-01-01 08:00:00.000">> ->
<<"--">>;
_ ->
V
end;
_ ->
V
end
end,
Acc ++ [#{<<"identifier">> => Identifier, <<"name">> => Name, <<"type">> => Typea, <<"number">> => NewV, <<"time">> => NewTime, <<"unit">> => Unit, <<"imgurl">> => Ico, <<"devicetype">> => Devicetype}];
_ -> Acc
case do_hook({Protocol, Identifier}, DataSource#{<<"deviceid">> => DeviceId}) of
ignore ->
NewV =
case maps:find(Identifier, Result) of
error ->
<<"--">>;
{ok, V} ->
check_field(Typea, V, #{<<"datatype">> => DataType, <<"specs">> => Specs, <<"deviceid">> => DeviceId})
end,
Acc ++ [#{<<"identifier">> => Identifier, <<"name">> => Name,
<<"type">> => Typea, <<"number">> => NewV,
<<"time">> => NewTime, <<"unit">> => Unit,
<<"imgurl">> => Ico, <<"devicetype">> => Devicetype}];
{error, _Reason} ->
Acc;
V ->
NewV = check_field(Typea, V, #{<<"datatype">> => DataType, <<"specs">> => Specs, <<"deviceid">> => DeviceId}),
Acc ++ [#{<<"identifier">> => Identifier, <<"name">> => Name,
<<"type">> => Typea, <<"number">> => NewV,
<<"time">> => NewTime, <<"unit">> => Unit,
<<"imgurl">> => Ico, <<"devicetype">> => Devicetype}]
end;
_ ->
Acc
end
end, [], Props).
do_hook(Key, Args) ->
io:format("~s ~p Key = ~p.~n", [?FILE, ?LINE, Key]),
io:format("~s ~p Args = ~p.~n", [?FILE, ?LINE, Args]),
case catch dgiot_hook:run_hook(Key, Args) of
{'EXIT', Reason} ->
{error, Reason};
{error, not_find} ->
ignore;
{ok, []} ->
ignore;
{ok, [{error, Reason} | _]} ->
{error, Reason};
{ok, [Rtn | _]} ->
Rtn
end.
check_field(Typea, V, #{<<"specs">> := Specs}) when Typea == <<"enum">>; Typea == <<"bool">> ->
maps:get(dgiot_utils:to_binary(V), Specs, V);
check_field(<<"struct">>, V, _) ->
V;
check_field(<<"geopoint">>, V, #{<<"deviceid">> := DeviceId}) ->
BinV = dgiot_utils:to_binary(V),
case binary:split(BinV, <<$_>>, [global, trim]) of
[Longitude, Latitude] ->
case dgiot_gps:get_baidu_addr(Longitude, Latitude) of
#{<<"baiduaddr">> := #{<<"formatted_address">> := FormattedAddress}} ->
case dgiot_parse:get_object(<<"Device">>, DeviceId) of
{ok, #{<<"location">> := #{<<"__type">> := <<"GeoPoint">>, <<"longitude">> := Longitude, <<"latitude">> := Latitude}}} ->
pass;
{ok, #{<<"detail">> := Detail}} ->
dgiot_parse:update_object(<<"Device">>, DeviceId, #{
<<"location">> => #{<<"__type">> => <<"GeoPoint">>, <<"longitude">> => Longitude, <<"latitude">> => Latitude},
<<"detail">> => Detail#{<<"address">> => FormattedAddress}});
_ ->
pass
end,
FormattedAddress;
_ ->
<<"[", BinV/binary, "]经纬度解析错误"/utf8>>
end;
_ ->
<<"无GPS信息"/utf8>>
end;
check_field(Typea, V, #{<<"specs">> := Specs}) when Typea == <<"float">>; Typea == <<"double">> ->
Precision = maps:get(<<"precision">>, Specs, 3),
dgiot_utils:to_float(V, Precision);
check_field(<<"image">>, V, #{<<"datatype">> := DataType, <<"deviceid">> := DeviceId}) ->
AppName = dgiot_device:get_appname(DeviceId),
Url = dgiot_device:get_url(AppName),
Imagevalue = maps:get(<<"imagevalue">>, DataType, <<"">>),
BinV = dgiot_utils:to_binary(V),
<<Url/binary, "/dgiot_file/", DeviceId/binary, "/", BinV/binary, ".", Imagevalue/binary>>;
check_field(<<"date">>, V, _) ->
case V of
<<"1970-01-01 08:00:00.000">> ->
<<"--">>;
_ ->
V
end;
check_field(_Typea, V, _) ->
V.
%%get_app(ProductId, Results, DeviceId) ->
%% Maps = get_prop(ProductId),
%% Props = get_props(ProductId),