homebridge-yoto 0.0.31 → 0.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/homebridge-ui/public/client.js +428 -0
- package/homebridge-ui/public/index.html +138 -0
- package/package.json +12 -1
- package/.github/dependabot.yml +0 -18
- package/.github/funding.yml +0 -4
- package/.github/workflows/release.yml +0 -41
- package/.github/workflows/tests.yml +0 -37
- package/AGENTS.md +0 -138
- package/CHANGELOG.md +0 -16
- package/CONTRIBUTING.md +0 -34
- package/NOTES.md +0 -87
- package/PLAN.md +0 -425
- package/eslint.config.js +0 -7
- package/index.test.js +0 -7
- package/logo.png +0 -0
- package/pnpm-workspace.yaml +0 -4
- package/tsconfig.json +0 -14
package/PLAN.md
DELETED
|
@@ -1,425 +0,0 @@
|
|
|
1
|
-
# Homebridge Yoto Plugin - Implementation Status
|
|
2
|
-
|
|
3
|
-
## ✅ What's Implemented
|
|
4
|
-
|
|
5
|
-
### Architecture
|
|
6
|
-
- ✅ Platform plugin using `yoto-nodejs-client` for device management
|
|
7
|
-
- ✅ One accessory per Yoto device (published as external accessory for SmartSpeaker support)
|
|
8
|
-
- ✅ Real-time updates via MQTT + periodic HTTP polling fallback
|
|
9
|
-
- ✅ Offline detection and "No Response" status handling
|
|
10
|
-
- ✅ Capability-based service registration (v2/v3/mini device support)
|
|
11
|
-
|
|
12
|
-
### Core Services (Always Present)
|
|
13
|
-
- ✅ **AccessoryInformation** - Device metadata (manufacturer, model, serial, firmware)
|
|
14
|
-
- ✅ **SmartSpeaker** (PRIMARY) - Playback control and volume
|
|
15
|
-
- ✅ **Battery** - Battery level, charging state, low battery indicator
|
|
16
|
-
- ✅ **ContactSensor (CardSlot)** - Card insertion detection
|
|
17
|
-
- ✅ **OccupancySensor (NightModeStatus)** - Day/night mode indicator
|
|
18
|
-
- ✅ **Switch (SleepTimer)** - Toggle sleep timer (30 min default)
|
|
19
|
-
- ✅ **Switch (Bluetooth)** - Toggle Bluetooth on/off
|
|
20
|
-
- ✅ **Fanv2 (DayMaxVolume)** - Day mode max volume limit control
|
|
21
|
-
- ✅ **Fanv2 (NightMaxVolume)** - Night mode max volume limit control
|
|
22
|
-
|
|
23
|
-
### Optional Services (Capability-Based)
|
|
24
|
-
- ✅ **TemperatureSensor** - Temperature reading (v3 only)
|
|
25
|
-
- ✅ **Lightbulb (DayNightlight)** - Day nightlight color/brightness control (v3 only)
|
|
26
|
-
- ✅ **Lightbulb (NightNightlight)** - Night nightlight color/brightness control (v3 only)
|
|
27
|
-
- ✅ **ContactSensor (NightlightActive)** - Live nightlight status (v3 only)
|
|
28
|
-
- ✅ **ContactSensor (DayNightlightActive)** - Day nightlight status (v3 only)
|
|
29
|
-
- ✅ **ContactSensor (NightNightlightActive)** - Night nightlight status (v3 only)
|
|
30
|
-
|
|
31
|
-
## Service & Characteristic Reference
|
|
32
|
-
|
|
33
|
-
All services are named consistently using `generateServiceName()` helper: `"[Device Name] [Service Name]"`
|
|
34
|
-
|
|
35
|
-
### Yoto Player Accessory
|
|
36
|
-
|
|
37
|
-
Each Yoto device is represented as a single HomeKit accessory with multiple services.
|
|
38
|
-
|
|
39
|
-
**Category**: `SPEAKER` (required for SmartSpeaker service)
|
|
40
|
-
|
|
41
|
-
---
|
|
42
|
-
|
|
43
|
-
#### Service: AccessoryInformation (Required)
|
|
44
|
-
|
|
45
|
-
Standard HomeKit service providing device identification.
|
|
46
|
-
|
|
47
|
-
**Characteristics:**
|
|
48
|
-
- `Manufacturer` (GET) - "Yoto Inc."
|
|
49
|
-
- `Model` (GET) - Device family (e.g., "v3", "v2", "mini")
|
|
50
|
-
- `SerialNumber` (GET) - Device ID
|
|
51
|
-
- `HardwareRevision` (GET) - Generation and form factor
|
|
52
|
-
- `FirmwareRevision` (GET) - Firmware version from device status
|
|
53
|
-
|
|
54
|
-
**Source:** `device` metadata + `status.firmwareVersion`
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
#### Service: SmartSpeaker (PRIMARY)
|
|
59
|
-
|
|
60
|
-
Controls playback and volume. Marked as primary service for the accessory.
|
|
61
|
-
|
|
62
|
-
**Characteristics:**
|
|
63
|
-
- `CurrentMediaState` (GET) - PLAY/PAUSE/STOP based on playback status
|
|
64
|
-
- `TargetMediaState` (GET/SET) - Control playback (play/pause/stop)
|
|
65
|
-
- `Volume` (GET/SET) - Volume level (0-16 native scale, dynamic max based on volume limit)
|
|
66
|
-
- `Mute` (GET/SET) - Mute state (derived from volume === 0)
|
|
67
|
-
- `StatusActive` (GET) - Online/offline indicator
|
|
68
|
-
|
|
69
|
-
**Source:** `status.volume`, `playback.playbackStatus`
|
|
70
|
-
**Control:** `sendCommand({ action: 'play' | 'pause' | 'stop' | 'volume', volume: N })`
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
#### Service: Battery
|
|
75
|
-
|
|
76
|
-
Battery status information.
|
|
77
|
-
|
|
78
|
-
**Characteristics:**
|
|
79
|
-
- `BatteryLevel` (GET) - Battery percentage (0-100)
|
|
80
|
-
- `ChargingState` (GET) - CHARGING or NOT_CHARGING
|
|
81
|
-
- `StatusLowBattery` (GET) - LOW when ≤20%, NORMAL otherwise
|
|
82
|
-
- `StatusActive` (GET) - Online/offline indicator
|
|
83
|
-
|
|
84
|
-
**Source:** `status.batteryLevelPercentage`, `status.isCharging`
|
|
85
|
-
|
|
86
|
-
---
|
|
87
|
-
|
|
88
|
-
#### Service: TemperatureSensor (OPTIONAL - v3 only)
|
|
89
|
-
|
|
90
|
-
Temperature reading from device sensor.
|
|
91
|
-
|
|
92
|
-
**Characteristics:**
|
|
93
|
-
- `CurrentTemperature` (GET) - Temperature in Celsius
|
|
94
|
-
- `StatusFault` (GET) - NO_FAULT (only shown when temperature available)
|
|
95
|
-
- `StatusActive` (GET) - Online/offline indicator
|
|
96
|
-
|
|
97
|
-
**Source:** `status.temperatureCelsius`
|
|
98
|
-
**Availability:** `deviceModel.capabilities.hasTemperatureSensor`
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
#### Service: Lightbulb (subtype: "DayNightlight") - OPTIONAL - v3 only
|
|
103
|
-
|
|
104
|
-
Day mode nightlight color and brightness control (config-based).
|
|
105
|
-
|
|
106
|
-
**Characteristics:**
|
|
107
|
-
- `On` (GET/SET) - Turn nightlight on/off (off states: '0x000000', 'off')
|
|
108
|
-
- `Brightness` (GET/SET) - Screen brightness 0-100% (or 'auto')
|
|
109
|
-
- `Hue` (GET/SET) - Color hue 0-360° (derived from hex color)
|
|
110
|
-
- `Saturation` (GET/SET) - Color saturation 0-100% (derived from hex color)
|
|
111
|
-
|
|
112
|
-
**Source:** `config.ambientColour`, `config.dayDisplayBrightness`
|
|
113
|
-
**Control:** `updateConfig({ ambientColour: '0xRRGGBB', dayDisplayBrightness: 'N' })`
|
|
114
|
-
**Availability:** `deviceModel.capabilities.hasColoredNightlight`
|
|
115
|
-
|
|
116
|
-
**Color Conversion:** Uses `color-convert` library for hex ↔ HSV conversion
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
#### Service: Lightbulb (subtype: "NightNightlight") - OPTIONAL - v3 only
|
|
121
|
-
|
|
122
|
-
Night mode nightlight color and brightness control (config-based).
|
|
123
|
-
|
|
124
|
-
**Characteristics:**
|
|
125
|
-
- `On` (GET/SET) - Turn nightlight on/off (off states: '0x000000', 'off')
|
|
126
|
-
- `Brightness` (GET/SET) - Screen brightness 0-100% (or 'auto')
|
|
127
|
-
- `Hue` (GET/SET) - Color hue 0-360° (derived from hex color)
|
|
128
|
-
- `Saturation` (GET/SET) - Color saturation 0-100% (derived from hex color)
|
|
129
|
-
|
|
130
|
-
**Source:** `config.nightAmbientColour`, `config.nightDisplayBrightness`
|
|
131
|
-
**Control:** `updateConfig({ nightAmbientColour: '0xRRGGBB', nightDisplayBrightness: 'N' })`
|
|
132
|
-
**Availability:** `deviceModel.capabilities.hasColoredNightlight`
|
|
133
|
-
|
|
134
|
-
---
|
|
135
|
-
|
|
136
|
-
#### Service: ContactSensor (subtype: "NightlightActive") - OPTIONAL - v3 only
|
|
137
|
-
|
|
138
|
-
Shows if nightlight is currently active (live device state).
|
|
139
|
-
|
|
140
|
-
**Characteristics:**
|
|
141
|
-
- `ContactSensorState` (GET) - CONTACT_DETECTED when nightlight on
|
|
142
|
-
- `StatusActive` (GET) - Online/offline indicator
|
|
143
|
-
|
|
144
|
-
**Source:** `status.nightlightMode !== 'off'`
|
|
145
|
-
**Availability:** `deviceModel.capabilities.hasColoredNightlight`
|
|
146
|
-
|
|
147
|
-
---
|
|
148
|
-
|
|
149
|
-
#### Service: ContactSensor (subtype: "DayNightlightActive") - OPTIONAL - v3 only
|
|
150
|
-
|
|
151
|
-
Shows if day nightlight is currently active and showing.
|
|
152
|
-
|
|
153
|
-
**Characteristics:**
|
|
154
|
-
- `ContactSensorState` (GET) - CONTACT_DETECTED when day mode + nightlight on
|
|
155
|
-
- `StatusActive` (GET) - Online/offline indicator
|
|
156
|
-
|
|
157
|
-
**Source:** `status.dayMode === 'day' && status.nightlightMode !== 'off'`
|
|
158
|
-
**Availability:** `deviceModel.capabilities.hasColoredNightlight`
|
|
159
|
-
|
|
160
|
-
---
|
|
161
|
-
|
|
162
|
-
#### Service: ContactSensor (subtype: "NightNightlightActive") - OPTIONAL - v3 only
|
|
163
|
-
|
|
164
|
-
Shows if night nightlight is currently active and showing.
|
|
165
|
-
|
|
166
|
-
**Characteristics:**
|
|
167
|
-
- `ContactSensorState` (GET) - CONTACT_DETECTED when night mode + nightlight on
|
|
168
|
-
- `StatusActive` (GET) - Online/offline indicator
|
|
169
|
-
|
|
170
|
-
**Source:** `status.dayMode === 'night' && status.nightlightMode !== 'off'`
|
|
171
|
-
**Availability:** `deviceModel.capabilities.hasColoredNightlight`
|
|
172
|
-
|
|
173
|
-
---
|
|
174
|
-
|
|
175
|
-
#### Service: ContactSensor (subtype: "CardSlot")
|
|
176
|
-
|
|
177
|
-
Shows if a card is currently inserted.
|
|
178
|
-
|
|
179
|
-
**Characteristics:**
|
|
180
|
-
- `ContactSensorState` (GET) - CONTACT_DETECTED when card present
|
|
181
|
-
- `StatusActive` (GET) - Online/offline indicator
|
|
182
|
-
|
|
183
|
-
**Source:** `status.cardInsertionState !== 'none'`
|
|
184
|
-
|
|
185
|
-
---
|
|
186
|
-
|
|
187
|
-
#### Service: OccupancySensor (subtype: "NightModeStatus")
|
|
188
|
-
|
|
189
|
-
Shows if device is in night mode (vs day mode).
|
|
190
|
-
|
|
191
|
-
**Characteristics:**
|
|
192
|
-
- `OccupancyDetected` (GET) - OCCUPANCY_DETECTED when in night mode
|
|
193
|
-
- `StatusActive` (GET) - Online/offline indicator
|
|
194
|
-
|
|
195
|
-
**Source:** `status.dayMode === 'night'`
|
|
196
|
-
|
|
197
|
-
**Use Case:** Trigger automations based on device's day/night schedule
|
|
198
|
-
|
|
199
|
-
---
|
|
200
|
-
|
|
201
|
-
#### Service: Switch (subtype: "SleepTimer")
|
|
202
|
-
|
|
203
|
-
Toggle sleep timer on/off.
|
|
204
|
-
|
|
205
|
-
**Characteristics:**
|
|
206
|
-
- `On` (GET/SET) - Sleep timer active state
|
|
207
|
-
- `StatusActive` (GET) - Online/offline indicator
|
|
208
|
-
|
|
209
|
-
**Source:** `playback.sleepTimerActive`
|
|
210
|
-
**Control:** `sendCommand({ action: 'sleep-timer', minutes: 30 })` (on) or `minutes: 0` (off)
|
|
211
|
-
|
|
212
|
-
---
|
|
213
|
-
|
|
214
|
-
#### Service: Switch (subtype: "Bluetooth")
|
|
215
|
-
|
|
216
|
-
Toggle Bluetooth on/off (config-based, works offline).
|
|
217
|
-
|
|
218
|
-
**Characteristics:**
|
|
219
|
-
- `On` (GET/SET) - Bluetooth enabled state
|
|
220
|
-
|
|
221
|
-
**Source:** `config.bluetoothEnabled` (string '0' or '1')
|
|
222
|
-
**Control:** `updateConfig({ bluetoothEnabled: '1' | '0' })`
|
|
223
|
-
|
|
224
|
-
**Note:** No StatusActive - config-based services work offline
|
|
225
|
-
|
|
226
|
-
---
|
|
227
|
-
|
|
228
|
-
#### Service: Fanv2 (subtype: "DayMaxVolume")
|
|
229
|
-
|
|
230
|
-
Control day mode maximum volume limit (config-based, works offline).
|
|
231
|
-
|
|
232
|
-
**Characteristics:**
|
|
233
|
-
- `Active` (GET) - Always ACTIVE
|
|
234
|
-
- `RotationSpeed` (GET/SET) - Volume limit 0-100%
|
|
235
|
-
|
|
236
|
-
**Source:** `config.maxVolumeLimit` (device: 0-16, HomeKit: 0-100%)
|
|
237
|
-
**Control:** `updateConfig({ maxVolumeLimit: 'N' })`
|
|
238
|
-
**Conversion:** `percentage = (limit / 16) * 100`
|
|
239
|
-
|
|
240
|
-
---
|
|
241
|
-
|
|
242
|
-
#### Service: Fanv2 (subtype: "NightMaxVolume")
|
|
243
|
-
|
|
244
|
-
Control night mode maximum volume limit (config-based, works offline).
|
|
245
|
-
|
|
246
|
-
**Characteristics:**
|
|
247
|
-
- `Active` (GET) - Always ACTIVE
|
|
248
|
-
- `RotationSpeed` (GET/SET) - Volume limit 0-100%
|
|
249
|
-
|
|
250
|
-
**Source:** `config.nightMaxVolumeLimit` (device: 0-16, HomeKit: 0-100%)
|
|
251
|
-
**Control:** `updateConfig({ nightMaxVolumeLimit: 'N' })`
|
|
252
|
-
**Conversion:** `percentage = (limit / 16) * 100`
|
|
253
|
-
|
|
254
|
-
---
|
|
255
|
-
|
|
256
|
-
#### Service: StatelessProgrammableSwitch (DYNAMIC) - NOT YET IMPLEMENTED
|
|
257
|
-
|
|
258
|
-
One service per shortcut configured on device. Trigger shortcuts from HomeKit.
|
|
259
|
-
|
|
260
|
-
**Characteristics:**
|
|
261
|
-
- `ProgrammableSwitchEvent` (READ/NOTIFY) - SINGLE_PRESS event
|
|
262
|
-
- `ServiceLabelIndex` (GET) - Index in shortcuts array
|
|
263
|
-
|
|
264
|
-
**Source:** `config.shortcuts.modes.day.content[]` and `config.shortcuts.modes.night.content[]`
|
|
265
|
-
**Control:** `sendCommand({ action: 'play', shortcut: X })`
|
|
266
|
-
|
|
267
|
-
**Note:** Dynamic services - created based on device configuration
|
|
268
|
-
|
|
269
|
-
---
|
|
270
|
-
|
|
271
|
-
### Service Availability Matrix
|
|
272
|
-
|
|
273
|
-
| Service | v2 | v3 | mini |
|
|
274
|
-
|---------|----|----|------|
|
|
275
|
-
| AccessoryInformation | ✅ | ✅ | ✅ |
|
|
276
|
-
| SmartSpeaker | ✅ | ✅ | ✅ |
|
|
277
|
-
| Battery | ✅ | ✅ | ✅ |
|
|
278
|
-
| ContactSensor (CardSlot) | ✅ | ✅ | ✅ |
|
|
279
|
-
| OccupancySensor (NightMode) | ✅ | ✅ | ✅ |
|
|
280
|
-
| Switch (SleepTimer) | ✅ | ✅ | ✅ |
|
|
281
|
-
| Switch (Bluetooth) | ✅ | ✅ | ✅ |
|
|
282
|
-
| Fanv2 (Volume Limits) | ✅ | ✅ | ✅ |
|
|
283
|
-
| TemperatureSensor | ❌ | ✅ | ❌ |
|
|
284
|
-
| Lightbulb (Nightlights) | ❌ | ✅ | ❌ |
|
|
285
|
-
| ContactSensor (Nightlight Status) | ❌ | ✅ | ❌ |
|
|
286
|
-
| StatelessProgrammableSwitch | 🚧 | 🚧 | 🚧 |
|
|
287
|
-
|
|
288
|
-
---
|
|
289
|
-
|
|
290
|
-
## Offline Behavior
|
|
291
|
-
|
|
292
|
-
### What Gets Marked as "No Response"
|
|
293
|
-
|
|
294
|
-
Services are categorized by data source:
|
|
295
|
-
|
|
296
|
-
**Device State Services** (require online connection):
|
|
297
|
-
- SmartSpeaker (playback, volume)
|
|
298
|
-
- Battery (level, charging)
|
|
299
|
-
- TemperatureSensor (temperature)
|
|
300
|
-
- ContactSensor - all variants (card, nightlight status)
|
|
301
|
-
- OccupancySensor (night mode)
|
|
302
|
-
- Switch (SleepTimer) - reads playback state
|
|
303
|
-
|
|
304
|
-
**Config-Based Services** (work offline):
|
|
305
|
-
- Lightbulb (nightlight color/brightness)
|
|
306
|
-
- Fanv2 (volume limits)
|
|
307
|
-
- Switch (Bluetooth)
|
|
308
|
-
- StatelessProgrammableSwitch (shortcuts)
|
|
309
|
-
|
|
310
|
-
### Implementation
|
|
311
|
-
|
|
312
|
-
Device state services use `StatusActive` characteristic to indicate offline status. When `StatusActive` is false, HomeKit shows "No Response" for the service.
|
|
313
|
-
|
|
314
|
-
Config-based services do NOT have `StatusActive` and remain accessible when offline since they only read/write device configuration (cached in `deviceModel.config`).
|
|
315
|
-
|
|
316
|
-
---
|
|
317
|
-
|
|
318
|
-
## ❌ What's Left to Implement
|
|
319
|
-
|
|
320
|
-
### StatelessProgrammableSwitch Services (Shortcuts)
|
|
321
|
-
|
|
322
|
-
Dynamic services created based on `config.shortcuts` configuration.
|
|
323
|
-
|
|
324
|
-
**Implementation Notes:**
|
|
325
|
-
- Parse `config.shortcuts.modes.day.content[]` and `config.shortcuts.modes.night.content[]`
|
|
326
|
-
- Create one service per unique shortcut
|
|
327
|
-
- Handle shortcuts refresh when config changes
|
|
328
|
-
- Trigger with `sendCommand({ action: 'play', shortcut: X })`
|
|
329
|
-
|
|
330
|
-
**Complexity:** Dynamic service lifecycle management, shortcut identification
|
|
331
|
-
|
|
332
|
-
---
|
|
333
|
-
|
|
334
|
-
## API Reference Documentation
|
|
335
|
-
|
|
336
|
-
### YotoDeviceModel - State & Events
|
|
337
|
-
|
|
338
|
-
**State Properties:**
|
|
339
|
-
- `device` - Device metadata (deviceId, name, deviceType, etc.)
|
|
340
|
-
- `status` - Live device status (volume, battery, temperature, etc.)
|
|
341
|
-
- `config` - Device configuration (nightlight colors, volume limits, etc.)
|
|
342
|
-
- `shortcuts` - Configured shortcuts
|
|
343
|
-
- `playback` - Playback state (status, track, sleep timer, etc.)
|
|
344
|
-
|
|
345
|
-
**Events:**
|
|
346
|
-
- `statusUpdate(status, source, changedFields)` - Device status changed
|
|
347
|
-
- `configUpdate(config, changedFields)` - Configuration changed
|
|
348
|
-
- `playbackUpdate(playback, changedFields)` - Playback state changed
|
|
349
|
-
- `online({ reason })` - Device came online
|
|
350
|
-
- `offline({ reason })` - Device went offline
|
|
351
|
-
|
|
352
|
-
### Device API Endpoints
|
|
353
|
-
|
|
354
|
-
- `GET /devices` - List all devices
|
|
355
|
-
- `GET /devices/:deviceId/config` - Get device config
|
|
356
|
-
- `GET /devices/:deviceId/status` - Get device status
|
|
357
|
-
- `POST /devices/:deviceId/config` - Update device config
|
|
358
|
-
- `POST /devices/:deviceId/mq` - Send device command
|
|
359
|
-
|
|
360
|
-
### Command Examples
|
|
361
|
-
|
|
362
|
-
```javascript
|
|
363
|
-
// Playback control
|
|
364
|
-
await deviceModel.sendCommand({ action: 'play' })
|
|
365
|
-
await deviceModel.sendCommand({ action: 'pause' })
|
|
366
|
-
await deviceModel.sendCommand({ action: 'stop' })
|
|
367
|
-
|
|
368
|
-
// Volume control
|
|
369
|
-
await deviceModel.sendCommand({ action: 'volume', volume: 10 })
|
|
370
|
-
|
|
371
|
-
// Sleep timer
|
|
372
|
-
await deviceModel.sendCommand({ action: 'sleep-timer', minutes: 30 })
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
### Config Update Examples
|
|
376
|
-
|
|
377
|
-
```javascript
|
|
378
|
-
// Nightlight colors
|
|
379
|
-
await deviceModel.updateConfig({ ambientColour: '0xff5733' })
|
|
380
|
-
await deviceModel.updateConfig({ nightAmbientColour: '0x3366ff' })
|
|
381
|
-
|
|
382
|
-
// Volume limits
|
|
383
|
-
await deviceModel.updateConfig({ maxVolumeLimit: '12' })
|
|
384
|
-
await deviceModel.updateConfig({ nightMaxVolumeLimit: '8' })
|
|
385
|
-
|
|
386
|
-
// Bluetooth
|
|
387
|
-
await deviceModel.updateConfig({ bluetoothEnabled: '1' })
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
---
|
|
391
|
-
|
|
392
|
-
## Testing Checklist
|
|
393
|
-
|
|
394
|
-
### Basic Functionality
|
|
395
|
-
- [ ] Device discovery and accessory creation
|
|
396
|
-
- [ ] Playback control (play/pause/stop)
|
|
397
|
-
- [ ] Volume control (0-16 range)
|
|
398
|
-
- [ ] Battery status updates
|
|
399
|
-
- [ ] Online/offline detection
|
|
400
|
-
- [ ] Firmware version display
|
|
401
|
-
|
|
402
|
-
### Optional Services
|
|
403
|
-
- [ ] Temperature sensor (v3 only)
|
|
404
|
-
- [ ] Nightlight color control (v3 only)
|
|
405
|
-
- [ ] Nightlight brightness control (v3 only)
|
|
406
|
-
- [ ] Nightlight status sensors (v3 only)
|
|
407
|
-
- [ ] Card slot detection (all devices)
|
|
408
|
-
- [ ] Night mode detection (all devices)
|
|
409
|
-
- [ ] Sleep timer control (all devices)
|
|
410
|
-
- [ ] Bluetooth toggle (all devices)
|
|
411
|
-
- [ ] Volume limit controls (all devices)
|
|
412
|
-
|
|
413
|
-
### Edge Cases
|
|
414
|
-
- [ ] Device goes offline during operation
|
|
415
|
-
- [ ] MQTT disconnection with HTTP fallback
|
|
416
|
-
- [ ] Multiple devices in one account
|
|
417
|
-
- [ ] Device rename handling
|
|
418
|
-
- [ ] Config changes from Yoto app
|
|
419
|
-
|
|
420
|
-
### Automations
|
|
421
|
-
- [ ] Trigger on card insertion
|
|
422
|
-
- [ ] Trigger on night mode change
|
|
423
|
-
- [ ] Trigger on nightlight activation
|
|
424
|
-
- [ ] Volume limit changes based on time
|
|
425
|
-
- [ ] Sleep timer activation
|
package/eslint.config.js
DELETED
package/index.test.js
DELETED
package/logo.png
DELETED
|
Binary file
|
package/pnpm-workspace.yaml
DELETED