brain remembers latest events (note design-problem: does not distinguish between...
[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     //~ "log"
11     )
12
13 type doorstate struct {
14     locked bool
15     shut bool
16 }
17
18 func MetaEventRoutine_Presence(ps *pubsub.PubSub) {
19     //~ var last_door_cmd *DoorCommandEvent
20     var last_presence bool
21     var last_movement, last_buttonpress int64
22     doorstatemap := make(map[int]doorstate,1)
23
24     events_chan := ps.Sub("door", "doorcmd", "buttons", "movement")
25     defer ps.Unsub(events_chan, "door", "doorcmd", "buttons", "movement")
26
27     for event := range(events_chan) {
28         //~ log.Printf("Presence: %s - %s", event, doorstatemap)
29         new_presence := last_presence
30         ts := time.Now().Unix()
31         switch evnt := event.(type) {
32             case r3events.SomethingReallyIsMoving:
33                 if evnt.Movement {
34                     last_movement = evnt.Ts
35                 } else {
36                     last_movement = 0
37                 }
38             case r3events.ButtonPressUpdate:
39                 last_buttonpress = evnt.Ts
40                 new_presence = true
41             //~ case DoorCommandEvent:
42                 //~ last_door_cmd = &evnt
43             case r3events.DoorLockUpdate:
44                 doorstatemap[evnt.DoorID]=doorstate{locked:evnt.Locked, shut:doorstatemap[evnt.DoorID].shut}
45             case r3events.DoorAjarUpdate:
46                 doorstatemap[evnt.DoorID]=doorstate{locked:doorstatemap[evnt.DoorID].locked, shut:evnt.Shut}
47         }
48
49         any_door_unlocked := false
50         any_door_ajar := false
51         for _, ds := range(doorstatemap) {
52             if ds.locked == false {any_door_unlocked = true }
53             if ds.shut == false {any_door_ajar = true }
54         }
55
56         if new_presence != last_presence {
57             //... skip state check .. we had a definite presence event
58         } else if any_door_unlocked || any_door_ajar {
59             new_presence = true
60         } else if last_movement != 0 || ts - last_buttonpress < 200 {
61             new_presence = true
62         } else {
63             new_presence = false
64         }
65         //~ log.Printf("Presence: new: %s , last:%s", new_presence, last_presence)
66         if new_presence != last_presence {
67             last_presence = new_presence
68             ps.Pub(r3events.PresenceUpdate{new_presence, ts} , "presence")
69         }
70     }
71 }