mirror of
https://gitee.com/dgiiot/dgiot.git
synced 2024-12-04 21:27:39 +08:00
fix: modbus_decoder
This commit is contained in:
parent
95368fafd5
commit
f8589991f5
@ -461,8 +461,7 @@ modbus_tcp_decoder(ProductId, TransactionId, Address, Data, Acc1) ->
|
||||
NewAddress = Sh * 256 + Sl,
|
||||
case {TransactionId, Address} of
|
||||
{NewSlaveid, NewAddress} ->
|
||||
%% case format_value(Data, X, Props) of
|
||||
case format_value(Data, X) of
|
||||
case format_value(Data, X, Props) of
|
||||
{Value, _Rest} ->
|
||||
Acc#{Identifier => Value};
|
||||
{map, Value, _Rest} ->
|
||||
@ -486,20 +485,24 @@ modbus_decoder(ProductId, SlaveId, Address, Data, Acc1) ->
|
||||
case X of
|
||||
#{<<"identifier">> := Identifier,
|
||||
<<"dataForm">> := #{
|
||||
<<"strategy">> := Strategy,
|
||||
<<"slaveid">> := OldSlaveid,
|
||||
<<"address">> := OldAddress,
|
||||
<<"protocol">> := <<"modbus">>
|
||||
}} ->
|
||||
}} when Strategy =/= <<"计算值"/utf8>> ->
|
||||
<<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 {SlaveId, Address} of
|
||||
{NewSlaveid, NewAddress} ->
|
||||
case format_value(Data, X) of
|
||||
case format_value(Data, X, Props) of
|
||||
{map, Value} ->
|
||||
maps:merge(Acc, Value);
|
||||
{Value, _Rest} ->
|
||||
Acc#{Identifier => Value};
|
||||
_ -> Acc
|
||||
_A ->
|
||||
Acc
|
||||
end;
|
||||
_ ->
|
||||
Acc
|
||||
@ -540,30 +543,64 @@ modbus_encoder(ProductId, SlaveId, Address, Value) ->
|
||||
%% 0x78 | 0x56 | 0x34 | 0x12
|
||||
|
||||
format_value(Buff, #{
|
||||
<<"dataType">> := #{<<"type">> := <<"geopoint">>, <<"gpstype">> := <<"NMEA0183">>}}) ->
|
||||
<<"dataType">> := #{<<"type">> := <<"geopoint">>, <<"gpstype">> := <<"NMEA0183">>}}, _Props) ->
|
||||
{Longitude, Latitude} = dgiot_gps:nmea0183_frame(Buff),
|
||||
{<<Longitude/binary, "_", Latitude/binary>>, <<"Rest">>};
|
||||
|
||||
format_value(Buff, #{
|
||||
<<"accessMode">> := <<"rw">>,
|
||||
<<"dataForm">> := DataForm} = X) ->
|
||||
<<"dataForm">> := DataForm} = X, _Props) ->
|
||||
format_value(Buff, X#{<<"accessMode">> => <<"r">>,
|
||||
<<"dataForm">> => DataForm#{<<"data">> => byte_size(Buff)}
|
||||
});
|
||||
}, _Props);
|
||||
|
||||
format_value(Buff, #{<<"dataForm">> := #{
|
||||
<<"data">> := Len,
|
||||
<<"originaltype">> := <<"bit">>
|
||||
}}) ->
|
||||
IntLen = dgiot_utils:to_int(Len),
|
||||
Size = max(2, IntLen) * 8,
|
||||
<<Value:Size, Rest/binary>> = Buff,
|
||||
{Value, Rest};
|
||||
format_value(Buff, #{<<"identifier">> := BitIdentifier,
|
||||
<<"dataForm">> := #{
|
||||
<<"originaltype">> := <<"bit">>
|
||||
}}, Props) ->
|
||||
Values =
|
||||
lists:foldl(fun(X, Acc) ->
|
||||
case X of
|
||||
#{<<"identifier">> := Identifier,
|
||||
<<"dataForm">> := #{
|
||||
<<"slaveid">> := BitIdentifier,
|
||||
<<"address">> := Offset,
|
||||
<<"data">> := Len,
|
||||
<<"protocol">> := <<"modbus">>,
|
||||
<<"strategy">> := <<"计算值"/utf8>>
|
||||
}} ->
|
||||
IntOffset = dgiot_utils:to_int(Offset),
|
||||
IntLen = dgiot_utils:to_int(Len),
|
||||
Value =
|
||||
case IntOffset of
|
||||
0 ->
|
||||
<<V:IntLen/binary, _/binary>> = Buff,
|
||||
case format_value(V, X, Props) of
|
||||
{Value1, _Rest} ->
|
||||
Value1;
|
||||
_ ->
|
||||
V
|
||||
end;
|
||||
_ ->
|
||||
<<_:IntOffset/binary, V:IntLen/binary, _/binary>> = Buff,
|
||||
case format_value(V, X, Props) of
|
||||
{Value1, _Rest} ->
|
||||
Value1;
|
||||
_ ->
|
||||
V
|
||||
end
|
||||
end,
|
||||
Acc#{Identifier => Value};
|
||||
_ ->
|
||||
Acc
|
||||
end
|
||||
end, #{}, Props),
|
||||
{map, Values};
|
||||
|
||||
format_value(Buff, #{<<"dataForm">> := #{
|
||||
<<"data">> := Len,
|
||||
<<"originaltype">> := <<"short16_AB">>
|
||||
}}) ->
|
||||
}}, _Props) ->
|
||||
IntLen = dgiot_utils:to_int(Len),
|
||||
Size = max(2, IntLen) * 8,
|
||||
<<Value:Size/signed-big-integer, Rest/binary>> = Buff,
|
||||
@ -572,7 +609,7 @@ format_value(Buff, #{<<"dataForm">> := #{
|
||||
format_value(Buff, #{<<"dataForm">> := #{
|
||||
<<"data">> := Len,
|
||||
<<"originaltype">> := <<"short16_BA">>
|
||||
}}) ->
|
||||
}}, _Props) ->
|
||||
IntLen = dgiot_utils:to_int(Len),
|
||||
Size = max(2, IntLen) * 8,
|
||||
<<Value:Size/signed-little-integer, Rest/binary>> = Buff,
|
||||
@ -581,7 +618,7 @@ format_value(Buff, #{<<"dataForm">> := #{
|
||||
format_value(Buff, #{<<"dataForm">> := #{
|
||||
<<"data">> := Len,
|
||||
<<"originaltype">> := <<"ushort16_AB">>
|
||||
}}) ->
|
||||
}}, _Props) ->
|
||||
IntLen = dgiot_utils:to_int(Len),
|
||||
Size = max(2, IntLen) * 8,
|
||||
<<Value:Size/unsigned-big-integer, Rest/binary>> = Buff,
|
||||
@ -590,7 +627,7 @@ format_value(Buff, #{<<"dataForm">> := #{
|
||||
format_value(Buff, #{<<"dataForm">> := #{
|
||||
<<"data">> := Len,
|
||||
<<"originaltype">> := <<"ushort16_BA">>
|
||||
}}) ->
|
||||
}}, _Props) ->
|
||||
IntLen = dgiot_utils:to_int(Len),
|
||||
Size = max(2, IntLen) * 8,
|
||||
<<Value:Size/unsigned-little-integer, Rest/binary>> = Buff,
|
||||
@ -599,7 +636,7 @@ format_value(Buff, #{<<"dataForm">> := #{
|
||||
format_value(Buff, #{<<"dataForm">> := #{
|
||||
<<"data">> := Len,
|
||||
<<"originaltype">> := <<"long32_ABCD">>
|
||||
}}) ->
|
||||
}}, _Props) ->
|
||||
IntLen = dgiot_utils:to_int(Len),
|
||||
Size = max(4, IntLen) * 8,
|
||||
<<H:2/binary, L:2/binary, Rest/binary>> = Buff,
|
||||
@ -609,7 +646,7 @@ format_value(Buff, #{<<"dataForm">> := #{
|
||||
format_value(Buff, #{<<"dataForm">> := #{
|
||||
<<"data">> := Len,
|
||||
<<"originaltype">> := <<"long32_CDAB">>
|
||||
}}) ->
|
||||
}}, _Props) ->
|
||||
IntLen = dgiot_utils:to_int(Len),
|
||||
Size = max(4, IntLen) * 8,
|
||||
<<H:2/binary, L:2/binary, Rest/binary>> = Buff,
|
||||
@ -619,7 +656,7 @@ format_value(Buff, #{<<"dataForm">> := #{
|
||||
format_value(Buff, #{<<"dataForm">> := #{
|
||||
<<"data">> := Len,
|
||||
<<"originaltype">> := <<"ulong32_ABCD">>
|
||||
}}) ->
|
||||
}}, _Props) ->
|
||||
IntLen = dgiot_utils:to_int(Len),
|
||||
Size = max(4, IntLen) * 8,
|
||||
<<H:2/binary, L:2/binary, Rest/binary>> = Buff,
|
||||
@ -629,7 +666,7 @@ format_value(Buff, #{<<"dataForm">> := #{
|
||||
format_value(Buff, #{<<"dataForm">> := #{
|
||||
<<"data">> := Len,
|
||||
<<"originaltype">> := <<"ulong32_CDAB">>
|
||||
}}) ->
|
||||
}}, _Props) ->
|
||||
IntLen = dgiot_utils:to_int(Len),
|
||||
Size = max(4, IntLen) * 8,
|
||||
<<H:2/binary, L:2/binary, Rest/binary>> = Buff,
|
||||
@ -639,7 +676,7 @@ format_value(Buff, #{<<"dataForm">> := #{
|
||||
format_value(Buff, #{<<"dataForm">> := #{
|
||||
<<"data">> := Len,
|
||||
<<"originaltype">> := <<"float32_ABCD">>
|
||||
}}) ->
|
||||
}}, _Props) ->
|
||||
IntLen = dgiot_utils:to_int(Len),
|
||||
Size = max(4, IntLen) * 8,
|
||||
<<H:2/binary, L:2/binary, Rest/binary>> = Buff,
|
||||
@ -649,7 +686,7 @@ format_value(Buff, #{<<"dataForm">> := #{
|
||||
format_value(Buff, #{<<"dataForm">> := #{
|
||||
<<"data">> := Len,
|
||||
<<"originaltype">> := <<"float32_CDAB">>
|
||||
}}) ->
|
||||
}}, _Props) ->
|
||||
IntLen = dgiot_utils:to_int(Len),
|
||||
Size = max(4, IntLen) * 8,
|
||||
<<H:2/binary, L:2/binary, Rest/binary>> = Buff,
|
||||
@ -657,6 +694,6 @@ format_value(Buff, #{<<"dataForm">> := #{
|
||||
{Value, Rest};
|
||||
|
||||
%% @todo 其它类型处理
|
||||
format_value(_, #{<<"identifier">> := Field}) ->
|
||||
format_value(_, #{<<"identifier">> := Field}, _Props) ->
|
||||
?LOG(info, "Field ~p", [Field]),
|
||||
throw({field_error, <<Field/binary, " is not validate">>}).
|
||||
|
@ -114,7 +114,7 @@ handle_message({sync_parse, Args, ObjectId}, State) ->
|
||||
#{<<"profile">> := _Profile, <<"devaddr">> := _Devaddr, <<"product">> := #{<<"objectId">> := _ProductId}} ->
|
||||
handle_message({sync_parse, Args}, State);
|
||||
#{<<"profile">> := Profile} ->
|
||||
io:format("~s ~p ObjectId = ~p.~n", [?FILE, ?LINE, ObjectId]),
|
||||
%% io:format("~s ~p ObjectId = ~p.~n", [?FILE, ?LINE, ObjectId]),
|
||||
case dgiot_device:lookup(dgiot_utils:to_binary(ObjectId)) of
|
||||
{ok, #{<<"devaddr">> := Devaddr, <<"productid">> := ProductId}} ->
|
||||
NewArgs = jsx:encode(#{<<"profile">> => Profile, <<"devaddr">> => Devaddr, <<"product">> => #{<<"objectId">> => ProductId}}),
|
||||
@ -133,7 +133,7 @@ handle_message({sync_parse, Args, ObjectId}, State) ->
|
||||
end;
|
||||
|
||||
handle_message({sync_parse, Args}, State) ->
|
||||
io:format("~s ~p Args = ~p.~n", [?FILE, ?LINE, jsx:decode(Args, [{labels, binary}, return_maps])]),
|
||||
%% io:format("~s ~p Args = ~p.~n", [?FILE, ?LINE, jsx:decode(Args, [{labels, binary}, return_maps])]),
|
||||
case jsx:decode(Args, [{labels, binary}, return_maps]) of
|
||||
#{<<"profile">> := Profile, <<"devaddr">> := Devaddr, <<"product">> := #{<<"objectId">> := ProductId}} = Arg ->
|
||||
Sessiontoken = maps:get(<<"sessiontoken">>, Arg, <<"">>),
|
||||
|
@ -146,7 +146,7 @@ handle_info(retry, State) ->
|
||||
handle_info({deliver, _, Msg}, #task{tid = Channel, dis = Dis, product = ProductId, devaddr = DevAddr, ack = Ack, que = Que} = State) when length(Que) == 0 ->
|
||||
Payload = jsx:decode(dgiot_mqtt:get_payload(Msg), [return_maps]),
|
||||
dgiot_bridge:send_log(Channel, ProductId, DevAddr, "~s ~p ~ts: ~ts ", [?FILE, ?LINE, unicode:characters_to_list(dgiot_mqtt:get_topic(Msg)), unicode:characters_to_list(dgiot_mqtt:get_payload(Msg))]),
|
||||
NewAck = dgiot_task:get_collection(ProductId, Dis, Payload, Ack),
|
||||
NewAck = dgiot_task:get_collection(ProductId, Dis, Payload, maps:merge(Ack, Payload)),
|
||||
dgiot_metrics:inc(dgiot_task, <<"task_recv">>, 1),
|
||||
{noreply, get_next_pn(State#task{ack = NewAck})};
|
||||
|
||||
@ -246,8 +246,8 @@ save_td(#task{app = _App, tid = Channel, product = ProductId, devaddr = DevAddr,
|
||||
0 ->
|
||||
pass;
|
||||
_ ->
|
||||
dgiot_bridge:send_log(Channel, ProductId, DevAddr, "save_td=> ~s ~p ~p: ~ts ", [?FILE, ?LINE, ProductId, unicode:characters_to_list(jsx:encode(Ack))]),
|
||||
Data = dgiot_task:get_calculated(ProductId, Ack),
|
||||
dgiot_bridge:send_log(Channel, ProductId, DevAddr, "save_td=> ~s ~p ~p: ~ts ", [?FILE, ?LINE, ProductId, unicode:characters_to_list(jsx:encode(Data))]),
|
||||
case length(maps:to_list(Data)) of
|
||||
0 ->
|
||||
pass;
|
||||
|
Loading…
Reference in New Issue
Block a user