mirror of
https://gitee.com/dgiiot/dgiot.git
synced 2024-11-29 18:57:41 +08:00
feat: add gb26875
This commit is contained in:
parent
a5ecc007b0
commit
497f375f2c
@ -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}} ->
|
||||
|
@ -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};
|
||||
_ ->
|
||||
|
@ -11,3 +11,6 @@
|
||||
+ GB 26875.7-2015 城市消防远程监控系统 第7部分:消防设施维护管理软件功能要求
|
||||
+ GB 26875.8-2015 城市消防远程监控系统 第8部分:监控中心对外数据交换协议
|
||||
|
||||
### 控制命令流程示意图
|
||||
|
||||
|
@ -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). % 8.2.1.1 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字节二进制数,取值范围0~255,类型标志见表3。
|
||||
-define(CLASS_UP_SYSTEM_STATE, 1). % 8.2.1.1 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). % 上传用户信息传输装置系统时间
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
%% 建筑消防设施系统状态 8.2.1.1
|
||||
%% 系统类型定义表
|
||||
-define(SYS_TYPE_COMMOM , 0). % 通用
|
||||
-define(SYS_TYPE_FIRE_ALARM, 0). % 火灾报警系统
|
@ -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}])).
|
||||
|
@ -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.
|
||||
|
@ -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};
|
||||
|
||||
%%GB/T 26875.3—2011
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% 定 义 | 描 述 |
|
||||
%------------------------------------------------------------------------------------------------------------------------
|
||||
%% 启动符‘@@’ | |
|
||||
%% (2字节) | 数据包的第1、2字节,为固定值64,64 |
|
||||
%-------------------------------------------------------------------------------------------------------------------------
|
||||
%% | 数据包的第3、4字节。发送/确认模式下,业务流水号由发送端在发送新的数据包 |
|
||||
%% | 时按顺序加一,确认方按发送包的业务流水号返回;请求/应答模式下,业务流水号 |
|
||||
%% 业务流水号 | 由请求端在发送新的请求命令时按顺序加一,应答方按请求包的业务流水号返回。 |
|
||||
%% (2字节) | 低字节传输在前。业务流水号是一个2字节的正整数,由通信双方第一次建立网络 (2字节) |
|
||||
%% | 连接时确定,初始值为o。业务流水号由业务发起方(业务发起方指发送/确认模式 |
|
||||
%% | 下的发送端或者请求/应答模式下的请求端)独立管理。业务发起方负责业务流水 |
|
||||
%% | 号的分配和回收,保证在业务存续期间业务流水号的唯一性 |
|
||||
%%-----------------------------------------------------------------------------------------------------------------------
|
||||
%% 协议版本号 | 协议版本号包含主版本号(第5字节)和用户版本号(第6字节)。主版本号为固定 |
|
||||
%% (2字节) | 值l,用户版本号由用户自行定义 |
|
||||
%%-----------------------------------------------------------------------------------------------------------------------
|
||||
%% 时间标签 | 数据包的第7~12字节,为数据包发出的时间,具体定义见8.2.2 |
|
||||
%% (6字节) | |
|
||||
%%-----------------------------------------------------------------------------------------------------------------------
|
||||
%% 源地址 | 数据包的第13~18字节,为数据包的源地址(监控中心或用户信息传输装置地 |
|
||||
%% (6字节) 址)。 | 低字节传输在前 |
|
||||
%%-----------------------------------------------------------------------------------------------------------------------
|
||||
%% 目的地址 | 数据包的第19~24字节,为数据包的目的地址(监控中心或用户信息传输装置地 |
|
||||
%% (6字节) | 址)。低字节传输在前 |
|
||||
%%-----------------------------------------------------------------------------------------------------------------------
|
||||
%% 应用数据单元长度 | 数据包的第25,26字节,为应用数据单元的长度,长度不应大于l 024;低字节传输在前 |
|
||||
%% (2字节) | |
|
||||
%%-----------------------------------------------------------------------------------------------------------------------
|
||||
%% 命令字节 | |
|
||||
%% (1字节) | 数据包的第27字节,为控制单元的命令字节,具体定义见表2 |
|
||||
%%-----------------------------------------------------------------------------------------------------------------------
|
||||
%% 应用数据单元 | 应用数据单元,基本格式见图5,对于确认/否认等命令包,此单元可为空 |
|
||||
%% (最大1 024字节) | |
|
||||
%%------------------------------------------------------------------------------------------------------------------------
|
||||
%% 校验和 | 控制单元中各字节数据(第3~27字节)及应用数据单元的算术校验和,舍去8位 |
|
||||
%% (1字节) | 以上的进位位后所形成的l字节二进制数 |
|
||||
%%------------------------------------------------------------------------------------------------------------------------
|
||||
%% 结束符‘##, | 为固定值35,35 |
|
||||
%% (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 |
|
||||
%%见8.2.1.1的定义
|
||||
%%------------------------------------------------------------------------------------------------------------------------
|
||||
%%|系统类型|系统地址|部件类型|部件地址|部件状态|部件说明 | 状态发生时间|
|
||||
%%|(1字节) |(1字节)|(1字节) |(4字节) |(2字节) |(31字节) |6字节 |
|
||||
%%|01 | 01 |2a |01000100|0200 |31bac5bdd3bfdab0e531bbd8c2b731bac500bac5d6f7bbfaf898cfa0000000|25110301060c|
|
||||
%%------------------------------------------------------------------------------------------------------------------------
|
||||
%%建筑消防设施系统类型标志、系统地址分别为1字节二进制数
|
||||
%%建筑消防设施部件类型标志符为1字节二进制数,定义如表5所示。
|
||||
%%建筑消防设施部件地址为4字节二进制数,建筑消防设施部件状态数据为2字节,低字节先传输。
|
||||
%%|部件状态|
|
||||
%%-------------------------------------------------------------------------------------------------------------------------
|
||||
%% |bit15|bit14|bit13|bit12|bit11|bit10|bit9|bit8 |bit7 |bit6 |bit5 |bit4 |bit3 |bit2 |bit1 |bit0 |
|
||||
%% 1 |预留 |预留 |预留 |预留 |预留 |预留 |预留 |电源故障|延时状态|反馈 |启动(开启)|监管 |屏蔽 |故障 |火警 |正常运行状态|
|
||||
%% 0 |预留 |预留 |预留 |预留 |预留 |预留 |预留 |电源正常|未延时 |无反馈 |停止(关闭)|无监管|无屏蔽|无故障|无火警 |测试状态 |
|
||||
%%-------------------------------------------------------------------------------------------------------------------------
|
||||
%%建筑消防设施部件说明为31字节的字符串,采用GB 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.
|
||||
|
27
apps/dgiot_gb26875/src/protocol/dgiot_gb26875_utils.erl
Normal file
27
apps/dgiot_gb26875/src/protocol/dgiot_gb26875_utils.erl
Normal 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.
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user