@silizia/homebridge-dioder 0.2.0 → 0.2.2
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/dist/index.mjs +181 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import lg from "lgpio";
|
|
2
2
|
import { colord } from "colord";
|
|
3
3
|
//#region src/DioderAccessory.ts
|
|
4
|
-
const MIN_PWM = .5;
|
|
5
|
-
const PWM_FREQUENCY = 1e4;
|
|
6
|
-
const GAMMA_COR = 2.8;
|
|
7
|
-
var DioderAccessory = class {
|
|
4
|
+
const MIN_PWM$1 = .5;
|
|
5
|
+
const PWM_FREQUENCY$1 = 1e4;
|
|
6
|
+
const GAMMA_COR$1 = 2.8;
|
|
7
|
+
var DioderAccessory$1 = class {
|
|
8
8
|
hsv;
|
|
9
9
|
on;
|
|
10
10
|
LEDservice;
|
|
@@ -51,9 +51,9 @@ var DioderAccessory = class {
|
|
|
51
51
|
this.log.info("Identify!");
|
|
52
52
|
}
|
|
53
53
|
pwm(r, g, b) {
|
|
54
|
-
lg.txPwm(this.gpiochip, this.config.rPin,
|
|
55
|
-
lg.txPwm(this.gpiochip, this.config.gPin,
|
|
56
|
-
lg.txPwm(this.gpiochip, this.config.bPin,
|
|
54
|
+
lg.txPwm(this.gpiochip, this.config.rPin, r === 0 ? 0 : this.config.freq ?? PWM_FREQUENCY$1, (r / 255) ** GAMMA_COR$1 * (100 - MIN_PWM$1) + MIN_PWM$1, 0, 0);
|
|
55
|
+
lg.txPwm(this.gpiochip, this.config.gPin, g === 0 ? 0 : this.config.freq ?? PWM_FREQUENCY$1, (g / 255) ** GAMMA_COR$1 * (100 - MIN_PWM$1) + MIN_PWM$1, 0, 0);
|
|
56
|
+
lg.txPwm(this.gpiochip, this.config.bPin, b === 0 ? 0 : this.config.freq ?? PWM_FREQUENCY$1, (b / 255) ** GAMMA_COR$1 * (100 - MIN_PWM$1) + MIN_PWM$1, 0, 0);
|
|
57
57
|
}
|
|
58
58
|
setOn(on) {
|
|
59
59
|
this.log.info("setOn", on);
|
|
@@ -269,11 +269,12 @@ var RainbowAccessory = class extends AnimatedAccessory {
|
|
|
269
269
|
};
|
|
270
270
|
//#endregion
|
|
271
271
|
//#region src/DioderPlatform.ts
|
|
272
|
-
const PLUGIN_NAME = "@silizia/homebridge-dioder";
|
|
273
|
-
var DioderPlatform = class {
|
|
272
|
+
const PLUGIN_NAME$1 = "@silizia/homebridge-dioder";
|
|
273
|
+
var DioderPlatform$1 = class {
|
|
274
274
|
accessories = /* @__PURE__ */ new Map();
|
|
275
275
|
outdatedAccessories = [];
|
|
276
276
|
animationCancel = void 0;
|
|
277
|
+
gpiochip;
|
|
277
278
|
constructor(log, config, api) {
|
|
278
279
|
this.log = log;
|
|
279
280
|
this.config = config;
|
|
@@ -284,7 +285,7 @@ var DioderPlatform = class {
|
|
|
284
285
|
const removedAccessories = new Map(this.accessories);
|
|
285
286
|
const newAccessories = [];
|
|
286
287
|
const dioderAccessories = [];
|
|
287
|
-
|
|
288
|
+
this.gpiochip = lg.gpiochipOpen(0);
|
|
288
289
|
for (const c of this.config.leds || []) {
|
|
289
290
|
const uuid = this.api.hap.uuid.generate(JSON.stringify(c.name));
|
|
290
291
|
const existingAccessory = this.accessories.get(uuid);
|
|
@@ -297,12 +298,12 @@ var DioderPlatform = class {
|
|
|
297
298
|
this.log.info("Updating existing accessory config:", c.name);
|
|
298
299
|
this.api.updatePlatformAccessories([existingAccessory]);
|
|
299
300
|
}
|
|
300
|
-
dioderAccessories.push(new DioderAccessory(this, existingAccessory, gpiochip));
|
|
301
|
+
dioderAccessories.push(new DioderAccessory$1(this, existingAccessory, this.gpiochip));
|
|
301
302
|
} else {
|
|
302
303
|
this.log.info("Adding new accessory:", c.name);
|
|
303
304
|
const accessory = new this.api.platformAccessory(c.name, uuid);
|
|
304
305
|
accessory.context.config = c;
|
|
305
|
-
dioderAccessories.push(new DioderAccessory(this, accessory, gpiochip));
|
|
306
|
+
dioderAccessories.push(new DioderAccessory$1(this, accessory, this.gpiochip));
|
|
306
307
|
newAccessories.push(accessory);
|
|
307
308
|
}
|
|
308
309
|
}
|
|
@@ -344,13 +345,16 @@ var DioderPlatform = class {
|
|
|
344
345
|
if (removedAccessories.size > 0) {
|
|
345
346
|
const ra = Array.from(removedAccessories).map(([_k, v]) => v);
|
|
346
347
|
this.log.warn("removing unused accessories", ra.map((a) => `${a.displayName} (${a.UUID})`));
|
|
347
|
-
this.api.unregisterPlatformAccessories(PLUGIN_NAME, "Dioder", ra);
|
|
348
|
+
this.api.unregisterPlatformAccessories(PLUGIN_NAME$1, "Dioder", ra);
|
|
348
349
|
}
|
|
349
350
|
if (newAccessories.length > 0) {
|
|
350
351
|
this.log.info("added new accessories", newAccessories.map((a) => `${a.displayName} (${a.UUID})`));
|
|
351
|
-
this.api.registerPlatformAccessories(PLUGIN_NAME, "Dioder", newAccessories);
|
|
352
|
+
this.api.registerPlatformAccessories(PLUGIN_NAME$1, "Dioder", newAccessories);
|
|
352
353
|
}
|
|
353
354
|
});
|
|
355
|
+
this.api.on("shutdown", () => {
|
|
356
|
+
if (this.gpiochip !== void 0) lg.gpiochipClose(this.gpiochip);
|
|
357
|
+
});
|
|
354
358
|
}
|
|
355
359
|
configureAccessory(accessory) {
|
|
356
360
|
this.log.info("Loading accessory from cache:", accessory.displayName, accessory.UUID);
|
|
@@ -371,9 +375,171 @@ var DioderPlatform = class {
|
|
|
371
375
|
}
|
|
372
376
|
};
|
|
373
377
|
//#endregion
|
|
378
|
+
//#region src/matter/DioderAccessory.ts
|
|
379
|
+
const MIN_PWM = .5;
|
|
380
|
+
const PWM_FREQUENCY = 1e4;
|
|
381
|
+
const GAMMA_COR = 2.8;
|
|
382
|
+
var DioderAccessory = class {
|
|
383
|
+
accessory;
|
|
384
|
+
constructor(api, log, gpiochip, config, accessory) {
|
|
385
|
+
this.api = api;
|
|
386
|
+
this.log = log;
|
|
387
|
+
this.gpiochip = gpiochip;
|
|
388
|
+
this.config = config;
|
|
389
|
+
this.accessory = accessory ?? {
|
|
390
|
+
UUID: this.api.hap.uuid.generate(this.config.name),
|
|
391
|
+
displayName: this.config.name,
|
|
392
|
+
deviceType: this.api.matter.deviceTypes.ExtendedColorLight,
|
|
393
|
+
serialNumber: "42",
|
|
394
|
+
manufacturer: "Silizia",
|
|
395
|
+
model: "Fancy LED",
|
|
396
|
+
clusters: {
|
|
397
|
+
onOff: { onOff: false },
|
|
398
|
+
levelControl: {
|
|
399
|
+
currentLevel: 254,
|
|
400
|
+
minLevel: 1,
|
|
401
|
+
maxLevel: 254
|
|
402
|
+
},
|
|
403
|
+
colorControl: {
|
|
404
|
+
currentHue: 0,
|
|
405
|
+
currentSaturation: 254,
|
|
406
|
+
colorMode: this.api.matter.types.ColorControl.ColorMode.CurrentHueAndCurrentSaturation
|
|
407
|
+
}
|
|
408
|
+
},
|
|
409
|
+
handlers: {
|
|
410
|
+
onOff: {
|
|
411
|
+
on: () => this.handleOn(),
|
|
412
|
+
off: () => this.handleOff()
|
|
413
|
+
},
|
|
414
|
+
levelControl: { moveToLevelWithOnOff: (request) => this.handleSetLevel(request) },
|
|
415
|
+
colorControl: { moveToHueAndSaturationLogic: (request) => this.handleSetHueSaturation(request) }
|
|
416
|
+
},
|
|
417
|
+
context: {}
|
|
418
|
+
};
|
|
419
|
+
lg.gpioClaimOutput(gpiochip, this.config.rPin);
|
|
420
|
+
lg.gpioClaimOutput(gpiochip, this.config.gPin);
|
|
421
|
+
lg.gpioClaimOutput(gpiochip, this.config.bPin);
|
|
422
|
+
}
|
|
423
|
+
getBrightness() {
|
|
424
|
+
return (this.accessory?.clusters?.levelControl?.currentLevel ?? 254 / 254) * 100;
|
|
425
|
+
}
|
|
426
|
+
getHsv() {
|
|
427
|
+
const mh = this.accessory?.clusters?.colorControl?.currentHue ?? 0;
|
|
428
|
+
const ms = this.accessory?.clusters?.colorControl?.currentSaturation ?? 254;
|
|
429
|
+
const v = this.getBrightness();
|
|
430
|
+
return {
|
|
431
|
+
h: mh / 254 * 360,
|
|
432
|
+
s: ms / 254 * 100,
|
|
433
|
+
v
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
pwm(r, g, b) {
|
|
437
|
+
lg.txPwm(this.gpiochip, this.config.rPin, r === 0 ? 0 : this.config.freq ?? PWM_FREQUENCY, (r / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM, 0, 0);
|
|
438
|
+
lg.txPwm(this.gpiochip, this.config.gPin, g === 0 ? 0 : this.config.freq ?? PWM_FREQUENCY, (g / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM, 0, 0);
|
|
439
|
+
lg.txPwm(this.gpiochip, this.config.bPin, b === 0 ? 0 : this.config.freq ?? PWM_FREQUENCY, (b / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM, 0, 0);
|
|
440
|
+
}
|
|
441
|
+
setHSV(c) {
|
|
442
|
+
if (c.v > 0) {
|
|
443
|
+
const { r, g, b } = colord(c).toRgb();
|
|
444
|
+
this.pwm(r, g, b);
|
|
445
|
+
this.log.info(`set ${this.config.name} r: ${r}, g: ${g}, b: ${b} or h: ${c.h}, s: ${c.s}, v: ${c.v}`);
|
|
446
|
+
} else this.log.warn("Skipping color change while light bulb being off");
|
|
447
|
+
}
|
|
448
|
+
async handleOn() {
|
|
449
|
+
this.log.info(`${this.config.name}: turning on.`);
|
|
450
|
+
const hsv = this.getHsv();
|
|
451
|
+
/*! if (hsv.v === 0) {
|
|
452
|
+
await this.api.matter.updateAccessoryState(
|
|
453
|
+
this.accessory.UUID,
|
|
454
|
+
this.api.matter.clusterNames.LevelControl,
|
|
455
|
+
{ currentLevel: 254 }
|
|
456
|
+
);
|
|
457
|
+
hsv.v = 100;
|
|
458
|
+
}*/
|
|
459
|
+
this.setHSV(hsv);
|
|
460
|
+
}
|
|
461
|
+
handleOff() {
|
|
462
|
+
this.log.info(`${this.config.name}: turning off.`);
|
|
463
|
+
this.pwm(0, 0, 0);
|
|
464
|
+
}
|
|
465
|
+
handleSetLevel(request) {
|
|
466
|
+
this.log.info(`${this.config.name}: MoveToLevel request: ${JSON.stringify(request)}`);
|
|
467
|
+
const { level } = request;
|
|
468
|
+
const hsv = this.getHsv();
|
|
469
|
+
hsv.v = level / 254 * 100;
|
|
470
|
+
this.setHSV(hsv);
|
|
471
|
+
this.log.info(`${this.config.name}: setting brightness to ${hsv.v}%.`);
|
|
472
|
+
}
|
|
473
|
+
handleSetHueSaturation(request) {
|
|
474
|
+
this.log.info(`${this.config.name}: MoveToHueAndSaturation request: ${JSON.stringify(request)}`);
|
|
475
|
+
const { hue, saturation } = request;
|
|
476
|
+
const hsv = {
|
|
477
|
+
h: hue / 254 * 360,
|
|
478
|
+
s: saturation / 254 * 100,
|
|
479
|
+
v: this.getBrightness()
|
|
480
|
+
};
|
|
481
|
+
this.setHSV(hsv);
|
|
482
|
+
this.log.info(`${this.config.name}: setting color to h: ${hsv.h}°, s: ${hsv.s}%, v: ${hsv.v}%.`);
|
|
483
|
+
}
|
|
484
|
+
getAccessory() {
|
|
485
|
+
return this.accessory;
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
//#endregion
|
|
489
|
+
//#region src/matter/DioderPlatform.ts
|
|
490
|
+
const PLUGIN_NAME = "@silizia/homebridge-dioder";
|
|
491
|
+
var DioderPlatform = class {
|
|
492
|
+
accessories = /* @__PURE__ */ new Map();
|
|
493
|
+
outdatedAccessories = [];
|
|
494
|
+
gpiochip;
|
|
495
|
+
constructor(log, config, api) {
|
|
496
|
+
this.log = log;
|
|
497
|
+
this.config = config;
|
|
498
|
+
this.api = api;
|
|
499
|
+
this.log.debug("Finished initializing platform: Dioder");
|
|
500
|
+
this.api.on("didFinishLaunching", () => {
|
|
501
|
+
this.log.debug("Executed didFinishLaunching callback");
|
|
502
|
+
const removedAccessories = new Map(this.accessories);
|
|
503
|
+
const newAccessories = [];
|
|
504
|
+
this.gpiochip = lg.gpiochipOpen(0);
|
|
505
|
+
for (const c of this.config.leds || []) {
|
|
506
|
+
const uuid = this.api.hap.uuid.generate(JSON.stringify(c.name));
|
|
507
|
+
const existingAccessory = this.accessories.get(uuid);
|
|
508
|
+
if (existingAccessory) {
|
|
509
|
+
removedAccessories.delete(uuid);
|
|
510
|
+
this.log.info("Restoring existing accessory from cache:", existingAccessory.displayName);
|
|
511
|
+
new DioderAccessory(this.api, this.log, this.gpiochip, c, existingAccessory);
|
|
512
|
+
} else {
|
|
513
|
+
this.log.info("Adding new accessory:", c.name);
|
|
514
|
+
const device = new DioderAccessory(this.api, this.log, this.gpiochip, c);
|
|
515
|
+
newAccessories.push(device.getAccessory());
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
if (removedAccessories.size > 0) {
|
|
519
|
+
const ra = Array.from(removedAccessories).map(([_k, v]) => v);
|
|
520
|
+
this.log.warn("removing unused accessories", ra.map((a) => `${a.displayName} (${a.UUID})`));
|
|
521
|
+
this.api.matter.unregisterPlatformAccessories(PLUGIN_NAME, "Dioder", ra);
|
|
522
|
+
}
|
|
523
|
+
if (newAccessories.length > 0) {
|
|
524
|
+
this.log.info("added new accessories", newAccessories.map((a) => `${a.displayName} (${a.UUID})`));
|
|
525
|
+
this.api.matter.registerPlatformAccessories(PLUGIN_NAME, "Dioder", newAccessories);
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
this.api.on("shutdown", () => {
|
|
529
|
+
if (this.gpiochip !== void 0) lg.gpiochipClose(this.gpiochip);
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
configureAccessory() {}
|
|
533
|
+
configureMatterAccessory(accessory) {
|
|
534
|
+
this.log.info("Loading accessory from cache:", accessory.displayName, accessory.UUID);
|
|
535
|
+
this.accessories.set(accessory.UUID, accessory);
|
|
536
|
+
}
|
|
537
|
+
};
|
|
538
|
+
//#endregion
|
|
374
539
|
//#region src/index.ts
|
|
375
540
|
function main(api) {
|
|
376
|
-
api.registerPlatform("
|
|
541
|
+
if (api.isMatterAvailable() && api.isMatterEnabled()) api.registerPlatform("MatterDioder", DioderPlatform);
|
|
542
|
+
else api.registerPlatform("Dioder", DioderPlatform$1);
|
|
377
543
|
}
|
|
378
544
|
//#endregion
|
|
379
545
|
export { main as default };
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/DioderAccessory.ts","../src/AnimatedAccessory.ts","../src/GradientAccessory.ts","../src/RainbowAccessory.ts","../src/DioderPlatform.ts","../src/index.ts"],"sourcesContent":["import { colord, type HsvColor } from 'colord';\nimport type { CharacteristicValue, PlatformAccessory, Service, Logging } from 'homebridge';\nimport lg from 'lgpio';\n\nimport type DioderPlatform from './DioderPlatform';\nimport type { DioderContext, LedConfig } from './DioderPlatform';\n\nconst MIN_PWM = 0.5; // min pwm to get actually light from dioder, depends on PWM_RANGE\nconst PWM_FREQUENCY = 10000;\nconst GAMMA_COR = 2.8;\n\nexport default class DioderAccessory {\n private hsv: HsvColor;\n private on: boolean;\n\n private readonly LEDservice: Service;\n private readonly Characteristic;\n private readonly log: Logging;\n private readonly config: LedConfig;\n\n constructor(\n private readonly platform: DioderPlatform,\n private readonly accessory: PlatformAccessory<DioderContext>,\n private readonly gpiochip: number\n ) {\n const { hap } = platform.api;\n this.Characteristic = hap.Characteristic;\n this.log = platform.log;\n\n this.config = accessory.context.config;\n lg.gpioClaimOutput(gpiochip, this.config.rPin);\n lg.gpioClaimOutput(gpiochip, this.config.gPin);\n lg.gpioClaimOutput(gpiochip, this.config.bPin);\n this.hsv = { h: 0, s: 0, v: 0 };\n this.on = false;\n\n this.accessory\n .getService(hap.Service.AccessoryInformation)\n ?.setCharacteristic(this.Characteristic.Manufacturer, 'Silizia')\n .setCharacteristic(this.Characteristic.Model, 'Fancy LED')\n .setCharacteristic(this.Characteristic.SerialNumber, '42');\n\n this.accessory.on('identify', () => this.identify());\n\n this.LEDservice = this.accessory.getService(hap.Service.Lightbulb) || this.accessory.addService(hap.Service.Lightbulb);\n this.LEDservice.setCharacteristic(this.Characteristic.Name, this.config.name);\n\n this.LEDservice.getCharacteristic(this.Characteristic.On).onGet(this.getOn.bind(this)).onSet(this.setOn.bind(this));\n this.LEDservice.getCharacteristic(this.Characteristic.Brightness).onSet(this.setBrightness.bind(this));\n this.LEDservice.getCharacteristic(this.Characteristic.Hue).onSet(this.setHue.bind(this));\n this.LEDservice.getCharacteristic(this.Characteristic.Saturation).onSet(this.setSaturation.bind(this));\n }\n\n identify(): void {\n this.pwm(0, 0, 0);\n setTimeout(() => {\n this.pwm(255, 0, 0);\n setTimeout(() => {\n this.pwm(0, 0, 0);\n if (this.hsv.v > 0) {\n setTimeout(() => {\n this.setHSV(this.hsv);\n }, 1000);\n }\n }, 3000);\n }, 1000);\n this.log.info('Identify!');\n }\n\n pwm(r: number, g: number, b: number): void {\n lg.txPwm(this.gpiochip, this.config.rPin, this.config.freq ?? PWM_FREQUENCY, r === 0 ? 0 : (r / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM, 0, 0);\n lg.txPwm(this.gpiochip, this.config.gPin, this.config.freq ?? PWM_FREQUENCY, g === 0 ? 0 : (g / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM, 0, 0);\n lg.txPwm(this.gpiochip, this.config.bPin, this.config.freq ?? PWM_FREQUENCY, b === 0 ? 0 : (b / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM, 0, 0);\n }\n\n setOn(on: CharacteristicValue): void {\n this.log.info('setOn', on);\n this.on = on as boolean;\n if (on) {\n this.platform.stopAnimation();\n if (this.hsv.v === 0) {\n this.hsv.v = 100;\n this.LEDservice.setCharacteristic(this.Characteristic.Brightness, 100);\n } else {\n this.setHSV(this.hsv);\n }\n } else {\n this.pwm(0, 0, 0);\n this.hsv = { h: 0, s: 0, v: 0 };\n }\n }\n\n getOn(): boolean {\n if (this.platform.isAnimationRunning()) return false;\n return this.hsv.v > 0;\n }\n\n setBrightness(v: CharacteristicValue): void {\n this.log.info('setBrightness', v);\n this.hsv.v = v as number;\n this.setHSV(this.hsv);\n }\n\n setHue(h: CharacteristicValue): void {\n this.log.info('setHue', h);\n this.hsv.h = h as number;\n this.setHSV(this.hsv);\n }\n\n setSaturation(s: CharacteristicValue): void {\n this.hsv.s = s as number;\n this.log.info('setSaturation', s, this.hsv.s);\n this.setHSV(this.hsv);\n }\n\n setHSV(c: HsvColor, t?: boolean): void {\n if (t || (this.on && this.hsv.v > 0)) {\n const { r, g, b } = colord(c).toRgb();\n this.pwm(r, g, b);\n if (!t) this.log.info(`set ${this.accessory.displayName} r: ${r}, g: ${g}, b: ${b} or h: ${c.h}, s: ${c.s}, v: ${c.v}`);\n } else {\n this.log.warn('Skipping color change while light bulb being off');\n }\n this.hsv = c;\n }\n\n getHSV(): HsvColor {\n return this.hsv;\n }\n\n turnOff(): void {\n this.pwm(0, 0, 0);\n this.hsv = { h: 0, s: 0, v: 0 };\n }\n}\n","import type { PlatformAccessory, CharacteristicValue, Service, Logging } from 'homebridge';\n\nimport type DioderAccessory from './DioderAccessory';\nimport type DioderPlatform from './DioderPlatform';\n\nconst INTERVAL = 1000 / 30; // 30 FPS\nconst SPEED = 100; // 1..100 => 0.01..1\nconst OFFSET_CT = 5; // 140..500 => 28..100\n\nexport default class AnimatedAccessory {\n public brightness: number;\n public offset: number;\n public speed: number;\n private on: boolean;\n private onS: boolean;\n private interval: NodeJS.Timeout | undefined;\n\n private readonly LEDservice: Service;\n private readonly FanService: Service;\n private readonly Characteristic;\n public readonly log: Logging;\n\n constructor(\n private readonly platform: DioderPlatform,\n private readonly accessory: PlatformAccessory,\n public readonly leds: DioderAccessory[],\n name: string\n ) {\n const { hap } = this.platform.api;\n this.Characteristic = hap.Characteristic;\n this.log = this.platform.log;\n\n this.on = false;\n this.onS = false;\n this.brightness = 0;\n this.offset = 50;\n this.speed = 0.5;\n this.interval = undefined;\n\n this.accessory\n .getService(hap.Service.AccessoryInformation)\n ?.setCharacteristic(this.Characteristic.Manufacturer, 'Silizia')\n .setCharacteristic(this.Characteristic.Model, 'Fancy LED')\n .setCharacteristic(this.Characteristic.SerialNumber, '42');\n\n this.accessory.on('identify', () => this.identify());\n\n this.LEDservice = this.accessory.getService(hap.Service.Lightbulb) || this.accessory.addService(hap.Service.Lightbulb);\n this.LEDservice.setCharacteristic(this.Characteristic.Name, name);\n this.LEDservice.getCharacteristic(this.Characteristic.On).onGet(this.getOn.bind(this)).onSet(this.setOn.bind(this));\n this.LEDservice.getCharacteristic(this.Characteristic.Brightness).onGet(this.getBrightness.bind(this)).onSet(this.setBrightness.bind(this));\n this.LEDservice.getCharacteristic(this.Characteristic.ColorTemperature)\n .onGet(this.getColorTemperature.bind(this))\n .onSet(this.setColorTemperature.bind(this));\n\n this.FanService = this.accessory.getService(hap.Service.Fan) || this.accessory.addService(hap.Service.Fan);\n this.FanService.setCharacteristic(this.Characteristic.Name, `${name} Speed`);\n this.FanService.getCharacteristic(this.Characteristic.On).onGet(this.getOnS.bind(this)).onSet(this.setOnS.bind(this));\n this.FanService.getCharacteristic(this.Characteristic.RotationSpeed).onGet(this.getSpeed.bind(this)).onSet(this.setSpeed.bind(this));\n }\n\n identify(): void {\n this.log.info('Identify!');\n }\n\n setOn(on: CharacteristicValue): void {\n this.log.info(`rainbow setOn`, on);\n this.on = on as boolean;\n if (on) {\n if (this.getBrightness() === 0) {\n this.LEDservice.setCharacteristic(this.Characteristic.Brightness, 100);\n }\n this.FanService.updateCharacteristic(this.Characteristic.On, true);\n this.onS = true;\n if (this.getSpeed() === 0) {\n this.FanService.setCharacteristic(this.Characteristic.RotationSpeed, 50);\n }\n this.interval = setInterval(() => this.runAnimation(), INTERVAL);\n this.platform.setAnimationCancel(this.cancelAnimation.bind(this));\n } else {\n this.FanService.updateCharacteristic(this.Characteristic.On, false);\n this.onS = false;\n clearInterval(this.interval);\n this.interval = undefined;\n for (const led of this.leds) led.turnOff();\n }\n }\n\n getOn(): boolean {\n return this.on;\n }\n\n setOnS(on: CharacteristicValue): void {\n this.log.info('rainbow setOnS', on);\n this.onS = on as boolean;\n if (on) {\n if (this.getSpeed() === 0) {\n this.FanService.setCharacteristic(this.Characteristic.RotationSpeed, 50);\n }\n this.interval = setInterval(() => this.runAnimation(), INTERVAL);\n this.LEDservice.updateCharacteristic(this.Characteristic.On, true);\n this.on = true;\n if (this.getBrightness() === 0) {\n this.LEDservice.setCharacteristic(this.Characteristic.Brightness, 100);\n }\n this.platform.setAnimationCancel(this.cancelAnimation.bind(this));\n } else {\n clearInterval(this.interval);\n this.interval = undefined;\n }\n }\n\n getOnS(): boolean {\n return this.onS; // interval running\n }\n\n setBrightness(v: CharacteristicValue): void {\n this.log.info('rainbow setBrightness', v);\n this.brightness = v as number;\n }\n\n getBrightness(): number {\n return this.brightness;\n }\n\n setColorTemperature(v: CharacteristicValue): void {\n this.log.info('rainbow setColorTemperature', v);\n this.offset = (v as number) / OFFSET_CT;\n }\n\n getColorTemperature(): number {\n return this.offset * OFFSET_CT;\n }\n\n setSpeed(v: CharacteristicValue): void {\n this.log.info('rainbow speed', v);\n this.speed = (v as number) / SPEED;\n }\n\n getSpeed(): number {\n return this.speed * SPEED;\n }\n\n // oxlint-disable-next-line class-methods-use-this, no-empty-function\n runAnimation(): void {}\n\n cancelAnimation(): void {\n clearInterval(this.interval);\n this.interval = undefined;\n this.LEDservice.updateCharacteristic(this.Characteristic.On, false);\n this.FanService.updateCharacteristic(this.Characteristic.On, false);\n }\n}\n","import { colord, type RgbColor } from 'colord';\nimport type { PlatformAccessory } from 'homebridge';\n\nimport AnimatedAccessory from './AnimatedAccessory';\nimport type DioderAccessory from './DioderAccessory';\nimport type DioderPlatform from './DioderPlatform';\nimport type { GradiantContext } from './DioderPlatform';\n\nexport default class GradientAccessory extends AnimatedAccessory {\n private currentStep: number;\n private readonly colors: RgbColor[];\n\n constructor(platform: DioderPlatform, accessory: PlatformAccessory<GradiantContext>, leds: DioderAccessory[]) {\n super(platform, accessory, leds, accessory.context.config.name);\n this.currentStep = 0;\n this.colors = accessory.context.config.colors.map((c: string) => colord(c).toRgb());\n }\n\n runAnimation(): void {\n const len = this.leds.length;\n for (let i = 0; i < len; i++) {\n const step = this.currentStep + (i * this.offset) / 50;\n const prevColor = Math.floor(step) % len;\n const nextColor = (prevColor + 1) % len;\n const prog = step % 1;\n const r = this.colors[prevColor].r * (1 - prog) + this.colors[nextColor].r * prog;\n const g = this.colors[prevColor].g * (1 - prog) + this.colors[nextColor].g * prog;\n const b = this.colors[prevColor].b * (1 - prog) + this.colors[nextColor].b * prog;\n this.leds[i].pwm((r * this.brightness) / 100, (g * this.brightness) / 100, (b * this.brightness) / 100);\n }\n this.currentStep = (this.currentStep + (this.speed * len) / 360) % len;\n }\n}\n","import type { PlatformAccessory } from 'homebridge';\n\nimport AnimatedAccessory from './AnimatedAccessory';\nimport type DioderAccessory from './DioderAccessory';\nimport type DioderPlatform from './DioderPlatform';\n\nconst SATURATION = 100;\n\nexport default class RainbowAccessory extends AnimatedAccessory {\n private currentHue: number;\n\n constructor(platform: DioderPlatform, accessory: PlatformAccessory, leds: DioderAccessory[]) {\n super(platform, accessory, leds, 'Rainbow Effect');\n this.currentHue = 0;\n }\n\n runAnimation(): void {\n //this.log.warn(`currentHue: ${this.currentHue}, offset: ${this.offset}, speed: ${this.speed}`);\n for (let i = 0; i < this.leds.length; i++) {\n this.leds[i].setHSV({ h: (this.currentHue + i * this.offset) % 360, s: SATURATION, v: this.brightness }, true);\n }\n this.currentHue = (this.currentHue + this.speed) % 360;\n }\n}\n","import type { PlatformAccessory, API, Logging, PlatformConfig, DynamicPlatformPlugin } from 'homebridge';\nimport lg from 'lgpio';\n\nimport DioderAccessory from './DioderAccessory';\nimport GradientAccessory from './GradientAccessory';\nimport RainbowAccessory from './RainbowAccessory';\n\nexport interface LedConfig {\n name: string;\n rPin: number;\n gPin: number;\n bPin: number;\n freq: number;\n}\n\ninterface GradiantConfig {\n name: string;\n colors: string[];\n}\n\ninterface DioderConfig extends PlatformConfig {\n leds: LedConfig[];\n gradientAnim: GradiantConfig[];\n rainbowAnim: { enabled: boolean };\n}\n\nexport interface DioderContext {\n config: LedConfig;\n}\n\nexport interface GradiantContext {\n config: GradiantConfig;\n}\n\nconst PLUGIN_NAME = '@silizia/homebridge-dioder';\n\nexport default class DioderPlatform implements DynamicPlatformPlugin {\n public readonly accessories: Map<string, PlatformAccessory> = new Map();\n public readonly outdatedAccessories: PlatformAccessory[] = [];\n public animationCancel?: () => void = undefined;\n\n constructor(\n public readonly log: Logging,\n public readonly config: DioderConfig,\n public readonly api: API\n ) {\n this.log.debug('Finished initializing platform: Dioder');\n this.api.on('didFinishLaunching', () => {\n this.log.debug('Executed didFinishLaunching callback');\n const removedAccessories = new Map(this.accessories);\n const newAccessories: PlatformAccessory[] = [];\n // DioderAccessories\n const dioderAccessories: DioderAccessory[] = [];\n const gpiochip = lg.gpiochipOpen(0);\n for (const c of this.config.leds || []) {\n const uuid = this.api.hap.uuid.generate(JSON.stringify(c.name));\n const existingAccessory = this.accessories.get(uuid) as PlatformAccessory<DioderContext>;\n if (existingAccessory) {\n removedAccessories.delete(uuid);\n this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName);\n const ec = existingAccessory.context.config;\n if (c.rPin !== ec.rPin || c.gPin !== ec.gPin || c.bPin !== ec.bPin || c.freq !== ec.freq) {\n existingAccessory.context.config = c;\n this.log.info('Updating existing accessory config:', c.name);\n this.api.updatePlatformAccessories([existingAccessory]);\n }\n dioderAccessories.push(new DioderAccessory(this, existingAccessory, gpiochip));\n } else {\n this.log.info('Adding new accessory:', c.name);\n const accessory = new this.api.platformAccessory<DioderContext>(c.name, uuid);\n accessory.context.config = c;\n dioderAccessories.push(new DioderAccessory(this, accessory, gpiochip));\n newAccessories.push(accessory);\n }\n }\n // RainbowAccessory\n if (this.config.rainbowAnim?.enabled) {\n const uuid = this.api.hap.uuid.generate('Rainbow Effect');\n const existingAccessory = this.accessories.get(uuid);\n if (existingAccessory) {\n removedAccessories.delete(uuid);\n this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName);\n // oxlint-disable-next-line no-new\n new RainbowAccessory(this, existingAccessory, dioderAccessories);\n } else {\n this.log.info('Adding new accessory: Rainbow Effect');\n const accessory = new this.api.platformAccessory('Rainbow Effect', uuid);\n // oxlint-disable-next-line no-new\n new RainbowAccessory(this, accessory, dioderAccessories);\n newAccessories.push(accessory);\n }\n }\n // GradientAccessory\n for (const c of this.config.gradientAnim || []) {\n const uuid = this.api.hap.uuid.generate(JSON.stringify(c.name));\n const existingAccessory = this.accessories.get(uuid) as PlatformAccessory<GradiantContext>;\n if (existingAccessory) {\n removedAccessories.delete(uuid);\n this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName);\n const ec = existingAccessory.context.config;\n if (c.colors.toString() !== ec.colors.toString()) {\n existingAccessory.context.config = c;\n this.log.info('Updating existing accessory config:', c.name);\n this.api.updatePlatformAccessories([existingAccessory]);\n }\n // oxlint-disable-next-line no-new\n new GradientAccessory(this, existingAccessory, dioderAccessories);\n } else {\n this.log.info('Adding new gradient accessory:', c.name);\n const accessory = new this.api.platformAccessory<GradiantContext>(c.name, uuid);\n accessory.context.config = c;\n // oxlint-disable-next-line no-new\n new GradientAccessory(this, accessory, dioderAccessories);\n newAccessories.push(accessory);\n }\n }\n // removed unused Accessories\n if (removedAccessories.size > 0) {\n const ra = Array.from(removedAccessories).map(([_k, v]) => v);\n this.log.warn(\n 'removing unused accessories',\n ra.map(a => `${a.displayName} (${a.UUID})`)\n );\n this.api.unregisterPlatformAccessories(PLUGIN_NAME, 'Dioder', ra);\n }\n if (newAccessories.length > 0) {\n this.log.info(\n 'added new accessories',\n newAccessories.map(a => `${a.displayName} (${a.UUID})`)\n );\n this.api.registerPlatformAccessories(PLUGIN_NAME, 'Dioder', newAccessories);\n }\n });\n }\n\n configureAccessory(accessory: PlatformAccessory): void {\n this.log.info('Loading accessory from cache:', accessory.displayName, accessory.UUID);\n this.accessories.set(accessory.UUID, accessory);\n }\n\n // oxlint-disable-next-line promise/prefer-await-to-callbacks\n setAnimationCancel(callback: () => void): void {\n if (this.animationCancel !== undefined) {\n (this.animationCancel as () => void)();\n }\n this.animationCancel = callback;\n }\n\n isAnimationRunning(): boolean {\n return this.animationCancel !== undefined;\n }\n\n stopAnimation(): void {\n if (this.animationCancel !== undefined) {\n (this.animationCancel as () => void)();\n this.animationCancel = undefined;\n }\n }\n}\n","import type { API } from 'homebridge';\n\nimport DioderPlatform from './DioderPlatform';\n\nexport default function main(api: API): void {\n api.registerPlatform('Dioder', DioderPlatform);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["MIN_PWM","PWM_FREQUENCY","GAMMA_COR","DioderAccessory","PLUGIN_NAME","DioderPlatform","DioderAccessory","MatterDioderPlatform","DioderPlatform"],"sources":["../src/DioderAccessory.ts","../src/AnimatedAccessory.ts","../src/GradientAccessory.ts","../src/RainbowAccessory.ts","../src/DioderPlatform.ts","../src/matter/DioderAccessory.ts","../src/matter/DioderPlatform.ts","../src/index.ts"],"sourcesContent":["import { colord, type HsvColor } from 'colord';\nimport type { CharacteristicValue, PlatformAccessory, Service, Logging } from 'homebridge';\nimport lg from 'lgpio';\n\nimport type DioderPlatform from './DioderPlatform';\nimport type { DioderContext, LedConfig } from './DioderPlatform';\n\nconst MIN_PWM = 0.5; // min pwm to get actually light from dioder, depends on PWM_RANGE\nconst PWM_FREQUENCY = 10000;\nconst GAMMA_COR = 2.8;\n\nexport default class DioderAccessory {\n private hsv: HsvColor;\n private on: boolean;\n\n private readonly LEDservice: Service;\n private readonly Characteristic;\n private readonly log: Logging;\n private readonly config: LedConfig;\n\n constructor(\n private readonly platform: DioderPlatform,\n private readonly accessory: PlatformAccessory<DioderContext>,\n private readonly gpiochip: number\n ) {\n const { hap } = platform.api;\n this.Characteristic = hap.Characteristic;\n this.log = platform.log;\n\n this.config = accessory.context.config;\n if (!DEV) {\n lg.gpioClaimOutput(gpiochip, this.config.rPin);\n lg.gpioClaimOutput(gpiochip, this.config.gPin);\n lg.gpioClaimOutput(gpiochip, this.config.bPin);\n }\n this.hsv = { h: 0, s: 0, v: 0 };\n this.on = false;\n\n this.accessory\n .getService(hap.Service.AccessoryInformation)\n ?.setCharacteristic(this.Characteristic.Manufacturer, 'Silizia')\n .setCharacteristic(this.Characteristic.Model, 'Fancy LED')\n .setCharacteristic(this.Characteristic.SerialNumber, '42');\n\n this.accessory.on('identify', () => this.identify());\n\n this.LEDservice = this.accessory.getService(hap.Service.Lightbulb) || this.accessory.addService(hap.Service.Lightbulb);\n this.LEDservice.setCharacteristic(this.Characteristic.Name, this.config.name);\n\n this.LEDservice.getCharacteristic(this.Characteristic.On).onGet(this.getOn.bind(this)).onSet(this.setOn.bind(this));\n this.LEDservice.getCharacteristic(this.Characteristic.Brightness).onSet(this.setBrightness.bind(this));\n this.LEDservice.getCharacteristic(this.Characteristic.Hue).onSet(this.setHue.bind(this));\n this.LEDservice.getCharacteristic(this.Characteristic.Saturation).onSet(this.setSaturation.bind(this));\n }\n\n identify(): void {\n this.pwm(0, 0, 0);\n setTimeout(() => {\n this.pwm(255, 0, 0);\n setTimeout(() => {\n this.pwm(0, 0, 0);\n if (this.hsv.v > 0) {\n setTimeout(() => {\n this.setHSV(this.hsv);\n }, 1000);\n }\n }, 3000);\n }, 1000);\n this.log.info('Identify!');\n }\n\n pwm(r: number, g: number, b: number): void {\n if (DEV) {\n this.log.info(`pwm r: ${r}, g: ${g}, b: ${b} for gpiochip: ${this.gpiochip} with freq: ${this.config.freq ?? PWM_FREQUENCY}`);\n this.log.info(`rpin ${this.config.rPin} to ${r === 0 ? 'off' : (r / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM}`);\n this.log.info(`gpin ${this.config.gPin} to ${g === 0 ? 'off' : (g / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM}`);\n this.log.info(`bpin ${this.config.bPin} to ${b === 0 ? 'off' : (b / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM}`);\n } else {\n lg.txPwm(this.gpiochip, this.config.rPin, r === 0 ? 0 : (this.config.freq ?? PWM_FREQUENCY), (r / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM, 0, 0);\n lg.txPwm(this.gpiochip, this.config.gPin, g === 0 ? 0 : (this.config.freq ?? PWM_FREQUENCY), (g / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM, 0, 0);\n lg.txPwm(this.gpiochip, this.config.bPin, b === 0 ? 0 : (this.config.freq ?? PWM_FREQUENCY), (b / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM, 0, 0);\n }\n }\n\n setOn(on: CharacteristicValue): void {\n this.log.info('setOn', on);\n this.on = on as boolean;\n if (on) {\n this.platform.stopAnimation();\n if (this.hsv.v === 0) {\n this.hsv.v = 100;\n this.LEDservice.setCharacteristic(this.Characteristic.Brightness, 100);\n } else {\n this.setHSV(this.hsv);\n }\n } else {\n this.pwm(0, 0, 0);\n this.hsv = { h: 0, s: 0, v: 0 };\n }\n }\n\n getOn(): boolean {\n if (this.platform.isAnimationRunning()) return false;\n return this.hsv.v > 0;\n }\n\n setBrightness(v: CharacteristicValue): void {\n this.log.info('setBrightness', v);\n this.hsv.v = v as number;\n this.setHSV(this.hsv);\n }\n\n setHue(h: CharacteristicValue): void {\n this.log.info('setHue', h);\n this.hsv.h = h as number;\n this.setHSV(this.hsv);\n }\n\n setSaturation(s: CharacteristicValue): void {\n this.hsv.s = s as number;\n this.log.info('setSaturation', s, this.hsv.s);\n this.setHSV(this.hsv);\n }\n\n setHSV(c: HsvColor, t?: boolean): void {\n if (t || (this.on && this.hsv.v > 0)) {\n const { r, g, b } = colord(c).toRgb();\n this.pwm(r, g, b);\n if (!t) this.log.info(`set ${this.accessory.displayName} r: ${r}, g: ${g}, b: ${b} or h: ${c.h}, s: ${c.s}, v: ${c.v}`);\n } else {\n this.log.warn('Skipping color change while light bulb being off');\n }\n this.hsv = c;\n }\n\n getHSV(): HsvColor {\n return this.hsv;\n }\n\n turnOff(): void {\n this.pwm(0, 0, 0);\n this.hsv = { h: 0, s: 0, v: 0 };\n }\n}\n","import type { PlatformAccessory, CharacteristicValue, Service, Logging } from 'homebridge';\n\nimport type DioderAccessory from './DioderAccessory';\nimport type DioderPlatform from './DioderPlatform';\n\nconst INTERVAL = 1000 / 30; // 30 FPS\nconst SPEED = 100; // 1..100 => 0.01..1\nconst OFFSET_CT = 5; // 140..500 => 28..100\n\nexport default class AnimatedAccessory {\n public brightness: number;\n public offset: number;\n public speed: number;\n private on: boolean;\n private onS: boolean;\n private interval: NodeJS.Timeout | undefined;\n\n private readonly LEDservice: Service;\n private readonly FanService: Service;\n private readonly Characteristic;\n public readonly log: Logging;\n\n constructor(\n private readonly platform: DioderPlatform,\n private readonly accessory: PlatformAccessory,\n public readonly leds: DioderAccessory[],\n name: string\n ) {\n const { hap } = this.platform.api;\n this.Characteristic = hap.Characteristic;\n this.log = this.platform.log;\n\n this.on = false;\n this.onS = false;\n this.brightness = 0;\n this.offset = 50;\n this.speed = 0.5;\n this.interval = undefined;\n\n this.accessory\n .getService(hap.Service.AccessoryInformation)\n ?.setCharacteristic(this.Characteristic.Manufacturer, 'Silizia')\n .setCharacteristic(this.Characteristic.Model, 'Fancy LED')\n .setCharacteristic(this.Characteristic.SerialNumber, '42');\n\n this.accessory.on('identify', () => this.identify());\n\n this.LEDservice = this.accessory.getService(hap.Service.Lightbulb) || this.accessory.addService(hap.Service.Lightbulb);\n this.LEDservice.setCharacteristic(this.Characteristic.Name, name);\n this.LEDservice.getCharacteristic(this.Characteristic.On).onGet(this.getOn.bind(this)).onSet(this.setOn.bind(this));\n this.LEDservice.getCharacteristic(this.Characteristic.Brightness).onGet(this.getBrightness.bind(this)).onSet(this.setBrightness.bind(this));\n this.LEDservice.getCharacteristic(this.Characteristic.ColorTemperature)\n .onGet(this.getColorTemperature.bind(this))\n .onSet(this.setColorTemperature.bind(this));\n\n this.FanService = this.accessory.getService(hap.Service.Fan) || this.accessory.addService(hap.Service.Fan);\n this.FanService.setCharacteristic(this.Characteristic.Name, `${name} Speed`);\n this.FanService.getCharacteristic(this.Characteristic.On).onGet(this.getOnS.bind(this)).onSet(this.setOnS.bind(this));\n this.FanService.getCharacteristic(this.Characteristic.RotationSpeed).onGet(this.getSpeed.bind(this)).onSet(this.setSpeed.bind(this));\n }\n\n identify(): void {\n this.log.info('Identify!');\n }\n\n setOn(on: CharacteristicValue): void {\n this.log.info(`rainbow setOn`, on);\n this.on = on as boolean;\n if (on) {\n if (this.getBrightness() === 0) {\n this.LEDservice.setCharacteristic(this.Characteristic.Brightness, 100);\n }\n this.FanService.updateCharacteristic(this.Characteristic.On, true);\n this.onS = true;\n if (this.getSpeed() === 0) {\n this.FanService.setCharacteristic(this.Characteristic.RotationSpeed, 50);\n }\n this.interval = setInterval(() => this.runAnimation(), INTERVAL);\n this.platform.setAnimationCancel(this.cancelAnimation.bind(this));\n } else {\n this.FanService.updateCharacteristic(this.Characteristic.On, false);\n this.onS = false;\n clearInterval(this.interval);\n this.interval = undefined;\n for (const led of this.leds) led.turnOff();\n }\n }\n\n getOn(): boolean {\n return this.on;\n }\n\n setOnS(on: CharacteristicValue): void {\n this.log.info('rainbow setOnS', on);\n this.onS = on as boolean;\n if (on) {\n if (this.getSpeed() === 0) {\n this.FanService.setCharacteristic(this.Characteristic.RotationSpeed, 50);\n }\n this.interval = setInterval(() => this.runAnimation(), INTERVAL);\n this.LEDservice.updateCharacteristic(this.Characteristic.On, true);\n this.on = true;\n if (this.getBrightness() === 0) {\n this.LEDservice.setCharacteristic(this.Characteristic.Brightness, 100);\n }\n this.platform.setAnimationCancel(this.cancelAnimation.bind(this));\n } else {\n clearInterval(this.interval);\n this.interval = undefined;\n }\n }\n\n getOnS(): boolean {\n return this.onS; // interval running\n }\n\n setBrightness(v: CharacteristicValue): void {\n this.log.info('rainbow setBrightness', v);\n this.brightness = v as number;\n }\n\n getBrightness(): number {\n return this.brightness;\n }\n\n setColorTemperature(v: CharacteristicValue): void {\n this.log.info('rainbow setColorTemperature', v);\n this.offset = (v as number) / OFFSET_CT;\n }\n\n getColorTemperature(): number {\n return this.offset * OFFSET_CT;\n }\n\n setSpeed(v: CharacteristicValue): void {\n this.log.info('rainbow speed', v);\n this.speed = (v as number) / SPEED;\n }\n\n getSpeed(): number {\n return this.speed * SPEED;\n }\n\n // oxlint-disable-next-line class-methods-use-this, no-empty-function\n runAnimation(): void {}\n\n cancelAnimation(): void {\n clearInterval(this.interval);\n this.interval = undefined;\n this.LEDservice.updateCharacteristic(this.Characteristic.On, false);\n this.FanService.updateCharacteristic(this.Characteristic.On, false);\n }\n}\n","import { colord, type RgbColor } from 'colord';\nimport type { PlatformAccessory } from 'homebridge';\n\nimport AnimatedAccessory from './AnimatedAccessory';\nimport type DioderAccessory from './DioderAccessory';\nimport type DioderPlatform from './DioderPlatform';\nimport type { GradiantContext } from './DioderPlatform';\n\nexport default class GradientAccessory extends AnimatedAccessory {\n private currentStep: number;\n private readonly colors: RgbColor[];\n\n constructor(platform: DioderPlatform, accessory: PlatformAccessory<GradiantContext>, leds: DioderAccessory[]) {\n super(platform, accessory, leds, accessory.context.config.name);\n this.currentStep = 0;\n this.colors = accessory.context.config.colors.map((c: string) => colord(c).toRgb());\n }\n\n runAnimation(): void {\n const len = this.leds.length;\n for (let i = 0; i < len; i++) {\n const step = this.currentStep + (i * this.offset) / 50;\n const prevColor = Math.floor(step) % len;\n const nextColor = (prevColor + 1) % len;\n const prog = step % 1;\n const r = this.colors[prevColor].r * (1 - prog) + this.colors[nextColor].r * prog;\n const g = this.colors[prevColor].g * (1 - prog) + this.colors[nextColor].g * prog;\n const b = this.colors[prevColor].b * (1 - prog) + this.colors[nextColor].b * prog;\n this.leds[i].pwm((r * this.brightness) / 100, (g * this.brightness) / 100, (b * this.brightness) / 100);\n }\n this.currentStep = (this.currentStep + (this.speed * len) / 360) % len;\n }\n}\n","import type { PlatformAccessory } from 'homebridge';\n\nimport AnimatedAccessory from './AnimatedAccessory';\nimport type DioderAccessory from './DioderAccessory';\nimport type DioderPlatform from './DioderPlatform';\n\nconst SATURATION = 100;\n\nexport default class RainbowAccessory extends AnimatedAccessory {\n private currentHue: number;\n\n constructor(platform: DioderPlatform, accessory: PlatformAccessory, leds: DioderAccessory[]) {\n super(platform, accessory, leds, 'Rainbow Effect');\n this.currentHue = 0;\n }\n\n runAnimation(): void {\n //this.log.warn(`currentHue: ${this.currentHue}, offset: ${this.offset}, speed: ${this.speed}`);\n for (let i = 0; i < this.leds.length; i++) {\n this.leds[i].setHSV({ h: (this.currentHue + i * this.offset) % 360, s: SATURATION, v: this.brightness }, true);\n }\n this.currentHue = (this.currentHue + this.speed) % 360;\n }\n}\n","import type { PlatformAccessory, API, Logging, PlatformConfig, DynamicPlatformPlugin } from 'homebridge';\nimport lg from 'lgpio';\n\nimport DioderAccessory from './DioderAccessory';\nimport GradientAccessory from './GradientAccessory';\nimport RainbowAccessory from './RainbowAccessory';\n\ndeclare global {\n var DEV: boolean;\n}\n\nexport interface LedConfig {\n name: string;\n rPin: number;\n gPin: number;\n bPin: number;\n freq: number;\n}\n\ninterface GradiantConfig {\n name: string;\n colors: string[];\n}\n\ninterface DioderConfig extends PlatformConfig {\n leds: LedConfig[];\n gradientAnim: GradiantConfig[];\n rainbowAnim: { enabled: boolean };\n}\n\nexport interface DioderContext {\n config: LedConfig;\n}\n\nexport interface GradiantContext {\n config: GradiantConfig;\n}\n\nconst PLUGIN_NAME = '@silizia/homebridge-dioder';\n\nexport default class DioderPlatform implements DynamicPlatformPlugin {\n public readonly accessories: Map<string, PlatformAccessory> = new Map();\n public readonly outdatedAccessories: PlatformAccessory[] = [];\n public animationCancel?: () => void = undefined;\n private gpiochip?: number;\n\n constructor(\n public readonly log: Logging,\n public readonly config: DioderConfig,\n public readonly api: API\n ) {\n this.log.debug('Finished initializing platform: Dioder');\n this.api.on('didFinishLaunching', () => {\n this.log.debug('Executed didFinishLaunching callback');\n const removedAccessories = new Map(this.accessories);\n const newAccessories: PlatformAccessory[] = [];\n // DioderAccessories\n const dioderAccessories: DioderAccessory[] = [];\n this.gpiochip = DEV ? 0 : lg.gpiochipOpen(0);\n for (const c of this.config.leds || []) {\n const uuid = this.api.hap.uuid.generate(JSON.stringify(c.name));\n const existingAccessory = this.accessories.get(uuid) as PlatformAccessory<DioderContext>;\n if (existingAccessory) {\n removedAccessories.delete(uuid);\n this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName);\n const ec = existingAccessory.context.config;\n if (c.rPin !== ec.rPin || c.gPin !== ec.gPin || c.bPin !== ec.bPin || c.freq !== ec.freq) {\n existingAccessory.context.config = c;\n this.log.info('Updating existing accessory config:', c.name);\n this.api.updatePlatformAccessories([existingAccessory]);\n }\n dioderAccessories.push(new DioderAccessory(this, existingAccessory, this.gpiochip));\n } else {\n this.log.info('Adding new accessory:', c.name);\n const accessory = new this.api.platformAccessory<DioderContext>(c.name, uuid);\n accessory.context.config = c;\n dioderAccessories.push(new DioderAccessory(this, accessory, this.gpiochip));\n newAccessories.push(accessory);\n }\n }\n // RainbowAccessory\n if (this.config.rainbowAnim?.enabled) {\n const uuid = this.api.hap.uuid.generate('Rainbow Effect');\n const existingAccessory = this.accessories.get(uuid);\n if (existingAccessory) {\n removedAccessories.delete(uuid);\n this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName);\n // oxlint-disable-next-line no-new\n new RainbowAccessory(this, existingAccessory, dioderAccessories);\n } else {\n this.log.info('Adding new accessory: Rainbow Effect');\n const accessory = new this.api.platformAccessory('Rainbow Effect', uuid);\n // oxlint-disable-next-line no-new\n new RainbowAccessory(this, accessory, dioderAccessories);\n newAccessories.push(accessory);\n }\n }\n // GradientAccessory\n for (const c of this.config.gradientAnim || []) {\n const uuid = this.api.hap.uuid.generate(JSON.stringify(c.name));\n const existingAccessory = this.accessories.get(uuid) as PlatformAccessory<GradiantContext>;\n if (existingAccessory) {\n removedAccessories.delete(uuid);\n this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName);\n const ec = existingAccessory.context.config;\n if (c.colors.toString() !== ec.colors.toString()) {\n existingAccessory.context.config = c;\n this.log.info('Updating existing accessory config:', c.name);\n this.api.updatePlatformAccessories([existingAccessory]);\n }\n // oxlint-disable-next-line no-new\n new GradientAccessory(this, existingAccessory, dioderAccessories);\n } else {\n this.log.info('Adding new gradient accessory:', c.name);\n const accessory = new this.api.platformAccessory<GradiantContext>(c.name, uuid);\n accessory.context.config = c;\n // oxlint-disable-next-line no-new\n new GradientAccessory(this, accessory, dioderAccessories);\n newAccessories.push(accessory);\n }\n }\n // removed unused Accessories\n if (removedAccessories.size > 0) {\n const ra = Array.from(removedAccessories).map(([_k, v]) => v);\n this.log.warn(\n 'removing unused accessories',\n ra.map(a => `${a.displayName} (${a.UUID})`)\n );\n this.api.unregisterPlatformAccessories(PLUGIN_NAME, 'Dioder', ra);\n }\n if (newAccessories.length > 0) {\n this.log.info(\n 'added new accessories',\n newAccessories.map(a => `${a.displayName} (${a.UUID})`)\n );\n this.api.registerPlatformAccessories(PLUGIN_NAME, 'Dioder', newAccessories);\n }\n });\n this.api.on('shutdown', () => {\n if (!DEV && this.gpiochip !== undefined) {\n lg.gpiochipClose(this.gpiochip);\n }\n });\n }\n\n configureAccessory(accessory: PlatformAccessory): void {\n this.log.info('Loading accessory from cache:', accessory.displayName, accessory.UUID);\n this.accessories.set(accessory.UUID, accessory);\n }\n\n // oxlint-disable-next-line promise/prefer-await-to-callbacks\n setAnimationCancel(callback: () => void): void {\n if (this.animationCancel !== undefined) {\n (this.animationCancel as () => void)();\n }\n this.animationCancel = callback;\n }\n\n isAnimationRunning(): boolean {\n return this.animationCancel !== undefined;\n }\n\n stopAnimation(): void {\n if (this.animationCancel !== undefined) {\n (this.animationCancel as () => void)();\n this.animationCancel = undefined;\n }\n }\n}\n","import { colord, type HsvColor } from 'colord';\nimport type { MatterAccessory, Logging, API, MatterRequests } from 'homebridge';\nimport lg from 'lgpio';\n\nimport type { LedConfig } from './DioderPlatform';\n\nconst MIN_PWM = 0.5; // min pwm to get actually light from dioder, depends on PWM_RANGE\nconst PWM_FREQUENCY = 10000;\nconst GAMMA_COR = 2.8;\n\nexport default class DioderAccessory {\n private readonly accessory: MatterAccessory<Record<string, never>>;\n\n constructor(\n private readonly api: API,\n private readonly log: Logging,\n private readonly gpiochip: number,\n private readonly config: LedConfig,\n accessory?: MatterAccessory<Record<string, never>>\n ) {\n this.accessory = accessory ?? {\n UUID: this.api.hap.uuid.generate(this.config.name),\n displayName: this.config.name,\n deviceType: this.api.matter.deviceTypes.ExtendedColorLight,\n serialNumber: '42',\n manufacturer: 'Silizia',\n model: 'Fancy LED',\n clusters: {\n onOff: { onOff: false },\n levelControl: { currentLevel: 254, minLevel: 1, maxLevel: 254 },\n colorControl: { currentHue: 0, currentSaturation: 254, colorMode: this.api.matter.types.ColorControl.ColorMode.CurrentHueAndCurrentSaturation },\n },\n handlers: {\n onOff: { on: (): Promise<void> => this.handleOn(), off: (): void => this.handleOff() },\n levelControl: { moveToLevelWithOnOff: (request): void => this.handleSetLevel(request) },\n colorControl: { moveToHueAndSaturationLogic: (request): void => this.handleSetHueSaturation(request) },\n },\n context: {},\n };\n\n if (!DEV) {\n lg.gpioClaimOutput(gpiochip, this.config.rPin);\n lg.gpioClaimOutput(gpiochip, this.config.gPin);\n lg.gpioClaimOutput(gpiochip, this.config.bPin);\n }\n }\n\n getBrightness(): number {\n return (this.accessory?.clusters?.levelControl?.currentLevel ?? 254 / 254) * 100;\n }\n\n getHsv(): HsvColor {\n const mh = this.accessory?.clusters?.colorControl?.currentHue ?? 0;\n const ms = this.accessory?.clusters?.colorControl?.currentSaturation ?? 254;\n const v = this.getBrightness();\n return { h: (mh / 254) * 360, s: (ms / 254) * 100, v };\n }\n\n pwm(r: number, g: number, b: number): void {\n if (DEV) {\n this.log.info(`pwm r: ${r}, g: ${g}, b: ${b} for gpiochip: ${this.gpiochip} with freq: ${this.config.freq ?? PWM_FREQUENCY}`);\n this.log.info(`rpin ${this.config.rPin} to ${r === 0 ? 'off' : (r / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM}`);\n this.log.info(`gpin ${this.config.gPin} to ${g === 0 ? 'off' : (g / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM}`);\n this.log.info(`bpin ${this.config.bPin} to ${b === 0 ? 'off' : (b / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM}`);\n } else {\n lg.txPwm(this.gpiochip, this.config.rPin, r === 0 ? 0 : (this.config.freq ?? PWM_FREQUENCY), (r / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM, 0, 0);\n lg.txPwm(this.gpiochip, this.config.gPin, g === 0 ? 0 : (this.config.freq ?? PWM_FREQUENCY), (g / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM, 0, 0);\n lg.txPwm(this.gpiochip, this.config.bPin, b === 0 ? 0 : (this.config.freq ?? PWM_FREQUENCY), (b / 255) ** GAMMA_COR * (100 - MIN_PWM) + MIN_PWM, 0, 0);\n }\n }\n\n setHSV(c: HsvColor): void {\n if (c.v > 0) {\n const { r, g, b } = colord(c).toRgb();\n this.pwm(r, g, b);\n this.log.info(`set ${this.config.name} r: ${r}, g: ${g}, b: ${b} or h: ${c.h}, s: ${c.s}, v: ${c.v}`);\n } else {\n this.log.warn('Skipping color change while light bulb being off');\n }\n }\n\n // oxlint-disable-next-line typescript/require-await\n private async handleOn(): Promise<void> {\n this.log.info(`${this.config.name}: turning on.`);\n const hsv = this.getHsv();\n /*! if (hsv.v === 0) {\n await this.api.matter.updateAccessoryState(\n this.accessory.UUID,\n this.api.matter.clusterNames.LevelControl,\n { currentLevel: 254 }\n );\n hsv.v = 100;\n }*/\n this.setHSV(hsv);\n }\n\n private handleOff(): void {\n this.log.info(`${this.config.name}: turning off.`);\n this.pwm(0, 0, 0);\n }\n\n private handleSetLevel(request: MatterRequests.MoveToLevel): void {\n this.log.info(`${this.config.name}: MoveToLevel request: ${JSON.stringify(request)}`);\n const { level /* transitionTime */ } = request;\n const hsv = this.getHsv();\n hsv.v = (level / 254) * 100;\n this.setHSV(hsv);\n this.log.info(`${this.config.name}: setting brightness to ${hsv.v}%.`);\n }\n\n private handleSetHueSaturation(request: { hue: number; saturation: number; transitionTime: number }): void {\n this.log.info(`${this.config.name}: MoveToHueAndSaturation request: ${JSON.stringify(request)}`);\n const { hue, saturation /* transitionTime */ } = request;\n const hsv = { h: (hue / 254) * 360, s: (saturation / 254) * 100, v: this.getBrightness() };\n this.setHSV(hsv);\n this.log.info(`${this.config.name}: setting color to h: ${hsv.h}°, s: ${hsv.s}%, v: ${hsv.v}%.`);\n }\n\n getAccessory(): MatterAccessory<Record<string, never>> {\n return this.accessory;\n }\n}\n","import type { MatterAccessory, API, Logging, PlatformConfig, DynamicPlatformPlugin } from 'homebridge';\nimport lg from 'lgpio';\n\nimport DioderAccessory from './DioderAccessory';\n\ndeclare global {\n var DEV: boolean;\n}\n\nexport interface LedConfig {\n name: string;\n rPin: number;\n gPin: number;\n bPin: number;\n freq: number;\n}\n\ninterface GradiantConfig {\n name: string;\n colors: string[];\n}\n\ninterface DioderConfig extends PlatformConfig {\n leds: LedConfig[];\n gradientAnim: GradiantConfig[];\n rainbowAnim: { enabled: boolean };\n}\n\nconst PLUGIN_NAME = '@silizia/homebridge-dioder';\n\nexport default class DioderPlatform implements DynamicPlatformPlugin {\n public readonly accessories: Map<string, MatterAccessory> = new Map();\n public readonly outdatedAccessories: MatterAccessory<Record<string, never>>[] = [];\n private gpiochip?: number;\n\n constructor(\n public readonly log: Logging,\n public readonly config: DioderConfig,\n public readonly api: API\n ) {\n this.log.debug('Finished initializing platform: Dioder');\n this.api.on('didFinishLaunching', () => {\n this.log.debug('Executed didFinishLaunching callback');\n const removedAccessories = new Map(this.accessories);\n const newAccessories: MatterAccessory[] = [];\n // DioderAccessories\n this.gpiochip = DEV ? 0 : lg.gpiochipOpen(0);\n for (const c of this.config.leds || []) {\n const uuid = this.api.hap.uuid.generate(JSON.stringify(c.name));\n const existingAccessory = this.accessories.get(uuid) as MatterAccessory<Record<string, never>>;\n if (existingAccessory) {\n removedAccessories.delete(uuid);\n this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName);\n // oxlint-disable-next-line no-new\n new DioderAccessory(this.api, this.log, this.gpiochip, c, existingAccessory);\n } else {\n this.log.info('Adding new accessory:', c.name);\n const device = new DioderAccessory(this.api, this.log, this.gpiochip, c);\n newAccessories.push(device.getAccessory());\n }\n }\n // removed unused Accessories\n if (removedAccessories.size > 0) {\n const ra = Array.from(removedAccessories).map(([_k, v]) => v);\n this.log.warn(\n 'removing unused accessories',\n ra.map(a => `${a.displayName} (${a.UUID})`)\n );\n this.api.matter.unregisterPlatformAccessories(PLUGIN_NAME, 'Dioder', ra);\n }\n if (newAccessories.length > 0) {\n this.log.info(\n 'added new accessories',\n newAccessories.map(a => `${a.displayName} (${a.UUID})`)\n );\n this.api.matter.registerPlatformAccessories(PLUGIN_NAME, 'Dioder', newAccessories);\n }\n });\n this.api.on('shutdown', () => {\n if (!DEV && this.gpiochip !== undefined) {\n lg.gpiochipClose(this.gpiochip);\n }\n });\n }\n\n // oxlint-disable-next-line no-empty-function, class-methods-use-this\n configureAccessory(): void {}\n\n configureMatterAccessory(accessory: MatterAccessory): void {\n this.log.info('Loading accessory from cache:', accessory.displayName, accessory.UUID);\n this.accessories.set(accessory.UUID, accessory);\n }\n}\n","import type { API } from 'homebridge';\n\nimport DioderPlatform from './DioderPlatform';\nimport MatterDioderPlatform from './matter/DioderPlatform';\n\nexport default function main(api: API): void {\n if (api.isMatterAvailable() && api.isMatterEnabled()) {\n api.registerPlatform('MatterDioder', MatterDioderPlatform);\n } else {\n api.registerPlatform('Dioder', DioderPlatform);\n }\n}\n"],"mappings":";;;AAOA,MAAMA,YAAU;AAChB,MAAMC,kBAAgB;AACtB,MAAMC,cAAY;AAElB,IAAqBC,oBAArB,MAAqC;CACnC;CACA;CAEA;CACA;CACA;CACA;CAEA,YACE,UACA,WACA,UACA;AAHiB,OAAA,WAAA;AACA,OAAA,YAAA;AACA,OAAA,WAAA;EAEjB,MAAM,EAAE,QAAQ,SAAS;AACzB,OAAK,iBAAiB,IAAI;AAC1B,OAAK,MAAM,SAAS;AAEpB,OAAK,SAAS,UAAU,QAAQ;AAE9B,KAAG,gBAAgB,UAAU,KAAK,OAAO,KAAK;AAC9C,KAAG,gBAAgB,UAAU,KAAK,OAAO,KAAK;AAC9C,KAAG,gBAAgB,UAAU,KAAK,OAAO,KAAK;AAEhD,OAAK,MAAM;GAAE,GAAG;GAAG,GAAG;GAAG,GAAG;GAAG;AAC/B,OAAK,KAAK;AAEV,OAAK,UACF,WAAW,IAAI,QAAQ,qBAAqB,EAC3C,kBAAkB,KAAK,eAAe,cAAc,UAAU,CAC/D,kBAAkB,KAAK,eAAe,OAAO,YAAY,CACzD,kBAAkB,KAAK,eAAe,cAAc,KAAK;AAE5D,OAAK,UAAU,GAAG,kBAAkB,KAAK,UAAU,CAAC;AAEpD,OAAK,aAAa,KAAK,UAAU,WAAW,IAAI,QAAQ,UAAU,IAAI,KAAK,UAAU,WAAW,IAAI,QAAQ,UAAU;AACtH,OAAK,WAAW,kBAAkB,KAAK,eAAe,MAAM,KAAK,OAAO,KAAK;AAE7E,OAAK,WAAW,kBAAkB,KAAK,eAAe,GAAG,CAAC,MAAM,KAAK,MAAM,KAAK,KAAK,CAAC,CAAC,MAAM,KAAK,MAAM,KAAK,KAAK,CAAC;AACnH,OAAK,WAAW,kBAAkB,KAAK,eAAe,WAAW,CAAC,MAAM,KAAK,cAAc,KAAK,KAAK,CAAC;AACtG,OAAK,WAAW,kBAAkB,KAAK,eAAe,IAAI,CAAC,MAAM,KAAK,OAAO,KAAK,KAAK,CAAC;AACxF,OAAK,WAAW,kBAAkB,KAAK,eAAe,WAAW,CAAC,MAAM,KAAK,cAAc,KAAK,KAAK,CAAC;;CAGxG,WAAiB;AACf,OAAK,IAAI,GAAG,GAAG,EAAE;AACjB,mBAAiB;AACf,QAAK,IAAI,KAAK,GAAG,EAAE;AACnB,oBAAiB;AACf,SAAK,IAAI,GAAG,GAAG,EAAE;AACjB,QAAI,KAAK,IAAI,IAAI,EACf,kBAAiB;AACf,UAAK,OAAO,KAAK,IAAI;OACpB,IAAK;MAET,IAAK;KACP,IAAK;AACR,OAAK,IAAI,KAAK,YAAY;;CAG5B,IAAI,GAAW,GAAW,GAAiB;AAOvC,KAAG,MAAM,KAAK,UAAU,KAAK,OAAO,MAAM,MAAM,IAAI,IAAK,KAAK,OAAO,QAAQF,kBAAiB,IAAI,QAAQC,eAAa,MAAMF,aAAWA,WAAS,GAAG,EAAE;AACtJ,KAAG,MAAM,KAAK,UAAU,KAAK,OAAO,MAAM,MAAM,IAAI,IAAK,KAAK,OAAO,QAAQC,kBAAiB,IAAI,QAAQC,eAAa,MAAMF,aAAWA,WAAS,GAAG,EAAE;AACtJ,KAAG,MAAM,KAAK,UAAU,KAAK,OAAO,MAAM,MAAM,IAAI,IAAK,KAAK,OAAO,QAAQC,kBAAiB,IAAI,QAAQC,eAAa,MAAMF,aAAWA,WAAS,GAAG,EAAE;;CAI1J,MAAM,IAA+B;AACnC,OAAK,IAAI,KAAK,SAAS,GAAG;AAC1B,OAAK,KAAK;AACV,MAAI,IAAI;AACN,QAAK,SAAS,eAAe;AAC7B,OAAI,KAAK,IAAI,MAAM,GAAG;AACpB,SAAK,IAAI,IAAI;AACb,SAAK,WAAW,kBAAkB,KAAK,eAAe,YAAY,IAAI;SAEtE,MAAK,OAAO,KAAK,IAAI;SAElB;AACL,QAAK,IAAI,GAAG,GAAG,EAAE;AACjB,QAAK,MAAM;IAAE,GAAG;IAAG,GAAG;IAAG,GAAG;IAAG;;;CAInC,QAAiB;AACf,MAAI,KAAK,SAAS,oBAAoB,CAAE,QAAO;AAC/C,SAAO,KAAK,IAAI,IAAI;;CAGtB,cAAc,GAA8B;AAC1C,OAAK,IAAI,KAAK,iBAAiB,EAAE;AACjC,OAAK,IAAI,IAAI;AACb,OAAK,OAAO,KAAK,IAAI;;CAGvB,OAAO,GAA8B;AACnC,OAAK,IAAI,KAAK,UAAU,EAAE;AAC1B,OAAK,IAAI,IAAI;AACb,OAAK,OAAO,KAAK,IAAI;;CAGvB,cAAc,GAA8B;AAC1C,OAAK,IAAI,IAAI;AACb,OAAK,IAAI,KAAK,iBAAiB,GAAG,KAAK,IAAI,EAAE;AAC7C,OAAK,OAAO,KAAK,IAAI;;CAGvB,OAAO,GAAa,GAAmB;AACrC,MAAI,KAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;GACpC,MAAM,EAAE,GAAG,GAAG,MAAM,OAAO,EAAE,CAAC,OAAO;AACrC,QAAK,IAAI,GAAG,GAAG,EAAE;AACjB,OAAI,CAAC,EAAG,MAAK,IAAI,KAAK,OAAO,KAAK,UAAU,YAAY,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI;QAEvH,MAAK,IAAI,KAAK,mDAAmD;AAEnE,OAAK,MAAM;;CAGb,SAAmB;AACjB,SAAO,KAAK;;CAGd,UAAgB;AACd,OAAK,IAAI,GAAG,GAAG,EAAE;AACjB,OAAK,MAAM;GAAE,GAAG;GAAG,GAAG;GAAG,GAAG;GAAG;;;;;ACxInC,MAAM,WAAW,MAAO;AACxB,MAAM,QAAQ;AACd,MAAM,YAAY;AAElB,IAAqB,oBAArB,MAAuC;CACrC;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CAEA,YACE,UACA,WACA,MACA,MACA;AAJiB,OAAA,WAAA;AACA,OAAA,YAAA;AACD,OAAA,OAAA;EAGhB,MAAM,EAAE,QAAQ,KAAK,SAAS;AAC9B,OAAK,iBAAiB,IAAI;AAC1B,OAAK,MAAM,KAAK,SAAS;AAEzB,OAAK,KAAK;AACV,OAAK,MAAM;AACX,OAAK,aAAa;AAClB,OAAK,SAAS;AACd,OAAK,QAAQ;AACb,OAAK,WAAW,KAAA;AAEhB,OAAK,UACF,WAAW,IAAI,QAAQ,qBAAqB,EAC3C,kBAAkB,KAAK,eAAe,cAAc,UAAU,CAC/D,kBAAkB,KAAK,eAAe,OAAO,YAAY,CACzD,kBAAkB,KAAK,eAAe,cAAc,KAAK;AAE5D,OAAK,UAAU,GAAG,kBAAkB,KAAK,UAAU,CAAC;AAEpD,OAAK,aAAa,KAAK,UAAU,WAAW,IAAI,QAAQ,UAAU,IAAI,KAAK,UAAU,WAAW,IAAI,QAAQ,UAAU;AACtH,OAAK,WAAW,kBAAkB,KAAK,eAAe,MAAM,KAAK;AACjE,OAAK,WAAW,kBAAkB,KAAK,eAAe,GAAG,CAAC,MAAM,KAAK,MAAM,KAAK,KAAK,CAAC,CAAC,MAAM,KAAK,MAAM,KAAK,KAAK,CAAC;AACnH,OAAK,WAAW,kBAAkB,KAAK,eAAe,WAAW,CAAC,MAAM,KAAK,cAAc,KAAK,KAAK,CAAC,CAAC,MAAM,KAAK,cAAc,KAAK,KAAK,CAAC;AAC3I,OAAK,WAAW,kBAAkB,KAAK,eAAe,iBAAiB,CACpE,MAAM,KAAK,oBAAoB,KAAK,KAAK,CAAC,CAC1C,MAAM,KAAK,oBAAoB,KAAK,KAAK,CAAC;AAE7C,OAAK,aAAa,KAAK,UAAU,WAAW,IAAI,QAAQ,IAAI,IAAI,KAAK,UAAU,WAAW,IAAI,QAAQ,IAAI;AAC1G,OAAK,WAAW,kBAAkB,KAAK,eAAe,MAAM,GAAG,KAAK,QAAQ;AAC5E,OAAK,WAAW,kBAAkB,KAAK,eAAe,GAAG,CAAC,MAAM,KAAK,OAAO,KAAK,KAAK,CAAC,CAAC,MAAM,KAAK,OAAO,KAAK,KAAK,CAAC;AACrH,OAAK,WAAW,kBAAkB,KAAK,eAAe,cAAc,CAAC,MAAM,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,MAAM,KAAK,SAAS,KAAK,KAAK,CAAC;;CAGtI,WAAiB;AACf,OAAK,IAAI,KAAK,YAAY;;CAG5B,MAAM,IAA+B;AACnC,OAAK,IAAI,KAAK,iBAAiB,GAAG;AAClC,OAAK,KAAK;AACV,MAAI,IAAI;AACN,OAAI,KAAK,eAAe,KAAK,EAC3B,MAAK,WAAW,kBAAkB,KAAK,eAAe,YAAY,IAAI;AAExE,QAAK,WAAW,qBAAqB,KAAK,eAAe,IAAI,KAAK;AAClE,QAAK,MAAM;AACX,OAAI,KAAK,UAAU,KAAK,EACtB,MAAK,WAAW,kBAAkB,KAAK,eAAe,eAAe,GAAG;AAE1E,QAAK,WAAW,kBAAkB,KAAK,cAAc,EAAE,SAAS;AAChE,QAAK,SAAS,mBAAmB,KAAK,gBAAgB,KAAK,KAAK,CAAC;SAC5D;AACL,QAAK,WAAW,qBAAqB,KAAK,eAAe,IAAI,MAAM;AACnE,QAAK,MAAM;AACX,iBAAc,KAAK,SAAS;AAC5B,QAAK,WAAW,KAAA;AAChB,QAAK,MAAM,OAAO,KAAK,KAAM,KAAI,SAAS;;;CAI9C,QAAiB;AACf,SAAO,KAAK;;CAGd,OAAO,IAA+B;AACpC,OAAK,IAAI,KAAK,kBAAkB,GAAG;AACnC,OAAK,MAAM;AACX,MAAI,IAAI;AACN,OAAI,KAAK,UAAU,KAAK,EACtB,MAAK,WAAW,kBAAkB,KAAK,eAAe,eAAe,GAAG;AAE1E,QAAK,WAAW,kBAAkB,KAAK,cAAc,EAAE,SAAS;AAChE,QAAK,WAAW,qBAAqB,KAAK,eAAe,IAAI,KAAK;AAClE,QAAK,KAAK;AACV,OAAI,KAAK,eAAe,KAAK,EAC3B,MAAK,WAAW,kBAAkB,KAAK,eAAe,YAAY,IAAI;AAExE,QAAK,SAAS,mBAAmB,KAAK,gBAAgB,KAAK,KAAK,CAAC;SAC5D;AACL,iBAAc,KAAK,SAAS;AAC5B,QAAK,WAAW,KAAA;;;CAIpB,SAAkB;AAChB,SAAO,KAAK;;CAGd,cAAc,GAA8B;AAC1C,OAAK,IAAI,KAAK,yBAAyB,EAAE;AACzC,OAAK,aAAa;;CAGpB,gBAAwB;AACtB,SAAO,KAAK;;CAGd,oBAAoB,GAA8B;AAChD,OAAK,IAAI,KAAK,+BAA+B,EAAE;AAC/C,OAAK,SAAU,IAAe;;CAGhC,sBAA8B;AAC5B,SAAO,KAAK,SAAS;;CAGvB,SAAS,GAA8B;AACrC,OAAK,IAAI,KAAK,iBAAiB,EAAE;AACjC,OAAK,QAAS,IAAe;;CAG/B,WAAmB;AACjB,SAAO,KAAK,QAAQ;;CAItB,eAAqB;CAErB,kBAAwB;AACtB,gBAAc,KAAK,SAAS;AAC5B,OAAK,WAAW,KAAA;AAChB,OAAK,WAAW,qBAAqB,KAAK,eAAe,IAAI,MAAM;AACnE,OAAK,WAAW,qBAAqB,KAAK,eAAe,IAAI,MAAM;;;;;AC9IvE,IAAqB,oBAArB,cAA+C,kBAAkB;CAC/D;CACA;CAEA,YAAY,UAA0B,WAA+C,MAAyB;AAC5G,QAAM,UAAU,WAAW,MAAM,UAAU,QAAQ,OAAO,KAAK;AAC/D,OAAK,cAAc;AACnB,OAAK,SAAS,UAAU,QAAQ,OAAO,OAAO,KAAK,MAAc,OAAO,EAAE,CAAC,OAAO,CAAC;;CAGrF,eAAqB;EACnB,MAAM,MAAM,KAAK,KAAK;AACtB,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK;GAC5B,MAAM,OAAO,KAAK,cAAe,IAAI,KAAK,SAAU;GACpD,MAAM,YAAY,KAAK,MAAM,KAAK,GAAG;GACrC,MAAM,aAAa,YAAY,KAAK;GACpC,MAAM,OAAO,OAAO;GACpB,MAAM,IAAI,KAAK,OAAO,WAAW,KAAK,IAAI,QAAQ,KAAK,OAAO,WAAW,IAAI;GAC7E,MAAM,IAAI,KAAK,OAAO,WAAW,KAAK,IAAI,QAAQ,KAAK,OAAO,WAAW,IAAI;GAC7E,MAAM,IAAI,KAAK,OAAO,WAAW,KAAK,IAAI,QAAQ,KAAK,OAAO,WAAW,IAAI;AAC7E,QAAK,KAAK,GAAG,IAAK,IAAI,KAAK,aAAc,KAAM,IAAI,KAAK,aAAc,KAAM,IAAI,KAAK,aAAc,IAAI;;AAEzG,OAAK,eAAe,KAAK,cAAe,KAAK,QAAQ,MAAO,OAAO;;;;;ACxBvE,MAAM,aAAa;AAEnB,IAAqB,mBAArB,cAA8C,kBAAkB;CAC9D;CAEA,YAAY,UAA0B,WAA8B,MAAyB;AAC3F,QAAM,UAAU,WAAW,MAAM,iBAAiB;AAClD,OAAK,aAAa;;CAGpB,eAAqB;AAEnB,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK,QAAQ,IACpC,MAAK,KAAK,GAAG,OAAO;GAAE,IAAI,KAAK,aAAa,IAAI,KAAK,UAAU;GAAK,GAAG;GAAY,GAAG,KAAK;GAAY,EAAE,KAAK;AAEhH,OAAK,cAAc,KAAK,aAAa,KAAK,SAAS;;;;;ACiBvD,MAAMI,gBAAc;AAEpB,IAAqBC,mBAArB,MAAqE;CACnE,8BAA8D,IAAI,KAAK;CACvE,sBAA2D,EAAE;CAC7D,kBAAsC,KAAA;CACtC;CAEA,YACE,KACA,QACA,KACA;AAHgB,OAAA,MAAA;AACA,OAAA,SAAA;AACA,OAAA,MAAA;AAEhB,OAAK,IAAI,MAAM,yCAAyC;AACxD,OAAK,IAAI,GAAG,4BAA4B;AACtC,QAAK,IAAI,MAAM,uCAAuC;GACtD,MAAM,qBAAqB,IAAI,IAAI,KAAK,YAAY;GACpD,MAAM,iBAAsC,EAAE;GAE9C,MAAM,oBAAuC,EAAE;AAC/C,QAAK,WAAqB,GAAG,aAAa,EAAE;AAC5C,QAAK,MAAM,KAAK,KAAK,OAAO,QAAQ,EAAE,EAAE;IACtC,MAAM,OAAO,KAAK,IAAI,IAAI,KAAK,SAAS,KAAK,UAAU,EAAE,KAAK,CAAC;IAC/D,MAAM,oBAAoB,KAAK,YAAY,IAAI,KAAK;AACpD,QAAI,mBAAmB;AACrB,wBAAmB,OAAO,KAAK;AAC/B,UAAK,IAAI,KAAK,4CAA4C,kBAAkB,YAAY;KACxF,MAAM,KAAK,kBAAkB,QAAQ;AACrC,SAAI,EAAE,SAAS,GAAG,QAAQ,EAAE,SAAS,GAAG,QAAQ,EAAE,SAAS,GAAG,QAAQ,EAAE,SAAS,GAAG,MAAM;AACxF,wBAAkB,QAAQ,SAAS;AACnC,WAAK,IAAI,KAAK,uCAAuC,EAAE,KAAK;AAC5D,WAAK,IAAI,0BAA0B,CAAC,kBAAkB,CAAC;;AAEzD,uBAAkB,KAAK,IAAIC,kBAAgB,MAAM,mBAAmB,KAAK,SAAS,CAAC;WAC9E;AACL,UAAK,IAAI,KAAK,yBAAyB,EAAE,KAAK;KAC9C,MAAM,YAAY,IAAI,KAAK,IAAI,kBAAiC,EAAE,MAAM,KAAK;AAC7E,eAAU,QAAQ,SAAS;AAC3B,uBAAkB,KAAK,IAAIA,kBAAgB,MAAM,WAAW,KAAK,SAAS,CAAC;AAC3E,oBAAe,KAAK,UAAU;;;AAIlC,OAAI,KAAK,OAAO,aAAa,SAAS;IACpC,MAAM,OAAO,KAAK,IAAI,IAAI,KAAK,SAAS,iBAAiB;IACzD,MAAM,oBAAoB,KAAK,YAAY,IAAI,KAAK;AACpD,QAAI,mBAAmB;AACrB,wBAAmB,OAAO,KAAK;AAC/B,UAAK,IAAI,KAAK,4CAA4C,kBAAkB,YAAY;AAExF,SAAI,iBAAiB,MAAM,mBAAmB,kBAAkB;WAC3D;AACL,UAAK,IAAI,KAAK,uCAAuC;KACrD,MAAM,YAAY,IAAI,KAAK,IAAI,kBAAkB,kBAAkB,KAAK;AAExE,SAAI,iBAAiB,MAAM,WAAW,kBAAkB;AACxD,oBAAe,KAAK,UAAU;;;AAIlC,QAAK,MAAM,KAAK,KAAK,OAAO,gBAAgB,EAAE,EAAE;IAC9C,MAAM,OAAO,KAAK,IAAI,IAAI,KAAK,SAAS,KAAK,UAAU,EAAE,KAAK,CAAC;IAC/D,MAAM,oBAAoB,KAAK,YAAY,IAAI,KAAK;AACpD,QAAI,mBAAmB;AACrB,wBAAmB,OAAO,KAAK;AAC/B,UAAK,IAAI,KAAK,4CAA4C,kBAAkB,YAAY;KACxF,MAAM,KAAK,kBAAkB,QAAQ;AACrC,SAAI,EAAE,OAAO,UAAU,KAAK,GAAG,OAAO,UAAU,EAAE;AAChD,wBAAkB,QAAQ,SAAS;AACnC,WAAK,IAAI,KAAK,uCAAuC,EAAE,KAAK;AAC5D,WAAK,IAAI,0BAA0B,CAAC,kBAAkB,CAAC;;AAGzD,SAAI,kBAAkB,MAAM,mBAAmB,kBAAkB;WAC5D;AACL,UAAK,IAAI,KAAK,kCAAkC,EAAE,KAAK;KACvD,MAAM,YAAY,IAAI,KAAK,IAAI,kBAAmC,EAAE,MAAM,KAAK;AAC/E,eAAU,QAAQ,SAAS;AAE3B,SAAI,kBAAkB,MAAM,WAAW,kBAAkB;AACzD,oBAAe,KAAK,UAAU;;;AAIlC,OAAI,mBAAmB,OAAO,GAAG;IAC/B,MAAM,KAAK,MAAM,KAAK,mBAAmB,CAAC,KAAK,CAAC,IAAI,OAAO,EAAE;AAC7D,SAAK,IAAI,KACP,+BACA,GAAG,KAAI,MAAK,GAAG,EAAE,YAAY,IAAI,EAAE,KAAK,GAAG,CAC5C;AACD,SAAK,IAAI,8BAA8BF,eAAa,UAAU,GAAG;;AAEnE,OAAI,eAAe,SAAS,GAAG;AAC7B,SAAK,IAAI,KACP,yBACA,eAAe,KAAI,MAAK,GAAG,EAAE,YAAY,IAAI,EAAE,KAAK,GAAG,CACxD;AACD,SAAK,IAAI,4BAA4BA,eAAa,UAAU,eAAe;;IAE7E;AACF,OAAK,IAAI,GAAG,kBAAkB;AAC5B,OAAY,KAAK,aAAa,KAAA,EAC5B,IAAG,cAAc,KAAK,SAAS;IAEjC;;CAGJ,mBAAmB,WAAoC;AACrD,OAAK,IAAI,KAAK,iCAAiC,UAAU,aAAa,UAAU,KAAK;AACrF,OAAK,YAAY,IAAI,UAAU,MAAM,UAAU;;CAIjD,mBAAmB,UAA4B;AAC7C,MAAI,KAAK,oBAAoB,KAAA,EAC1B,MAAK,iBAAgC;AAExC,OAAK,kBAAkB;;CAGzB,qBAA8B;AAC5B,SAAO,KAAK,oBAAoB,KAAA;;CAGlC,gBAAsB;AACpB,MAAI,KAAK,oBAAoB,KAAA,GAAW;AACrC,QAAK,iBAAgC;AACtC,QAAK,kBAAkB,KAAA;;;;;;AC/J7B,MAAM,UAAU;AAChB,MAAM,gBAAgB;AACtB,MAAM,YAAY;AAElB,IAAqB,kBAArB,MAAqC;CACnC;CAEA,YACE,KACA,KACA,UACA,QACA,WACA;AALiB,OAAA,MAAA;AACA,OAAA,MAAA;AACA,OAAA,WAAA;AACA,OAAA,SAAA;AAGjB,OAAK,YAAY,aAAa;GAC5B,MAAM,KAAK,IAAI,IAAI,KAAK,SAAS,KAAK,OAAO,KAAK;GAClD,aAAa,KAAK,OAAO;GACzB,YAAY,KAAK,IAAI,OAAO,YAAY;GACxC,cAAc;GACd,cAAc;GACd,OAAO;GACP,UAAU;IACR,OAAO,EAAE,OAAO,OAAO;IACvB,cAAc;KAAE,cAAc;KAAK,UAAU;KAAG,UAAU;KAAK;IAC/D,cAAc;KAAE,YAAY;KAAG,mBAAmB;KAAK,WAAW,KAAK,IAAI,OAAO,MAAM,aAAa,UAAU;KAAgC;IAChJ;GACD,UAAU;IACR,OAAO;KAAE,UAAyB,KAAK,UAAU;KAAE,WAAiB,KAAK,WAAW;KAAE;IACtF,cAAc,EAAE,uBAAuB,YAAkB,KAAK,eAAe,QAAQ,EAAE;IACvF,cAAc,EAAE,8BAA8B,YAAkB,KAAK,uBAAuB,QAAQ,EAAE;IACvG;GACD,SAAS,EAAE;GACZ;AAGC,KAAG,gBAAgB,UAAU,KAAK,OAAO,KAAK;AAC9C,KAAG,gBAAgB,UAAU,KAAK,OAAO,KAAK;AAC9C,KAAG,gBAAgB,UAAU,KAAK,OAAO,KAAK;;CAIlD,gBAAwB;AACtB,UAAQ,KAAK,WAAW,UAAU,cAAc,gBAAgB,MAAM,OAAO;;CAG/E,SAAmB;EACjB,MAAM,KAAK,KAAK,WAAW,UAAU,cAAc,cAAc;EACjE,MAAM,KAAK,KAAK,WAAW,UAAU,cAAc,qBAAqB;EACxE,MAAM,IAAI,KAAK,eAAe;AAC9B,SAAO;GAAE,GAAI,KAAK,MAAO;GAAK,GAAI,KAAK,MAAO;GAAK;GAAG;;CAGxD,IAAI,GAAW,GAAW,GAAiB;AAOvC,KAAG,MAAM,KAAK,UAAU,KAAK,OAAO,MAAM,MAAM,IAAI,IAAK,KAAK,OAAO,QAAQ,gBAAiB,IAAI,QAAQ,aAAa,MAAM,WAAW,SAAS,GAAG,EAAE;AACtJ,KAAG,MAAM,KAAK,UAAU,KAAK,OAAO,MAAM,MAAM,IAAI,IAAK,KAAK,OAAO,QAAQ,gBAAiB,IAAI,QAAQ,aAAa,MAAM,WAAW,SAAS,GAAG,EAAE;AACtJ,KAAG,MAAM,KAAK,UAAU,KAAK,OAAO,MAAM,MAAM,IAAI,IAAK,KAAK,OAAO,QAAQ,gBAAiB,IAAI,QAAQ,aAAa,MAAM,WAAW,SAAS,GAAG,EAAE;;CAI1J,OAAO,GAAmB;AACxB,MAAI,EAAE,IAAI,GAAG;GACX,MAAM,EAAE,GAAG,GAAG,MAAM,OAAO,EAAE,CAAC,OAAO;AACrC,QAAK,IAAI,GAAG,GAAG,EAAE;AACjB,QAAK,IAAI,KAAK,OAAO,KAAK,OAAO,KAAK,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI;QAErG,MAAK,IAAI,KAAK,mDAAmD;;CAKrE,MAAc,WAA0B;AACtC,OAAK,IAAI,KAAK,GAAG,KAAK,OAAO,KAAK,eAAe;EACjD,MAAM,MAAM,KAAK,QAAQ;;;;;;;;;AASzB,OAAK,OAAO,IAAI;;CAGlB,YAA0B;AACxB,OAAK,IAAI,KAAK,GAAG,KAAK,OAAO,KAAK,gBAAgB;AAClD,OAAK,IAAI,GAAG,GAAG,EAAE;;CAGnB,eAAuB,SAA2C;AAChE,OAAK,IAAI,KAAK,GAAG,KAAK,OAAO,KAAK,yBAAyB,KAAK,UAAU,QAAQ,GAAG;EACrF,MAAM,EAAE,UAA+B;EACvC,MAAM,MAAM,KAAK,QAAQ;AACzB,MAAI,IAAK,QAAQ,MAAO;AACxB,OAAK,OAAO,IAAI;AAChB,OAAK,IAAI,KAAK,GAAG,KAAK,OAAO,KAAK,0BAA0B,IAAI,EAAE,IAAI;;CAGxE,uBAA+B,SAA4E;AACzG,OAAK,IAAI,KAAK,GAAG,KAAK,OAAO,KAAK,oCAAoC,KAAK,UAAU,QAAQ,GAAG;EAChG,MAAM,EAAE,KAAK,eAAoC;EACjD,MAAM,MAAM;GAAE,GAAI,MAAM,MAAO;GAAK,GAAI,aAAa,MAAO;GAAK,GAAG,KAAK,eAAe;GAAE;AAC1F,OAAK,OAAO,IAAI;AAChB,OAAK,IAAI,KAAK,GAAG,KAAK,OAAO,KAAK,wBAAwB,IAAI,EAAE,QAAQ,IAAI,EAAE,QAAQ,IAAI,EAAE,IAAI;;CAGlG,eAAuD;AACrD,SAAO,KAAK;;;;;AC3FhB,MAAM,cAAc;AAEpB,IAAqB,iBAArB,MAAqE;CACnE,8BAA4D,IAAI,KAAK;CACrE,sBAAgF,EAAE;CAClF;CAEA,YACE,KACA,QACA,KACA;AAHgB,OAAA,MAAA;AACA,OAAA,SAAA;AACA,OAAA,MAAA;AAEhB,OAAK,IAAI,MAAM,yCAAyC;AACxD,OAAK,IAAI,GAAG,4BAA4B;AACtC,QAAK,IAAI,MAAM,uCAAuC;GACtD,MAAM,qBAAqB,IAAI,IAAI,KAAK,YAAY;GACpD,MAAM,iBAAoC,EAAE;AAE5C,QAAK,WAAqB,GAAG,aAAa,EAAE;AAC5C,QAAK,MAAM,KAAK,KAAK,OAAO,QAAQ,EAAE,EAAE;IACtC,MAAM,OAAO,KAAK,IAAI,IAAI,KAAK,SAAS,KAAK,UAAU,EAAE,KAAK,CAAC;IAC/D,MAAM,oBAAoB,KAAK,YAAY,IAAI,KAAK;AACpD,QAAI,mBAAmB;AACrB,wBAAmB,OAAO,KAAK;AAC/B,UAAK,IAAI,KAAK,4CAA4C,kBAAkB,YAAY;AAExF,SAAI,gBAAgB,KAAK,KAAK,KAAK,KAAK,KAAK,UAAU,GAAG,kBAAkB;WACvE;AACL,UAAK,IAAI,KAAK,yBAAyB,EAAE,KAAK;KAC9C,MAAM,SAAS,IAAI,gBAAgB,KAAK,KAAK,KAAK,KAAK,KAAK,UAAU,EAAE;AACxE,oBAAe,KAAK,OAAO,cAAc,CAAC;;;AAI9C,OAAI,mBAAmB,OAAO,GAAG;IAC/B,MAAM,KAAK,MAAM,KAAK,mBAAmB,CAAC,KAAK,CAAC,IAAI,OAAO,EAAE;AAC7D,SAAK,IAAI,KACP,+BACA,GAAG,KAAI,MAAK,GAAG,EAAE,YAAY,IAAI,EAAE,KAAK,GAAG,CAC5C;AACD,SAAK,IAAI,OAAO,8BAA8B,aAAa,UAAU,GAAG;;AAE1E,OAAI,eAAe,SAAS,GAAG;AAC7B,SAAK,IAAI,KACP,yBACA,eAAe,KAAI,MAAK,GAAG,EAAE,YAAY,IAAI,EAAE,KAAK,GAAG,CACxD;AACD,SAAK,IAAI,OAAO,4BAA4B,aAAa,UAAU,eAAe;;IAEpF;AACF,OAAK,IAAI,GAAG,kBAAkB;AAC5B,OAAY,KAAK,aAAa,KAAA,EAC5B,IAAG,cAAc,KAAK,SAAS;IAEjC;;CAIJ,qBAA2B;CAE3B,yBAAyB,WAAkC;AACzD,OAAK,IAAI,KAAK,iCAAiC,UAAU,aAAa,UAAU,KAAK;AACrF,OAAK,YAAY,IAAI,UAAU,MAAM,UAAU;;;;;ACrFnD,SAAwB,KAAK,KAAgB;AAC3C,KAAI,IAAI,mBAAmB,IAAI,IAAI,iBAAiB,CAClD,KAAI,iBAAiB,gBAAgBG,eAAqB;KAE1D,KAAI,iBAAiB,UAAUC,iBAAe"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silizia/homebridge-dioder",
|
|
3
3
|
"displayName": "Homebridge Dioder",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.2",
|
|
5
5
|
"description": "Homebridge plugin to control Dioder LED strips over pigpio pins",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"homebridge-plugin"
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"scripts": {
|
|
25
25
|
"prepare": "rolldown -c",
|
|
26
26
|
"build": "rolldown -c",
|
|
27
|
-
"watch": "rolldown -c -w",
|
|
27
|
+
"watch": "DEV=true rolldown -c -w",
|
|
28
28
|
"test": "oxlint && oxfmt --check",
|
|
29
29
|
"lint": "oxlint",
|
|
30
30
|
"format": "oxfmt",
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "^24.12.0",
|
|
39
|
-
"homebridge": "^2.0.0-beta.
|
|
39
|
+
"homebridge": "^2.0.0-beta.83",
|
|
40
40
|
"oxfmt": "^0.43.0",
|
|
41
41
|
"oxlint": "^1.58.0",
|
|
42
|
-
"oxlint-tsgolint": "^0.
|
|
43
|
-
"rolldown": "^1.0.0-rc.
|
|
42
|
+
"oxlint-tsgolint": "^0.19.0",
|
|
43
|
+
"rolldown": "^1.0.0-rc.13"
|
|
44
44
|
},
|
|
45
45
|
"engines": {
|
|
46
46
|
"homebridge": "^1.3.5 || ^2.0.0-beta.0",
|