python
authorrealraum <realraum@realraum.at>
Thu, 30 Apr 2009 01:09:34 +0000 (01:09 +0000)
committerrealraum <realraum@realraum.at>
Thu, 30 Apr 2009 01:09:34 +0000 (01:09 +0000)
door_daemon.pl
door_daemon.py [new file with mode: 0755]
firmware/tuer.pde

index 8aa48c4..ce14364 100755 (executable)
@@ -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 (executable)
index 0000000..903d6cf
--- /dev/null
@@ -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)
index c404b74..7b2b4a0 100644 (file)
@@ -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();