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