summaryrefslogtreecommitdiff
path: root/devicemon.erl
diff options
context:
space:
mode:
Diffstat (limited to 'devicemon.erl')
-rw-r--r--devicemon.erl112
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