feat: add gb26875

This commit is contained in:
U-JOHNLIU\jonhl 2022-03-07 18:08:18 +08:00
parent a5ecc007b0
commit 497f375f2c
9 changed files with 336 additions and 278 deletions

View File

@ -20,7 +20,7 @@
-include_lib("dgiot/include/logger.hrl").
-export([
create_amis/3,
put_amis_device/3,
put_amis_device/2,
del_amis_device/1,
created_amis_device/3
]).
@ -29,7 +29,7 @@
del_amis_device(DeviceId) ->
dgiot_device:delete(DeviceId).
%%
put_amis_device(put_amis_device, #{<<"objectId">> := Deviceid} = Body, SessionToken) ->
put_amis_device( #{<<"objectId">> := Deviceid} = Body, SessionToken) ->
case dgiot_parse:get_object(<<"Device">>, Deviceid,
[{"X-Parse-Session-Token", SessionToken}], [{from, rest}]) of
{ok, #{<<"data">> := OldRole}} ->

View File

@ -115,9 +115,9 @@ do_request(get_amis_device, #{<<"deviceid">> := Deviceid}, _Context, _Req) ->
%% Role模版 : amis设备
%% OperationId:put_amis_device
%% :POST /iotapi/put_amis_device
do_request(put_amis_device, #{<<"objectId">> := Deviceid} = _Body,_Context, _Req0) ->
do_request(put_amis_device, Body, #{<<"sessionToken">> := SessionToken}, _Req0) ->
%% io:format("Body ~p~n", [Body]),
case dgiot_bamis:put_amis_device(Deviceid) of
case dgiot_bamis:put_amis_device(Body, SessionToken) of
{ok, Info} ->
{ok, Info};
_ ->

View File

@ -11,3 +11,6 @@
+ GB 26875.7-2015 城市消防远程监控系统 第7部分消防设施维护管理软件功能要求
+ GB 26875.8-2015 城市消防远程监控系统 第8部分监控中心对外数据交换协议
### 控制命令流程示意图

View File

@ -2,15 +2,10 @@
-record(state, {
id,
devaddr = <<>>,
heartcount = 0,
regtype = <<>>,
head = "xxxxxx0eee",
len = 0,
app = <<>>,
product = <<>>,
deviceId = <<>>,
scale = 10,
temperature = 0,
env = <<>>,
dtutype = <<>>
}).
@ -19,7 +14,7 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
-define(COMMAND_RESERVED, 0). %
-define(COMMAND_RESERVED(Name), lists:member(Name, [0 |lists:seq(7, 127)]). %
-define(COMMAND_CONTROL, 1). %
-define(COMMAND_SEND_DATA, 2). %
-define(COMMAND_CONFIRM, 3). %
@ -29,12 +24,25 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 8.1.1
-define(TYPE_RESERVED(Name), lists:member(Name, [0 |lists:seq(26, 29)| lists:seq(45, 49)| lists:seq(54, 59)| lists:seq(63, 68)| lists:seq(70, 73)| lists:seq(75, 77)])). %
-define(TYPE_UP_SYSTEM_STATE, 1). % 8211 4,
-define(TYPE_UP_RUNNING_STATUS, 2). %
-define(TYPE_UP_ANALOG_QUANTITY, 3). %
-define(TYPE_UP_OPERATING_INFORMATION, 4). %
-define(TYPE_UP_SOFTWARE_VERSION, 5). %
-define(TYPE_UP_SYSTEM_CONFIGURATION, 6). %
-define(TYPE_UP_PARTS_CONFIGURATION, 7). %
-define(TYPE_UP_SYSTEM_TIME, 8). %
%% l字节二进制数02553
-define(CLASS_UP_SYSTEM_STATE, 1). % 8211 4,
-define(CLASS_UP_RUNNING_STATUS, 2). %
-define(CLASS_UP_ANALOG_QUANTITY, 3). %
-define(CLASS_UP_OPERATING_INFORMATION, 4). %
-define(CLASS_UP_SOFTWARE_VERSION, 5). %
-define(CLASS_UP_SYSTEM_CONFIGURATION, 6). %
-define(CLASS_UP_PARTS_CONFIGURATION, 7). %
-define(CLASS_UP_SYSTEM_TIME, 8). %
-define(CLASS_UP_RESERVED(Name), lists:member(Name, [22, 23, 27 | lists:seq(9, 20)] | lists:seq(29, 60)] ).
-define(CLASS_UP_USERDEV_RUNINFO, 21). %
-define(CLASS_UP_USERDEV_OPINFO, 24). %
-define(CLASS_UP_USERDEV_SOFTVER, 25). %
-define(CLASS_UP_USERDEV_CONFIG, 26). %
-define(CLASS_UP_USERDEV_SYSTIME, 28). %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 8211
%%
-define(SYS_TYPE_COMMOM , 0). %
-define(SYS_TYPE_FIRE_ALARM, 0). %

View File

@ -19,7 +19,7 @@
-include_lib("dgiot_bridge/include/dgiot_bridge.hrl").
-include("dgiot_gb26875.hrl").
-include_lib("dgiot/include/logger.hrl").
-define(TYPE, <<"GB26875">>).
-define(TYPE, <<"gb26875">>).
%% API
-export([start/2]).
@ -31,10 +31,10 @@
cType => ?TYPE,
type => ?PROTOCOL_CHL,
title => #{
zh => <<"GB26875采集通道"/utf8>>
zh => <<"GB26875"/utf8>>
},
description => #{
zh => <<"GB26875采集通道"/utf8>>
zh => <<"gb26875"/utf8>>
}
}).
%%
@ -43,7 +43,7 @@
order => 1,
type => integer,
required => true,
default => 20110,
default => 7533,
title => #{
zh => <<"端口"/utf8>>
},
@ -51,47 +51,23 @@
zh => <<"侦听端口"/utf8>>
}
},
<<"regtype">> => #{
<<"dtutype">> => #{
order => 2,
type => string,
required => true,
default => <<"上传Mac"/utf8>>,
default => <<"消防电子"/utf8>>,
title => #{
zh => <<"注册类型"/utf8>>
zh => <<"消防电子"/utf8>>
},
description => #{
zh => <<"上传Mac"/utf8>>
}
},
<<"regular">> => #{
order => 3,
type => string,
required => true,
default => <<"9C-A5-25-**-**-**">>,
title => #{
zh => <<"登录报文帧头"/utf8>>
},
description => #{
zh => <<"填写正则表达式匹配login"/utf8>>
}
},
<<"dtutype">> => #{
order => 4,
type => string,
required => true,
default => <<"usr">>,
title => #{
zh => <<"控制器厂商"/utf8>>
},
description => #{
zh => <<"控制器厂商"/utf8>>
zh => <<"消防电子"/utf8>>
}
},
<<"ico">> => #{
order => 102,
type => string,
required => false,
default => <<"http://dgiot-1253666439.cos.ap-shanghai-fsi.myqcloud.com/shuwa_tech/zh/product/dgiot/channel/GB26875.png">>,
default => <<"http://dgiot-1253666439.cos.ap-shanghai-fsi.myqcloud.com/shuwa_tech/zh/product/dgiot/channel/modbus.png">>,
title => #{
en => <<"channel ICO">>,
zh => <<"通道ICO"/utf8>>
@ -109,24 +85,17 @@ start(ChannelId, ChannelArgs) ->
%%
init(?TYPE, ChannelId, #{
<<"port">> := Port,
<<"regtype">> := Type,
<<"regular">> := Regular,
<<"product">> := Products,
<<"dtutype">> := Dtutype
} = _Args) ->
[{ProdcutId, App} | _] = get_app(Products),
{Header, Len} = get_header(Regular),
State = #state{
id = ChannelId,
regtype = Type,
head = Header,
len = Len,
app = App,
product = ProdcutId,
dtutype = Dtutype
},
%% dgiot_data:insert({ChannelId, heartbeat}, {Heartbeat, Port}),
{ok, State, dgiot_gb26875_tcp:start(Port, State)};
init(?TYPE, _ChannelId, _Args) ->
@ -172,14 +141,3 @@ get_app(Products) ->
{ProdcutId, App}
end, Products).
get_header(Regular) ->
lists:foldl(fun(X, {Header, Len}) ->
case X of
"**" -> {Header, Len + length(X)};
"*" -> {Header, Len + length(X)};
_ -> {Header ++ X, Len + length(X)}
end
end, {[], 0},
re:split(dgiot_utils:to_list(Regular), "-", [{return, list}])).

View File

@ -32,11 +32,6 @@
start(Port, State) ->
dgiot_tcp_server:child_spec(?MODULE, dgiot_utils:to_int(Port), State).
%% =======================
%% {ok, State} | {stop, Reason}
%%init(TCPState) ->
%% erlang:send_after(5 * 1000, self(), login),.
%% {ok, TCPState}.
init(#tcp{state = #state{id = ChannelId}} = TCPState) ->
?LOG(info, "ChannelId ~p", [ChannelId]),
@ -47,53 +42,25 @@ init(#tcp{state = #state{id = ChannelId}} = TCPState) ->
{stop, not_find_channel}
end.
%% 9C A5 25 CD 00 DB
%% 11 04 02 06 92 FA FE
handle_info({tcp, Buff}, #tcp{socket = Socket, state = #state{id = ChannelId, devaddr = <<>>, head = Head, len = Len, product = ProductId, dtutype = Dtutype} = State} = TCPState) ->
dgiot_bridge:send_log(ChannelId, "DTU revice from ~p", [dgiot_utils:binary_to_hex(Buff)]),
DTUIP = dgiot_utils:get_ip(Socket),
DtuAddr = dgiot_utils:binary_to_hex(Buff),
List = dgiot_utils:to_list(DtuAddr),
List1 = dgiot_utils:to_list(Buff),
#{<<"objectId">> := DeviceId} =
dgiot_parse:get_objectid(<<"Device">>, #{<<"product">> => ProductId, <<"devaddr">> => DtuAddr}),
case re:run(DtuAddr, Head, [{capture, first, list}]) of
{match, [Head]} when length(List) == Len ->
{DevId, Devaddr} =
case create_device(DeviceId, ProductId, DtuAddr, DTUIP, Dtutype) of
{<<>>, <<>>} ->
{<<>>, <<>>};
{DevId1, Devaddr1} ->
{DevId1, Devaddr1}
end,
{noreply, TCPState#tcp{buff = <<>>, state = State#state{devaddr = Devaddr, deviceId = DevId}}};
_Error ->
case re:run(Buff, Head, [{capture, first, list}]) of
{match, [Head]} when length(List1) == Len ->
create_device(DeviceId, ProductId, Buff, DTUIP, Dtutype),
{noreply, TCPState#tcp{buff = <<>>, state = State#state{devaddr = Buff}}};
Error1 ->
?LOG(info, "Error1 ~p Buff ~p ", [Error1, dgiot_utils:to_list(Buff)]),
{noreply, TCPState#tcp{buff = <<>>}}
end
end;
%% 3D302E30303030203D302E303030303530303138200D0A
handle_info({tcp, Buff}, #tcp{state = #state{id = ChannelId, devaddr = _DevAddr, product = _ProductId} = State} = TCPState) ->
dgiot_bridge:send_log(ChannelId, "revice from ~p", [Buff]),
dgiot_bridge:send_log(ChannelId, "revice from ~p", [dgiot_utils:binary_to_hex(Buff)]),
io:format("revice from Buff ~p ~n", [dgiot_utils:binary_to_hex(Buff)]),
case dgiot_gb26875_decoder:parse_frame(Buff, State) of
{ok, #{<<"ack">> := Ack} = _Result} ->
dgiot_tcp_server:send(TCPState, Ack);
{ok, Result} ->
io:format("Result ~p~n", [Result]),
dgiot_bridge:send_log(ChannelId, "parse_frame Buff ~p", [Result]),
R = dgiot_gb26875_decoder:to_frame(Result),
case R =:= Buff of
true ->
io:format("success to_frame Buff ~p~n", [Buff]),
dgiot_bridge:send_log(ChannelId, "success to_frame Buff ~p", [Buff]);
_ ->
io:format("error to_frame R ~p~n", [R]),
dgiot_bridge:send_log(ChannelId, "error to_frame Buff ~p", [R])
end;
io:format("revice from Buff ~p ~n", [dgiot_utils:binary_to_hex(Buff)]),
io:format("Result ~p ~n", [Result]),
dgiot_bridge:send_log(ChannelId, "parse_frame Buff ~p", [Result]);
%% R = dgiot_gb26875_decoder:to_frame(Result),
%% case R =:= Buff of
%% true ->
%% io:format("success to_frame Buff ~p~n", [Buff]),
%% dgiot_bridge:send_log(ChannelId, "success to_frame Buff ~p", [Buff]);
%% _ ->
%% io:format("error to_frame R ~p~n", [R]),
%% dgiot_bridge:send_log(ChannelId, "error to_frame Buff ~p", [R])
%% end;
_ ->
pass
end,
@ -123,55 +90,3 @@ get_deviceid(ProdcutId, DevAddr) ->
#{<<"objectId">> := DeviceId} =
dgiot_parse:get_objectid(<<"Device">>, #{<<"product">> => ProdcutId, <<"devaddr">> => DevAddr}),
DeviceId.
create_device(DeviceId, ProductId, DTUMAC, DTUIP, Dtutype) ->
case dgiot_parse:get_object(<<"Product">>, ProductId) of
{ok, #{<<"ACL">> := Acl, <<"devType">> := DevType}} ->
case dgiot_parse:get_object(<<"Device">>, DeviceId) of
{ok, #{<<"devaddr">> := _GWAddr}} ->
dgiot_parse:update_object(<<"Device">>, DeviceId, #{<<"ip">> => DTUIP, <<"status">> => <<"ONLINE">>});
_ ->
dgiot_device:create_device(#{
<<"devaddr">> => DTUMAC,
<<"name">> => <<Dtutype/binary, DTUMAC/binary>>,
<<"ip">> => DTUIP,
<<"isEnable">> => true,
<<"product">> => ProductId,
<<"ACL">> => Acl,
<<"status">> => <<"ONLINE">>,
<<"location">> => #{<<"__type">> => <<"GeoPoint">>, <<"longitude">> => 120.161324, <<"latitude">> => 30.262441},
<<"brand">> => Dtutype,
<<"devModel">> => DevType
})
end,
Productname =
case dgiot_parse:get_object(<<"Product">>, ProductId) of
{ok, #{<<"name">> := Productname1}} ->
Productname1;
_ ->
<<"">>
end,
?MLOG(info, #{<<"clientid">> => DeviceId, <<"devaddr">> => DTUMAC, <<"productid">> => ProductId, <<"productname">> => Productname, <<"devicename">> => <<Dtutype/binary, DTUMAC/binary>>, <<"status">> => <<"上线"/utf8>>}, ['device_statuslog']),
{DeviceId, DTUMAC};
Error2 ->
?LOG(info, "Error2 ~p ", [Error2]),
{<<>>, <<>>}
end.
%%create_instruct(ACL, DtuProductId, DtuDevId) ->
%% case dgiot_product:lookup_prod(DtuProductId) of
%% {ok, #{<<"thing">> := #{<<"properties">> := Properties}}} ->
%% lists:map(fun(Y) ->
%% case Y of
%% #{<<"dataForm">> := #{<<"slaveid">> := 256}} -> %%
%% pass;
%% #{<<"dataForm">> := #{<<"slaveid">> := SlaveId}} ->
%% Pn = dgiot_utils:to_binary(SlaveId),
%%%% ?LOG(info,"DtuProductId ~p DtuDevId ~p Pn ~p ACL ~p", [DtuProductId, DtuDevId, Pn, ACL]),
%%%% ?LOG(info,"Y ~p", [Y]),
%% dgiot_instruct:create(DtuProductId, DtuDevId, Pn, ACL, <<"all">>, #{<<"properties">> => [Y]});
%% _ -> pass
%% end
%% end, Properties);
%% _ -> pass
%% end.

View File

@ -27,7 +27,6 @@
test() ->
Buff = <<16#40, 16#40, 16#00, 16#00, 16#01, 16#01, 16#18, 16#0d, 16#11, 16#16, 16#0a, 16#14, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#06, 16#05, 16#04, 16#03, 16#02, 16#01, 16#30, 16#00, 16#02, 16#02, 16#01, 16#01, 16#03, 16#00, 16#d9, 16#00, 16#06, 16#00, 16#02, 16#00, 16#a3, 16#c1, 16#c7, 16#f8, 16#a3, 16#b1, 16#b2, 16#e3, 16#df, 16#c8, 16#b2, 16#b8, 16#d7, 16#df, 16#c0, 16#c8, 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#30, 16#12, 16#13, 16#01, 16#08, 16#14, 16#68, 16#23, 16#23>>,
{ok, Result} = parse_frame(Buff, #{}),
?LOG(info, "Result ~p~n", [Result]),
io:format("Result ~p~n", [Result]),
R = to_frame(Result),
case R =:= Buff of
@ -38,32 +37,117 @@ test() ->
end.
parse_frame(Buff, Opts) ->
?LOG(info, "Buff ~p~n", [Buff]),
parse_frame(Buff, #{}, Opts).
parse_frame(<<"@@", Header:22/binary, Length:16/little-integer, Tail/binary>> = Buff, Acc, Opts) when size(Tail) >= Length + 4 ->
parse_frame(<<>>, Acc, _Opts) ->
{ok, Acc};
%%GBT 2687532011
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% | |
%------------------------------------------------------------------------------------------------------------------------
%% @@ | |
%% (2) | 126464 |
%-------------------------------------------------------------------------------------------------------------------------
%% | 34 |
%% | |
%% | |
%% (2) | 2 (2) |
%% | o( |
%% | ) |
%% | |
%%-----------------------------------------------------------------------------------------------------------------------
%% | (5)(6) |
%% (2) | l |
%%-----------------------------------------------------------------------------------------------------------------------
%% | 712822 |
%% (6) | |
%%-----------------------------------------------------------------------------------------------------------------------
%% | 1318( |
%% (6) ) | |
%%-----------------------------------------------------------------------------------------------------------------------
%% | 1924( |
%% (6) | ) |
%%-----------------------------------------------------------------------------------------------------------------------
%% | 2526l 024 |
%% (2) | |
%%-----------------------------------------------------------------------------------------------------------------------
%% | |
%% (1) | 272 |
%%-----------------------------------------------------------------------------------------------------------------------
%% | 5 |
%% (1 024) | |
%%------------------------------------------------------------------------------------------------------------------------
%% | (327)8 |
%% (1) | l字节二进制数 |
%%------------------------------------------------------------------------------------------------------------------------
%% ## | 3535 |
%% (2) | |
%%------------------------------------------------------------------------------------------------------------------------
%%
%%4040 F809 1000 081E09030316 000000000000 C0A801046D1D 0100 02 16 6C 2323
%%
%%
%%4040 6900 1000 0a110e030615 000000000000 ac103cd56d1d 0100 02 16 30 2323
%%
%%4040 6900 1000 0a110e030615 ac103cd56d1d 000000000000 0100 03 17 30 2323
parse_frame(<<"@@", SerialId:16, Version:16, Time:6/binary, Source:6/binary, Destination:6/binary, Length:16/little, ?COMMAND_SEND_DATA:8, UserZone:1/binary, Crc:1/binary, "##", Rest/binary>> = Buff,
Acc, Opts) when Length == 1 ->
<<"@@", Head:25/binary, _/binary>> = Buff,
CheckCrc = dgiot_utils:get_parity(<<Head/binary, UserZone/binary>>),
{Acc1, Rest1} =
case <<CheckCrc>> =:= Crc of
true ->
AckBuff = <<"@@", SerialId:16, Version:16, Time:6/binary, Destination:6/binary, Source:6/binary, Length:16/little, ?COMMAND_CONFIRM:8, UserZone:1/binary, Crc:1/binary, "##">>,
NewAcc = Acc#{
<<"msgtype">> => ?GB26875,
<<"header">> => #{
<<"serialid">> => SerialId,
<<"version">> => Version,
<<"timestamp">> => get_timestamp(Time),
<<"source">> => get_address(Source),
<<"destination">> => get_address(Destination)
},
<<"command">> => ?COMMAND_SEND_DATA,
<<"appdata">> => dgiot_utils:binary_to_hex(UserZone),
<<"ack">> => AckBuff
},
{NewAcc, Rest};
false ->
{Acc, Rest}
end,
parse_frame(Rest1, Acc1, Opts);
parse_frame(<<"@@", SerialId:16, Version:16, Time:6/binary, Source:6/binary, Destination:6/binary, Length:16/little, Command:8, Tail/binary>> = Buff, Acc, Opts)
when size(Tail) >= Length + 3 andalso Length > 2 ->
<<"@@", Head:25/binary, _/binary>> = Buff,
<<SerialId:16, Version:16, Time:6/binary, Source:6/binary, Destination:6/binary>> = Header,
{Acc1, Rest1} =
case Tail of
<<Action:8, Appdata:Length/binary, Crc:1/binary, "##", Rest/binary>> ->
CheckCrc = dgiot_utils:get_parity(<<Head/binary, Appdata/binary>>),
<<UserZone:Length/binary, Crc:1/binary, "##", Rest/binary>> ->
CheckCrc = dgiot_utils:get_parity(<<Head/binary, UserZone/binary>>),
case <<CheckCrc>> =:= Crc of
true ->
<<Type:1/binary, Len:1/binary, Bodys/binary>> = Appdata,
{maps:merge(Acc#{
Map = maps:merge(Acc#{
<<"msgtype">> => ?GB26875,
<<"header">> => #{
<<"serialid">> => SerialId,
<<"version">> => Version,
<<"timestamp">> => get_timestamp(Time),
<<"source">> => dgiot_utils:binary_to_hex(reverse(Source)),
<<"target">> => dgiot_utils:binary_to_hex(reverse(Destination))
<<"source">> => get_address(Source),
<<"destination">> => get_address(Destination)
},
<<"action">> => Action,
<<"appdata">> => dgiot_utils:binary_to_hex(Appdata)
}, decoder_appdata(dgiot_utils:to_int(dgiot_utils:binary_to_hex(Type)), dgiot_utils:to_int(dgiot_utils:binary_to_hex(Len)), Bodys)), Rest};
false ->
<<"command">> => Command,
<<"appdata">> => dgiot_utils:binary_to_hex(UserZone),
<<"rawdata">> => #{
<<"timestamp">> => Time,
<<"source">> => Source,
<<"destination">> => Destination,
<<"appdata">> => UserZone
}
}, parse_userzone(UserZone)),
{Map, Rest};
_ ->
{Acc, <<>>}
end;
_Oth ->
@ -72,12 +156,8 @@ parse_frame(<<"@@", Header:22/binary, Length:16/little-integer, Tail/binary>> =
end,
parse_frame(Rest1, Acc1, Opts);
%%parse_frame(<<_:8, _/binary>> = Rest, Acc, Opts) ->
%% ?LOG(info, "Rest ~p~n", [Rest]),
%% parse_frame(Rest, Acc, Opts);
parse_frame(<<>>, Acc, _Opts) ->
{ok, Acc};
parse_frame(<<_:8, _/binary>> = Rest, Acc, Opts) ->
parse_frame(Rest, Acc, Opts);
parse_frame(Buff, Acc, Opts) ->
?LOG(info, "Buff ~p", [Buff]),
@ -85,48 +165,110 @@ parse_frame(Buff, Acc, Opts) ->
?LOG(info, "Opts ~p", [Opts]),
ok.
get_address(<<A:8, B:8, C:8, D:8, Port:16>>) ->
Address = lists:concat([A, ".", B, ".", C, ".", D, ":", Port]),
dgiot_utils:to_binary(Address).
reverse(Bin) -> reverse(Bin, <<>>).
reverse(<<>>, Acc) -> Acc;
reverse(<<H:1/binary, Rest/binary>>, Acc) ->
reverse(Rest, <<H/binary, Acc/binary>>).
get_delen(Type) ->
case Type of
?TYPE_UP_SYSTEM_STATE -> {<<"systemstate">>, 4};
?TYPE_UP_RUNNING_STATUS -> {<<"runningstatus">>, 40};
_ ->
{<<"unknow">>, 4}
end.
get_flag(Type, Flag) ->
{_, Flags} =
lists:foldl(fun(X, {Num, Acc}) ->
FlagId = dgiot_utils:to_binary(dgiot_utils:to_list(Type) ++ "." ++ dgiot_utils:to_list(Num)),
case X of
1 ->
{Num + 1, Acc#{FlagId => X}};
0 ->
{Num + 1, Acc}
end
end, {0, #{}}, [X || <<X:1>> <= Flag]),
Flags.
%%--------------------------------------------------------------------
%% | | 1 |
%% | | 1 |
%%--------------------------------------------------------------------
%% 1 | | |
%% | 1(a) | 6 |
%%--------------------------------------------------------------------
%% | | |
%%--------------------------------------------------------------------
%% n | n | |
%% | (b) | 6 |
%%--------------------------------------------------------------------
%% (a)(b)
%%
decoder_appdata(Type, Len, Bodys) ->
{Key, BodyLen} = get_delen(Type),
?LOG(info, "BodyLen ~p", [BodyLen]),
ShortLen = Len * BodyLen,
LongLen = Len * (BodyLen + 6),
%%
%%
%%4040 3113 1000 160F11030316 000000000000 C0A801046D1D 0A00 02 18010200160F11030316 16 2323
parse_userzone(<<Type:8, Num:8, InfoBodys/binary>>) ->
{Key, Len} = get_infobody_len(Type),
?LOG(info, "Type ~p Num ~p Len ~p", [Type, Num, Len]),
ShortLen = Num * Len,
LongLen = Num * (Len + 6),
NewBodys =
case size(Bodys) of
case size(InfoBodys) of
ShortLen ->
[decoder_appdata(Type, {Body, #{}}) || <<Body:BodyLen/binary>> <= Bodys];
[parse_infobody(Type, {InfoBody, #{}}) || <<InfoBody:Len/binary>> <= InfoBodys];
LongLen ->
[decoder_appdata(Type, {Body, #{<<"timestamp">> => get_timestamp(Time)}}) || <<Body:BodyLen/binary, Time:6/binary>> <= Bodys];
[parse_infobody(Type, {InfoBody, #{<<"timestamp">> => get_timestamp(Time)}}) || <<InfoBody:Len/binary, Time:6/binary>> <= InfoBodys];
_ ->
[]
end,
?LOG(info, "Key ~p~n", [Key]),
?LOG(info, "Bodys ~p~n", [NewBodys]),
#{Key => NewBodys}.
decoder_appdata(?TYPE_UP_SYSTEM_STATE, {<<Type:8, Addr:8, Flag:16>>, Timestamp}) ->
%%--------------------------------------------------------
%% 18 01 |
%%--------------------------------------------------------
%%| 02 | 00 | 160F | 11030316 |
%%--------------------------------------------------------
%%| | | | |
%%---------------------------------------------------------------------------------------------------------------------------------------
%% |bit15|bit14|bit13|bit12 |bit11 |bit10 |bit9 |bit8 |bit7 |bit6 |bit5 |bit4 |bit3 |bit2 |bit1 |bit0 |
%% 1 | | | | ||线|||| |()| | | | | |
%% 0 | | | |||线||| | |()|||| | |
%%---------------------------------------------------------------------------------------------------------------------------------------
parse_infobody(?CLASS_UP_SYSTEM_STATE, {<<Type:8, Addr:8, Flag:2/binary>>, Timestamp}) ->
maps:merge(#{<<"equ">> => #{
<<"ctrl">> => #{
<<"type">> => Type,
<<"addr">> => Addr
}
},
<<"flag">> => dgiot_utils:binary_to_hex(reverse(Flag))
<<"flag">> => get_flag(?CLASS_UP_SYSTEM_STATE, reverse(Flag))
}, Timestamp);
decoder_appdata(?TYPE_UP_RUNNING_STATUS, {<<Type:8, Addr:8, Type2:8, Addr2:4/binary, Flag:2/binary, Description:31/binary>>, Timestamp}) ->
%%------------------------
%%()|
%%------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
%%40 40 14 00 10 00 05 09 09 1b 07 15 2c 31 2c 32 00 00 78 4d 07 91 8e 23 30 00 02 02 01 01 01 2a 01 00 01 00 02 00 31 ba c5 bd d3 bf da b0 e5 31 bb d8 c2 b7 31 ba c5 00 ba c5 d6 f7 bb fa f8 98 cf a0 00 00 00 25 11 03 01 06 0c 47 23 23|
%%------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
%%| || | | |||||||
%%|40401400| 1000 | 0509091b0715|2c312c320000|784d07918e23|3000 |0202 |01 |XXXX..XX | 47 | 2323 |
%%-----------------------------------------------------------------------------------------------------------------------
%%| (1)|(1) |
%%| 02 | 02 |
%%8211
%%------------------------------------------------------------------------------------------------------------------------
%%|||||| | |
%%|(1) |(1)|(1) |(4) |(2) |(31) |6 |
%%|01 | 01 |2a |01000100|0200 |31bac5bdd3bfdab0e531bbd8c2b731bac500bac5d6f7bbfaf898cfa0000000|25110301060c|
%%------------------------------------------------------------------------------------------------------------------------
%%1
%%15
%%42
%%||
%%-------------------------------------------------------------------------------------------------------------------------
%% |bit15|bit14|bit13|bit12|bit11|bit10|bit9|bit8 |bit7 |bit6 |bit5 |bit4 |bit3 |bit2 |bit1 |bit0 |
%% 1 | | | | | | | ||| |()| | | | ||
%% 0 | | | | | | | || | |()|||| | |
%%-------------------------------------------------------------------------------------------------------------------------
%%31GB 18030--2005
%%
parse_infobody(?CLASS_UP_RUNNING_STATUS, {<<Type:8, Addr:8, Type2:8, Addr2:4/binary, Flag:2/binary, Description:31/binary>>, Timestamp}) ->
maps:merge(#{<<"equ">> => #{
<<"ctrl">> => #{
<<"type">> => Type,
@ -135,59 +277,65 @@ decoder_appdata(?TYPE_UP_RUNNING_STATUS, {<<Type:8, Addr:8, Type2:8, Addr2:4/bin
<<"type">> => Type2,
<<"addr">> => dgiot_utils:binary_to_hex(reverse(Addr2))
},
<<"flag">> => dgiot_utils:binary_to_hex(reverse(Flag)),
<<"flag">> => get_flag(?CLASS_UP_RUNNING_STATUS, reverse(Flag)),
<<"description">> => dgiot_utils:binary_to_hex(Description)
}, Timestamp);
%%decoder_appdata(?TYPE_UP_ANALOG_QUANTITY, Len, Body) ->
%%
%% #{};
%%decoder_appdata(?TYPE_UP_OPERATING_INFORMATION, Len, Body) ->
%%
%% #{};
%%decoder_appdata(?TYPE_UP_SYSTEM_CONFIGURATION, Len, Body) ->
%%
%% #{};
%%decoder_appdata(?TYPE_UP_PARTS_CONFIGURATION, Len, Body) ->
%%
%% #{};
%%decoder_appdata(?TYPE_UP_SYSTEM_TIME, Len, Body) ->
%%
%% #{};
%%---------------------------------------------------------------------------------------------
%% |bit7|bit6 |bit5 |bit4 |bit3 |bit2 |bit1 |bit0 |
%%---------------------------------------------------------------------------------------------
%% 1||线| || | | ||
%% 0||线| || | || |
%%---------------------------------------------------------------------------------------------
%% 21
parse_infobody(?CLASS_UP_USERDEV_RUNINFO, {<<Flag:1/binary>>, Timestamp}) ->
maps:merge(#{
<<"equ">> => #{
<<"ctrl">> => #{
<<"type">> => ?CLASS_UP_USERDEV_RUNINFO}
},
<<"flag">> => get_flag(?CLASS_UP_USERDEV_RUNINFO, Flag)
}, Timestamp);
%%
%%-------------------------------------------------------------
%% |bit7|bit6 |bit5 |bit4 |bit3 |bit2 |bit1 |bit0 |
%%-------------------------------------------------------------
%% 1|| || ||| | |
%% 0||| || | |||
%%-------------------------------------------------------------
%% 24
%%
parse_infobody(?CLASS_UP_USERDEV_OPINFO, {<<Flag:1/binary, Addr:8>>, Timestamp}) ->
maps:merge(#{
<<"equ">> => #{
<<"ctrl">> => #{
<<"type">> => ?CLASS_UP_USERDEV_OPINFO,
<<"addr">> => Addr}
},
<<"flag">> => get_flag(?CLASS_UP_USERDEV_OPINFO, Flag)
}, Timestamp);
decoder_appdata(_Type, {_Body, _Timestamp}) ->
parse_infobody(_Type, {_InfoBody, _Acc}) ->
?LOG(info, "_Type ~p", [_Type]),
?LOG(info, "_Body ~p", [_Body]),
?LOG(info, "_Timestamp ~p", [_Timestamp]),
?LOG(info, "_InfoBody ~p", [_InfoBody]),
?LOG(info, "_Acc ~p", [_Acc]),
#{}.
%%
%%parse_userzone(#{<<"msgtype">> := ?GB26875, <<"command">> := ?COMMAND_CONTROL, <<"data">> := Appdata}, Opts) ->
%%
%% ok;
%%
%%parse_userzone(#{<<"msgtype">> := ?GB26875, <<"command">> := ?COMMAND_SEND_DATA, <<"data">> := Appdata}, Opts) ->
%%
%% ok;
%%parse_userzone(#{<<"msgtype">> := ?GB26875, <<"command">> := ?COMMAND_CONFIRM, <<"data">> := Appdata}, Opts) ->
%%
%% ok;
%%
%%parse_userzone(#{<<"msgtype">> := ?GB26875, <<"command">> := ?COMMAND_REQUEST, <<"data">> := Appdata}, Opts) ->
%%
%% ok;
%%parse_userzone(#{<<"msgtype">> := ?GB26875, <<"command">> := ?COMMAND_RESPONSE, <<"data">> := Appdata}, Opts) ->
%%
%% ok;
%%
%%parse_userzone(#{<<"msgtype">> := ?GB26875, <<"command">> := ?COMMAND_DENY, <<"data">> := Appdata}, Opts) ->
%%
%% ok;
%%
%%parse_userzone(#{<<"msgtype">> := ?GB26875, <<"command">> := _, <<"data">> := _}, _Opts) ->
%%
%% ok.
get_infobody_len(Type) ->
case Type of
?CLASS_UP_SYSTEM_STATE ->
{<<"systemstate">>, 4};
?CLASS_UP_RUNNING_STATUS ->
{<<"runningstatus">>, 40};
?CLASS_UP_USERDEV_RUNINFO ->
{<<"userdev_runinfo">>, 1};
?CLASS_UP_USERDEV_OPINFO ->
{<<"userdev_opinfo">>, 2};
_ ->
{<<"unknow">>, 4}
end.
to_frame(Frame) ->
to_frame_last(Frame).
@ -198,7 +346,7 @@ to_frame_last(#{
<<"version">> := Version,
<<"timestamp">> := Timestamp,
<<"source">> := Source,
<<"target">> := Target
<<"destination">> := Destination
},
<<"action">> := Action
} = Frame) ->
@ -212,7 +360,7 @@ to_frame_last(#{
put(number, SerialId),
Time = get_time(Timestamp),
ReverseSource = reverse(dgiot_utils:hex_to_binary(Source)),
ReverseTarget = reverse(dgiot_utils:hex_to_binary(Target)),
ReverseTarget = reverse(dgiot_utils:hex_to_binary(Destination)),
Header = <<SerialId:16, Version:16, Time:6/binary, ReverseSource:6/binary, ReverseTarget:6/binary>>,
Appdata = encoder_appdata(Frame),
Length = size(Appdata),
@ -243,8 +391,11 @@ set_time(Body) ->
get_enlen(Type) ->
case Type of
<<"systemstate">> -> {?TYPE_UP_SYSTEM_STATE, 4};
<<"runningstatus">> -> {?TYPE_UP_RUNNING_STATUS, 40};
<<"systemstate">> ->
{?CLASS_UP_SYSTEM_STATE, 4};
<<"runningstatus">> ->
%% 40 40 14 00 10 00 05 09 09 1b 07 15 2c 31 2c 32 00 00 78 4d 07 91 8e 23 30 00 02 02 01 01 01 2a 01 00 01 00 02 00 31 ba c5 bd d3 bf da b0 e5 31 bb d8 c2 b7 31 ba c5 00 ba c5 d6 f7 bb fa f8 98 cf a0 00 00 00 25 11 03 01 06 0c 47 23 23
{?CLASS_UP_RUNNING_STATUS, 40};
_ ->
{<<"unknow">>, 4}
end.

View File

@ -0,0 +1,27 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020-2021 DGIOT Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%--------------------------------------------------------------------
-module(dgiot_gb26875_utils).
-include_lib("dgiot_gb26875.hrl").
-author("stoneliu").
-include_lib("dgiot/include/logger.hrl").
%% API
-export([get_equ_type/1]).
get_equ_type(_Type) ->
ok.

View File

@ -1216,15 +1216,24 @@ function pre_build_dgiot() {
cd ${script_dir}/
if [ ! -d ${script_dir}/dgiot/ ]; then
git clone root@git.iotn2n.com:dgiot/dgiot.git
if [ ! -d ${script_dir}/$plugin/ ]; then
git clone https://gitee.com/dgiiot/dgiot.git $plugin
fi
cd ${script_dir}/dgiot/
cd ${script_dir}/$plugin/
git reset --hard
git pull
rm ${script_dir}/dgiot/_build/emqx/rel/ -rf
if [ $plugin == 'dgiot' ]; then
echo "dgiot plugin"
else
cd ${script_dir}/$plugin/apps/
rm $plugin -rf
git clone root@git.iotn2n.com:dgiot/$plugin.git
fi
cd ${script_dir}
rm ${script_dir}/$plugin/_build/emqx/rel/ -rf
if [ -d ${script_dir}/dgiot_dashboard/dist ]; then
rm ${script_dir}/$plugin/_build/emqx/lib/dgiot_api -rf
@ -1236,19 +1245,6 @@ function pre_build_dgiot() {
rm ${script_dir}/dgiot/emqx/rel -rf
fi
if [ ! -d ${script_dir}/$plugin/ ]; then
git clone https://gitee.com/dgiiot/dgiot.git $plugin
fi
if [ ! -d ${script_dir}/$plugin/apps/$plugin/ ]; then
cd ${script_dir}/$plugin/apps/
git clone root@git.iotn2n.com:dgiot/$plugin.git
fi
cd ${script_dir}/$plugin/
git reset --hard
git pull
rm ${script_dir}/$plugin/rebar.config -rf
cp ${script_dir}/$plugin/apps/$plugin/conf/rebar.config ${script_dir}/$plugin/rebar.config -rf
rm ${script_dir}/$plugin/rebar.config.erl -rf
@ -1355,4 +1351,4 @@ else
fi
fi
echo -e "`date +%F_%T` $LINENO: ${GREEN} dgiot ${verType} deploy success end${NC}"
echo -e "`date +%F_%T` $LINENO: ${GREEN} dgiot ${verType} deploy success end${NC}"