From c00593313e03ce45be97b5a90e09d6ffff5d9085 Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Mon, 25 Dec 2023 23:05:16 +0800 Subject: [PATCH] fix devices --- apps/iot/src/iot_database_buffer.erl | 114 --------------------------- apps/iot/src/iot_device.erl | 29 +++---- apps/iot/src/iot_device_sup.erl | 14 +++- apps/iot/src/iot_host.erl | 4 - apps/iot/src/iot_sup.erl | 9 --- 5 files changed, 26 insertions(+), 144 deletions(-) delete mode 100644 apps/iot/src/iot_database_buffer.erl diff --git a/apps/iot/src/iot_database_buffer.erl b/apps/iot/src/iot_database_buffer.erl deleted file mode 100644 index 0c5a367..0000000 --- a/apps/iot/src/iot_database_buffer.erl +++ /dev/null @@ -1,114 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author aresei -%%% @copyright (C) 2023, -%%% @doc -%%% -%%% @end -%%% Created : 25. 9月 2023 10:05 -%%%------------------------------------------------------------------- --module(iot_database_buffer). --author("aresei"). - --behaviour(gen_server). - -%% API --export([start_link/0]). --export([find_device/1]). - -%% gen_server callbacks --export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). - --define(SERVER, ?MODULE). - --record(state, { - devices_map = #{} :: map() -}). - -%%%=================================================================== -%%% API -%%%=================================================================== - --spec find_device(DeviceUUID :: binary()) -> error | {ok, Device :: map()}. -find_device(DeviceUUID) when is_binary(DeviceUUID) -> - gen_server:call(?MODULE, {find_device, DeviceUUID}). - -%% @doc Spawns the server and registers the local name (unique) --spec(start_link() -> - {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). -start_link() -> - gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). - -%%%=================================================================== -%%% gen_server callbacks -%%%=================================================================== - -%% @private -%% @doc Initializes the server --spec(init(Args :: term()) -> - {ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} | - {stop, Reason :: term()} | ignore). -init([]) -> - {ok, Devices} = device_bo:get_all_devices(), - DevicesMap = maps:from_list(lists:map(fun(Device = #{<<"device_uuid">> := DeviceUUID}) -> {DeviceUUID, Device} end, Devices)), - - erlang:start_timer(300 * 1000, self(), clean_up), - - {ok, #state{devices_map = DevicesMap}}. - -%% @private -%% @doc Handling call messages --spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()}, - State :: #state{}) -> - {reply, Reply :: term(), NewState :: #state{}} | - {reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} | - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), Reply :: term(), NewState :: #state{}} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_call({find_device, DeviceUUID}, _From, State = #state{devices_map = DevicesMap}) -> - case maps:take(DeviceUUID, DevicesMap) of - error -> - {reply, error, State}; - {DeviceInfo, NDevicesMap} -> - {reply, {ok, DeviceInfo}, State#state{devices_map = NDevicesMap}} - end. - -%% @private -%% @doc Handling cast messages --spec(handle_cast(Request :: term(), State :: #state{}) -> - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_cast(_Request, State = #state{}) -> - {noreply, State}. - -%% @private -%% @doc Handling all non call/cast messages --spec(handle_info(Info :: timeout() | term(), State :: #state{}) -> - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_info({timeout, _, clean_up}, State = #state{}) -> - {noreply, State#state{devices_map = #{}}}. - -%% @private -%% @doc This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any -%% necessary cleaning up. When it returns, the gen_server terminates -%% with Reason. The return value is ignored. --spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()), - State :: #state{}) -> term()). -terminate(_Reason, _State = #state{}) -> - ok. - -%% @private -%% @doc Convert process state when code is changed --spec(code_change(OldVsn :: term() | {down, term()}, State :: #state{}, - Extra :: term()) -> - {ok, NewState :: #state{}} | {error, Reason :: term()}). -code_change(_OldVsn, State = #state{}, _Extra) -> - {ok, State}. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== diff --git a/apps/iot/src/iot_device.erl b/apps/iot/src/iot_device.erl index d1f36c2..3a09fed 100644 --- a/apps/iot/src/iot_device.erl +++ b/apps/iot/src/iot_device.erl @@ -81,7 +81,9 @@ auth(Pid, Auth) when is_pid(Pid), is_boolean(Auth) -> %% initialize. To ensure a synchronized start-up procedure, this %% function does not return until Module:init/1 has returned. start_link(Name, DeviceUUID) when is_atom(Name), is_binary(DeviceUUID) -> - gen_statem:start_link({local, Name}, ?MODULE, [DeviceUUID], []). + gen_statem:start_link({local, Name}, ?MODULE, [DeviceUUID], []); +start_link(Name, DeviceInfo) when is_atom(Name), is_map(DeviceInfo) -> + gen_statem:start_link({local, Name}, ?MODULE, [DeviceInfo], []). %%%=================================================================== %%% gen_statem callbacks @@ -92,24 +94,19 @@ start_link(Name, DeviceUUID) when is_atom(Name), is_binary(DeviceUUID) -> %% gen_statem:start_link/[3,4], this function is called by the new %% process to initialize. init([DeviceUUID]) when is_binary(DeviceUUID) -> - DeviceInfo1 = case iot_database_buffer:find_device(DeviceUUID) of - error -> - device_bo:get_device_by_uuid(DeviceUUID); - {ok, DeviceInfo} -> - {ok, DeviceInfo} - end, - - case DeviceInfo1 of - {ok, #{<<"authorize_status">> := AuthorizeStatus, <<"status">> := Status}} -> - case AuthorizeStatus =:= ?DEVICE_AUTH_AUTHED of - true -> - {ok, ?STATE_ACTIVATED, #state{device_uuid = DeviceUUID, status = Status}}; - false -> - {ok, ?STATE_DENIED, #state{device_uuid = DeviceUUID, status = Status}} - end; + case device_bo:get_device_by_uuid(DeviceUUID) of + {ok, DeviceInfo} -> + init([DeviceInfo]); undefined -> lager:warning("[iot_device] device uuid: ~p, loaded from mysql failed", [DeviceUUID]), ignore + end; +init([DeviceInfo = #{<<"device_uuid">> := DeviceUUID, <<"authorize_status">> := AuthorizeStatus, <<"status">> := Status}]) when is_map(DeviceInfo) -> + case AuthorizeStatus =:= ?DEVICE_AUTH_AUTHED of + true -> + {ok, ?STATE_ACTIVATED, #state{device_uuid = DeviceUUID, status = Status}}; + false -> + {ok, ?STATE_DENIED, #state{device_uuid = DeviceUUID, status = Status}} end. %% @private diff --git a/apps/iot/src/iot_device_sup.erl b/apps/iot/src/iot_device_sup.erl index c7dc12d..6af3d70 100644 --- a/apps/iot/src/iot_device_sup.erl +++ b/apps/iot/src/iot_device_sup.erl @@ -15,7 +15,11 @@ start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). init([]) -> - {ok, {#{strategy => one_for_one, intensity => 1000, period => 3600}, []}}. + %% 启动主机相关的devices + {ok, DeviceInfos} = device_bo:get_all_devices(), + Specs = lists:map(fun child_spec/1, DeviceInfos), + + {ok, {#{strategy => one_for_one, intensity => 1000, period => 3600}, [Specs]}}. -spec ensured_device_started(UUID :: binary()) -> {ok, Pid :: pid()} | {error, Reason :: any()}. ensured_device_started(DeviceUUID) when is_binary(DeviceUUID) -> @@ -45,4 +49,12 @@ child_spec(DeviceUUID) when is_binary(DeviceUUID) -> restart => permanent, shutdown => 2000, type => worker, + modules => ['iot_device']}; +child_spec(DeviceInfo = #{<<"device_uuid">> := DeviceUUID}) when is_binary(DeviceUUID) -> + Name = iot_device:get_name(DeviceUUID), + #{id => Name, + start => {iot_device, start_link, [Name, DeviceInfo]}, + restart => permanent, + shutdown => 2000, + type => worker, modules => ['iot_device']}. \ No newline at end of file diff --git a/apps/iot/src/iot_host.erl b/apps/iot/src/iot_host.erl index 4cc274d..718a023 100644 --- a/apps/iot/src/iot_host.erl +++ b/apps/iot/src/iot_host.erl @@ -197,10 +197,6 @@ init([UUID]) -> %% 心跳检测机制 erlang:start_timer(?HEARTBEAT_INTERVAL, self(), heartbeat_ticker), - %% 启动主机相关的devices - {ok, Devices} = device_bo:get_host_devices(HostId), - lists:foreach(fun iot_device_sup:ensured_device_started/1, Devices), - StateName = case AuthorizeStatus =:= 1 of true -> ?STATE_ACTIVATED; false -> ?STATE_DENIED diff --git a/apps/iot/src/iot_sup.erl b/apps/iot/src/iot_sup.erl index e0b76cf..6cd29d5 100644 --- a/apps/iot/src/iot_sup.erl +++ b/apps/iot/src/iot_sup.erl @@ -37,15 +37,6 @@ init([]) -> modules => ['iot_api'] }, - #{ - id => 'iot_database_buffer', - start => {'iot_database_buffer', start_link, []}, - restart => permanent, - shutdown => 2000, - type => supervisor, - modules => ['iot_database_buffer'] - }, - #{ id => 'iot_device_sup', start => {'iot_device_sup', start_link, []},