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";
$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");
sub handler
{
#local($sig) = @_;
+ print $ttyusb "c" if (defined $ttyusb);
door_log("Door Daemon stopped");
close $logfile;
close $fifo if (defined $fifo);
{
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();
}
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);
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 &');
}
}
}
{
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 &');
}
}
--- /dev/null
+#!/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)