matterbridge-dyson-robot 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/CHANGELOG.md +15 -0
- package/LICENSE +14 -0
- package/README.md +365 -0
- package/dist/async-eventemitter.d.ts +9 -0
- package/dist/async-eventemitter.d.ts.map +1 -0
- package/dist/async-eventemitter.js +35 -0
- package/dist/async-eventemitter.js.map +1 -0
- package/dist/check-configuration.d.ts +5 -0
- package/dist/check-configuration.d.ts.map +1 -0
- package/dist/check-configuration.js +35 -0
- package/dist/check-configuration.js.map +1 -0
- package/dist/check-versions.d.ts +3 -0
- package/dist/check-versions.d.ts.map +1 -0
- package/dist/check-versions.js +31 -0
- package/dist/check-versions.js.map +1 -0
- package/dist/config-types.d.ts +48 -0
- package/dist/config-types.d.ts.map +1 -0
- package/dist/config-types.js +4 -0
- package/dist/config-types.js.map +1 -0
- package/dist/decorator-changed.d.ts +16 -0
- package/dist/decorator-changed.d.ts.map +1 -0
- package/dist/decorator-changed.js +62 -0
- package/dist/decorator-changed.js.map +1 -0
- package/dist/dyson-360-msg-types.d.ts +113 -0
- package/dist/dyson-360-msg-types.d.ts.map +1 -0
- package/dist/dyson-360-msg-types.js +4 -0
- package/dist/dyson-360-msg-types.js.map +1 -0
- package/dist/dyson-360-types.d.ts +76 -0
- package/dist/dyson-360-types.d.ts.map +1 -0
- package/dist/dyson-360-types.js +72 -0
- package/dist/dyson-360-types.js.map +1 -0
- package/dist/dyson-air-msg-types.d.ts +99 -0
- package/dist/dyson-air-msg-types.d.ts.map +1 -0
- package/dist/dyson-air-msg-types.js +4 -0
- package/dist/dyson-air-msg-types.js.map +1 -0
- package/dist/dyson-air-sensor-types.d.ts +59 -0
- package/dist/dyson-air-sensor-types.d.ts.map +1 -0
- package/dist/dyson-air-sensor-types.js +4 -0
- package/dist/dyson-air-sensor-types.js.map +1 -0
- package/dist/dyson-air-state-types.d.ts +96 -0
- package/dist/dyson-air-state-types.d.ts.map +1 -0
- package/dist/dyson-air-state-types.js +4 -0
- package/dist/dyson-air-state-types.js.map +1 -0
- package/dist/dyson-air-types.d.ts +325 -0
- package/dist/dyson-air-types.d.ts.map +1 -0
- package/dist/dyson-air-types.js +382 -0
- package/dist/dyson-air-types.js.map +1 -0
- package/dist/dyson-device-360-base.d.ts +35 -0
- package/dist/dyson-device-360-base.d.ts.map +1 -0
- package/dist/dyson-device-360-base.js +233 -0
- package/dist/dyson-device-360-base.js.map +1 -0
- package/dist/dyson-device-360-commands.d.ts +7 -0
- package/dist/dyson-device-360-commands.d.ts.map +1 -0
- package/dist/dyson-device-360-commands.js +129 -0
- package/dist/dyson-device-360-commands.js.map +1 -0
- package/dist/dyson-device-360-faults-table.d.ts +20 -0
- package/dist/dyson-device-360-faults-table.d.ts.map +1 -0
- package/dist/dyson-device-360-faults-table.js +161 -0
- package/dist/dyson-device-360-faults-table.js.map +1 -0
- package/dist/dyson-device-360-faults.d.ts +10 -0
- package/dist/dyson-device-360-faults.d.ts.map +1 -0
- package/dist/dyson-device-360-faults.js +123 -0
- package/dist/dyson-device-360-faults.js.map +1 -0
- package/dist/dyson-device-360.d.ts +38 -0
- package/dist/dyson-device-360.d.ts.map +1 -0
- package/dist/dyson-device-360.js +45 -0
- package/dist/dyson-device-360.js.map +1 -0
- package/dist/dyson-device-air-base.d.ts +41 -0
- package/dist/dyson-device-air-base.d.ts.map +1 -0
- package/dist/dyson-device-air-base.js +446 -0
- package/dist/dyson-device-air-base.js.map +1 -0
- package/dist/dyson-device-air-heat.d.ts +52 -0
- package/dist/dyson-device-air-heat.d.ts.map +1 -0
- package/dist/dyson-device-air-heat.js +71 -0
- package/dist/dyson-device-air-heat.js.map +1 -0
- package/dist/dyson-device-air-quality.d.ts +7 -0
- package/dist/dyson-device-air-quality.d.ts.map +1 -0
- package/dist/dyson-device-air-quality.js +101 -0
- package/dist/dyson-device-air-quality.js.map +1 -0
- package/dist/dyson-device-air.d.ts +216 -0
- package/dist/dyson-device-air.d.ts.map +1 -0
- package/dist/dyson-device-air.js +80 -0
- package/dist/dyson-device-air.js.map +1 -0
- package/dist/dyson-device-base.d.ts +49 -0
- package/dist/dyson-device-base.d.ts.map +1 -0
- package/dist/dyson-device-base.js +46 -0
- package/dist/dyson-device-base.js.map +1 -0
- package/dist/dyson-device.d.ts +5 -0
- package/dist/dyson-device.d.ts.map +1 -0
- package/dist/dyson-device.js +43 -0
- package/dist/dyson-device.js.map +1 -0
- package/dist/dyson-mqtt-360.d.ts +16 -0
- package/dist/dyson-mqtt-360.d.ts.map +1 -0
- package/dist/dyson-mqtt-360.js +83 -0
- package/dist/dyson-mqtt-360.js.map +1 -0
- package/dist/dyson-mqtt-air.d.ts +48 -0
- package/dist/dyson-mqtt-air.d.ts.map +1 -0
- package/dist/dyson-mqtt-air.js +216 -0
- package/dist/dyson-mqtt-air.js.map +1 -0
- package/dist/dyson-mqtt-config.d.ts +6 -0
- package/dist/dyson-mqtt-config.d.ts.map +1 -0
- package/dist/dyson-mqtt-config.js +47 -0
- package/dist/dyson-mqtt-config.js.map +1 -0
- package/dist/dyson-mqtt-connect.d.ts +22 -0
- package/dist/dyson-mqtt-connect.d.ts.map +1 -0
- package/dist/dyson-mqtt-connect.js +145 -0
- package/dist/dyson-mqtt-connect.js.map +1 -0
- package/dist/dyson-mqtt-filter.d.ts +10 -0
- package/dist/dyson-mqtt-filter.d.ts.map +1 -0
- package/dist/dyson-mqtt-filter.js +25 -0
- package/dist/dyson-mqtt-filter.js.map +1 -0
- package/dist/dyson-mqtt-parse.d.ts +16 -0
- package/dist/dyson-mqtt-parse.d.ts.map +1 -0
- package/dist/dyson-mqtt-parse.js +100 -0
- package/dist/dyson-mqtt-parse.js.map +1 -0
- package/dist/dyson-mqtt-subscribe.d.ts +28 -0
- package/dist/dyson-mqtt-subscribe.d.ts.map +1 -0
- package/dist/dyson-mqtt-subscribe.js +85 -0
- package/dist/dyson-mqtt-subscribe.js.map +1 -0
- package/dist/dyson-mqtt.d.ts +51 -0
- package/dist/dyson-mqtt.d.ts.map +1 -0
- package/dist/dyson-mqtt.js +138 -0
- package/dist/dyson-mqtt.js.map +1 -0
- package/dist/dyson-types.d.ts +18 -0
- package/dist/dyson-types.d.ts.map +1 -0
- package/dist/dyson-types.js +20 -0
- package/dist/dyson-types.js.map +1 -0
- package/dist/endpoint-360-behavior.d.ts +55 -0
- package/dist/endpoint-360-behavior.d.ts.map +1 -0
- package/dist/endpoint-360-behavior.js +156 -0
- package/dist/endpoint-360-behavior.js.map +1 -0
- package/dist/endpoint-360-rvc.d.ts +14 -0
- package/dist/endpoint-360-rvc.d.ts.map +1 -0
- package/dist/endpoint-360-rvc.js +149 -0
- package/dist/endpoint-360-rvc.js.map +1 -0
- package/dist/endpoint-360.d.ts +35 -0
- package/dist/endpoint-360.d.ts.map +1 -0
- package/dist/endpoint-360.js +197 -0
- package/dist/endpoint-360.js.map +1 -0
- package/dist/endpoint-air-purifier.d.ts +24 -0
- package/dist/endpoint-air-purifier.d.ts.map +1 -0
- package/dist/endpoint-air-purifier.js +97 -0
- package/dist/endpoint-air-purifier.js.map +1 -0
- package/dist/endpoint-air-quality.d.ts +11 -0
- package/dist/endpoint-air-quality.d.ts.map +1 -0
- package/dist/endpoint-air-quality.js +104 -0
- package/dist/endpoint-air-quality.js.map +1 -0
- package/dist/endpoint-air-thermostat.d.ts +358 -0
- package/dist/endpoint-air-thermostat.d.ts.map +1 -0
- package/dist/endpoint-air-thermostat.js +67 -0
- package/dist/endpoint-air-thermostat.js.map +1 -0
- package/dist/endpoint-air.d.ts +125 -0
- package/dist/endpoint-air.d.ts.map +1 -0
- package/dist/endpoint-air.js +459 -0
- package/dist/endpoint-air.js.map +1 -0
- package/dist/endpoint-base.d.ts +36 -0
- package/dist/endpoint-base.d.ts.map +1 -0
- package/dist/endpoint-base.js +137 -0
- package/dist/endpoint-base.js.map +1 -0
- package/dist/error-360.d.ts +35 -0
- package/dist/error-360.d.ts.map +1 -0
- package/dist/error-360.js +105 -0
- package/dist/error-360.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/logger-filter.d.ts +23 -0
- package/dist/logger-filter.d.ts.map +1 -0
- package/dist/logger-filter.js +104 -0
- package/dist/logger-filter.js.map +1 -0
- package/dist/logger-options.d.ts +18 -0
- package/dist/logger-options.d.ts.map +1 -0
- package/dist/logger-options.js +41 -0
- package/dist/logger-options.js.map +1 -0
- package/dist/logger-prefix.d.ts +12 -0
- package/dist/logger-prefix.d.ts.map +1 -0
- package/dist/logger-prefix.js +37 -0
- package/dist/logger-prefix.js.map +1 -0
- package/dist/periodic.d.ts +31 -0
- package/dist/periodic.d.ts.map +1 -0
- package/dist/periodic.js +102 -0
- package/dist/periodic.js.map +1 -0
- package/dist/platform.d.ts +18 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +138 -0
- package/dist/platform.js.map +1 -0
- package/dist/settings.d.ts +9 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +28 -0
- package/dist/settings.js.map +1 -0
- package/dist/ti/config-types-ti.d.ts +16 -0
- package/dist/ti/config-types-ti.d.ts.map +1 -0
- package/dist/ti/config-types-ti.js +65 -0
- package/dist/ti/config-types-ti.js.map +1 -0
- package/dist/ti/config-types.d.ts +37 -0
- package/dist/ti/config-types.d.ts.map +1 -0
- package/dist/ti/config-types.js +11 -0
- package/dist/ti/config-types.js.map +1 -0
- package/dist/ti/dyson-360-msg-types-ti.d.ts +22 -0
- package/dist/ti/dyson-360-msg-types-ti.d.ts.map +1 -0
- package/dist/ti/dyson-360-msg-types-ti.js +134 -0
- package/dist/ti/dyson-360-msg-types-ti.js.map +1 -0
- package/dist/ti/dyson-360-msg-types.d.ts +55 -0
- package/dist/ti/dyson-360-msg-types.d.ts.map +1 -0
- package/dist/ti/dyson-360-msg-types.js +13 -0
- package/dist/ti/dyson-360-msg-types.js.map +1 -0
- package/dist/ti/dyson-360-types-ti.d.ts +17 -0
- package/dist/ti/dyson-360-types-ti.d.ts.map +1 -0
- package/dist/ti/dyson-360-types-ti.js +94 -0
- package/dist/ti/dyson-360-types-ti.js.map +1 -0
- package/dist/ti/dyson-360-types.d.ts +40 -0
- package/dist/ti/dyson-360-types.d.ts.map +1 -0
- package/dist/ti/dyson-360-types.js +11 -0
- package/dist/ti/dyson-360-types.js.map +1 -0
- package/dist/ti/dyson-air-msg-types-ti.d.ts +19 -0
- package/dist/ti/dyson-air-msg-types-ti.d.ts.map +1 -0
- package/dist/ti/dyson-air-msg-types-ti.js +115 -0
- package/dist/ti/dyson-air-msg-types-ti.js.map +1 -0
- package/dist/ti/dyson-air-msg-types.d.ts +46 -0
- package/dist/ti/dyson-air-msg-types.d.ts.map +1 -0
- package/dist/ti/dyson-air-msg-types.js +15 -0
- package/dist/ti/dyson-air-msg-types.js.map +1 -0
- package/dist/ti/dyson-air-sensor-types-ti.d.ts +9 -0
- package/dist/ti/dyson-air-sensor-types-ti.d.ts.map +1 -0
- package/dist/ti/dyson-air-sensor-types-ti.js +68 -0
- package/dist/ti/dyson-air-sensor-types-ti.js.map +1 -0
- package/dist/ti/dyson-air-sensor-types.d.ts +16 -0
- package/dist/ti/dyson-air-sensor-types.d.ts.map +1 -0
- package/dist/ti/dyson-air-sensor-types.js +12 -0
- package/dist/ti/dyson-air-sensor-types.js.map +1 -0
- package/dist/ti/dyson-air-state-types-ti.d.ts +9 -0
- package/dist/ti/dyson-air-state-types-ti.d.ts.map +1 -0
- package/dist/ti/dyson-air-state-types-ti.js +105 -0
- package/dist/ti/dyson-air-state-types-ti.js.map +1 -0
- package/dist/ti/dyson-air-state-types.d.ts +16 -0
- package/dist/ti/dyson-air-state-types.d.ts.map +1 -0
- package/dist/ti/dyson-air-state-types.js +12 -0
- package/dist/ti/dyson-air-state-types.js.map +1 -0
- package/dist/ti/dyson-air-types-ti.d.ts +59 -0
- package/dist/ti/dyson-air-types-ti.d.ts.map +1 -0
- package/dist/ti/dyson-air-types-ti.js +385 -0
- package/dist/ti/dyson-air-types-ti.js.map +1 -0
- package/dist/ti/dyson-air-types.d.ts +166 -0
- package/dist/ti/dyson-air-types.d.ts.map +1 -0
- package/dist/ti/dyson-air-types.js +11 -0
- package/dist/ti/dyson-air-types.js.map +1 -0
- package/dist/ti/dyson-types-ti.d.ts +10 -0
- package/dist/ti/dyson-types-ti.d.ts.map +1 -0
- package/dist/ti/dyson-types-ti.js +29 -0
- package/dist/ti/dyson-types-ti.js.map +1 -0
- package/dist/ti/dyson-types.d.ts +19 -0
- package/dist/ti/dyson-types.d.ts.map +1 -0
- package/dist/ti/dyson-types.js +11 -0
- package/dist/ti/dyson-types.js.map +1 -0
- package/dist/utils.d.ts +24 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +150 -0
- package/dist/utils.js.map +1 -0
- package/matterbridge-dyson-robot.schema.json +359 -0
- package/package.json +93 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dyson-types.d.ts","sourceRoot":"","sources":["../../src/ti/dyson-types.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAkB,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClG,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAKhF,MAAM,WAAW,OAAO;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,eAAe,EAAE,eAAe,CAAC;IACjC,gBAAgB,EAAE,gBAAgB,CAAC;CACtC;AAGD,eAAO,MAAM,SAAS,EAAwB,UAAU,GAAG;IACvD,QAAQ,EAAE,KAAK,CAAC;IAChB,eAAe,EAAE,KAAK,CAAC;IACvB,gBAAgB,EAAE,KAAK,CAAC;CAC3B,CAAC;AAGF,eAAO,MAAM,QAAQ,EAAgC,aAAa,GAAG;IACjE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC7B,eAAe,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IAC3C,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;CAChD,CAAC;AAGF,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// This module was automatically generated by node ts-interface-post.ts
|
|
2
|
+
// 2025-05-16T17:16:14.902Z
|
|
3
|
+
import { createCheckers } from 'ts-interface-checker';
|
|
4
|
+
import exportedTypeSuite from './dyson-types-ti.js';
|
|
5
|
+
// Type definitions
|
|
6
|
+
export const typeSuite = exportedTypeSuite;
|
|
7
|
+
// Checkers
|
|
8
|
+
export const checkers = createCheckers(typeSuite);
|
|
9
|
+
// Export the checkers by default
|
|
10
|
+
export default checkers;
|
|
11
|
+
//# sourceMappingURL=dyson-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dyson-types.js","sourceRoot":"","sources":["../../src/ti/dyson-types.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,2BAA2B;AAE3B,OAAO,EAAY,cAAc,EAAoC,MAAM,sBAAsB,CAAC;AAElG,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AAUpD,mBAAmB;AACnB,MAAM,CAAC,MAAM,SAAS,GAAG,iBAIxB,CAAC;AAEF,WAAW;AACX,MAAM,CAAC,MAAM,QAAQ,GAAG,cAAc,CAAC,SAAS,CAI/C,CAAC;AAEF,iCAAiC;AACjC,eAAe,QAAQ,CAAC"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import EventEmitter from 'events';
|
|
2
|
+
import { AnsiLogger } from 'matterbridge/logger';
|
|
3
|
+
import { MaybePromise } from 'matterbridge/matter';
|
|
4
|
+
import { IErrorDetail } from 'ts-interface-checker';
|
|
5
|
+
export declare const MS = 1000;
|
|
6
|
+
export type Constructor<T = object> = new (...args: any[]) => T;
|
|
7
|
+
export type AbstractConstructor<T = object> = abstract new (...args: any[]) => T;
|
|
8
|
+
export type UnionToIntersection<U> = (U extends unknown ? (x: U) => unknown : never) extends (x: infer I) => unknown ? I : never;
|
|
9
|
+
export declare function assertIsDefined<Type>(value: Type): asserts value is NonNullable<Type>;
|
|
10
|
+
export declare function assertIsNotUndefined<Type>(value: Type): asserts value is Exclude<Type, undefined>;
|
|
11
|
+
export declare function assertIsBoolean(value: unknown): asserts value is boolean;
|
|
12
|
+
export declare function assertIsNumber(value: unknown): asserts value is number;
|
|
13
|
+
export declare function assertIsInstanceOf<Type extends object>(value: unknown, type: Constructor<Type>): asserts value is Type;
|
|
14
|
+
export declare function logError(log: AnsiLogger, when: string, err: unknown): void;
|
|
15
|
+
export declare function formatMilliseconds(ms: number, maxParts?: number): string;
|
|
16
|
+
export declare function formatSeconds(seconds: number, maxParts?: number): string;
|
|
17
|
+
export declare function formatDateISO8601(date: Date, separator: '' | '-'): string;
|
|
18
|
+
export declare function formatList(items: string[]): string;
|
|
19
|
+
export declare function plural(count: number, noun: string | [string, string], showCount?: boolean): string;
|
|
20
|
+
export declare function columns(rows: string[][], separator?: string): string[];
|
|
21
|
+
export declare function deepMerge(...objects: object[]): object;
|
|
22
|
+
export declare function getValidationTree(errors: IErrorDetail[]): string[];
|
|
23
|
+
export declare function tryListener<T extends unknown[]>(emitter: EventEmitter, op: (...args: T) => MaybePromise, errorHandler?: (err: unknown) => void): (...args: T) => void;
|
|
24
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAIA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,eAAO,MAAM,EAAE,OAAO,CAAC;AAGvB,MAAM,MAAM,WAAW,CAAS,CAAC,GAAG,MAAM,IAAa,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AACjF,MAAM,MAAM,mBAAmB,CAAC,CAAC,GAAG,MAAM,IAAI,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AAGjF,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAC7B,CAAC,CAAC,SAAS,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC;AAGhG,wBAAgB,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,GAAG,OAAO,CAAC,KAAK,IAAI,WAAW,CAAC,IAAI,CAAC,CAGrF;AACD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAEjG;AACD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAExE;AACD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,MAAM,CAEtE;AACD,wBAAgB,kBAAkB,CAAC,IAAI,SAAS,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,CAEtH;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAQ1E;AAGD,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,MAAM,CAoBnE;AAGD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,MAAM,CAEnE;AAGD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,GAAG,GAAG,GAAG,MAAM,CAKzE;AAGD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAOlD;AAGD,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,UAAO,GAAG,MAAM,CAkB/F;AAGD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,SAAO,GAAG,MAAM,EAAE,CAYpE;AAGD,wBAAgB,SAAS,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAYtD;AAGD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,CAWlE;AAGD,wBAAgB,WAAW,CAAC,CAAC,SAAS,OAAO,EAAE,EAC3C,OAAO,EAAS,YAAY,EAC5B,EAAE,EAAc,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,YAAY,EAC5C,YAAY,GAAI,CAAC,GAAG,EAAE,OAAO,KAAK,IAA0C,GAC7E,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,CAUtB"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// Matterbridge plugin for Dyson robot vacuum and air treatment devices
|
|
2
|
+
// Copyright © 2025 Alexander Thoukydides
|
|
3
|
+
import assert from 'assert';
|
|
4
|
+
// Milliseconds in a second
|
|
5
|
+
export const MS = 1000;
|
|
6
|
+
// Type assertions
|
|
7
|
+
export function assertIsDefined(value) {
|
|
8
|
+
assert.notStrictEqual(value, undefined);
|
|
9
|
+
assert.notStrictEqual(value, null);
|
|
10
|
+
}
|
|
11
|
+
export function assertIsNotUndefined(value) {
|
|
12
|
+
assert.notStrictEqual(value, undefined);
|
|
13
|
+
}
|
|
14
|
+
export function assertIsBoolean(value) {
|
|
15
|
+
assert.strictEqual(typeof value, 'boolean');
|
|
16
|
+
}
|
|
17
|
+
export function assertIsNumber(value) {
|
|
18
|
+
assert.strictEqual(typeof value, 'number');
|
|
19
|
+
}
|
|
20
|
+
export function assertIsInstanceOf(value, type) {
|
|
21
|
+
assert(value instanceof type, `Not an instance of ${type.name}`);
|
|
22
|
+
}
|
|
23
|
+
// Log an error
|
|
24
|
+
export function logError(log, when, err) {
|
|
25
|
+
try {
|
|
26
|
+
// Log the error message itself
|
|
27
|
+
log.error(`[${when}] ${String(err)}`);
|
|
28
|
+
// Log any stack backtrace
|
|
29
|
+
if (err instanceof Error && err.stack)
|
|
30
|
+
log.debug(err.stack);
|
|
31
|
+
}
|
|
32
|
+
catch { /* empty */ }
|
|
33
|
+
}
|
|
34
|
+
// Format a milliseconds duration
|
|
35
|
+
export function formatMilliseconds(ms, maxParts = 2) {
|
|
36
|
+
if (ms < 1)
|
|
37
|
+
return 'n/a';
|
|
38
|
+
// Split the duration into components
|
|
39
|
+
const duration = [
|
|
40
|
+
['day', Math.floor(ms / (24 * 60 * 60 * MS))],
|
|
41
|
+
['hour', Math.floor(ms / (60 * 60 * MS)) % 24],
|
|
42
|
+
['minute', Math.floor(ms / (60 * MS)) % 60],
|
|
43
|
+
['second', Math.floor(ms / MS) % 60],
|
|
44
|
+
['millisecond', Math.floor(ms) % MS]
|
|
45
|
+
];
|
|
46
|
+
// Remove any leading zero components
|
|
47
|
+
while (duration[0]?.[1] === 0)
|
|
48
|
+
duration.shift();
|
|
49
|
+
// Combine the required number of remaining components
|
|
50
|
+
return duration.slice(0, maxParts)
|
|
51
|
+
.filter(([_key, value]) => value !== 0)
|
|
52
|
+
.map(([key, value]) => plural(value, key))
|
|
53
|
+
.join(' ');
|
|
54
|
+
}
|
|
55
|
+
// Format a seconds duration
|
|
56
|
+
export function formatSeconds(seconds, maxParts = 2) {
|
|
57
|
+
return formatMilliseconds(seconds * 1000, maxParts);
|
|
58
|
+
}
|
|
59
|
+
// Format a date as YYYYMMDD or YYYY-MM-DD
|
|
60
|
+
export function formatDateISO8601(date, separator) {
|
|
61
|
+
const year = date.getUTCFullYear();
|
|
62
|
+
const month = String(date.getUTCMonth() + 1).padStart(2, '0');
|
|
63
|
+
const day = String(date.getUTCDate()).padStart(2, '0');
|
|
64
|
+
return [year, month, day].join(separator);
|
|
65
|
+
}
|
|
66
|
+
// Format a list (with Oxford comma)
|
|
67
|
+
export function formatList(items) {
|
|
68
|
+
switch (items.length) {
|
|
69
|
+
case 0: return 'n/a';
|
|
70
|
+
case 1: return items[0] ?? '';
|
|
71
|
+
case 2: return `${items[0]} and ${items[1]}`;
|
|
72
|
+
default: return [...items.slice(0, -1), `and ${items[items.length - 1]}`].join(', ');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Format a counted noun (handling most regular cases automatically)
|
|
76
|
+
export function plural(count, noun, showCount = true) {
|
|
77
|
+
const [singular, plural] = Array.isArray(noun) ? noun : [noun, ''];
|
|
78
|
+
noun = count === 1 ? singular : plural;
|
|
79
|
+
if (!noun) {
|
|
80
|
+
// Apply regular rules
|
|
81
|
+
const rules = [
|
|
82
|
+
['on$', 'a', 2], // phenomenon/phenomena criterion/criteria
|
|
83
|
+
['us$', 'i', 1], // cactus/cacti focus/foci
|
|
84
|
+
['[^aeiou]y$', 'ies', 1], // cty/cites puppy/puppies
|
|
85
|
+
['(ch|is|o|s|sh|x|z)$', 'es', 0], // iris/irises truss/trusses
|
|
86
|
+
['', 's', 0] // cat/cats house/houses
|
|
87
|
+
];
|
|
88
|
+
const rule = rules.find(([ending]) => new RegExp(ending, 'i').test(singular));
|
|
89
|
+
assertIsDefined(rule);
|
|
90
|
+
const matchCase = (s) => singular === singular.toUpperCase() ? s.toUpperCase() : s;
|
|
91
|
+
noun = singular.substring(0, singular.length - rule[2]).concat(matchCase(rule[1]));
|
|
92
|
+
}
|
|
93
|
+
return showCount ? `${count} ${noun}` : noun;
|
|
94
|
+
}
|
|
95
|
+
// Format strings in columns
|
|
96
|
+
export function columns(rows, separator = ' ') {
|
|
97
|
+
// Determine the required column widths
|
|
98
|
+
const width = [];
|
|
99
|
+
rows.forEach(row => {
|
|
100
|
+
row.forEach((value, index) => {
|
|
101
|
+
width[index] = Math.max(width[index] ?? 0, value.length);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
width.splice(-1, 1, 0);
|
|
105
|
+
// Format the rows
|
|
106
|
+
return rows.map(row => row.map((value, index) => value.padEnd(width[index] ?? 0)).join(separator));
|
|
107
|
+
}
|
|
108
|
+
// Recursive object assignment, skipping undefined values
|
|
109
|
+
export function deepMerge(...objects) {
|
|
110
|
+
const isObject = (value) => value !== undefined && typeof value === 'object' && !Array.isArray(value);
|
|
111
|
+
return objects.reduce((acc, object) => {
|
|
112
|
+
Object.entries(object).forEach(([key, value]) => {
|
|
113
|
+
const accValue = acc[key];
|
|
114
|
+
if (value === undefined)
|
|
115
|
+
return;
|
|
116
|
+
if (isObject(accValue) && isObject(value))
|
|
117
|
+
acc[key] = deepMerge(accValue, value);
|
|
118
|
+
else
|
|
119
|
+
acc[key] = value;
|
|
120
|
+
});
|
|
121
|
+
return acc;
|
|
122
|
+
}, {});
|
|
123
|
+
}
|
|
124
|
+
// Convert checker validation error into lines of text
|
|
125
|
+
export function getValidationTree(errors) {
|
|
126
|
+
const lines = [];
|
|
127
|
+
errors.forEach((error, index) => {
|
|
128
|
+
const prefix = (a, b) => index < errors.length - 1 ? a : b;
|
|
129
|
+
lines.push(`${prefix('├─ ', '└─ ')}${error.path} ${error.message}`);
|
|
130
|
+
if (error.nested) {
|
|
131
|
+
const nested = getValidationTree(error.nested);
|
|
132
|
+
lines.push(...nested.map(line => `${prefix('│ ', ' ')} ${line}`));
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
return lines;
|
|
136
|
+
}
|
|
137
|
+
// Convert any errors in an event listener to 'error' events
|
|
138
|
+
export function tryListener(emitter, op, errorHandler = (err) => emitter.emit('error', err)) {
|
|
139
|
+
return (...args) => {
|
|
140
|
+
void (async () => {
|
|
141
|
+
try {
|
|
142
|
+
await op(...args);
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
errorHandler(err);
|
|
146
|
+
}
|
|
147
|
+
})();
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,yCAAyC;AAEzC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAM5B,2BAA2B;AAC3B,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;AAUvB,kBAAkB;AAClB,MAAM,UAAU,eAAe,CAAO,KAAW;IAC7C,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACxC,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACvC,CAAC;AACD,MAAM,UAAU,oBAAoB,CAAO,KAAW;IAClD,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AAC5C,CAAC;AACD,MAAM,UAAU,eAAe,CAAC,KAAc;IAC1C,MAAM,CAAC,WAAW,CAAC,OAAO,KAAK,EAAE,SAAS,CAAC,CAAC;AAChD,CAAC;AACD,MAAM,UAAU,cAAc,CAAC,KAAc;IACzC,MAAM,CAAC,WAAW,CAAC,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC;AAC/C,CAAC;AACD,MAAM,UAAU,kBAAkB,CAAsB,KAAc,EAAE,IAAuB;IAC3F,MAAM,CAAC,KAAK,YAAY,IAAI,EAAE,sBAAsB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AACrE,CAAC;AACD,eAAe;AACf,MAAM,UAAU,QAAQ,CAAC,GAAe,EAAE,IAAY,EAAE,GAAY;IAChE,IAAI,CAAC;QACD,+BAA+B;QAC/B,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEtC,0BAA0B;QAC1B,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,KAAK;YAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;AAC3B,CAAC;AAED,iCAAiC;AACjC,MAAM,UAAU,kBAAkB,CAAC,EAAU,EAAE,QAAQ,GAAG,CAAC;IACvD,IAAI,EAAE,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAEzB,qCAAqC;IACrC,MAAM,QAAQ,GAAuB;QACjC,CAAC,KAAK,EAAU,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAM;QAC1D,CAAC,MAAM,EAAS,IAAI,CAAC,KAAK,CAAC,EAAE,GAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;QAC1D,CAAC,QAAQ,EAAO,IAAI,CAAC,KAAK,CAAC,EAAE,GAAa,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;QAC1D,CAAC,QAAQ,EAAO,IAAI,CAAC,KAAK,CAAC,EAAE,GAAmB,EAAE,CAAE,GAAG,EAAE,CAAC;QAC1D,CAAC,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAuB,GAAG,EAAE,CAAC;KAC7D,CAAC;IAEF,qCAAqC;IACrC,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;IAEhD,sDAAsD;IACtD,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;SAC7B,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;SACzC,IAAI,CAAC,GAAG,CAAC,CAAC;AACnB,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,QAAQ,GAAG,CAAC;IACvD,OAAO,kBAAkB,CAAC,OAAO,GAAG,IAAI,EAAE,QAAQ,CAAC,CAAC;AACxD,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,iBAAiB,CAAC,IAAU,EAAE,SAAmB;IAC7D,MAAM,IAAI,GAAW,IAAI,CAAC,cAAc,EAAE,CAAC;IAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,GAAG,GAAK,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACzD,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC9C,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,UAAU,CAAC,KAAe;IACtC,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAC;QACvB,KAAK,CAAC,CAAC,CAAK,OAAO,KAAK,CAAC;QACzB,KAAK,CAAC,CAAC,CAAK,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClC,KAAK,CAAC,CAAC,CAAK,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,OAAO,CAAC,CAAI,OAAO,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxF,CAAC;AACL,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,MAAM,CAAC,KAAa,EAAE,IAA+B,EAAE,SAAS,GAAG,IAAI;IACnF,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACnE,IAAI,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;IACvC,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,sBAAsB;QACtB,MAAM,KAAK,GAA+B;YACtC,CAAC,KAAK,EAAkB,GAAG,EAAI,CAAC,CAAC,EAAE,0CAA0C;YAC7E,CAAC,KAAK,EAAkB,GAAG,EAAI,CAAC,CAAC,EAAE,sCAAsC;YACzE,CAAC,YAAY,EAAW,KAAK,EAAE,CAAC,CAAC,EAAE,yCAAyC;YAC5E,CAAC,qBAAqB,EAAE,IAAI,EAAG,CAAC,CAAC,EAAE,yCAAyC;YAC5E,CAAC,EAAE,EAAqB,GAAG,EAAI,CAAC,CAAC,CAAE,wCAAwC;SAC9E,CAAC;QACF,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9E,eAAe,CAAC,IAAI,CAAC,CAAC;QACtB,MAAM,SAAS,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,QAAQ,KAAK,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACnG,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvF,CAAC;IACD,OAAO,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACjD,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,OAAO,CAAC,IAAgB,EAAE,SAAS,GAAG,IAAI;IACtD,uCAAuC;IACvC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QACf,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACzB,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAEvB,kBAAkB;IAClB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;AACvG,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,SAAS,CAAC,GAAG,OAAiB;IAC1C,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAmB,EAAE,CACjD,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9E,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,GAA4B,EAAE,MAAc,EAAE,EAAE;QACnE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;YAC5C,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;YAC1B,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO;YAChC,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC;gBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;;gBAC5E,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC1B,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,CAAC;IACf,CAAC,EAAE,EAAE,CAAC,CAAC;AACX,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,iBAAiB,CAAC,MAAsB;IACpD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC5B,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,CAAS,EAAU,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnF,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACpE,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC/C,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;QACzE,CAAC;IACL,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,WAAW,CACvB,OAA4B,EAC5B,EAA4C,EAC5C,eAAyC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC;IAE5E,OAAO,CAAC,GAAG,IAAO,EAAQ,EAAE;QACxB,KAAK,CAAC,KAAK,IAAmB,EAAE;YAC5B,IAAI,CAAC;gBACD,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;YACtB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACX,YAAY,CAAC,GAAG,CAAC,CAAC;YACtB,CAAC;QACL,CAAC,CAAC,EAAE,CAAC;IACT,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Matterbridge Dyson Robot Vacuum and Air Treatment Devices Plugin",
|
|
3
|
+
"description": "Dyson Robot Vacuum and Air Treatment Devices",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"required": [
|
|
6
|
+
"devices"
|
|
7
|
+
],
|
|
8
|
+
"properties": {
|
|
9
|
+
"name": {
|
|
10
|
+
"description": "Plugin name",
|
|
11
|
+
"type": "string",
|
|
12
|
+
"readOnly": true,
|
|
13
|
+
"ui:widget": "hidden"
|
|
14
|
+
},
|
|
15
|
+
"type": {
|
|
16
|
+
"description": "Plugin type",
|
|
17
|
+
"type": "string",
|
|
18
|
+
"readOnly": true,
|
|
19
|
+
"ui:widget": "hidden"
|
|
20
|
+
},
|
|
21
|
+
"devices": {
|
|
22
|
+
"description": "List of Dyson robot vacuum and air treatment devices to expose.",
|
|
23
|
+
"type": "array",
|
|
24
|
+
"items": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"properties": {
|
|
27
|
+
"name": {
|
|
28
|
+
"description": "Friendly name used to identify the robot vacuum or air treatment device. This is used as the Matter NodeLabel for the device.",
|
|
29
|
+
"title": "e.g. Sweep",
|
|
30
|
+
"type": "string",
|
|
31
|
+
"minLength": 1,
|
|
32
|
+
"maxLength": 64
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"required": [
|
|
36
|
+
"name"
|
|
37
|
+
],
|
|
38
|
+
"oneOf": [
|
|
39
|
+
{
|
|
40
|
+
"title": "Wi-Fi Setup Configuration",
|
|
41
|
+
"description": "Connect to the appliance directly via the local network, deriving the MQTT configuration from the Wi-Fi setup credentials. These details can be found on a label attached to the product (behind the clear bin of robot vacuums or underneath the base of air treatment devices) or its operating manual.",
|
|
42
|
+
"type": "object",
|
|
43
|
+
"properties": {
|
|
44
|
+
"host": {
|
|
45
|
+
"$ref": "#/definitions/host"
|
|
46
|
+
},
|
|
47
|
+
"port": {
|
|
48
|
+
"$ref": "#/definitions/port"
|
|
49
|
+
},
|
|
50
|
+
"wifi_ssid": {
|
|
51
|
+
"description": "Product SSID from the label attached to the product or its operating manual.",
|
|
52
|
+
"title": "e.g. DYSON-XXX-YY-ZZZZZZZZ-NNN",
|
|
53
|
+
"type": "string",
|
|
54
|
+
"pattern": "^(((360EYE-)?[A-Z0-9]{3}-[A-Z]{2}-[A-Z0-9]{8,})|(DYSON-[A-Z0-9]{3}-[A-Z]{2}-[A-Z0-9]{8,}-[0-9]{3}[A-Z]?))$"
|
|
55
|
+
},
|
|
56
|
+
"wifi_password": {
|
|
57
|
+
"description": "Product Wi-Fi Password from the label attached to the product or its operating manual.",
|
|
58
|
+
"title": "e.g. xxxxxxxx",
|
|
59
|
+
"type": "string",
|
|
60
|
+
"pattern": "^[A-Za-z0-9]{8,}$"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"required": [
|
|
64
|
+
"host",
|
|
65
|
+
"port",
|
|
66
|
+
"wifi_ssid",
|
|
67
|
+
"wifi_password"
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"title": "Local MQTT Configuration",
|
|
72
|
+
"description": "Connect to the appliance directly via the local network, providing the MQTT configuration explicitly. Use opendyson to obtain these details.",
|
|
73
|
+
"type": "object",
|
|
74
|
+
"properties": {
|
|
75
|
+
"host": {
|
|
76
|
+
"$ref": "#/definitions/host"
|
|
77
|
+
},
|
|
78
|
+
"port": {
|
|
79
|
+
"$ref": "#/definitions/port"
|
|
80
|
+
},
|
|
81
|
+
"username": {
|
|
82
|
+
"$ref": "#/definitions/username"
|
|
83
|
+
},
|
|
84
|
+
"password": {
|
|
85
|
+
"description": "MQTT password.",
|
|
86
|
+
"title": "From opendyson: mqtt → password",
|
|
87
|
+
"type": "string",
|
|
88
|
+
"pattern": "^[A-Za-z0-9+/]{86}==$"
|
|
89
|
+
},
|
|
90
|
+
"root_topic": {
|
|
91
|
+
"$ref": "#/definitions/root_topic"
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"required": [
|
|
95
|
+
"host",
|
|
96
|
+
"port",
|
|
97
|
+
"username",
|
|
98
|
+
"password",
|
|
99
|
+
"root_topic"
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"title": "Cloud IoT Service Configuration (do not use)",
|
|
104
|
+
"description": "Connect to the appliance via Dyson's cloud IoT service. Use opendyson to obtain these details.",
|
|
105
|
+
"type": "object",
|
|
106
|
+
"properties": {
|
|
107
|
+
"endpoint": {
|
|
108
|
+
"description": "Cloud IoT endpoint.",
|
|
109
|
+
"title": "From opendyson: iot → endpoint",
|
|
110
|
+
"type": "string",
|
|
111
|
+
"format": "hostname"
|
|
112
|
+
},
|
|
113
|
+
"client_id": {
|
|
114
|
+
"description": "Cloud IoT client identifier (probably the same as the token_value).",
|
|
115
|
+
"title": "From opendyson: iot → client_id",
|
|
116
|
+
"type": "string",
|
|
117
|
+
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
|
|
118
|
+
},
|
|
119
|
+
"custom_authorizer_name": {
|
|
120
|
+
"description": "Cloud IoT custom_authorizer_name.",
|
|
121
|
+
"title": "From opendyson: iot → custom_authorizer_name",
|
|
122
|
+
"type": "string",
|
|
123
|
+
"pattern": "^[A-Za-z0-9-]+$"
|
|
124
|
+
},
|
|
125
|
+
"token_key": {
|
|
126
|
+
"description": "Cloud IoT name of the token header.",
|
|
127
|
+
"title": "From opendyson: iot → token_key",
|
|
128
|
+
"type": "string",
|
|
129
|
+
"default": "token",
|
|
130
|
+
"pattern": "^[a-zA-Z0-9_-]+$"
|
|
131
|
+
},
|
|
132
|
+
"token_value": {
|
|
133
|
+
"description": "Cloud IoT value for the token header (probably the same as the client_id).",
|
|
134
|
+
"title": "From opendyson: iot → token_value",
|
|
135
|
+
"type": "string",
|
|
136
|
+
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
|
|
137
|
+
},
|
|
138
|
+
"token_signature": {
|
|
139
|
+
"description": "Cloud IoT token signature.",
|
|
140
|
+
"title": "From opendyson: iot → token_signature",
|
|
141
|
+
"type": "string",
|
|
142
|
+
"pattern": "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}={2})$"
|
|
143
|
+
},
|
|
144
|
+
"username": {
|
|
145
|
+
"$ref": "#/definitions/username"
|
|
146
|
+
},
|
|
147
|
+
"root_topic": {
|
|
148
|
+
"$ref": "#/definitions/root_topic"
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
"required": [
|
|
152
|
+
"endpoint",
|
|
153
|
+
"client_id",
|
|
154
|
+
"custom_authorizer_name",
|
|
155
|
+
"token_key",
|
|
156
|
+
"token_signature",
|
|
157
|
+
"token_value",
|
|
158
|
+
"root_topic"
|
|
159
|
+
]
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
},
|
|
163
|
+
"minItems": 1,
|
|
164
|
+
"uniqueItems": true
|
|
165
|
+
},
|
|
166
|
+
"wildcardTopic": {
|
|
167
|
+
"description": "Subscribe to all MQTT topics (using the '#' wildcard). This is useful for discovering new endpoints or checking that the rootTopic and username have been correctly configured. Disabling this limits subscription to the expected status topic(s).",
|
|
168
|
+
"type": "boolean",
|
|
169
|
+
"default": true
|
|
170
|
+
},
|
|
171
|
+
"whiteList": {
|
|
172
|
+
"description": "Only expose robot vacuum and air treatment devices listed here, identified by their serial number (i.e. the MQTT username). Leave empty to expose all devices.",
|
|
173
|
+
"type": "array",
|
|
174
|
+
"items": {
|
|
175
|
+
"$ref": "#/definitions/username"
|
|
176
|
+
},
|
|
177
|
+
"uniqueItems": true,
|
|
178
|
+
"selectFrom": "serial",
|
|
179
|
+
"default": []
|
|
180
|
+
},
|
|
181
|
+
"blackList": {
|
|
182
|
+
"description": "Exclude any robot vacuum and air treatment devices listed here, identified by their serial number (i.e. the MQTT username). Leave empty to expose all devices.",
|
|
183
|
+
"type": "array",
|
|
184
|
+
"items": {
|
|
185
|
+
"$ref": "#/definitions/username"
|
|
186
|
+
},
|
|
187
|
+
"uniqueItems": true,
|
|
188
|
+
"selectFrom": "serial",
|
|
189
|
+
"default": []
|
|
190
|
+
},
|
|
191
|
+
"entityWhiteList": {
|
|
192
|
+
"description": "Only expose Matter device types listed here: Air Purifier, Air Quality Sensor, Composed Air Purifier, Humidity Sensor, Temperature Sensor, or Thermostat. This applies to all air treatment devices, but does not affect robot vacuum devices. Leave empty to expose all device types.",
|
|
193
|
+
"type": "array",
|
|
194
|
+
"items": {
|
|
195
|
+
"type": "string"
|
|
196
|
+
},
|
|
197
|
+
"uniqueItems": true,
|
|
198
|
+
"selectEntityFrom": "name",
|
|
199
|
+
"default": []
|
|
200
|
+
},
|
|
201
|
+
"entityBlackList": {
|
|
202
|
+
"description": "Exclude any Matter device types listed here: Air Purifier, Air Quality Sensor, Composed Air Purifier, Humidity Sensor, Temperature Sensor, or Thermostat. This applies to all air treatment devices, but does not affect robot vacuum devices. Leave empty to expose all device types.",
|
|
203
|
+
"type": "array",
|
|
204
|
+
"items": {
|
|
205
|
+
"type": "string"
|
|
206
|
+
},
|
|
207
|
+
"uniqueItems": true,
|
|
208
|
+
"selectEntityFrom": "name",
|
|
209
|
+
"default": [
|
|
210
|
+
"Composed Air Purifier",
|
|
211
|
+
"Humidity Sensor",
|
|
212
|
+
"Temperature Sensor"
|
|
213
|
+
]
|
|
214
|
+
},
|
|
215
|
+
"deviceEntityBlackList": {
|
|
216
|
+
"description": "Exclude Matter device types per air treatment device. This does not affect robot vacuum devices. Enter the device's serial number (i.e. the MQTT username) in the first field, and in the list add all of the device types to exclude for that device.",
|
|
217
|
+
"type": "object",
|
|
218
|
+
"uniqueItems": true,
|
|
219
|
+
"selectFrom": "serial",
|
|
220
|
+
"additionalProperties": {
|
|
221
|
+
"description": "Exclude any device types listed here.",
|
|
222
|
+
"type": "array",
|
|
223
|
+
"uniqueItems": true,
|
|
224
|
+
"items": {
|
|
225
|
+
"type": "string"
|
|
226
|
+
},
|
|
227
|
+
"selectDeviceEntityFrom": "name"
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
"debug": {
|
|
231
|
+
"description": "Capture debug-level logging from this plugin, overriding the Matterbridge global log level setting.",
|
|
232
|
+
"type": "boolean",
|
|
233
|
+
"default": false
|
|
234
|
+
},
|
|
235
|
+
"debugFeatures": {
|
|
236
|
+
"description": "Advanced diagnostics: Enable only for troubleshooting or development.",
|
|
237
|
+
"type": "array",
|
|
238
|
+
"uniqueItems": true,
|
|
239
|
+
"items": {
|
|
240
|
+
"type": "string",
|
|
241
|
+
"enum": [
|
|
242
|
+
"Log Endpoint Debug",
|
|
243
|
+
"Log MQTT Client",
|
|
244
|
+
"Log MQTT Payloads",
|
|
245
|
+
"Log Serial Numbers",
|
|
246
|
+
"Log Debug as Info"
|
|
247
|
+
]
|
|
248
|
+
},
|
|
249
|
+
"default": []
|
|
250
|
+
},
|
|
251
|
+
"unregisterOnShutdown": {
|
|
252
|
+
"description": "Unregister all exposed devices on shutdown (used for development/testing).",
|
|
253
|
+
"type": "boolean",
|
|
254
|
+
"default": false,
|
|
255
|
+
"ui:widget": "hidden"
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
"definitions": {
|
|
259
|
+
"host": {
|
|
260
|
+
"description": "Local network hostname or IP address of the robot vacuum or air treatment device.",
|
|
261
|
+
"title": "e.g. sweep.local or 192.168.0.100",
|
|
262
|
+
"type": "string",
|
|
263
|
+
"format": "hostname"
|
|
264
|
+
},
|
|
265
|
+
"port": {
|
|
266
|
+
"description": "MQTT port number. This should usually be left at its default value of 1883.",
|
|
267
|
+
"title": "e.g. 1883",
|
|
268
|
+
"type": "integer",
|
|
269
|
+
"default": 1883,
|
|
270
|
+
"ui:widget": "hidden"
|
|
271
|
+
},
|
|
272
|
+
"username": {
|
|
273
|
+
"description": "MQTT username (should match the product's serial number).",
|
|
274
|
+
"title": "From opendyson: mqtt → username",
|
|
275
|
+
"type": "string",
|
|
276
|
+
"pattern": "^[A-Z0-9]{3}-[A-Z]{2}-[A-Z0-9]{8,}$"
|
|
277
|
+
},
|
|
278
|
+
"root_topic": {
|
|
279
|
+
"description": "MQTT root topic (Dyson internal product type). If using opendyson: mqtt → root_topic",
|
|
280
|
+
"title": "e.g. N223 or 475",
|
|
281
|
+
"type": "string",
|
|
282
|
+
"pattern": "^[0-9]{3}[A-Z]?$",
|
|
283
|
+
"oneOf": [
|
|
284
|
+
{
|
|
285
|
+
"const": "N223",
|
|
286
|
+
"title": "N223 = Dyson 360 Eye (RB01)"
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
"const": "276",
|
|
290
|
+
"title": "276 = Dyson 360 Heurist (RB02)"
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
"const": "277",
|
|
294
|
+
"title": "277 = Dyson 360 Vis Nav (RB03)"
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
"const": "358",
|
|
298
|
+
"title": "358 = Dyson Pure Humidify+Cool (PH01)"
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
"const": "358E",
|
|
302
|
+
"title": "358E = Dyson Pure Humidify+Cool (PH03)"
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
"const": "358K",
|
|
306
|
+
"title": "358K = Dyson Pure Humidify+Cool Formaldehyde (PH04)"
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
"const": "438",
|
|
310
|
+
"title": "438 = Dyson Pure Cool (TP04 or TP06)"
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"const": "438E",
|
|
314
|
+
"title": "438E = Dyson Pure Cool Formaldehyde (TP07 or TP09)"
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
"const": "438K",
|
|
318
|
+
"title": "438K = Dyson Pure Cool Formaldehyde (TP07 or TP09)"
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
"const": "455",
|
|
322
|
+
"title": "455 = Dyson Pure Hot+Cool Link (HP02)"
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
"const": "455A",
|
|
326
|
+
"title": "455A = Dyson Pure Hot+Cool Link (HP02)"
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
"const": "469",
|
|
330
|
+
"title": "469 = Dyson Pure Cool Link Desk (DP01)"
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
"const": "475",
|
|
334
|
+
"title": "475 = Dyson Pure Cool Link (TP02)"
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
"const": "520",
|
|
338
|
+
"title": "520 = Dyson Pure Cool Desk (DP04)"
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
"const": "527",
|
|
342
|
+
"title": "527 = Dyson Pure Hot+Cool (HP04 or HP06)"
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"const": "527E",
|
|
346
|
+
"title": "527E = Dyson Purifier Hot+Cool (HP07)"
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
"const": "527K",
|
|
350
|
+
"title": "527K = Dyson Purifier Hot+Cool Formaldehyde (HP09)"
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
"const": "664",
|
|
354
|
+
"title": "664 = Dyson Purifier Big+Quiet Series (BP02, BP03, BP04, or BP06)"
|
|
355
|
+
}
|
|
356
|
+
]
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|