From 4e521b7af1473e139cdd79332086eb2139de3990 Mon Sep 17 00:00:00 2001 From: realraum Date: Thu, 30 Apr 2009 01:09:34 +0000 Subject: [PATCH] python --- door_daemon.pl | 27 +++++--- door_daemon.py | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++++ firmware/tuer.pde | 2 +- 3 files changed, 201 insertions(+), 11 deletions(-) create mode 100755 door_daemon.py diff --git a/door_daemon.pl b/door_daemon.pl index 8aa48c4..ce14364 100755 --- a/door_daemon.pl +++ b/door_daemon.pl @@ -6,8 +6,8 @@ use Date::Format; use Fcntl; use strict; -my $url_door_open = "https://www.realraum.at/"; -my $url_door_closed = "https://www.realraum.at/"; +my $url_door_open = 'https://www.realraum.at/cgi/status.cgi?pass=jako16&set=%3Chtml%3E%3Cbody%20bgcolor=%22lime%22%3E%3Ch3%3E%3Ccenter%3ETuer%20ist%20Offen%3C/center%3E%3C/h3%3E%3C/body%3E%3C/html%3E'; +my $url_door_closed = 'https://www.realraum.at/cgi/status.cgi?pass=jako16&set=%3Chtml%3E%3Cbody%20bgcolor=%22red%22%3E%3Ch3%3E%3Ccenter%3ETuer%20ist%20Geschlossen%3C/center%3E%3C/h3%3E%3C/body%3E%3C/html%3E'; my $door_ttyusb_dev = "/dev/ttyUSB0"; my $fifofile = "/tmp/door_cmd.fifo"; @@ -24,7 +24,9 @@ open($logfile,'>>/var/log/tuer.log'); $logfile->autoflush(1); sub door_log { - print $logfile Date::Format::time2str("%Y-%m-%d %T: ",time()).shift()."\n"; + my $msg=shift; + chomp($msg); + print $logfile Date::Format::time2str("%Y-%m-%d %T: ",time()).$msg."\n"; } door_log("Door Daemon started"); @@ -41,6 +43,7 @@ my $ttyusb=undef; sub handler { #local($sig) = @_; + print $ttyusb "c" if (defined $ttyusb); door_log("Door Daemon stopped"); close $logfile; close $fifo if (defined $fifo); @@ -97,11 +100,12 @@ while(1) { my ($rh_set) = IO::Select->select($read_set, undef, undef); #print "tuer_status_start: ".$main::tuer_status,"\n"; + sleep(1); #give other end time to finish writing... (bad fix) foreach my $fh (@$rh_set) { if ($fh == $fifo) { - my $fifo_msg = <$fh>; + my $fifo_msg = readline($fh); unless ($fifo_msg) { close_fifo(); @@ -116,7 +120,7 @@ while(1) } elsif ($fh == $ttyusb) { - my $ttyusb_msg = <$fh>; + my $ttyusb_msg = readline($fh); last unless ($ttyusb_msg); #print($ttyusb_msg); door_log($door_ttyusb_dev.": ".$ttyusb_msg); @@ -132,18 +136,21 @@ while(1) my $tuer=$main::tuer_status; $tuer=$main::door_open if $ttyusb_msg =~ /open/; $tuer=$main::door_closed if $ttyusb_msg =~ /close|closing/; - if (not $tuer == $main::tuer_status) + door_log("$tuer"); + if (not ($tuer == $main::tuer_status)) { $main::tuer_status=$tuer; if ($tuer == $main::door_open) { + door_log("change to opened"); #print "change to open\n"; - system('wget --no-check-certificate -q -O /dev/null '.$url_door_open.' &>/dev/null &'); + system('wget --no-check-certificate -q -O /dev/null "'.$url_door_open.'" &>/dev/null &'); } else { #print "change to closed\n"; - system('wget --no-check-certificate -q -O /dev/null '.$url_door_closed.' &>/dev/null &'); + door_log("change to closed"); + system('wget --no-check-certificate -q -O /dev/null "'.$url_door_closed.'" &>/dev/null &'); } } } @@ -170,13 +177,13 @@ sub handle_cmd { door_log("Door opened by $who"); print $ttyusb "o"; - system('wget --no-check-certificate -q -O /dev/null '.$url_door_open.' &>/dev/null &'); + system('wget --no-check-certificate -q -O /dev/null "'.$url_door_open.'" &>/dev/null &'); } else { door_log("Door closed by $who"); print $ttyusb "c"; - system('wget --no-check-certificate -q -O /dev/null '.$url_door_closed.' &>/dev/null &'); + system('wget --no-check-certificate -q -O /dev/null "'.$url_door_closed.'" &>/dev/null &'); } } diff --git a/door_daemon.py b/door_daemon.py new file mode 100755 index 0000000..903d6cf --- /dev/null +++ b/door_daemon.py @@ -0,0 +1,183 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +import os +import sys +import threading +import logging +import urllib +import time +import signal +import re + +logging.basicConfig(level=logging.INFO,filename='/var/log/tuer.log') + +class StatusDisplay(object): + def __init__(self): + self.url_open = 'https://www.realraum.at/cgi/status.cgi?pass=jako16&set=%3Chtml%3E%3Cbody%20bgcolor=%22lime%22%3E%3Ch3%3E%3Ccenter%3ETuer%20ist%20Offen%3C/center%3E%3C/h3%3E%3C/body%3E%3C/html%3E'; + self.url_closed = 'https://www.realraum.at/cgi/status.cgi?pass=jako16&set=%3Chtml%3E%3Cbody%20bgcolor=%22red%22%3E%3Ch3%3E%3Ccenter%3ETuer%20ist%20Geschlossen%3C/center%3E%3C/h3%3E%3C/body%3E%3C/html%3E'; + self.last_status_set=self.url_open + #object.__init__(self) + + def display_open(self): + if self.last_status_set != self.url_open: + self.last_status_set=self.url_open + f = urllib.urlopen(self.last_status_set) + f.close() + + def display_closed(self): + if self.last_status_set != self.url_closed: + self.last_status_set=self.url_closed + f = urllib.urlopen(self.last_status_set) + f.close() + + +class ArduinoUSBThread ( threading.Thread ): + def __init__(self, file_dev_ttyusb): + self.re_isidle = re.compile(r'open') + self.re_isopen = re.compile(r'open') + self.re_isclosed = re.compile(r'close|closing') + self.re_toolong = re.compile(r'took too long!') + self.min_seconds_between_reset=10; + self.timestamp_send_reset=0; + self.running=True + self.lastline="" + self.last_status=None + self.cv_updatestatus = threading.Condition(); #lock ist automatically created withing condition + self.file_dev_ttyusb=file_dev_ttyusb + self.statusdisplay = StatusDisplay() + threading.Thread.__init__(self) + + def stop(self): + self.running=False + self.fh.close() + + def send_open(self): + self.send_statusrequest() + self.cv_updatestatus.acquire() + self.cv_updatestatus.wait(3.0) + self.cv_updatestatus.release() + if re_isidle.search(self.lastline): + logging.info("Opening Door") + self.fh.write("o"); + + def send_close(self): + self.send_statusrequest() + self.cv_updatestatus.acquire() + self.cv_updatestatus.wait(3.0) + self.cv_updatestatus.release() + if re_isidle.search(self.lastline): + logging.info("Closing Door") + self.fh.write("c"); + + def send_toggle(self): + self.send_statusrequest() + self.cv_updatestatus.acquire() + self.cv_updatestatus.wait(3.0) + self.cv_updatestatus.release() + if re_isidle.search(self.lastline): + if self.last_status == "open": + logging.info("Closing Door") + self.fh.write("c"); + elif self.last_status == "closed": + logging.info("Opening Door") + self.fh.write("o"); + + def send_reset(self): + logging.info("Resetting Door") + self.fh.write("r"); + + def send_statusrequest(self): + self.fh.write("s"); + + def run (self): + self.fh = open(self.file_dev_ttyusb,"rw") + while (self.running): + print "." + line = self.fh.readline(); + self.cv_updatestatus.acquire() + self.lastline=line + logging.info(self.file_dev_ttyusb+": "+self.lastline) + if self.re_isclosed.search(self.lastline): + self.last_status="closed" + self.statusdisplay.display_open() + elif self.re_isopen.search(self.lastline): + self.last_status="open" + self.statusdisplay.display_closed() + elif self.re_toolong.search(self.lastline): + self.last_status="error" + if (time.time() - self.timestamp_send_reset) > self.min_seconds_between_reset: + self.timestamp_send_reset=time.time() + self.send_reset() + self.cv_updatestatus.notifyAll() + self.cv_updatestatus.release() + if self.fh: + self.fh.close() + +class ControlFIFOThread ( threading.Thread ): + def __init__(self, file_fifo, arduino): + self.running=True + self.file_fifo=file_fifo + self.arduino = arduino + self.re_cmd = re.compile(r'^(\w+)\s*(.*)') + threading.Thread.__init__(self) + + def stop(self): + self.running=False + self.fh.close() + + def run (self): + self.fh = open(self.file_fifo,"r") + while (self.running): + print "." + line=self.fh.readline() + m = self.re_cmd.match(line) + if not m is None: + (cmd,who) = m.group(1,2) + if cmd == "open": + logging.info("Open Requested by %s" % who) + arduino.send_open() + elif cmd == "close": + logging.info("Close Requested by %s" % who) + arduino.send_close() + elif cmd == "toggle": + logging.info("Toggle Requested by %s" % who) + arduino.send_toggle() + elif cmd == "reset": + logging.info("Reset Requested by %s" % who) + arduino.send_reset() + elif cmd == "status": + arduino.send_statusrequest() + elif cmd == "log": + logging.info(who) + else: + logging.info("Invalid Command %s %s" % (cmd,who)) + if self.fh: + self.fh.close() + + + +fifofile = "/tmp/door_cmd.fifo" + +if (not os.path.exists(fifofile)): + os.system("mkfifo -m 600 $fifofile") + os.system("setfacl -m u:realraum:rw $fifofile") + os.system("setfacl -m u:asterisk:rw $fifofile") + +logging.info("Door Daemon started") + +arduino = ArduinoUSBThread("/dev/ttyUSB0") +arduino.start() +ctrlfifo = ControlFIFOThread(fifofile,arduino) +ctrlfifo.start() + +def exit_handler(signum, frame): + global arduino, ctrlfifo + logging.info("Door Daemon stopping") + arduino.send_close() + ctrlfifo.stop() + arduino.stop() + sys.exit(0) + +signal.signal(signal.SIGTERM, exit_handler) +signal.signal(signal.SIGINT, exit_handler) +signal.signal(signal.SIGQUIT, exit_handler) diff --git a/firmware/tuer.pde b/firmware/tuer.pde index c404b74..7b2b4a0 100644 --- a/firmware/tuer.pde +++ b/firmware/tuer.pde @@ -519,7 +519,7 @@ void loop() char command = Serial.read(); if(current_state == ERROR && command != CMD_RESET) { - Serial.println("Error: last open/close operation took to long!"); + Serial.println("Error: last open/close operation took too long!"); } else if (command == CMD_RESET) { reset_after_error(); -- 1.7.10.4