homebridge-moonside 0.1.0
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/LICENSE +176 -0
- package/README.md +77 -0
- package/config.schema.json +65 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +12 -0
- package/dist/logger.js +30 -0
- package/dist/logger.js.map +1 -0
- package/dist/moonsideApi.d.ts +50 -0
- package/dist/moonsideApi.js +343 -0
- package/dist/moonsideApi.js.map +1 -0
- package/dist/platform.d.ts +60 -0
- package/dist/platform.js +278 -0
- package/dist/platform.js.map +1 -0
- package/dist/platformAccessory.d.ts +46 -0
- package/dist/platformAccessory.js +369 -0
- package/dist/platformAccessory.js.map +1 -0
- package/dist/settings.d.ts +8 -0
- package/dist/settings.js +9 -0
- package/dist/settings.js.map +1 -0
- package/dist/themeSwitchAccessory.d.ts +18 -0
- package/dist/themeSwitchAccessory.js +114 -0
- package/dist/themeSwitchAccessory.js.map +1 -0
- package/eslint +0 -0
- package/homebridge-moonside-cloud@0.1.0 +0 -0
- package/npm +0 -0
- package/package.json +46 -0
- package/scripts/moonside-control.ts +251 -0
package/dist/platform.js
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { MoonsideLampAccessory } from './platformAccessory.js';
|
|
2
|
+
import { ThemeSwitchAccessory } from './themeSwitchAccessory.js';
|
|
3
|
+
import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js';
|
|
4
|
+
import { MoonsideApiClient } from './moonsideApi.js';
|
|
5
|
+
import { PluginLogger } from './logger.js';
|
|
6
|
+
/**
|
|
7
|
+
* HomebridgePlatform
|
|
8
|
+
* This class is the main constructor for your plugin, this is where you should
|
|
9
|
+
* parse the user config and discover/register accessories with Homebridge.
|
|
10
|
+
*/
|
|
11
|
+
export class MoonsideCloudPlatform {
|
|
12
|
+
log;
|
|
13
|
+
config;
|
|
14
|
+
api;
|
|
15
|
+
Service;
|
|
16
|
+
Characteristic;
|
|
17
|
+
// this is used to track restored cached accessories
|
|
18
|
+
accessories = new Map();
|
|
19
|
+
apiClient;
|
|
20
|
+
pollingInterval;
|
|
21
|
+
enablePolling;
|
|
22
|
+
logger;
|
|
23
|
+
configured;
|
|
24
|
+
accessoriesByDeviceId = new Map();
|
|
25
|
+
themeAccessories = new Map();
|
|
26
|
+
themeSwitchNames;
|
|
27
|
+
streamUnsubscribe;
|
|
28
|
+
themeDefinitionsCache;
|
|
29
|
+
constructor(log, config, api) {
|
|
30
|
+
this.log = log;
|
|
31
|
+
this.config = config;
|
|
32
|
+
this.api = api;
|
|
33
|
+
this.Service = api.hap.Service;
|
|
34
|
+
this.Characteristic = api.hap.Characteristic;
|
|
35
|
+
this.logger = new PluginLogger(log, this.resolveLogLevel(config.logLevel));
|
|
36
|
+
this.pollingInterval = Math.max(5, config.pollingInterval ?? 60) * 1000;
|
|
37
|
+
this.enablePolling = config.enablePolling ?? false;
|
|
38
|
+
this.themeSwitchNames = (config.themeSwitches ?? []).map(name => name.trim()).filter(name => !!name);
|
|
39
|
+
this.configured = Boolean(config.email && config.password);
|
|
40
|
+
if (!this.configured) {
|
|
41
|
+
this.logger.warn('Moonside Cloud plugin is not configured. Please provide your Moonside email and password.');
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
this.apiClient = new MoonsideApiClient(this.logger, config.email, config.password, config.firebaseApiKey);
|
|
45
|
+
}
|
|
46
|
+
this.logger.debug('Finished initializing platform: %s', this.config.name ?? PLATFORM_NAME);
|
|
47
|
+
// When this event is fired it means Homebridge has restored all cached accessories from disk.
|
|
48
|
+
// Dynamic Platform plugins should only register new accessories after this event was fired,
|
|
49
|
+
// in order to ensure they weren't added to homebridge already. This event can also be used
|
|
50
|
+
// to start discovery of new accessories.
|
|
51
|
+
this.api.on('didFinishLaunching', () => {
|
|
52
|
+
this.logger.debug('Executed didFinishLaunching callback');
|
|
53
|
+
void this.discoverDevices();
|
|
54
|
+
});
|
|
55
|
+
this.api.on('shutdown', () => {
|
|
56
|
+
this.streamUnsubscribe?.();
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* This function is invoked when homebridge restores cached accessories from disk at startup.
|
|
61
|
+
* It should be used to set up event handlers for characteristics and update respective values.
|
|
62
|
+
*/
|
|
63
|
+
configureAccessory(accessory) {
|
|
64
|
+
this.logger.debug('Loading accessory from cache: %s', accessory.displayName);
|
|
65
|
+
if (accessory.context?.isThemeAccessory && accessory.context.device?.deviceId) {
|
|
66
|
+
const device = {
|
|
67
|
+
deviceId: accessory.context.device.deviceId,
|
|
68
|
+
name: accessory.context.device.name ?? accessory.displayName.replace(/ - Themes$/, ''),
|
|
69
|
+
};
|
|
70
|
+
const handler = new ThemeSwitchAccessory(this, accessory, device, []);
|
|
71
|
+
this.themeAccessories.set(device.deviceId, handler);
|
|
72
|
+
}
|
|
73
|
+
// add the restored accessory to the accessories cache, so we can track if it has already been registered
|
|
74
|
+
this.accessories.set(accessory.UUID, accessory);
|
|
75
|
+
}
|
|
76
|
+
async discoverDevices() {
|
|
77
|
+
if (!this.configured || !this.apiClient) {
|
|
78
|
+
this.logger.warn('Skipping Moonside discovery because the plugin is not configured.');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const devices = await this.apiClient.fetchDevices();
|
|
83
|
+
const themeDefinitions = await this.resolveThemeDefinitions();
|
|
84
|
+
await this.syncDeviceSnapshot(devices, themeDefinitions);
|
|
85
|
+
await this.startRealtimeStream(true);
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
this.logger.error('Failed to discover Moonside lamps: %s', error instanceof Error ? error.message : String(error));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async registerOrUpdateAccessory(deviceId, state) {
|
|
92
|
+
const name = state?.deviceName ?? deviceId;
|
|
93
|
+
const uuid = this.api.hap.uuid.generate(deviceId);
|
|
94
|
+
const existingAccessory = this.accessories.get(uuid);
|
|
95
|
+
if (existingAccessory) {
|
|
96
|
+
let handler = this.accessoriesByDeviceId.get(deviceId);
|
|
97
|
+
if (!handler) {
|
|
98
|
+
handler = new MoonsideLampAccessory(this, existingAccessory, { deviceId, name }, state);
|
|
99
|
+
this.accessoriesByDeviceId.set(deviceId, handler);
|
|
100
|
+
}
|
|
101
|
+
else if (state) {
|
|
102
|
+
handler.updateFromCloud(state);
|
|
103
|
+
}
|
|
104
|
+
existingAccessory.context.device = { deviceId, name };
|
|
105
|
+
this.api.updatePlatformAccessories([existingAccessory]);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
this.logger.debug('Adding new accessory: %s', name);
|
|
109
|
+
const accessory = new this.api.platformAccessory(name, uuid);
|
|
110
|
+
accessory.context.device = { deviceId, name };
|
|
111
|
+
const handler = new MoonsideLampAccessory(this, accessory, { deviceId, name }, state);
|
|
112
|
+
this.accessoriesByDeviceId.set(deviceId, handler);
|
|
113
|
+
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
114
|
+
this.accessories.set(accessory.UUID, accessory);
|
|
115
|
+
}
|
|
116
|
+
return name;
|
|
117
|
+
}
|
|
118
|
+
removeAccessory(deviceId, accessory) {
|
|
119
|
+
this.logger.debug('Removing accessory for device %s', accessory.displayName);
|
|
120
|
+
this.accessoriesByDeviceId.get(deviceId)?.destroy();
|
|
121
|
+
this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
122
|
+
this.accessories.delete(accessory.UUID);
|
|
123
|
+
this.accessoriesByDeviceId.delete(deviceId);
|
|
124
|
+
this.removeThemeAccessory(deviceId);
|
|
125
|
+
}
|
|
126
|
+
async startRealtimeStream(skipInitialRefresh = false) {
|
|
127
|
+
if (!this.apiClient) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
let skipRefresh = skipInitialRefresh;
|
|
131
|
+
this.streamUnsubscribe?.();
|
|
132
|
+
this.streamUnsubscribe = await this.apiClient.subscribeToDeviceUpdates(async (deviceId, update) => {
|
|
133
|
+
if (update === null) {
|
|
134
|
+
const uuid = this.api.hap.uuid.generate(deviceId);
|
|
135
|
+
const accessory = this.accessories.get(uuid);
|
|
136
|
+
if (accessory) {
|
|
137
|
+
this.removeAccessory(deviceId, accessory);
|
|
138
|
+
}
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const handler = this.accessoriesByDeviceId.get(deviceId);
|
|
142
|
+
if (handler) {
|
|
143
|
+
handler.updateFromCloud(update);
|
|
144
|
+
await this.registerOrUpdateThemeAccessory(deviceId, handler.getDeviceName(), this.themeDefinitionsCache ?? []);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
const deviceName = await this.registerOrUpdateAccessory(deviceId, update);
|
|
148
|
+
await this.registerOrUpdateThemeAccessory(deviceId, deviceName, this.themeDefinitionsCache ?? []);
|
|
149
|
+
}
|
|
150
|
+
}, (error) => {
|
|
151
|
+
this.logger.warn('Moonside realtime stream warning: %s', error instanceof Error ? error.message : String(error));
|
|
152
|
+
}, async () => {
|
|
153
|
+
if (skipRefresh) {
|
|
154
|
+
skipRefresh = false;
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
await this.refreshDevicesFromCloud();
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
async syncDeviceSnapshot(devices, themeDefinitions) {
|
|
161
|
+
const seenDeviceIds = [];
|
|
162
|
+
for (const [deviceId, state] of devices.entries()) {
|
|
163
|
+
if (!state) {
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
const deviceName = await this.registerOrUpdateAccessory(deviceId, state);
|
|
167
|
+
await this.registerOrUpdateThemeAccessory(deviceId, deviceName, themeDefinitions);
|
|
168
|
+
seenDeviceIds.push(deviceId);
|
|
169
|
+
}
|
|
170
|
+
for (const accessory of this.accessories.values()) {
|
|
171
|
+
const cachedDeviceId = accessory.context.device?.deviceId;
|
|
172
|
+
if (cachedDeviceId && !seenDeviceIds.includes(cachedDeviceId)) {
|
|
173
|
+
this.removeAccessory(cachedDeviceId, accessory);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
async refreshDevicesFromCloud() {
|
|
178
|
+
if (!this.apiClient) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const devices = await this.apiClient.fetchDevices();
|
|
182
|
+
const themeDefinitions = await this.resolveThemeDefinitions();
|
|
183
|
+
await this.syncDeviceSnapshot(devices, themeDefinitions);
|
|
184
|
+
}
|
|
185
|
+
async registerOrUpdateThemeAccessory(deviceId, deviceName, themes) {
|
|
186
|
+
const uuid = this.api.hap.uuid.generate(`${deviceId}:themes`);
|
|
187
|
+
const existingAccessory = this.accessories.get(uuid);
|
|
188
|
+
const shouldExist = themes.length > 0;
|
|
189
|
+
if (!shouldExist) {
|
|
190
|
+
if (existingAccessory) {
|
|
191
|
+
this.removeThemeAccessory(deviceId);
|
|
192
|
+
}
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (existingAccessory) {
|
|
196
|
+
let handler = this.themeAccessories.get(deviceId);
|
|
197
|
+
if (!handler) {
|
|
198
|
+
handler = new ThemeSwitchAccessory(this, existingAccessory, { deviceId, name: deviceName }, themes);
|
|
199
|
+
this.themeAccessories.set(deviceId, handler);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
handler.updateDevice({ deviceId, name: deviceName });
|
|
203
|
+
handler.updateThemes(themes);
|
|
204
|
+
}
|
|
205
|
+
existingAccessory.context.device = { deviceId, name: deviceName };
|
|
206
|
+
existingAccessory.context.isThemeAccessory = true;
|
|
207
|
+
this.api.updatePlatformAccessories([existingAccessory]);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const accessory = new this.api.platformAccessory(`${deviceName} - Themes`, uuid);
|
|
211
|
+
accessory.context.device = { deviceId, name: deviceName };
|
|
212
|
+
accessory.context.isThemeAccessory = true;
|
|
213
|
+
const handler = new ThemeSwitchAccessory(this, accessory, { deviceId, name: deviceName }, themes);
|
|
214
|
+
this.themeAccessories.set(deviceId, handler);
|
|
215
|
+
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
216
|
+
this.accessories.set(accessory.UUID, accessory);
|
|
217
|
+
}
|
|
218
|
+
removeThemeAccessory(deviceId) {
|
|
219
|
+
const handler = this.themeAccessories.get(deviceId);
|
|
220
|
+
const uuid = this.api.hap.uuid.generate(`${deviceId}:themes`);
|
|
221
|
+
const accessory = this.accessories.get(uuid);
|
|
222
|
+
handler?.destroy();
|
|
223
|
+
if (accessory) {
|
|
224
|
+
this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
225
|
+
this.accessories.delete(uuid);
|
|
226
|
+
}
|
|
227
|
+
this.themeAccessories.delete(deviceId);
|
|
228
|
+
}
|
|
229
|
+
refreshThemeAccessories(definitions) {
|
|
230
|
+
if (!definitions.length) {
|
|
231
|
+
const deviceIds = Array.from(this.themeAccessories.keys());
|
|
232
|
+
for (const id of deviceIds) {
|
|
233
|
+
this.removeThemeAccessory(id);
|
|
234
|
+
}
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
for (const handler of this.themeAccessories.values()) {
|
|
238
|
+
handler.updateThemes(definitions);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
async resolveThemeDefinitions() {
|
|
242
|
+
if (!this.apiClient || !this.themeSwitchNames.length) {
|
|
243
|
+
this.themeDefinitionsCache = [];
|
|
244
|
+
this.refreshThemeAccessories([]);
|
|
245
|
+
return [];
|
|
246
|
+
}
|
|
247
|
+
if (this.themeDefinitionsCache) {
|
|
248
|
+
return this.themeDefinitionsCache;
|
|
249
|
+
}
|
|
250
|
+
try {
|
|
251
|
+
const library = await this.apiClient.fetchThemeLibrary();
|
|
252
|
+
const selected = [];
|
|
253
|
+
for (const themeName of this.themeSwitchNames) {
|
|
254
|
+
const def = library.get(themeName.toLowerCase());
|
|
255
|
+
if (def) {
|
|
256
|
+
selected.push(def);
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
this.logger.warn('Configured theme "%s" was not found in the Moonside catalog.', themeName);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
this.themeDefinitionsCache = selected;
|
|
263
|
+
this.refreshThemeAccessories(selected);
|
|
264
|
+
return selected;
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
this.logger.error('Failed to load theme catalog: %s', error instanceof Error ? error.message : String(error));
|
|
268
|
+
return [];
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
resolveLogLevel(level) {
|
|
272
|
+
if (level === 'debug' || level === 'warning' || level === 'none') {
|
|
273
|
+
return level;
|
|
274
|
+
}
|
|
275
|
+
return 'warning';
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=platform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { PlatformAccessory } from 'homebridge';
|
|
2
|
+
import type { MoonsideCloudPlatform, MoonsideDeviceConfig } from './platform.js';
|
|
3
|
+
import type { DeviceState } from './moonsideApi.js';
|
|
4
|
+
export declare class MoonsideLampAccessory {
|
|
5
|
+
private readonly platform;
|
|
6
|
+
private readonly accessory;
|
|
7
|
+
private device;
|
|
8
|
+
private readonly initialState?;
|
|
9
|
+
private readonly service;
|
|
10
|
+
private cachedState;
|
|
11
|
+
private currentColor;
|
|
12
|
+
private targetHue;
|
|
13
|
+
private targetSaturation;
|
|
14
|
+
private colorUpdatePromise?;
|
|
15
|
+
private colorUpdateResolve?;
|
|
16
|
+
private colorUpdateReject?;
|
|
17
|
+
private colorUpdateTimeout?;
|
|
18
|
+
private readonly pollTimer?;
|
|
19
|
+
constructor(platform: MoonsideCloudPlatform, accessory: PlatformAccessory, device: MoonsideDeviceConfig, initialState?: DeviceState | undefined);
|
|
20
|
+
updateFromCloud(update?: DeviceState): void;
|
|
21
|
+
getDeviceName(): string;
|
|
22
|
+
destroy(): void;
|
|
23
|
+
private pollState;
|
|
24
|
+
private applyStateFromCloud;
|
|
25
|
+
private removeLegacyThemeSwitches;
|
|
26
|
+
private parsePowerState;
|
|
27
|
+
private parseBrightness;
|
|
28
|
+
private parseColor;
|
|
29
|
+
private normalizeBrightness;
|
|
30
|
+
private clamp01;
|
|
31
|
+
private handleSetOn;
|
|
32
|
+
private handleGetOn;
|
|
33
|
+
private handleSetBrightness;
|
|
34
|
+
private handleGetBrightness;
|
|
35
|
+
private handleSetHue;
|
|
36
|
+
private handleGetHue;
|
|
37
|
+
private handleSetSaturation;
|
|
38
|
+
private handleGetSaturation;
|
|
39
|
+
private scheduleColorUpdate;
|
|
40
|
+
private settleColorPromise;
|
|
41
|
+
private pushColorUpdate;
|
|
42
|
+
private buildColorCommand;
|
|
43
|
+
private rgbToHsv;
|
|
44
|
+
private hsvToRgb;
|
|
45
|
+
private logPrefix;
|
|
46
|
+
}
|