From 2861667377adbcd509606ef83bfa457ff3f249f4 Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Fri, 3 Jan 2025 11:37:51 +0800 Subject: [PATCH] fix device data --- apps/iot/src/iot_device.erl | 59 ++++++++++++++++++++++++++--- apps/iot/src/iot_host.erl | 20 ++++++++-- apps/iot/src/iot_router.erl | 26 ------------- apps/iot/src/redis/redis_client.erl | 1 - docs/事件分类.md | 10 ++--- 5 files changed, 74 insertions(+), 42 deletions(-) delete mode 100644 apps/iot/src/iot_router.erl diff --git a/apps/iot/src/iot_device.erl b/apps/iot/src/iot_device.erl index c19cc14..9ac1c75 100644 --- a/apps/iot/src/iot_device.erl +++ b/apps/iot/src/iot_device.erl @@ -16,7 +16,7 @@ %% API -export([get_name/1, get_pid/1, serialize/1]). -export([start_link/2, is_activated/1, is_alive/1, change_status/2, reload/1, auth/2, data/2, query/6]). --export([ai_event/3]). +-export([ai_event/3, handle_data/3]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). @@ -34,6 +34,9 @@ %% 记录事件的ttl值 ai_event_ttl = #{}, + %% 设备类型 + model_id = 0, + status = ?DEVICE_OFFLINE }). @@ -117,6 +120,10 @@ query(Pid, Fields, Tags, StartTs, StopTs, Limit) when is_pid(Pid), is_list(Field ai_event(Pid, EventType, Params) when is_pid(Pid), is_integer(EventType), is_map(Params) -> gen_server:cast(Pid, {ai_event, EventType, Params}). +-spec handle_data(Pid :: pid(), Fields :: list(), Timestamp :: integer()) -> no_return(). +handle_data(Pid, Fields, Timestamp) when is_pid(Pid), is_list(Fields), is_integer(Timestamp) -> + gen_server:cast(Pid, {handle_data, Fields, Timestamp}). + %% @doc Spawns the server and registers the local name (unique) -spec(start_link(Name :: atom(), DeviceUUID :: binary()) -> {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). @@ -142,11 +149,12 @@ init([DeviceUUID]) when is_binary(DeviceUUID) -> lager:warning("[iot_device] device uuid: ~p, loaded from mysql failed", [DeviceUUID]), ignore end; -init([#{<<"device_uuid">> := DeviceUUID, <<"authorize_status">> := AuthorizeStatus, <<"status">> := Status}]) -> +init([#{<<"device_uuid">> := DeviceUUID, <<"authorize_status">> := AuthorizeStatus, <<"status">> := Status, <<"model_id">> := ModelId}]) -> {ok, CacheSize} = application:get_env(iot, device_cache_size), {ok, AiEventThrottle} = application:get_env(iot, ai_event_throttle), - {ok, #state{device_uuid = DeviceUUID, ai_event_throttle = AiEventThrottle, cache_size = CacheSize, status = as_integer(Status), auth_status = as_integer(AuthorizeStatus)}}. + {ok, #state{device_uuid = DeviceUUID, ai_event_throttle = AiEventThrottle, cache_size = CacheSize, + status = as_integer(Status), auth_status = as_integer(AuthorizeStatus), model_id = as_integer(ModelId)}}. %% @private %% @doc Handling call messages @@ -274,7 +282,30 @@ handle_cast({ai_event, EventType, Params}, State = #state{device_uuid = DeviceUU lager:debug("[iot_device] device_uuid: ~p, ai_event type: ~p not limited", [DeviceUUID, EventType]), iot_ai_router:route_uuid(DeviceUUID, EventType, Params), {noreply, State} - end. + end; + +%% 设备数据转发 +handle_cast({handle_data, Fields, Timestamp}, State = #state{device_uuid = DeviceUUID, model_id = ModelId}) -> + %% 查找终端设备对应的点位信息 + case redis_client:hgetall(DeviceUUID) of + {ok, #{<<"location_code">> := LocationCode, <<"dynamic_location_code">> := DynamicLocationCode}} when is_binary(LocationCode), is_binary(DynamicLocationCode) -> + %% 智慧照明设备的数据需要归类到建筑物下面 + case ModelId =:= 20 of + true -> + NLocationCode = extract_build_location_code(LocationCode), + NDynamicLocationCode = extract_build_location_code(DynamicLocationCode), + lager:debug("[iot_device] light device: ~p, location_code: ~p", [DeviceUUID, NLocationCode]), + + iot_zd_endpoint:forward(NLocationCode, NDynamicLocationCode, Fields, Timestamp); + false -> + iot_zd_endpoint:forward(LocationCode, DynamicLocationCode, Fields, Timestamp) + end; + {ok, _} -> + lager:warning("[iot_device] the north_data hget location_code, uuid: ~p, not found, fields: ~p", [DeviceUUID, Fields]); + {error, Reason} -> + lager:warning("[iot_device] the north_data hget location_code uuid: ~p, get error: ~p, fields: ~p", [DeviceUUID, Reason, Fields]) + end, + {noreply, State}. %% @private %% @doc Handling all non call/cast messages @@ -325,7 +356,15 @@ report_event(DeviceUUID, NewStatus) when is_binary(DeviceUUID), is_integer(NewSt <<"name">> => <<"设备状态"/utf8>>, <<"timestamp">> => Timestamp }], - iot_router:route_uuid(DeviceUUID, FieldsList, Timestamp), + + case redis_client:hgetall(DeviceUUID) of + {ok, #{<<"location_code">> := LocationCode, <<"dynamic_location_code">> := DynamicLocationCode}} when is_binary(LocationCode), is_binary(DynamicLocationCode) -> + iot_zd_endpoint:forward(LocationCode, DynamicLocationCode, FieldsList, Timestamp); + {ok, _} -> + lager:warning("[iot_device] the north_data hget location_code, uuid: ~p, not found, fields: ~p", [DeviceUUID, FieldsList]); + {error, Reason} -> + lager:warning("[iot_device] the north_data hget location_code uuid: ~p, get error: ~p, fields: ~p", [DeviceUUID, Reason, FieldsList]) + end, lager:debug("[iot_device] device_uuid: ~p, route fields: ~p", [DeviceUUID, FieldsList]). %% 过滤时间 @@ -354,4 +393,12 @@ filter_tags(L, Tags) when map_size(Tags) =:= 0 -> as_integer(Val) when is_integer(Val) -> Val; as_integer(Val) when is_binary(Val) -> - binary_to_integer(Val). \ No newline at end of file + binary_to_integer(Val). + +-spec extract_build_location_code(binary()) -> binary(). +extract_build_location_code(<>) -> + Len = byte_size(Suffix), + NSuffix = iolist_to_binary(lists:map(fun(_) -> <<"0">> end, lists:seq(1, Len))), + <>; +extract_build_location_code(Code) when is_binary(Code) -> + Code. diff --git a/apps/iot/src/iot_host.erl b/apps/iot/src/iot_host.erl index ab852d9..2db924d 100644 --- a/apps/iot/src/iot_host.erl +++ b/apps/iot/src/iot_host.erl @@ -591,7 +591,7 @@ handle_data(#{<<"device_uuid">> := DeviceUUID, <<"service_name">> := ServiceName case iot_device:is_activated(DevicePid) of true -> %% 查找终端设备对应的点位信息 - (not iot_ignore_devices:exists(DeviceUUID)) andalso iot_router:route_uuid(DeviceUUID, FieldsList, Timestamp), + (not iot_ignore_devices:exists(DeviceUUID)) andalso iot_device:handle_data(DevicePid, FieldsList, Timestamp), %% 数据写入influxdb NTags = Tags#{<<"uuid">> => UUID, <<"service_name">> => ServiceName, <<"device_uuid">> => DeviceUUID}, @@ -614,7 +614,7 @@ handle_data(#{<<"device_uuid">> := DeviceUUID, <<"service_name">> := ServiceName handle_data(#{<<"service_name">> := ServiceName, <<"at">> := Timestamp, <<"fields">> := FieldsList, <<"tags">> := Tags}, #state{uuid = UUID}) -> %% 查找终端设备对应的点位信息 - iot_router:route_uuid(UUID, FieldsList, Timestamp), + route_host_data(UUID, FieldsList, Timestamp), %% 数据写入influxdb NTags = Tags#{<<"uuid">> => UUID, <<"service_name">> => ServiceName}, @@ -638,7 +638,7 @@ report_event(UUID, NewStatus) when is_binary(UUID), is_integer(NewStatus) -> <<"name">> => <<"主机状态"/utf8>>, <<"timestamp">> => Timestamp }], - iot_router:route_uuid(UUID, FieldsList, Timestamp), + route_host_data(UUID, FieldsList, Timestamp), lager:debug("[iot_host] host_uuid: ~p, route fields: ~p", [UUID, FieldsList]). %% 报警主机的状态 @@ -664,4 +664,16 @@ parse_props(Props) when is_binary(Props) -> [_, SceneId0, MicroId0] = binary:split(Props, <<":">>, [global]), SceneId = binary_to_integer(SceneId0), MicroId = binary_to_integer(MicroId0), - {SceneId, MicroId}. \ No newline at end of file + {SceneId, MicroId}. + +-spec route_host_data(RouterUUID :: binary(), Fields :: list(), Timestamp :: integer()) -> no_return(). +route_host_data(RouterUUID, Fields, Timestamp) when is_binary(RouterUUID), is_list(Fields), is_integer(Timestamp) -> + %% 查找终端设备对应的点位信息 + case redis_client:hgetall(RouterUUID) of + {ok, #{<<"location_code">> := LocationCode, <<"dynamic_location_code">> := DynamicLocationCode}} when is_binary(LocationCode), is_binary(DynamicLocationCode) -> + iot_zd_endpoint:forward(LocationCode, DynamicLocationCode, Fields, Timestamp); + {ok, _} -> + lager:warning("[iot_host] the north_data hget location_code, uuid: ~p, not found, fields: ~p", [RouterUUID, Fields]); + {error, Reason} -> + lager:warning("[iot_host] the north_data hget location_code uuid: ~p, get error: ~p, fields: ~p", [RouterUUID, Reason, Fields]) + end. \ No newline at end of file diff --git a/apps/iot/src/iot_router.erl b/apps/iot/src/iot_router.erl deleted file mode 100644 index 45a4759..0000000 --- a/apps/iot/src/iot_router.erl +++ /dev/null @@ -1,26 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author aresei -%%% @copyright (C) 2023, -%%% @doc -%%% -%%% @end -%%% Created : 04. 7月 2023 11:30 -%%%------------------------------------------------------------------- --module(iot_router). --author("aresei"). --include("iot.hrl"). - -%% API --export([route_uuid/3]). - --spec route_uuid(RouterUUID :: binary(), Fields :: list(), Timestamp :: integer()) -> no_return(). -route_uuid(RouterUUID, Fields, Timestamp) when is_binary(RouterUUID), is_list(Fields), is_integer(Timestamp) -> - %% 查找终端设备对应的点位信息 - case redis_client:hgetall(RouterUUID) of - {ok, #{<<"location_code">> := LocationCode, <<"dynamic_location_code">> := DynamicLocationCode}} when is_binary(LocationCode), is_binary(DynamicLocationCode) -> - iot_zd_endpoint:forward(LocationCode, DynamicLocationCode, Fields, Timestamp); - {ok, _} -> - lager:warning("[iot_host] the north_data hget location_code, uuid: ~p, not found, fields: ~p", [RouterUUID, Fields]); - {error, Reason} -> - lager:warning("[iot_host] the north_data hget location_code uuid: ~p, get error: ~p, fields: ~p", [RouterUUID, Reason, Fields]) - end. \ No newline at end of file diff --git a/apps/iot/src/redis/redis_client.erl b/apps/iot/src/redis/redis_client.erl index ea29396..cfbddac 100755 --- a/apps/iot/src/redis/redis_client.erl +++ b/apps/iot/src/redis/redis_client.erl @@ -31,7 +31,6 @@ hgetall(Key) when is_binary(Key) -> end end). - to_map(Items) when is_list(Items), length(Items) rem 2 == 0 -> to_map(Items, #{}). to_map([], Target) -> diff --git a/docs/事件分类.md b/docs/事件分类.md index da36b79..44b55d5 100644 --- a/docs/事件分类.md +++ b/docs/事件分类.md @@ -7,11 +7,11 @@ 12 22503 后厨非标着装 15 23104 动火离人 16 22706 强弱电间违规进入 -17 20863 作业人员抽烟监测 -18 20864 作业人员手机使用监测 -19 23105 挡鼠板监测 -20 23106 垃圾桶加盖 -21 22714 配电间人员进入监测 +17 20863 作业人员抽烟监测 +18 20864 作业人员手机使用监测 +19 23105 挡鼠板监测 +20 23106 垃圾桶加盖 +21 22714 配电间人员进入监测 ``` 1、鼠类检测 0508103010001050300001 朴苑餐厅