summaryrefslogtreecommitdiff
path: root/hosts/gnuslashprinter/resources/flaskrelayctl/server
diff options
context:
space:
mode:
authorTim Keller <tjk@tjkeller.xyz>2026-06-03 13:54:18 -0500
committerTim Keller <tjk@tjkeller.xyz>2026-06-03 13:54:18 -0500
commit8264c4659dbdb8d98310414badf288f8200fe242 (patch)
treed4e967cd63990a464e36b7754676a58379e0f871 /hosts/gnuslashprinter/resources/flaskrelayctl/server
parenta6d9a9de1defe2c39c9514c0de76d37dcf8a0576 (diff)
downloadnixos-8264c4659dbdb8d98310414badf288f8200fe242.tar.xz
nixos-8264c4659dbdb8d98310414badf288f8200fe242.zip
aliases for printer and new power control relay. moonraker power control for printer enabled and accessible via mainsail. power control python script for power control via http in moonraker
Diffstat (limited to 'hosts/gnuslashprinter/resources/flaskrelayctl/server')
-rw-r--r--hosts/gnuslashprinter/resources/flaskrelayctl/server/__init__.py54
1 files changed, 54 insertions, 0 deletions
diff --git a/hosts/gnuslashprinter/resources/flaskrelayctl/server/__init__.py b/hosts/gnuslashprinter/resources/flaskrelayctl/server/__init__.py
new file mode 100644
index 0000000..f2c0bc3
--- /dev/null
+++ b/hosts/gnuslashprinter/resources/flaskrelayctl/server/__init__.py
@@ -0,0 +1,54 @@
+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()