mirror of
https://gitee.com/dgiiot/dgiot.git
synced 2024-11-29 18:57:41 +08:00
feat: device lookup
This commit is contained in:
parent
ef4b154746
commit
5a92781954
@ -49,22 +49,25 @@ post(Device) ->
|
||||
Devaddr = maps:get(<<"devaddr">>, Device),
|
||||
Product = maps:get(<<"product">>, Device),
|
||||
ProductId = maps:get(<<"objectId">>, Product),
|
||||
<<DeviceSecretdefult:10/binary, _/binary>> = dgiot_utils:to_md5(dgiot_utils:random()),
|
||||
DeviceSecret = maps:get(<<"deviceSecret">>, Device, DeviceSecretdefult),
|
||||
Status =
|
||||
case maps:get(<<"status">>, Device, <<"OFFLINE">>) of
|
||||
<<"OFFLINE">> -> false;
|
||||
_ -> true
|
||||
end,
|
||||
dgiot_mnesia:insert(DeviceId, {[Status, dgiot_datetime:now_secs(), get_acl(Device), DeviceName, Devaddr, ProductId], node()}).
|
||||
dgiot_mnesia:insert(DeviceId, {[Status, dgiot_datetime:now_secs(), get_acl(Device), DeviceName, Devaddr, ProductId, DeviceSecret], node()}).
|
||||
|
||||
put(Device) ->
|
||||
DeviceId = maps:get(<<"objectId">>, Device),
|
||||
case lookup(DeviceId) of
|
||||
{ok, {[Status, _, Acl, DeviceName, Devaddr, ProductId], Node}} ->
|
||||
{ok, #{<<"status">> := Status, <<"acl">> := Acl,
|
||||
<<"devaddr">> := Devaddr, <<"productid">> := ProductId, <<"devicesecret">> := DeviceSecret, <<"node">> := Node}} ->
|
||||
case maps:find(<<"ACL">>, Device) of
|
||||
error ->
|
||||
dgiot_mnesia:insert(DeviceId, {[Status, dgiot_datetime:now_secs(), Acl, DeviceName, Devaddr, ProductId], Node});
|
||||
dgiot_mnesia:insert(DeviceId, {[Status, dgiot_datetime:now_secs(), Acl, Devaddr, ProductId, DeviceSecret], Node});
|
||||
{ok, _} ->
|
||||
dgiot_mnesia:insert(DeviceId, {[Status, dgiot_datetime:now_secs(), get_acl(Device), DeviceName, Devaddr, ProductId], Node})
|
||||
dgiot_mnesia:insert(DeviceId, {[Status, dgiot_datetime:now_secs(), get_acl(Device), Devaddr, ProductId, DeviceSecret], Node})
|
||||
end;
|
||||
_ ->
|
||||
pass
|
||||
@ -76,6 +79,8 @@ save(Device) ->
|
||||
Devaddr = maps:get(<<"devaddr">>, Device),
|
||||
Product = maps:get(<<"product">>, Device),
|
||||
ProductId = maps:get(<<"objectId">>, Product),
|
||||
<<DeviceSecretdefult:10/binary, _/binary>> = dgiot_utils:to_md5(dgiot_utils:random()),
|
||||
DeviceSecret = maps:get(<<"deviceSecret">>, Device, DeviceSecretdefult),
|
||||
UpdatedAt =
|
||||
case maps:get(<<"updatedAt">>, Device, dgiot_datetime:now_secs()) of
|
||||
<<Data:10/binary, "T", Time:8/binary, _/binary>> ->
|
||||
@ -87,7 +92,7 @@ save(Device) ->
|
||||
<<"OFFLINE">> -> false;
|
||||
_ -> true
|
||||
end,
|
||||
dgiot_mnesia:insert(DeviceId, {[Status, UpdatedAt, get_acl(Device), DeviceName, Devaddr, ProductId], node()}).
|
||||
dgiot_mnesia:insert(DeviceId, {[Status, UpdatedAt, get_acl(Device), DeviceName, Devaddr, ProductId, DeviceSecret], node()}).
|
||||
|
||||
get_acl(Device) when is_map(Device) ->
|
||||
ACL = maps:get(<<"ACL">>, Device, #{}),
|
||||
@ -97,7 +102,7 @@ get_acl(Device) when is_map(Device) ->
|
||||
|
||||
get_acl(DeviceId) when is_binary(DeviceId) ->
|
||||
case lookup(DeviceId) of
|
||||
{ok, {[_, _, [Acl | _], _, _, _], _}} ->
|
||||
{ok, #{<<"acl">> := Acl}} ->
|
||||
BinAcl = atom_to_binary(Acl),
|
||||
#{BinAcl => #{
|
||||
<<"read">> => true,
|
||||
@ -122,15 +127,17 @@ get_acl(_DeviceId) ->
|
||||
|
||||
online(DeviceId) ->
|
||||
case lookup(DeviceId) of
|
||||
{ok, {[Status, _Now, Acl, DeviceName, Devaddr, ProductId], Node}} ->
|
||||
dgiot_mnesia:insert(DeviceId, {[Status, dgiot_datetime:now_secs() + 72000, Acl, DeviceName, Devaddr, ProductId], Node});
|
||||
{ok, #{<<"status">> := Status, <<"acl">> := Acl,
|
||||
<<"devaddr">> := Devaddr, <<"productid">> := ProductId, <<"devicesecret">> := DeviceSecret, <<"node">> := Node}} ->
|
||||
dgiot_mnesia:insert(DeviceId, {[Status, dgiot_datetime:now_secs() + 72000, Acl, Devaddr, ProductId, DeviceSecret], Node});
|
||||
_ -> pass
|
||||
end.
|
||||
|
||||
offline(DeviceId) ->
|
||||
case lookup(DeviceId) of
|
||||
{ok, {[Status, Now, Acl, DeviceName, Devaddr, ProductId], Node}} ->
|
||||
dgiot_mnesia:insert(DeviceId, {[Status, Now - 72000, Acl, DeviceName, Devaddr, ProductId], Node}),
|
||||
{ok, #{<<"status">> := Status, <<"time">> := Now, <<"acl">> := Acl,
|
||||
<<"devaddr">> := Devaddr, <<"productid">> := ProductId, <<"devicesecret">> := DeviceSecret, <<"node">> := Node}} ->
|
||||
dgiot_mnesia:insert(DeviceId, {[Status, Now - 72000, Acl, Devaddr, ProductId, DeviceSecret], Node}),
|
||||
offline_child(DeviceId);
|
||||
_ -> pass
|
||||
end.
|
||||
@ -156,7 +163,7 @@ sync_parse(OffLine) ->
|
||||
{_, DeviceId, V} = X,
|
||||
Now = dgiot_datetime:now_secs(),
|
||||
case V of
|
||||
{[_, Last, Acl, DeviceName, Devaddr, ProductId], Node} when (Now - Last) < 0 ->
|
||||
{[_, Last, Acl, DeviceName, Devaddr, ProductId, DeviceSecret], Node} when (Now - Last) < 0 ->
|
||||
case dgiot_parse:update_object(<<"Device">>, DeviceId, #{<<"status">> => <<"ONLINE">>}) of
|
||||
{ok, _R} ->
|
||||
Productname =
|
||||
@ -167,12 +174,12 @@ sync_parse(OffLine) ->
|
||||
<<"">>
|
||||
end,
|
||||
?MLOG(info, #{<<"deviceid">> => DeviceId, <<"devaddr">> => Devaddr, <<"productid">> => ProductId, <<"productname">> => Productname, <<"devicename">> => DeviceName, <<"status">> => <<"上线"/utf8>>}, ['device_statuslog']),
|
||||
dgiot_mnesia:insert(DeviceId, {[true, Now, Acl, DeviceName, Devaddr, ProductId], Node});
|
||||
dgiot_mnesia:insert(DeviceId, {[true, Now, Acl, DeviceName, Devaddr, ProductId, DeviceSecret], Node});
|
||||
_ ->
|
||||
pass
|
||||
end,
|
||||
timer:sleep(50);
|
||||
{[true, Last, Acl, DeviceName, Devaddr, ProductId], Node} when (Now - Last) > OffLine ->
|
||||
{[true, Last, Acl, DeviceName, Devaddr, ProductId, DeviceSecret], Node} when (Now - Last) > OffLine ->
|
||||
case dgiot_parse:update_object(<<"Device">>, DeviceId, #{<<"status">> => <<"OFFLINE">>}) of
|
||||
{ok, _R} ->
|
||||
Productname =
|
||||
@ -184,12 +191,12 @@ sync_parse(OffLine) ->
|
||||
end,
|
||||
?MLOG(info, #{<<"deviceid">> => DeviceId, <<"devaddr">> => Devaddr, <<"productid">> => ProductId, <<"productname">> => Productname, <<"devicename">> => DeviceName, <<"status">> => <<"下线"/utf8>>}, ['device_statuslog']),
|
||||
dgiot_umeng:save_devicestatus(DeviceId, <<"OFFLINE">>),
|
||||
dgiot_mnesia:insert(DeviceId, {[false, Last, Acl, DeviceName, Devaddr, ProductId], Node});
|
||||
dgiot_mnesia:insert(DeviceId, {[false, Last, Acl, DeviceName, Devaddr, ProductId, DeviceSecret], Node});
|
||||
_ ->
|
||||
pass
|
||||
end,
|
||||
timer:sleep(50);
|
||||
{[false, Last, Acl, DeviceName, Devaddr, ProductId], Node} when (Now - Last) < OffLine ->
|
||||
{[false, Last, Acl, DeviceName, Devaddr, ProductId, DeviceSecret], Node} when (Now - Last) < OffLine ->
|
||||
case dgiot_parse:update_object(<<"Device">>, DeviceId, #{<<"status">> => <<"ONLINE">>}) of
|
||||
{ok, _R} ->
|
||||
Productname =
|
||||
@ -200,7 +207,7 @@ sync_parse(OffLine) ->
|
||||
<<"">>
|
||||
end,
|
||||
?MLOG(info, #{<<"deviceid">> => DeviceId, <<"devaddr">> => Devaddr, <<"productid">> => ProductId, <<"productname">> => Productname, <<"devicename">> => DeviceName, <<"status">> => <<"上线"/utf8>>}, ['device_statuslog']),
|
||||
dgiot_mnesia:insert(DeviceId, {[true, Last, Acl, DeviceName, Devaddr, ProductId], Node});
|
||||
dgiot_mnesia:insert(DeviceId, {[true, Last, Acl, DeviceName, Devaddr, ProductId, DeviceSecret], Node});
|
||||
_ ->
|
||||
pass
|
||||
end,
|
||||
@ -216,8 +223,9 @@ lookup(DeviceId) ->
|
||||
case dgiot_mnesia:lookup(DeviceId) of
|
||||
{aborted, Reason} ->
|
||||
{error, Reason};
|
||||
{ok, [{mnesia, _K, V}]} ->
|
||||
{ok, V};
|
||||
{ok, [{mnesia, _K, {[Status, Time, Acl, Devaddr, ProductId, DeviceSecret], Node}}]} ->
|
||||
{ok, #{<<"status">> => Status, <<"time">> => Time, <<"acl">> => Acl,
|
||||
<<"devaddr">> => Devaddr, <<"productid">> => ProductId, <<"devicesecret">> => DeviceSecret, <<"node">> => Node}};
|
||||
_ ->
|
||||
{error, not_find}
|
||||
end.
|
||||
@ -349,6 +357,7 @@ create_device(#{
|
||||
_R ->
|
||||
{{Y, M, D}, {_, _, _}} = dgiot_datetime:local_time(),
|
||||
Batch_name = dgiot_utils:to_list(Y) ++ dgiot_utils:to_list(M) ++ dgiot_utils:to_list(D),
|
||||
<<DeviceSecret:10/binary, _/binary>> = dgiot_utils:to_md5(dgiot_utils:random()),
|
||||
NewDevice = Device#{
|
||||
<<"location">> => maps:get(<<"location">>, Device, #{<<"__type">> => <<"GeoPoint">>, <<"longitude">> => 120.161324, <<"latitude">> => 30.262441}),
|
||||
<<"basedata">> => maps:get(<<"basedata">>, Device, #{}),
|
||||
@ -359,6 +368,7 @@ create_device(#{
|
||||
<<"objectId">> => ProductId
|
||||
},
|
||||
<<"ACL">> => maps:without([<<"*">>], Acl),
|
||||
<<"deviceSecret">> => DeviceSecret,
|
||||
<<"detail">> => #{
|
||||
<<"desc">> => Name,
|
||||
<<"brand">> => Brand,
|
||||
@ -422,7 +432,7 @@ get_online(DeviceId) ->
|
||||
OffLine = dgiot_data:get({device, offline}),
|
||||
Now = dgiot_datetime:now_secs(),
|
||||
case lookup(DeviceId) of
|
||||
{ok, {[_, Ts, _, _, _, _], _}} when Now - Ts < OffLine ->
|
||||
{ok, #{<<"time">> := Ts}} when Now - Ts < OffLine ->
|
||||
true;
|
||||
_ ->
|
||||
false
|
||||
@ -497,7 +507,7 @@ get_url(AppName) ->
|
||||
|
||||
get_appname(DeviceId) ->
|
||||
case dgiot_device:lookup(DeviceId) of
|
||||
{ok, {[_, _, [Acl | _], _, _, _], _}} ->
|
||||
{ok, #{<<"acl">> := Acl}} ->
|
||||
BinAcl = atom_to_binary(Acl),
|
||||
case BinAcl of
|
||||
<<"role:", Name/binary>> ->
|
||||
@ -511,12 +521,11 @@ get_appname(DeviceId) ->
|
||||
|
||||
save_log(DeviceId, Payload, Domain) ->
|
||||
case dgiot_device:lookup(DeviceId) of
|
||||
{ok, {[_, _, _, DeviceName, Devaddr, ProductId], _}} ->
|
||||
{ok, #{<<"devaddr">> := Devaddr, <<"productid">> := ProductId}} ->
|
||||
?MLOG(info, #{
|
||||
<<"deviceid">> => DeviceId,
|
||||
<<"devaddr">> => Devaddr,
|
||||
<<"productid">> => ProductId,
|
||||
<<"devicename">> => DeviceName,
|
||||
<<"msg">> => Payload}, Domain);
|
||||
_ ->
|
||||
pass
|
||||
@ -524,7 +533,7 @@ save_log(DeviceId, Payload, Domain) ->
|
||||
|
||||
sub_topic(DeviceId, Type) ->
|
||||
case dgiot_device:lookup(DeviceId) of
|
||||
{ok, {[_, _, _, _DeviceName, Devaddr, ProductId], _}} ->
|
||||
{ok, #{<<"devaddr">> := Devaddr, <<"productid">> := ProductId}} ->
|
||||
Topic = <<"thing/", ProductId/binary, "/", Devaddr/binary, "/", Type/binary>>,
|
||||
dgiot_mqtt:subscribe(Topic);
|
||||
_ -> pass
|
||||
|
@ -215,7 +215,7 @@ save_notification(Ruleid, DevAddr, Payload) ->
|
||||
[ProductId, _] ->
|
||||
DeviceId = dgiot_parse:get_deviceid(ProductId, DevAddr),
|
||||
case dgiot_device:lookup(DeviceId) of
|
||||
{ok, {[_, _, Acl, _, _, _], _}} ->
|
||||
{ok, #{<<"acl">> := Acl}} ->
|
||||
Requests =
|
||||
lists:foldl(fun(X, Acc) ->
|
||||
BinX = atom_to_binary(X),
|
||||
@ -393,7 +393,7 @@ save_devicestatus(DeviceId, Status) ->
|
||||
end,
|
||||
|
||||
case dgiot_device:lookup(DeviceId) of
|
||||
{ok, {[_, _, Acl, _, Devaddr, ProductId], _}} ->
|
||||
{ok, #{<<"acl">> := Acl, <<"devaddr">> := Devaddr, <<"productid">> := ProductId}} ->
|
||||
Ruleid = <<ProductId/binary, "_status">>,
|
||||
Productname =
|
||||
case dgiot_parse:get_object(<<"Product">>, ProductId) of
|
||||
|
@ -27,7 +27,7 @@
|
||||
build_req_message/1]
|
||||
).
|
||||
|
||||
-export([modbus_encoder/4, modbus_decoder/5, is16/1, set_params/3]).
|
||||
-export([modbus_encoder/4, modbus_decoder/5, is16/1, set_params/3, decode_data/4, decode_data/5]).
|
||||
|
||||
init(State) ->
|
||||
State#{<<"req">> => [], <<"ts">> => dgiot_datetime:now_ms(), <<"interval">> => 300}.
|
||||
@ -160,13 +160,6 @@ set_params(Basedata, ProductId, DevAddr) ->
|
||||
quality = Value1
|
||||
},
|
||||
DeviceId = dgiot_parse:get_deviceid(ProductId, DevAddr),
|
||||
DeviceName =
|
||||
case dgiot_device:lookup(DeviceId) of
|
||||
{ok, {[_, _, _, DeviceName1, _, _], _}} ->
|
||||
DeviceName1;
|
||||
_ ->
|
||||
<<"">>
|
||||
end,
|
||||
Sessiontoken = maps:get(<<"sessiontoken">>, Basedata, <<"">>),
|
||||
{Username, Acl} =
|
||||
case dgiot_auth:get_session(Sessiontoken) of
|
||||
@ -175,7 +168,12 @@ set_params(Basedata, ProductId, DevAddr) ->
|
||||
_ ->
|
||||
{<<"">>, #{}}
|
||||
end,
|
||||
?MLOG(info, #{<<"clientid">> => DeviceId, <<"username">> => Username, <<"status">> => <<"ONLINE">>, <<"ACL">> => Acl, <<"devaddr">> => DevAddr, <<"productid">> => ProductId, <<"devicename">> => DeviceName, <<"productname">> => Productname, <<"thingname">> => Name, <<"protocol">> => <<"modbus">>, <<"identifier">> => Identifier, <<"value">> => Value1}, ['device_operationlog']),
|
||||
?MLOG(info, #{<<"clientid">> => DeviceId, <<"username">> => Username,
|
||||
<<"status">> => <<"ONLINE">>, <<"ACL">> => Acl,
|
||||
<<"devaddr">> => DevAddr, <<"productid">> => ProductId,
|
||||
<<"productname">> => Productname, <<"thingname">> => Name,
|
||||
<<"protocol">> => <<"modbus">>, <<"identifier">> => Identifier, <<"value">> => Value1},
|
||||
['device_operationlog']),
|
||||
Acc ++ [build_req_message(RtuReq)];
|
||||
_ ->
|
||||
Acc
|
||||
@ -217,6 +215,16 @@ parse_frame(<<MbAddr:8, BadCode:8, ErrorCode:8, Crc:2/binary>> = Buff, Acc,
|
||||
parse_frame(Buff, Acc, State)
|
||||
end;
|
||||
|
||||
%% modbustcp
|
||||
%% Buff = <<"000100000006011000000001">>,
|
||||
parse_frame(<<_TransactionId:16, _ProtocolId:16, Size:16, _ResponseData:Size/bytes>> = Buff, Acc, #{<<"dtuproduct">> := ProductId, <<"dtuaddr">> := DtuAddr} = State) ->
|
||||
case decode_data(Buff, ProductId, DtuAddr, Acc) of
|
||||
{Rest1, Acc1} ->
|
||||
parse_frame(Rest1, Acc1, State);
|
||||
[Buff, Acc] ->
|
||||
[Buff, Acc]
|
||||
end;
|
||||
|
||||
%% 传感器直接做为dtu物模型的一个指标
|
||||
parse_frame(<<SlaveId:8, _/binary>> = Buff, Acc, #{<<"dtuproduct">> := ProductId, <<"slaveId">> := SlaveId, <<"dtuaddr">> := DtuAddr, <<"address">> := Address} = State) ->
|
||||
case decode_data(Buff, ProductId, DtuAddr, Address, Acc) of
|
||||
@ -244,6 +252,9 @@ parse_frame(_Other, Acc, _State) ->
|
||||
?LOG(error, "_Other ~p", [_Other]),
|
||||
{error, Acc}.
|
||||
|
||||
decode_data(<<TransactionId:16, _ProtocolId:16, _Size1:16, Address:8, _FunCode:8, Data/binary>>, ProductId, _DtuAddr, Acc) ->
|
||||
{<<>>, modbus_tcp_decoder(ProductId, TransactionId, Address, Data, Acc)}.
|
||||
|
||||
decode_data(Buff, ProductId, DtuAddr, Address, Acc) ->
|
||||
<<SlaveId:8, FunCode:8, ResponseData/binary>> = Buff,
|
||||
{SizeOfData, DataBytes} =
|
||||
@ -432,6 +443,38 @@ list_word16_to_binary(Values) when is_list(Values) ->
|
||||
)
|
||||
).
|
||||
|
||||
modbus_tcp_decoder(ProductId, TransactionId, Address, Data, Acc1) ->
|
||||
case dgiot_product:lookup_prod(ProductId) of
|
||||
{ok, #{<<"thing">> := #{<<"properties">> := Props}}} ->
|
||||
lists:foldl(fun(X, Acc) ->
|
||||
case X of
|
||||
#{<<"identifier">> := Identifier,
|
||||
<<"dataForm">> := #{
|
||||
<<"slaveid">> := OldSlaveid,
|
||||
<<"address">> := OldAddress,
|
||||
<<"protocol">> := <<"modbus">>
|
||||
}} ->
|
||||
<<H:8, L:8>> = dgiot_utils:hex_to_binary(modbus_rtu:is16(OldSlaveid)),
|
||||
<<Sh:8, Sl:8>> = dgiot_utils:hex_to_binary(modbus_rtu:is16(OldAddress)),
|
||||
NewSlaveid = H * 256 + L,
|
||||
NewAddress = Sh * 256 + Sl,
|
||||
case {TransactionId, Address} of
|
||||
{NewSlaveid, NewAddress} ->
|
||||
case format_value(Data, X) of
|
||||
{Value, _Rest} ->
|
||||
Acc#{Identifier => Value};
|
||||
_ -> Acc
|
||||
end;
|
||||
_ ->
|
||||
Acc
|
||||
end;
|
||||
_ ->
|
||||
Acc
|
||||
end
|
||||
end, Acc1, Props);
|
||||
_ -> #{}
|
||||
end.
|
||||
|
||||
modbus_decoder(ProductId, SlaveId, Address, Data, Acc1) ->
|
||||
case dgiot_product:lookup_prod(ProductId) of
|
||||
{ok, #{<<"thing">> := #{<<"properties">> := Props}}} ->
|
||||
|
@ -401,7 +401,7 @@ get_Product() ->
|
||||
{ok, #{<<"results">> := Results}} ->
|
||||
lists:foldl(fun(X, _Acc) ->
|
||||
case X of
|
||||
#{<<"objectId">> := ProductId, <<"config">> := #{<<"konva">> := #{<<"Stage">> := #{<<"children">> := Children}}}, <<"thing">> := #{<<"properties">> := Properties}} ->
|
||||
#{<<"objectId">> := ProductId, <<"thing">> := #{<<"properties">> := Properties}} ->
|
||||
lists:map(fun(P) ->
|
||||
DataType = maps:get(<<"dataType">>, P, #{}),
|
||||
Type = maps:get(<<"type">>, DataType, <<"">>),
|
||||
@ -412,7 +412,15 @@ get_Product() ->
|
||||
dgiot_data:insert({product, <<ProductId/binary, Identifier/binary>>}, {Name, Type, Unit}),
|
||||
dgiot_data:insert({thing, <<ProductId/binary, Identifier/binary>>}, P)
|
||||
end, Properties),
|
||||
get_children(<<"web">>, ProductId, Children, ProductId, <<"KonvatId">>, <<"Shapeid">>, <<"Identifier">>, <<"Name">>);
|
||||
case dgiot_parse:query_object(<<"View">>, #{<<"limit">> => 1, <<"where">> => #{<<"key">> => ProductId, <<"type">> => <<"topo">>, <<"class">> => <<"Product">>}}) of
|
||||
{ok, #{<<"results">> := Views}} when length(Views) > 0 ->
|
||||
lists:foldl(fun(View, _Acc1) ->
|
||||
#{<<"data">> := #{<<"konva">> := #{<<"Stage">> := #{<<"children">> := Children}}}} = View,
|
||||
get_children(<<"web">>, ProductId, Children, ProductId, <<"KonvatId">>, <<"Shapeid">>, <<"Identifier">>, <<"Name">>)
|
||||
end, #{}, Views);
|
||||
_ ->
|
||||
pass
|
||||
end;
|
||||
_ ->
|
||||
pass
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user