homebridge-smarthq-client 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 (84) hide show
  1. package/LICENSE +21 -0
  2. package/Readme.md +138 -0
  3. package/config.schema.json +146 -0
  4. package/dist/index.d.ts +6 -0
  5. package/dist/index.js +9 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/platform.d.ts +40 -0
  8. package/dist/platform.js +243 -0
  9. package/dist/platform.js.map +1 -0
  10. package/dist/refrigerator/controlLock.d.ts +19 -0
  11. package/dist/refrigerator/controlLock.js +85 -0
  12. package/dist/refrigerator/controlLock.js.map +1 -0
  13. package/dist/refrigerator/convertibleDrawer.d.ts +27 -0
  14. package/dist/refrigerator/convertibleDrawer.js +317 -0
  15. package/dist/refrigerator/convertibleDrawer.js.map +1 -0
  16. package/dist/refrigerator/dispenserLight.d.ts +19 -0
  17. package/dist/refrigerator/dispenserLight.js +85 -0
  18. package/dist/refrigerator/dispenserLight.js.map +1 -0
  19. package/dist/refrigerator/energy.d.ts +19 -0
  20. package/dist/refrigerator/energy.js +93 -0
  21. package/dist/refrigerator/energy.js.map +1 -0
  22. package/dist/refrigerator/freezer.d.ts +41 -0
  23. package/dist/refrigerator/freezer.js +188 -0
  24. package/dist/refrigerator/freezer.js.map +1 -0
  25. package/dist/refrigerator/iceMaker.d.ts +19 -0
  26. package/dist/refrigerator/iceMaker.js +81 -0
  27. package/dist/refrigerator/iceMaker.js.map +1 -0
  28. package/dist/refrigerator/interiorLight.d.ts +21 -0
  29. package/dist/refrigerator/interiorLight.js +100 -0
  30. package/dist/refrigerator/interiorLight.js.map +1 -0
  31. package/dist/refrigerator/refrigerator.d.ts +41 -0
  32. package/dist/refrigerator/refrigerator.js +204 -0
  33. package/dist/refrigerator/refrigerator.js.map +1 -0
  34. package/dist/refrigerator/refrigeratorAlerts.d.ts +36 -0
  35. package/dist/refrigerator/refrigeratorAlerts.js +204 -0
  36. package/dist/refrigerator/refrigeratorAlerts.js.map +1 -0
  37. package/dist/refrigerator/sabbathMode.d.ts +20 -0
  38. package/dist/refrigerator/sabbathMode.js +91 -0
  39. package/dist/refrigerator/sabbathMode.js.map +1 -0
  40. package/dist/refrigerator/temperatureUnits.d.ts +21 -0
  41. package/dist/refrigerator/temperatureUnits.js +147 -0
  42. package/dist/refrigerator/temperatureUnits.js.map +1 -0
  43. package/dist/refrigerator/turboCoolMode.d.ts +23 -0
  44. package/dist/refrigerator/turboCoolMode.js +134 -0
  45. package/dist/refrigerator/turboCoolMode.js.map +1 -0
  46. package/dist/refrigerator/waterFilter.d.ts +19 -0
  47. package/dist/refrigerator/waterFilter.js +89 -0
  48. package/dist/refrigerator/waterFilter.js.map +1 -0
  49. package/dist/refrigeratorServices.d.ts +5 -0
  50. package/dist/refrigeratorServices.js +54 -0
  51. package/dist/refrigeratorServices.js.map +1 -0
  52. package/dist/settings.d.ts +12 -0
  53. package/dist/settings.js +13 -0
  54. package/dist/settings.js.map +1 -0
  55. package/dist/smartHqApi.d.ts +29 -0
  56. package/dist/smartHqApi.js +267 -0
  57. package/dist/smartHqApi.js.map +1 -0
  58. package/dist/smarthq-types.d.ts +29 -0
  59. package/dist/smarthq-types.js +2 -0
  60. package/dist/smarthq-types.js.map +1 -0
  61. package/eslint.config.js +12 -0
  62. package/images/homebridge.svg +1 -0
  63. package/package.json +61 -0
  64. package/src/@types/homebridge-lib.d.ts +14 -0
  65. package/src/index.ts +11 -0
  66. package/src/platform.ts +300 -0
  67. package/src/refrigerator/controlLock.ts +103 -0
  68. package/src/refrigerator/convertibleDrawer.ts +381 -0
  69. package/src/refrigerator/dispenserLight.ts +103 -0
  70. package/src/refrigerator/energy.ts +106 -0
  71. package/src/refrigerator/freezer.ts +227 -0
  72. package/src/refrigerator/iceMaker.ts +100 -0
  73. package/src/refrigerator/interiorLight.ts +118 -0
  74. package/src/refrigerator/refrigerator.ts +241 -0
  75. package/src/refrigerator/refrigeratorAlerts.ts +228 -0
  76. package/src/refrigerator/sabbathMode.ts +111 -0
  77. package/src/refrigerator/temperatureUnits.ts +178 -0
  78. package/src/refrigerator/turboCoolMode.ts +164 -0
  79. package/src/refrigerator/waterFilter.ts +107 -0
  80. package/src/refrigeratorServices.ts +60 -0
  81. package/src/settings.ts +14 -0
  82. package/src/smartHqApi.ts +305 -0
  83. package/src/smarthq-types.ts +31 -0
  84. package/tsconfig.json +24 -0
@@ -0,0 +1,228 @@
1
+ import { CharacteristicValue, PlatformAccessory, Logging } from 'homebridge';
2
+ import { SmartHqPlatform } from '../platform.js';
3
+ import { SmartHqApi } from '../smartHqApi.js';
4
+ import chalk from 'chalk';
5
+ import { DevService } from '../smarthq-types.js';
6
+
7
+ /**
8
+ * Platform Accessory
9
+ * An instance of this class is created for each accessory your platform registers
10
+ * These switches can be used with Pushover switches in Homekit automations to send notifications to your iOS devices
11
+ */
12
+ export class RefrigeratorAlerts {
13
+
14
+ private alertDoorState: boolean = false;
15
+ private alertLeakState: boolean = false;
16
+ private alertFilterState: boolean = false;
17
+ private alertTemperatureState: boolean = false;
18
+ private alertUpdateState: boolean = false;
19
+
20
+ private readonly smartHqApi: SmartHqApi;
21
+ private log : Logging;
22
+
23
+ constructor(
24
+ private readonly platform: SmartHqPlatform,
25
+ private readonly accessory: PlatformAccessory,
26
+ public readonly deviceServices: DevService[],
27
+ public readonly deviceId: string
28
+ ) {
29
+ this.platform = platform;
30
+ this.accessory = accessory;
31
+ this.deviceServices = deviceServices;
32
+ this.deviceId = deviceId;
33
+ this.log = platform.log;
34
+
35
+ this.smartHqApi = new SmartHqApi(this.platform);
36
+ this.platform.debug('green', 'Adding alert/notification Switches');
37
+ // set accessory information
38
+ this.accessory.getService(this.platform.Service.AccessoryInformation)!
39
+ .setCharacteristic(this.platform.Characteristic.Manufacturer, 'GE')
40
+ .setCharacteristic(this.platform.Characteristic.Model, accessory.context.device.model || 'Default-Model')
41
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, accessory.context.device.serial || 'Default-Serial');
42
+
43
+
44
+ //=====================================================================================
45
+ // create new Switch services for notifications/alerts.
46
+ // These switches can be used with Pushover switches in Homekit automations to send notifications to your iOS devices
47
+ // Switches created here will be turned ON when an alert is detected and can be reset to OFF automatically or manually
48
+ // Alerts include: Door Open Alarms, High Temperature Alarms, Water Leak Alerts, Water Filter Change Alerts, OTA Updates(firmware)
49
+ //=====================================================================================
50
+ let displayName = "Alert Door";
51
+ const alertDoor = this.accessory.getService(displayName)
52
+ || this.accessory.addService(this.platform.Service.Switch, displayName, displayName);
53
+
54
+ alertDoor.setCharacteristic(this.platform.Characteristic.Name, displayName);
55
+ alertDoor.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
56
+ alertDoor.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
57
+ alertDoor.getCharacteristic(this.platform.Characteristic.On)
58
+ .onGet(this.getAlertDoorOn.bind(this))
59
+ .onSet(this.setAlertDoorOn.bind(this));
60
+
61
+ displayName = "Alert Temp";
62
+ const alertTemp = this.accessory.getService(displayName)
63
+ || this.accessory.addService(this.platform.Service.Switch, displayName, displayName);
64
+
65
+ alertTemp.setCharacteristic(this.platform.Characteristic.Name, displayName);
66
+ alertTemp.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
67
+ alertTemp.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
68
+ alertTemp.getCharacteristic(this.platform.Characteristic.On)
69
+ .onGet(this.getAlertTemperatureOn.bind(this))
70
+ .onSet(this.setAlertTemperatureOn.bind(this));
71
+
72
+ displayName = "Alert Leak";
73
+ const alertLeak = this.accessory.getService(displayName)
74
+ || this.accessory.addService(this.platform.Service.Switch, displayName, displayName);
75
+
76
+ alertLeak.setCharacteristic(this.platform.Characteristic.Name, displayName);
77
+ alertLeak.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
78
+ alertLeak.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
79
+ alertLeak.getCharacteristic(this.platform.Characteristic.On)
80
+ .onGet(this.getAlertLeakOn.bind(this))
81
+ .onSet(this.setAlertLeakOn.bind(this));
82
+
83
+ displayName = "Alert Filter";
84
+ const alertFilter = this.accessory.getService(displayName)
85
+ || this.accessory.addService(this.platform.Service.Switch, displayName, displayName);
86
+
87
+ alertFilter.setCharacteristic(this.platform.Characteristic.Name, displayName);
88
+ alertFilter.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
89
+ alertFilter.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
90
+ alertFilter.getCharacteristic(this.platform.Characteristic.On)
91
+ .onGet(this.getAlertFilterOn.bind(this))
92
+ .onSet(this.setAlertFilterOn.bind(this));
93
+
94
+ displayName = "Alert Firm";
95
+ const alertFirm = this.accessory.getService(displayName)
96
+ || this.accessory.addService(this.platform.Service.Switch, displayName, displayName);
97
+
98
+ alertFirm.setCharacteristic(this.platform.Characteristic.Name, displayName);
99
+ alertFirm.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
100
+ alertFirm.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
101
+ alertFirm.getCharacteristic(this.platform.Characteristic.On)
102
+ .onGet(this.getAlertUpdateOn.bind(this))
103
+ .onSet(this.setAlertUpdateOn.bind(this));
104
+
105
+ //=====================================================================================
106
+ // Updating characteristics values asynchronously.
107
+ //=====================================================================================
108
+
109
+ setInterval(() => {
110
+ // push the new value to HomeKit
111
+ this.getAlertDoorOn().then(state => {
112
+ alertDoor.getCharacteristic(this.platform.Characteristic.On).updateValue(state);
113
+ if (state) {
114
+ this.setAlertDoorOn(false);
115
+ }
116
+ });
117
+ this.getAlertTemperatureOn().then(state => {
118
+ alertTemp.getCharacteristic(this.platform.Characteristic.On).updateValue(state);
119
+ if (state) {
120
+ this.setAlertTemperatureOn(false);
121
+ }
122
+ });
123
+ this.getAlertLeakOn().then(state => {
124
+ alertLeak.getCharacteristic(this.platform.Characteristic.On).updateValue(state);
125
+ if (state) {
126
+ this.setAlertLeakOn(false);
127
+ }
128
+ });
129
+ this.getAlertFilterOn().then(state => {
130
+ alertFilter.getCharacteristic(this.platform.Characteristic.On).updateValue(state);
131
+ if (state) {
132
+ this.setAlertFilterOn(false);
133
+ }
134
+ });
135
+ this.getAlertUpdateOn().then(state => {
136
+ alertFirm.getCharacteristic(this.platform.Characteristic.On).updateValue(state);
137
+ if (state) {
138
+ this.setAlertUpdateOn(false);
139
+ }
140
+ });
141
+ }, 5000);
142
+
143
+ setInterval(() => {
144
+ this.checkForAlerts();
145
+ }, 60000);
146
+
147
+ }
148
+
149
+ //=====================================================================================
150
+ // Check for any alerts - filter for last minute
151
+ //=====================================================================================
152
+ async checkForAlerts() {
153
+ const alerts = await this.smartHqApi.getRecentAlerts();
154
+ if (alerts == null) {
155
+ return;
156
+ }
157
+ for (const alert of alerts) {
158
+ const type = alert.alertType;
159
+ if (type.includes('door.alarm')) {
160
+ this.log.warn(chalk.yellow(`Alert: ${alert.alertType} `));
161
+ this.setAlertDoorOn(true);
162
+ } else if (type.includes('temperature.high')) {
163
+ this.log.warn(chalk.red(`Alert: ${alert.alertType} `));
164
+ this.setAlertTemperatureOn(true);
165
+ } else if (type.includes('leak')) {
166
+ this.log.warn(chalk.red(`Alert: ${alert.alertType} `));
167
+ this.setAlertLeakOn(true);
168
+ } else if (type.includes('filter')) {
169
+ this.log.warn(chalk.red(`Alert: ${alert.alertType} `));
170
+ this.setAlertFilterOn(true);
171
+ } else if (type.includes('ota.update')) {
172
+ this.log.warn(chalk.red(`Alert: ${alert.alertType} `));
173
+ this.setAlertUpdateOn(true);
174
+ }
175
+ }
176
+ }
177
+
178
+
179
+ getAlertDoorOn(): Promise<CharacteristicValue> {
180
+ const currentValue = this.alertDoorState;
181
+
182
+ return Promise.resolve(currentValue);
183
+ }
184
+ getAlertTemperatureOn(): Promise<CharacteristicValue> {
185
+ const currentValue = this.alertTemperatureState;
186
+
187
+ return Promise.resolve(currentValue);
188
+ }
189
+ getAlertFilterOn(): Promise<CharacteristicValue> {
190
+ const currentValue = this.alertFilterState;
191
+
192
+ return Promise.resolve(currentValue);
193
+ }
194
+ getAlertUpdateOn(): Promise<CharacteristicValue> {
195
+ const currentValue = this.alertUpdateState;
196
+
197
+ return Promise.resolve(currentValue);
198
+ }
199
+ getAlertLeakOn(): Promise<CharacteristicValue> {
200
+ const currentValue = this.alertLeakState;
201
+
202
+ return Promise.resolve(currentValue);
203
+ }
204
+
205
+ /**
206
+ * Handle requests to set the "On" characteristic
207
+ */
208
+ setAlertDoorOn(value: CharacteristicValue) {
209
+ this.alertDoorState = value as boolean;
210
+ // Will reset the alert (turn switch OFF) after 5 seconds by code in the setInterval function above
211
+ }
212
+ setAlertTemperatureOn(value: CharacteristicValue) {
213
+ this.alertTemperatureState = value as boolean;
214
+ // Will reset the alert (turn switch OFF) after 5 seconds by code in the setInterval function above
215
+ }
216
+ setAlertFilterOn(value: CharacteristicValue) {
217
+ this.alertFilterState = value as boolean;
218
+ // Will reset the alert (turn switch OFF) after 5 seconds by code in the setInterval function above
219
+ }
220
+ setAlertUpdateOn(value: CharacteristicValue) {
221
+ this.alertUpdateState = value as boolean;
222
+ // Will reset the alert (turn switch OFF) after 5 seconds by code in the setInterval function above
223
+ }
224
+ setAlertLeakOn(value: CharacteristicValue) {
225
+ this.alertLeakState = value as boolean;
226
+ // Will reset the alert (turn switch OFF) after 5 seconds by code in the setInterval function above
227
+ }
228
+ }
@@ -0,0 +1,111 @@
1
+ import { CharacteristicValue, PlatformAccessory, Logging } from 'homebridge';
2
+ import { SmartHqPlatform } from '../platform.js';
3
+ import { SmartHqApi } from '../smartHqApi.js';
4
+ import { DevService } from '../smarthq-types.js';
5
+
6
+ /**
7
+ * Platform Accessory
8
+ * An instance of this class is created for each accessory your platform registers
9
+ * Each accessory may expose multiple services of different service types.
10
+ */
11
+ export class SabbathMode {
12
+ static sabbathModeStatus = false;private readonly smartHqApi: SmartHqApi;
13
+ private log : Logging;
14
+
15
+ constructor(
16
+ private readonly platform: SmartHqPlatform,
17
+ private readonly accessory: PlatformAccessory,
18
+ public readonly deviceServices: DevService[],
19
+ public readonly deviceId: string
20
+ ) {
21
+ this.platform = platform;
22
+ this.accessory = accessory;
23
+ this.deviceServices = deviceServices;
24
+ this.deviceId = deviceId;
25
+ this.log = platform.log;
26
+
27
+ this.smartHqApi = new SmartHqApi(this.platform);
28
+
29
+ //=====================================================================================
30
+ // Check to see if the device has any supported Sabbath Mode services
31
+ // If not, then don't add services for device that doesn't support it
32
+ //=====================================================================================
33
+
34
+ if (!this.platform.deviceSupportsThisService(this.deviceServices,
35
+ 'cloud.smarthq.device.appliance',
36
+ 'cloud.smarthq.service.toggle',
37
+ 'cloud.smarthq.domain.sabbath')) {
38
+ this.log.info('No supported Sabbath Mode service found for device: ' + this.accessory.displayName);
39
+ return;
40
+ }
41
+ this.platform.debug('green', 'Adding Sabbath Mode Switch');
42
+
43
+ // set accessory information
44
+
45
+ this.accessory.getService(this.platform.Service.AccessoryInformation)!
46
+ .setCharacteristic(this.platform.Characteristic.Manufacturer, 'GE')
47
+ .setCharacteristic(this.platform.Characteristic.Model, accessory.context.device.model || 'Default-Model')
48
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, accessory.context.device.serial || 'Default-Serial');
49
+
50
+ //=====================================================================================
51
+ // create a sabbath mode switch for the Refrigerator
52
+ //=====================================================================================
53
+ const displayName = "Sabbath Mode";
54
+
55
+ const sabbathMode = this.accessory.getService(displayName)
56
+ || this.accessory.addService(this.platform.Service.Switch, displayName, 'sabbathmode123');
57
+ sabbathMode.setCharacteristic(this.platform.Characteristic.Name, displayName);
58
+
59
+ sabbathMode.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
60
+ sabbathMode.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
61
+
62
+ sabbathMode.getCharacteristic(this.platform.Characteristic.On)
63
+ .onGet(this.getSabbathMode.bind(this))
64
+ .onSet(this.setSabbathMode.bind(this));
65
+ }
66
+
67
+ //=====================================================================================
68
+ async getSabbathMode(): Promise<CharacteristicValue> {
69
+
70
+ for (const service of this.deviceServices) {
71
+ if (service.serviceDeviceType === 'cloud.smarthq.device.appliance'
72
+ && service.serviceType === 'cloud.smarthq.service.toggle'
73
+ && service.domainType === 'cloud.smarthq.domain.sabbath') {
74
+
75
+ const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
76
+ if (state?.on == null) {
77
+ this.platform.debug('blue', 'No state.on returned from getSabbathMode state');
78
+ return false;
79
+ }
80
+ SabbathMode.sabbathModeStatus = state?.on;
81
+ break
82
+ }
83
+ }
84
+ return SabbathMode.sabbathModeStatus;
85
+ }
86
+
87
+ //=====================================================================================
88
+ async setSabbathMode(value: CharacteristicValue) {
89
+
90
+ value = SabbathMode.sabbathModeStatus ? false : true;
91
+
92
+ const cmdBody = {
93
+ command: {
94
+ commandType: 'cloud.smarthq.command.toggle.set',
95
+ on: value
96
+ },
97
+ kind: 'service#command',
98
+ deviceId: this.deviceId,
99
+ serviceDeviceType: 'cloud.smarthq.device.appliance',
100
+ serviceType: 'cloud.smarthq.service.toggle',
101
+ domainType: 'cloud.smarthq.domain.sabbath'
102
+ };
103
+
104
+ const response = await this.smartHqApi.command(JSON.stringify(cmdBody));
105
+
106
+ if (response == null) {
107
+ this.platform.debug('blue', 'No response from setSabbathMode command');
108
+ return;
109
+ }
110
+ }
111
+ }
@@ -0,0 +1,178 @@
1
+ import { CharacteristicValue, PlatformAccessory, Logging } from 'homebridge';
2
+ import { SmartHqPlatform } from '../platform.js';
3
+ import { SmartHqApi } from '../smartHqApi.js';
4
+ import { DevService } from '../smarthq-types.js';
5
+
6
+ /**
7
+ * Platform Accessory
8
+ * An instance of this class is created for each accessory your platform registers
9
+ * Each accessory may expose multiple services of different service types.
10
+ */
11
+ export class TemperatureUnits {
12
+
13
+ private readonly smartHqApi: SmartHqApi;
14
+ private log : Logging;
15
+
16
+ constructor(
17
+ private readonly platform: SmartHqPlatform,
18
+ private readonly accessory: PlatformAccessory,
19
+ public readonly deviceServices: DevService[],
20
+ public readonly deviceId: string
21
+ ) {
22
+ this.platform = platform;
23
+ this.accessory = accessory;
24
+ this.deviceServices = deviceServices;
25
+ this.deviceId = deviceId;
26
+ this.log = platform.log;
27
+
28
+ this.smartHqApi = new SmartHqApi(this.platform);
29
+
30
+ //=====================================================================================
31
+ // Check to see if the device has any supported Temperature Units services
32
+ // If not, then don't add services for device that doesn't support it
33
+ //=====================================================================================
34
+
35
+ if (!this.platform.deviceSupportsThisService(this.deviceServices,
36
+ 'cloud.smarthq.device.refrigerator',
37
+ 'cloud.smarthq.service.mode',
38
+ 'cloud.smarthq.domain.temperatureunits')) {
39
+ this.log.info('No supported Temperature Units service found for device: ' + this.accessory.displayName);
40
+ return;
41
+ }
42
+ this.platform.debug('green', 'Adding Temperature Units Switches');
43
+
44
+ //=====================================================================================
45
+ // create Temperature Unit switches for the Refrigerator
46
+ //=====================================================================================
47
+ let displayName = "Units: Celsius";
48
+
49
+ const unitsCelsius = this.accessory.getService(displayName)
50
+ || this.accessory.addService(this.platform.Service.Switch, displayName, 'units-celsius-123');
51
+ unitsCelsius.setCharacteristic(this.platform.Characteristic.Name, displayName);
52
+
53
+ unitsCelsius.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
54
+ unitsCelsius.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
55
+
56
+ unitsCelsius.getCharacteristic(this.platform.Characteristic.On)
57
+ .onGet(this.getunitsCelsius.bind(this))
58
+ .onSet(this.setunitsCelsius.bind(this));
59
+
60
+
61
+ displayName = "Units: Fahrenheit";
62
+
63
+ const unitsFahrenheit = this.accessory.getService(displayName)
64
+ || this.accessory.addService(this.platform.Service.Switch, displayName, 'units-fahrenheit-123');
65
+ unitsFahrenheit.setCharacteristic(this.platform.Characteristic.Name, displayName);
66
+ unitsFahrenheit.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
67
+ unitsFahrenheit.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
68
+
69
+ unitsFahrenheit.getCharacteristic(this.platform.Characteristic.On)
70
+ .onGet(this.getunitsFahrenheit.bind(this))
71
+ .onSet(this.setunitsFahrenheit.bind(this));
72
+
73
+ }
74
+
75
+ //=====================================================================================
76
+ async getunitsCelsius(): Promise<CharacteristicValue> {
77
+
78
+ let isOn = false;
79
+
80
+ for (const service of this.deviceServices) {
81
+ if (service.serviceDeviceType === 'cloud.smarthq.device.refrigerator'
82
+ && service.serviceType === 'cloud.smarthq.service.mode'
83
+ && service.domainType === 'cloud.smarthq.domain.temperatureunits') {
84
+ const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
85
+ if (state?.mode == null) {
86
+ this.platform.debug('blue', 'No state.mode returned from getunitsCelsius state');
87
+ return false;
88
+ }
89
+ const units = state?.mode;
90
+ if (units === 'cloud.smarthq.type.mode.celsius') {
91
+ isOn = true;
92
+ }
93
+ }
94
+ }
95
+ return isOn;
96
+ }
97
+
98
+ //=====================================================================================
99
+ async setunitsCelsius(value: CharacteristicValue) {
100
+
101
+ if (value) {
102
+ const cmdBody = {
103
+ command: {
104
+ commandType: 'cloud.smarthq.command.mode.set',
105
+ mode: 'cloud.smarthq.type.mode.celsius'
106
+ },
107
+ kind: 'service#command',
108
+ deviceId: this.deviceId,
109
+ serviceDeviceType: 'cloud.smarthq.device.refrigerator',
110
+ serviceType: 'cloud.smarthq.service.mode',
111
+ domainType: 'cloud.smarthq.domain.temperatureunits'
112
+ };
113
+
114
+ const response = await this.smartHqApi.command(JSON.stringify(cmdBody));
115
+
116
+ if (response == null) {
117
+ this.platform.debug('blue', 'No response from setunitsCelsius command');
118
+ return;
119
+ }
120
+
121
+ // Update the opposite switch
122
+ const unitsFahrenheit = this.accessory.getService("Units: Fahrenheit");
123
+ unitsFahrenheit?.getCharacteristic(this.platform.Characteristic.On).updateValue(false);
124
+ }
125
+ }
126
+ //=====================================================================================
127
+ async getunitsFahrenheit(): Promise<CharacteristicValue> {
128
+
129
+ let isOn = false;
130
+
131
+ for (const service of this.deviceServices) {
132
+ if (service.serviceDeviceType === 'cloud.smarthq.device.refrigerator'
133
+ && service.serviceType === 'cloud.smarthq.service.mode'
134
+ && service.domainType === 'cloud.smarthq.domain.temperatureunits') {
135
+ const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
136
+ if (state?.mode == null) {
137
+ this.platform.debug('blue', 'No state.mode returned from getunitsFahrenheit state');
138
+ return false;
139
+ }
140
+ const units = state?.mode;
141
+ if (units === 'cloud.smarthq.type.mode.fahrenheit') {
142
+ isOn = true;
143
+ }
144
+ }
145
+ }
146
+ return isOn;
147
+ }
148
+
149
+ //=====================================================================================
150
+ async setunitsFahrenheit(value: CharacteristicValue) {
151
+ this.platform.debug("blue", "Triggered setunitsFahrenheit: " + value);
152
+ if (value) {
153
+ const cmdBody = {
154
+ command: {
155
+ commandType: 'cloud.smarthq.command.mode.set',
156
+ mode: 'cloud.smarthq.type.mode.fahrenheit'
157
+ },
158
+ kind: 'service#command',
159
+ deviceId: this.deviceId,
160
+ serviceDeviceType: 'cloud.smarthq.device.refrigerator',
161
+ serviceType: 'cloud.smarthq.service.mode',
162
+ domainType: 'cloud.smarthq.domain.temperatureunits'
163
+ };
164
+
165
+ const response = await this.smartHqApi.command(JSON.stringify(cmdBody));
166
+
167
+ if (response == null) {
168
+ this.platform.debug('blue', 'No response from setunitsFahrenheit command');
169
+ return;
170
+ }
171
+
172
+ // Update the opposite switch
173
+ // Update the opposite switch
174
+ const unitsCelsius = this.accessory.getService("Units: Celsius");
175
+ unitsCelsius?.getCharacteristic(this.platform.Characteristic.On).updateValue(false);
176
+ }
177
+ }
178
+ }
@@ -0,0 +1,164 @@
1
+ import { CharacteristicValue, PlatformAccessory, Logging } from 'homebridge';
2
+ import { SmartHqPlatform } from '../platform.js';
3
+ import { SmartHqApi } from '../smartHqApi.js';
4
+ import { DevService } from '../smarthq-types.js';
5
+
6
+ /**
7
+ * Platform Accessory
8
+ * An instance of this class is created for each accessory your platform registers
9
+ * Each accessory may expose multiple services of different service types.
10
+ */
11
+ export class TurboCoolMode {
12
+ static turboCoolFreezerStatus = false;
13
+ static turboCoolFridgeStatus = false;
14
+
15
+ private readonly smartHqApi: SmartHqApi;
16
+ private log : Logging;
17
+
18
+ constructor(
19
+ private readonly platform: SmartHqPlatform,
20
+ private readonly accessory: PlatformAccessory,
21
+ public readonly deviceServices: DevService[],
22
+ public readonly deviceId: string
23
+ ) {
24
+ this.platform = platform;
25
+ this.accessory = accessory;
26
+ this.deviceServices = deviceServices;
27
+ this.deviceId = deviceId;
28
+ this.log = platform.log;
29
+
30
+ this.smartHqApi = new SmartHqApi(this.platform);
31
+
32
+ //=====================================================================================
33
+ // Check to see if the device has any supported Turbo Cool services
34
+ // If not, then don't add services for device that doesn't support it
35
+ //=====================================================================================
36
+
37
+ if (!this.platform.deviceSupportsThisService(this.deviceServices,
38
+ 'cloud.smarthq.device.refrigerator.freshfood',
39
+ 'cloud.smarthq.service.toggle',
40
+ 'cloud.smarthq.domain.turbo')) {
41
+ this.log.info('No supported Turbo Cool service found for device: ' + this.accessory.displayName);
42
+ return;
43
+ }
44
+ this.platform.debug('green', 'Adding Turbo Cool Mode Switches ');
45
+
46
+ //=====================================================================================
47
+ // create a Turbo Cool Refrigerator mode switch for the Refrigerator
48
+ //=====================================================================================
49
+ let displayName = "Turbo Cool Fridge";
50
+
51
+ const turboCoolFridge = this.accessory.getService(displayName)
52
+ || this.accessory.addService(this.platform.Service.Switch, displayName, 'turbo-cool-123');
53
+ turboCoolFridge.setCharacteristic(this.platform.Characteristic.Name, displayName);
54
+
55
+ turboCoolFridge.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
56
+ turboCoolFridge.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
57
+
58
+ turboCoolFridge.getCharacteristic(this.platform.Characteristic.On)
59
+ .onGet(this.getTurboCoolFridge.bind(this))
60
+ .onSet(this.setTurboCoolFridge.bind(this));
61
+
62
+ //=====================================================================================
63
+ // create a Turbo Cool Freezer mode switch for the Freezer
64
+ //=====================================================================================
65
+ displayName = "Turbo Cool Freezer";
66
+
67
+ const turboCoolFreezer = this.accessory.getService(displayName)
68
+ || this.accessory.addService(this.platform.Service.Switch, displayName, 'turbo-cool-freezer-123');
69
+ turboCoolFreezer.setCharacteristic(this.platform.Characteristic.Name, displayName);
70
+
71
+ turboCoolFreezer.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
72
+ turboCoolFreezer.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
73
+
74
+ turboCoolFreezer.getCharacteristic(this.platform.Characteristic.On)
75
+ .onGet(this.getTurboCoolFreezer.bind(this))
76
+ .onSet(this.setTurboCoolFreezer.bind(this));
77
+
78
+ }
79
+
80
+ //=====================================================================================
81
+ async getTurboCoolFridge(): Promise<CharacteristicValue> {
82
+
83
+ for (const service of this.deviceServices) {
84
+ if (service.serviceDeviceType === 'cloud.smarthq.device.refrigerator.freshfood'
85
+ && service.serviceType === 'cloud.smarthq.service.toggle'
86
+ && service.domainType === 'cloud.smarthq.domain.turbo') {
87
+ const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
88
+ if (state?.on == null) {
89
+ this.platform.debug('blue', 'No state.on returned from getTurboCoolFridge state');
90
+ return false;
91
+ }
92
+ TurboCoolMode.turboCoolFridgeStatus = state?.on;
93
+ }
94
+ }
95
+ return TurboCoolMode.turboCoolFridgeStatus;
96
+ }
97
+
98
+ //=====================================================================================
99
+ async setTurboCoolFridge(value: CharacteristicValue) {
100
+ this.platform.debug('blue', "Triggered setTurboCoolFridge toggle");
101
+
102
+ const cmdBody = {
103
+ kind: 'service#command',
104
+ deviceId: this.deviceId,
105
+ serviceDeviceType: 'cloud.smarthq.device.refrigerator.freshfood',
106
+ serviceType: 'cloud.smarthq.service.toggle',
107
+ domainType: 'cloud.smarthq.domain.turbo',
108
+ command: {
109
+ commandType: 'cloud.smarthq.command.toggle.set',
110
+ on: value
111
+ }
112
+ };
113
+
114
+ const response = await this.smartHqApi.command(JSON.stringify(cmdBody));
115
+
116
+ if (response == null) {
117
+ this.platform.debug('blue', 'No response from setTurboCoolFridge command');
118
+ return;
119
+ }
120
+ }
121
+
122
+ //=====================================================================================
123
+ async getTurboCoolFreezer(): Promise<CharacteristicValue> {
124
+ for (const service of this.deviceServices) {
125
+ if (service.serviceDeviceType === 'cloud.smarthq.device.refrigerator.freezer'
126
+ && service.serviceType === 'cloud.smarthq.service.toggle'
127
+ && service.domainType === 'cloud.smarthq.domain.turbo') {
128
+
129
+ const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
130
+ if (state?.on == null) {
131
+ this.platform.debug('blue', 'No state.on returned from getTurboCoolFreezer state');
132
+ return false;
133
+ }
134
+
135
+ TurboCoolMode.turboCoolFreezerStatus = state?.on;
136
+ }
137
+ }
138
+ return TurboCoolMode.turboCoolFreezerStatus;
139
+ }
140
+
141
+ //=====================================================================================
142
+ async setTurboCoolFreezer(value: CharacteristicValue) {
143
+ this.platform.debug('blue', "Triggered setTurboCoolFreezer = toggle");
144
+
145
+ const cmdBody = {
146
+ kind: 'service#command',
147
+ deviceId: this.deviceId,
148
+ serviceDeviceType: 'cloud.smarthq.device.refrigerator.freezer',
149
+ serviceType: 'cloud.smarthq.service.toggle',
150
+ domainType: 'cloud.smarthq.domain.turbo',
151
+ command: {
152
+ commandType: 'cloud.smarthq.command.toggle.set',
153
+ on: value
154
+ }
155
+ };
156
+
157
+ const response = await this.smartHqApi.command(JSON.stringify(cmdBody));
158
+
159
+ if (response == null) {
160
+ this.platform.debug('blue', 'No response from setTurboCoolFreezer command');
161
+ return;
162
+ }
163
+ }
164
+ }