mirror of
https://gitee.com/dgiiot/dgiot.git
synced 2024-11-29 18:57:41 +08:00
fix: 修复modbus下发控制
This commit is contained in:
parent
7f1d042028
commit
2fda1eed7a
@ -177,6 +177,58 @@ oss_signature(VerB, Expire, Bucket, ObjectName) ->
|
||||
String = lists:concat([dgiot_utils:to_list(VerB), LineBreak, LineBreak, LineBreak, dgiot_utils:to_list(Expire), LineBreak, "/", dgiot_utils:to_list(Bucket), "/", dgiot_utils:to_list(ObjectName)]),
|
||||
http_uri:encode(dgiot_utils:to_list(base64:encode(crypto:hmac(sha, dgiot_utils:to_list(?AccessKeySecret), String)))).
|
||||
|
||||
jwtlogin(<<"yanshizhanghao">>) ->
|
||||
Md5Idtoken = dgiot_utils:to_md5(<<"yanshizhanghao">>),
|
||||
case dgiot_data:get({userinfo, Md5Idtoken}) of
|
||||
not_find ->
|
||||
State = #{
|
||||
<<"exp">> => 1640688171,
|
||||
<<"iat">> => 1640687571,
|
||||
<<"jti">> => <<"yanshizhanghao">>,
|
||||
<<"nbf">> => 1640687511,
|
||||
<<"sub">> => <<"yanshizhanghao">>,
|
||||
<<"name">> => <<"演示账号"/utf8>>,
|
||||
<<"ouId">> => null,
|
||||
<<"email">> => null,
|
||||
<<"mobile">> => <<"15873875357">>,
|
||||
<<"openId">> => null,
|
||||
<<"ouName">> => <<"演示账号"/utf8>>,
|
||||
<<"username">> => <<"yanshizhanghao">>,
|
||||
<<"externalId">> => <<"3309863849979079019">>,
|
||||
<<"instanceId">> => <<"test">>,
|
||||
<<"idpUsername">> => <<"yanshizhanghao">>,
|
||||
<<"aliyunDomain">> => <<"">>,
|
||||
<<"enterpriseId">> => <<"test">>,
|
||||
<<"extendFields">> => #{
|
||||
<<"orgNo">> => <<"yanshizhanghao">>,
|
||||
<<"zwwId">> => <<"yanshizhanghao">>,
|
||||
<<"orgType">> => <<"企业、农专社、个体工商户"/utf8>>,
|
||||
<<"uniscid">> => <<"yanshizhanghao">>,
|
||||
<<"userType">> => <<"法人"/utf8>>,
|
||||
<<"companyName">> => <<"演示账号"/utf8>>,
|
||||
<<"companyAddress">> => <<"浙江省杭州市余杭区良渚街道网周路99号3幢24层2418室"/utf8>>,
|
||||
<<"ZheLiBanLegalPersonSSOToken">> => <<"yanshizhanghao">>
|
||||
},
|
||||
<<"udAccountUuid">> => <<"82f280ae9935f80d5bb8bf8e2e94395ddRQgCWJLD26">>,
|
||||
<<"applicationName">> => <<"水泵远程检测"/utf8>>
|
||||
},
|
||||
UserInfo =
|
||||
case dgiot_parse_auth:login_by_account(<<"yanshizhanghao">>, <<"yanshizhanghao">>) of
|
||||
{ok, #{<<"objectId">> := _UserId} = UserInfo1} ->
|
||||
UserInfo1#{<<"code">> => 200, <<"msg">> => <<"operation success">>};
|
||||
{error, _Msg} ->
|
||||
#{<<"code">> => 200, <<"msg">> => <<"operation success">>}
|
||||
end,
|
||||
dgiot_data:insert({userinfo, Md5Idtoken}, {UserInfo#{<<"state">> => State}, <<"yanshizhanghao">>, <<"yanshizhanghao">>}),
|
||||
{ok, UserInfo#{<<"state">> => State}};
|
||||
{UserInfo2, Username2, UdAccountUuid2} ->
|
||||
case dgiot_parse_auth:login_by_account(Username2, UdAccountUuid2) of
|
||||
{ok, #{<<"objectId">> := _UserId} = UserInfo3} ->
|
||||
{ok, maps:merge(UserInfo2, UserInfo3)};
|
||||
{error, _Msg} ->
|
||||
{ok, UserInfo2}
|
||||
end
|
||||
end;
|
||||
|
||||
jwtlogin(Idtoken) ->
|
||||
Path = code:priv_dir(dgiot_http),
|
||||
|
@ -749,7 +749,7 @@ frame_write_param(#{<<"concentrator">> := ConAddr, <<"payload">> := Frame}) ->
|
||||
%% io:format("~s ~p SortFrame ~p.~n", [?FILE, ?LINE, Length]),
|
||||
{BitList, Afn, Da, Fn} =
|
||||
lists:foldl(fun(Index, {Acc, A, D, F}) ->
|
||||
case maps:find(dgiot_utils:to_binary(Index), Frame) of
|
||||
case maps:find(Index, Frame) of
|
||||
{ok, #{<<"value">> := Value, <<"dataSource">> := DataSource}} ->
|
||||
get_bitlist(Value, DataSource, Acc);
|
||||
_ ->
|
||||
|
@ -62,7 +62,7 @@
|
||||
%%|16 |写 |整型、字符型、状态字、浮点型 |
|
||||
%%——————————————————————————————————————————————
|
||||
|
||||
-record(rtu_req, {slaveId, funcode, address, registersnumber, dataByteSize, quality}).
|
||||
-record(rtu_req, {slaveId, funcode, address, registersnumber, dataByteSize, quality, data}).
|
||||
-record(rtu_pdu, {slaveId, funcode, dataByteSize, data}).
|
||||
-record(tcp_request, {sock, tid = 1, address = 1, function, start, data}).
|
||||
|
||||
|
21
apps/dgiot_modbus/priv/aaa.json
Normal file
21
apps/dgiot_modbus/priv/aaa.json
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
一、首先跳绳100个,然后做开合跳30次,燃烧全身脂肪这里选择开合跳,是因为它有三大好处在这里非常适用:
|
||||
1、它可以增强腿部肌肉运动能力:开合跳其实也是一种比较常用的热身运动,因为能够让全身的肌肉都在短时间内活跃起来,这样就能够大大的增强我们的运动能力,加强我们的跳绳训练。
|
||||
2、有效锻炼腹部肌肉。因为这种运动方式能够充分的调动身体的各项肌肉,让身体堆积的脂肪快速的进行燃烧。
|
||||
3、增强肌肉耐力。
|
||||
|
||||
二、再跳绳100个,做同侧提膝30次,减少侧腰顽固赘肉
|
||||
同侧提膝是一项非常高效的有氧运动,而且这项动作还是练就马甲线的必备动作之一,它可以减少侧腰上的顽固脂肪。
|
||||
|
||||
三、之后再跳绳100个,做胯下击掌20次,减少小肚子赘肉
|
||||
胯下击掌即高抬腿胯下击掌,是一种在家里就能减肥瘦身的健身动作,因此受到广大人群的喜爱,它可以锻炼到我们的腿部、腹部、臀部。
|
||||
1、腿部,胯下击掌在某种程度上是大腿带动小腿的运动,而且腿部只是不断重复拉伸和收缩动作,脚步不直接重重地落到地面,腿上的脂肪会变得很优美。
|
||||
2、腹部,也就是肚子,胯下击掌可以锻炼腹部,从而达到减少腹部脂肪堆积的效果。
|
||||
3、臀部,胯下击掌对臀部也有锻炼效果,最好配上改变饮食习惯,做全身的锻炼,不要想着练哪里就瘦哪里,脂肪就好比一个水缸,不管从哪里放水都是上边水的先没,上边就是四肢,下边才是臀部。
|
||||
|
||||
四、最后跳绳100个,然后做后踢腿30次,瘦腿燃脂后踢腿属于常见的有氧代谢运动,它有三个非常显著的优点:
|
||||
1、强化骨骼:适量的踢腿的练习,能够增强身体骨骼的柔韧程度。强化因为骨量下降而出现的骨质变差的问题。
|
||||
2、减脂塑形:踢腿运动能够提升基础代谢能力。坚持下来体内脂肪燃烧量大大提升,有助于保持苗条的身材。
|
||||
3、有助于长身高:经常性的进行后踢腿练习,能够帮助人体起到成果明显的增高功效。踢腿练习能够有效的刺激机体的骨骼进行进一步的生长以及发育。
|
||||
|
||||
所有动作循环四组,坚持一周没有效果,那只能说明你特殊,神仙来了都难解决。
|
@ -20,12 +20,20 @@
|
||||
|
||||
-behaviour(application).
|
||||
-include("dgiot_modbus.hrl").
|
||||
|
||||
-include_lib("dgiot_task/include/dgiot_task.hrl").
|
||||
%% Application callbacks
|
||||
-export([start/2, stop/1]).
|
||||
-export([start/2, stop/1, start_hook/0, stop_hook/0]).
|
||||
|
||||
start(_StartType, _StartArgs) ->
|
||||
start_hook(),
|
||||
dgiot_modbus_sup:start_link().
|
||||
|
||||
stop(_State) ->
|
||||
stop_hook(),
|
||||
ok.
|
||||
|
||||
start_hook() ->
|
||||
dgiot_hook:add(one_for_one, {?DGIOT_DATASOURCE, <<"MODBUSRTU">>}, fun modbus_rtu:get_datasource/1).
|
||||
|
||||
stop_hook() ->
|
||||
dgiot_hook:remove({?DGIOT_DATASOURCE, <<"MODBUSRTU">>}).
|
||||
|
@ -143,7 +143,7 @@ handle_info({deliver, _, Msg}, #tcp{state = #state{id = ChannelId} = State} = TC
|
||||
end;
|
||||
%% {stop, TCPState} | {stop, Reason} | {ok, TCPState} | ok | stop
|
||||
handle_info(_Info, TCPState) ->
|
||||
?LOG(info, "TCPState ~p", [TCPState]),
|
||||
%% ?LOG(info, "TCPState ~p", [TCPState]),
|
||||
{noreply, TCPState}.
|
||||
|
||||
handle_call(_Msg, _From, TCPState) ->
|
||||
|
@ -30,8 +30,6 @@
|
||||
-export([init/1, handle_info/2, handle_cast/2, handle_call/3, terminate/2, code_change/3]).
|
||||
|
||||
start(Port, State) ->
|
||||
|
||||
|
||||
dgiot_tcp_server:child_spec(?MODULE, dgiot_utils:to_int(Port), State).
|
||||
|
||||
%% =======================
|
||||
@ -108,7 +106,8 @@ handle_info({deliver, _, Msg}, #tcp{state = #state{id = ChannelId} = State} = TC
|
||||
case binary:split(Topic, <<$/>>, [global, trim]) of
|
||||
[<<"$dg">>, <<"device">>, ProductId, DevAddr, <<"profile">>] ->
|
||||
%% 设置参数
|
||||
Payloads = modbus_rtu:set_params(jsx:decode(Payload), ProductId, DevAddr),
|
||||
ProfilePayload = dgiot_device_profile:encode_profile(ProductId, jsx:decode(Payload)),
|
||||
Payloads = modbus_rtu:set_params(ProfilePayload, ProductId, DevAddr),
|
||||
lists:map(fun(X) ->
|
||||
dgiot_tcp_server:send(TCPState, X)
|
||||
end, Payloads),
|
||||
@ -132,7 +131,8 @@ handle_info({deliver, _, Msg}, #tcp{state = #state{id = ChannelId} = State} = TC
|
||||
case binary:split(Topic, <<$/>>, [global, trim]) of
|
||||
[<<"$dg">>, <<"device">>, ProductId, DevAddr, <<"profile">>] ->
|
||||
%% 设置参数
|
||||
Payloads = modbus_rtu:set_params(jsx:decode(Payload), ProductId, DevAddr),
|
||||
ProfilePayload = dgiot_device_profile:encode_profile(ProductId, jsx:decode(Payload)),
|
||||
Payloads = modbus_rtu:set_params(ProfilePayload, ProductId, DevAddr),
|
||||
lists:map(fun(X) ->
|
||||
dgiot_tcp_server:send(TCPState, X)
|
||||
end, Payloads),
|
||||
@ -143,7 +143,7 @@ handle_info({deliver, _, Msg}, #tcp{state = #state{id = ChannelId} = State} = TC
|
||||
end;
|
||||
%% {stop, TCPState} | {stop, Reason} | {ok, TCPState} | ok | stop
|
||||
handle_info(_Info, TCPState) ->
|
||||
?LOG(info, "TCPState ~p", [TCPState]),
|
||||
%% ?LOG(info, "TCPState ~p", [TCPState]),
|
||||
{noreply, TCPState}.
|
||||
|
||||
handle_call(_Msg, _From, TCPState) ->
|
||||
|
@ -27,7 +27,7 @@
|
||||
build_req_message/1]
|
||||
).
|
||||
|
||||
-export([modbus_encoder/4, modbus_decoder/5, is16/1, set_params/3, decode_data/5]).
|
||||
-export([modbus_encoder/4, modbus_decoder/5, is16/1, set_params/3, decode_data/5, get_datasource/1]).
|
||||
|
||||
-define(TYPE, ?MODBUS_RTU).
|
||||
|
||||
@ -144,50 +144,56 @@ init(State) ->
|
||||
%% {ok, State}.
|
||||
|
||||
to_frame(#{
|
||||
<<"data">> := Data,
|
||||
<<"registersnumber">> := Quality,
|
||||
<<"slaveid">> := SlaveId,
|
||||
<<"operatetype">> := Operatetype,
|
||||
<<"originaltype">> := Originaltype,
|
||||
<<"address">> := Address
|
||||
}) ->
|
||||
encode_data(Quality, Address, SlaveId, Operatetype);
|
||||
encode_data(Data, Quality, Address, SlaveId, Operatetype, Originaltype);
|
||||
|
||||
%%<<"cmd">> => Cmd,
|
||||
%%<<"gateway">> => DtuAddr,
|
||||
%%<<"addr">> => SlaveId,
|
||||
%%<<"di">> => Address
|
||||
to_frame(#{
|
||||
<<"data">> := Value,
|
||||
<<"data">> := Data,
|
||||
<<"registersnumber">> := Quality,
|
||||
<<"gateway">> := DtuAddr,
|
||||
<<"slaveid">> := SlaveId,
|
||||
<<"originaltype">> := Originaltype,
|
||||
<<"address">> := Address
|
||||
}) ->
|
||||
case dgiot_device:get_subdevice(DtuAddr, SlaveId) of
|
||||
not_find -> [];
|
||||
[ProductId, _DevAddr] ->
|
||||
encode_data(Value, Address, SlaveId, ProductId)
|
||||
encode_data(Data, Quality, Address, SlaveId, ProductId, Originaltype)
|
||||
end.
|
||||
|
||||
%% Quality 读的时候代表寄存器个数,16位的寄存器,一个寄存器表示两个字节,写的时候代表实际下发值
|
||||
encode_data(Quality, Address, SlaveId, OperateType) ->
|
||||
{FunCode, NewQuality} =
|
||||
encode_data(Data, Quality, Address, SlaveId, OperateType, Originaltype) ->
|
||||
FunCode =
|
||||
case OperateType of
|
||||
<<"readCoils">> -> {?FC_READ_COILS, dgiot_utils:to_int(Quality)};
|
||||
<<"readInputs">> -> {?FC_READ_INPUTS, dgiot_utils:to_int(Quality)};
|
||||
<<"readHregs">> -> {?FC_READ_HREGS, dgiot_utils:to_int(Quality)};
|
||||
<<"readIregs">> -> {?FC_READ_IREGS, dgiot_utils:to_int(Quality)};
|
||||
<<"writeCoil">> -> {?FC_WRITE_COIL, dgiot_utils:to_int(Quality)};
|
||||
<<"writeHreg">> -> {?FC_WRITE_HREG, dgiot_utils:to_int(Quality)}; %%需要校验,写多个线圈是什么状态
|
||||
<<"writeCoils">> -> {?FC_WRITE_COILS, dgiot_utils:to_int(Quality)};
|
||||
<<"writeHregs">> -> {?FC_WRITE_HREGS, dgiot_utils:to_int(Quality)}; %%需要校验,写多个保持寄存器是什么状态
|
||||
_ -> {?FC_READ_HREGS, dgiot_utils:to_int(dgiot_utils:to_int(Quality))}
|
||||
<<"readCoils">> -> ?FC_READ_COILS;
|
||||
<<"readInputs">> -> ?FC_READ_INPUTS;
|
||||
<<"readHregs">> -> ?FC_READ_HREGS;
|
||||
<<"readIregs">> -> ?FC_READ_IREGS;
|
||||
<<"writeCoil">> -> ?FC_WRITE_COIL;
|
||||
<<"writeHreg">> -> ?FC_WRITE_HREG; %%需要校验,写多个线圈是什么状态
|
||||
<<"writeCoils">> -> ?FC_WRITE_COILS;
|
||||
<<"writeHregs">> -> ?FC_WRITE_HREGS; %%需要校验,写多个保持寄存器是什么状态
|
||||
_ -> ?FC_READ_HREGS
|
||||
end,
|
||||
<<H:8, L:8>> = dgiot_utils:hex_to_binary(is16(Address)),
|
||||
<<Sh:8, Sl:8>> = dgiot_utils:hex_to_binary(is16(SlaveId)),
|
||||
NewQuality = dgiot_utils:to_int(get_len(Quality, Originaltype) / 2),
|
||||
RtuReq = #rtu_req{
|
||||
slaveId = Sh * 256 + Sl,
|
||||
funcode = dgiot_utils:to_int(FunCode),
|
||||
address = H * 256 + L,
|
||||
quality = NewQuality
|
||||
quality = NewQuality,
|
||||
data = dgiot_utils:to_int(Data)
|
||||
},
|
||||
build_req_message(RtuReq).
|
||||
|
||||
@ -211,7 +217,7 @@ set_params(Payload, _ProductId, _DevAddr) ->
|
||||
Length = length(maps:keys(Payload)),
|
||||
Payloads =
|
||||
lists:foldl(fun(Index, Acc) ->
|
||||
case maps:find(dgiot_utils:to_binary(Index), Payload) of
|
||||
case maps:find(Index, Payload) of
|
||||
{ok, #{
|
||||
<<"dataForm">> := #{
|
||||
<<"protocol">> := <<"MODBUSRTU">>,
|
||||
@ -219,7 +225,7 @@ set_params(Payload, _ProductId, _DevAddr) ->
|
||||
<<"dataSource">> := #{
|
||||
<<"slaveid">> := SlaveId,
|
||||
<<"address">> := Address,
|
||||
<<"bytes">> := Bytes,
|
||||
<<"originaltype">> := Originaltype,
|
||||
<<"operatetype">> := OperateType} = DataSource
|
||||
} = Data} ->
|
||||
case maps:find(<<"value">>, Data) of
|
||||
@ -246,6 +252,7 @@ set_params(Payload, _ProductId, _DevAddr) ->
|
||||
Value1 = dgiot_utils:to_int(dgiot_task:string2value(Str1, <<"type">>)),
|
||||
%% NewBt = Bytes * 8,
|
||||
Registersnumber = maps:get(<<"registersnumber">>, DataSource, <<"1">>),
|
||||
Bytes = get_len(Registersnumber, Originaltype),
|
||||
RtuReq = #rtu_req{
|
||||
slaveId = Sh * 256 + Sl,
|
||||
funcode = dgiot_utils:to_int(FunCode),
|
||||
@ -315,7 +322,7 @@ parse_frame(<<SlaveId:8, _/binary>> = Buff, Acc, #{<<"dtuaddr">> := DtuAddr, <<"
|
||||
end;
|
||||
%rtu modbus
|
||||
parse_frame(_Other, Acc, _State) ->
|
||||
?LOG(error, "_Other ~p", [_Other]),
|
||||
%% ?LOG(error, "_Other ~p", [_Other]),
|
||||
{error, Acc}.
|
||||
|
||||
decode_data(Buff, ProductId, DtuAddr, Address, Acc) ->
|
||||
@ -424,7 +431,7 @@ build_req_message(Req) when is_record(Req, rtu_req) ->
|
||||
ByteCount = length(binary_to_list(ValuesBin)),
|
||||
<<(Req#rtu_req.slaveId):8, (Req#rtu_req.funcode):8, (Req#rtu_req.address):16, Quantity:16, ByteCount:8, ValuesBin/binary>>;
|
||||
?FC_WRITE_HREG ->
|
||||
ValueBin = list_word16_to_binary([Req#rtu_req.quality]),
|
||||
ValueBin = list_word16_to_binary([Req#rtu_req.data]),
|
||||
<<(Req#rtu_req.slaveId):8, (Req#rtu_req.funcode):8, (Req#rtu_req.address):16, ValueBin/binary>>;
|
||||
?FC_WRITE_HREGS ->
|
||||
%% ValuesBin = list_word16_to_binary(Req#rtu_req.quality),
|
||||
@ -737,34 +744,41 @@ format_value(_, #{<<"identifier">> := Field}, _Props) ->
|
||||
|
||||
%% 获取寄存器字节长度
|
||||
get_len(IntNum, <<"short16_AB">>) ->
|
||||
IntNum * 2;
|
||||
dgiot_utils:to_int(IntNum) * 2;
|
||||
|
||||
get_len(IntNum, <<"short16_BA">>) ->
|
||||
IntNum * 2;
|
||||
dgiot_utils:to_int(IntNum) * 2;
|
||||
|
||||
get_len(IntNum, <<"ushort16_AB">>) ->
|
||||
IntNum * 2;
|
||||
dgiot_utils:to_int(IntNum) * 2;
|
||||
|
||||
get_len(IntNum, <<"ushort16_BA">>) ->
|
||||
IntNum * 2;
|
||||
dgiot_utils:to_int(IntNum) * 2;
|
||||
|
||||
get_len(IntNum, <<"long32_ABCD">>) ->
|
||||
IntNum * 4;
|
||||
dgiot_utils:to_int(IntNum) * 4;
|
||||
|
||||
get_len(IntNum, <<"long32_CDAB">>) ->
|
||||
IntNum * 4;
|
||||
dgiot_utils:to_int(IntNum) * 4;
|
||||
|
||||
get_len(IntNum, <<"ulong32_ABCD">>) ->
|
||||
IntNum * 4;
|
||||
dgiot_utils:to_int(IntNum) * 4;
|
||||
|
||||
get_len(IntNum, <<"ulong32_CDAB">>) ->
|
||||
IntNum * 4;
|
||||
dgiot_utils:to_int(IntNum) * 4;
|
||||
|
||||
get_len(IntNum, <<"float32_ABCD">>) ->
|
||||
IntNum * 4;
|
||||
dgiot_utils:to_int(IntNum) * 4;
|
||||
|
||||
get_len(IntNum, <<"float32_CDAB">>) ->
|
||||
IntNum * 4;
|
||||
dgiot_utils:to_int(IntNum) * 4;
|
||||
|
||||
get_len(IntNum, _Originaltype) ->
|
||||
IntNum * 2.
|
||||
dgiot_utils:to_int(IntNum) * 2.
|
||||
|
||||
|
||||
get_datasource(#{<<"operatetype">> := <<"writeHreg">>, <<"data">> := Data} = DataSource) ->
|
||||
DataSource#{<<"data">> => Data};
|
||||
|
||||
get_datasource(DataSource) ->
|
||||
DataSource.
|
||||
|
@ -216,7 +216,7 @@ set_params(Payload, _ProductId, _DevAddr) ->
|
||||
Length = length(maps:keys(Payload)),
|
||||
Payloads =
|
||||
lists:foldl(fun(Index, Acc) ->
|
||||
case maps:find(dgiot_utils:to_binary(Index), Payload) of
|
||||
case maps:find(Index, Payload) of
|
||||
{ok, #{
|
||||
<<"dataForm">> := #{
|
||||
<<"protocol">> := <<"MODBUSTCP">>,
|
||||
|
Loading…
Reference in New Issue
Block a user