#!/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()