#!/usr/bin/env python3 # Pins controllable by client # Types: # 1: switch on or off depending on power # 2: toggle on or off with single power high event # 3: addressable (TODO) # 4: on/off event to client (TODO) # 5: analog event to client (TODO) import socket, threading import RPi.GPIO as GPIO import configparser import os, io # Initialize GPIO # Pinout help: https://pinout.xyz/ GPIO.setmode(GPIO.BOARD) GPIO.setwarnings(False) configfile = "server.ini" config = configparser.ConfigParser() # Check if there is already a configurtion file if not os.path.isfile(configfile): # Create the configuration file as it doesn't exist yet cfgfile = open(configfile, "w") # Add content to the file config.add_section("server") config.set("server", "host", "0.0.0.0") config.set("server", "port", "62002") config.add_section("output") config.set("output", "type", "1") config.set("output", "pin", "8") config.write(cfgfile) cfgfile.close() else: # Load config from file config = configparser.ConfigParser() config.read(configfile) # Set up all pins for section in config.sections(): if section == "server": continue type = int(config.get(section, "type")) pin = int(config.get(section, "pin")) if type == 1: GPIO.setup(pin, GPIO.OUT, initial=GPIO.LOW) # Client connection thread class ClientThread(threading.Thread): def __init__(self, ip, port, clientsocket): threading.Thread.__init__(self) self.ip = ip self.port = port self.csocket = clientsocket print("[+] New thread started for %s:%s" % (ip, str(port))) def handler(self, power, key, val): if not config.has_section(key): return type = int(config.get(key, "type")) pin = int(config.get(key, "pin")) if type == 1: if power > 0: GPIO.output(pin, GPIO.HIGH) else: GPIO.output(pin, GPIO.LOW) def srvcmd(self,line): split = line[:-2].split(':') if split[0] and split[1]: self.handler(int(split[0]), split[1], split[2]) def run(self): self.csocket.send(b'connected\r\n') # Receive messages from client while True: data = self.csocket.recv(1024) if not data: break data = data.decode('utf-8') # Handle command from client self.srvcmd(data) self.csocket.close() print("Client at %s disconnected..." % (self.ip)) def run_sockets(): HOST = config.get("server", "host") PORT = int(config.get("server", "port")) # Start server socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((HOST,PORT)) print("Bound to %s:%s" % (HOST,PORT)) while True: s.listen(4) print("Listening for incoming connections...") (clientsock, (ip, port)) = s.accept() # New thread for new client newthread = ClientThread(ip, port, clientsock) newthread.start() run_sockets()