From 28acc41c610b6a1a8fb8506c42ee1df19f8b2085 Mon Sep 17 00:00:00 2001 From: dawnwinterLiu <1737801684@qq.com> Date: Thu, 23 Jun 2022 19:57:34 +0800 Subject: [PATCH] feat: Default latitude and longitude --- apps/dgiot_device/src/dgiot_product.erl | 2 +- .../src/utils/dgiot_device_cache.erl | 25 ++- .../dgiot_modbus/src/dgiot_modbus_channel.erl | 26 +-- apps/dgiot_modbus/src/dgiot_modbustcp_tcp.erl | 205 ------------------ 4 files changed, 20 insertions(+), 238 deletions(-) delete mode 100644 apps/dgiot_modbus/src/dgiot_modbustcp_tcp.erl diff --git a/apps/dgiot_device/src/dgiot_product.erl b/apps/dgiot_device/src/dgiot_product.erl index 14a1b297..75dc1303 100644 --- a/apps/dgiot_device/src/dgiot_product.erl +++ b/apps/dgiot_device/src/dgiot_product.erl @@ -282,7 +282,7 @@ to_frame(ProductId, Msg) -> format_product(#{<<"objectId">> := ProductId} = Product) -> Thing = maps:get(<<"thing">>, Product, #{}), Props = maps:get(<<"properties">>, Thing, []), - Keys = [<<"ACL">>, <<"name">>, <<"devType">>, <<"status">>, <<"channel">>, <<"content">>, <<"profile">>, <<"nodeType">>, <<"dynamicReg">>, <<"topics">>, <<"productSecret">>], + Keys = [<<"ACL">>, <<"name">>, <<"config">>, <<"devType">>, <<"status">>, <<"channel">>, <<"content">>, <<"profile">>, <<"nodeType">>, <<"dynamicReg">>, <<"topics">>, <<"productSecret">>], Map = maps:with(Keys, Product), Map#{ <<"productId">> => ProductId, diff --git a/apps/dgiot_device/src/utils/dgiot_device_cache.erl b/apps/dgiot_device/src/utils/dgiot_device_cache.erl index 452e53a4..32450335 100644 --- a/apps/dgiot_device/src/utils/dgiot_device_cache.erl +++ b/apps/dgiot_device/src/utils/dgiot_device_cache.erl @@ -84,15 +84,24 @@ post(Device) -> ProductId = maps:get(<<"objectId">>, Product), DeviceSecret = maps:get(<<"deviceSecret">>, Device, <<"oioojn">>), DeviceId = maps:get(<<"objectId">>, Device, dgiot_parse_id:get_deviceid(ProductId, Devaddr)), - case dgiot_product:lookup_prod(ProductId) of - {ok, ProductInfo} -> - Data = maps:with([<<"profile">>, <<"content">>], ProductInfo), - dgiot_parse:update_object(<<"Device">>, DeviceId, Data); - _ -> - pass - end, + {Data, Location, Address} = + case dgiot_product:lookup_prod(ProductId) of + {ok, ProductInfo} -> + Data1 = maps:with([<<"profile">>, <<"content">>], ProductInfo), + case maps:find(<<"config">>, #{}) of + {ok, #{<<"location">> := Location1, <<"address">> := Address1}} -> + {Data1, Location1, Address1}; + _ -> + {Data1, #{<<"__type">> => <<"GeoPoint">>, <<"longitude">> => 120.065463, <<"latitude">> => 30.368707}, <<>>} + end; + _ -> + {#{}, #{<<"__type">> => <<"GeoPoint">>, <<"longitude">> => 120.065463, <<"latitude">> => 30.368707}, <<>>} + end, + + dgiot_parse:update_object(<<"Device">>, DeviceId, Data#{<<"location">> => maps:get(<<"location">>, Device, Location), <<"address">> => maps:get(<<"address">>, Device, Address)}), + #{<<"longitude">> := Longitude, <<"latitude">> := Latitude} = - maps:get(<<"location">>, Device, #{<<"__type">> => <<"GeoPoint">>, <<"longitude">> => 120.161324, <<"latitude">> => 30.262441}), + maps:get(<<"location">>, Device, Location), Status = case maps:get(<<"status">>, Device, <<"OFFLINE">>) of <<"OFFLINE">> -> false; diff --git a/apps/dgiot_modbus/src/dgiot_modbus_channel.erl b/apps/dgiot_modbus/src/dgiot_modbus_channel.erl index fcf1b4d1..aabc1464 100644 --- a/apps/dgiot_modbus/src/dgiot_modbus_channel.erl +++ b/apps/dgiot_modbus/src/dgiot_modbus_channel.erl @@ -75,22 +75,6 @@ zh => <<"填写正则表达式匹配login报文, 9C-A5标识设备类型,**-**-**-**为设备地址,中杆会自动去除"/utf8>> } }, - <<"modbustype">> => #{ - order => 4, - type => string, - required => true, - default => #{<<"value">> => <<"modbusrtu">>, <<"label">> => <<"Modbus RTU">>}, - enum => [ - #{<<"value">> => <<"modbusrtu">>, <<"label">> => <<"Modbus RTU">>}, - #{<<"value">> => <<"modbustcp">>, <<"label">> => <<"Modbus TCP">>} - ], - title => #{ - zh => <<"Modbus种类"/utf8>> - }, - description => #{ - zh => <<"Modbus种类"/utf8>> - } - }, <<"dtutype">> => #{ order => 5, type => string, @@ -129,7 +113,7 @@ init(?TYPE, ChannelId, #{ <<"regular">> := Regular, <<"product">> := Products, <<"dtutype">> := Dtutype -} = Args) -> +} = _Args) -> {ProdcutId, App} = case get_app(Products) of [{ProdcutId1, App1} | _] -> @@ -149,13 +133,7 @@ init(?TYPE, ChannelId, #{ product = ProdcutId, dtutype = Dtutype }, -%% dgiot_data:insert({ChannelId, heartbeat}, {Heartbeat, Port}), - case maps:get(<<"modbustype">>, Args, <<"modbusrtu">>) of - <<"modbustcp">> -> - {ok, State, dgiot_modbustcp_tcp:start(Port, State)}; - _ -> - {ok, State, dgiot_modbusrtu_tcp:start(Port, State)} - end; + {ok, State, dgiot_modbusrtu_tcp:start(Port, State)}; init(?TYPE, _ChannelId, _Args) -> diff --git a/apps/dgiot_modbus/src/dgiot_modbustcp_tcp.erl b/apps/dgiot_modbus/src/dgiot_modbustcp_tcp.erl deleted file mode 100644 index 7aa10647..00000000 --- a/apps/dgiot_modbus/src/dgiot_modbustcp_tcp.erl +++ /dev/null @@ -1,205 +0,0 @@ -%%-------------------------------------------------------------------- -%% 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_modbustcp_tcp). --author("stoneliu"). --include("dgiot_modbus.hrl"). --include_lib("dgiot/include/dgiot_socket.hrl"). --include_lib("dgiot/include/logger.hrl"). - --define(MAX_BUFF_SIZE, 1024). - --export([ - get_deviceid/2, - start/2 -]). - -%% TCP callback --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). - -%% ======================= -%% {ok, State} | {stop, Reason} -%%init(TCPState) -> -%% erlang:send_after(5 * 1000, self(), login),. -%% {ok, TCPState}. - -init(#tcp{state = #state{id = ChannelId}} = TCPState) -> - case dgiot_bridge:get_products(ChannelId) of - {ok, _TYPE, _ProductIds} -> - {ok, TCPState}; - {error, not_find} -> - {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) -> - 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), - case re:run(DtuAddr, Head, [{capture, first, list}]) of - {match, [Head]} when length(List) == Len -> - DeviceId = dgiot_parse_id:get_deviceid(ProductId, DtuAddr), - create_device(DeviceId, ProductId, DtuAddr, DTUIP, Dtutype), - dgiot_bridge:send_log(ChannelId, ProductId, DtuAddr, "~s ~p DTU login DtuAddr:~p", [?FILE, ?LINE, DtuAddr]), - Topic = <<"$dg/device/", ProductId/binary, "/", DtuAddr/binary, "/profile">>, - dgiot_mqtt:subscribe(Topic), - {noreply, TCPState#tcp{buff = <<>>, register = true, clientid = DeviceId, state = State#state{devaddr = DtuAddr, deviceId = DeviceId}}}; - _Error -> - case re:run(Buff, Head, [{capture, first, list}]) of - {match, [Head]} when length(List1) == Len -> - DeviceId = dgiot_parse_id:get_deviceid(ProductId, Buff), - create_device(DeviceId, ProductId, Buff, DTUIP, Dtutype), - Topic = <<"$dg/device/", ProductId/binary, "/", Buff/binary, "/profile">>, - dgiot_bridge:send_log(ChannelId, ProductId, Buff, "~s ~p DTU login DtuAddr:~p", [?FILE, ?LINE, Buff]), - dgiot_mqtt:subscribe(Topic), - {noreply, TCPState#tcp{buff = <<>>, register = true, clientid = DeviceId, state = State#state{devaddr = Buff}}}; - Error1 -> - ?LOG(info, "Error1 ~p Buff ~p ", [Error1, dgiot_utils:to_list(Buff)]), - {noreply, TCPState#tcp{buff = <<>>}} - end - end; - -handle_info({tcp, Buff}, #tcp{state = #state{id = ChannelId, devaddr = DtuAddr, env = #{product := ProductId, pn := Pn, di := Di}, product = DtuProductId} = State} = TCPState) -> - dgiot_bridge:send_log(ChannelId, ProductId, DtuAddr, "~s ~p DTU ~p recv ~p", [?FILE, ?LINE, DtuAddr, dgiot_utils:binary_to_hex(Buff)]), - <> = dgiot_utils:hex_to_binary(modbus_tcp:is16(Di)), - <> = dgiot_utils:hex_to_binary(modbus_tcp:is16(Pn)), - case modbus_tcp:parse_frame(Buff, #{}, #{ - <<"dtuproduct">> => ProductId, - <<"channel">> => ChannelId, - <<"dtuaddr">> => DtuAddr, - <<"slaveId">> => Sh * 256 + Sl, - <<"address">> => H * 256 + L}) of - {_, Things} -> - NewTopic = <<"$dg/thing/", DtuProductId/binary, "/", DtuAddr/binary, "/properties/report">>, - dgiot_bridge:send_log(ChannelId, ProductId, DtuAddr, "~s ~p to task ~p ~ts ", [?FILE, ?LINE, NewTopic, unicode:characters_to_list(jsx:encode(Things))]), - DeviceId = dgiot_parse_id:get_deviceid(ProductId, DtuAddr), - Taskchannel = dgiot_product:get_taskchannel(ProductId), - dgiot_client:send(Taskchannel, DeviceId, NewTopic, Things); - Other -> - ?LOG(info, "Other ~p", [Other]), - pass - end, - {noreply, TCPState#tcp{buff = <<>>, state = State#state{env = <<>>}}}; - -handle_info({deliver, _, Msg}, #tcp{state = #state{id = ChannelId} = State} = TCPState) -> - Payload = dgiot_mqtt:get_payload(Msg), - Topic = dgiot_mqtt:get_topic(Msg), - case jsx:is_json(Payload) of - true -> - case binary:split(Topic, <<$/>>, [global, trim]) of - [<<"$dg">>, <<"device">>, ProductId, DevAddr, <<"profile">>] -> -%% 设置参数 - Payloads = modbus_tcp:set_params(jsx:decode(Payload), ProductId, DevAddr), - lists:map(fun(X) -> - dgiot_tcp_server:send(TCPState, X) - end, Payloads), - {noreply, TCPState}; - [<<"$dg">>, <<"device">>, ProductId, DevAddr, <<"properties">>] -> - case jsx:decode(Payload, [{labels, binary}, return_maps]) of - #{<<"slaveid">> := SlaveId, <<"address">> := Address} = DataSource -> - Data = modbus_tcp:to_frame(DataSource), -%% io:format("~s ~p Data = ~p.~n", [?FILE, ?LINE, dgiot_utils:to_hex(Data)]), - dgiot_bridge:send_log(ChannelId, ProductId, DevAddr, "Channel sends ~p to DTU ~p", [dgiot_utils:binary_to_hex(Data), DevAddr]), - dgiot_tcp_server:send(TCPState, Data), - {noreply, TCPState#tcp{state = State#state{env = #{product => ProductId, pn => SlaveId, di => Address}}}}; - _ -> - {noreply, TCPState} - end; - _Other -> - ?LOG(error, "_Other ~p", [_Other]), - {noreply, TCPState} - end; - false -> - case binary:split(Topic, <<$/>>, [global, trim]) of - [<<"$dg">>, <<"device">>, ProductId, DevAddr, <<"profile">>] -> - %% 设置参数 - Payloads = modbus_tcp:set_params(jsx:decode(Payload), ProductId, DevAddr), - lists:map(fun(X) -> - dgiot_tcp_server:send(TCPState, X) - end, Payloads), - {noreply, TCPState}; - _ -> - {noreply, TCPState} - end - end; -%% {stop, TCPState} | {stop, Reason} | {ok, TCPState} | ok | stop -handle_info(_Info, TCPState) -> - ?LOG(info, "TCPState ~p", [TCPState]), - {noreply, TCPState}. - -handle_call(_Msg, _From, TCPState) -> - {reply, ok, TCPState}. - -handle_cast(_Msg, TCPState) -> - {noreply, TCPState}. - -terminate(_Reason, #tcp{state = #state{devaddr = DtuAddr, product = ProductId}} = _TCPState) -> - DeviceId = dgiot_parse_id:get_deviceid(ProductId, DtuAddr), - Taskchannel = dgiot_product:get_taskchannel(ProductId), - dgiot_task:del_pnque(DeviceId), - dgiot_client:stop(Taskchannel, DeviceId), - ok; - -terminate(_Reason, _TCPState) -> - ok. - -code_change(_OldVsn, TCPState, _Extra) -> - {ok, TCPState}. - -get_deviceid(ProdcutId, DevAddr) -> - #{<<"objectId">> := DeviceId} = - dgiot_parse_id:get_objectid(<<"Device">>, #{<<"product">> => ProdcutId, <<"devaddr">> => DevAddr}), - DeviceId. - -create_device(DeviceId, ProductId, DTUMAC, DTUIP, Dtutype) -> - case dgiot_product:lookup_prod(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_task:save_pnque(ProductId, DTUMAC, ProductId, DTUMAC); - _ -> - dgiot_device:create_device(#{ - <<"devaddr">> => DTUMAC, - <<"name">> => <>, - <<"ip">> => DTUIP, - <<"isEnable">> => true, - <<"product">> => ProductId, - <<"ACL">> => Acl, - <<"status">> => <<"ONLINE">>, - <<"location">> => #{<<"__type">> => <<"GeoPoint">>, <<"longitude">> => 120.161324, <<"latitude">> => 30.262441}, - <<"brand">> => Dtutype, - <<"devModel">> => DevType - }), - dgiot_task:save_pnque(ProductId, DTUMAC, ProductId, DTUMAC) - 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">> => <>, <<"status">> => <<"上线"/utf8>>}, ['device_statuslog']), - {DeviceId, DTUMAC}; - _Error2 -> -%% ?LOG(info, "Error2 ~p ", [Error2]), - {<<>>, <<>>} - end.