Skip to content

eftekin/iot-pitwall

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

iot-pitwall

Bridges F1 MultiViewer live timing to Meross smart bulbs.

When the safety car comes out, your room knows before the commentators finish their sentence.

Python GraphQL aiohttp MultiViewer Meross License


Overview

iot-pitwall subscribes to MultiViewer's GraphQL live timing feed and translates track status changes into real-time lighting effects on Meross Wi-Fi bulbs. Green flag, yellow flag, red flag, safety car, VSC — each state triggers a distinct strobe pattern tuned to minimize perceived latency without overwhelming the bulb's command queue.

iotpitwall.mp4

Track Status Bulb Behavior
Green / Clear 4 fast green flashes, then off
Yellow Continuous amber strobe loop
Safety Car Continuous amber strobe loop
Virtual Safety Car Continuous amber strobe loop
VSC Ending Alternating yellow/green fast strobes
Red Flag 10 rapid red flashes, then solid red

Transport is WebSocket-first with automatic subprotocol negotiation (graphql-transport-ws → Apollo → bare). Falls back to HTTP polling if WebSocket upgrade is unavailable.


Prerequisites

  • Python 3.10+
  • MultiViewer 2.x running locally with a live timing or replay session active
  • A Meross account and a compatible RGB bulb (tested on MSL120DR)

Installation

git clone https://github.com/eftekin/iot-pitwall.git
cd iot-pitwall
python3 -m venv .venv
source .venv/bin/activate      # Windows: .venv\Scripts\activate
pip install -r requirements.txt

Configuration

Copy the example and fill in your credentials:

cp .env.example .env

Required:

MEROSS_EMAIL=your-email@example.com
MEROSS_PASSWORD=your-password

Device targeting — use UUID to avoid ambiguity:

python tools/find_devices.py
MEROSS_DEVICE_UUID=your-device-uuid

Full reference:

Variable Default Description
MEROSS_EMAIL Meross account email (required)
MEROSS_PASSWORD Meross account password (required)
MEROSS_DEVICE_UUID Target bulb UUID (recommended)
MEROSS_DEVICE_NAME Target bulb name (fallback)
MEROSS_DEVICE_TYPE Device type filter, e.g. msl120dr
MVF1_TRANSPORT auto auto, websocket, or http_poll
MVF1_GRAPHQL_WS_URL ws://localhost:10101/api/graphql MultiViewer WebSocket endpoint
MVF1_GRAPHQL_HTTP_URL (derived from WS URL) MultiViewer HTTP endpoint
GQL_WEBSOCKET_SUBPROTOCOL auto auto, graphql-transport-ws, graphql-ws
HTTP_POLL_INTERVAL_SECONDS 2.0 Poll interval when WebSocket is unavailable
STROBE_ON_SECONDS 0.15 Bulb on-time per strobe cycle
STROBE_OFF_SECONDS 0.15 Bulb off-time per strobe cycle
MEROSS_MIN_COMMAND_INTERVAL 0.1 Minimum gap between bulb commands
RECONNECT_MIN_SECONDS 1.0 Initial reconnect backoff
RECONNECT_MAX_SECONDS 60.0 Maximum reconnect backoff cap

Strobe timing note: Values below ~0.3 s may cause bulb firmware to drop commands. The defaults are intentionally aggressive for responsiveness — increase if you observe missed flashes.


Usage

python run.py

MultiViewer must be running with a live or replay timing session active. Replay sessions behave identically to live — useful for tuning strobe timing without waiting for a race weekend.

Logging is minimal by default: pitwall.* logs at INFO, everything else at WARNING. The Meross SDK is silenced to CRITICAL.


Architecture

run.py
└── pitwall/
    ├── __init__.py      Async entrypoint and consume loop
    ├── listener.py      GraphQL client — emits TrackStatus to a shared queue
    ├── controller.py    Meross bulb effects with rate-limited command queue
    └── config.py        Settings loaded from environment variables

The listener and controller run as concurrent asyncio tasks sharing a queue. Status changes are deduplicated — the same status won't re-trigger an effect until a different one is received. Effect tasks are cancellable: a new status preempts the current strobe loop with a short transition buffer.


Notes

  • Requires MultiViewer 2.x or later. The liveTimingState field was deprecated in favor of f1LiveTimingState in recent builds — the listener handles both.
  • Meross commands route through the cloud by default. Local LAN control is not used. Keep this in mind if your internet connection is unreliable during races.
  • If the bulb stops responding mid-session, increase MEROSS_MIN_COMMAND_INTERVAL and STROBE_ON/OFF_SECONDS to reduce command frequency.

Contributing

Issues and pull requests are welcome. Please open an issue first for significant changes.


License

MIT. See LICENSE.

About

Real-time F1 track status visualized through smart bulbs

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages