aac99f51348d57ddfdd8b5ca83415ea151d4c4df
[svn42.git] / go / r3-eventbroker_zmq / presence.go
1 // (c) Bernhard Tittelbach, 2013
2
3 package main
4
5 import (
6     "time"
7     //~ "./brain"
8     pubsub "github.com/tuxychandru/pubsub"
9     "./r3events"
10     )
11
12 type doorstate struct {
13     locked bool
14     shut bool
15 }
16
17 func MetaEventRoutine_Presence(ps *pubsub.PubSub) {
18     //~ var last_door_cmd *DoorCommandEvent
19     var last_presence bool
20     var last_movement, last_buttonpress int64
21     doorstatemap := make(map[int]doorstate,1)
22
23     events_chan := ps.Sub("door", "doorcmd", "buttons", "movement")
24
25     for event := range(events_chan) {
26         new_presence := last_presence
27         ts := time.Now().Unix()
28         switch evnt := event.(type) {
29             case r3events.SomethingReallyIsMoving:
30                 if evnt.Movement {
31                     last_movement = evnt.Ts
32                 } else {
33                     last_movement = 0
34                 }
35             case r3events.ButtonPressUpdate:
36                 last_buttonpress = evnt.Ts
37                 new_presence = true
38             //~ case DoorCommandEvent:
39                 //~ last_door_cmd = &evnt
40             case r3events.DoorLockUpdate:
41                 doorstatemap[evnt.DoorID]=doorstate{locked:evnt.Locked, shut:doorstatemap[evnt.DoorID].shut}
42             case r3events.DoorAjarUpdate:
43                 doorstatemap[evnt.DoorID]=doorstate{locked:doorstatemap[evnt.DoorID].locked, shut:evnt.Shut}
44         }
45
46         any_door_unlocked := false
47         any_door_ajar := false
48         for _, ds := range(doorstatemap) {
49             if ds.locked == false {any_door_unlocked = true }
50             if ds.shut == false {any_door_ajar = true }
51         }
52
53         if new_presence != last_presence {
54             //... skip state check .. we had a definite presence event
55         } else if any_door_unlocked || any_door_ajar {
56             new_presence = true
57         } else if last_movement != 0 || ts - last_buttonpress < 200 {
58             new_presence = true
59         } else {
60             new_presence = false
61         }
62
63         if new_presence != last_presence {
64             last_presence = new_presence
65             ps.Pub(r3events.PresenceUpdate{new_presence, ts} , "presence")
66         }
67     }
68 }