Detecting device status changes
Code similar to the following can be used to detect when a device goes offline:
CREATE TYPE MyUser (
name java.lang.String ,
myid java.lang.String
) ;
CREATE CACHE LoadIDsCache USING FileReader (
wildcard: 'user.csv',
directory: '.'
)
PARSE USING Global.DSVParser ()
QUERY ( keytomap: 'myid' ) OF MyUser;
CREATE CQ PopulateMasterStream
INSERT INTO MasterStream
SELECT * FROM admin.LoadIDsCache c, heartbeat(interval 5 second) h;
CREATE WINDOW MasterWinow OVER MasterStream KEEP 1 ROWS PARTITION BY myid;
CREATE SOURCE LiveEventStream USING TCPReader (
IPAddress: 'localhost',
portno: 1234
)
PARSE USING DSVParser ()
headerlineno: 0
)
OUTPUT TO liveEvStream ;
CREATE OR REPLACE CQ CreateLiveEventsCQ
INSERT INTO liveObjectStream
SELECT TO_STRING(data[0]) as myId FROM liveEvStream l;
CREATE OR REPLACE JUMPING WINDOW LiveObjWindow
OVER liveObjectStream KEEP 1 ROWS WITHIN 10 second PARTITION BY myId;
/* select * from admin.NonExistObjStream;
[
myID = 1
cnt = 1
status = existent
]
[
myID = null
cnt = 4
status = non-existent
]
*/
select lw.myId as myID, count(*) as cnt,
CASE WHEN lw.myId IS NULL
THEN "non-existent"
ELSE "existent" END as status
from MasterWinow mw
left join LiveObjWindow lw on mw.myid = lw.myId
group by lw.myId;
The cache file has the format:
device_name_a,1 device_name_b,2 ...
Code similar to the following can be used detect both when a device goes offline and comes back online:
CREATE OR REPLACE CQ UserStateCQ INSERT INTO CurrentUserStateStream SELECT lw.myId as myID, count(*) as cnt, DNOW() as StateTime, CASE WHEN lw.myId IS NULL THEN "offline" ELSE "online" END as status FROM MasterWinow mw LEFT JOIN LiveObjWindow lw on mw.myid = lw.myId GROUP BY lw.myId; CREATE SLIDING WINDOW UserState OVER CurrentUserStateStream KEEP 2 ROW PARTITION BY myId; CREATE OR REPLACE CQ WatchUserStateCQ INSERT INTO ChangedUserStateStream SELECT lw.myId as myID, TO_LONG(LAST(w.StateTime) - FIRST(w.StateTime)) as StateChangeInterval, CASE WHEN LAST(w.status) == 'online' AND FIRST(w.status) == 'online' THEN "up" WHEN LAST(w.status) == 'online' AND FIRST(w.status) == 'offline' THEN "online" WHEN LAST(w.status) == 'offline' AND FIRST(w.status) == 'online' THEN "down" WHEN LAST(w.status) == 'offline' AND FIRST(w.status) == 'offline' THEN "offline" END as ChangeLabel FROM UserState w GROUP BY w.myID HAVING ChangeLabel = 'down' OR ChangeLabel ='online';
The two-row window acts as a two-node state machine. The addition of a CQ can generate events that meet business requirements:
alerts on state changes
accumulating statistics on device uptime, downtime, frequency of change, and so on