Add SplitFlap Gateway as a target for the app#50
Conversation
…rt connect "Serial Port" settings panel replaced by a "Hardware Connection" panel with a Connection Type selector toggling between the serial panel and a new gateway panel (broker, port, topic prefix, optional username/password). Added a clarifying note on the existing "MQTT / Home Assistant" section.
…rt connect onConnectionTypeChange(), loadConnectionConfig(), applyGatewayConnection(); loadSettingsData() now also loads the connection config; applying a serial port syncs the type selector.
…rt connect Feature bullet + a "SplitFlap Gateway (MQTT)" section documenting the topic contract and environment variables.
There was a problem hiding this comment.
Great work! Duck-typing the serial interface means zero downstream changes, the fail-fast behavior mirrors serial properly, and the password handling is done right.
A few things I'd like addressed before merging:
Silent publish on disconnect (important):
write() doesn't check self._connected before publishing. If the broker disconnects mid-session, paho silently queues messages and the user won't know commands aren't reaching the display. This is especially concerning during calibration/EEPROM writes. At minimum, write() should log a warning or raise when not connected, otherwise command loss is invisible.
Minor items (non-blocking):
-
client_iduses second-precision timestamps (int(time.time())). If the app restarts within the same second (crash loop on Pi), you get a duplicate client ID. Consider appendingos.getpid()or a short random suffix. -
_read_config_file()is called independently by_get_connection_type(),_get_gateway_config(), and_get_serial_port()at startup — reads settings.json 2-3 times. Not a real problem, just noting it. -
/connectionPOST doesn't validate thetypefield. An unknown value silently falls through to the serial branch. A 400 for unrecognized types would be cleaner.
Once the disconnect issue is handled, this is good to go. Since the feature is opt-in (off by default, requires explicit config), I'm comfortable merging to main without a beta release.
fixes suggest by @csader
|
All 4 items resolved, i think. Tested locally no issues with the changes. |
csader
left a comment
There was a problem hiding this comment.
All four items addressed cleanly. The warning-not-raise approach in write() is the right call for pyserial compatibility. Good to go.
SplitFlap Gateway (MQTT) Integration — Change Summary
This adds an option to drive the display through a SplitFlap Gateway
(Waveshare ESP32-S3-RS485-CAN running SplitFlap Gateway firmware at https://github.com/avandeputte/SplitFlapGateway ) over MQTT, as an alternative to a
local serial port. The design goal was to minimize impact on the existing
splitflap-os codebase: the OS interacts with only two topics —
<prefix>/sendand<prefix>/rx.How it works
A new transport class presents the same interface the existing code already
used for the serial port (
.write(),.flush(),.reset_input_buffer(),.in_waiting,.read(),.close()). Because of this, none of the existingread/write call sites had to change.
<prefix>/send: the exact RS485 frame bytes the oldcode wrote to the serial port (e.g.
m05-A\n,m05c\n,m05d\n) arepublished verbatim. The gateway forwards them straight to the bus.
<prefix>/rx: the gateway publishes JSON{"ts":...,"wt":"...","command":"<ascii frame>"}for each frame receivedfrom a module. The transport extracts
command, re-appends the newline thegateway stripped, and buffers it so the existing calibration / EEPROM-dump
read loops parse it exactly as they did with serial.
The gateway MQTT connection is independent of the pre-existing
MQTT / Home Assistant integration (which publishes state and accepts control
commands). They use separate clients and settings.
Files changed
New:
server/gateway_transport.pyGatewayTransport, a pyserial-compatible facade over MQTT. Touches only<prefix>/send(publish) and<prefix>/rx(subscribe). Fails fast on anunreachable broker so the app can fall back to simulation mode, mirroring how
serial failure is handled.
server/app.pyGatewayTransport(graceful fallback if unavailable).connection_type(serial|gateway),gateway_broker,gateway_port,gateway_prefix,gateway_user,gateway_password._read_config_file(),_get_connection_type(),_get_gateway_config()helpers (readable at startup, before
load_settings()runs)._open_gateway()and_open_connection(); startup now calls_open_connection(), which dispatches onconnection_type./serial_portnow also setsconnection_type='serial'when applied./connectionroute (GET/POST) to view/switch/configure the connection.Password is preserved on blank resubmit and never echoed back in full.
ser.write()/ser.read()call sites were modified.server/templates/index.htmla Connection Type selector toggling between the serial panel and a new
gateway panel (broker, port, topic prefix, optional username/password).
server/static/app.jsonConnectionTypeChange(),loadConnectionConfig(),applyGatewayConnection();loadSettingsData()now also loads theconnection config; applying a serial port syncs the type selector.
README.mdcontract and environment variables.
Environment variables (optional, override settings.json)
Dependencies
paho-mqttwas already present inrequirements.txt; no new dependency added.