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

This commit is contained in:
jhonliu 2022-06-13 18:11:48 +08:00
commit 33fc7a9ff2
6 changed files with 244 additions and 7 deletions

View File

@ -318,12 +318,14 @@ timestamp_to_datetime(Timestamp) ->
calendar:datetime_to_gregorian_seconds({{1970, 1, 1}, {0, 0, 0}}))).
last_month(Count) ->
EndTime = dgiot_datetime:nowstamp(),
{{Year, Month, _Day}, {_Hour, _Minute, _Second}} = calendar:local_time(),
{{Year, Month, Day}, {_Hour, _Minute, _Second}} = calendar:local_time(),
EndTime = dgiot_datetime:localtime_to_unixtime({{Year, Month, Day}, {23, 59, 59}}),
StartTime = dgiot_datetime:localtime_to_unixtime({{Year, Month, 1}, {0, 0, 0}}),
last_month(StartTime, EndTime, Count - 1).
last_month(StartTime, EndTime, 0) ->
{StartTime, EndTime};
last_month(StartTime, EndTime, Count) ->
{{Year, Month, _Day}, {_Hour, _Minute, _Second}} = dgiot_datetime:unixtime_to_localtime(StartTime),
{NewYear, NewMonth} =

View File

@ -196,6 +196,27 @@
"summary": "获取当前设备时序数据图表",
"description": "获取当前设备数据图表,支持折线图,柱状图,饼图等",
"parameters": [
{
"in": "query",
"name": "style",
"description": "图标类型",
"default": "line",
"required": true,
"type": "string",
"enum": [
"amis_table",
"line",
"echart_category"
]
},
{
"in": "query",
"name": "month_count",
"description": "月份数量",
"default": "1",
"required": false,
"type": "number"
},
{
"in": "path",
"name": "deviceid",
@ -270,7 +291,7 @@
"last"
],
"default": "last",
"required": true,
"required": false,
"type": "string"
}
],

View File

@ -129,13 +129,21 @@ do_request(get_device_deviceid, #{<<"deviceid">> := DeviceId} = Args, #{<<"sessi
end;
%% TDengine : :
do_request(get_echart_deviceid, #{<<"deviceid">> := DeviceId} = Args, #{<<"sessionToken">> := SessionToken} = _Context, _Req) ->
do_request(get_echart_deviceid, #{<<"deviceid">> := DeviceId,<<"style">> := Style} = Args, #{<<"sessionToken">> := SessionToken} = _Context, _Req) ->
case dgiot_product_tdengine:get_channel(SessionToken) of
{error, Error} -> {error, Error};
{ok, Channel} ->
case dgiot_parse:get_object(<<"Device">>, DeviceId) of
{ok, #{<<"objectId">> := DeviceId, <<"product">> := #{<<"objectId">> := ProductId}}} ->
dgiot_device_echart:get_echart_data(Channel, ProductId, DeviceId, Args);
case Style of
<<"amis_table">> ->
dgiot_device_echart:get_data_by_month(Channel, ProductId, DeviceId, Args);
<<"echart_category">> ->
dgiot_device_echart:get_data_by_echart_category(Channel, ProductId, DeviceId, Args);
_ ->
dgiot_device_echart:get_echart_data(Channel, ProductId, DeviceId, Args)
end;
_ ->
{error, <<"not find device">>}
end

View File

@ -21,6 +21,7 @@
-include_lib("dgiot_tdengine/include/dgiot_tdengine.hrl").
-export([get_echart_data/4]).
-export([get_data_by_month/4,get_data_by_echart_category/4, get_keys/2,get_table/2]).
get_echart_data(Channel, ProductId, DeviceId, Args) ->
Query = maps:without([<<"productid">>, <<"deviceid">>], Args),
@ -91,3 +92,195 @@ get_echart(ProductId, Results, Names, Interval) ->
?LOG(debug, "Child ~p", [Child]),
#{<<"columns">> => Columns, <<"rows">> => Rows, <<"child">> => Child}.
%%keys是否累计并根据结果设置Function
%% keys和目标keys得到目标keys是否累计
%%keys分到sum和last
%%sum和last分别配置参数并调用history函数
%%history
%%get_data_by_month(Channel, ProductId, DeviceId,Args)
get_data_by_month(Channel, ProductId, DeviceId, Args) ->
%% io:format("~s ~p Channel = ~p , ProductId = ~p, DeviceId = ~p ~n",[?FILE,?LINE,Channel, ProductId, DeviceId]),
case dgiot_data:get({tdengine_os, Channel}) of
<<"windows">> ->
pass;
_ ->
%% io:format("~s ~p here ~n",[?FILE,?LINE]),
%%
{ok,Count} = maps:find(<<"month_count">>,Args),
{StartTime, EndTime} = dgiot_datetime:last_month(Count),
%% key并分割转为list
{ok, K} = maps:find(<<"keys">>,Args),
Keys = re:split(K,","),
%% key提取其accu属性并生成sql命令
Res = case dgiot_product:lookup_prod(ProductId) of
{ok, Product} ->
%% io:format("~s ~p Product =~p , Keys = ~p ~n",[?FILE,?LINE,Product,Keys]),
get_keys(Product, Keys);
_ ->
error
end,
%% io:format("~s ~p Res = ~p~n",[?FILE,?LINE,Res]),
{ok,Sql} = maps:find(<<"sql">>,Res),
{ok,Names} = maps:find(<<"names">>,Res),
%%
TableName = ?Table(DeviceId),
Interval = <<"1d">>,
%%
case dgiot_device_tdengine:get_history_data2(Sql, Channel, TableName, Interval, ProductId, StartTime, EndTime) of
%%
{ok, #{<<"results">> := Results}} ->
%% io:format("~s ~p Results = ~p ~n",[?FILE,?LINE,Results]),
Tabledata = get_table(Results,Names),
%% io:format("~s ~p Tabledata = ~p ~n",[?FILE,?LINE,Tabledata]),
{ok,Tabledata};
_ ->
{ok, #{<<"code">> => 400, <<"msg">> => <<"no data">>}}
end
end.
get_keys(#{<<"thing">> := #{<<"properties">> := Properties}}, [<<"*">>]) ->
lists:foldl(fun(X, Acc) ->
%% io:format("~s ~p Acc = ~p ~n",[?FILE,?LINE,Acc]),
case X of
#{<<"identifier">> := Identifier, <<"isaccumulate">> := true,<<"name">> := Name,<<"identifier">> := Key} ->
case Acc of
#{<<"sql">> := Sql,<<"names">> :=Names } ->
%% io:format("~s ~p Key = ~p ~n",[?FILE,?LINE,Key]),
#{<<"sql">> => <<Sql/binary, ", sum(", Identifier/binary, ")">>,<<"names">> => Names#{<<Key/binary>> => <<Name/binary>>}};
_ ->
%% io:format("~s ~p Key = ~p ~n",[?FILE,?LINE,Key]),
#{<<"sql">> => <<" sum(", Identifier/binary, ")">>,<<"names">> => #{<<Key/binary>> => Name/binary}}
end;
#{<<"identifier">> := Identifier, <<"isaccumulate">> := false,<<"name">> := Name,<<"identifier">> := Key} ->
case Acc of
#{<<"sql">> := Sql,<<"names">> :=Names } ->
%% io:format("~s ~p Key = ~p ~n",[?FILE,?LINE,Key]),
#{<<"sql">> => <<Sql/binary, ", last(", Identifier/binary, ")">>,<<"names">> => Names#{<<Key/binary>> => <<Name/binary>>}};
_ ->
%% io:format("~s ~p Key = ~p ~n",[?FILE,?LINE,Key]),
%% io:format("~s ~p Name = ~p ~n",[?FILE,?LINE,Name]),
#{<<"sql">> => <<" last(", Identifier/binary, ")">>,<<"names">> => #{<<Key/binary>> => <<Name/binary>>}}
end
end
end, #{}, Properties);
get_keys(#{<<"thing">> := #{<<"properties">> := Properties}}, Keys) ->
lists:foldl(fun(X, Acc) ->
case X of
#{<<"identifier">> := Identifier, <<"isaccumulate">> := true, <<"name">> := Name, <<"identifier">> := Key} ->
case lists:member(Identifier, Keys) of
true ->
case Acc of
#{<<"sql">> := Sql,<<"names">> :=Names } ->
{ok, Sql} = maps:find(<<"sql">>, Acc),
{ok, Names} = maps:find(<<"names">>, Acc),
#{<<"sql">> => <<Sql/binary, ", sum(", Identifier/binary, ")">>, <<"names">> => Names#{<<Key/binary>> => <<Name/binary>>}};
_ ->
#{<<"sql">> => <<" sum(", Identifier/binary, ")">>, <<"names">> => #{<<Key/binary>> => <<Name/binary>>}}
end;
false ->
Acc
end;
#{<<"identifier">> := Identifier, <<"isaccumulate">> := false, <<"name">> := Name, <<"identifier">> := Key} ->
case lists:member(Identifier, Keys) of
true ->
case Acc of
#{<<"sql">> := Sql,<<"names">> :=Names } ->
{ok, Sql} = maps:find(<<"sql">>, Acc),
{ok, Names} = maps:find(<<"names">>, Acc),
#{<<"sql">> => <<Sql/binary, " last(", Identifier/binary, ")">>, <<"names">> => Names#{<<Key/binary>> => <<Name/binary>>}};
_ ->
#{<<"sql">> => <<" last(", Identifier/binary, ")">>, <<"names">> => #{<<Key/binary>> => <<Name/binary>>}}
end;
false -> Acc
end
end
end, #{}, Properties).
get_table(Results,Names) ->
Count = string:len(Results),
TableData = lists:foldl(fun(X, Acc) ->
Res = maps:fold(fun(K, V, Init) ->
case K of
<<"createdat">> ->
Init#{<<"时间"/utf8>> => V};
_ ->
case binary:match(K, <<"last">>) of
{0, 4} ->
Last_Key = binary:part(K, 5, byte_size(K) - 6),
case maps:find(<<Last_Key/binary>>, Names) of
{ok, Name} ->
Init#{<<Name/binary>> => V};
error ->
Init#{<<K/binary>> => V}
end;
_ ->
case binary:match(K, <<"sum">>) of
{0, 3} ->
Sum_Key = binary:part(K, 4, byte_size(K) - 5),
case maps:find(<<Sum_Key/binary>>, Names) of
{ok, Name1} ->
Init#{<<Name1/binary>> => V};
error ->
Init#{<<K/binary>> => V}
end;
_ ->
Init#{<<K/binary>> => V}
end
end
end
end, #{}, X),
Acc ++ [Res]
end, [], Results),
#{<<"status">> => 0, <<"msg">> => <<"ok">>, <<"data">> => #{<<"counts">> => Count ,<<"rows">> => TableData}}.
get_data_by_echart_category(Channel, ProductId, DeviceId, Args) ->
%% io:format("~s ~p Channel = ~p , ProductId = ~p, DeviceId = ~p ~n",[?FILE,?LINE,Channel, ProductId, DeviceId]),
case dgiot_data:get({tdengine_os, Channel}) of
<<"windows">> ->
pass;
_ ->
%% io:format("~s ~p here ~n",[?FILE,?LINE]),
%%
{ok,Count} = maps:find(<<"month_count">>,Args),
{StartTime, EndTime} = dgiot_datetime:last_month(Count),
%% key并分割转为list
{ok, K} = maps:find(<<"keys">>,Args),
Keys = re:split(K,","),
%% key提取其accu属性并生成sql命令
Res = case dgiot_product:lookup_prod(ProductId) of
{ok, Product} ->
%% io:format("~s ~p Product =~p , Keys = ~p ~n",[?FILE,?LINE,Product,Keys]),
get_keys(Product, Keys);
_ ->
error
end,
%% io:format("~s ~p Res = ~p~n",[?FILE,?LINE,Res]),
{ok,Sql} = maps:find(<<"sql">>,Res),
{ok,Names} = maps:find(<<"names">>,Res),
%%
TableName = ?Table(DeviceId),
Interval = <<"1d">>,
%%
case dgiot_device_tdengine:get_history_data2(Sql, Channel, TableName, Interval, ProductId, StartTime, EndTime) of
%%
{ok, #{<<"results">> := Results}} ->
%% io:format("~s ~p Results = ~p ~n",[?FILE,?LINE,Results]),
Tabledata = get_table(Results,Names),
%% io:format("~s ~p Tabledata = ~p ~n",[?FILE,?LINE,Tabledata]),
{ok,Tabledata};
_ ->
{ok, #{<<"code">> => 400, <<"msg">> => <<"no data">>}}
end
end.

View File

@ -22,6 +22,7 @@
-export([get_device/3, get_device/4, get_device/5]).
-export([get_history_data/3, get_realtime_data/3]).
-export([get_history_data2/7]).
%% #{<<"keys">> => <<"last_row(*)">>, <<"limit">> => 1} td最新的一条device
get_device(ProductId, DevAddr, Query) ->
@ -146,3 +147,15 @@ get_realtime_data(Channel, TableName, Query) ->
end
end).
get_history_data2(Order, Channel, TableName, Interval, ProductId, StartTime, _EndTime) ->
%% io:format("~s ~p Order= ~p, Channel= ~p, TableName= ~p, TableName= ~p,~n Interval= ~p, ProductId= ~p, ~n StartTime= ~p, EndTime =~p. ~n",[?FILE,?LINE,Order, Channel, TableName, TableName, Interval, ProductId, StartTime, _EndTime]),
dgiot_tdengine:transaction(Channel,
fun(Context) ->
Database = ProductId,
DB = dgiot_tdengine_select:format_db(?Database(Database)),
BinStartTime = dgiot_utils:to_binary(StartTime),
Tail = <<" where createdat >= ", BinStartTime/binary, " INTERVAL(", Interval/binary, ") ", ";">>,
Sql = <<"SELECT ", Order/binary, " FROM ", DB/binary, TableName/binary, Tail/binary>>,
?LOG(error, "Sql ~s", [Sql]),
dgiot_tdengine_pool:run_sql(Context#{<<"channel">> => Channel}, execute_query, Sql)
end).

View File

@ -1486,9 +1486,9 @@ dgiot_shell
# set parameters by default value
deployType=single # [single | cluster | devops | ci]
domain_name="prod.iotn2n.com" # [prod.iotn2n.com | your_domain_name]
software="dgiot_n183" # [dgiot_n183| dgiot_n]
software="dgiot_n184" # [dgiot_n184| dgiot_n]
plugin="dgiot" # [dgiot | dgiot_your_plugin]
dgiotmd5="7c410d76293b2e44d50da1e9cabff99c" # [dgiotmd5]
dgiotmd5="963afd492685c5c5cd14a52b072f17b4" # [dgiotmd5]
pg_eip="changeyourip" # [datanode_eip]
pg_auth='changeyourpassword' # [pg_auth]