homebridge-switcher-laundry 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -7
- package/config.schema.json +27 -2
- package/dist/accessory.d.ts +2 -0
- package/dist/accessory.js +5 -4
- package/dist/accessory.js.map +1 -1
- package/dist/platform.js +12 -1
- package/dist/platform.js.map +1 -1
- package/dist/switcher-power.d.ts +22 -7
- package/dist/switcher-power.js +87 -20
- package/dist/switcher-power.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Homebridge plugin that watches a **Switcher Power Plug** and tells HomeKit when a washer or dryer finishes.
|
|
4
4
|
|
|
5
|
-
Apple Home does not show live watts. Eve can. This plugin
|
|
5
|
+
Apple Home does not show live watts. Eve can. This plugin reads Switcher wattage (UDP broadcast, or TCP poll if UDP is busy) and turns power changes into sensors Home can automate.
|
|
6
6
|
|
|
7
7
|
## What you get in Home
|
|
8
8
|
|
|
@@ -18,7 +18,7 @@ For each configured plug:
|
|
|
18
18
|
sudo npm install -g homebridge-switcher-laundry
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
Until the package is on npm
|
|
21
|
+
Until the package is on npm:
|
|
22
22
|
|
|
23
23
|
```sh
|
|
24
24
|
sudo npm install -g github:mirimalulkasif/hb-switcher-laundry
|
|
@@ -37,7 +37,8 @@ Restart Homebridge, then add **Switcher Laundry** from the Plugins page.
|
|
|
37
37
|
"devices": [
|
|
38
38
|
{
|
|
39
39
|
"name": "Washing Machine",
|
|
40
|
-
"identifier": "
|
|
40
|
+
"identifier": "192.168.68.90",
|
|
41
|
+
"deviceId": "e4eaf6",
|
|
41
42
|
"startWatts": 5,
|
|
42
43
|
"stopWatts": 2,
|
|
43
44
|
"startSeconds": 60,
|
|
@@ -51,6 +52,12 @@ Restart Homebridge, then add **Switcher Laundry** from the Plugins page.
|
|
|
51
52
|
|
|
52
53
|
`identifier` can be the Switcher device id, a static IP, or the exact device name from the Switcher app.
|
|
53
54
|
|
|
55
|
+
### Running next to homebridge-switcher-platform
|
|
56
|
+
|
|
57
|
+
Both plugins want Switcher UDP port **20002**. If Platform is already running, Laundry cannot listen and will fall back to **TCP polling**.
|
|
58
|
+
|
|
59
|
+
For that fallback, set **`deviceId`** (hex id from Switcher Platform logs, e.g. `Found New Switcher ... | ID:e4eaf6`). If `identifier` is not the IP, also set **`deviceIp`**.
|
|
60
|
+
|
|
54
61
|
### Calibrating thresholds
|
|
55
62
|
|
|
56
63
|
1. Run a normal wash with the plug connected.
|
|
@@ -65,8 +72,6 @@ Restart Homebridge, then add **Switcher Laundry** from the Plugins page.
|
|
|
65
72
|
2. After a real start, power stays at or below `stopWatts` for `stopSeconds` → **done**
|
|
66
73
|
3. The next sustained high-power stretch starts a new cycle and clears **done**
|
|
67
74
|
|
|
68
|
-
The plug must stay on the same LAN as Homebridge. No cloud login is required for reading wattage from Power Plug broadcasts.
|
|
69
|
-
|
|
70
75
|
## Notifications
|
|
71
76
|
|
|
72
77
|
In the Home app, create an automation:
|
|
@@ -80,8 +85,6 @@ npm install
|
|
|
80
85
|
npm test
|
|
81
86
|
```
|
|
82
87
|
|
|
83
|
-
`npm test` compiles TypeScript and runs cycle-detection and HomeKit registration tests without a physical Switcher.
|
|
84
|
-
|
|
85
88
|
## License
|
|
86
89
|
|
|
87
90
|
Apache-2.0
|
package/config.schema.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"pluginAlias": "SwitcherLaundry",
|
|
3
3
|
"pluginType": "platform",
|
|
4
4
|
"singular": true,
|
|
5
|
-
"headerDisplay": "Watches a Switcher Power Plug and exposes HomeKit sensors when a laundry cycle finishes.
|
|
5
|
+
"headerDisplay": "Watches a Switcher Power Plug and exposes HomeKit sensors when a laundry cycle finishes. Uses UDP broadcasts when free; if homebridge-switcher-platform already owns the Switcher UDP port, set deviceId so this plugin can poll watts over TCP instead.",
|
|
6
6
|
"schema": {
|
|
7
7
|
"type": "object",
|
|
8
8
|
"properties": {
|
|
@@ -12,6 +12,21 @@
|
|
|
12
12
|
"default": "Switcher Laundry",
|
|
13
13
|
"required": true
|
|
14
14
|
},
|
|
15
|
+
"token": {
|
|
16
|
+
"title": "Switcher token (optional)",
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "From https://switcher.co.il/GetKey/ — only needed if TCP poll login requires a token on your firmware.",
|
|
19
|
+
"x-schema-form": {
|
|
20
|
+
"type": "password"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"pollSeconds": {
|
|
24
|
+
"title": "TCP poll interval (seconds)",
|
|
25
|
+
"type": "integer",
|
|
26
|
+
"default": 10,
|
|
27
|
+
"minimum": 5,
|
|
28
|
+
"description": "Used only when UDP listen is unavailable and the plugin falls back to TCP status polling."
|
|
29
|
+
},
|
|
15
30
|
"devices": {
|
|
16
31
|
"title": "Laundry devices",
|
|
17
32
|
"type": "array",
|
|
@@ -29,7 +44,17 @@
|
|
|
29
44
|
"title": "Switcher identifier",
|
|
30
45
|
"type": "string",
|
|
31
46
|
"required": true,
|
|
32
|
-
"description": "Device id, IP address, or exact name from the Switcher app /
|
|
47
|
+
"description": "Device id, IP address, or exact name from the Switcher app / Switcher Platform logs."
|
|
48
|
+
},
|
|
49
|
+
"deviceId": {
|
|
50
|
+
"title": "Device ID (for TCP fallback)",
|
|
51
|
+
"type": "string",
|
|
52
|
+
"description": "Hex id from Switcher Platform logs (e.g. e4eaf6). Required if you also run homebridge-switcher-platform, because both plugins cannot bind UDP 20002."
|
|
53
|
+
},
|
|
54
|
+
"deviceIp": {
|
|
55
|
+
"title": "Device IP (optional)",
|
|
56
|
+
"type": "string",
|
|
57
|
+
"description": "Set if identifier is a name/id and you need TCP fallback. If identifier is already an IP, leave blank."
|
|
33
58
|
},
|
|
34
59
|
"startWatts": {
|
|
35
60
|
"title": "Start threshold (W)",
|
package/dist/accessory.d.ts
CHANGED
package/dist/accessory.js
CHANGED
|
@@ -34,18 +34,19 @@ class LaundryAccessory {
|
|
|
34
34
|
this.accessory.getService(Service.AccessoryInformation)
|
|
35
35
|
?.setCharacteristic(Characteristic.Manufacturer, 'Switcher')
|
|
36
36
|
.setCharacteristic(Characteristic.Model, 'Power Plug Laundry')
|
|
37
|
-
.setCharacteristic(Characteristic.SerialNumber, device.identifier);
|
|
38
|
-
|
|
37
|
+
.setCharacteristic(Characteristic.SerialNumber, device.deviceId || device.identifier);
|
|
38
|
+
// Use subtype lookup so restored cached accessories are reused (not duplicated).
|
|
39
|
+
this.doneService = this.accessory.getServiceById(Service.ContactSensor, 'washer-done')
|
|
39
40
|
|| this.accessory.addService(Service.ContactSensor, `${device.name} Done`, 'washer-done');
|
|
40
41
|
this.doneService.setCharacteristic(Characteristic.Name, `${device.name} Done`);
|
|
41
42
|
this.doneService.getCharacteristic(Characteristic.ContactSensorState)
|
|
42
43
|
.onGet(() => this.doneContactState());
|
|
43
|
-
this.runningService = this.accessory.
|
|
44
|
+
this.runningService = this.accessory.getServiceById(Service.OccupancySensor, 'washer-running')
|
|
44
45
|
|| this.accessory.addService(Service.OccupancySensor, `${device.name} Running`, 'washer-running');
|
|
45
46
|
this.runningService.setCharacteristic(Characteristic.Name, `${device.name} Running`);
|
|
46
47
|
this.runningService.getCharacteristic(Characteristic.OccupancyDetected)
|
|
47
48
|
.onGet(() => this.runningOccupancy());
|
|
48
|
-
this.clearService = this.accessory.
|
|
49
|
+
this.clearService = this.accessory.getServiceById(Service.Switch, 'clear-done')
|
|
49
50
|
|| this.accessory.addService(Service.Switch, `${device.name} Clear Done`, 'clear-done');
|
|
50
51
|
this.clearService.setCharacteristic(Characteristic.Name, `${device.name} Clear Done`);
|
|
51
52
|
this.clearService.getCharacteristic(Characteristic.On)
|
package/dist/accessory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accessory.js","sourceRoot":"","sources":["../src/accessory.ts"],"names":[],"mappings":";;;AAEA,mCAAmE;
|
|
1
|
+
{"version":3,"file":"accessory.js","sourceRoot":"","sources":["../src/accessory.ts"],"names":[],"mappings":"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"}
|
package/dist/platform.js
CHANGED
|
@@ -14,7 +14,14 @@ class SwitcherLaundryPlatform {
|
|
|
14
14
|
cachedAccessories = [];
|
|
15
15
|
handlers = [];
|
|
16
16
|
ready = Promise.resolve();
|
|
17
|
-
constructor(log, config, api, powerFactory = (device) => new switcher_power_1.
|
|
17
|
+
constructor(log, config, api, powerFactory = (device) => new switcher_power_1.SwitcherPowerSource({
|
|
18
|
+
identifier: device.identifier,
|
|
19
|
+
deviceId: device.deviceId,
|
|
20
|
+
deviceIp: device.deviceIp,
|
|
21
|
+
token: typeof this.config.token === 'string' ? this.config.token : undefined,
|
|
22
|
+
pollSeconds: Number(this.config.pollSeconds) || 10,
|
|
23
|
+
log: (message) => this.log.debug(message),
|
|
24
|
+
})) {
|
|
18
25
|
this.log = log;
|
|
19
26
|
this.config = config;
|
|
20
27
|
this.api = api;
|
|
@@ -76,9 +83,13 @@ class SwitcherLaundryPlatform {
|
|
|
76
83
|
return null;
|
|
77
84
|
}
|
|
78
85
|
const name = String(item.name ?? identifier).trim() || identifier;
|
|
86
|
+
const deviceId = String(item.deviceId ?? '').trim() || undefined;
|
|
87
|
+
const deviceIp = String(item.deviceIp ?? '').trim() || undefined;
|
|
79
88
|
return {
|
|
80
89
|
name,
|
|
81
90
|
identifier,
|
|
91
|
+
deviceId,
|
|
92
|
+
deviceIp,
|
|
82
93
|
startWatts: positiveNumber(item.startWatts, settings_1.DEFAULT_START_WATTS),
|
|
83
94
|
stopWatts: positiveNumber(item.stopWatts, settings_1.DEFAULT_STOP_WATTS),
|
|
84
95
|
startSeconds: positiveNumber(item.startSeconds, settings_1.DEFAULT_START_SECONDS),
|
package/dist/platform.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":";;;AAUA,2CAAyE;AACzE,yCAOoB;AACpB,
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|
package/dist/switcher-power.d.ts
CHANGED
|
@@ -14,19 +14,34 @@ export interface PowerSource {
|
|
|
14
14
|
off(event: 'power', listener: (sample: PowerSample) => void): this;
|
|
15
15
|
off(event: 'error', listener: (error: Error) => void): this;
|
|
16
16
|
}
|
|
17
|
+
export interface SwitcherPowerOptions {
|
|
18
|
+
identifier: string;
|
|
19
|
+
deviceId?: string;
|
|
20
|
+
deviceIp?: string;
|
|
21
|
+
token?: string;
|
|
22
|
+
pollSeconds?: number;
|
|
23
|
+
log?: (message: string) => void;
|
|
24
|
+
}
|
|
17
25
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
26
|
+
* Prefers UDP broadcasts; if the Switcher UDP port is already taken
|
|
27
|
+
* (e.g. by homebridge-switcher-platform), falls back to TCP status polling.
|
|
20
28
|
*/
|
|
21
|
-
export declare class
|
|
22
|
-
private readonly
|
|
23
|
-
private readonly log;
|
|
29
|
+
export declare class SwitcherPowerSource extends EventEmitter implements PowerSource {
|
|
30
|
+
private readonly options;
|
|
24
31
|
private listener?;
|
|
32
|
+
private pollTimer?;
|
|
33
|
+
private device?;
|
|
25
34
|
private started;
|
|
26
|
-
|
|
35
|
+
private readonly log;
|
|
36
|
+
private readonly pollSeconds;
|
|
37
|
+
private resolvedId?;
|
|
38
|
+
private resolvedIp?;
|
|
39
|
+
constructor(options: SwitcherPowerOptions);
|
|
27
40
|
start(): void;
|
|
28
41
|
stop(): void;
|
|
29
|
-
private
|
|
42
|
+
private closeListener;
|
|
43
|
+
private startTcpPoll;
|
|
44
|
+
private handleWatts;
|
|
30
45
|
}
|
|
31
46
|
/** Test double that feeds watt samples into the same PowerSource contract. */
|
|
32
47
|
export declare class FakePowerSource extends EventEmitter implements PowerSource {
|
package/dist/switcher-power.js
CHANGED
|
@@ -1,59 +1,120 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FakePowerSource = exports.
|
|
3
|
+
exports.FakePowerSource = exports.SwitcherPowerSource = void 0;
|
|
4
4
|
const node_events_1 = require("node:events");
|
|
5
5
|
// switcher-js2 ships as CommonJS without TypeScript types.
|
|
6
6
|
const Switcher = require('switcher-js2');
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* Prefers UDP broadcasts; if the Switcher UDP port is already taken
|
|
9
|
+
* (e.g. by homebridge-switcher-platform), falls back to TCP status polling.
|
|
10
10
|
*/
|
|
11
|
-
class
|
|
12
|
-
|
|
13
|
-
log;
|
|
11
|
+
class SwitcherPowerSource extends node_events_1.EventEmitter {
|
|
12
|
+
options;
|
|
14
13
|
listener;
|
|
14
|
+
pollTimer;
|
|
15
|
+
device;
|
|
15
16
|
started = false;
|
|
16
|
-
|
|
17
|
+
log;
|
|
18
|
+
pollSeconds;
|
|
19
|
+
resolvedId;
|
|
20
|
+
resolvedIp;
|
|
21
|
+
constructor(options) {
|
|
17
22
|
super();
|
|
18
|
-
this.
|
|
19
|
-
this.log = log;
|
|
23
|
+
this.options = options;
|
|
24
|
+
this.log = options.log || (() => undefined);
|
|
25
|
+
this.pollSeconds = Math.max(5, options.pollSeconds || 10);
|
|
26
|
+
this.resolvedId = options.deviceId || (isDeviceId(options.identifier) ? options.identifier : undefined);
|
|
27
|
+
this.resolvedIp = options.deviceIp || (isIpAddress(options.identifier) ? options.identifier : undefined);
|
|
20
28
|
}
|
|
21
29
|
start() {
|
|
22
30
|
if (this.started) {
|
|
23
31
|
return;
|
|
24
32
|
}
|
|
25
33
|
this.started = true;
|
|
26
|
-
|
|
27
|
-
|
|
34
|
+
try {
|
|
35
|
+
this.listener = Switcher.listen((message) => this.log(message), this.options.identifier);
|
|
36
|
+
this.listener.on('error', (error) => {
|
|
37
|
+
this.log(`UDP listen failed (${error.message}); trying TCP poll fallback`);
|
|
38
|
+
void this.closeListener().then(() => this.startTcpPoll());
|
|
39
|
+
});
|
|
40
|
+
this.listener.on('message', (message) => {
|
|
41
|
+
this.resolvedId = message.device_id;
|
|
42
|
+
this.resolvedIp = message.device_ip;
|
|
43
|
+
this.handleWatts(Number(message.state?.power_consumption), message.device_id, message.device_ip, message.name, Number(message.state?.power) === 1);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
this.log(`UDP listen threw (${error instanceof Error ? error.message : String(error)}); trying TCP poll`);
|
|
48
|
+
this.startTcpPoll();
|
|
49
|
+
}
|
|
28
50
|
}
|
|
29
51
|
stop() {
|
|
30
52
|
if (!this.started) {
|
|
31
53
|
return;
|
|
32
54
|
}
|
|
33
55
|
this.started = false;
|
|
56
|
+
if (this.pollTimer) {
|
|
57
|
+
clearInterval(this.pollTimer);
|
|
58
|
+
this.pollTimer = undefined;
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
this.device?.close?.();
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// ignore
|
|
65
|
+
}
|
|
66
|
+
this.device = undefined;
|
|
67
|
+
void this.closeListener();
|
|
68
|
+
}
|
|
69
|
+
async closeListener() {
|
|
34
70
|
const closing = this.listener?.close();
|
|
35
71
|
this.listener = undefined;
|
|
36
72
|
if (closing && typeof closing.then === 'function') {
|
|
37
|
-
|
|
73
|
+
try {
|
|
74
|
+
await closing;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// ignore
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
startTcpPoll() {
|
|
82
|
+
if (this.pollTimer || !this.started) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (!this.resolvedId || !this.resolvedIp) {
|
|
86
|
+
const error = new Error('UDP port busy (often homebridge-switcher-platform). Set deviceId (and deviceIp if needed) in the laundry device config to poll over TCP.');
|
|
87
|
+
this.emit('error', error);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
this.log(`Polling Switcher ${this.resolvedId} at ${this.resolvedIp} every ${this.pollSeconds}s over TCP`);
|
|
91
|
+
this.device = new Switcher(this.resolvedId, this.resolvedIp, (message) => this.log(message), false, 'power_plug', undefined, this.options.token);
|
|
92
|
+
const tick = () => {
|
|
93
|
+
void this.device?.status()
|
|
94
|
+
.then((status) => {
|
|
95
|
+
this.handleWatts(Number(status.power_consumption), this.resolvedId || this.options.identifier, this.resolvedIp || '0.0.0.0', this.options.identifier, Number(status.power) === 1 || status.power === 'ON');
|
|
96
|
+
})
|
|
97
|
+
.catch((error) => {
|
|
38
98
|
this.emit('error', error instanceof Error ? error : new Error(String(error)));
|
|
39
99
|
});
|
|
40
|
-
}
|
|
100
|
+
};
|
|
101
|
+
tick();
|
|
102
|
+
this.pollTimer = setInterval(tick, this.pollSeconds * 1000);
|
|
41
103
|
}
|
|
42
|
-
|
|
43
|
-
const watts = Number(message.state?.power_consumption);
|
|
104
|
+
handleWatts(watts, deviceId, deviceIp, name, on) {
|
|
44
105
|
if (!Number.isFinite(watts)) {
|
|
45
106
|
return;
|
|
46
107
|
}
|
|
47
108
|
this.emit('power', {
|
|
48
|
-
deviceId
|
|
49
|
-
deviceIp
|
|
50
|
-
name
|
|
109
|
+
deviceId,
|
|
110
|
+
deviceIp,
|
|
111
|
+
name,
|
|
51
112
|
watts,
|
|
52
|
-
on
|
|
113
|
+
on,
|
|
53
114
|
});
|
|
54
115
|
}
|
|
55
116
|
}
|
|
56
|
-
exports.
|
|
117
|
+
exports.SwitcherPowerSource = SwitcherPowerSource;
|
|
57
118
|
/** Test double that feeds watt samples into the same PowerSource contract. */
|
|
58
119
|
class FakePowerSource extends node_events_1.EventEmitter {
|
|
59
120
|
start() {
|
|
@@ -73,4 +134,10 @@ class FakePowerSource extends node_events_1.EventEmitter {
|
|
|
73
134
|
}
|
|
74
135
|
}
|
|
75
136
|
exports.FakePowerSource = FakePowerSource;
|
|
137
|
+
function isIpAddress(value) {
|
|
138
|
+
return /^\d{1,3}(?:\.\d{1,3}){3}$/.test(value);
|
|
139
|
+
}
|
|
140
|
+
function isDeviceId(value) {
|
|
141
|
+
return /^[a-f0-9]{6,}$/i.test(value);
|
|
142
|
+
}
|
|
76
143
|
//# sourceMappingURL=switcher-power.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switcher-power.js","sourceRoot":"","sources":["../src/switcher-power.ts"],"names":[],"mappings":";;;AAAA,6CAA2C;AAE3C,2DAA2D;AAC3D,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAc,
|
|
1
|
+
{"version":3,"file":"switcher-power.js","sourceRoot":"","sources":["../src/switcher-power.ts"],"names":[],"mappings":";;;AAAA,6CAA2C;AAE3C,2DAA2D;AAC3D,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAmB,CAAC;AAkE3D;;;GAGG;AACH,MAAa,mBAAoB,SAAQ,0BAAY;IAUtB;IATrB,QAAQ,CAAoB;IAC5B,SAAS,CAAkC;IAC3C,MAAM,CAAkB;IACxB,OAAO,GAAG,KAAK,CAAC;IACP,GAAG,CAA4B;IAC/B,WAAW,CAAS;IAC7B,UAAU,CAAU;IACpB,UAAU,CAAU;IAE5B,YAA6B,OAA6B;QACxD,KAAK,EAAE,CAAC;QADmB,YAAO,GAAP,OAAO,CAAsB;QAExD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC5C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACxG,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC3G,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,IAAI,CAAC;YACH,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YACzF,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClC,IAAI,CAAC,GAAG,CAAC,sBAAsB,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;gBAC3E,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;YAC5D,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;gBACtC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC;gBACpC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC;gBACpC,IAAI,CAAC,WAAW,CACd,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,iBAAiB,CAAC,EACxC,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,IAAI,EACZ,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CACnC,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,qBAAqB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;YAC1G,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC;IACH,CAAC;IAED,IAAI;QACF,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC;IAC5B,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC;QACvC,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC1B,IAAI,OAAO,IAAI,OAAQ,OAAyB,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACrE,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC;YAChB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;IACH,CAAC;IAEO,YAAY;QAClB,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,IAAI,KAAK,CACrB,0IAA0I,CAC3I,CAAC;YACF,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,UAAU,OAAO,IAAI,CAAC,UAAU,UAAU,IAAI,CAAC,WAAW,YAAY,CAAC,CAAC;QAC1G,IAAI,CAAC,MAAM,GAAG,IAAI,QAAQ,CACxB,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,UAAU,EACf,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAC9B,KAAK,EACL,YAAY,EACZ,SAAS,EACT,IAAI,CAAC,OAAO,CAAC,KAAK,CACnB,CAAC;QAEF,MAAM,IAAI,GAAG,GAAG,EAAE;YAChB,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE;iBACvB,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;gBACf,IAAI,CAAC,WAAW,CACd,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAChC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAC1C,IAAI,CAAC,UAAU,IAAI,SAAS,EAC5B,IAAI,CAAC,OAAO,CAAC,UAAU,EACvB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,CACpD,CAAC;YACJ,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;gBACxB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAChF,CAAC,CAAC,CAAC;QACP,CAAC,CAAC;QAEF,IAAI,EAAE,CAAC;QACP,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC9D,CAAC;IAEO,WAAW,CACjB,KAAa,EACb,QAAgB,EAChB,QAAgB,EAChB,IAAY,EACZ,EAAW;QAEX,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO;QACT,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,QAAQ;YACR,QAAQ;YACR,IAAI;YACJ,KAAK;YACL,EAAE;SACmB,CAAC,CAAC;IAC3B,CAAC;CACF;AA1ID,kDA0IC;AAED,8EAA8E;AAC9E,MAAa,eAAgB,SAAQ,0BAAY;IAC/C,KAAK;QACH,4BAA4B;IAC9B,CAAC;IAED,IAAI;QACF,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAED,IAAI,CAAC,KAAa,EAAE,SAA+B,EAAE;QACnD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,MAAM;YACnC,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,WAAW;YACxC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,WAAW;YAChC,KAAK;YACL,EAAE,EAAE,MAAM,CAAC,EAAE,IAAI,IAAI;SACA,CAAC,CAAC;IAC3B,CAAC;CACF;AAlBD,0CAkBC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-switcher-laundry",
|
|
3
3
|
"displayName": "Switcher Laundry",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.1",
|
|
5
5
|
"description": "Detect when a washer or dryer finishes by watching a Switcher Power Plug wattage.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"author": "mirimalulkasif",
|