diff options
Diffstat (limited to 'devicemon.erl')
-rw-r--r-- | devicemon.erl | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/devicemon.erl b/devicemon.erl new file mode 100644 index 0000000..84c2849 --- /dev/null +++ b/devicemon.erl @@ -0,0 +1,112 @@ +%%%------------------------------------------------------------------- +%%% @author Joe Zhao +%%% @copyright (C) 2014, <COMPANY> +%%% @doc +%%% This modules monitors different devices which includes registering devices when linked and monitoring their states. +%%% Registering devices and deregister them are done automatically when device are on/off line. +%%% Other than that the changing states of different devices is recorded, and boardcast / return when queried. +%%% @end +%%% Created : 29. 四月 2014 15:35 +%%%------------------------------------------------------------------- +-module(devicemon). +-author("Joe Zhao"). + +-compile([debug_info,export_all]). + +-include("devicemon.hrl"). + +%% API +%% -export([]). + +-define(QTOUT,100). + +cleanloop() -> +%% Cleanup the message queue -> Don't call it + receive + _ -> cleanloop() + after 0 -> + ok + end. + +deviceloop(Devices) -> + receive + %% Basic Ops within server + {Pid,shutdown} -> ok; + {Pid,reg,Addr,Type} -> + %% Register -> auto replace + deviceloop(orddict:store(Addr,#device{type=Type},Devices)); + {Pid,reg,Addr,Type,State} -> + deviceloop(orddict:store(Addr,#device{type=Type,state = State},Devices)); + {Pid,dereg,Addr} -> + %% Register -> auto remove + case orddict:find(Addr,Devices) of + error -> deviceloop(Devices); + _Else -> deviceloop(orddict:erase(Addr,Devices)) + end; + {Pid,stat,Addr} -> + case orddict:find(Addr,Devices) of + error -> Pid ! {self(),Addr,error}; + {ok,Value} -> Pid ! {self(),Addr,Value} + end, + deviceloop(Devices); + + %% Query about device list & status + %% Next step: remembering states + {Pid,comm,[0]} -> % General query + Pid ! {self(),comm,orddict:fold(fun(Key,Val,Acc) -> [Key,Val#device.type]++Val#device.state++Acc end, [],Devices)}, + deviceloop(Devices); + {Pid,comm,[0,Addr]} -> % Specific query, this also shouldn't happen. + Dev=orddict:fetch(Addr,Devices), + Pid ! {self(),comm,[Dev#device.type]++Dev#device.state}, + deviceloop(Devices); + + %% Messages received from rsbus + {Pid,device,Addr,{error,Cause}} -> + io:format("[Device Err]Device address: ~p Error: ~p \n",[Addr,Cause]), + self() ! {self(),dereg,Addr}, + deviceloop(Devices); + {Pid,device,Addr,{stat,Type,Msg}} -> + tcpserv ! {self(),comm,[Addr,Type|Msg]}, + deviceloop(orddict:store(Addr,#device{type=Type,state = Msg},Devices)); + + %% Messages received from some other server -> redirect to rsbus + {Pid,comm,[Addr|Msg]} -> + rsbusserv ! {self(),comm,Addr,Msg}, + deviceloop(Devices); + + %% General ops + {Pid,clean} -> % Clean message queue -> use it when garbage might be cloting the server + cleanloop(), + deviceloop(Devices); + {Pid,heartbeat,Addr} -> % Specific heartbeat !!! Good stuff + self() ! {self(),comm,[Addr]}, + deviceloop(Devices); + {Pid,heartbeat} -> % This type of heartbeat will cause congestion, use with caution + [self() ! {self(),comm,[Addr]}|| Addr <- lists:seq(1,?ADDRANGE)], + deviceloop(Devices) + end. + +devicemon() -> + register(?MODULE,self()), + spawn(?MODULE,devicepool,[?ADDRANGE]), + deviceloop(orddict:new()). + +getStat(Addr) -> + devicemon ! {self(),stat,Addr}, + receive + {_Pid,Addr,error} -> error; + {_Pid,Addr,Val} -> Val + after ?QTOUT -> + error + end. + +getStaus(Addr) -> + case getStat(Addr) of + error -> error; + Val -> Val + %% device status multiplexer + %% ready | busy + end. + +start() -> + spawn(?MODULE,devicemon,[]).
\ No newline at end of file |