115 lines
3.1 KiB
Python
115 lines
3.1 KiB
Python
#!/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()
|