feat: Meter login message length interpretation

This commit is contained in:
dawnwinterLiu 2022-06-30 20:54:05 +08:00
parent e581e7b612
commit bf411a27a0
3 changed files with 74 additions and 38 deletions

View File

@ -38,7 +38,8 @@
step = login,
ref = undefined,
search = <<"quick">>,
protocol = dlt645
protocol = dlt645,
len = 15
}).
%% Internal Header File

View File

@ -128,6 +128,18 @@
zh => <<"搜表模式:nosearch|quick|normal"/utf8>>
}
},
<<"len">> => #{
order => 3,
type => integer,
required => true,
default => 15,
title => #{
zh => <<"登录报文长度"/utf8>>
},
description => #{
zh => <<"登录报文长度,默认15位IEMI码"/utf8>>
}
},
<<"ico">> => #{
order => 102,
type => string,
@ -152,7 +164,7 @@ start(ChannelId, ChannelArgs) ->
init(?TYPE, ChannelId, #{
<<"port">> := Port,
<<"product">> := Products,
<<"search">> := Search}) ->
<<"search">> := Search} = Args) ->
lists:map(fun(X) ->
case X of
{ProductId, #{<<"ACL">> := Acl, <<"nodeType">> := 1, <<"thing">> := Thing}} ->
@ -186,9 +198,17 @@ init(?TYPE, ChannelId, #{
end
end, Products),
dgiot_data:set_consumer(ChannelId, 20),
Len =
case maps:find(<<"len">>, Args) of
error ->
15;
{ok, Len1} ->
Len1
end,
State = #state{
id = ChannelId,
search = Search
search = Search,
len = Len
},
{ok, State, dgiot_meter_tcp:start(Port, State)};

View File

@ -35,18 +35,13 @@ init(TCPState) ->
{ok, TCPState}.
%%
handle_info({tcp, Buff}, #tcp{socket = Socket, state = #state{id = ChannelId, dtuaddr = <<>>, search = Search} = State} = TCPState) ->
handle_info({tcp, Buff}, #tcp{socket = Socket, state = #state{id = ChannelId, dtuaddr = <<>>, search = Search, len = Len} = State} = TCPState) ->
DTUIP = dgiot_utils:get_ip(Socket),
NewBuff =
case is_binary(Buff) of
true -> dgiot_utils:binary_to_hex(Buff);
false -> Buff
end,
{DtuProductId, _, _} = dgiot_data:get({dtu, ChannelId}),
{Protocol, DtuAddr} =
case Buff of
<<16#68, _:4/bytes, 16#68, _A1:8/bytes, _Rest/binary>> ->
dgiot_bridge:send_log(ChannelId, "~s ~p DLT376 login ~p ", [?FILE, ?LINE, NewBuff]),
dgiot_bridge:send_log(ChannelId, "~s ~p DLT376 login ~p ", [?FILE, ?LINE, dgiot_utils:binary_to_hex(Buff)]),
{_, [Acc | _]} = dlt376_decoder:parse_frame(Buff, []), %% NewBuff
#{<<"msgtype">> := Protocol1, <<"con">> := Con, <<"addr">> := MeterAddr} = Acc,
Concentrator = maps:get(<<"concentrator">>, Acc, <<16#31, 16#07, 16#5F, 16#81, 16#00>>),
@ -69,6 +64,21 @@ handle_info({tcp, Buff}, #tcp{socket = Socket, state = #state{id = ChannelId, dt
dgiot_tcp_server:send(TCPState, Frame2),
{Protocol1, MeterAddr};
_ ->
BinBuff = dgiot_utils:binary_to_hex(Buff),
List = dgiot_utils:to_list(BinBuff),
List1 = dgiot_utils:to_list(Buff),
NewBuff =
case length(List) of
Len ->
BinBuff;
_ ->
case length(List1) of
Len ->
Buff;
_ ->
<<>>
end
end,
dgiot_bridge:send_log(ChannelId, "~s ~p DLT645 dtu login ~p", [?FILE, ?LINE, NewBuff]),
{?DLT645, NewBuff}
end,
@ -100,34 +110,39 @@ handle_info({tcp, Buff}, #tcp{socket = Socket, state = #state{id = ChannelId, dt
dgiot_metrics:inc(dgiot_meter, <<"dtu_online">>, 1),
{noreply, TCPState#tcp{buff = <<>>, register = true, clientid = DtuId, state = State#state{product = ProductId, dtuaddr = DtuAddr, protocol = ?DLT376, ref = NewRef, step = NewStep}}};
?DLT645 ->
dgiot_meter:create_dtu(DtuAddr, ChannelId, DTUIP),
{DtuProductId, _, _} = dgiot_data:get({dtu, ChannelId}),
%% $dg/device/{productId}/{deviceAddr}/profile
Topic = <<"$dg/device/", DtuProductId/binary, "/", DtuAddr/binary, "/profile">>,
dgiot_mqtt:subscribe(Topic),
{NewRef, NewStep} =
case Search of
<<"nosearch">> ->
lists:map(fun(X) ->
case X of
#{<<"product">> := #{<<"objectId">> := MeterProductid}, <<"devaddr">> := Meteraddr} ->
dgiot_bridge:send_log(ChannelId, MeterProductid, Meteraddr, "save taskque Meteraddr ~p", [Meteraddr]),
dgiot_task:save_pnque(DtuProductId, DtuAddr, MeterProductid, Meteraddr);
_ ->
pass
end
end, dgiot_meter:get_sub_device(DtuAddr)),
{undefined, read_meter};
<<"quick">> ->
dgiot_meter:search_meter(tcp, undefined, TCPState, 0),
{undefined, search_meter};
_ ->
{Ref, Step, _Payload} = dgiot_meter:search_meter(tcp, undefined, TCPState, 1),
{Ref, Step}
end,
DtuId = dgiot_parse_id:get_deviceid(DtuProductId, DtuAddr),
dgiot_metrics:inc(dgiot_meter, <<"dtu_online">>, 1),
{noreply, TCPState#tcp{buff = <<>>, register = true, clientid = DtuId, state = State#state{product = DtuProductId, dtuaddr = DtuAddr, protocol = ?DLT645, ref = NewRef, step = NewStep}}}
case DtuAddr of
<<>> ->
{noreply, TCPState#tcp{buff = <<>>}};
_->
dgiot_meter:create_dtu(DtuAddr, ChannelId, DTUIP),
{DtuProductId, _, _} = dgiot_data:get({dtu, ChannelId}),
%% $dg/device/{productId}/{deviceAddr}/profile
Topic = <<"$dg/device/", DtuProductId/binary, "/", DtuAddr/binary, "/profile">>,
dgiot_mqtt:subscribe(Topic),
{NewRef, NewStep} =
case Search of
<<"nosearch">> ->
lists:map(fun(X) ->
case X of
#{<<"product">> := #{<<"objectId">> := MeterProductid}, <<"devaddr">> := Meteraddr} ->
dgiot_bridge:send_log(ChannelId, MeterProductid, Meteraddr, "save taskque Meteraddr ~p", [Meteraddr]),
dgiot_task:save_pnque(DtuProductId, DtuAddr, MeterProductid, Meteraddr);
_ ->
pass
end
end, dgiot_meter:get_sub_device(DtuAddr)),
{undefined, read_meter};
<<"quick">> ->
dgiot_meter:search_meter(tcp, undefined, TCPState, 0),
{undefined, search_meter};
_ ->
{Ref, Step, _Payload} = dgiot_meter:search_meter(tcp, undefined, TCPState, 1),
{Ref, Step}
end,
DtuId = dgiot_parse_id:get_deviceid(DtuProductId, DtuAddr),
dgiot_metrics:inc(dgiot_meter, <<"dtu_online">>, 1),
{noreply, TCPState#tcp{buff = <<>>, register = true, clientid = DtuId, state = State#state{product = DtuProductId, dtuaddr = DtuAddr, protocol = ?DLT645, ref = NewRef, step = NewStep}}}
end
end;
%%