Skip to content

Commit 54586de

Browse files
authored
Merge pull request #81 from Wouter0100/dev
Release v2.0.0
2 parents 3cf4587 + 772fb11 commit 54586de

24 files changed

Lines changed: 2993 additions & 123 deletions

AGENTS.md

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,17 @@ The integration follows the standard structure for a Home Assistant
3535

3636
- **`coordinator.py`**: Hosts `NanoKVMDataUpdateCoordinator`.
3737
- Central polling logic (`_async_update_data`) and API fetch helpers.
38-
- Handles reauthentication, storage-state fetches, and SSH metric refresh.
38+
- Handles reauthentication, storage-state fetches, optional NanoKVM Pro
39+
state, dynamic media/network/SSH entities, and SSH metric refresh.
40+
- Gates non-Pro-only endpoints such as swap size, CD-ROM state, HDMI output,
41+
and non-Pro virtual disk controls.
3942

4043
- **`entity.py`**: Defines `NanoKVMEntity` base class.
4144
- Shared entity behavior (`unique_id`, `device_info`) for all platforms.
4245

4346
- **`services.py`**: Service schemas, registration, and handlers.
44-
- Implements all `nanokvm.*` service behavior and unregister logic.
47+
- Implements all `nanokvm.*` service behavior, response services, and
48+
unregister logic.
4549

4650
- **`config_flow.py`**: Manages the user configuration flow in Home Assistant.
4751
- Implements `ConfigFlow` for manual setup and zeroconf discovery.
@@ -60,6 +64,9 @@ The integration follows the standard structure for a Home Assistant
6064
- **`ssh_metrics.py`**: SSH metrics collection implementation used by the
6165
coordinator.
6266

67+
- **`led.py`**: Shared NanoKVM Pro LED strip validation and config helpers.
68+
- Enforces LED brightness and bead-count constraints for entities/services.
69+
6370
- **`manifest.json`**: Integration metadata.
6471
- Domain, name, version, dependencies (including `zeroconf`).
6572
- PyPI requirement (`nanokvm`).
@@ -75,6 +82,8 @@ Assistant entity type:
7582
- `button.py`
7683
- `camera.py`
7784
- `camera_webrtc.py` (WebRTC helper used by the camera platform)
85+
- `camera_webrtc_sdp.py` (NanoKVM Pro SDP split/merge helpers)
86+
- `number.py`
7887
- `select.py`
7988
- `sensor.py`
8089
- `switch.py`
@@ -112,6 +121,13 @@ Each platform follows a similar pattern:
112121
- **Coordinator pattern**:
113122
`DataUpdateCoordinator` provides one polling path and shared state for all
114123
entities.
124+
- **Optional and dynamic entities**:
125+
Some entities are created only after the coordinator sees supporting state,
126+
such as mounted media, active wired/wireless connections, or SSH metrics.
127+
- **NanoKVM Pro compatibility**:
128+
Pro devices expose several APIs with different schemas from non-Pro models.
129+
Keep Pro-specific polling optional and keep non-Pro-only entities gated by
130+
hardware support.
115131
- **Declarative entities**:
116132
Dataclass-based entity descriptions keep entity definitions compact.
117133
- **`nanokvm` library boundary**:
@@ -127,12 +143,16 @@ Each platform follows a similar pattern:
127143

128144
Run these checks locally before pushing:
129145

130-
1. Python lint:
131-
- `ruff check custom_components/nanokvm`
132-
- If needed: `.\venv\Scripts\python -m ruff check custom_components/nanokvm`
133-
2. Validate metadata JSON:
134-
- `Get-Content hacs.json | ConvertFrom-Json > $null`
135-
- `Get-Content custom_components/nanokvm/manifest.json | ConvertFrom-Json > $null`
146+
1. Python checks:
147+
- `python -m ruff check custom_components/nanokvm`
148+
- `python -m py_compile custom_components/nanokvm/*.py`
149+
2. Validate JSON metadata, strings, and translations:
150+
- `python -m json.tool hacs.json`
151+
- `python -m json.tool custom_components/nanokvm/manifest.json`
152+
- `python -m json.tool custom_components/nanokvm/strings.json`
153+
- `python -m json.tool custom_components/nanokvm/translations/en.json`
154+
- `python -m json.tool custom_components/nanokvm/translations/fr.json`
155+
- `python -m json.tool custom_components/nanokvm/translations/pt-BR.json`
136156
3. Verify the integration against a Home Assistant test instance and inspect logs.
137157

138158
## Required GitHub Workflows

CONTRIBUTING.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,24 @@ Recommended flow:
2020
- Keep changes focused and small when possible.
2121
- AI-assisted coding is welcome, but contributors are responsible for
2222
understanding, reviewing, and validating generated changes.
23-
- Update docs/translations when behavior or user-facing text changes.
23+
- Update README, SERVICES, strings, and translations together when behavior,
24+
services, entities, or user-facing text changes.
2425
- Add tests for bug fixes and new behavior when practical.
2526

2627
## Validation
2728

2829
Before opening a PR, run:
2930

30-
1. `ruff check custom_components/nanokvm`
31-
2. Test the integration on a Home Assistant instance (if relevant)
31+
1. `python -m ruff check custom_components/nanokvm`
32+
2. `python -m py_compile custom_components/nanokvm/*.py`
33+
3. `python -m json.tool hacs.json`
34+
4. `python -m json.tool custom_components/nanokvm/manifest.json`
35+
5. `python -m json.tool custom_components/nanokvm/strings.json`
36+
6. `python -m json.tool custom_components/nanokvm/translations/en.json`
37+
7. `python -m json.tool custom_components/nanokvm/translations/fr.json`
38+
8. `python -m json.tool custom_components/nanokvm/translations/pt-BR.json`
39+
40+
When behavior changes, also test the integration on a Home Assistant instance.
3241

3342
CI must pass on the PR branch:
3443

README.md

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@ device settings, diagnostics, services, and camera streaming in Home Assistant.
1515

1616
| Area | Capabilities |
1717
| --- | --- |
18-
| Power and hardware | Power/reset actions, status LEDs, HDMI output control (PCI-E) |
19-
| Device settings | SSH, mDNS, HID mode, OLED timeout, swap size, mouse jiggler, watchdog |
20-
| Virtual devices | Virtual network and virtual disk switches |
21-
| Monitoring | Mounted image, CD-ROM mode, Tailscale, Wi-Fi |
18+
| Power and hardware | Power/reset actions, status LEDs, HDMI output control (PCI-E), Pro HDMI capture/passthrough |
19+
| Device settings | SSH, mDNS, HID mode, OLED timeout, swap size, mouse jiggler, watchdog, Pro low power, Pro LCD time format |
20+
| Virtual devices | Virtual network, non-Pro virtual disk switch, Pro virtual mic, Pro virtual disk type |
21+
| Pro LED strip | On/off, brightness, horizontal bead count, vertical bead count |
22+
| Monitoring | Mounted image, CD-ROM mode, Tailscale, Wi-Fi, wired/wireless IP diagnostics, Pro time/static IP state |
2223
| Updates | Application version reporting and install action |
2324
| SSH diagnostics | Uptime, CPU temp, memory/storage usage when SSH is enabled |
24-
| Camera | HDMI still snapshots and native WebRTC streaming |
25+
| Camera | HDMI still snapshots on non-Pro models and native WebRTC streaming |
2526

2627
## Installation
2728

@@ -66,18 +67,20 @@ Notes:
6667

6768
- Host updates from discovery are disabled when **Use static host only** is enabled.
6869
- Camera stream availability depends on HDMI input/source status.
70+
- NanoKVM Pro still snapshots are skipped to avoid interrupting WebRTC video mode.
6971
- Feature-specific entities only appear when the device reports support for them.
7072

7173
## Entities
7274

7375
| Platform | Highlights |
7476
| --- | --- |
75-
| Binary sensor | Power LED, HDD LED, Wi-Fi connected, CD-ROM mode |
76-
| Button | Power/Reset buttons, reboot, reset HID/HDMI |
77-
| Camera | HDMI stream camera with still snapshots and WebRTC |
78-
| Select | HID mode, Mouse Jiggler, OLED timeout, Swap size |
79-
| Sensor | Mounted image, Tailscale, SSH diagnostics |
80-
| Switch | Power, SSH, mDNS, Virtual network/disk, HDMI output, watchdog |
77+
| Binary sensor | Power LED, HDD LED, Wi-Fi/wired connected, CD-ROM mode, Pro static IP enabled, Pro time synchronized |
78+
| Button | Power/Reset buttons, reboot, reset HID/HDMI, Pro sync time |
79+
| Camera | HDMI stream camera with WebRTC and non-Pro still snapshots |
80+
| Number | Pro LED brightness, horizontal beads, vertical beads |
81+
| Select | HID mode, Mouse Jiggler, OLED timeout, Swap size, Pro LCD time format, Pro virtual disk type |
82+
| Sensor | IP address, wired/wireless IP address, mounted image, Tailscale, SSH diagnostics |
83+
| Switch | Power, SSH, mDNS, virtual network/disk, HDMI output, watchdog, Pro HDMI capture/passthrough, Pro low power, Pro LED strip, Pro virtual mic |
8184
| Update | Application version and install action |
8285

8386
Notes:
@@ -87,6 +90,7 @@ Notes:
8790
- Wi-Fi entities only appear when the device reports Wi-Fi support.
8891
- SSH diagnostics appear after SSH is enabled on the NanoKVM.
8992
- The watchdog switch requires SSH and NanoKVM application version `2.2.2` or newer.
93+
- Pro LED bead counts must satisfy `horizontal + (2 * vertical) <= 150`.
9094

9195
## Hardware Compatibility
9296

@@ -95,6 +99,26 @@ Notes:
9599
| HDMI switch/button controls | PCI-E models |
96100
| HDD LED binary sensor | Alpha models |
97101
| SSH diagnostic sensors | Any model with SSH enabled |
102+
| Swap size, CD-ROM mode, virtual disk switch | Non-Pro models |
103+
| Virtual network switch | Non-Pro and Pro models |
104+
| HDMI capture/passthrough, low power, LED strip, virtual mic, LCD time format, sync time | Pro models |
105+
| Wired/wireless IP sensors | Created when that connection type is active |
106+
107+
### NanoKVM Pro
108+
109+
NanoKVM Pro devices are supported through the `nanokvm` Python library.
110+
The integration exposes Pro controls for HDMI capture/passthrough, low power,
111+
LED strip configuration, virtual network, virtual microphone, virtual disk
112+
type, LCD time format, sync time, static IP state, and time synchronization
113+
state.
114+
115+
Because the Pro firmware does not expose the same endpoints as non-Pro models,
116+
these non-Pro entities are hidden on Pro:
117+
118+
- Swap size select
119+
- HDMI output switch and Reset HDMI button
120+
- CD-ROM Mode binary sensor
121+
- Virtual Disk switch
98122

99123
## Services
100124

@@ -110,11 +134,19 @@ For full call examples, see [`SERVICES.md`](SERVICES.md).
110134
| `reset_hid` | `host` | Reset HID subsystem |
111135
| `wake_on_lan` | `host`, `mac` | Send Wake-on-LAN packet |
112136
| `set_mouse_jiggler` | `host`, `enabled`, `mode` | Set mouse jiggler state |
137+
| `set_led_strip` | `host`, `on`, `brightness`, `horizontal_count`, `vertical_count` | Set NanoKVM Pro LED strip state |
138+
| `scan_wifi` | `host` | Scan Wi-Fi networks and return the Pro response |
139+
| `list_images` | `host` | Return available NanoKVM images |
140+
| `is_image_download_enabled` | `host` | Return whether image downloading is enabled |
141+
| `get_image_download_status` | `host` | Return image download status |
142+
| `list_custom_edids` | `host` | Return custom EDIDs available on NanoKVM Pro |
113143

114144
Notes:
115145

116146
- `push_button.duration` range is `100-5000` ms.
147+
- `set_led_strip.brightness` range is `0-100`; LED beads must satisfy `horizontal + (2 * vertical) <= 150`.
117148
- `host` is optional when one NanoKVM is configured and required when multiple devices are configured.
149+
- Response services return structured data to callers that request a response.
118150

119151
## Example Automation
120152

@@ -140,6 +172,8 @@ automation:
140172
| Missing entities | Some entities only appear after the related feature is available (for example SSH enabled or media mounted) |
141173
| No SSH sensors | Enable SSH on NanoKVM |
142174
| No HDMI controls | HDMI controls only appear on PCI-E hardware |
175+
| No Pro still image | Pro snapshots are intentionally skipped to avoid interrupting WebRTC video |
176+
| Missing wired/wireless IP sensor | The sensor appears after the device reports an active address for that connection type |
143177
144178
## Supported Languages
145179

SERVICES.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# NanoKVM Service Examples
22

33
All service calls use the `nanokvm` domain.
4+
The `host` field is optional when one NanoKVM is configured and required when
5+
multiple NanoKVM devices are configured.
6+
7+
Response services return structured data. In automations or scripts, use
8+
`response_variable` when you need to consume the returned data.
49

510
## `nanokvm.push_button`
611

@@ -125,3 +130,120 @@ data:
125130
enabled: true
126131
mode: absolute
127132
```
133+
134+
## `nanokvm.set_led_strip`
135+
136+
Configure NanoKVM Pro LED strip state.
137+
138+
Parameters:
139+
140+
- `host`: optional target host; required when multiple NanoKVM devices are configured
141+
- `on`: `true` or `false` (optional)
142+
- `brightness`: brightness percentage from `0` to `100` (optional)
143+
- `horizontal_count`: horizontal LED bead count, minimum `1` (optional)
144+
- `vertical_count`: vertical LED bead count, minimum `1` (optional)
145+
146+
At least one of `on`, `brightness`, `horizontal_count`, or `vertical_count`
147+
is required. Omitted values are preserved from the current LED strip state.
148+
The bead counts must satisfy:
149+
150+
```text
151+
horizontal_count + (2 * vertical_count) <= 150
152+
```
153+
154+
Example:
155+
156+
```yaml
157+
service: nanokvm.set_led_strip
158+
data:
159+
host: "192.168.1.50"
160+
on: true
161+
brightness: 75
162+
horizontal_count: 10
163+
vertical_count: 70
164+
```
165+
166+
## `nanokvm.scan_wifi`
167+
168+
Scan nearby Wi-Fi networks and return the NanoKVM Pro response.
169+
170+
Parameters:
171+
172+
- `host`: optional target host; required when multiple NanoKVM devices are configured
173+
174+
Example:
175+
176+
```yaml
177+
service: nanokvm.scan_wifi
178+
data:
179+
host: "192.168.1.50"
180+
response_variable: wifi_scan
181+
```
182+
183+
## `nanokvm.list_images`
184+
185+
List images available on the NanoKVM.
186+
187+
Parameters:
188+
189+
- `host`: optional target host; required when multiple NanoKVM devices are configured
190+
191+
Example:
192+
193+
```yaml
194+
service: nanokvm.list_images
195+
data:
196+
host: "192.168.1.50"
197+
response_variable: images
198+
```
199+
200+
## `nanokvm.is_image_download_enabled`
201+
202+
Return whether image downloading is enabled on the NanoKVM.
203+
204+
Parameters:
205+
206+
- `host`: optional target host; required when multiple NanoKVM devices are configured
207+
208+
Example:
209+
210+
```yaml
211+
service: nanokvm.is_image_download_enabled
212+
data:
213+
host: "192.168.1.50"
214+
response_variable: image_download_enabled
215+
```
216+
217+
## `nanokvm.get_image_download_status`
218+
219+
Return the current NanoKVM image download status.
220+
221+
Parameters:
222+
223+
- `host`: optional target host; required when multiple NanoKVM devices are configured
224+
225+
Example:
226+
227+
```yaml
228+
service: nanokvm.get_image_download_status
229+
data:
230+
host: "192.168.1.50"
231+
response_variable: image_download_status
232+
```
233+
234+
## `nanokvm.list_custom_edids`
235+
236+
List custom EDIDs available on a NanoKVM Pro.
237+
238+
Parameters:
239+
240+
- `host`: optional target host; required when multiple NanoKVM devices are configured
241+
242+
Example:
243+
244+
```yaml
245+
service: nanokvm.list_custom_edids
246+
data:
247+
host: "192.168.1.50"
248+
response_variable: custom_edids
249+
```

custom_components/nanokvm/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
Platform.BINARY_SENSOR,
2525
Platform.BUTTON,
2626
Platform.CAMERA,
27+
Platform.NUMBER,
2728
Platform.SELECT,
2829
Platform.SENSOR,
2930
Platform.SWITCH,

0 commit comments

Comments
 (0)