diff --git a/apps/iot/src/database/micro_inform_log.erl b/apps/iot/src/database/micro_inform_log.erl new file mode 100644 index 0000000..989d9f5 --- /dev/null +++ b/apps/iot/src/database/micro_inform_log.erl @@ -0,0 +1,17 @@ +%%%------------------------------------------------------------------- +%%% @author aresei +%%% @copyright (C) 2023, +%%% @doc +%%% +%%% @end +%%% Created : 16. 5月 2023 12:48 +%%%------------------------------------------------------------------- +-module(micro_inform_log). +-author("aresei"). +-include("iot.hrl"). + +%% API +-export([insert/1]). + +insert(Fields) when is_map(Fields) -> + mysql_client:insert(<<"micro_inform_log">>, Fields, true). \ No newline at end of file diff --git a/apps/iot/src/database/scene_feedback.erl b/apps/iot/src/database/scene_feedback.erl new file mode 100644 index 0000000..60b4550 --- /dev/null +++ b/apps/iot/src/database/scene_feedback.erl @@ -0,0 +1,17 @@ +%%%------------------------------------------------------------------- +%%% @author aresei +%%% @copyright (C) 2023, +%%% @doc +%%% +%%% @end +%%% Created : 16. 5月 2023 12:48 +%%%------------------------------------------------------------------- +-module(scene_feedback). +-author("aresei"). +-include("iot.hrl"). + +%% API +-export([insert/1]). + +insert(Fields) when is_map(Fields) -> + mysql_client:insert(<<"scene_feedback">>, Fields, true). \ No newline at end of file diff --git a/apps/iot/src/iot_host.erl b/apps/iot/src/iot_host.erl index e13fc37..0d6e724 100644 --- a/apps/iot/src/iot_host.erl +++ b/apps/iot/src/iot_host.erl @@ -26,6 +26,7 @@ -define(SERVER, ?MODULE). -record(state, { + host_id :: integer(), %% 从数据库里面读取到的数据 uuid :: binary(), %% 当前的状态 @@ -124,12 +125,12 @@ start_link(Name, UUID) when is_atom(Name), is_binary(UUID) -> {stop, Reason :: term()} | ignore). init([UUID]) -> case host_bo:get_host_by_uuid(UUID) of - {ok, #{<<"status">> := Status}} -> + {ok, #{<<"status">> := Status, <<"id">> := HostId}} -> %% 启动心跳定时器 erlang:start_timer(?TICKER_INTERVAL, self(), ping_ticker), Aes = list_to_binary(iot_util:rand_bytes(32)), - {ok, #state{uuid = UUID, aes = Aes, is_activated = (Status /= ?HOST_STATUS_INACTIVE), status = Status, has_session = false}}; + {ok, #state{host_id = HostId, uuid = UUID, aes = Aes, is_activated = (Status /= ?HOST_STATUS_INACTIVE), status = Status, has_session = false}}; undefined -> lager:warning("[iot_host] host uuid: ~p, loaded from mysql failed", [UUID]), ignore @@ -161,9 +162,9 @@ handle_call({make_assoc, ReceivePid}, _From, State = #state{uuid = UUID, increme handle_call(reload, _From, State = #state{uuid = UUID}) -> %% 重新加载主机信息 case host_bo:get_host_by_uuid(UUID) of - {ok, Host = #{<<"status">> := Status}} -> + {ok, Host = #{<<"status">> := Status, <<"id">> := HostId}} -> lager:debug("[iot_host] reload host uuid: ~p, successed", [Host]), - {reply, ok, State#state{is_activated = (Status /= ?HOST_STATUS_INACTIVE), status = Status}}; + {reply, ok, State#state{host_id = HostId, is_activated = (Status /= ?HOST_STATUS_INACTIVE), status = Status}}; undefined -> lager:debug("[iot_host] reload host uuid: ~p, failed", [UUID]), {reply, {error, <<"host not found">>}, State} @@ -309,6 +310,45 @@ handle_message(#{<<"method">> := <<"ping">>, <<"params">> := CipherMetric}, Stat lager:debug("[iot_host] host_id uuid: ~p, get ping: ~p", [UUID, Metrics]), State#state{metrics = Metrics}; +%% 处理微服务的信息上报 +handle_message(#{<<"method">> := <<"inform">>, <<"params">> := Info0}, State = #state{has_session = true, host_id = HostId, aes = AES}) -> + Info = iot_cipher_aes:decrypt(AES, base64:decode(Info0)), + case catch jiffy:decode(Info, [return_maps]) of + #{<<"at">> := At, <<"services">> := ServiceInforms} -> + lists:foreach(fun(#{<<"scene_id">> := SceneId, <<"name">> := Name, <<"version">> := Version, <<"version_copy">> := VersionCopy, <<"status">> := Status}) -> + micro_inform_log:insert(#{ + <<"host_id">> => HostId, + <<"scene_id">> => SceneId, + <<"service_name">> => Name, + <<"version">> => Version, + <<"version_copy">> => VersionCopy, + <<"status">> => Status, + <<"created_at">> => At + }) + end, ServiceInforms); + Error -> + lager:warning("[iot_host] inform error: ~p", [Error]) + end, + State; + +%% 处理命令的上报结果 +handle_message(#{<<"method">> := <<"feedback_result">>, <<"params">> := Info0}, State = #state{has_session = true, aes = AES}) -> + Info = iot_cipher_aes:decrypt(AES, base64:decode(Info0)), + case catch jiffy:decode(Info, [return_maps]) of + #{<<"task_id">> := TaskId, <<"time">> := Time, <<"code">> := Code, <<"reason">> := Reason, <<"error">> := Error, <<"type">> := Type} -> + scene_feedback:insert(#{ + <<"task_id">> => TaskId, + <<"task_type">> => Type, + <<"code">> => Code, + <<"reason">> => Reason, + <<"error">> => Error, + <<"created_at">> => Time + }); + Other -> + lager:warning("[iot_host] feedback_result error: ~p", [Other]) + end, + State; + %% 处理客户端激活的响应, 完整格式为: {"code": 0|1, "message": "", "assoc": string} handle_message(Msg = #{<<"code">> := _Code, <<"assoc">> := Assoc}, State = #state{assoc_map = AssocMap}) -> case maps:take(Assoc, AssocMap) of diff --git a/apps/iot/src/mocker/host_mocker.erl b/apps/iot/src/mocker/host_mocker.erl index f37a63d..5c75859 100644 --- a/apps/iot/src/mocker/host_mocker.erl +++ b/apps/iot/src/mocker/host_mocker.erl @@ -338,5 +338,21 @@ handle_command(8, #{<<"aes">> := Aes, <<"auth">> := true, <<"reply">> := #{<<"to lager:debug("[host_mocker] send reply failed, reason: ~p", [Reason]) end, + State#state{aes = Aes}; +handle_command(8, #{<<"aes">> := Aes, <<"auth">> := false, <<"reply">> := #{<<"topic">> := Topic, <<"assoc">> := Assoc}}, State) -> + Msg = jiffy:encode(#{ + <<"code">> => 1, + <<"message">> => "", + <<"assoc">> => Assoc + }, [force_utf8]), + + {ok, Ref} = iot_mqtt_publisher:publish(Topic, Msg, 1), + receive + {ok, Ref, PacketId} -> + lager:debug("[host_mocker] send reply success, packet_id: ~p", [PacketId]); + {error, Reason} -> + lager:debug("[host_mocker] send reply failed, reason: ~p", [Reason]) + end, + State#state{aes = Aes}. diff --git a/docs/host-mqtt-jiaohu.md b/docs/host-mqtt-jiaohu.md index 08b98ba..cc1c954 100644 --- a/docs/host-mqtt-jiaohu.md +++ b/docs/host-mqtt-jiaohu.md @@ -290,6 +290,7 @@ inform信息会发送给``, 结构如下: "at": $int64, // 微服务信息 "services": [{ + "scene_id": $int "场景的编号", "name": "微服务名称", "version": "微服务版本", "version_copy": "微服务副本",