@boozilla/homebridge-shome 1.0.8 → 1.0.9
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/config.schema.json +15 -11
- package/dist/accessories/doorlockAccessory.d.ts +2 -0
- package/dist/accessories/doorlockAccessory.js +7 -0
- package/dist/accessories/doorlockAccessory.js.map +1 -1
- package/dist/accessories/heaterAccessory.d.ts +2 -0
- package/dist/accessories/heaterAccessory.js +18 -3
- package/dist/accessories/heaterAccessory.js.map +1 -1
- package/dist/accessories/lightAccessory.d.ts +2 -0
- package/dist/accessories/lightAccessory.js +7 -0
- package/dist/accessories/lightAccessory.js.map +1 -1
- package/dist/accessories/ventilatorAccessory.d.ts +2 -0
- package/dist/accessories/ventilatorAccessory.js +15 -0
- package/dist/accessories/ventilatorAccessory.js.map +1 -1
- package/dist/platform.d.ts +4 -0
- package/dist/platform.js +65 -19
- package/dist/platform.js.map +1 -1
- package/package.json +1 -1
- package/src/accessories/doorlockAccessory.ts +9 -0
- package/src/accessories/heaterAccessory.ts +20 -4
- package/src/accessories/lightAccessory.ts +9 -0
- package/src/accessories/ventilatorAccessory.ts +16 -0
- package/src/platform.ts +69 -20
package/config.schema.json
CHANGED
|
@@ -5,31 +5,35 @@
|
|
|
5
5
|
"name": {
|
|
6
6
|
"title": "Name",
|
|
7
7
|
"type": "string",
|
|
8
|
-
"default": "sHome"
|
|
8
|
+
"default": "sHome",
|
|
9
|
+
"required": true
|
|
9
10
|
},
|
|
10
11
|
"username": {
|
|
11
12
|
"title": "Username",
|
|
12
13
|
"type": "string",
|
|
13
|
-
"description": "Your Samsung sHome account username."
|
|
14
|
+
"description": "Your Samsung sHome account username.",
|
|
15
|
+
"required": true
|
|
14
16
|
},
|
|
15
17
|
"password": {
|
|
16
18
|
"title": "Password",
|
|
17
19
|
"type": "string",
|
|
18
20
|
"description": "Your Samsung sHome account password.",
|
|
19
|
-
"format": "password"
|
|
21
|
+
"format": "password",
|
|
22
|
+
"required": true
|
|
20
23
|
},
|
|
21
24
|
"deviceId": {
|
|
22
25
|
"title": "Device ID",
|
|
23
26
|
"type": "string",
|
|
24
|
-
"description": "Your mobile device ID."
|
|
27
|
+
"description": "Your mobile device ID.",
|
|
28
|
+
"required": true
|
|
29
|
+
},
|
|
30
|
+
"pollingInterval": {
|
|
31
|
+
"title": "Polling Interval (ms)",
|
|
32
|
+
"type": "integer",
|
|
33
|
+
"default": 3000,
|
|
34
|
+
"description": "The interval in milliseconds to poll for device status updates. Set to 0 to disable."
|
|
25
35
|
}
|
|
26
|
-
}
|
|
27
|
-
"required": [
|
|
28
|
-
"name",
|
|
29
|
-
"username",
|
|
30
|
-
"password",
|
|
31
|
-
"deviceId"
|
|
32
|
-
]
|
|
36
|
+
}
|
|
33
37
|
},
|
|
34
38
|
"pluginAlias": "sHome",
|
|
35
39
|
"pluginType": "platform"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CharacteristicValue, PlatformAccessory } from 'homebridge';
|
|
2
2
|
import { ShomePlatform } from '../platform.js';
|
|
3
|
+
import { MainDevice } from '../shomeClient.js';
|
|
3
4
|
export declare class DoorlockAccessory {
|
|
4
5
|
private readonly platform;
|
|
5
6
|
private readonly accessory;
|
|
@@ -7,4 +8,5 @@ export declare class DoorlockAccessory {
|
|
|
7
8
|
constructor(platform: ShomePlatform, accessory: PlatformAccessory);
|
|
8
9
|
getCurrentState(): Promise<CharacteristicValue>;
|
|
9
10
|
setTargetState(value: CharacteristicValue): Promise<void>;
|
|
11
|
+
updateState(newDevice: MainDevice): Promise<void>;
|
|
10
12
|
}
|
|
@@ -49,5 +49,12 @@ export class DoorlockAccessory {
|
|
|
49
49
|
}, 1000);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
+
async updateState(newDevice) {
|
|
53
|
+
if (this.accessory.context.device.status !== newDevice.status) {
|
|
54
|
+
this.platform.log.info(`Updating state for ${this.accessory.displayName}: ${newDevice.status ? 'SECURED' : 'UNSECURED'}`);
|
|
55
|
+
this.accessory.context.device = newDevice;
|
|
56
|
+
this.service.updateCharacteristic(this.platform.Characteristic.LockCurrentState, await this.getCurrentState());
|
|
57
|
+
}
|
|
58
|
+
}
|
|
52
59
|
}
|
|
53
60
|
//# sourceMappingURL=doorlockAccessory.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doorlockAccessory.js","sourceRoot":"","sources":["../../src/accessories/doorlockAccessory.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"doorlockAccessory.js","sourceRoot":"","sources":["../../src/accessories/doorlockAccessory.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CharacteristicValue, PlatformAccessory } from 'homebridge';
|
|
2
2
|
import { ShomePlatform } from '../platform.js';
|
|
3
|
+
import { SubDevice } from '../shomeClient.js';
|
|
3
4
|
export declare class HeaterAccessory {
|
|
4
5
|
private readonly platform;
|
|
5
6
|
private readonly accessory;
|
|
@@ -13,4 +14,5 @@ export declare class HeaterAccessory {
|
|
|
13
14
|
setActive(value: CharacteristicValue): Promise<void>;
|
|
14
15
|
setTargetState(): Promise<void>;
|
|
15
16
|
setTargetTemperature(value: CharacteristicValue): Promise<void>;
|
|
17
|
+
updateState(newSubDevice: SubDevice): void;
|
|
16
18
|
}
|
|
@@ -29,7 +29,6 @@ export class HeaterAccessory {
|
|
|
29
29
|
this.service.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
|
|
30
30
|
.onGet(this.getCurrentTemperature.bind(this));
|
|
31
31
|
const thresholdCharacteristic = this.service.getCharacteristic(this.platform.Characteristic.HeatingThresholdTemperature);
|
|
32
|
-
// Prevent initial value error log by setting a valid default if the current value is out of bounds.
|
|
33
32
|
const currentTargetTemp = this.accessory.context.subDevice.setTemp;
|
|
34
33
|
if (currentTargetTemp < 5) {
|
|
35
34
|
thresholdCharacteristic.updateValue(5);
|
|
@@ -61,9 +60,8 @@ export class HeaterAccessory {
|
|
|
61
60
|
async getTargetTemperature() {
|
|
62
61
|
const subDevice = this.accessory.context.subDevice;
|
|
63
62
|
const targetTemp = subDevice.setTemp;
|
|
64
|
-
// When the heater is off, the API might return 0. We should return a valid temp for HomeKit.
|
|
65
63
|
if (subDevice.deviceStatus !== 1 || targetTemp < 5) {
|
|
66
|
-
return
|
|
64
|
+
return 5;
|
|
67
65
|
}
|
|
68
66
|
return targetTemp;
|
|
69
67
|
}
|
|
@@ -93,5 +91,22 @@ export class HeaterAccessory {
|
|
|
93
91
|
throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
|
|
94
92
|
}
|
|
95
93
|
}
|
|
94
|
+
updateState(newSubDevice) {
|
|
95
|
+
const oldSubDevice = this.accessory.context.subDevice;
|
|
96
|
+
if (oldSubDevice.deviceStatus !== newSubDevice.deviceStatus) {
|
|
97
|
+
this.platform.log.info(`Updating state for ${this.accessory.displayName}: ${newSubDevice.deviceStatus ? 'ON' : 'OFF'}`);
|
|
98
|
+
this.service.updateCharacteristic(this.platform.Characteristic.Active, newSubDevice.deviceStatus === 1);
|
|
99
|
+
}
|
|
100
|
+
if (oldSubDevice.currentTemp !== newSubDevice.currentTemp) {
|
|
101
|
+
this.platform.log.info(`Updating current temperature for ${this.accessory.displayName}: ${newSubDevice.currentTemp}`);
|
|
102
|
+
this.service.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, newSubDevice.currentTemp);
|
|
103
|
+
}
|
|
104
|
+
if (oldSubDevice.setTemp !== newSubDevice.setTemp) {
|
|
105
|
+
const newTemp = newSubDevice.setTemp < 5 ? 5 : newSubDevice.setTemp;
|
|
106
|
+
this.platform.log.info(`Updating target temperature for ${this.accessory.displayName}: ${newTemp}`);
|
|
107
|
+
this.service.updateCharacteristic(this.platform.Characteristic.HeatingThresholdTemperature, newTemp);
|
|
108
|
+
}
|
|
109
|
+
this.accessory.context.subDevice = newSubDevice;
|
|
110
|
+
}
|
|
96
111
|
}
|
|
97
112
|
//# sourceMappingURL=heaterAccessory.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heaterAccessory.js","sourceRoot":"","sources":["../../src/accessories/heaterAccessory.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"heaterAccessory.js","sourceRoot":"","sources":["../../src/accessories/heaterAccessory.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CharacteristicValue, PlatformAccessory } from 'homebridge';
|
|
2
2
|
import { ShomePlatform } from '../platform.js';
|
|
3
|
+
import { SubDevice } from '../shomeClient.js';
|
|
3
4
|
export declare class LightAccessory {
|
|
4
5
|
private readonly platform;
|
|
5
6
|
private readonly accessory;
|
|
@@ -7,4 +8,5 @@ export declare class LightAccessory {
|
|
|
7
8
|
constructor(platform: ShomePlatform, accessory: PlatformAccessory);
|
|
8
9
|
getOn(): Promise<CharacteristicValue>;
|
|
9
10
|
setOn(value: CharacteristicValue): Promise<void>;
|
|
11
|
+
updateState(newSubDevice: SubDevice): Promise<void>;
|
|
10
12
|
}
|
|
@@ -34,5 +34,12 @@ export class LightAccessory {
|
|
|
34
34
|
throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
+
async updateState(newSubDevice) {
|
|
38
|
+
if (this.accessory.context.subDevice.deviceStatus !== newSubDevice.deviceStatus) {
|
|
39
|
+
this.platform.log.info(`Updating state for ${this.accessory.displayName}: ${newSubDevice.deviceStatus ? 'ON' : 'OFF'}`);
|
|
40
|
+
this.accessory.context.subDevice = newSubDevice;
|
|
41
|
+
this.service.updateCharacteristic(this.platform.Characteristic.On, await this.getOn());
|
|
42
|
+
}
|
|
43
|
+
}
|
|
37
44
|
}
|
|
38
45
|
//# sourceMappingURL=lightAccessory.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lightAccessory.js","sourceRoot":"","sources":["../../src/accessories/lightAccessory.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lightAccessory.js","sourceRoot":"","sources":["../../src/accessories/lightAccessory.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CharacteristicValue, PlatformAccessory } from 'homebridge';
|
|
2
2
|
import { ShomePlatform } from '../platform.js';
|
|
3
|
+
import { SubDevice } from '../shomeClient.js';
|
|
3
4
|
export declare class VentilatorAccessory {
|
|
4
5
|
private readonly platform;
|
|
5
6
|
private readonly accessory;
|
|
@@ -9,4 +10,5 @@ export declare class VentilatorAccessory {
|
|
|
9
10
|
getRotationSpeed(): Promise<CharacteristicValue>;
|
|
10
11
|
setActive(value: CharacteristicValue): Promise<void>;
|
|
11
12
|
setRotationSpeed(value: CharacteristicValue): Promise<void>;
|
|
13
|
+
updateState(newSubDevice: SubDevice): Promise<void>;
|
|
12
14
|
}
|
|
@@ -71,5 +71,20 @@ export class VentilatorAccessory {
|
|
|
71
71
|
throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
+
async updateState(newSubDevice) {
|
|
75
|
+
const oldSubDevice = this.accessory.context.subDevice;
|
|
76
|
+
if (oldSubDevice.deviceStatus !== newSubDevice.deviceStatus) {
|
|
77
|
+
this.platform.log.info(`Updating state for ${this.accessory.displayName}: ${newSubDevice.deviceStatus ? 'ON' : 'OFF'}`);
|
|
78
|
+
this.fanService.updateCharacteristic(this.platform.Characteristic.Active, newSubDevice.deviceStatus === 1);
|
|
79
|
+
}
|
|
80
|
+
if (oldSubDevice.windSpeedMode !== newSubDevice.windSpeedMode) {
|
|
81
|
+
this.platform.log.info(`Updating rotation speed for ${this.accessory.displayName}`);
|
|
82
|
+
this.accessory.context.subDevice = newSubDevice;
|
|
83
|
+
this.fanService.updateCharacteristic(this.platform.Characteristic.RotationSpeed, await this.getRotationSpeed());
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
this.accessory.context.subDevice = newSubDevice;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
74
89
|
}
|
|
75
90
|
//# sourceMappingURL=ventilatorAccessory.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ventilatorAccessory.js","sourceRoot":"","sources":["../../src/accessories/ventilatorAccessory.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ventilatorAccessory.js","sourceRoot":"","sources":["../../src/accessories/ventilatorAccessory.ts"],"names":[],"mappings":"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"}
|
package/dist/platform.d.ts
CHANGED
|
@@ -8,9 +8,13 @@ export declare class ShomePlatform implements DynamicPlatformPlugin {
|
|
|
8
8
|
readonly Characteristic: typeof Characteristic;
|
|
9
9
|
readonly accessories: PlatformAccessory[];
|
|
10
10
|
readonly shomeClient: ShomeClient;
|
|
11
|
+
private readonly accessoryHandlers;
|
|
12
|
+
private pollingInterval;
|
|
13
|
+
private pollingTimer?;
|
|
11
14
|
constructor(log: Logger, config: PlatformConfig, api: API);
|
|
12
15
|
configureAccessory(accessory: PlatformAccessory): void;
|
|
13
16
|
discoverDevices(): Promise<void>;
|
|
14
17
|
setupAccessory(mainDevice: MainDevice, subDevice: SubDevice | null, uuid: string): PlatformAccessory;
|
|
15
18
|
createAccessory(accessory: PlatformAccessory): void;
|
|
19
|
+
startPolling(): void;
|
|
16
20
|
}
|
package/dist/platform.js
CHANGED
|
@@ -14,39 +14,48 @@ export class ShomePlatform {
|
|
|
14
14
|
Characteristic;
|
|
15
15
|
accessories = [];
|
|
16
16
|
shomeClient;
|
|
17
|
+
accessoryHandlers = new Map();
|
|
18
|
+
pollingInterval;
|
|
19
|
+
pollingTimer;
|
|
17
20
|
constructor(log, config, api) {
|
|
18
21
|
this.log = log;
|
|
19
22
|
this.config = config;
|
|
20
23
|
this.api = api;
|
|
21
24
|
this.Service = this.api.hap.Service;
|
|
22
25
|
this.Characteristic = this.api.hap.Characteristic;
|
|
23
|
-
|
|
26
|
+
this.pollingInterval = this.config.pollingInterval ?? 3000;
|
|
24
27
|
if (!this.config.username || !this.config.password || !this.config.deviceId) {
|
|
25
28
|
this.log.error('Missing required configuration. Please check your config.json file.');
|
|
26
29
|
this.log.error('Required fields are: "username", "password", and "deviceId".');
|
|
27
|
-
// Prevent further initialization by not creating the client
|
|
28
30
|
this.shomeClient = null;
|
|
29
31
|
return;
|
|
30
32
|
}
|
|
31
33
|
this.shomeClient = new ShomeClient(this.log, this.config.username, this.config.password, this.config.deviceId);
|
|
32
34
|
this.api.on('didFinishLaunching', () => {
|
|
33
|
-
// Defer device discovery until Homebridge is fully launched.
|
|
34
35
|
this.discoverDevices();
|
|
36
|
+
if (this.pollingInterval > 0) {
|
|
37
|
+
this.startPolling();
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
this.api.on('shutdown', () => {
|
|
41
|
+
if (this.pollingTimer) {
|
|
42
|
+
clearInterval(this.pollingTimer);
|
|
43
|
+
}
|
|
35
44
|
});
|
|
36
45
|
}
|
|
37
46
|
configureAccessory(accessory) {
|
|
38
47
|
this.accessories.push(accessory);
|
|
39
48
|
}
|
|
40
49
|
async discoverDevices() {
|
|
41
|
-
// Gracefully handle cases where the client was not initialized due to config errors
|
|
42
50
|
if (!this.shomeClient) {
|
|
43
51
|
return;
|
|
44
52
|
}
|
|
45
53
|
try {
|
|
54
|
+
this.log.info('Discovering devices...');
|
|
46
55
|
const devices = await this.shomeClient.getDeviceList();
|
|
47
56
|
const foundAccessories = [];
|
|
48
57
|
if (!devices || devices.length === 0) {
|
|
49
|
-
this.log.warn('No devices found on your sHome account.
|
|
58
|
+
this.log.warn('No devices found on your sHome account.');
|
|
50
59
|
}
|
|
51
60
|
for (const device of devices) {
|
|
52
61
|
if (CONTROLLABLE_MULTI_DEVICE_TYPES.includes(device.thngModelTypeName)) {
|
|
@@ -72,11 +81,12 @@ export class ShomePlatform {
|
|
|
72
81
|
if (accessoriesToRemove.length > 0) {
|
|
73
82
|
this.log.info('Removing stale accessories:', accessoriesToRemove.map(a => a.displayName));
|
|
74
83
|
this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, accessoriesToRemove);
|
|
84
|
+
accessoriesToRemove.forEach(acc => this.accessoryHandlers.delete(acc.UUID));
|
|
75
85
|
}
|
|
86
|
+
this.log.info('Device discovery finished.');
|
|
76
87
|
}
|
|
77
88
|
catch (error) {
|
|
78
89
|
this.log.error('Failed to discover devices due to a network or API error.');
|
|
79
|
-
this.log.error('Please check your network connection and sHome credentials. The plugin will not be able to control devices.');
|
|
80
90
|
}
|
|
81
91
|
}
|
|
82
92
|
setupAccessory(mainDevice, subDevice, uuid) {
|
|
@@ -101,20 +111,56 @@ export class ShomePlatform {
|
|
|
101
111
|
}
|
|
102
112
|
createAccessory(accessory) {
|
|
103
113
|
const device = accessory.context.device;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
const accessoryType = device.thngModelTypeName;
|
|
115
|
+
if (!this.accessoryHandlers.has(accessory.UUID)) {
|
|
116
|
+
switch (accessoryType) {
|
|
117
|
+
case 'LIGHT':
|
|
118
|
+
this.accessoryHandlers.set(accessory.UUID, new LightAccessory(this, accessory));
|
|
119
|
+
break;
|
|
120
|
+
case 'VENTILATOR':
|
|
121
|
+
this.accessoryHandlers.set(accessory.UUID, new VentilatorAccessory(this, accessory));
|
|
122
|
+
break;
|
|
123
|
+
case 'HEATER':
|
|
124
|
+
this.accessoryHandlers.set(accessory.UUID, new HeaterAccessory(this, accessory));
|
|
125
|
+
break;
|
|
126
|
+
case 'DOORLOCK':
|
|
127
|
+
this.accessoryHandlers.set(accessory.UUID, new DoorlockAccessory(this, accessory));
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
117
130
|
}
|
|
118
131
|
}
|
|
132
|
+
startPolling() {
|
|
133
|
+
this.log.info(`Starting periodic device state polling every ${this.pollingInterval / 1000} seconds.`);
|
|
134
|
+
this.pollingTimer = setInterval(async () => {
|
|
135
|
+
this.log.debug('Polling for device updates...');
|
|
136
|
+
try {
|
|
137
|
+
const devices = await this.shomeClient.getDeviceList();
|
|
138
|
+
for (const device of devices) {
|
|
139
|
+
if (CONTROLLABLE_MULTI_DEVICE_TYPES.includes(device.thngModelTypeName)) {
|
|
140
|
+
const deviceInfoList = await this.shomeClient.getDeviceInfo(device.thngId, device.thngModelTypeName);
|
|
141
|
+
if (deviceInfoList) {
|
|
142
|
+
for (const subDevice of deviceInfoList) {
|
|
143
|
+
const subUuid = this.api.hap.uuid.generate(`${device.thngId}-${subDevice.deviceId}`);
|
|
144
|
+
const handler = this.accessoryHandlers.get(subUuid);
|
|
145
|
+
if (handler) {
|
|
146
|
+
handler.updateState(subDevice);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else if (SPECIAL_CONTROLLABLE_TYPES.includes(device.thngModelTypeName)) {
|
|
152
|
+
const uuid = this.api.hap.uuid.generate(device.thngId);
|
|
153
|
+
const handler = this.accessoryHandlers.get(uuid);
|
|
154
|
+
if (handler) {
|
|
155
|
+
handler.updateState(device);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
this.log.error('An error occurred during polling:', error);
|
|
162
|
+
}
|
|
163
|
+
}, this.pollingInterval);
|
|
164
|
+
}
|
|
119
165
|
}
|
|
120
166
|
//# sourceMappingURL=platform.js.map
|
package/dist/platform.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAyB,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAEvE,MAAM,+BAA+B,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;AAC1E,MAAM,0BAA0B,GAAG,CAAC,UAAU,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAyB,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAEvE,MAAM,+BAA+B,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;AAC1E,MAAM,0BAA0B,GAAG,CAAC,UAAU,CAAC,CAAC;AAKhD,MAAM,OAAO,aAAa;IAUF;IACA;IACA;IAXN,OAAO,CAAiB;IACxB,cAAc,CAAwB;IACtC,WAAW,GAAwB,EAAE,CAAC;IACtC,WAAW,CAAc;IACxB,iBAAiB,GAAG,IAAI,GAAG,EAA4B,CAAC;IACjE,eAAe,CAAS;IACxB,YAAY,CAAkB;IAEtC,YACsB,GAAW,EACX,MAAsB,EACtB,GAAQ;QAFR,QAAG,GAAH,GAAG,CAAQ;QACX,WAAM,GAAN,MAAM,CAAgB;QACtB,QAAG,GAAH,GAAG,CAAK;QAE5B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;QACpC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC;QAClD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,IAAI,CAAC;QAE3D,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC5E,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,qEAAqE,CAAC,CAAC;YACtF,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAC;YAC/E,IAAI,CAAC,WAAW,GAAG,IAAK,CAAC;YACzB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAChC,IAAI,CAAC,GAAG,EACR,IAAI,CAAC,MAAM,CAAC,QAAQ,EACpB,IAAI,CAAC,MAAM,CAAC,QAAQ,EACpB,IAAI,CAAC,MAAM,CAAC,QAAQ,CACrB,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;YACrC,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC,EAAE,CAAC;gBAC7B,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE;YAC3B,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACnC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,kBAAkB,CAAC,SAA4B;QAC7C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;YACxC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC;YACvD,MAAM,gBAAgB,GAAwB,EAAE,CAAC;YAEjD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;YAC3D,CAAC;YAED,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,IAAI,+BAA+B,CAAC,QAAQ,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC;oBACvE,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC;oBACrG,IAAI,cAAc,EAAE,CAAC;wBACnB,KAAK,MAAM,SAAS,IAAI,cAAc,EAAE,CAAC;4BACvC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;4BAClF,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;4BAC/D,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;wBACnC,CAAC;oBACH,CAAC;gBACH,CAAC;qBAAM,IAAI,0BAA0B,CAAC,QAAQ,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC;oBACzE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;oBACvD,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;oBAC1D,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACnC,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,MAAM,CAAC,QAAQ,WAAW,MAAM,CAAC,iBAAiB,GAAG,CAAC,CAAC;gBAC3F,CAAC;YACH,CAAC;YAED,MAAM,mBAAmB,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,CACpE,CAAC,gBAAgB,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,KAAK,eAAe,CAAC,IAAI,CAAC,CACvF,CAAC;YAEF,IAAI,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACnC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,6BAA6B,EAAE,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;gBAC1F,IAAI,CAAC,GAAG,CAAC,6BAA6B,CAAC,WAAW,EAAE,aAAa,EAAE,mBAAmB,CAAC,CAAC;gBACxF,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9E,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAED,cAAc,CAAC,UAAsB,EAAE,SAA2B,EAAE,IAAY;QAC9E,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;QACzE,MAAM,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAEtF,IAAI,iBAAiB,EAAE,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,0CAA0C,EAAE,WAAW,CAAC,CAAC;YACvE,iBAAiB,CAAC,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC;YAC9C,iBAAiB,CAAC,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;YAChD,IAAI,CAAC,eAAe,CAAC,iBAAiB,CAAC,CAAC;YACxC,OAAO,iBAAiB,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,uBAAuB,EAAE,WAAW,CAAC,CAAC;YACpD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;YACpE,SAAS,CAAC,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC;YACtC,SAAS,CAAC,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;YACxC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;YAChC,IAAI,CAAC,GAAG,CAAC,2BAA2B,CAAC,WAAW,EAAE,aAAa,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;YAC9E,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,eAAe,CAAC,SAA4B;QAC1C,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC;QACxC,MAAM,aAAa,GAAG,MAAM,CAAC,iBAAiB,CAAC;QAE/C,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,QAAQ,aAAa,EAAE,CAAC;gBACxB,KAAK,OAAO;oBACV,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;oBAChF,MAAM;gBACR,KAAK,YAAY;oBACf,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,mBAAmB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;oBACrF,MAAM;gBACR,KAAK,QAAQ;oBACX,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,eAAe,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;oBACjF,MAAM;gBACR,KAAK,UAAU;oBACb,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,iBAAiB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;oBACnF,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,YAAY;QACV,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gDAAgD,IAAI,CAAC,eAAe,GAAG,IAAI,WAAW,CAAC,CAAC;QACtG,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;YACzC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;YAChD,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC;gBACvD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;oBAC7B,IAAI,+BAA+B,CAAC,QAAQ,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC;wBACvE,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC;wBACrG,IAAI,cAAc,EAAE,CAAC;4BACnB,KAAK,MAAM,SAAS,IAAI,cAAc,EAAE,CAAC;gCACvC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;gCACrF,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAA2D,CAAC;gCAC9G,IAAI,OAAO,EAAE,CAAC;oCACZ,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;gCACjC,CAAC;4BACH,CAAC;wBACH,CAAC;oBACH,CAAC;yBAAM,IAAI,0BAA0B,CAAC,QAAQ,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC;wBACzE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;wBACvD,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAsB,CAAC;wBACtE,IAAI,OAAO,EAAE,CAAC;4BACZ,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;wBAC9B,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;IAC3B,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
|
|
2
2
|
import { ShomePlatform } from '../platform.js';
|
|
3
|
+
import { MainDevice } from '../shomeClient.js';
|
|
3
4
|
|
|
4
5
|
export class DoorlockAccessory {
|
|
5
6
|
private service: Service;
|
|
@@ -57,4 +58,12 @@ export class DoorlockAccessory {
|
|
|
57
58
|
}, 1000);
|
|
58
59
|
}
|
|
59
60
|
}
|
|
61
|
+
|
|
62
|
+
async updateState(newDevice: MainDevice) {
|
|
63
|
+
if (this.accessory.context.device.status !== newDevice.status) {
|
|
64
|
+
this.platform.log.info(`Updating state for ${this.accessory.displayName}: ${newDevice.status ? 'SECURED' : 'UNSECURED'}`);
|
|
65
|
+
this.accessory.context.device = newDevice;
|
|
66
|
+
this.service.updateCharacteristic(this.platform.Characteristic.LockCurrentState, await this.getCurrentState());
|
|
67
|
+
}
|
|
68
|
+
}
|
|
60
69
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
|
|
2
2
|
import { ShomePlatform } from '../platform.js';
|
|
3
|
+
import { SubDevice } from '../shomeClient.js';
|
|
3
4
|
|
|
4
5
|
export class HeaterAccessory {
|
|
5
6
|
private service: Service;
|
|
@@ -42,7 +43,6 @@ export class HeaterAccessory {
|
|
|
42
43
|
|
|
43
44
|
const thresholdCharacteristic = this.service.getCharacteristic(this.platform.Characteristic.HeatingThresholdTemperature);
|
|
44
45
|
|
|
45
|
-
// Prevent initial value error log by setting a valid default if the current value is out of bounds.
|
|
46
46
|
const currentTargetTemp = this.accessory.context.subDevice.setTemp;
|
|
47
47
|
if (currentTargetTemp < 5) {
|
|
48
48
|
thresholdCharacteristic.updateValue(5);
|
|
@@ -81,11 +81,9 @@ export class HeaterAccessory {
|
|
|
81
81
|
const subDevice = this.accessory.context.subDevice;
|
|
82
82
|
const targetTemp = subDevice.setTemp;
|
|
83
83
|
|
|
84
|
-
// When the heater is off, the API might return 0. We should return a valid temp for HomeKit.
|
|
85
84
|
if (subDevice.deviceStatus !== 1 || targetTemp < 5) {
|
|
86
|
-
return
|
|
85
|
+
return 5;
|
|
87
86
|
}
|
|
88
|
-
|
|
89
87
|
return targetTemp;
|
|
90
88
|
}
|
|
91
89
|
|
|
@@ -124,4 +122,22 @@ export class HeaterAccessory {
|
|
|
124
122
|
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
125
123
|
}
|
|
126
124
|
}
|
|
125
|
+
|
|
126
|
+
updateState(newSubDevice: SubDevice) {
|
|
127
|
+
const oldSubDevice = this.accessory.context.subDevice;
|
|
128
|
+
if (oldSubDevice.deviceStatus !== newSubDevice.deviceStatus) {
|
|
129
|
+
this.platform.log.info(`Updating state for ${this.accessory.displayName}: ${newSubDevice.deviceStatus ? 'ON' : 'OFF'}`);
|
|
130
|
+
this.service.updateCharacteristic(this.platform.Characteristic.Active, newSubDevice.deviceStatus === 1);
|
|
131
|
+
}
|
|
132
|
+
if (oldSubDevice.currentTemp !== newSubDevice.currentTemp) {
|
|
133
|
+
this.platform.log.info(`Updating current temperature for ${this.accessory.displayName}: ${newSubDevice.currentTemp}`);
|
|
134
|
+
this.service.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, newSubDevice.currentTemp as number);
|
|
135
|
+
}
|
|
136
|
+
if (oldSubDevice.setTemp !== newSubDevice.setTemp) {
|
|
137
|
+
const newTemp = (newSubDevice.setTemp as number) < 5 ? 5 : (newSubDevice.setTemp as number);
|
|
138
|
+
this.platform.log.info(`Updating target temperature for ${this.accessory.displayName}: ${newTemp}`);
|
|
139
|
+
this.service.updateCharacteristic(this.platform.Characteristic.HeatingThresholdTemperature, newTemp);
|
|
140
|
+
}
|
|
141
|
+
this.accessory.context.subDevice = newSubDevice;
|
|
142
|
+
}
|
|
127
143
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
|
|
2
2
|
import { ShomePlatform } from '../platform.js';
|
|
3
|
+
import { SubDevice } from '../shomeClient.js';
|
|
3
4
|
|
|
4
5
|
export class LightAccessory {
|
|
5
6
|
private service: Service;
|
|
@@ -44,4 +45,12 @@ export class LightAccessory {
|
|
|
44
45
|
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
45
46
|
}
|
|
46
47
|
}
|
|
48
|
+
|
|
49
|
+
async updateState(newSubDevice: SubDevice) {
|
|
50
|
+
if (this.accessory.context.subDevice.deviceStatus !== newSubDevice.deviceStatus) {
|
|
51
|
+
this.platform.log.info(`Updating state for ${this.accessory.displayName}: ${newSubDevice.deviceStatus ? 'ON' : 'OFF'}`);
|
|
52
|
+
this.accessory.context.subDevice = newSubDevice;
|
|
53
|
+
this.service.updateCharacteristic(this.platform.Characteristic.On, await this.getOn());
|
|
54
|
+
}
|
|
55
|
+
}
|
|
47
56
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
|
|
2
2
|
import { ShomePlatform } from '../platform.js';
|
|
3
|
+
import { SubDevice } from '../shomeClient.js';
|
|
3
4
|
|
|
4
5
|
export class VentilatorAccessory {
|
|
5
6
|
private fanService: Service;
|
|
@@ -91,4 +92,19 @@ export class VentilatorAccessory {
|
|
|
91
92
|
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
92
93
|
}
|
|
93
94
|
}
|
|
95
|
+
|
|
96
|
+
async updateState(newSubDevice: SubDevice) {
|
|
97
|
+
const oldSubDevice = this.accessory.context.subDevice;
|
|
98
|
+
if (oldSubDevice.deviceStatus !== newSubDevice.deviceStatus) {
|
|
99
|
+
this.platform.log.info(`Updating state for ${this.accessory.displayName}: ${newSubDevice.deviceStatus ? 'ON' : 'OFF'}`);
|
|
100
|
+
this.fanService.updateCharacteristic(this.platform.Characteristic.Active, newSubDevice.deviceStatus === 1);
|
|
101
|
+
}
|
|
102
|
+
if (oldSubDevice.windSpeedMode !== newSubDevice.windSpeedMode) {
|
|
103
|
+
this.platform.log.info(`Updating rotation speed for ${this.accessory.displayName}`);
|
|
104
|
+
this.accessory.context.subDevice = newSubDevice;
|
|
105
|
+
this.fanService.updateCharacteristic(this.platform.Characteristic.RotationSpeed, await this.getRotationSpeed());
|
|
106
|
+
} else {
|
|
107
|
+
this.accessory.context.subDevice = newSubDevice;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
94
110
|
}
|
package/src/platform.ts
CHANGED
|
@@ -9,11 +9,17 @@ import { DoorlockAccessory } from './accessories/doorlockAccessory.js';
|
|
|
9
9
|
const CONTROLLABLE_MULTI_DEVICE_TYPES = ['LIGHT', 'HEATER', 'VENTILATOR'];
|
|
10
10
|
const SPECIAL_CONTROLLABLE_TYPES = ['DOORLOCK'];
|
|
11
11
|
|
|
12
|
+
// Define a type for our accessory handlers
|
|
13
|
+
type AccessoryHandler = LightAccessory | VentilatorAccessory | HeaterAccessory | DoorlockAccessory;
|
|
14
|
+
|
|
12
15
|
export class ShomePlatform implements DynamicPlatformPlugin {
|
|
13
16
|
public readonly Service: typeof Service;
|
|
14
17
|
public readonly Characteristic: typeof Characteristic;
|
|
15
18
|
public readonly accessories: PlatformAccessory[] = [];
|
|
16
19
|
public readonly shomeClient: ShomeClient;
|
|
20
|
+
private readonly accessoryHandlers = new Map<string, AccessoryHandler>();
|
|
21
|
+
private pollingInterval: number;
|
|
22
|
+
private pollingTimer?: NodeJS.Timeout;
|
|
17
23
|
|
|
18
24
|
constructor(
|
|
19
25
|
public readonly log: Logger,
|
|
@@ -22,12 +28,11 @@ export class ShomePlatform implements DynamicPlatformPlugin {
|
|
|
22
28
|
) {
|
|
23
29
|
this.Service = this.api.hap.Service;
|
|
24
30
|
this.Characteristic = this.api.hap.Characteristic;
|
|
31
|
+
this.pollingInterval = this.config.pollingInterval ?? 3000;
|
|
25
32
|
|
|
26
|
-
// 1. Validate configuration
|
|
27
33
|
if (!this.config.username || !this.config.password || !this.config.deviceId) {
|
|
28
34
|
this.log.error('Missing required configuration. Please check your config.json file.');
|
|
29
35
|
this.log.error('Required fields are: "username", "password", and "deviceId".');
|
|
30
|
-
// Prevent further initialization by not creating the client
|
|
31
36
|
this.shomeClient = null!;
|
|
32
37
|
return;
|
|
33
38
|
}
|
|
@@ -40,8 +45,16 @@ export class ShomePlatform implements DynamicPlatformPlugin {
|
|
|
40
45
|
);
|
|
41
46
|
|
|
42
47
|
this.api.on('didFinishLaunching', () => {
|
|
43
|
-
// Defer device discovery until Homebridge is fully launched.
|
|
44
48
|
this.discoverDevices();
|
|
49
|
+
if (this.pollingInterval > 0) {
|
|
50
|
+
this.startPolling();
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
this.api.on('shutdown', () => {
|
|
55
|
+
if (this.pollingTimer) {
|
|
56
|
+
clearInterval(this.pollingTimer);
|
|
57
|
+
}
|
|
45
58
|
});
|
|
46
59
|
}
|
|
47
60
|
|
|
@@ -50,23 +63,22 @@ export class ShomePlatform implements DynamicPlatformPlugin {
|
|
|
50
63
|
}
|
|
51
64
|
|
|
52
65
|
async discoverDevices() {
|
|
53
|
-
// Gracefully handle cases where the client was not initialized due to config errors
|
|
54
66
|
if (!this.shomeClient) {
|
|
55
67
|
return;
|
|
56
68
|
}
|
|
57
69
|
|
|
58
70
|
try {
|
|
71
|
+
this.log.info('Discovering devices...');
|
|
59
72
|
const devices = await this.shomeClient.getDeviceList();
|
|
60
73
|
const foundAccessories: PlatformAccessory[] = [];
|
|
61
74
|
|
|
62
75
|
if (!devices || devices.length === 0) {
|
|
63
|
-
this.log.warn('No devices found on your sHome account.
|
|
76
|
+
this.log.warn('No devices found on your sHome account.');
|
|
64
77
|
}
|
|
65
78
|
|
|
66
79
|
for (const device of devices) {
|
|
67
80
|
if (CONTROLLABLE_MULTI_DEVICE_TYPES.includes(device.thngModelTypeName)) {
|
|
68
81
|
const deviceInfoList = await this.shomeClient.getDeviceInfo(device.thngId, device.thngModelTypeName);
|
|
69
|
-
|
|
70
82
|
if (deviceInfoList) {
|
|
71
83
|
for (const subDevice of deviceInfoList) {
|
|
72
84
|
const uuid = this.api.hap.uuid.generate(`${device.thngId}-${subDevice.deviceId}`);
|
|
@@ -90,10 +102,11 @@ export class ShomePlatform implements DynamicPlatformPlugin {
|
|
|
90
102
|
if (accessoriesToRemove.length > 0) {
|
|
91
103
|
this.log.info('Removing stale accessories:', accessoriesToRemove.map(a => a.displayName));
|
|
92
104
|
this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, accessoriesToRemove);
|
|
105
|
+
accessoriesToRemove.forEach(acc => this.accessoryHandlers.delete(acc.UUID));
|
|
93
106
|
}
|
|
107
|
+
this.log.info('Device discovery finished.');
|
|
94
108
|
} catch (error) {
|
|
95
109
|
this.log.error('Failed to discover devices due to a network or API error.');
|
|
96
|
-
this.log.error('Please check your network connection and sHome credentials. The plugin will not be able to control devices.');
|
|
97
110
|
}
|
|
98
111
|
}
|
|
99
112
|
|
|
@@ -120,19 +133,55 @@ export class ShomePlatform implements DynamicPlatformPlugin {
|
|
|
120
133
|
|
|
121
134
|
createAccessory(accessory: PlatformAccessory) {
|
|
122
135
|
const device = accessory.context.device;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
+
const accessoryType = device.thngModelTypeName;
|
|
137
|
+
|
|
138
|
+
if (!this.accessoryHandlers.has(accessory.UUID)) {
|
|
139
|
+
switch (accessoryType) {
|
|
140
|
+
case 'LIGHT':
|
|
141
|
+
this.accessoryHandlers.set(accessory.UUID, new LightAccessory(this, accessory));
|
|
142
|
+
break;
|
|
143
|
+
case 'VENTILATOR':
|
|
144
|
+
this.accessoryHandlers.set(accessory.UUID, new VentilatorAccessory(this, accessory));
|
|
145
|
+
break;
|
|
146
|
+
case 'HEATER':
|
|
147
|
+
this.accessoryHandlers.set(accessory.UUID, new HeaterAccessory(this, accessory));
|
|
148
|
+
break;
|
|
149
|
+
case 'DOORLOCK':
|
|
150
|
+
this.accessoryHandlers.set(accessory.UUID, new DoorlockAccessory(this, accessory));
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
136
153
|
}
|
|
137
154
|
}
|
|
155
|
+
|
|
156
|
+
startPolling() {
|
|
157
|
+
this.log.info(`Starting periodic device state polling every ${this.pollingInterval / 1000} seconds.`);
|
|
158
|
+
this.pollingTimer = setInterval(async () => {
|
|
159
|
+
this.log.debug('Polling for device updates...');
|
|
160
|
+
try {
|
|
161
|
+
const devices = await this.shomeClient.getDeviceList();
|
|
162
|
+
for (const device of devices) {
|
|
163
|
+
if (CONTROLLABLE_MULTI_DEVICE_TYPES.includes(device.thngModelTypeName)) {
|
|
164
|
+
const deviceInfoList = await this.shomeClient.getDeviceInfo(device.thngId, device.thngModelTypeName);
|
|
165
|
+
if (deviceInfoList) {
|
|
166
|
+
for (const subDevice of deviceInfoList) {
|
|
167
|
+
const subUuid = this.api.hap.uuid.generate(`${device.thngId}-${subDevice.deviceId}`);
|
|
168
|
+
const handler = this.accessoryHandlers.get(subUuid) as LightAccessory | HeaterAccessory | VentilatorAccessory;
|
|
169
|
+
if (handler) {
|
|
170
|
+
handler.updateState(subDevice);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
} else if (SPECIAL_CONTROLLABLE_TYPES.includes(device.thngModelTypeName)) {
|
|
175
|
+
const uuid = this.api.hap.uuid.generate(device.thngId);
|
|
176
|
+
const handler = this.accessoryHandlers.get(uuid) as DoorlockAccessory;
|
|
177
|
+
if (handler) {
|
|
178
|
+
handler.updateState(device);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
} catch (error) {
|
|
183
|
+
this.log.error('An error occurred during polling:', error);
|
|
184
|
+
}
|
|
185
|
+
}, this.pollingInterval);
|
|
186
|
+
}
|
|
138
187
|
}
|