From 8b5623fae0e593ed08d1d8d808ddeff4895bd538 Mon Sep 17 00:00:00 2001 From: "U-JOHNLIU\\jonhl" Date: Tue, 22 Feb 2022 11:44:15 +0800 Subject: [PATCH] fix: meter modify --- apps/dgiot_meter/src/dgiot_meter_tcp.erl | 2 +- .../src/proctol/dlt376_decoder.erl | 80 ++++++++++++------- apps/dgiot_task/src/dgiot_profile_channel.erl | 45 ++++++----- 3 files changed, 74 insertions(+), 53 deletions(-) diff --git a/apps/dgiot_meter/src/dgiot_meter_tcp.erl b/apps/dgiot_meter/src/dgiot_meter_tcp.erl index f566ad68..c449070e 100644 --- a/apps/dgiot_meter/src/dgiot_meter_tcp.erl +++ b/apps/dgiot_meter/src/dgiot_meter_tcp.erl @@ -228,7 +228,7 @@ handle_info({deliver, _Topic, Msg}, #tcp{state = #state{id = _ChannelId, protoco dgiot_tcp_server:send(TCPState, Payload1) end; [<<"profile">>, _ProductId, DevAddr] -> %%[<<"profile">>,<<"ecfbf67dd7">>,<<"330100480000">> - io:format("~s ~p ProData ~p Protocol ~p~n", [?FILE, ?LINE, Payload, Protocol]), +%% io:format("~s ~p ProData ~p Protocol ~p~n", [?FILE, ?LINE, Payload, Protocol]), case Protocol of ?DLT376 -> Payload2 = dlt376_decoder:frame_write_param(#{<<"concentrator">> => DevAddr, <<"payload">> => jsx:decode(Payload)}), diff --git a/apps/dgiot_meter/src/proctol/dlt376_decoder.erl b/apps/dgiot_meter/src/proctol/dlt376_decoder.erl index c9bd98e3..64376978 100644 --- a/apps/dgiot_meter/src/proctol/dlt376_decoder.erl +++ b/apps/dgiot_meter/src/proctol/dlt376_decoder.erl @@ -288,6 +288,33 @@ check_Command(State = #{<<"afn">> := 16#10}) -> check_Command(State) -> State. +to_frame(#{ + % <<"msgtype">> := ?DLT376, + <<"command">> := C, +%% <<"addr">> := Addr, %%?? Addr是6位字符 + <<"concentrator">> := Addr, + <<"afn">> := AFN +} = Msg) when AFN == 1 orelse AFN == 4 orelse AFN == 5 orelse AFN == 6 orelse AFN == 10 -> + {ok, UserZone} = get_userzone(Msg), + %% todo 密码应该是从密码机传递过来 + Pwd = <<16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00>>, + UserData = <>, + Len = (byte_size(UserData) + 8) * 4 + 2, + Crc = dgiot_utils:get_parity(<>), + << + 16#68, + Len:16/little, + Len:16/little, + 16#68, + C:8, + Addr:5/bytes, + AFN:8, + 16#61, + UserData/binary, + Crc:8, + 16#16 + >>; + %% 组装成封包 to_frame(#{ % <<"msgtype">> := ?DLT376, @@ -498,29 +525,32 @@ pn_to_da(Pn) -> %%#{<<"byteType">> => <<"bit">>, %%<<"bytes">> => <<"4">>}, %%<<"sessiontoken">> => <<>>}} - +%% ConAddr = <<"000033010048">>, frame_write_param(#{<<"concentrator">> := ConAddr, <<"payload">> := Frame}) -> Length = length(maps:keys(Frame)), io:format("~s ~p SortFrame ~p.~n", [?FILE, ?LINE, Length]), {BitList, Afn, Da, Fn} = - lists:map(fun(Index, {Acc, A, D, F}) -> - case maps:find(Index, Frame) of - {ok, #{<<"dataForm">> := #{<<"afn">> := AFN, <<"di">> := FN, <<"length">> := Len, <<"type">> := Type} = DataForm} = Data} -> - DA = dgiot_utils:binary_to_hex(pn_to_da(to_integer(maps:get(<<"da">>, DataForm, 0)))), + lists:foldl(fun(Index, {Acc, A, D, F}) -> + case maps:find(dgiot_utils:to_binary(Index), Frame) of + {ok, #{<<"value">> := Value, <<"dataForm">> := #{<<"afn">> := AFN, <<"da">> := Da, <<"di">> := FN, <<"length">> := Len, <<"type">> := Type} = _DataForm}} -> + io:format("~s ~p Value ~p. Da ~p FN ~p ~n", [?FILE, ?LINE, Value, Da,FN]), + DA = dgiot_utils:binary_to_hex(pn_to_da(Da)), case Type of <<"bytes">> -> - Value = maps:get(<<"value">>, Data), - Value1 = dlt645_proctol:reverse(dgiot_utils:hex_to_binary(Value)), - {Acc ++ get_values(Value1), AFN, DA, FN}; + NewValue = dlt645_proctol:reverse(dgiot_utils:hex_to_binary(Value)), + io:format("~s ~p NewValue ~p.~n", [?FILE, ?LINE, NewValue]), + {get_values(Acc,NewValue), AFN, DA, FN}; <<"little">> -> - Value = to_integer(maps:get(<<"value">>, Data)), - L = to_integer(Len), + NewValue = dgiot_utils:to_int(Value), + L = dgiot_utils:to_int(Len), Len1 = L * 8, - {Acc ++ [get_values(<>)], AFN, DA, FN}; + io:format("~s ~p NewValue ~p.~n", [?FILE, ?LINE, NewValue]), + {get_values(Acc,<>), AFN, DA, FN}; <<"bit">> -> - Value = to_integer(maps:get(<<"value">>, Data)), - L = to_integer(Len), - {Acc ++ [{Value, L}], AFN, DA, FN} + NewValue = dgiot_utils:to_int(Value), + L = dgiot_utils:to_int(Len), + io:format("~s ~p NewValue ~p.~n", [?FILE, ?LINE, NewValue]), + {Acc ++ [{NewValue, L}], AFN, DA, FN} end; _ -> {Acc, A, D, F} @@ -528,19 +558,19 @@ frame_write_param(#{<<"concentrator">> := ConAddr, <<"payload">> := Frame}) -> end, {[], 0, <<>>, <<>>}, lists:seq(1, Length)), io:format("~s ~p BitList ~p.~n", [?FILE, ?LINE, BitList]), UserZone = <<<> || {V, BitLen} <- BitList>>, - io:format("~s ~p UserZone ~p.~n", [?FILE, ?LINE, UserZone]), + io:format("~s ~p UserZone ~p. Afn ~p ~n", [?FILE, ?LINE, UserZone,Afn]), UserData = add_to_userzone(UserZone, Afn, Fn), dlt376_decoder:to_frame(#{<<"command">> => 16#4B, <<"concentrator">> => concentrator_to_addr(ConAddr), - <<"afn">> => to_integer(Afn), + <<"afn">> => dgiot_utils:to_int(Afn), %% <<"da">> => Da, <<"di">> => <>, <<"data">> => dgiot_utils:binary_to_hex(UserData)}). -get_values(Data) -> - lists:foldl(fun(V, Acc) -> - Acc ++ [{V, 8}] - end, binary_to_list(Data), []). +get_values(Acc, Data) -> + lists:foldl(fun(V, Acc1) -> + Acc1 ++ [{V, 8}] + end, Acc, binary_to_list(Data)). %%frame_write_param(#{<<"concentrator">> := ConAddr, <<"basedata">> := Data}) -> %% ZZXH = to_integer(maps:get(<<"zzxh">>, Data, <<"2040">>)), @@ -572,12 +602,9 @@ get_values(Data) -> %% <<"di">> => <<16#02, 16#01>>, %% <<"data">> => UserZone}). -add_to_userzone(UserZone, Afn, Fn) when Afn == 16#04 orelse Fn == <<"0201">> -> - <<16#01, 16#00, UserZone/bytes>>; add_to_userzone(UserZone, _Afn, _Fn) -> UserZone. - concentrator_to_addr(ConAddr) when byte_size(ConAddr) == 6 -> <<_:2/bytes, A11:2/bytes, A22:2/bytes>> = ConAddr, A1 = dlt645_proctol:reverse(A11), @@ -593,10 +620,3 @@ concentrator_to_addr(ConAddr) when byte_size(ConAddr) == 12 -> concentrator_to_addr(_ConAddr) -> <<16#00, 16#00, 16#00, 16#00, 16#00>>. - -to_integer(Hex) when is_integer(Hex) -> - Hex; -to_integer(Hex) when is_binary(Hex) -> - binary_to_integer(Hex); -to_integer(Hex) when is_list(Hex) -> - list_to_integer(Hex). diff --git a/apps/dgiot_task/src/dgiot_profile_channel.erl b/apps/dgiot_task/src/dgiot_profile_channel.erl index c8018816..8e83502e 100644 --- a/apps/dgiot_task/src/dgiot_profile_channel.erl +++ b/apps/dgiot_task/src/dgiot_profile_channel.erl @@ -138,7 +138,8 @@ handle_message({sync_parse, Args}, State) -> #{<<"profile">> := Profile, <<"devaddr">> := Devaddr, <<"product">> := #{<<"objectId">> := ProductId}} = Arg -> Sessiontoken = maps:get(<<"sessiontoken">>, Arg, <<"">>), DeviceId = dgiot_parse:get_deviceid(ProductId, Devaddr), - Modifyprofile = get_modifyprofile(DeviceId, Profile), + Modifyprofile = Profile, +%% get_modifyprofile(DeviceId, Profile), %% 设置参数 case dgiot_device:get_online(DeviceId) of true -> @@ -147,7 +148,7 @@ handle_message({sync_parse, Args}, State) -> NewPayLoad = lists:foldl(fun(X, Acc) -> case X of - #{<<"identifier">> := Identifier, <<"accessMode">> := <<"w">>, <<"dataForm">> := #{<<"_dlinkindex">> := Index} = DataForm} -> + #{<<"identifier">> := Identifier, <<"accessMode">> := <<"rw">>, <<"dataForm">> := #{<<"_dlinkindex">> := Index} = DataForm} -> case maps:find(Identifier, Modifyprofile) of {ok, V} -> Acc#{ @@ -163,8 +164,8 @@ handle_message({sync_parse, Args}, State) -> end end, #{}, Properties), Topic = <<"profile/", ProductId/binary, "/", Devaddr/binary>>, - dgiot_mqtt:publish(DeviceId, Topic, NewPayLoad), - io:format("~s ~p NewPayLoad = ~p.~n", [?FILE, ?LINE, NewPayLoad]), + dgiot_mqtt:publish(DeviceId, Topic, jsx:encode(NewPayLoad)), +%% io:format("~s ~p NewPayLoad = ~p.~n", [?FILE, ?LINE, jsx:encode(NewPayLoad)]), dgiot_data:insert(?PROFILE, DeviceId, Profile); false -> dgiot_data:insert(?MODIFYPROFILE, DeviceId, {Modifyprofile, ProductId, Devaddr}) @@ -189,21 +190,21 @@ stop(ChannelType, ChannelId, #state{env = #{<<"product">> := ProductId, <<"args" ok. -get_modifyprofile(DeviceId, Profile) -> - case dgiot_data:get(?PROFILE, DeviceId) of - not_find -> - dgiot_data:insert(?PROFILE, DeviceId, Profile), - Profile; - OldProfile -> - maps:fold(fun(K, V, Acc) -> - case maps:find(K, OldProfile) of - error -> - Acc#{K => V}; - {ok, V} -> - Acc; - _ -> - Acc#{K => V} - end - end, #{}, Profile) - - end. +%%get_modifyprofile(DeviceId, Profile) -> +%% case dgiot_data:get(?PROFILE, DeviceId) of +%% not_find -> +%% dgiot_data:insert(?PROFILE, DeviceId, Profile), +%% Profile; +%% OldProfile -> +%% maps:fold(fun(K, V, Acc) -> +%% case maps:find(K, OldProfile) of +%% error -> +%% Acc#{K => V}; +%% {ok, V} -> +%% Acc; +%% _ -> +%% Acc#{K => V} +%% end +%% end, #{}, Profile) +%% +%% end.