from flask import Flask, jsonify import serial import os app = Flask(__name__) RELAY_DEV = os.environ.get("RELAYCTL_DEV", "/dev/ttyUSB0") RELAY_HOST = os.environ.get("RELAYCTL_HOST", "127.0.0.1") RELAY_PORT = os.environ.get("RELAYCTL_PORT", "5050") RELAY_BAUD = 9600 RELAY_ID = 1 # NOTE: multi relay boards are not supported (only relay id 1) def get_cmd(state: bool): """ LCUS relay 4-byte control command syntax is as follows: start: always 0xA0 relay: id of relay (counts from 1) state: coil energized 0 or 1 checksum: sum of previous 3 bytes """ start = 0xA0 relay = RELAY_ID state = int(state) checksum = start + relay + state return bytes((start, relay, state, checksum)) def get_serial(): return serial.Serial(RELAY_DEV, RELAY_BAUD, timeout=1) @app.route("/on", methods=["GET", "POST"]) def on(): with get_serial() as ser: ser.write(get_cmd(True)) return jsonify({"state": "ON"}) @app.route("/off", methods=["GET", "POST"]) def off(): with get_serial() as ser: ser.write(get_cmd(False)) return jsonify({"state": "OFF"}) @app.route("/status", methods=["GET"]) def status(): with get_serial() as ser: ser.write(bytes((0xFF,))) # write 0xFF to get status r = ser.readline() state = r.decode("utf-8").removeprefix("CH1: ").strip() return jsonify({"state": state}) def main(): app.run(host=RELAY_HOST, port=int(RELAY_PORT)) if __name__ == "__main__": main()