1 // (c) Bernhard Tittelbach, 2013
8 pubsub "github.com/tuxychandru/pubsub"
9 r3events "svn.spreadspace.org/realraum/go.svn/r3events"
12 func MetaEventRoutine_Presence(ps *pubsub.PubSub, movement_timeout, button_timeout int64) {
13 var last_door_cmd *r3events.DoorCommandEvent
14 var last_presence bool
15 var last_event_indicating_presence, last_frontlock_use, last_manual_lockhandling int64
16 var front_locked, front_shut, back_shut bool = true, true, true
18 events_chan := ps.Sub("door", "doorcmd", "buttons", "movement")
19 defer ps.Unsub(events_chan, "door", "doorcmd", "buttons", "movement")
21 for event := range(events_chan) {
22 Debug_.Printf("Presence prior: %t : %T %+v", last_presence, event, event)
23 new_presence := last_presence
24 ts := time.Now().Unix()
25 switch evnt := event.(type) {
26 case r3events.SomethingReallyIsMoving:
28 //ignore movements that happened just after locking door
29 if (evnt.Ts - last_event_indicating_presence) > movement_timeout {
32 last_event_indicating_presence = evnt.Ts
34 if last_presence { Syslog_.Printf("Presence: Mhh, SomethingReallyIsMoving{%+v} received but presence still true. Quite still a bunch we have here.", evnt) }
35 if front_locked && front_shut && back_shut && evnt.Confidence >= 20 && last_event_indicating_presence > 1800 {
39 case r3events.BoreDoomButtonPressEvent:
41 last_event_indicating_presence = evnt.Ts
42 case r3events.DoorCommandEvent:
44 case r3events.DoorManualMovementEvent:
45 last_manual_lockhandling = evnt.Ts
46 last_event_indicating_presence = evnt.Ts
47 case r3events.DoorLockUpdate:
48 front_locked = evnt.Locked
49 last_frontlock_use = evnt.Ts
50 last_event_indicating_presence = evnt.Ts
51 case r3events.DoorAjarUpdate:
52 if front_shut == false && evnt.Shut && front_locked && evnt.Ts - last_frontlock_use > 2 {
53 Syslog_.Print("Presence: ignoring frontdoor ajar event, since obviously someone is fooling around with the microswitch while the door is still open")
55 front_shut = evnt.Shut
57 last_event_indicating_presence = evnt.Ts
58 case r3events.BackdoorAjarUpdate:
60 last_event_indicating_presence = evnt.Ts
63 any_door_unlocked := (front_locked == false)
64 any_door_ajar := ! (front_shut && back_shut)
66 if new_presence != last_presence {
67 //... skip state check .. we had a definite presence event
68 } else if any_door_unlocked || any_door_ajar {
70 } else if last_door_cmd != nil && (last_door_cmd.Using == "Button" || last_door_cmd.Ts < last_manual_lockhandling) {
75 //~ Debug_.Printf("Presence: new: %s , last:%s", new_presence, last_presence)
76 if new_presence != last_presence {
77 last_presence = new_presence
78 ps.Pub(r3events.PresenceUpdate{new_presence, ts} , "presence")