X-Git-Url: https://git.realraum.at/?p=svn42.git;a=blobdiff_plain;f=go%2Fdoor_daemon_zmq%2Fhandle_commands.go;fp=go%2Fdoor_daemon_zmq%2Fhandle_commands.go;h=0000000000000000000000000000000000000000;hp=1eb72e7beeb143cba50fb239bb24d27c199edbbc;hb=c775b5528f8f96e75c28264b9cea8525c6da9298;hpb=a87c91b7d4544703879b7ef6e472b863765e3949 diff --git a/go/door_daemon_zmq/handle_commands.go b/go/door_daemon_zmq/handle_commands.go deleted file mode 100644 index 1eb72e7..0000000 --- a/go/door_daemon_zmq/handle_commands.go +++ /dev/null @@ -1,108 +0,0 @@ -// (c) Bernhard Tittelbach, 2013 - -package main - -import ( - "errors" - "time" -) - -type DoorCmdHandler struct { - Checker func([][]byte) error - FirmwareChar string -} - -var cmdToDoorCmdHandler = map[string]DoorCmdHandler{ - "open": DoorCmdHandler{checkCmdDoorControl, "o"}, - "close": DoorCmdHandler{checkCmdDoorControl, "c"}, - "toggle": DoorCmdHandler{checkCmdDoorControl, "t"}, - "status": DoorCmdHandler{checkCmdNoArgs, "s"}, -} - -// ---------- Talk with Firmware directly in response to stuff it sends ------------ - -// The problem is this: -// If the key/motor turns just far enough so that the door is unlocked, -// but still get's blocked on the way (because the door clamped) -// the firmware will enter state "timeout_after_open" instead of "open" -// In this state, manual moving the key/cogwheel will not trigger the state "manual_movement" -// Users however will not notice that the door is in an error state and needs to manually be moved to the real open position, -// they have after all, already successfully entered the room. -// Without that information however, the r3-event-broker daemon, cannot tell if the door is being locked manuall from the inside -// or if someone else is locking the door for other reasons. -// Thus, if the door has been opened imperfectly and is then closed manually, it will trigger a presence=false event and switch off the lights. -// -// As Workaround, the door daemon watches for "timeout_after_open" events. -// If one is detected and followed by an "door is now ajar" info, we tell the firmware -// to open the door, causing it to move out of the error state and into the final open key/cogwheel position. -func WorkaroundFirmware(serial_wr chan string) (in chan [][]byte) { - in = make(chan [][]byte, 5) - go func() { - var last_state_time time.Time - var last_door_state string - for firmware_output := range in { - Debug_.Printf("WorkaroundFirmware Input: %s", firmware_output) - if len(firmware_output) > 1 && string(firmware_output[0]) == "State:" { - last_state_time = time.Now() - last_door_state = string(firmware_output[1]) - } - if len(firmware_output) == 5 && - string(firmware_output[0]) == "Info(ajar):" && - string(firmware_output[4]) == "ajar" && - time.Now().Sub(last_state_time) < 30*time.Second && - last_door_state == "timeout_after_open" { - //If we were in state "timeout_after_open" and within 30s the door was openend anyway, - //we send another "open" command - serial_wr <- cmdToDoorCmdHandler["open"].FirmwareChar - Syslog_.Print("Telling Firmware to open, since door was ajar'ed after timeout_after_open") - } - } - }() - return in -} - -// ---------- ZMQ Command Handling Code ------------- - -func checkCmdDoorControl(tokens [][]byte) error { - doorctrl_usage := "syntax: " - if len(tokens) < 2 || len(tokens) > 3 { - return errors.New(doorctrl_usage) - } - cmd := string(tokens[0]) - if !(cmd == "open" || cmd == "close" || cmd == "toggle") { - return errors.New(doorctrl_usage) - } - method := string(tokens[1]) - if !(method == "Button" || method == "ssh" || method == "SSH" || method == "Phone") { - return errors.New("method must be one either Button, SSH or Phone") - } - if (len(tokens) == 2 || len(tokens[2]) == 0) && method != "Button" { - return errors.New("Operator nickname must be given") - } - return nil -} - -func checkCmdNoArgs(tokens [][]byte) error { - if len(tokens) != 1 { - return errors.New("command does not accept arguments") - } - return nil -} - -func HandleCommand(tokens [][]byte, serial_wr chan string, serial_rd chan [][]byte) error { - if len(tokens) < 1 { - return errors.New("No Command to handle") - } - - dch, present := cmdToDoorCmdHandler[string(tokens[0])] - if !present { - return errors.New("Unknown Command") - } - - if err := dch.Checker(tokens); err != nil { - return err - } - - serial_wr <- dch.FirmwareChar - return nil -}