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.
Files changed (43) hide show
  1. package/LICENSE +176 -0
  2. package/README.md +215 -0
  3. package/config.schema.json +18 -0
  4. package/dist/@types/device.d.ts +65 -0
  5. package/dist/@types/device.js +2 -0
  6. package/dist/@types/device.js.map +1 -0
  7. package/dist/@types/index.d.ts +5 -0
  8. package/dist/@types/index.js +2 -0
  9. package/dist/@types/index.js.map +1 -0
  10. package/dist/accessory/baseAccessory.d.ts +3 -0
  11. package/dist/accessory/baseAccessory.js +2 -0
  12. package/dist/accessory/baseAccessory.js.map +1 -0
  13. package/dist/accessory/hcl.d.ts +25 -0
  14. package/dist/accessory/hcl.js +79 -0
  15. package/dist/accessory/hcl.js.map +1 -0
  16. package/dist/accessory/heater.d.ts +23 -0
  17. package/dist/accessory/heater.js +113 -0
  18. package/dist/accessory/heater.js.map +1 -0
  19. package/dist/accessory/light.d.ts +40 -0
  20. package/dist/accessory/light.js +78 -0
  21. package/dist/accessory/light.js.map +1 -0
  22. package/dist/index.d.ts +6 -0
  23. package/dist/index.js +9 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/modules/base.d.ts +17 -0
  26. package/dist/modules/base.js +65 -0
  27. package/dist/modules/base.js.map +1 -0
  28. package/dist/modules/heater.d.ts +9 -0
  29. package/dist/modules/heater.js +32 -0
  30. package/dist/modules/heater.js.map +1 -0
  31. package/dist/modules/light.d.ts +10 -0
  32. package/dist/modules/light.js +47 -0
  33. package/dist/modules/light.js.map +1 -0
  34. package/dist/platform.d.ts +31 -0
  35. package/dist/platform.js +146 -0
  36. package/dist/platform.js.map +1 -0
  37. package/dist/settings.d.ts +8 -0
  38. package/dist/settings.js +9 -0
  39. package/dist/settings.js.map +1 -0
  40. package/dist/util/client.d.ts +46 -0
  41. package/dist/util/client.js +171 -0
  42. package/dist/util/client.js.map +1 -0
  43. 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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"}
@@ -0,0 +1,6 @@
1
+ import type { API } from 'homebridge';
2
+ /**
3
+ * This method registers the platform with Homebridge
4
+ */
5
+ declare const _default: (api: API) => void;
6
+ export default _default;
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
+ }
@@ -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