func main() {
zmqctx, sub_in_chans, pub_out_socket, keylookup_socket := ZmqsInit(doorsub_addr_, sensorssub_port_, pub_port_, keylookup_addr_)
+ if sub_in_chans != nil {defer sub_in_chans.Close()}
defer zmqctx.Close()
- defer sub_in_chans.Close()
- defer pub_out_socket.Close()
- defer keylookup_socket.Close()
-
+ if pub_out_socket != nil {defer pub_out_socket.Close()}
+ if keylookup_socket != nil {defer keylookup_socket.Close()}
if sub_in_chans == nil || pub_out_socket == nil || keylookup_socket == nil {
panic("zmq sockets must not be nil !!")
}
-
if use_syslog_ {
var logerr error
Syslog_, logerr = syslog.NewLogger(syslog.LOG_INFO | (18<<3), 0)
Syslog_.Print("started")
defer Syslog_.Print("exiting")
}
-
+
ps := pubsub.New(3)
//~ ticker := time.NewTicker(time.Duration(5) * time.Minute)
publish_these_events_chan := ps.Sub("door", "doorcmd", "presence", "sensors", "buttons", "movement")
-
+
go MetaEventRoutine_Movement(ps, 10, 20, 10)
go MetaEventRoutine_Presence(ps)
-
- for xx := range(sub_in_chans.In()) {
- log.Print(xx)
- Syslog_.Print(xx)
- }
-
-
+
for {
- log.Print("for loop")
select {
case subin := <- sub_in_chans.In():
ParseSocketInputLine(subin, ps, keylookup_socket)
//~ MakeTimeTick(ps)
case event_interface := <- publish_these_events_chan:
data, err := FormatEventForSocket(event_interface)
- log.Print("publishing", data)
+ log.Printf("publishing %s",data)
if err != nil {
- Syslog_.Print(err)
+ if Syslog_ != nil {Syslog_.Print(err)}
continue
}
if err := pub_out_socket.Send(data); err != nil {
}
}
- //~ nick, err := keylookup_socket.LookupCardIdNick(keyhexid)
-
}
#!/bin/zsh
export GO386=387
export CGO_ENABLED=1
-go clean
+go-linux-386 clean
#go-linux-386 build
#strip ${PWD:t}
-go build -ldflags "-s" && rsync -v ${PWD:t} wuzzler.realraum.at:/flash/tuer/
+go-linux-386 build -ldflags "-s" && rsync -v ${PWD:t} wuzzler.realraum.at:/flash/tuer/
movement_window := ring.New(granularity+1)
events_chan := ps.Sub("movement")
myticker := time.NewTicker(time.Duration(gran_duration) * time.Second)
-
+
for { select {
case event := <- events_chan:
switch event.(type) {
ps.Pub( SomethingReallyIsMoving{true,ts}, "movement")
last_movement = ts
}
-
+
if last_movement > 0 && ts - last_movement < 3600*6 && ts - last_movement > 3600*3 {
last_movement = 0
ps.Pub( SomethingReallyIsMoving{false, ts}, "movement")
//~ var last_door_cmd *DoorCommandEvent
var last_presence bool
var last_movement, last_buttonpress int64
- doorstatemap := make(map[byte]doorstate,1)
+ doorstatemap := make(map[int]doorstate,1)
events_chan := ps.Sub("door", "doorcmd", "buttons", "movement")
-
+
for event := range(events_chan) {
new_presence := last_presence
ts := time.Now().Unix()
case DoorAjarUpdate:
doorstatemap[evnt.DoorID]=doorstate{locked:doorstatemap[evnt.DoorID].locked, shut:evnt.Shut}
}
-
+
any_door_unlocked := false
any_door_ajar := false
for _, ds := range(doorstatemap) {
if ds.locked == false {any_door_unlocked = true }
if ds.shut == false {any_door_ajar = true }
}
-
+
if new_presence != last_presence {
//... skip state check .. we had a definite presence event
} else if any_door_unlocked || any_door_ajar {
} else {
new_presence = false
}
-
+
if new_presence != last_presence {
last_presence = new_presence
ps.Pub(PresenceUpdate{new_presence, ts} , "presence")
//~ "./brain"
"encoding/json"
pubsub "github.com/tuxychandru/pubsub"
- zmq "github.com/vaughan0/go-zmq"
+ zmq "github.com/vaughan0/go-zmq"
"log"
+ "fmt"
)
var (
type DoorLockUpdate struct {
- DoorID byte
+ DoorID int
Locked bool
Ts int64
}
type DoorAjarUpdate struct {
- DoorID byte
+ DoorID int
Shut bool
Ts int64
}
case "timeout": //after open | after close
case "opening":
case "closing":
- default:
+ default:
}
}
var tidbit interface{}
ts := time.Now().Unix()
if len(lines) < 1 { return }
- log.Print("ParseSocketInputLine",string(lines[0]))
+ log.Printf("ParseSocketInputLine: %s %s",string(lines[0]), lines[1:])
switch string(lines[0]) {
case "State:":
if len(lines) < 2 { return }
ps.Pub(tidbit, "door")
tidbit = DoorAjarUpdate{0, string(lines[len(lines)-2]) == "shut", ts}
//~ brn.Oboite("door", tidbit)
- ps.Pub(tidbit, "door")
+ ps.Pub(tidbit, "door")
case "Info(card):":
if len(lines) < 3 { return }
if string(lines[2]) != "found" { return }
if len(lines) < 5 { return }
tidbit = DoorAjarUpdate{0, string(lines[4]) == "shut", ts}
//~ brn.Oboite("door", tidbit)
- ps.Pub(tidbit, "door")
+ ps.Pub(tidbit, "door")
case "open", "close", "toggle", "reset":
ps.Pub(DoorCommandEvent{string(lines[0]), string(lines[1]), string(lines[2]), ts},"doorcmd")
case "photo0":
}
func FormatEventForSocket(event_interface interface{}) (data [][]byte, err error) {
- msg, err := json.Marshal(data)
+ var msg []byte
+ fmt.Printf("%T%+v\n", event_interface, event_interface)
+ etype := fmt.Sprintf("%T", event_interface)[5:]
+ msg, err = json.Marshal(map[string]interface{}{etype: event_interface})
if err != nil {
return
}
- return [][]byte{msg}, nil
+ data = [][]byte{msg}
+ return
}
//~ match_presence := re_presence_.FindStringSubmatch(line)
}
defer func() { if r:= recover(); r != nil { sub_sock.Close(); panic(r) } }()
+ sub_sock.Subscribe([]byte{}) //subscribe empty filter -> aka to all messages
+
if err = sub_sock.Bind(sub_listen_port); err != nil {
panic(err)
}
}
if len(pub_port) > 0 {
- pub_sock, err := ctx.Socket(zmq.Pub)
+ pub_sock, err = ctx.Socket(zmq.Pub)
if err != nil {
panic(err)
}
}
if len(keylookup_port) > 0 {
- keylookup_sock, err := ctx.Socket(zmq.Req)
+ keylookup_sock, err = ctx.Socket(zmq.Req)
if err != nil {
panic(err)
}
answ := ZmqsRequestAnswer(s, [][]byte{hexbytes})
if len(answ) == 0 {
return "", errors.New("Empty reply received")
- }
+ }
if bytes.Compare(answ[0], []byte("ERROR")) == 0 {
return "", errors.New(string(bytes.Join(answ[1:],[]byte(" "))))
}