aboutsummaryrefslogtreecommitdiffstats
path: root/doc/lightswitch.py.ex
diff options
context:
space:
mode:
Diffstat (limited to 'doc/lightswitch.py.ex')
-rwxr-xr-xdoc/lightswitch.py.ex106
1 files changed, 106 insertions, 0 deletions
diff --git a/doc/lightswitch.py.ex b/doc/lightswitch.py.ex
new file mode 100755
index 0000000..8648600
--- /dev/null
+++ b/doc/lightswitch.py.ex
@@ -0,0 +1,106 @@
+#!/usr/bin/python3
+
+import time
+import datetime
+import subprocess
+import select
+import atexit
+import serial
+import socket
+
+procs = []
+timerange_start = dict(hour=18, minute=30, second=0, microsecond=0)
+timerange_stop = dict(hour=22, minute=00, second=0, microsecond=0)
+listen_addr = '192.168.1.1'
+listen_port = 1078
+
+@atexit.register
+def kill_subprocesses():
+ for proc in procs:
+ proc.kill()
+
+class Tailer:
+
+ def __init__(self):
+ command1 = '/usr/bin/tail /var/log/syslog -f'
+ command2 = '/bin/grep --line-buffered "DHCPREQUEST.*AA:BB:CC:DD:EE:FF"'
+ self.tailpipe = subprocess.Popen(
+ '{} | {}'.format(command1, command2),
+ shell=True,
+ stdout=subprocess.PIPE,
+ universal_newlines=True,
+ )
+ procs.append(self.tailpipe)
+
+ def in_correct_timerange(self):
+ line = self.tailpipe.stdout.readline().strip()
+ line = ' '.join(line.split()[:3])
+ current_dt = datetime.datetime.strptime(
+ line, '%b %d %H:%M:%S').replace(
+ year=datetime.datetime.now().year)
+ start_dt = current_dt.replace(**timerange_start)
+ stop_dt = current_dt.replace(**timerange_stop)
+ return start_dt < current_dt < stop_dt
+
+ def get_fd(self):
+ return self.tailpipe.stdout
+
+class LightCommand:
+
+ def __init__(self):
+ self.serial = serial.Serial('/dev/serial/by-id/device', baudrate=9600)
+ self.state = None
+
+ def toggle(self):
+ print('Toggling light')
+ self.serial.write(b'T')
+ if self.state is not None:
+ self.state != self.state
+
+ def on(self):
+ print('Turn on light')
+ if not self.state:
+ self.serial.write(b'1')
+ self.state = True
+
+ def off(self):
+ print('Turn off light')
+ if self.state:
+ self.serial.write(b'0')
+ self.state = False
+
+class Server:
+
+ def __init__(self):
+ self.ssock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ self.ssock.bind((listen_addr, listen_port))
+
+ def get_fd(self):
+ return self.ssock
+
+ def get_command(self):
+ data, _ = self.ssock.recvfrom(32)
+ return data.strip().strip(b'\r\n').lower()
+
+tailer = Tailer()
+lightcommand = LightCommand()
+server = Server()
+
+while True:
+
+ fdlist, _, _ = select.select([
+ tailer.get_fd(), server.get_fd()], [], [])
+
+ for fd in fdlist:
+ if fd is tailer.get_fd() and tailer.in_correct_timerange():
+ print('Ok, in correct timerange, turning light on')
+ lightcommand.on()
+ elif fd is server.get_fd():
+ command = server.get_command()
+ print('Received command "{}" on udp socket'.format(command))
+ if command == b'on':
+ lightcommand.on()
+ elif command == b'off':
+ lightcommand.off()
+ elif command == b'toggle':
+ lightcommand.toggle()