homebridge-yoto 0.0.28 → 0.0.31

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/AGENTS.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  This document contains patterns, conventions, and guidelines for developing the homebridge-yoto plugin.
4
4
 
5
+ ## Dont write summary markdown files unless asked to do so
6
+
5
7
  ## JSDoc Typing Patterns
6
8
 
7
9
  ### Use TypeScript-in-JavaScript (ts-in-js)
@@ -80,174 +82,57 @@ import { EventEmitter } from 'events';
80
82
  /** @import { API, PlatformAccessory } from 'homebridge' */
81
83
  ```
82
84
 
83
- ### Homebridge Type Import Patterns
84
-
85
- Homebridge types are available from the `homebridge` package:
86
-
87
- ```javascript
88
- /** @import { API, Characteristic, DynamicPlatformPlugin, Logger, PlatformAccessory, PlatformConfig, Service } from 'homebridge' */
89
- /** @import { CharacteristicValue } from 'homebridge' */
90
- ```
91
-
92
- For HAP (HomeKit Accessory Protocol) types:
93
-
94
- ```javascript
95
- /** @import { HAPStatus } from 'homebridge' */
96
-
97
- /**
98
- * @throws {import('homebridge').HapStatusError}
99
- */
100
- function throwNotResponding() {
101
- throw new this.api.hap.HapStatusError(this.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
102
- }
103
- ```
104
-
105
- ### Prefer Schema-Based Types
106
-
107
- Define types for API responses and configuration objects using JSDoc typedef.
108
-
109
- ```javascript
110
- /**
111
- * @typedef {Object} YotoDeviceStatus
112
- * @property {string} deviceId
113
- * @property {number} batteryLevelPercentage
114
- * @property {boolean} isCharging
115
- * @property {boolean} isOnline
116
- * @property {string | null} activeCard
117
- * @property {number} userVolumePercentage
118
- * @property {number} systemVolumePercentage
119
- * @property {number} temperatureCelcius
120
- * @property {number} wifiStrength
121
- * @property {0 | 1 | 2} cardInsertionState - 0=none, 1=physical, 2=remote
122
- * @property {-1 | 0 | 1} dayMode - -1=unknown, 0=night, 1=day
123
- * @property {0 | 1 | 2 | 3} powerSource - 0=battery, 1=V2 dock, 2=USB-C, 3=Qi
124
- */
125
-
126
- /**
127
- * @typedef {Object} YotoDevice
128
- * @property {string} deviceId
129
- * @property {string} name
130
- * @property {string} description
131
- * @property {boolean} online
132
- * @property {string} releaseChannel
133
- * @property {string} deviceType
134
- * @property {string} deviceFamily
135
- * @property {string} deviceGroup
136
- */
137
-
138
- /**
139
- * @typedef {Object} YotoDeviceConfig
140
- * @property {string} name
141
- * @property {YotoDeviceConfigSettings} config
142
- */
143
-
144
- /**
145
- * @typedef {Object} YotoDeviceConfigSettings
146
- * @property {any[]} alarms
147
- * @property {string} ambientColour
148
- * @property {string} bluetoothEnabled
149
- * @property {boolean} btHeadphonesEnabled
150
- * @property {string} clockFace
151
- * @property {string} dayDisplayBrightness
152
- * @property {string} dayTime
153
- * @property {string} maxVolumeLimit
154
- * @property {string} nightAmbientColour
155
- * @property {string} nightDisplayBrightness
156
- * @property {string} nightMaxVolumeLimit
157
- * @property {string} nightTime
158
- * @property {boolean} repeatAll
159
- * @property {string} shutdownTimeout
160
- * @property {string} volumeLevel
161
- */
162
- ```
163
-
164
- ### API Response Typing
85
+ ## Event Pattern Preference
165
86
 
166
- Type API responses explicitly:
87
+ ### Use Aggregate Events with Exhaustive Type Narrowing
167
88
 
168
- ```javascript
169
- /**
170
- * @typedef {Object} YotoApiDevicesResponse
171
- * @property {YotoDevice[]} devices
172
- */
89
+ The `yoto-nodejs-client` library should emit **only aggregate events** with `changedFields` arrays:
173
90
 
174
- /**
175
- * Get all devices for authenticated user
176
- * @returns {Promise<YotoDevice[]>}
177
- */
178
- async function getDevices() {
179
- const response = await fetch('https://api.yotoplay.com/device-v2/devices/mine', {
180
- headers: { 'Authorization': `Bearer ${this.accessToken}` }
181
- });
182
-
183
- /** @type {YotoApiDevicesResponse} */
184
- const data = await response.json();
185
- return data.devices;
186
- }
187
- ```
91
+ - `statusUpdate` - passes `(status, source, changedFields[])`
92
+ - `configUpdate` - passes `(config, changedFields[])`
93
+ - `playbackUpdate` - passes `(playback, changedFields[])`
188
94
 
189
- ### Platform Accessory Context Typing
95
+ **Do NOT create granular field events** like `volumeChanged`, `batteryLevelChanged`, etc.
190
96
 
191
- Define the context object structure stored in accessories:
97
+ ### Homebridge Plugin Pattern
192
98
 
193
- ```javascript
194
- /**
195
- * @typedef {Object} YotoAccessoryContext
196
- * @property {YotoDevice} device
197
- * @property {YotoDeviceStatus | null} lastStatus
198
- * @property {number} lastUpdate
199
- */
200
-
201
- /**
202
- * @param {PlatformAccessory<YotoAccessoryContext>} accessory
203
- */
204
- function configureAccessory(accessory) {
205
- const device = accessory.context.device;
206
- this.log.info('Restoring device:', device.name);
207
- }
208
- ```
209
-
210
- ### Nullable Fields in API Responses
211
-
212
- Use union types with `null` for fields that may be absent:
99
+ The plugin should use exhaustive switch statements to handle field updates:
213
100
 
214
101
  ```javascript
215
- /**
216
- * @typedef {Object} YotoCardContent
217
- * @property {string} cardId
218
- * @property {string} title
219
- * @property {string | null} author
220
- * @property {string | null} description
221
- * @property {YotoChapter[] | null} chapters
222
- */
102
+ this.deviceModel.on('statusUpdate', (status, source, changedFields) => {
103
+ for (const field of changedFields) {
104
+ switch (field) {
105
+ case 'volume':
106
+ // Update volume characteristic
107
+ break
108
+
109
+ case 'batteryLevelPercentage':
110
+ // Update battery characteristic
111
+ break
112
+
113
+ // ... handle all fields
114
+
115
+ case 'firmwareVersion':
116
+ // Empty case - available but not used yet
117
+ break
118
+
119
+ default: {
120
+ // Exhaustive check - TypeScript error if field missed
121
+ const _exhaustive: never = field
122
+ break
123
+ }
124
+ }
125
+ }
126
+ })
223
127
  ```
224
128
 
225
- ### Optional vs Nullable
226
-
227
- Distinguish between optional fields (may not exist) and nullable fields (exists but may be null):
228
-
229
- ```javascript
230
- /**
231
- * @typedef {Object} YotoPlayerState
232
- * @property {string} deviceId - Always present
233
- * @property {string | null} activeCard - Present but may be null
234
- * @property {string} [lastPlayedCard] - May not be present in response
235
- */
236
- ```
129
+ **Benefits:**
130
+ - Fewer event listeners (3 instead of 20+)
131
+ - Exhaustive TypeScript checking ensures all fields handled
132
+ - Empty cases document available fields
133
+ - Easy to extend - just fill in empty cases
134
+ - Type-safe with proper field typing
237
135
 
238
136
  ## Changelog Management
239
137
 
240
138
  **NEVER manually edit CHANGELOG.md**
241
-
242
- The changelog is automatically generated using `auto-changelog` during the version bump process:
243
-
244
- - When running `npm version [patch|minor|major]`, the `version:changelog` script runs automatically
245
- - It uses the keepachangelog template
246
- - Detects breaking changes via `BREAKING CHANGE:` pattern in commit messages
247
- - Generates entries from git commits
248
-
249
- To ensure proper changelog generation:
250
- - Write meaningful git commit messages
251
- - Use conventional commit format when possible
252
- - Mark breaking changes with `BREAKING CHANGE:` in commit body
253
- - Let the automation handle changelog updates during `npm version`
package/CHANGELOG.md CHANGED
@@ -1,8 +1,16 @@
1
- # homebridge-yoto Change Log
1
+ # Changelog
2
+
2
3
  All notable changes to this project will be documented in this file.
3
- This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
- ## Unreleased
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
9
+
10
+ ## 0.0.31
11
+
12
+ ### Commits
6
13
 
7
- ## 1.0.0 - {{date}}
8
- * ...
14
+ - init [`88b35b6`](https://github.com/bcomnes/homebridge-yoto/commit/88b35b695166c6f5c3e3ec381c4afb52940a369b)
15
+ - WIP [`cf0e5c8`](https://github.com/bcomnes/homebridge-yoto/commit/cf0e5c85df5984eb7fe10a2118de08990d875337)
16
+ - Implement against client [`27d4fae`](https://github.com/bcomnes/homebridge-yoto/commit/27d4fae930a84f12a4671d3cd129c299505e398b)
package/NOTES.md ADDED
@@ -0,0 +1,87 @@
1
+ Homebridge Notes

2
+ http://bee.local:8581/login
3
+
4
+
5
+ - Instance: https://homebridge.io
6
+ - Homepage: https://homebridge.io
7
+ - Plugin Docs: https://developers.homebridge.io/#/
8
+ - Wiki: https://github.com/homebridge/homebridge/wiki
9
+ - Homebridge package: https://github.com/homebridge/homebridge
10
+ - Plugins Repo: https://github.com/homebridge/plugins
11
+ - Plugin UI Utils: https://github.com/homebridge/plugin-ui-utils
12
+ - HAP Client: https://github.com/homebridge/hap-client
13
+ - HAP-NodeJS: https://github.com/homebridge/HAP-NodeJS
14
+ - HAP-NodeJS JSDocs: https://developers.homebridge.io/HAP-NodeJS/modules.html
15
+ - Old docs?: https://github.com/homebridge/documentation
16
+ - PLugin Tempalte: https://github.com/homebridge/homebridge-plugin-template
17
+ - Template lib helper thing: https://github.com/ebaauw/homebridge-lib
18
+ - Ring: https://github.com/homebridge-plugins/homebridge-meross/blob/9ea479ea94a8cfa8dce9051976fafb8308faae85/lib/platform.js#L1037
19
+ - Scoped Plugins (Reference) https://github.com/homebridge/plugins/wiki/Scoped-Plugins#available-plugins
20
+ - https://github.com/homebridge-plugins/homebridge-rainbird/blob/latest/src/platform.ts
21
+ - https://github.com/homebridge-plugins/homebridge-unifi-network
22
+
23
+
24
+ Yoto Docs:

25
+ - https://yoto.dev/get-started/start-here/
26
+ - https://yoto.dev/api/
27
+ - https://yoto.space/developers
28
+ - https://yoto.space/developers/post/home-assistant-integration-Ao9OxbsMDBqaG9I
29
+ - https://github.com/yotoplay/examples
30
+ - https://github.com/yotoplay/twine-to-yoto
31
+
32
+ MQTT
33
+ - MQTT: https://github.com/mqttjs/MQTT.js
34
+ - https://mqtt.org
35
+ - https://www.emqx.com/en/blog/the-easiest-guide-to-getting-started-with-mqtt
36
+ - https://aws.amazon.com/what-is/mqtt/
37
+ - https://en.wikipedia.org/wiki/MQTT
38
+ -
39
+
40
+ - https://github.com/ebaauw/homebridge-zp/issues/10#issuecomment-270743358
41
+
42
+
43
+ - Implement a improved config type, and populate it.
44
+ - Audit the set functions in hb, make sure the client works/helps with that.
45
+ - Clean up unused vars and config
46
+ - Audit online/offline config set methods
47
+
48
+
49
+ [12/26/2025, 4:05:52 PM] [homebridge-yoto] Device discovered: GGs Boombox (y29sZvOdk63vN50Qed5eH4Y0)
50
+ [12/26/2025, 4:05:52 PM] [homebridge-yoto] Adding new accessory: GGs Boombox
51
+ [12/26/2025, 4:05:52 PM] [homebridge-yoto] [Accessory] Setting up GGs Boombox
52
+ [GGs Boombox@GGs Boombox@Status Active] Characteristic not in required or optional characteristic section for service SmartSpeaker. Adding anyway.
53
+ [GGs Boombox@GGs Boombox Battery@Status Active] Characteristic not in required or optional characteristic section for service Battery. Adding anyway.
54
+ [12/26/2025, 4:05:52 PM] [homebridge-yoto] [Accessory] ✓ GGs Boombox ready
55
+ [12/26/2025, 4:05:52 PM] [homebridge-yoto] Publishing new external accessory: GGs Boombox
56
+ [12/26/2025, 4:05:52 PM] GGs Boombox 55FC is running on port 45125.
57
+ [12/26/2025, 4:05:52 PM] Please add [GGs Boombox 55FC] manually in Home app. Setup Code: 547-78-744
58
+ [12/26/2025, 4:05:54 PM] [homebridge-yoto] Device discovered: Gigis mini (y2JVD5AxvJEeaK1g6nvBWkej)
59
+ [12/26/2025, 4:05:54 PM] [homebridge-yoto] Adding new accessory: Gigis mini
60
+ [12/26/2025, 4:05:54 PM] [homebridge-yoto] [Accessory] Setting up Gigis mini
61
+ [Gigis mini@Gigis mini@Status Active] Characteristic not in required or optional characteristic section for service SmartSpeaker. Adding anyway.
62
+ [Gigis mini@Gigis mini Battery@Status Active] Characteristic not in required or optional characteristic section for service Battery. Adding anyway.
63
+ [12/26/2025, 4:05:54 PM] [homebridge-yoto] [Accessory] ✓ Gigis mini ready
64
+ [12/26/2025, 4:05:54 PM] [homebridge-yoto] Publishing new external accessory: Gigis mini
65
+ [12/26/2025, 4:05:54 PM] Gigis mini 8D02 is running on port 38987.
66
+ [12/26/2025, 4:05:54 PM] Please add [Gigis mini 8D02] manually in Home app. Setup Code: 547-78-744
67
+ [12/26/2025, 4:05:55 PM] [homebridge-yoto] Device discovered: Otto's mini (y2iYT7ItkMRWbuMzTDuGjgmS)
68
+ [12/26/2025, 4:05:55 PM] [homebridge-yoto] Adding new accessory: Otto's mini
69
+ [12/26/2025, 4:05:55 PM] [homebridge-yoto] [Accessory] Setting up Otto's mini
70
+ [Otto's mini @Otto's mini @Status Active] Characteristic not in required or optional characteristic section for service SmartSpeaker. Adding anyway.
71
+ [Otto's mini @Otto's mini Battery@Status Active] Characteristic not in required or optional characteristic section for service Battery. Adding anyway.
72
+ [12/26/2025, 4:05:55 PM] [homebridge-yoto] [Accessory] ✓ Otto's mini ready
73
+ [12/26/2025, 4:05:55 PM] [homebridge-yoto] Publishing new external accessory: Otto's mini
74
+ [12/26/2025, 4:05:55 PM] Otto's mini 024E is running on port 33839.
75
+ [12/26/2025, 4:05:55 PM] Please add [Otto's mini 024E] manually in Home app. Setup Code: 547-78-744
76
+ [12/26/2025, 4:05:57 PM] [homebridge-yoto] Device discovered: Ottos Boombox (y2knTzvDkKVtvnhl09z9bWfe)
77
+ [12/26/2025, 4:05:57 PM] [homebridge-yoto] Adding new accessory: Ottos Boombox
78
+ [12/26/2025, 4:05:57 PM] [homebridge-yoto] [Accessory] Setting up Ottos Boombox
79
+ [Ottos Boombox@Ottos Boombox@Status Active] Characteristic not in required or optional characteristic section for service SmartSpeaker. Adding anyway.
80
+ [Ottos Boombox@Ottos Boombox Battery@Status Active] Characteristic not in required or optional characteristic section for service Battery. Adding anyway.
81
+ [12/26/2025, 4:05:57 PM] [homebridge-yoto] [Accessory] ✓ Ottos Boombox ready
82
+ [12/26/2025, 4:05:57 PM] [homebridge-yoto] Publishing new external accessory: Ottos Boombox
83
+ [12/26/2025, 4:05:57 PM] [homebridge-yoto] ✓ Yoto account started with 4 device(s)
84
+ [12/26/2025, 4:05:57 PM] Ottos Boombox 3486 is running on port 37845.
85
+ [12/26/2025, 4:05:57 PM] Please add [Ottos Boombox 3486] manually in Home app. Setup Code: 547-78-744
86
+ [12/26/2025, 4:05:59 PM] [homebridge-yoto] This plugin generated a warning from the characteristic 'Brightness': characteristic was supplied illegal value: number 255 exceeded maximum of 100. See https://homebridge.io/w/JtMGR for more info.
87
+ [12/26/2025, 4:05:59 PM] [homebridge-yoto] This plugin generated a warning from the characteristic 'Brightness': characteristic was supplied illegal value: number 255 exceeded maximum of 100. See https://homebridge.io/w/JtMGR for more info.