yoto-nodejs-client 0.0.6 → 0.0.7
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/README.md +51 -36
- package/lib/test-helpers/device-model-test-helpers.d.ts +29 -0
- package/lib/test-helpers/device-model-test-helpers.d.ts.map +1 -0
- package/lib/test-helpers/device-model-test-helpers.js +116 -0
- package/lib/yoto-account.d.ts +339 -9
- package/lib/yoto-account.d.ts.map +1 -1
- package/lib/yoto-account.js +411 -39
- package/lib/yoto-account.test.js +139 -0
- package/lib/yoto-device.d.ts +31 -3
- package/lib/yoto-device.d.ts.map +1 -1
- package/lib/yoto-device.js +33 -11
- package/lib/yoto-device.test.js +6 -111
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -211,24 +211,21 @@ account.on('started', (metadata) => {
|
|
|
211
211
|
|
|
212
212
|
|
|
213
213
|
|
|
214
|
-
// Listen for device
|
|
215
|
-
account.on('
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
console.log(`${deviceId} battery: ${status.batteryLevelPercentage}%`)
|
|
219
|
-
})
|
|
214
|
+
// Listen for device events across all devices via the unified bus
|
|
215
|
+
account.on('statusUpdate', ({ deviceId, status, source }) => {
|
|
216
|
+
console.log(`${deviceId} battery: ${status.batteryLevelPercentage}% (${source})`)
|
|
217
|
+
})
|
|
220
218
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
219
|
+
account.on('online', ({ deviceId }) => {
|
|
220
|
+
console.log(`${deviceId} came online`)
|
|
221
|
+
})
|
|
224
222
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
})
|
|
223
|
+
account.on('offline', ({ deviceId }) => {
|
|
224
|
+
console.log(`${deviceId} went offline`)
|
|
228
225
|
})
|
|
229
226
|
|
|
230
227
|
// Unified error handling
|
|
231
|
-
account.on('error', (error, context) => {
|
|
228
|
+
account.on('error', ({ error, context }) => {
|
|
232
229
|
console.error(`Error in ${context.source}:`, error.message)
|
|
233
230
|
if (context.deviceId) {
|
|
234
231
|
console.error(`Device: ${context.deviceId}`)
|
|
@@ -970,10 +967,17 @@ Create a stateful device client that manages device state primarily from MQTT wi
|
|
|
970
967
|
- `playbackUpdate(playback, changedFields)` - Playback state changed, passes (playback, changedFields)
|
|
971
968
|
- `online(metadata)` - Device came online, passes metadata with reason and optional upTime
|
|
972
969
|
- `offline(metadata)` - Device went offline, passes metadata with reason and optional shutDownReason or timeSinceLastSeen
|
|
973
|
-
- `mqttConnect()` - MQTT client connected
|
|
970
|
+
- `mqttConnect(metadata)` - MQTT client connected, passes CONNACK metadata
|
|
974
971
|
- `mqttDisconnect(metadata)` - MQTT disconnect packet received, passes metadata with disconnect packet
|
|
975
972
|
- `mqttClose(metadata)` - MQTT connection closed, passes metadata with close reason
|
|
976
973
|
- `mqttReconnect()` - MQTT client is reconnecting
|
|
974
|
+
- `mqttOffline()` - MQTT client goes offline
|
|
975
|
+
- `mqttEnd()` - MQTT client end is called
|
|
976
|
+
- `mqttStatus(topic, message)` - Raw MQTT status messages (documented status topic)
|
|
977
|
+
- `mqttEvents(topic, message)` - Raw MQTT events messages
|
|
978
|
+
- `mqttStatusLegacy(topic, message)` - Raw legacy MQTT status messages (undocumented status topic)
|
|
979
|
+
- `mqttResponse(topic, message)` - Raw MQTT response messages
|
|
980
|
+
- `mqttUnknown(topic, message)` - Raw MQTT messages that do not match known types
|
|
977
981
|
- `error(error)` - Error occurred, passes error
|
|
978
982
|
|
|
979
983
|
**Static Properties & Methods:**
|
|
@@ -1051,11 +1055,27 @@ Create an account manager that automatically discovers and manages all devices f
|
|
|
1051
1055
|
**Events:**
|
|
1052
1056
|
- `started(metadata)` - Account started (metadata: { deviceCount, devices })
|
|
1053
1057
|
- `stopped()` - Account stopped
|
|
1054
|
-
- `deviceAdded(deviceId
|
|
1055
|
-
- `deviceRemoved(deviceId)` - Device was removed
|
|
1056
|
-
- `
|
|
1057
|
-
|
|
1058
|
-
|
|
1058
|
+
- `deviceAdded({ deviceId })` - Device was added
|
|
1059
|
+
- `deviceRemoved({ deviceId })` - Device was removed
|
|
1060
|
+
- `statusUpdate({ deviceId, status, source, changedFields })` - Re-emitted device status update
|
|
1061
|
+
- `configUpdate({ deviceId, config, changedFields })` - Re-emitted config update
|
|
1062
|
+
- `playbackUpdate({ deviceId, playback, changedFields })` - Re-emitted playback update
|
|
1063
|
+
- `online({ deviceId, metadata })` - Re-emitted online event
|
|
1064
|
+
- `offline({ deviceId, metadata })` - Re-emitted offline event
|
|
1065
|
+
- `mqttConnect({ deviceId, metadata })` - Re-emitted MQTT connect
|
|
1066
|
+
- `mqttDisconnect({ deviceId, metadata })` - Re-emitted MQTT disconnect
|
|
1067
|
+
- `mqttClose({ deviceId, metadata })` - Re-emitted MQTT close
|
|
1068
|
+
- `mqttReconnect({ deviceId })` - Re-emitted MQTT reconnect
|
|
1069
|
+
- `mqttOffline({ deviceId })` - Re-emitted MQTT offline
|
|
1070
|
+
- `mqttEnd({ deviceId })` - Re-emitted MQTT end
|
|
1071
|
+
- `mqttStatus({ deviceId, topic, message })` - Re-emitted raw MQTT status
|
|
1072
|
+
- `mqttEvents({ deviceId, topic, message })` - Re-emitted raw MQTT events
|
|
1073
|
+
- `mqttStatusLegacy({ deviceId, topic, message })` - Re-emitted raw MQTT legacy status
|
|
1074
|
+
- `mqttResponse({ deviceId, topic, message })` - Re-emitted raw MQTT response
|
|
1075
|
+
- `mqttUnknown({ deviceId, topic, message })` - Re-emitted raw MQTT unknown message
|
|
1076
|
+
- `error({ error, context })` - Error occurred (context: { source, deviceId, operation })
|
|
1077
|
+
|
|
1078
|
+
**Note:** You can still listen to individual device events by attaching listeners to each `YotoDeviceModel`, but the account now re-emits device and MQTT events with device context for unified handling.
|
|
1059
1079
|
|
|
1060
1080
|
```js
|
|
1061
1081
|
import { YotoAccount } from 'yoto-nodejs-client'
|
|
@@ -1075,26 +1095,21 @@ const account = new YotoAccount({
|
|
|
1075
1095
|
})
|
|
1076
1096
|
|
|
1077
1097
|
// Account-level error handling
|
|
1078
|
-
account.on('error', (error, context) => {
|
|
1098
|
+
account.on('error', ({ error, context }) => {
|
|
1079
1099
|
console.error(`Error in ${context.source}:`, error.message)
|
|
1080
1100
|
})
|
|
1081
1101
|
|
|
1082
|
-
//
|
|
1083
|
-
account.on('
|
|
1084
|
-
console.log(
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
})
|
|
1094
|
-
|
|
1095
|
-
deviceModel.on('offline', (metadata) => {
|
|
1096
|
-
console.log(`${deviceId} went offline (${metadata.reason})`)
|
|
1097
|
-
})
|
|
1102
|
+
// Unified device events across all devices
|
|
1103
|
+
account.on('statusUpdate', ({ deviceId, status, source }) => {
|
|
1104
|
+
console.log(`${deviceId} battery: ${status.batteryLevelPercentage}% (${source})`)
|
|
1105
|
+
})
|
|
1106
|
+
|
|
1107
|
+
account.on('online', ({ deviceId, metadata }) => {
|
|
1108
|
+
console.log(`${deviceId} came online (${metadata.reason})`)
|
|
1109
|
+
})
|
|
1110
|
+
|
|
1111
|
+
account.on('offline', ({ deviceId, metadata }) => {
|
|
1112
|
+
console.log(`${deviceId} went offline (${metadata.reason})`)
|
|
1098
1113
|
})
|
|
1099
1114
|
|
|
1100
1115
|
await account.start()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {Promise<unknown>} promise
|
|
3
|
+
* @param {number} timeoutMs
|
|
4
|
+
* @param {string} label
|
|
5
|
+
* @returns {Promise<unknown>}
|
|
6
|
+
*/
|
|
7
|
+
export function withTimeout(promise: Promise<unknown>, timeoutMs: number, label: string): Promise<unknown>;
|
|
8
|
+
/**
|
|
9
|
+
* @param {YotoDeviceModel} model
|
|
10
|
+
* @returns {Promise<void>}
|
|
11
|
+
*/
|
|
12
|
+
export function waitForModelReady(model: YotoDeviceModel): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* @param {YotoDeviceModelConfig} config
|
|
15
|
+
*/
|
|
16
|
+
export function assertConfigShape(config: YotoDeviceModelConfig): void;
|
|
17
|
+
/**
|
|
18
|
+
* @param {YotoPlaybackState} playback
|
|
19
|
+
*/
|
|
20
|
+
export function assertPlaybackShape(playback: YotoPlaybackState): void;
|
|
21
|
+
/**
|
|
22
|
+
* @param {string | undefined} value
|
|
23
|
+
* @returns {string}
|
|
24
|
+
*/
|
|
25
|
+
export function toLower(value: string | undefined): string;
|
|
26
|
+
import type { YotoDeviceModel } from '../yoto-device.js';
|
|
27
|
+
import type { YotoDeviceModelConfig } from '../yoto-device.js';
|
|
28
|
+
import type { YotoPlaybackState } from '../yoto-device.js';
|
|
29
|
+
//# sourceMappingURL=device-model-test-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-model-test-helpers.d.ts","sourceRoot":"","sources":["device-model-test-helpers.js"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,qCALW,OAAO,CAAC,OAAO,CAAC,aAChB,MAAM,SACN,MAAM,GACJ,OAAO,CAAC,OAAO,CAAC,CAS5B;AAED;;;GAGG;AACH,yCAHW,eAAe,GACb,OAAO,CAAC,IAAI,CAAC,CAUzB;AAED;;GAEG;AACH,0CAFW,qBAAqB,QAkD/B;AAED;;GAEG;AACH,8CAFW,iBAAiB,QAkB3B;AAED;;;GAGG;AACH,+BAHW,MAAM,GAAG,SAAS,GAChB,MAAM,CAIlB;qCAnH8E,mBAAmB;2CAAnB,mBAAmB;uCAAnB,mBAAmB"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/** @import { YotoDeviceModel, YotoDeviceModelConfig, YotoPlaybackState } from '../yoto-device.js' */
|
|
2
|
+
|
|
3
|
+
import assert from 'node:assert/strict'
|
|
4
|
+
import { once } from 'node:events'
|
|
5
|
+
import { setTimeout as sleep } from 'node:timers/promises'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {Promise<unknown>} promise
|
|
9
|
+
* @param {number} timeoutMs
|
|
10
|
+
* @param {string} label
|
|
11
|
+
* @returns {Promise<unknown>}
|
|
12
|
+
*/
|
|
13
|
+
export function withTimeout (promise, timeoutMs, label) {
|
|
14
|
+
return Promise.race([
|
|
15
|
+
promise,
|
|
16
|
+
sleep(timeoutMs).then(() => {
|
|
17
|
+
throw new Error(`${label} timed out after ${timeoutMs}ms`)
|
|
18
|
+
})
|
|
19
|
+
])
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param {YotoDeviceModel} model
|
|
24
|
+
* @returns {Promise<void>}
|
|
25
|
+
*/
|
|
26
|
+
export async function waitForModelReady (model) {
|
|
27
|
+
const started = withTimeout(once(model, 'started'), 15000, 'started')
|
|
28
|
+
const statusUpdated = withTimeout(once(model, 'statusUpdate'), 15000, 'statusUpdate')
|
|
29
|
+
const configUpdated = withTimeout(once(model, 'configUpdate'), 15000, 'configUpdate')
|
|
30
|
+
|
|
31
|
+
await model.start()
|
|
32
|
+
await Promise.all([started, statusUpdated, configUpdated])
|
|
33
|
+
await sleep(1500)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param {YotoDeviceModelConfig} config
|
|
38
|
+
*/
|
|
39
|
+
export function assertConfigShape (config) {
|
|
40
|
+
assert.ok(Array.isArray(config.alarms), 'alarms should be an array')
|
|
41
|
+
assert.equal(typeof config.ambientColour, 'string', 'ambientColour should be string')
|
|
42
|
+
assert.equal(typeof config.bluetoothEnabled, 'boolean', 'bluetoothEnabled should be boolean')
|
|
43
|
+
assert.equal(typeof config.btHeadphonesEnabled, 'boolean', 'btHeadphonesEnabled should be boolean')
|
|
44
|
+
assert.equal(typeof config.clockFace, 'string', 'clockFace should be string')
|
|
45
|
+
assert.equal(typeof config.dayDisplayBrightnessAuto, 'boolean', 'dayDisplayBrightnessAuto should be boolean')
|
|
46
|
+
if (config.dayDisplayBrightnessAuto) {
|
|
47
|
+
assert.equal(config.dayDisplayBrightness, null, 'dayDisplayBrightness should be null when auto')
|
|
48
|
+
} else {
|
|
49
|
+
assert.equal(typeof config.dayDisplayBrightness, 'number', 'dayDisplayBrightness should be number when not auto')
|
|
50
|
+
}
|
|
51
|
+
assert.equal(typeof config.dayTime, 'string', 'dayTime should be string')
|
|
52
|
+
assert.equal(typeof config.dayYotoDaily, 'string', 'dayYotoDaily should be string')
|
|
53
|
+
assert.equal(typeof config.dayYotoRadio, 'string', 'dayYotoRadio should be string')
|
|
54
|
+
assert.equal(typeof config.daySoundsOff, 'boolean', 'daySoundsOff should be boolean')
|
|
55
|
+
assert.equal(typeof config.displayDimBrightness, 'number', 'displayDimBrightness should be number')
|
|
56
|
+
assert.equal(typeof config.displayDimTimeout, 'number', 'displayDimTimeout should be number')
|
|
57
|
+
assert.equal(typeof config.headphonesVolumeLimited, 'boolean', 'headphonesVolumeLimited should be boolean')
|
|
58
|
+
assert.ok(config.hourFormat === 12 || config.hourFormat === 24, 'hourFormat should be 12 or 24')
|
|
59
|
+
assert.equal(typeof config.locale, 'string', 'locale should be string')
|
|
60
|
+
assert.equal(typeof config.logLevel, 'string', 'logLevel should be string')
|
|
61
|
+
assert.equal(typeof config.maxVolumeLimit, 'number', 'maxVolumeLimit should be number')
|
|
62
|
+
assert.equal(typeof config.nightAmbientColour, 'string', 'nightAmbientColour should be string')
|
|
63
|
+
assert.equal(typeof config.nightDisplayBrightnessAuto, 'boolean', 'nightDisplayBrightnessAuto should be boolean')
|
|
64
|
+
if (config.nightDisplayBrightnessAuto) {
|
|
65
|
+
assert.equal(config.nightDisplayBrightness, null, 'nightDisplayBrightness should be null when auto')
|
|
66
|
+
} else {
|
|
67
|
+
assert.equal(typeof config.nightDisplayBrightness, 'number', 'nightDisplayBrightness should be number when not auto')
|
|
68
|
+
}
|
|
69
|
+
assert.equal(typeof config.nightMaxVolumeLimit, 'number', 'nightMaxVolumeLimit should be number')
|
|
70
|
+
assert.equal(typeof config.nightTime, 'string', 'nightTime should be string')
|
|
71
|
+
assert.equal(typeof config.nightYotoDaily, 'string', 'nightYotoDaily should be string')
|
|
72
|
+
assert.equal(typeof config.nightYotoRadioEnabled, 'boolean', 'nightYotoRadioEnabled should be boolean')
|
|
73
|
+
if (config.nightYotoRadioEnabled) {
|
|
74
|
+
assert.equal(typeof config.nightYotoRadio, 'string', 'nightYotoRadio should be string when enabled')
|
|
75
|
+
} else {
|
|
76
|
+
assert.equal(config.nightYotoRadio, null, 'nightYotoRadio should be null when disabled')
|
|
77
|
+
}
|
|
78
|
+
assert.equal(typeof config.nightSoundsOff, 'boolean', 'nightSoundsOff should be boolean')
|
|
79
|
+
assert.equal(typeof config.pausePowerButton, 'boolean', 'pausePowerButton should be boolean')
|
|
80
|
+
assert.equal(typeof config.pauseVolumeDown, 'boolean', 'pauseVolumeDown should be boolean')
|
|
81
|
+
assert.equal(typeof config.repeatAll, 'boolean', 'repeatAll should be boolean')
|
|
82
|
+
assert.equal(typeof config.showDiagnostics, 'boolean', 'showDiagnostics should be boolean')
|
|
83
|
+
assert.equal(typeof config.shutdownTimeout, 'number', 'shutdownTimeout should be number')
|
|
84
|
+
assert.equal(typeof config.systemVolume, 'number', 'systemVolume should be number')
|
|
85
|
+
assert.equal(typeof config.timezone, 'string', 'timezone should be string')
|
|
86
|
+
assert.equal(typeof config.volumeLevel, 'string', 'volumeLevel should be string')
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @param {YotoPlaybackState} playback
|
|
91
|
+
*/
|
|
92
|
+
export function assertPlaybackShape (playback) {
|
|
93
|
+
assert.ok(playback, 'playback should exist')
|
|
94
|
+
assert.equal(typeof playback.updatedAt, 'string', 'playback.updatedAt should be string')
|
|
95
|
+
|
|
96
|
+
assert.ok(playback.cardId === null || typeof playback.cardId === 'string', 'playback.cardId should be string or null')
|
|
97
|
+
assert.ok(playback.source === null || typeof playback.source === 'string', 'playback.source should be string or null')
|
|
98
|
+
assert.ok(playback.playbackStatus === null || typeof playback.playbackStatus === 'string', 'playback.playbackStatus should be string or null')
|
|
99
|
+
assert.ok(playback.trackTitle === null || typeof playback.trackTitle === 'string', 'playback.trackTitle should be string or null')
|
|
100
|
+
assert.ok(playback.trackKey === null || typeof playback.trackKey === 'string', 'playback.trackKey should be string or null')
|
|
101
|
+
assert.ok(playback.chapterTitle === null || typeof playback.chapterTitle === 'string', 'playback.chapterTitle should be string or null')
|
|
102
|
+
assert.ok(playback.chapterKey === null || typeof playback.chapterKey === 'string', 'playback.chapterKey should be string or null')
|
|
103
|
+
assert.ok(playback.position === null || typeof playback.position === 'number', 'playback.position should be number or null')
|
|
104
|
+
assert.ok(playback.trackLength === null || typeof playback.trackLength === 'number', 'playback.trackLength should be number or null')
|
|
105
|
+
assert.ok(playback.streaming === null || typeof playback.streaming === 'boolean', 'playback.streaming should be boolean or null')
|
|
106
|
+
assert.ok(playback.sleepTimerActive === null || typeof playback.sleepTimerActive === 'boolean', 'playback.sleepTimerActive should be boolean or null')
|
|
107
|
+
assert.ok(playback.sleepTimerSeconds === null || typeof playback.sleepTimerSeconds === 'number', 'playback.sleepTimerSeconds should be number or null')
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @param {string | undefined} value
|
|
112
|
+
* @returns {string}
|
|
113
|
+
*/
|
|
114
|
+
export function toLower (value) {
|
|
115
|
+
return typeof value === 'string' ? value.toLowerCase() : ''
|
|
116
|
+
}
|
package/lib/yoto-account.d.ts
CHANGED
|
@@ -17,14 +17,168 @@
|
|
|
17
17
|
* @property {number} deviceCount - Number of devices managed
|
|
18
18
|
* @property {string[]} devices - Array of device IDs
|
|
19
19
|
*/
|
|
20
|
+
/**
|
|
21
|
+
* Device event wrapper
|
|
22
|
+
* @template T
|
|
23
|
+
* @typedef {{ deviceId: string } & T} YotoAccountDeviceEvent
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Device added event data
|
|
27
|
+
* @typedef {YotoAccountDeviceEvent<{}>} YotoAccountDeviceAddedEvent
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Device removed event data
|
|
31
|
+
* @typedef {YotoAccountDeviceEvent<{}>} YotoAccountDeviceRemovedEvent
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Device status update event data
|
|
35
|
+
* @typedef {YotoAccountDeviceEvent<{
|
|
36
|
+
* status: YotoDeviceStatus,
|
|
37
|
+
* source: string,
|
|
38
|
+
* changedFields: Set<keyof YotoDeviceStatus>
|
|
39
|
+
* }>} YotoAccountStatusUpdateEvent
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* Device config update event data
|
|
43
|
+
* @typedef {YotoAccountDeviceEvent<{
|
|
44
|
+
* config: YotoDeviceModelConfig,
|
|
45
|
+
* changedFields: Set<keyof YotoDeviceModelConfig>
|
|
46
|
+
* }>} YotoAccountConfigUpdateEvent
|
|
47
|
+
*/
|
|
48
|
+
/**
|
|
49
|
+
* Device playback update event data
|
|
50
|
+
* @typedef {YotoAccountDeviceEvent<{
|
|
51
|
+
* playback: YotoPlaybackState,
|
|
52
|
+
* changedFields: Set<keyof YotoPlaybackState>
|
|
53
|
+
* }>} YotoAccountPlaybackUpdateEvent
|
|
54
|
+
*/
|
|
55
|
+
/**
|
|
56
|
+
* Device online event data
|
|
57
|
+
* @typedef {YotoAccountDeviceEvent<{
|
|
58
|
+
* metadata: YotoDeviceOnlineMetadata
|
|
59
|
+
* }>} YotoAccountOnlineEvent
|
|
60
|
+
*/
|
|
61
|
+
/**
|
|
62
|
+
* Device offline event data
|
|
63
|
+
* @typedef {YotoAccountDeviceEvent<{
|
|
64
|
+
* metadata: YotoDeviceOfflineMetadata
|
|
65
|
+
* }>} YotoAccountOfflineEvent
|
|
66
|
+
*/
|
|
67
|
+
/**
|
|
68
|
+
* MQTT connect event data
|
|
69
|
+
* @typedef {YotoAccountDeviceEvent<{
|
|
70
|
+
* metadata: YotoMqttConnectMetadata
|
|
71
|
+
* }>} YotoAccountMqttConnectEvent
|
|
72
|
+
*/
|
|
73
|
+
/**
|
|
74
|
+
* MQTT disconnect event data
|
|
75
|
+
* @typedef {YotoAccountDeviceEvent<{
|
|
76
|
+
* metadata: YotoMqttDisconnectMetadata
|
|
77
|
+
* }>} YotoAccountMqttDisconnectEvent
|
|
78
|
+
*/
|
|
79
|
+
/**
|
|
80
|
+
* MQTT close event data
|
|
81
|
+
* @typedef {YotoAccountDeviceEvent<{
|
|
82
|
+
* metadata: YotoMqttCloseMetadata
|
|
83
|
+
* }>} YotoAccountMqttCloseEvent
|
|
84
|
+
*/
|
|
85
|
+
/**
|
|
86
|
+
* MQTT reconnect event data
|
|
87
|
+
* @typedef {YotoAccountDeviceEvent<{}>} YotoAccountMqttReconnectEvent
|
|
88
|
+
*/
|
|
89
|
+
/**
|
|
90
|
+
* MQTT offline event data
|
|
91
|
+
* @typedef {YotoAccountDeviceEvent<{}>} YotoAccountMqttOfflineEvent
|
|
92
|
+
*/
|
|
93
|
+
/**
|
|
94
|
+
* MQTT end event data
|
|
95
|
+
* @typedef {YotoAccountDeviceEvent<{}>} YotoAccountMqttEndEvent
|
|
96
|
+
*/
|
|
97
|
+
/**
|
|
98
|
+
* MQTT status event data
|
|
99
|
+
* @typedef {YotoAccountDeviceEvent<{
|
|
100
|
+
* topic: string,
|
|
101
|
+
* message: YotoStatusMessage
|
|
102
|
+
* }>} YotoAccountMqttStatusEvent
|
|
103
|
+
*/
|
|
104
|
+
/**
|
|
105
|
+
* MQTT events event data
|
|
106
|
+
* @typedef {YotoAccountDeviceEvent<{
|
|
107
|
+
* topic: string,
|
|
108
|
+
* message: YotoEventsMessage
|
|
109
|
+
* }>} YotoAccountMqttEventsEvent
|
|
110
|
+
*/
|
|
111
|
+
/**
|
|
112
|
+
* MQTT legacy status event data
|
|
113
|
+
* @typedef {YotoAccountDeviceEvent<{
|
|
114
|
+
* topic: string,
|
|
115
|
+
* message: YotoStatusLegacyMessage
|
|
116
|
+
* }>} YotoAccountMqttStatusLegacyEvent
|
|
117
|
+
*/
|
|
118
|
+
/**
|
|
119
|
+
* MQTT response event data
|
|
120
|
+
* @typedef {YotoAccountDeviceEvent<{
|
|
121
|
+
* topic: string,
|
|
122
|
+
* message: YotoResponseMessage
|
|
123
|
+
* }>} YotoAccountMqttResponseEvent
|
|
124
|
+
*/
|
|
125
|
+
/**
|
|
126
|
+
* MQTT unknown event data
|
|
127
|
+
* @typedef {YotoAccountDeviceEvent<{
|
|
128
|
+
* topic: string,
|
|
129
|
+
* message: unknown
|
|
130
|
+
* }>} YotoAccountMqttUnknownEvent
|
|
131
|
+
*/
|
|
132
|
+
/**
|
|
133
|
+
* Account error event data
|
|
134
|
+
* @typedef {Object} YotoAccountErrorEvent
|
|
135
|
+
* @property {Error} error - Error instance
|
|
136
|
+
* @property {YotoAccountErrorContext} context - Error context
|
|
137
|
+
*/
|
|
138
|
+
/**
|
|
139
|
+
* Device event handler set
|
|
140
|
+
* @typedef {Object} YotoAccountDeviceEventHandlers
|
|
141
|
+
* @property {(status: YotoDeviceStatus, source: string, changedFields: Set<keyof YotoDeviceStatus>) => void} statusUpdate
|
|
142
|
+
* @property {(config: YotoDeviceModelConfig, changedFields: Set<keyof YotoDeviceModelConfig>) => void} configUpdate
|
|
143
|
+
* @property {(playback: YotoPlaybackState, changedFields: Set<keyof YotoPlaybackState>) => void} playbackUpdate
|
|
144
|
+
* @property {(metadata: YotoDeviceOnlineMetadata) => void} online
|
|
145
|
+
* @property {(metadata: YotoDeviceOfflineMetadata) => void} offline
|
|
146
|
+
* @property {(metadata: YotoMqttConnectMetadata) => void} mqttConnect
|
|
147
|
+
* @property {(metadata: YotoMqttDisconnectMetadata) => void} mqttDisconnect
|
|
148
|
+
* @property {(metadata: YotoMqttCloseMetadata) => void} mqttClose
|
|
149
|
+
* @property {() => void} mqttReconnect
|
|
150
|
+
* @property {() => void} mqttOffline
|
|
151
|
+
* @property {() => void} mqttEnd
|
|
152
|
+
* @property {(topic: string, message: YotoStatusMessage) => void} mqttStatus
|
|
153
|
+
* @property {(topic: string, message: YotoEventsMessage) => void} mqttEvents
|
|
154
|
+
* @property {(topic: string, message: YotoStatusLegacyMessage) => void} mqttStatusLegacy
|
|
155
|
+
* @property {(topic: string, message: YotoResponseMessage) => void} mqttResponse
|
|
156
|
+
* @property {(topic: string, message: unknown) => void} mqttUnknown
|
|
157
|
+
*/
|
|
20
158
|
/**
|
|
21
159
|
* Event map for YotoAccount
|
|
22
160
|
* @typedef {{
|
|
23
161
|
* 'started': [YotoAccountStartedMetadata],
|
|
24
162
|
* 'stopped': [],
|
|
25
|
-
* 'deviceAdded': [
|
|
26
|
-
* 'deviceRemoved': [
|
|
27
|
-
* '
|
|
163
|
+
* 'deviceAdded': [YotoAccountDeviceAddedEvent],
|
|
164
|
+
* 'deviceRemoved': [YotoAccountDeviceRemovedEvent],
|
|
165
|
+
* 'statusUpdate': [YotoAccountStatusUpdateEvent],
|
|
166
|
+
* 'configUpdate': [YotoAccountConfigUpdateEvent],
|
|
167
|
+
* 'playbackUpdate': [YotoAccountPlaybackUpdateEvent],
|
|
168
|
+
* 'online': [YotoAccountOnlineEvent],
|
|
169
|
+
* 'offline': [YotoAccountOfflineEvent],
|
|
170
|
+
* 'mqttConnect': [YotoAccountMqttConnectEvent],
|
|
171
|
+
* 'mqttDisconnect': [YotoAccountMqttDisconnectEvent],
|
|
172
|
+
* 'mqttClose': [YotoAccountMqttCloseEvent],
|
|
173
|
+
* 'mqttReconnect': [YotoAccountMqttReconnectEvent],
|
|
174
|
+
* 'mqttOffline': [YotoAccountMqttOfflineEvent],
|
|
175
|
+
* 'mqttEnd': [YotoAccountMqttEndEvent],
|
|
176
|
+
* 'mqttStatus': [YotoAccountMqttStatusEvent],
|
|
177
|
+
* 'mqttEvents': [YotoAccountMqttEventsEvent],
|
|
178
|
+
* 'mqttStatusLegacy': [YotoAccountMqttStatusLegacyEvent],
|
|
179
|
+
* 'mqttResponse': [YotoAccountMqttResponseEvent],
|
|
180
|
+
* 'mqttUnknown': [YotoAccountMqttUnknownEvent],
|
|
181
|
+
* 'error': [YotoAccountErrorEvent]
|
|
28
182
|
* }} YotoAccountEventMap
|
|
29
183
|
*/
|
|
30
184
|
/**
|
|
@@ -33,9 +187,10 @@
|
|
|
33
187
|
* Events:
|
|
34
188
|
* - 'started' - Emitted when account starts, passes metadata with deviceCount and devices array
|
|
35
189
|
* - 'stopped' - Emitted when account stops
|
|
36
|
-
* - 'deviceAdded' - Emitted when a device is added, passes
|
|
37
|
-
* - 'deviceRemoved' - Emitted when a device is removed, passes deviceId
|
|
38
|
-
* -
|
|
190
|
+
* - 'deviceAdded' - Emitted when a device is added, passes { deviceId }
|
|
191
|
+
* - 'deviceRemoved' - Emitted when a device is removed, passes { deviceId }
|
|
192
|
+
* - Device events are re-emitted with device context, see event map for signatures
|
|
193
|
+
* - 'error' - Emitted when an error occurs, passes { error, context }
|
|
39
194
|
*
|
|
40
195
|
* Note: To listen to individual device events (statusUpdate, configUpdate, playbackUpdate, online, offline, etc.),
|
|
41
196
|
* access the device models directly via account.devices or account.getDevice(deviceId) and attach listeners.
|
|
@@ -145,19 +300,194 @@ export type YotoAccountStartedMetadata = {
|
|
|
145
300
|
*/
|
|
146
301
|
devices: string[];
|
|
147
302
|
};
|
|
303
|
+
/**
|
|
304
|
+
* Device event wrapper
|
|
305
|
+
*/
|
|
306
|
+
export type YotoAccountDeviceEvent<T> = {
|
|
307
|
+
deviceId: string;
|
|
308
|
+
} & T;
|
|
309
|
+
/**
|
|
310
|
+
* Device added event data
|
|
311
|
+
*/
|
|
312
|
+
export type YotoAccountDeviceAddedEvent = YotoAccountDeviceEvent<{}>;
|
|
313
|
+
/**
|
|
314
|
+
* Device removed event data
|
|
315
|
+
*/
|
|
316
|
+
export type YotoAccountDeviceRemovedEvent = YotoAccountDeviceEvent<{}>;
|
|
317
|
+
/**
|
|
318
|
+
* Device status update event data
|
|
319
|
+
*/
|
|
320
|
+
export type YotoAccountStatusUpdateEvent = YotoAccountDeviceEvent<{
|
|
321
|
+
status: YotoDeviceStatus;
|
|
322
|
+
source: string;
|
|
323
|
+
changedFields: Set<keyof YotoDeviceStatus>;
|
|
324
|
+
}>;
|
|
325
|
+
/**
|
|
326
|
+
* Device config update event data
|
|
327
|
+
*/
|
|
328
|
+
export type YotoAccountConfigUpdateEvent = YotoAccountDeviceEvent<{
|
|
329
|
+
config: YotoDeviceModelConfig;
|
|
330
|
+
changedFields: Set<keyof YotoDeviceModelConfig>;
|
|
331
|
+
}>;
|
|
332
|
+
/**
|
|
333
|
+
* Device playback update event data
|
|
334
|
+
*/
|
|
335
|
+
export type YotoAccountPlaybackUpdateEvent = YotoAccountDeviceEvent<{
|
|
336
|
+
playback: YotoPlaybackState;
|
|
337
|
+
changedFields: Set<keyof YotoPlaybackState>;
|
|
338
|
+
}>;
|
|
339
|
+
/**
|
|
340
|
+
* Device online event data
|
|
341
|
+
*/
|
|
342
|
+
export type YotoAccountOnlineEvent = YotoAccountDeviceEvent<{
|
|
343
|
+
metadata: YotoDeviceOnlineMetadata;
|
|
344
|
+
}>;
|
|
345
|
+
/**
|
|
346
|
+
* Device offline event data
|
|
347
|
+
*/
|
|
348
|
+
export type YotoAccountOfflineEvent = YotoAccountDeviceEvent<{
|
|
349
|
+
metadata: YotoDeviceOfflineMetadata;
|
|
350
|
+
}>;
|
|
351
|
+
/**
|
|
352
|
+
* MQTT connect event data
|
|
353
|
+
*/
|
|
354
|
+
export type YotoAccountMqttConnectEvent = YotoAccountDeviceEvent<{
|
|
355
|
+
metadata: YotoMqttConnectMetadata;
|
|
356
|
+
}>;
|
|
357
|
+
/**
|
|
358
|
+
* MQTT disconnect event data
|
|
359
|
+
*/
|
|
360
|
+
export type YotoAccountMqttDisconnectEvent = YotoAccountDeviceEvent<{
|
|
361
|
+
metadata: YotoMqttDisconnectMetadata;
|
|
362
|
+
}>;
|
|
363
|
+
/**
|
|
364
|
+
* MQTT close event data
|
|
365
|
+
*/
|
|
366
|
+
export type YotoAccountMqttCloseEvent = YotoAccountDeviceEvent<{
|
|
367
|
+
metadata: YotoMqttCloseMetadata;
|
|
368
|
+
}>;
|
|
369
|
+
/**
|
|
370
|
+
* MQTT reconnect event data
|
|
371
|
+
*/
|
|
372
|
+
export type YotoAccountMqttReconnectEvent = YotoAccountDeviceEvent<{}>;
|
|
373
|
+
/**
|
|
374
|
+
* MQTT offline event data
|
|
375
|
+
*/
|
|
376
|
+
export type YotoAccountMqttOfflineEvent = YotoAccountDeviceEvent<{}>;
|
|
377
|
+
/**
|
|
378
|
+
* MQTT end event data
|
|
379
|
+
*/
|
|
380
|
+
export type YotoAccountMqttEndEvent = YotoAccountDeviceEvent<{}>;
|
|
381
|
+
/**
|
|
382
|
+
* MQTT status event data
|
|
383
|
+
*/
|
|
384
|
+
export type YotoAccountMqttStatusEvent = YotoAccountDeviceEvent<{
|
|
385
|
+
topic: string;
|
|
386
|
+
message: YotoStatusMessage;
|
|
387
|
+
}>;
|
|
388
|
+
/**
|
|
389
|
+
* MQTT events event data
|
|
390
|
+
*/
|
|
391
|
+
export type YotoAccountMqttEventsEvent = YotoAccountDeviceEvent<{
|
|
392
|
+
topic: string;
|
|
393
|
+
message: YotoEventsMessage;
|
|
394
|
+
}>;
|
|
395
|
+
/**
|
|
396
|
+
* MQTT legacy status event data
|
|
397
|
+
*/
|
|
398
|
+
export type YotoAccountMqttStatusLegacyEvent = YotoAccountDeviceEvent<{
|
|
399
|
+
topic: string;
|
|
400
|
+
message: YotoStatusLegacyMessage;
|
|
401
|
+
}>;
|
|
402
|
+
/**
|
|
403
|
+
* MQTT response event data
|
|
404
|
+
*/
|
|
405
|
+
export type YotoAccountMqttResponseEvent = YotoAccountDeviceEvent<{
|
|
406
|
+
topic: string;
|
|
407
|
+
message: YotoResponseMessage;
|
|
408
|
+
}>;
|
|
409
|
+
/**
|
|
410
|
+
* MQTT unknown event data
|
|
411
|
+
*/
|
|
412
|
+
export type YotoAccountMqttUnknownEvent = YotoAccountDeviceEvent<{
|
|
413
|
+
topic: string;
|
|
414
|
+
message: unknown;
|
|
415
|
+
}>;
|
|
416
|
+
/**
|
|
417
|
+
* Account error event data
|
|
418
|
+
*/
|
|
419
|
+
export type YotoAccountErrorEvent = {
|
|
420
|
+
/**
|
|
421
|
+
* - Error instance
|
|
422
|
+
*/
|
|
423
|
+
error: Error;
|
|
424
|
+
/**
|
|
425
|
+
* - Error context
|
|
426
|
+
*/
|
|
427
|
+
context: YotoAccountErrorContext;
|
|
428
|
+
};
|
|
429
|
+
/**
|
|
430
|
+
* Device event handler set
|
|
431
|
+
*/
|
|
432
|
+
export type YotoAccountDeviceEventHandlers = {
|
|
433
|
+
statusUpdate: (status: YotoDeviceStatus, source: string, changedFields: Set<keyof YotoDeviceStatus>) => void;
|
|
434
|
+
configUpdate: (config: YotoDeviceModelConfig, changedFields: Set<keyof YotoDeviceModelConfig>) => void;
|
|
435
|
+
playbackUpdate: (playback: YotoPlaybackState, changedFields: Set<keyof YotoPlaybackState>) => void;
|
|
436
|
+
online: (metadata: YotoDeviceOnlineMetadata) => void;
|
|
437
|
+
offline: (metadata: YotoDeviceOfflineMetadata) => void;
|
|
438
|
+
mqttConnect: (metadata: YotoMqttConnectMetadata) => void;
|
|
439
|
+
mqttDisconnect: (metadata: YotoMqttDisconnectMetadata) => void;
|
|
440
|
+
mqttClose: (metadata: YotoMqttCloseMetadata) => void;
|
|
441
|
+
mqttReconnect: () => void;
|
|
442
|
+
mqttOffline: () => void;
|
|
443
|
+
mqttEnd: () => void;
|
|
444
|
+
mqttStatus: (topic: string, message: YotoStatusMessage) => void;
|
|
445
|
+
mqttEvents: (topic: string, message: YotoEventsMessage) => void;
|
|
446
|
+
mqttStatusLegacy: (topic: string, message: YotoStatusLegacyMessage) => void;
|
|
447
|
+
mqttResponse: (topic: string, message: YotoResponseMessage) => void;
|
|
448
|
+
mqttUnknown: (topic: string, message: unknown) => void;
|
|
449
|
+
};
|
|
148
450
|
/**
|
|
149
451
|
* Event map for YotoAccount
|
|
150
452
|
*/
|
|
151
453
|
export type YotoAccountEventMap = {
|
|
152
454
|
"started": [YotoAccountStartedMetadata];
|
|
153
455
|
"stopped": [];
|
|
154
|
-
"deviceAdded": [
|
|
155
|
-
"deviceRemoved": [
|
|
156
|
-
"
|
|
456
|
+
"deviceAdded": [YotoAccountDeviceAddedEvent];
|
|
457
|
+
"deviceRemoved": [YotoAccountDeviceRemovedEvent];
|
|
458
|
+
"statusUpdate": [YotoAccountStatusUpdateEvent];
|
|
459
|
+
"configUpdate": [YotoAccountConfigUpdateEvent];
|
|
460
|
+
"playbackUpdate": [YotoAccountPlaybackUpdateEvent];
|
|
461
|
+
"online": [YotoAccountOnlineEvent];
|
|
462
|
+
"offline": [YotoAccountOfflineEvent];
|
|
463
|
+
"mqttConnect": [YotoAccountMqttConnectEvent];
|
|
464
|
+
"mqttDisconnect": [YotoAccountMqttDisconnectEvent];
|
|
465
|
+
"mqttClose": [YotoAccountMqttCloseEvent];
|
|
466
|
+
"mqttReconnect": [YotoAccountMqttReconnectEvent];
|
|
467
|
+
"mqttOffline": [YotoAccountMqttOfflineEvent];
|
|
468
|
+
"mqttEnd": [YotoAccountMqttEndEvent];
|
|
469
|
+
"mqttStatus": [YotoAccountMqttStatusEvent];
|
|
470
|
+
"mqttEvents": [YotoAccountMqttEventsEvent];
|
|
471
|
+
"mqttStatusLegacy": [YotoAccountMqttStatusLegacyEvent];
|
|
472
|
+
"mqttResponse": [YotoAccountMqttResponseEvent];
|
|
473
|
+
"mqttUnknown": [YotoAccountMqttUnknownEvent];
|
|
474
|
+
"error": [YotoAccountErrorEvent];
|
|
157
475
|
};
|
|
158
476
|
import { EventEmitter } from 'events';
|
|
159
477
|
import { YotoClient } from './api-client.js';
|
|
160
478
|
import { YotoDeviceModel } from './yoto-device.js';
|
|
161
479
|
import type { YotoClientConstructorOptions } from './api-client.js';
|
|
162
480
|
import type { YotoDeviceModelOptions } from './yoto-device.js';
|
|
481
|
+
import type { YotoDeviceStatus } from './yoto-device.js';
|
|
482
|
+
import type { YotoDeviceModelConfig } from './yoto-device.js';
|
|
483
|
+
import type { YotoPlaybackState } from './yoto-device.js';
|
|
484
|
+
import type { YotoDeviceOnlineMetadata } from './yoto-device.js';
|
|
485
|
+
import type { YotoDeviceOfflineMetadata } from './yoto-device.js';
|
|
486
|
+
import type { YotoMqttConnectMetadata } from './yoto-device.js';
|
|
487
|
+
import type { YotoMqttDisconnectMetadata } from './yoto-device.js';
|
|
488
|
+
import type { YotoMqttCloseMetadata } from './yoto-device.js';
|
|
489
|
+
import type { YotoStatusMessage } from './mqtt/client.js';
|
|
490
|
+
import type { YotoEventsMessage } from './mqtt/client.js';
|
|
491
|
+
import type { YotoStatusLegacyMessage } from './mqtt/client.js';
|
|
492
|
+
import type { YotoResponseMessage } from './mqtt/client.js';
|
|
163
493
|
//# sourceMappingURL=yoto-account.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yoto-account.d.ts","sourceRoot":"","sources":["yoto-account.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"yoto-account.d.ts","sourceRoot":"","sources":["yoto-account.js"],"names":[],"mappings":"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"}
|