This commit introduces a complete integration for Mirabox StreamDock devices with Home Assistant, allowing users to control entities and monitor states directly from the hardware. Key features included: - Support for multiple Mirabox models: N1, N3, N4, N4Pro, XL, M3, M18, K1Pro, and various 293 variants. - Home Assistant WebSocket integration for real-time entity updates and service execution. - Dynamic LCD key rendering with support for custom icons, labels, and entity-state aware colors. - Input handling for physical buttons and rotary encoders (knobs). - Multi-page navigation support with configurable cycle keys and knobs. - Cross-platform transport layer using a custom HID library. - Configuration system using YAML with page-based layouts. - Linux udev rules for non-root USB access.
StreamDock Home Assistant Integration
Displays Home Assistant entity states on Mirabox StreamDock LCD keys and triggers HA services on button/knob presses.
Tested on StreamDock N3 (6 LCD keys + 3 knobs). Should work with other Mirabox StreamDock models (N1, N4, N4Pro, M3, XL, 293 variants, K1Pro).
Requirements
- Python 3.11+
- A Mirabox StreamDock device
- Home Assistant with a long-lived access token
- Linux (x86_64 or aarch64), macOS, or Windows
System packages (Debian/Raspberry Pi OS)
sudo apt install python3-venv fonts-dejavu-core
For USB device permissions (avoid running as root):
sudo cp 99-streamdock.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules
sudo udevadm trigger
# Then unplug and re-plug the StreamDock
Python packages
python3 -m venv venv
source venv/bin/activate
pip install Pillow pyyaml HomeAssistant-API pyudev
Setup
- Create your config from the example:
cp config.example.yaml config.yaml
- Edit
config.yamlwith your HA connection details:
homeassistant:
url: "ws://YOUR_HA_IP:8123/api/websocket"
token: "YOUR_LONG_LIVED_ACCESS_TOKEN"
Get a token from Home Assistant: Settings → People → Your User → Security → Long-Lived Access Tokens
- Run:
source venv/bin/activate
python3 streamdock_ha.py
Configuration Reference
Full config.yaml structure:
homeassistant:
url: "ws://homeassistant.local:8123/api/websocket"
token: "YOUR_TOKEN"
navigation:
page_cycle: "button_8" # which button cycles pages (middle of 3 bottom buttons)
knob_left: "knob_1" # knob whose left-rotation goes to previous page
knob_right: "knob_2" # knob whose right-rotation goes to next page
knob_press_left: "knob_1" # knob whose press goes to previous page
knob_press_right: "knob_2"# knob whose press goes to next page
pages:
- name: "Lights"
keys:
1: # LCD key number (1-6 on N3)
entity: "light.living_room" # HA entity ID
service: "toggle" # HA service to call on press
icon: "lightbulb" # icon name (see below)
label: "Living" # short label shown on key
2:
entity: "switch.kitchen"
service: "toggle"
icon: "power"
label: "Kitchen"
3: # sensor with no service = display-only
entity: "sensor.temperature"
icon: "thermometer"
label: "Temp"
knobs: # per-page knob bindings
knob_3:
rotate_left:
entity: "script.volume_down"
service: "turn_on"
rotate_right:
entity: "script.volume_up"
service: "turn_on"
press:
entity: "script.mute"
service: "turn_on"
- name: "Climate"
keys:
1:
entity: "climate.bedroom"
service: "toggle"
icon: "thermostat"
label: "Bedroom"
Key Numbers
| Keys | N3 | N1 | N4/N4Pro | XL |
|---|---|---|---|---|
| LCD keys | 1-6 | 1-15 | 6-15 | 1-32 |
Bottom buttons (no LCD): keys 7, 8, 9 (N3). Key 8 is the middle one.
Knob Names
| Knob | N3 position |
|---|---|
knob_1 |
Bottom-left |
knob_2 |
Bottom-right |
knob_3 |
Top |
Navigation Button/ Knob References
Buttons can be referenced as button_7, button_8, button_9, key_7, etc., or just the number 7, 8, 9.
Knobs: knob_1, knob_2, knob_3, knob_4, or aliases left, right, top, bottom_left, bottom_right.
Available Icons
lightbulb, power, thermometer, thermostat, play, film, door, lock, speaker, fan, or default
Icons render with distinct "on" and "off" colors. For example, lightbulb shows yellow when on, gray when off. door shows green when open, red when closed.
Entity State Detection
The app automatically detects on/off states from HA entity states:
- On:
on,playing,open,unlocked,home,heat,cool,auto - Off: everything else
Sensor values (temperature, humidity, etc.) are displayed as-is on the key.
Running on Raspberry Pi
The included libtransport_arm64.so supports aarch64 Linux (Pi 3, 4, 5, Zero 2 W). The library loader auto-detects the architecture.
# On Raspberry Pi OS
sudo apt install python3-venv fonts-dejavu-core
python3 -m venv venv
source venv/bin/activate
pip install Pillow pyyaml HomeAssistant-API pyudev
# USB permissions
sudo cp 99-streamdock.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules && sudo udevadm trigger
# Configure and run
cp config.example.yaml config.yaml
nano config.yaml
python3 streamdock_ha.py
Autostart on Boot (systemd)
Create /etc/systemd/system/streamdock-ha.service:
[Unit]
Description=StreamDock Home Assistant
After=network.target
[Service]
Type=simple
User=karl
WorkingDirectory=/home/karl/streamdocklinux
ExecStart=/home/karl/streamdocklinux/venv/bin/python3 streamdock_ha.py
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
sudo systemctl enable streamdock-ha
sudo systemctl start streamdock-ha
Architecture
streamdock_ha.py - Main app: HA WebSocket + StreamDock event loop
key_renderer.py - Dynamic key image generation (icons + state text)
config.py - YAML config loader
config.yaml - User configuration (gitignored)
config.example.yaml - Example configuration
99-streamdock.rules - udev rules for USB permissions
StreamDock/ - Mirabox StreamDock Device SDK (Python + C transport lib)
License
This project includes the Mirabox StreamDock Device SDK. See StreamDock/ for its license terms.