diff --git a/apps/iot/include/iot.hrl b/apps/iot/include/iot.hrl index aa426ca..9f353da 100644 --- a/apps/iot/include/iot.hrl +++ b/apps/iot/include/iot.hrl @@ -41,6 +41,8 @@ %% 事件类型 -define(EVENT_DEVICE, 16#01). +%% 主机的相关事件 +-define(EVENT_HOST, 16#02). %% 缓存数据库表 -record(kv, { diff --git a/apps/iot/src/database/device_bo.erl b/apps/iot/src/database/device_bo.erl index eab0e5f..1fa657b 100644 --- a/apps/iot/src/database/device_bo.erl +++ b/apps/iot/src/database/device_bo.erl @@ -31,6 +31,12 @@ get_device_by_uuid(DeviceUUID) when is_binary(DeviceUUID) -> mysql_pool:get_row(mysql_iot, <<"SELECT * FROM device WHERE device_uuid = ? LIMIT 1">>, [DeviceUUID]). %% 修改主机的状态 --spec change_status(DeviceId :: integer(), Status :: integer()) -> {ok, AffectedRows :: integer()} | {error, Reason :: any()}. -change_status(DeviceId, Status) when is_integer(DeviceId), is_integer(Status) -> - mysql_pool:update_by(mysql_iot, <<"UPDATE device SET status = ? WHERE id = ? LIMIT 1">>, [Status, DeviceId]). \ No newline at end of file +-spec change_status(DeviceUUID :: binary(), Status :: integer()) -> {ok, AffectedRows :: integer()} | {error, Reason :: any()}. +change_status(DeviceUUID, Status) when is_binary(DeviceUUID), is_integer(Status) -> + case mysql_pool:update_by(mysql_iot, <<"UPDATE device SET status = ? WHERE device_uuid = ? LIMIT 1">>, [Status, DeviceUUID]) of + Result = {ok, _} -> + event_logs_bo:insert(?EVENT_DEVICE, DeviceUUID, Status), + Result; + Error -> + Error + end. \ No newline at end of file diff --git a/apps/iot/src/database/event_logs_bo.erl b/apps/iot/src/database/event_logs_bo.erl new file mode 100644 index 0000000..87f98c8 --- /dev/null +++ b/apps/iot/src/database/event_logs_bo.erl @@ -0,0 +1,25 @@ +%%%------------------------------------------------------------------- +%%% @author aresei +%%% @copyright (C) 2023, +%%% @doc +%%% +%%% @end +%%% Created : 16. 5月 2023 12:48 +%%%------------------------------------------------------------------- +-module(event_logs_bo). +-author("aresei"). +-include("iot.hrl"). + +-export([insert/3]). + +%% API + +-spec insert(EventType :: integer(), AssocUUID :: binary(), Status :: integer()) -> + {ok, InsertId :: integer()} | {error, Reason :: any()}. +insert(EventType, AssocUUID, Status) when is_integer(EventType), is_binary(AssocUUID), is_integer(Status) -> + mysql_pool:insert(mysql_iot, <<"event_logs">>, #{ + <<"event_type">> => EventType, + <<"assoc_uuid">> => AssocUUID, + <<"status">> => Status, + <<"created_at">> => calendar:local_time() + }, true). \ No newline at end of file diff --git a/apps/iot/src/database/host_bo.erl b/apps/iot/src/database/host_bo.erl index d159e88..2d1cce3 100644 --- a/apps/iot/src/database/host_bo.erl +++ b/apps/iot/src/database/host_bo.erl @@ -33,4 +33,10 @@ get_host_by_id(HostId) when is_integer(HostId) -> %% 修改主机的状态 -spec change_status(UUID :: binary(), Status :: integer()) -> {ok, AffectedRows :: integer()} | {error, Reason :: any()}. change_status(UUID, Status) when is_binary(UUID), is_integer(Status) -> - mysql_pool:update_by(mysql_iot, <<"UPDATE host SET status = ? WHERE uuid = ? LIMIT 1">>, [Status, UUID]). \ No newline at end of file + case mysql_pool:update_by(mysql_iot, <<"UPDATE host SET status = ? WHERE uuid = ? LIMIT 1">>, [Status, UUID]) of + Result = {ok, _} -> + event_logs_bo:insert(?EVENT_HOST, UUID, Status), + Result; + Error -> + Error + end. diff --git a/apps/iot/src/iot_device.erl b/apps/iot/src/iot_device.erl index ebbfa2b..8f607d7 100644 --- a/apps/iot/src/iot_device.erl +++ b/apps/iot/src/iot_device.erl @@ -1,5 +1,4 @@ %%%------------------------------------------------------------------- -%%% @author aresei %%% @copyright (C) 2023, %%% @doc %%% @@ -28,7 +27,6 @@ -define(STATE_ACTIVATED, activated). -record(state, { - device_id :: integer(), device_uuid :: binary(), status = ?DEVICE_OFFLINE }). @@ -88,15 +86,15 @@ init([DeviceUUID]) when is_binary(DeviceUUID) -> end; init([DeviceInfo]) when is_map(DeviceInfo) -> init0(DeviceInfo). -init0(#{<<"device_uuid">> := DeviceUUID, <<"status">> := Status, <<"authorize_status">> := AuthorizeStatus, <<"id">> := DeviceId}) -> +init0(#{<<"device_uuid">> := DeviceUUID, <<"status">> := Status, <<"authorize_status">> := AuthorizeStatus}) -> case AuthorizeStatus =:= ?DEVICE_AUTH_AUTHED of true -> lager:debug("[iot_device] started device: ~p, state_name: ~p, status: ~p", [DeviceUUID, ?STATE_ACTIVATED, Status]), - {ok, ?STATE_ACTIVATED, #state{device_id = DeviceId, device_uuid = DeviceUUID, status = Status}}; + {ok, ?STATE_ACTIVATED, #state{device_uuid = DeviceUUID, status = Status}}; false -> - {ok, _} = device_bo:change_status(DeviceId, ?DEVICE_OFFLINE), + {ok, _} = device_bo:change_status(DeviceUUID, ?DEVICE_OFFLINE), lager:debug("[iot_device] started device: ~p, state_name: ~p, status: ~p", [DeviceUUID, ?STATE_DENIED, ?DEVICE_OFFLINE]), - {ok, ?STATE_DENIED, #state{device_id = DeviceId, device_uuid = DeviceUUID, status = ?DEVICE_OFFLINE}} + {ok, ?STATE_DENIED, #state{device_uuid = DeviceUUID, status = ?DEVICE_OFFLINE}} end. %% @private @@ -123,15 +121,15 @@ handle_event({call, From}, is_activated, StateName, State = #state{}) -> {keep_state, State, [{reply, From, StateName =:= ?STATE_ACTIVATED}]}; %% 改变数据库的状态, 离线状态事件必须执行(主动触发离线的情况很少,不会造成数据库眼里) -handle_event(cast, {change_status, ?DEVICE_OFFLINE}, ?STATE_ACTIVATED, State = #state{device_id = DeviceId}) -> - {ok, _} = device_bo:change_status(DeviceId, ?DEVICE_OFFLINE), +handle_event(cast, {change_status, ?DEVICE_OFFLINE}, ?STATE_ACTIVATED, State = #state{device_uuid = DeviceUUID}) -> + {ok, _} = device_bo:change_status(DeviceUUID, ?DEVICE_OFFLINE), {keep_state, State#state{status = ?DEVICE_OFFLINE}}; %% 改变为在线状态,但是数据库中的状态已经是在线状态,忽略 handle_event(cast, {change_status, ?DEVICE_ONLINE}, ?STATE_ACTIVATED, State = #state{status = ?DEVICE_ONLINE}) -> {keep_state, State}; %% 其他情况下需要修改数据状态为在线状态 -handle_event(cast, {change_status, ?DEVICE_ONLINE}, ?STATE_ACTIVATED, State = #state{device_id = DeviceId}) -> - {ok, _} = device_bo:change_status(DeviceId, ?DEVICE_ONLINE), +handle_event(cast, {change_status, ?DEVICE_ONLINE}, ?STATE_ACTIVATED, State = #state{device_uuid = DeviceUUID}) -> + {ok, _} = device_bo:change_status(DeviceUUID, ?DEVICE_ONLINE), {keep_state, State#state{status = ?DEVICE_ONLINE}}; %% 其他状态下不存在在线状态的变化 handle_event(cast, {change_status, _}, _, State = #state{}) -> @@ -141,13 +139,13 @@ handle_event(cast, {change_status, _}, _, State = #state{}) -> handle_event(cast, reload, _, State = #state{device_uuid = DeviceUUID}) -> lager:debug("[iot_device] will reload: ~p", [DeviceUUID]), case device_bo:get_device_by_uuid(DeviceUUID) of - {ok, #{<<"authorize_status">> := AuthorizeStatus, <<"id">> := DeviceId, <<"status">> := Status}} -> + {ok, #{<<"authorize_status">> := AuthorizeStatus, <<"status">> := Status}} -> case AuthorizeStatus =:= ?DEVICE_AUTH_AUTHED of true -> - {next_state, ?STATE_ACTIVATED, State#state{device_id = DeviceId, status = Status}}; + {next_state, ?STATE_ACTIVATED, State#state{status = Status}}; false -> - {ok, _} = device_bo:change_status(DeviceId, ?DEVICE_OFFLINE), - {next_state, ?STATE_DENIED, State#state{device_id = DeviceId, status = ?DEVICE_OFFLINE}} + {ok, _} = device_bo:change_status(DeviceUUID, ?DEVICE_OFFLINE), + {next_state, ?STATE_DENIED, State#state{status = ?DEVICE_OFFLINE}} end; undefined -> lager:warning("[iot_device] device uuid: ~p, loaded from mysql failed", [DeviceUUID]), @@ -155,9 +153,9 @@ handle_event(cast, reload, _, State = #state{device_uuid = DeviceUUID}) -> end; %% 处理授权 -handle_event(cast, {auth, false}, ?STATE_DENIED, State = #state{device_id = DeviceId, device_uuid = DeviceUUID}) -> +handle_event(cast, {auth, false}, ?STATE_DENIED, State = #state{device_uuid = DeviceUUID}) -> lager:debug("[iot_device] device_uuid: ~p, auth: false, will keep state_name: ~p", [DeviceUUID, ?STATE_DENIED]), - {ok, _} = device_bo:change_status(DeviceId, ?DEVICE_OFFLINE), + {ok, _} = device_bo:change_status(DeviceUUID, ?DEVICE_OFFLINE), {keep_state, State}; handle_event(cast, {auth, true}, ?STATE_DENIED, State) -> @@ -166,9 +164,9 @@ handle_event(cast, {auth, true}, ?STATE_DENIED, State) -> handle_event(cast, {auth, true}, ?STATE_ACTIVATED, State = #state{device_uuid = DeviceUUID}) -> lager:debug("[iot_device] device_uuid: ~p, auth: true, will keep state_name: ~p", [DeviceUUID, ?STATE_ACTIVATED]), {keep_state, State}; -handle_event(cast, {auth, false}, ?STATE_ACTIVATED, State = #state{device_id = DeviceId, device_uuid = DeviceUUID}) -> +handle_event(cast, {auth, false}, ?STATE_ACTIVATED, State = #state{device_uuid = DeviceUUID}) -> lager:debug("[iot_device] device_uuid: ~p, auth: false, state_name from: ~p, to: ~p", [DeviceUUID, ?STATE_ACTIVATED, ?STATE_DENIED]), - {ok, _} = device_bo:change_status(DeviceId, ?DEVICE_OFFLINE), + {ok, _} = device_bo:change_status(DeviceUUID, ?DEVICE_OFFLINE), {next_state, ?STATE_DENIED, State#state{status = ?DEVICE_OFFLINE}}. %% @private