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.
214 lines
5.6 KiB
Markdown
214 lines
5.6 KiB
Markdown
# 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)
|
|
|
|
```bash
|
|
sudo apt install python3-venv fonts-dejavu-core
|
|
```
|
|
|
|
For USB device permissions (avoid running as root):
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
python3 -m venv venv
|
|
source venv/bin/activate
|
|
pip install Pillow pyyaml HomeAssistant-API pyudev
|
|
```
|
|
|
|
## Setup
|
|
|
|
1. Create your config from the example:
|
|
|
|
```bash
|
|
cp config.example.yaml config.yaml
|
|
```
|
|
|
|
2. Edit `config.yaml` with your HA connection details:
|
|
|
|
```yaml
|
|
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**
|
|
|
|
3. Run:
|
|
|
|
```bash
|
|
source venv/bin/activate
|
|
python3 streamdock_ha.py
|
|
```
|
|
|
|
## Configuration Reference
|
|
|
|
Full `config.yaml` structure:
|
|
|
|
```yaml
|
|
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.
|
|
|
|
```bash
|
|
# 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`:
|
|
|
|
```ini
|
|
[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
|
|
```
|
|
|
|
```bash
|
|
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. |