homebridge-yoto 0.0.27 → 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 +42 -157
- package/CHANGELOG.md +13 -5
- package/NOTES.md +87 -0
- package/PLAN.md +320 -504
- package/README.md +18 -314
- package/config.schema.cjs +3 -0
- package/config.schema.json +19 -155
- package/homebridge-ui/server.js +264 -0
- package/index.js +1 -1
- package/index.test.js +1 -1
- package/lib/accessory.js +1870 -0
- package/lib/constants.js +8 -149
- package/lib/platform.js +303 -364
- package/lib/sanitize-name.js +49 -0
- package/lib/settings.js +16 -0
- package/lib/sync-service-names.js +34 -0
- package/logo.png +0 -0
- package/package.json +17 -22
- package/pnpm-workspace.yaml +4 -0
- package/declaration.tsconfig.json +0 -15
- package/lib/auth.js +0 -237
- package/lib/playerAccessory.js +0 -1724
- package/lib/types.js +0 -253
- package/lib/yotoApi.js +0 -270
- package/lib/yotoMqtt.js +0 -570
package/lib/constants.js
CHANGED
|
@@ -1,158 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview Constants
|
|
2
|
+
* @fileoverview Constants for Yoto Homebridge plugin
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
*/
|
|
8
|
-
export const PLATFORM_NAME = 'Yoto'
|
|
9
|
-
export const PLUGIN_NAME = 'homebridge-yoto'
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Yoto API endpoints
|
|
13
|
-
*/
|
|
14
|
-
export const YOTO_API_BASE_URL = 'https://api.yotoplay.com'
|
|
15
|
-
export const YOTO_OAUTH_BASE_URL = 'https://login.yotoplay.com'
|
|
16
|
-
export const YOTO_OAUTH_AUTHORIZE_URL = `${YOTO_OAUTH_BASE_URL}/authorize`
|
|
17
|
-
export const YOTO_OAUTH_TOKEN_URL = `${YOTO_OAUTH_BASE_URL}/oauth/token`
|
|
18
|
-
export const YOTO_OAUTH_DEVICE_CODE_URL = `${YOTO_OAUTH_BASE_URL}/oauth/device/code`
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* MQTT configuration
|
|
22
|
-
*/
|
|
23
|
-
export const YOTO_MQTT_BROKER_URL = 'wss://aqrphjqbp3u2z-ats.iot.eu-west-2.amazonaws.com'
|
|
24
|
-
export const YOTO_MQTT_AUTH_NAME = 'PublicJWTAuthorizer'
|
|
25
|
-
export const MQTT_RECONNECT_PERIOD = 5000 // milliseconds
|
|
26
|
-
export const MQTT_CONNECT_TIMEOUT = 30000 // milliseconds
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* MQTT topic templates
|
|
30
|
-
*/
|
|
31
|
-
export const MQTT_TOPIC_DATA_STATUS = 'device/{deviceId}/status'
|
|
32
|
-
export const MQTT_TOPIC_DATA_EVENTS = 'device/{deviceId}/events'
|
|
33
|
-
export const MQTT_TOPIC_RESPONSE = 'device/{deviceId}/response'
|
|
34
|
-
export const MQTT_TOPIC_COMMAND_STATUS_REQUEST = 'device/{deviceId}/command/status/request'
|
|
35
|
-
export const MQTT_TOPIC_COMMAND_EVENTS_REQUEST = 'device/{deviceId}/command/events/request'
|
|
36
|
-
export const MQTT_TOPIC_COMMAND_VOLUME_SET = 'device/{deviceId}/command/volume/set'
|
|
37
|
-
export const MQTT_TOPIC_COMMAND_CARD_START = 'device/{deviceId}/command/card/start'
|
|
38
|
-
export const MQTT_TOPIC_COMMAND_CARD_STOP = 'device/{deviceId}/command/card/stop'
|
|
39
|
-
export const MQTT_TOPIC_COMMAND_CARD_PAUSE = 'device/{deviceId}/command/card/pause'
|
|
40
|
-
export const MQTT_TOPIC_COMMAND_CARD_RESUME = 'device/{deviceId}/command/card/resume'
|
|
41
|
-
export const MQTT_TOPIC_COMMAND_SLEEP_TIMER = 'device/{deviceId}/command/sleep-timer/set'
|
|
42
|
-
export const MQTT_TOPIC_COMMAND_AMBIENTS_SET = 'device/{deviceId}/command/ambients/set'
|
|
43
|
-
export const MQTT_TOPIC_COMMAND_REBOOT = 'device/{deviceId}/command/reboot'
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* OAuth configuration
|
|
47
|
-
*/
|
|
48
|
-
export const OAUTH_CLIENT_ID = 'Y4HJ8BFqRQ24GQoLzgOzZ2KSqWmFG8LI'
|
|
49
|
-
export const OAUTH_AUDIENCE = 'https://api.yotoplay.com'
|
|
50
|
-
export const OAUTH_SCOPE = 'openid profile offline_access'
|
|
51
|
-
export const OAUTH_POLLING_INTERVAL = 5000 // milliseconds
|
|
52
|
-
export const OAUTH_DEVICE_CODE_TIMEOUT = 300000 // 5 minutes
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Device polling and timeouts
|
|
56
|
-
*/
|
|
57
|
-
export const DEFAULT_STATUS_TIMEOUT_SECONDS = 120 // Mark device offline after no updates
|
|
58
|
-
export const TOKEN_REFRESH_BUFFER_SECONDS = 300 // Refresh token 5 minutes before expiry
|
|
59
|
-
export const INITIAL_STATUS_REQUEST_DELAY = 2000 // milliseconds after MQTT connect
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* HomeKit service configuration
|
|
63
|
-
*/
|
|
64
|
-
export const DEFAULT_MANUFACTURER = 'Yoto'
|
|
5
|
+
// Device defaults
|
|
6
|
+
export const DEFAULT_MANUFACTURER = 'Yoto Inc.'
|
|
65
7
|
export const DEFAULT_MODEL = 'Yoto Player'
|
|
66
|
-
export const LOW_BATTERY_THRESHOLD = 20 // percentage
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Volume configuration
|
|
70
|
-
*/
|
|
71
|
-
export const MIN_VOLUME = 0
|
|
72
|
-
export const MAX_VOLUME = 100
|
|
73
|
-
export const YOTO_MAX_VOLUME_LIMIT = 16 // Yoto's internal max volume scale
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Playback status mapping
|
|
77
|
-
*/
|
|
78
|
-
export const PLAYBACK_STATUS = {
|
|
79
|
-
PLAYING: 'playing',
|
|
80
|
-
PAUSED: 'paused',
|
|
81
|
-
STOPPED: 'stopped'
|
|
82
|
-
}
|
|
83
8
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
*/
|
|
87
|
-
export const CARD_INSERTION_STATE = {
|
|
88
|
-
NONE: 0,
|
|
89
|
-
PHYSICAL: 1,
|
|
90
|
-
REMOTE: 2
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Day mode states
|
|
95
|
-
*/
|
|
96
|
-
export const DAY_MODE = {
|
|
97
|
-
UNKNOWN: -1,
|
|
98
|
-
NIGHT: 0,
|
|
99
|
-
DAY: 1
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Power source states
|
|
104
|
-
*/
|
|
105
|
-
export const POWER_SOURCE = {
|
|
106
|
-
BATTERY: 0,
|
|
107
|
-
V2_DOCK: 1,
|
|
108
|
-
USB_C: 2,
|
|
109
|
-
QI_DOCK: 3
|
|
110
|
-
}
|
|
9
|
+
// Battery threshold
|
|
10
|
+
export const LOW_BATTERY_THRESHOLD = 20
|
|
111
11
|
|
|
112
|
-
|
|
113
|
-
* Default configuration values
|
|
114
|
-
*/
|
|
115
|
-
export const DEFAULT_CONFIG = {
|
|
116
|
-
platform: PLATFORM_NAME,
|
|
117
|
-
name: PLATFORM_NAME,
|
|
118
|
-
clientId: OAUTH_CLIENT_ID,
|
|
119
|
-
statusTimeoutSeconds: DEFAULT_STATUS_TIMEOUT_SECONDS,
|
|
120
|
-
exposeTemperature: true,
|
|
121
|
-
exposeBattery: true,
|
|
122
|
-
exposeAdvancedControls: false,
|
|
123
|
-
exposeConnectionStatus: true,
|
|
124
|
-
exposeCardDetection: false,
|
|
125
|
-
exposeDisplayBrightness: true,
|
|
126
|
-
exposeSleepTimer: false,
|
|
127
|
-
exposeVolumeLimits: false,
|
|
128
|
-
exposeAmbientLight: false,
|
|
129
|
-
exposeActiveContent: true,
|
|
130
|
-
updateAccessoryName: false,
|
|
131
|
-
volumeControlType: 'speaker',
|
|
132
|
-
debug: false
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Error messages
|
|
137
|
-
*/
|
|
138
|
-
export const ERROR_MESSAGES = {
|
|
139
|
-
NO_AUTH: 'No authentication credentials found. Please complete OAuth setup.',
|
|
140
|
-
TOKEN_EXPIRED: 'Access token expired. Attempting to refresh...',
|
|
141
|
-
TOKEN_REFRESH_FAILED: 'Failed to refresh access token. Please re-authenticate.',
|
|
142
|
-
MQTT_CONNECTION_FAILED: 'Failed to connect to MQTT broker.',
|
|
143
|
-
MQTT_DISCONNECTED: 'MQTT connection lost. Attempting to reconnect...',
|
|
144
|
-
DEVICE_OFFLINE: 'Device appears to be offline.',
|
|
145
|
-
API_ERROR: 'API request failed',
|
|
146
|
-
INVALID_CONFIG: 'Invalid configuration'
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Log prefixes
|
|
151
|
-
*/
|
|
12
|
+
// Logging prefixes for debugging
|
|
152
13
|
export const LOG_PREFIX = {
|
|
153
|
-
AUTH: '[Auth]',
|
|
154
|
-
API: '[API]',
|
|
155
|
-
MQTT: '[MQTT]',
|
|
156
14
|
PLATFORM: '[Platform]',
|
|
157
|
-
ACCESSORY: '[Accessory]'
|
|
15
|
+
ACCESSORY: '[Accessory]',
|
|
16
|
+
MQTT: '[MQTT]',
|
|
158
17
|
}
|