homebridge-xihome-plugin 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +176 -0
- package/README.md +215 -0
- package/config.schema.json +18 -0
- package/dist/@types/device.d.ts +65 -0
- package/dist/@types/device.js +2 -0
- package/dist/@types/device.js.map +1 -0
- package/dist/@types/index.d.ts +5 -0
- package/dist/@types/index.js +2 -0
- package/dist/@types/index.js.map +1 -0
- package/dist/accessory/baseAccessory.d.ts +3 -0
- package/dist/accessory/baseAccessory.js +2 -0
- package/dist/accessory/baseAccessory.js.map +1 -0
- package/dist/accessory/hcl.d.ts +25 -0
- package/dist/accessory/hcl.js +79 -0
- package/dist/accessory/hcl.js.map +1 -0
- package/dist/accessory/heater.d.ts +23 -0
- package/dist/accessory/heater.js +113 -0
- package/dist/accessory/heater.js.map +1 -0
- package/dist/accessory/light.d.ts +40 -0
- package/dist/accessory/light.js +78 -0
- package/dist/accessory/light.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/base.d.ts +17 -0
- package/dist/modules/base.js +65 -0
- package/dist/modules/base.js.map +1 -0
- package/dist/modules/heater.d.ts +9 -0
- package/dist/modules/heater.js +32 -0
- package/dist/modules/heater.js.map +1 -0
- package/dist/modules/light.d.ts +10 -0
- package/dist/modules/light.js +47 -0
- package/dist/modules/light.js.map +1 -0
- package/dist/platform.d.ts +31 -0
- package/dist/platform.js +146 -0
- package/dist/platform.js.map +1 -0
- package/dist/settings.d.ts +8 -0
- package/dist/settings.js +9 -0
- package/dist/settings.js.map +1 -0
- package/dist/util/client.d.ts +46 -0
- package/dist/util/client.js +171 -0
- package/dist/util/client.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform Accessory
|
|
3
|
+
* An instance of this class is created for each accessory your platform registers
|
|
4
|
+
* Each accessory may expose multiple services of different service types.
|
|
5
|
+
*/
|
|
6
|
+
export class HeaterAccessory {
|
|
7
|
+
platform;
|
|
8
|
+
accessory;
|
|
9
|
+
service;
|
|
10
|
+
/**
|
|
11
|
+
* These are just used to create a working example
|
|
12
|
+
* You should implement your own code to track the state of your accessory
|
|
13
|
+
*/
|
|
14
|
+
device;
|
|
15
|
+
constructor(platform, accessory) {
|
|
16
|
+
this.platform = platform;
|
|
17
|
+
this.accessory = accessory;
|
|
18
|
+
// set accessory information
|
|
19
|
+
this.accessory
|
|
20
|
+
.getService(this.platform.Service.AccessoryInformation)
|
|
21
|
+
.setCharacteristic(this.platform.Characteristic.Manufacturer, "Default-Manufacturer")
|
|
22
|
+
.setCharacteristic(this.platform.Characteristic.Model, "Default-Model")
|
|
23
|
+
.setCharacteristic(this.platform.Characteristic.SerialNumber, accessory.context.device.uuid);
|
|
24
|
+
// get the HeaterCooler service if it exists, otherwise create a new HeaterCooler service
|
|
25
|
+
// you can create multiple services for each accessory
|
|
26
|
+
this.service =
|
|
27
|
+
this.accessory.getService(this.platform.Service.Thermostat) ||
|
|
28
|
+
this.accessory.addService(this.platform.Service.Thermostat);
|
|
29
|
+
// set the service name, this is what is displayed as the default name on the Home app
|
|
30
|
+
// in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method.
|
|
31
|
+
this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.context.device.name);
|
|
32
|
+
this.device = accessory.context.device;
|
|
33
|
+
// each service must implement at-minimum the "required characteristics" for the given service type
|
|
34
|
+
// see https://developers.homebridge.io/#/service/Thermostat
|
|
35
|
+
this.service
|
|
36
|
+
.getCharacteristic(this.platform.Characteristic.CurrentHeatingCoolingState)
|
|
37
|
+
.setProps({
|
|
38
|
+
validValues: [
|
|
39
|
+
this.platform.Characteristic.CurrentHeatingCoolingState.HEAT,
|
|
40
|
+
this.platform.Characteristic.CurrentHeatingCoolingState.OFF,
|
|
41
|
+
],
|
|
42
|
+
})
|
|
43
|
+
.onGet(async () => {
|
|
44
|
+
return this.platform.Characteristic.CurrentHeatingCoolingState.HEAT;
|
|
45
|
+
})
|
|
46
|
+
.onSet(this.setOn.bind(this));
|
|
47
|
+
this.service
|
|
48
|
+
.getCharacteristic(this.platform.Characteristic.TargetHeatingCoolingState)
|
|
49
|
+
.setProps({
|
|
50
|
+
validValues: [
|
|
51
|
+
this.platform.Characteristic.TargetHeatingCoolingState.HEAT,
|
|
52
|
+
this.platform.Characteristic.TargetHeatingCoolingState.OFF,
|
|
53
|
+
],
|
|
54
|
+
})
|
|
55
|
+
.onGet(async () => {
|
|
56
|
+
const device = this.platform.client.getDevice(this.device.id);
|
|
57
|
+
return device.raw.status.power
|
|
58
|
+
? this.platform.Characteristic.TargetHeatingCoolingState.HEAT
|
|
59
|
+
: this.platform.Characteristic.TargetHeatingCoolingState.OFF;
|
|
60
|
+
})
|
|
61
|
+
.onSet(this.setOn.bind(this));
|
|
62
|
+
this.service
|
|
63
|
+
.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
|
|
64
|
+
.onGet(async () => {
|
|
65
|
+
const device = this.platform.client.getDevice(this.device.id);
|
|
66
|
+
return parseInt(device.raw.status.curtemp);
|
|
67
|
+
});
|
|
68
|
+
this.service
|
|
69
|
+
.getCharacteristic(this.platform.Characteristic.TargetTemperature)
|
|
70
|
+
.setProps({
|
|
71
|
+
minValue: 10,
|
|
72
|
+
maxValue: 40,
|
|
73
|
+
minStep: 1,
|
|
74
|
+
})
|
|
75
|
+
.onGet(async () => {
|
|
76
|
+
const device = this.platform.client.getDevice(this.device.id);
|
|
77
|
+
return Math.max(parseInt(device.raw.status.settemp), 10);
|
|
78
|
+
})
|
|
79
|
+
.onSet(this.setTemperature.bind(this));
|
|
80
|
+
this.service
|
|
81
|
+
.getCharacteristic(this.platform.Characteristic.TemperatureDisplayUnits)
|
|
82
|
+
.setProps({
|
|
83
|
+
validValues: [
|
|
84
|
+
this.platform.Characteristic.TemperatureDisplayUnits.CELSIUS,
|
|
85
|
+
],
|
|
86
|
+
})
|
|
87
|
+
.onGet(async () => {
|
|
88
|
+
const device = this.platform.client.getDevice(this.device.id);
|
|
89
|
+
return this.platform.Characteristic.TemperatureDisplayUnits.CELSIUS;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
async setOn(value) {
|
|
93
|
+
await this.platform.client.modules.heater.setHeaterState(this.device.id, {
|
|
94
|
+
power: value === "1",
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
async setTemperature(value) {
|
|
98
|
+
console.log("Setting Heater Temperature to", value);
|
|
99
|
+
await this.platform.client.modules.heater.setHeaterState(this.device.id, {
|
|
100
|
+
temperature: value,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
async updateState() {
|
|
104
|
+
const device = this.platform.client.getDevice(this.device.id);
|
|
105
|
+
this.device = device;
|
|
106
|
+
this.service.updateCharacteristic(this.platform.Characteristic.CurrentHeatingCoolingState, device.raw.status.power
|
|
107
|
+
? this.platform.Characteristic.CurrentHeatingCoolingState.HEAT
|
|
108
|
+
: this.platform.Characteristic.CurrentHeatingCoolingState.OFF);
|
|
109
|
+
this.service.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, parseInt(device.raw.status.curtemp));
|
|
110
|
+
this.service.updateCharacteristic(this.platform.Characteristic.TargetTemperature, Math.max(parseInt(device.raw.status.settemp), 10));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=heater.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heater.js","sourceRoot":"","sources":["../../src/accessory/heater.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { CharacteristicValue } from "homebridge";
|
|
2
|
+
import type { ExampleHomebridgePlatform } from "../platform.js";
|
|
3
|
+
import { XiHomePlatformAccessory as XiHomePlatformAccessory } from "../@types/index.js";
|
|
4
|
+
import { BaseAccessory } from "./baseAccessory.js";
|
|
5
|
+
/**
|
|
6
|
+
* Platform Accessory
|
|
7
|
+
* An instance of this class is created for each accessory your platform registers
|
|
8
|
+
* Each accessory may expose multiple services of different service types.
|
|
9
|
+
*/
|
|
10
|
+
export declare class LightAccessory implements BaseAccessory {
|
|
11
|
+
private readonly platform;
|
|
12
|
+
private readonly accessory;
|
|
13
|
+
private client;
|
|
14
|
+
private service;
|
|
15
|
+
/**
|
|
16
|
+
* These are just used to create a working example
|
|
17
|
+
* You should implement your own code to track the state of your accessory
|
|
18
|
+
*/
|
|
19
|
+
private state;
|
|
20
|
+
private device;
|
|
21
|
+
constructor(platform: ExampleHomebridgePlatform, accessory: XiHomePlatformAccessory<"light">);
|
|
22
|
+
setOn(value: CharacteristicValue): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Handle the "GET" requests from HomeKit
|
|
25
|
+
* These are sent when HomeKit wants to know the current state of the accessory, for example, checking if a Light bulb is on.
|
|
26
|
+
*
|
|
27
|
+
* GET requests should return as fast as possible. A long delay here will result in
|
|
28
|
+
* HomeKit being unresponsive and a bad user experience in general.
|
|
29
|
+
*
|
|
30
|
+
* If your device takes time to respond you should update the status of your device
|
|
31
|
+
* asynchronously instead using the `updateCharacteristic` method instead.
|
|
32
|
+
* In this case, you may decide not to implement `onGet` handlers, which may speed up
|
|
33
|
+
* the responsiveness of your device in the Home app.
|
|
34
|
+
|
|
35
|
+
* @example
|
|
36
|
+
* this.service.updateCharacteristic(this.platform.Characteristic.On, true)
|
|
37
|
+
*/
|
|
38
|
+
getOn(): Promise<CharacteristicValue>;
|
|
39
|
+
updateState(): Promise<void>;
|
|
40
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform Accessory
|
|
3
|
+
* An instance of this class is created for each accessory your platform registers
|
|
4
|
+
* Each accessory may expose multiple services of different service types.
|
|
5
|
+
*/
|
|
6
|
+
export class LightAccessory {
|
|
7
|
+
platform;
|
|
8
|
+
accessory;
|
|
9
|
+
client;
|
|
10
|
+
service;
|
|
11
|
+
/**
|
|
12
|
+
* These are just used to create a working example
|
|
13
|
+
* You should implement your own code to track the state of your accessory
|
|
14
|
+
*/
|
|
15
|
+
state = {
|
|
16
|
+
on: false,
|
|
17
|
+
};
|
|
18
|
+
device;
|
|
19
|
+
constructor(platform, accessory) {
|
|
20
|
+
this.platform = platform;
|
|
21
|
+
this.accessory = accessory;
|
|
22
|
+
this.client = platform.client;
|
|
23
|
+
// set accessory information
|
|
24
|
+
this.accessory
|
|
25
|
+
.getService(this.platform.Service.AccessoryInformation)
|
|
26
|
+
.setCharacteristic(this.platform.Characteristic.Manufacturer, "Default-Manufacturer")
|
|
27
|
+
.setCharacteristic(this.platform.Characteristic.Model, "Default-Model")
|
|
28
|
+
.setCharacteristic(this.platform.Characteristic.SerialNumber, accessory.context.device.uuid);
|
|
29
|
+
this.device = accessory.context.device;
|
|
30
|
+
// get the LightBulb service if it exists, otherwise create a new LightBulb service
|
|
31
|
+
// you can create multiple services for each accessory
|
|
32
|
+
this.service =
|
|
33
|
+
this.accessory.getService(this.platform.Service.Lightbulb) ||
|
|
34
|
+
this.accessory.addService(this.platform.Service.Lightbulb);
|
|
35
|
+
// set the service name, this is what is displayed as the default name on the Home app
|
|
36
|
+
// in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method.
|
|
37
|
+
this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.context.device.name);
|
|
38
|
+
// each service must implement at-minimum the "required characteristics" for the given service type
|
|
39
|
+
// see https://developers.homebridge.io/#/service/Lightbulb
|
|
40
|
+
// register handlers for the On/Off Characteristic
|
|
41
|
+
this.service
|
|
42
|
+
.getCharacteristic(this.platform.Characteristic.On)
|
|
43
|
+
.setValue(this.device.raw.status.power) // set the initial value based on the device status
|
|
44
|
+
.onSet(this.setOn.bind(this)) // SET - bind to the `setOn` method below
|
|
45
|
+
.onGet(this.getOn.bind(this)); // GET - bind to the `getOn` method below
|
|
46
|
+
}
|
|
47
|
+
async setOn(value) {
|
|
48
|
+
this.platform.log.debug("Setting Characteristic On to", value);
|
|
49
|
+
// implement your own code to turn your device on/off
|
|
50
|
+
this.state.on = value;
|
|
51
|
+
this.platform.log.debug("Set Characteristic On ->", value);
|
|
52
|
+
this.platform.client.modules.light.toggle(this.accessory.context.device.id, this.state.on);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Handle the "GET" requests from HomeKit
|
|
56
|
+
* These are sent when HomeKit wants to know the current state of the accessory, for example, checking if a Light bulb is on.
|
|
57
|
+
*
|
|
58
|
+
* GET requests should return as fast as possible. A long delay here will result in
|
|
59
|
+
* HomeKit being unresponsive and a bad user experience in general.
|
|
60
|
+
*
|
|
61
|
+
* If your device takes time to respond you should update the status of your device
|
|
62
|
+
* asynchronously instead using the `updateCharacteristic` method instead.
|
|
63
|
+
* In this case, you may decide not to implement `onGet` handlers, which may speed up
|
|
64
|
+
* the responsiveness of your device in the Home app.
|
|
65
|
+
|
|
66
|
+
* @example
|
|
67
|
+
* this.service.updateCharacteristic(this.platform.Characteristic.On, true)
|
|
68
|
+
*/
|
|
69
|
+
async getOn() {
|
|
70
|
+
const device = this.client.getDevice(this.device.id);
|
|
71
|
+
return device?.raw.status.power ?? false;
|
|
72
|
+
}
|
|
73
|
+
async updateState() {
|
|
74
|
+
const device = this.client.getDevice(this.device.id);
|
|
75
|
+
this.service.updateCharacteristic(this.platform.Characteristic.On, device?.raw.status.power ?? false);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=light.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"light.js","sourceRoot":"","sources":["../../src/accessory/light.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ExampleHomebridgePlatform } from './platform.js';
|
|
2
|
+
import { PLATFORM_NAME } from './settings.js';
|
|
3
|
+
/**
|
|
4
|
+
* This method registers the platform with Homebridge
|
|
5
|
+
*/
|
|
6
|
+
export default (api) => {
|
|
7
|
+
api.registerPlatform(PLATFORM_NAME, ExampleHomebridgePlatform);
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C;;GAEG;AACH,eAAe,CAAC,GAAQ,EAAE,EAAE;IAC1B,GAAG,CAAC,gBAAgB,CAAC,aAAa,EAAE,yBAAyB,CAAC,CAAC;AACjE,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Device } from "../@types/device.js";
|
|
2
|
+
import type XiHomeClient from "../util/client.js";
|
|
3
|
+
export default class BaseModule {
|
|
4
|
+
protected client: XiHomeClient;
|
|
5
|
+
deviceGroup: string;
|
|
6
|
+
apartmentInfo: {
|
|
7
|
+
dong_no: string;
|
|
8
|
+
ho_no: string;
|
|
9
|
+
apt_code: string;
|
|
10
|
+
};
|
|
11
|
+
private pollLock;
|
|
12
|
+
constructor(client: XiHomeClient);
|
|
13
|
+
init(): Promise<void>;
|
|
14
|
+
protected lockPolling(duration?: number): void;
|
|
15
|
+
protected listDevices(group: string): Promise<Device[]>;
|
|
16
|
+
poll(): Promise<void>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export default class BaseModule {
|
|
2
|
+
client;
|
|
3
|
+
deviceGroup = "";
|
|
4
|
+
apartmentInfo = {
|
|
5
|
+
dong_no: "211",
|
|
6
|
+
ho_no: "2204",
|
|
7
|
+
apt_code: "0009347",
|
|
8
|
+
};
|
|
9
|
+
pollLock = null;
|
|
10
|
+
constructor(client) {
|
|
11
|
+
this.client = client;
|
|
12
|
+
}
|
|
13
|
+
async init() {
|
|
14
|
+
const devices = await this.listDevices(this.deviceGroup);
|
|
15
|
+
for (const device of devices) {
|
|
16
|
+
this.client.addDevice(device);
|
|
17
|
+
}
|
|
18
|
+
this.poll();
|
|
19
|
+
}
|
|
20
|
+
lockPolling(duration = 10000) {
|
|
21
|
+
if (this.pollLock) {
|
|
22
|
+
clearTimeout(this.pollLock);
|
|
23
|
+
}
|
|
24
|
+
this.pollLock = setTimeout(() => {
|
|
25
|
+
this.pollLock = null;
|
|
26
|
+
}, duration);
|
|
27
|
+
}
|
|
28
|
+
async listDevices(group) {
|
|
29
|
+
const r = await this.client.requestWebviewSide({
|
|
30
|
+
path: "/device/by_device_group_main",
|
|
31
|
+
method: "GET",
|
|
32
|
+
params: {
|
|
33
|
+
dong_no: "211",
|
|
34
|
+
ho_no: "2204",
|
|
35
|
+
apt_code: "0009347",
|
|
36
|
+
device_group_main: group,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
return r.result.devices.map((d) => {
|
|
40
|
+
return {
|
|
41
|
+
id: d.device_id,
|
|
42
|
+
uuid: d.device_uuid,
|
|
43
|
+
name: d.device_name,
|
|
44
|
+
roomId: d.room_id,
|
|
45
|
+
group: d.device_group_main.split("_").slice(2).join(""), // "device_group_light" -> "light",
|
|
46
|
+
type: d.device_type,
|
|
47
|
+
raw: d,
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async poll() {
|
|
52
|
+
while (true) {
|
|
53
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
54
|
+
if (this.pollLock) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const devices = await this.listDevices(this.deviceGroup);
|
|
58
|
+
for (const device of devices) {
|
|
59
|
+
this.client.devices[device.id] = device;
|
|
60
|
+
this.client.accessories[device.id]?.updateState();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/modules/base.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,OAAO,UAAU;IACnB,MAAM,CAAe;IAE/B,WAAW,GAAW,EAAE,CAAC;IAEzB,aAAa,GAAG;QACd,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,MAAM;QACb,QAAQ,EAAE,SAAS;KACpB,CAAC;IAEM,QAAQ,GAA0B,IAAI,CAAC;IAE/C,YAAY,MAAoB;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAES,WAAW,CAAC,WAAmB,KAAK;QAC5C,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACvB,CAAC,EAAE,QAAQ,CAAC,CAAC;IACf,CAAC;IAES,KAAK,CAAC,WAAW,CAAC,KAAa;QACvC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;YAC7C,IAAI,EAAE,8BAA8B;YACpC,MAAM,EAAE,KAAK;YACb,MAAM,EAAE;gBACN,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,MAAM;gBACb,QAAQ,EAAE,SAAS;gBACnB,iBAAiB,EAAE,KAAK;aACzB;SACF,CAAC,CAAC;QACH,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAY,EAAE,EAAE;YAC3C,OAAO;gBACL,EAAE,EAAE,CAAC,CAAC,SAAS;gBACf,IAAI,EAAE,CAAC,CAAC,WAAW;gBACnB,IAAI,EAAE,CAAC,CAAC,WAAW;gBACnB,MAAM,EAAE,CAAC,CAAC,OAAO;gBACjB,KAAK,EAAE,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAQ,EAAE,mCAAmC;gBACnG,IAAI,EAAE,CAAC,CAAC,WAAkB;gBAC1B,GAAG,EAAE,CAAC;aACU,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;YAC1D,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,SAAS;YACX,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACzD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;gBACxC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC;YACpD,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { HeaterDevice } from "../@types/device.js";
|
|
2
|
+
import BaseModule from "./base.js";
|
|
3
|
+
export default class Heater extends BaseModule {
|
|
4
|
+
deviceGroup: string;
|
|
5
|
+
setHeaterState(deviceId: string, options: {
|
|
6
|
+
power?: boolean;
|
|
7
|
+
temperature?: number;
|
|
8
|
+
}): Promise<HeaterDevice["status"]>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import BaseModule from "./base.js";
|
|
2
|
+
export default class Heater extends BaseModule {
|
|
3
|
+
deviceGroup = "device_group_heating";
|
|
4
|
+
async setHeaterState(deviceId, options) {
|
|
5
|
+
const prev = this.client.devices[deviceId].raw
|
|
6
|
+
.status;
|
|
7
|
+
if (options.power !== undefined) {
|
|
8
|
+
prev.settemp = options.power ? prev.curtemp : prev.settemp;
|
|
9
|
+
prev.power = options.power;
|
|
10
|
+
prev.mode = options.power ? 0 : 1;
|
|
11
|
+
}
|
|
12
|
+
if (options.temperature !== undefined) {
|
|
13
|
+
prev.settemp = options.temperature.toString();
|
|
14
|
+
}
|
|
15
|
+
const r = await this.client.requestWebviewSide({
|
|
16
|
+
path: "/device/heating/command",
|
|
17
|
+
method: "POST",
|
|
18
|
+
body: {
|
|
19
|
+
device_id: deviceId,
|
|
20
|
+
status: {
|
|
21
|
+
...prev,
|
|
22
|
+
},
|
|
23
|
+
...this.apartmentInfo,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
const currentStatus = r.result.status;
|
|
27
|
+
this.client.devices[deviceId].raw.status = currentStatus;
|
|
28
|
+
this.lockPolling();
|
|
29
|
+
return r.result;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=heater.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heater.js","sourceRoot":"","sources":["../../src/modules/heater.ts"],"names":[],"mappings":"AACA,OAAO,UAAU,MAAM,WAAW,CAAC;AAEnC,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,UAAU;IACnC,WAAW,GAAG,sBAAsB,CAAC;IAE9C,KAAK,CAAC,cAAc,CAClB,QAAgB,EAChB,OAAgD;QAEhD,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG;aAC3C,MAAgC,CAAC;QACpC,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;YAC3D,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;YAC3B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACtC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;QAChD,CAAC;QACD,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;YAC7C,IAAI,EAAE,yBAAyB;YAC/B,MAAM,EAAE,MAAM;YACd,IAAI,EAAE;gBACJ,SAAS,EAAE,QAAQ;gBACnB,MAAM,EAAE;oBACN,GAAG,IAAI;iBACR;gBACD,GAAG,IAAI,CAAC,aAAa;aACtB;SACF,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,MAAgC,CAAC;QAEhE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,aAAa,CAAC;QACzD,IAAI,CAAC,WAAW,EAAE,CAAC;QAEnB,OAAO,CAAC,CAAC,MAAM,CAAC;IAClB,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { HclLightDevice, LightDevice } from "../@types/device.js";
|
|
2
|
+
import BaseModule from "./base.js";
|
|
3
|
+
export default class Light extends BaseModule {
|
|
4
|
+
deviceGroup: string;
|
|
5
|
+
toggle(deviceId: string, on: boolean): Promise<LightDevice["status"]>;
|
|
6
|
+
setHclState(deviceId: string, options: {
|
|
7
|
+
power?: boolean;
|
|
8
|
+
brightness?: number;
|
|
9
|
+
}): Promise<HclLightDevice["status"]>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import BaseModule from "./base.js";
|
|
2
|
+
export default class Light extends BaseModule {
|
|
3
|
+
deviceGroup = "device_group_light";
|
|
4
|
+
async toggle(deviceId, on) {
|
|
5
|
+
const r = await this.client.requestWebviewSide({
|
|
6
|
+
path: "/device/light/command",
|
|
7
|
+
method: "POST",
|
|
8
|
+
body: {
|
|
9
|
+
device_id: deviceId,
|
|
10
|
+
status: {
|
|
11
|
+
power: on,
|
|
12
|
+
},
|
|
13
|
+
...this.apartmentInfo,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
const currentStatus = r.result;
|
|
17
|
+
this.client.devices[deviceId].raw.status = currentStatus;
|
|
18
|
+
this.lockPolling();
|
|
19
|
+
return r.result;
|
|
20
|
+
}
|
|
21
|
+
async setHclState(deviceId, options) {
|
|
22
|
+
const prev = this.client.devices[deviceId].raw
|
|
23
|
+
.status;
|
|
24
|
+
if (options.power !== undefined) {
|
|
25
|
+
prev.power = options.power;
|
|
26
|
+
}
|
|
27
|
+
if (options.brightness !== undefined) {
|
|
28
|
+
prev.dimming = options.brightness.toString();
|
|
29
|
+
}
|
|
30
|
+
const r = await this.client.requestWebviewSide({
|
|
31
|
+
path: "/device/hcl/command",
|
|
32
|
+
method: "POST",
|
|
33
|
+
body: {
|
|
34
|
+
device_id: deviceId,
|
|
35
|
+
status: {
|
|
36
|
+
...prev,
|
|
37
|
+
},
|
|
38
|
+
...this.apartmentInfo,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
const currentStatus = r.result.status;
|
|
42
|
+
this.client.devices[deviceId].raw.status = currentStatus;
|
|
43
|
+
this.lockPolling();
|
|
44
|
+
return r.result;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=light.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"light.js","sourceRoot":"","sources":["../../src/modules/light.ts"],"names":[],"mappings":"AACA,OAAO,UAAU,MAAM,WAAW,CAAC;AAEnC,MAAM,CAAC,OAAO,OAAO,KAAM,SAAQ,UAAU;IAClC,WAAW,GAAG,oBAAoB,CAAC;IAE5C,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,EAAW;QACxC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;YAC7C,IAAI,EAAE,uBAAuB;YAC7B,MAAM,EAAE,MAAM;YACd,IAAI,EAAE;gBACJ,SAAS,EAAE,QAAQ;gBACnB,MAAM,EAAE;oBACN,KAAK,EAAE,EAAE;iBACV;gBACD,GAAG,IAAI,CAAC,aAAa;aACtB;SACF,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,CAAC,CAAC,MAA+B,CAAC;QAExD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,aAAa,CAAC;QACzD,IAAI,CAAC,WAAW,EAAE,CAAC;QAEnB,OAAO,CAAC,CAAC,MAAM,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,WAAW,CACf,QAAgB,EAChB,OAA+C;QAE/C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG;aAC3C,MAAkC,CAAC;QACtC,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC7B,CAAC;QACD,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACrC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;QAC/C,CAAC;QACD,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;YAC7C,IAAI,EAAE,qBAAqB;YAC3B,MAAM,EAAE,MAAM;YACd,IAAI,EAAE;gBACJ,SAAS,EAAE,QAAQ;gBACnB,MAAM,EAAE;oBACN,GAAG,IAAI;iBACR;gBACD,GAAG,IAAI,CAAC,aAAa;aACtB;SACF,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,MAAkC,CAAC;QAElE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,aAAa,CAAC;QACzD,IAAI,CAAC,WAAW,EAAE,CAAC;QAEnB,OAAO,CAAC,CAAC,MAAM,CAAC;IAClB,CAAC;CACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type API, type Characteristic, type DynamicPlatformPlugin, type Logging, type PlatformAccessory, type PlatformConfig, type Service } from "homebridge";
|
|
2
|
+
import XiHomeClient from "./util/client.js";
|
|
3
|
+
/**
|
|
4
|
+
* HomebridgePlatform
|
|
5
|
+
* This class is the main constructor for your plugin, this is where you should
|
|
6
|
+
* parse the user config and discover/register accessories with Homebridge.
|
|
7
|
+
*/
|
|
8
|
+
export declare class ExampleHomebridgePlatform implements DynamicPlatformPlugin {
|
|
9
|
+
readonly log: Logging;
|
|
10
|
+
readonly config: PlatformConfig;
|
|
11
|
+
readonly api: API;
|
|
12
|
+
readonly Service: typeof Service;
|
|
13
|
+
readonly Characteristic: typeof Characteristic;
|
|
14
|
+
readonly accessories: Map<string, PlatformAccessory>;
|
|
15
|
+
readonly discoveredCacheUUIDs: string[];
|
|
16
|
+
client: XiHomeClient;
|
|
17
|
+
constructor(log: Logging, config: PlatformConfig, api: API);
|
|
18
|
+
/**
|
|
19
|
+
* This function is invoked when homebridge restores cached accessories from disk at startup.
|
|
20
|
+
* It should be used to set up event handlers for characteristics and update respective values.
|
|
21
|
+
*/
|
|
22
|
+
configureAccessory(accessory: PlatformAccessory): void;
|
|
23
|
+
/**
|
|
24
|
+
* This is an example method showing how to register discovered accessories.
|
|
25
|
+
* Accessories must only be registered once, previously created accessories
|
|
26
|
+
* must not be registered again to prevent "duplicate UUID" errors.
|
|
27
|
+
*/
|
|
28
|
+
discoverDevices(): Promise<void>;
|
|
29
|
+
private determineCategory;
|
|
30
|
+
private instantiateAccessory;
|
|
31
|
+
}
|
package/dist/platform.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { PLATFORM_NAME, PLUGIN_NAME } from "./settings.js";
|
|
2
|
+
import XiHomeClient from "./util/client.js";
|
|
3
|
+
import { LightAccessory } from "./accessory/light.js";
|
|
4
|
+
import { HCLAccessory } from "./accessory/hcl.js";
|
|
5
|
+
import { HeaterAccessory } from "./accessory/heater.js";
|
|
6
|
+
const dictionary = {
|
|
7
|
+
LivingRoom: "거실",
|
|
8
|
+
Room: "침실",
|
|
9
|
+
};
|
|
10
|
+
function getRoom(roomId) {
|
|
11
|
+
for (const [key, value] of Object.entries(dictionary)) {
|
|
12
|
+
if (roomId.includes(key)) {
|
|
13
|
+
return roomId.replace(key, value);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
throw new Error(`Unknown roomId: ${roomId}`);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* HomebridgePlatform
|
|
20
|
+
* This class is the main constructor for your plugin, this is where you should
|
|
21
|
+
* parse the user config and discover/register accessories with Homebridge.
|
|
22
|
+
*/
|
|
23
|
+
export class ExampleHomebridgePlatform {
|
|
24
|
+
log;
|
|
25
|
+
config;
|
|
26
|
+
api;
|
|
27
|
+
Service;
|
|
28
|
+
Characteristic;
|
|
29
|
+
// this is used to track restored cached accessories
|
|
30
|
+
accessories = new Map();
|
|
31
|
+
discoveredCacheUUIDs = [];
|
|
32
|
+
client;
|
|
33
|
+
constructor(log, config, api) {
|
|
34
|
+
this.log = log;
|
|
35
|
+
this.config = config;
|
|
36
|
+
this.api = api;
|
|
37
|
+
this.Service = api.hap.Service;
|
|
38
|
+
this.Characteristic = api.hap.Characteristic;
|
|
39
|
+
this.log.debug("Finished initializing platform:", this.config.name);
|
|
40
|
+
this.api.on("didFinishLaunching", () => {
|
|
41
|
+
this.log.debug("Executed didFinishLaunching callback");
|
|
42
|
+
// run the method to discover / register your devices as accessories
|
|
43
|
+
this.discoverDevices();
|
|
44
|
+
});
|
|
45
|
+
this.client = new XiHomeClient(this);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* This function is invoked when homebridge restores cached accessories from disk at startup.
|
|
49
|
+
* It should be used to set up event handlers for characteristics and update respective values.
|
|
50
|
+
*/
|
|
51
|
+
configureAccessory(accessory) {
|
|
52
|
+
this.log.info("Loading accessory from cache:", accessory.displayName, "UUID:", accessory.UUID);
|
|
53
|
+
// add the restored accessory to the accessories cache, so we can track if it has already been registered
|
|
54
|
+
this.accessories.set(accessory.UUID, accessory);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* This is an example method showing how to register discovered accessories.
|
|
58
|
+
* Accessories must only be registered once, previously created accessories
|
|
59
|
+
* must not be registered again to prevent "duplicate UUID" errors.
|
|
60
|
+
*/
|
|
61
|
+
async discoverDevices() {
|
|
62
|
+
// if (<any>true) return;
|
|
63
|
+
this.log.info("Discovering devices...");
|
|
64
|
+
await this.client.init();
|
|
65
|
+
const devices = this.client.devices;
|
|
66
|
+
// loop over the discovered devices and register each one if it has not already been registered
|
|
67
|
+
for (const [id, device] of Object.entries(devices)) {
|
|
68
|
+
// generate a unique id for the accessory this should be generated from
|
|
69
|
+
// something globally unique, but constant, for example, the device serial
|
|
70
|
+
// number or MAC address
|
|
71
|
+
const uuid = device.uuid;
|
|
72
|
+
// this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [
|
|
73
|
+
// ...(this.accessories.get(uuid) ? [this.accessories.get(uuid)!] : []),
|
|
74
|
+
// ]);
|
|
75
|
+
// see if an accessory with the same uuid has already been registered and restored from
|
|
76
|
+
// the cached devices we stored in the `configureAccessory` method above
|
|
77
|
+
let accessory = this.accessories.get(uuid);
|
|
78
|
+
this.log.debug("Processing device:", device.name, "UUID:", uuid);
|
|
79
|
+
if (accessory) {
|
|
80
|
+
this.instantiateAccessory(accessory);
|
|
81
|
+
this.log.info("Restoring existing accessory from cache:", accessory.displayName);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
this.log.info(`Registering device: ${device.name} (${device.id}) AS`, `${getRoom(device.roomId)} ${device.raw.device_name_by_room}`);
|
|
85
|
+
try {
|
|
86
|
+
const newAccessory = new this.api.platformAccessory(`${getRoom(device.roomId)} ${device.raw.device_name_by_room}`, uuid, this.determineCategory(device.type));
|
|
87
|
+
newAccessory.context.device = device;
|
|
88
|
+
this.instantiateAccessory(newAccessory);
|
|
89
|
+
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [
|
|
90
|
+
newAccessory,
|
|
91
|
+
]);
|
|
92
|
+
accessory = newAccessory;
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
this.log.error(`Failed to register device: ${device.name} (${device.id})`, error);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// push into discoveredCacheUUIDs
|
|
100
|
+
this.discoveredCacheUUIDs.push(uuid);
|
|
101
|
+
}
|
|
102
|
+
// you can also deal with accessories from the cache which are no longer present by removing them from Homebridge
|
|
103
|
+
// for example, if your plugin logs into a cloud account to retrieve a device list, and a user has previously removed a device
|
|
104
|
+
// from this cloud account, then this device will no longer be present in the device list but will still be in the Homebridge cache
|
|
105
|
+
for (const [uuid, accessory] of this.accessories) {
|
|
106
|
+
if (!this.discoveredCacheUUIDs.includes(uuid)) {
|
|
107
|
+
try {
|
|
108
|
+
this.log.info("Removing existing accessory from cache:", accessory.displayName);
|
|
109
|
+
this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [
|
|
110
|
+
accessory,
|
|
111
|
+
]);
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
this.log.error(`Failed to unregister accessory: ${accessory.displayName} (${accessory.UUID})`, error);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
determineCategory(deviceType) {
|
|
120
|
+
switch (deviceType) {
|
|
121
|
+
case "heater":
|
|
122
|
+
return 9 /* Categories.THERMOSTAT */;
|
|
123
|
+
default:
|
|
124
|
+
return 5 /* Categories.LIGHTBULB */;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
instantiateAccessory(accessory) {
|
|
128
|
+
const device = accessory.context.device;
|
|
129
|
+
this.log.debug("Instantiating accessory for device:", device.name, "type:", device.type);
|
|
130
|
+
let accessoryInstance;
|
|
131
|
+
switch (device.type) {
|
|
132
|
+
case "heating":
|
|
133
|
+
case "heater":
|
|
134
|
+
accessoryInstance = new HeaterAccessory(this, accessory);
|
|
135
|
+
break;
|
|
136
|
+
case "hcl":
|
|
137
|
+
accessoryInstance = new HCLAccessory(this, accessory);
|
|
138
|
+
break;
|
|
139
|
+
default: // light
|
|
140
|
+
accessoryInstance = new LightAccessory(this, accessory);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
this.client.accessories[device.id] = accessoryInstance;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=platform.js.map
|