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,227 @@
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 Freezer {
12
+
13
+ // Default temperatures for a GE Profile Refrigerator
14
+ private freezerTargetTemperature = -17.77; // Default 0F
15
+
16
+
17
+ private readonly smartHqApi: SmartHqApi;
18
+ private log : Logging;
19
+
20
+ constructor(
21
+ private readonly platform: SmartHqPlatform,
22
+ private readonly accessory: PlatformAccessory,
23
+ public readonly deviceServices: DevService[],
24
+ public readonly deviceId: string
25
+ ) {
26
+ this.platform = platform;
27
+ this.accessory = accessory;
28
+ this.deviceServices = deviceServices;
29
+ this.deviceId = deviceId;
30
+ this.log = platform.log;
31
+
32
+ this.smartHqApi = new SmartHqApi(this.platform);
33
+ this.platform.debug('green', 'Adding Freezer Thermostat');
34
+
35
+ //=====================================================================================
36
+ // create a new Thermostat service for the Freezer
37
+ //=====================================================================================
38
+ const displayName = "Freezer";
39
+ const freezerThermostat = this.accessory.getService(displayName)
40
+ || this.accessory.addService(this.platform.Service.Thermostat, displayName, 'freezer-thermo1');
41
+ freezerThermostat.setCharacteristic(this.platform.Characteristic.Name, displayName);
42
+ freezerThermostat.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
43
+ freezerThermostat.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
44
+
45
+ const currentHeatCoolCharacteristicFreezer = freezerThermostat.getCharacteristic(this.platform.Characteristic.CurrentHeatingCoolingState);
46
+ const targetHeatCoolCharacteristicFreezer = freezerThermostat.getCharacteristic(this.platform.Characteristic.TargetHeatingCoolingState);
47
+ const currentTempCharacteristicFreezer = freezerThermostat.getCharacteristic(this.platform.Characteristic.CurrentTemperature);
48
+ const targetTempCharacteristicFreezer = freezerThermostat.getCharacteristic(this.platform.Characteristic.TargetTemperature);
49
+
50
+ //=====================================================================================
51
+ // Now modify the properties for each characteristic to match the freezer capabilities
52
+ //=====================================================================================
53
+ currentHeatCoolCharacteristicFreezer.setProps({
54
+ minValue: this.platform.Characteristic.CurrentHeatingCoolingState.OFF,
55
+ maxValue: this.platform.Characteristic.CurrentHeatingCoolingState.COOL,
56
+ validValues: [this.platform.Characteristic.CurrentHeatingCoolingState.COOL]
57
+ });
58
+
59
+ targetHeatCoolCharacteristicFreezer.setProps({
60
+ minValue: this.platform.Characteristic.TargetHeatingCoolingState.OFF,
61
+ maxValue: this.platform.Characteristic.TargetHeatingCoolingState.COOL,
62
+ validValues: [this.platform.Characteristic.TargetHeatingCoolingState.COOL]
63
+ });
64
+
65
+ try {
66
+ currentTempCharacteristicFreezer.setProps({
67
+ minValue: -21.111, // -6F
68
+ maxValue: -15.0, // 5F
69
+ minStep: 0.1
70
+ });
71
+ } catch (error) {
72
+ this.platform.debug('blue', 'Error setting Freezer Current Temperature properties: ' + error);
73
+ }
74
+ //=====================================================================================
75
+ // Change properties for the characteristic for a GE Profile Refrigerator temperature range is -21.111C (-6F) to -15C (5F)
76
+ // Values obtained from SmartHQ Api service config for refrigerator.freezer.temperature see HB log output when debug is enabled
77
+ //=====================================================================================
78
+ try {
79
+ targetTempCharacteristicFreezer.setProps({
80
+ minValue: -21.111,
81
+ maxValue: -15.0,
82
+ minStep: 0.1
83
+ });
84
+ } catch (error) {
85
+ this.platform.debug('blue', 'Error setting Freezer Target Temperature properties: ' + error);
86
+ }
87
+
88
+ // create handlers for required characteristics
89
+ freezerThermostat.getCharacteristic(this.platform.Characteristic.CurrentHeatingCoolingState)
90
+ .onGet(this.getCurrentHeatingCoolingState.bind(this));
91
+
92
+ freezerThermostat.getCharacteristic(this.platform.Characteristic.TargetHeatingCoolingState)
93
+ .onGet(this.getCurrentHeatingCoolingState.bind(this))
94
+ .onSet(this.setTargetHeatingCoolingState.bind(this));
95
+
96
+ freezerThermostat.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
97
+ .onGet(this.getFreezerTemperature.bind(this));
98
+
99
+ freezerThermostat.getCharacteristic(this.platform.Characteristic.TargetTemperature)
100
+ .onGet(this.getFreezerTargetTemperature.bind(this))
101
+ .onSet(this.setFreezerTemperature.bind(this));
102
+
103
+ freezerThermostat.getCharacteristic(this.platform.Characteristic.TemperatureDisplayUnits)
104
+ .onGet(this.handleTemperatureDisplayUnitsGet.bind(this))
105
+ .onSet(this.handleTemperatureDisplayUnitsSet.bind(this));
106
+
107
+ //=====================================================================================
108
+ // Updating characteristics values asynchronously.
109
+ //=====================================================================================
110
+
111
+ setInterval(() => {
112
+ // push the new value to HomeKit
113
+ this.getFreezerTemperature().then(temp => {
114
+ freezerThermostat.getCharacteristic(this.platform.Characteristic.CurrentTemperature).updateValue(temp);
115
+ });
116
+ }, 10000); // every 10 seconds
117
+
118
+ }
119
+
120
+ //=====================================================================================
121
+ async getFreezerTemperature(): Promise<CharacteristicValue> {
122
+ let temp = 0;
123
+ for (const service of this.deviceServices) {
124
+ if (service.serviceDeviceType === 'cloud.smarthq.device.refrigerator.freezer'
125
+ && service.serviceType === 'cloud.smarthq.service.temperature') {
126
+
127
+ const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
128
+ if (state?.celsiusConverted == null) {
129
+ this.platform.debug('blue', 'No celsiusConverted returned from getFreezerTemperature state');
130
+ return -17.77; // Return -17.77C (0F) if no data
131
+ }
132
+ temp = state?.celsiusConverted;
133
+ break;
134
+ }
135
+ }
136
+ return temp;
137
+ }
138
+
139
+ //=====================================================================================
140
+ async setFreezerTemperature(value: CharacteristicValue) {
141
+ this.platform.debug('blue', "Triggered setTemperature");
142
+
143
+ const cmdBody = {
144
+ command: {
145
+ commandType: 'cloud.smarthq.command.temperature.set',
146
+ celsius: value as number
147
+ },
148
+ kind: 'service#command',
149
+ deviceId: this.deviceId,
150
+ serviceDeviceType: 'cloud.smarthq.device.refrigerator.freezer',
151
+ serviceType: 'cloud.smarthq.service.temperature',
152
+ domainType: 'cloud.smarthq.domain.setpoint'
153
+ };
154
+ const response = await this.smartHqApi.command(JSON.stringify(cmdBody));
155
+
156
+ if (response == null) {
157
+ this.platform.debug('blue', 'No response from setFreezerTemperature command');
158
+ return;
159
+ }
160
+ };
161
+
162
+ /**
163
+ * Handle requests to get the current value of the "Current Heating Cooling State" characteristic
164
+ */
165
+ //=====================================================================================
166
+ getCurrentHeatingCoolingState() {
167
+
168
+ // set this to a valid value for CurrentHeatingCoolingState
169
+ const currentValue = this.platform.Characteristic.CurrentHeatingCoolingState.COOL;
170
+
171
+ return currentValue;
172
+ }
173
+
174
+
175
+ /**
176
+ * Handle requests to get the current value of the "Target Heating Cooling State" characteristic
177
+ */
178
+ //=====================================================================================
179
+ setCurrentHeatingCoolingState() {
180
+
181
+ // set this to a valid value for TargetHeatingCoolingState
182
+ const currentValue = this.platform.Characteristic.TargetHeatingCoolingState.COOL;
183
+
184
+ return currentValue;
185
+ }
186
+
187
+ /**
188
+ * Handle requests to set the "Target Heating Cooling State" characteristic
189
+ */
190
+ //=====================================================================================
191
+ setTargetHeatingCoolingState(value: CharacteristicValue) {
192
+ // Nothing to do since refrigerator can only be in COOL mode
193
+
194
+ const currentValue = this.platform.Characteristic.TargetHeatingCoolingState.COOL;
195
+ this.platform.debug('blue', 'setTargetHeatingCoolingState value: ' + value + ', returning: ' + currentValue);
196
+
197
+ return currentValue;
198
+ }
199
+
200
+ /**
201
+ * Handle requests to get the current value of the "Target Temperature" characteristic
202
+ */
203
+
204
+ getFreezerTargetTemperature() {
205
+ const currentValue = this.freezerTargetTemperature
206
+
207
+ return currentValue;
208
+ }
209
+
210
+ handleTemperatureDisplayUnitsGet() {
211
+
212
+ // set this to a valid value for TemperatureDisplayUnits
213
+ const currentValue = this.platform.Characteristic.TemperatureDisplayUnits.CELSIUS;
214
+
215
+ return currentValue;
216
+ }
217
+
218
+ /**
219
+ * Handle requests to set the "Temperature Display Units" characteristic
220
+ */
221
+ //=====================================================================================
222
+ handleTemperatureDisplayUnitsSet(value: CharacteristicValue) {
223
+ this.platform.debug('blue', 'handleTemperatureDisplayUnitsSet value: ' + value);
224
+ }
225
+
226
+
227
+ }
@@ -0,0 +1,100 @@
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 IceMaker {
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
+ if (!this.platform.deviceSupportsThisService(this.deviceServices,
31
+ 'cloud.smarthq.device.icemaker.1',
32
+ 'cloud.smarthq.service.toggle',
33
+ 'cloud.smarthq.domain.power')) {
34
+ this.log.info('No supported Ice Maker service found for device: ' + this.accessory.displayName);
35
+ return;
36
+ }
37
+ this.platform.debug('green', 'Adding Ice Maker Switch');
38
+
39
+ //=====================================================================================
40
+ // create a Ice Maker switch for the Refrigerator
41
+ //=====================================================================================
42
+ const displayName = "Ice Maker";
43
+
44
+ const iceMaker = this.accessory.getService(displayName)
45
+ || this.accessory.addService(this.platform.Service.Switch, displayName, 'ice-maker-123');
46
+ iceMaker.setCharacteristic(this.platform.Characteristic.Name, displayName);
47
+
48
+ iceMaker.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
49
+ iceMaker.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
50
+
51
+ iceMaker.getCharacteristic(this.platform.Characteristic.On)
52
+ .onGet(this.geticeMaker.bind(this))
53
+ .onSet(this.seticeMaker.bind(this));
54
+
55
+ }
56
+
57
+ //=====================================================================================
58
+ async geticeMaker(): Promise<CharacteristicValue> {
59
+
60
+ let isOn = false;
61
+
62
+ for (const service of this.deviceServices) {
63
+ if (service.serviceDeviceType === 'cloud.smarthq.device.icemaker.1'
64
+ && service.serviceType === 'cloud.smarthq.service.toggle'
65
+ && service.domainType === 'cloud.smarthq.domain.power') {
66
+ const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
67
+ if (state?.on == null) {
68
+ this.platform.debug('blue', 'No state.On returned from geticeMaker state');
69
+ return false;
70
+ }
71
+ isOn = state?.on;
72
+ }
73
+ }
74
+ return isOn;
75
+ }
76
+
77
+ //=====================================================================================
78
+ async seticeMaker(value: CharacteristicValue) {
79
+ this.platform.debug('blue', "Triggered seticeMaker toggle");
80
+
81
+ const cmdBody = {
82
+ command: {
83
+ commandType: 'cloud.smarthq.command.toggle.set',
84
+ on: value
85
+ },
86
+ kind: 'service#command',
87
+ deviceId: this.deviceId,
88
+ serviceDeviceType: 'cloud.smarthq.device.icemaker.1',
89
+ serviceType: 'cloud.smarthq.service.toggle',
90
+ domainType: 'cloud.smarthq.domain.power'
91
+ };
92
+
93
+ const response = await this.smartHqApi.command(JSON.stringify(cmdBody));
94
+
95
+ if (response == null) {
96
+ this.platform.debug('blue', 'No response from seticeMaker command');
97
+ return;
98
+ }
99
+ }
100
+ }
@@ -0,0 +1,118 @@
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 InteriorLight {
12
+ 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
+ if (!this.platform.deviceSupportsThisService(this.deviceServices,
30
+ 'cloud.smarthq.device.refrigerator',
31
+ 'cloud.smarthq.service.integer',
32
+ 'cloud.smarthq.domain.brightness.light')) {
33
+ this.log.info('No supported Interior Light service found for device: ' + this.accessory.displayName);
34
+ return;
35
+ }
36
+ this.platform.debug('green', 'Adding Interior Light Switch');
37
+ // set accessory information
38
+
39
+ //=====================================================================================
40
+ // create a new Lightbulb service for the Refrigerator Wall Brightness Light
41
+ //=====================================================================================
42
+ const displayName = "Fridge Light";
43
+ const refrigeratorLight = this.accessory.getService(displayName)
44
+ || this.accessory.addService(this.platform.Service.Lightbulb, displayName, 'brightness-light-2');
45
+
46
+ refrigeratorLight.setCharacteristic(this.platform.Characteristic.Name, displayName);
47
+ refrigeratorLight.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
48
+ refrigeratorLight.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
49
+
50
+ refrigeratorLight.getCharacteristic(this.platform.Characteristic.On).updateValue(true);
51
+ refrigeratorLight.getCharacteristic(this.platform.Characteristic.On)
52
+ .onGet(this.getRefrigBrightnessLightOn.bind(this))
53
+ .onSet(this.setRefrigBrightnessLightOn.bind(this));
54
+
55
+ refrigeratorLight.getCharacteristic(this.platform.Characteristic.Brightness)
56
+ .onGet(this.getFridgeBackLight.bind(this))
57
+ .onSet(this.setFridgeBackLight.bind(this));
58
+ }
59
+
60
+
61
+ //=====================================================================================
62
+ async getFridgeBackLight(): Promise<CharacteristicValue> {
63
+ let brightness = 0;
64
+ for (const service of this.deviceServices) {
65
+ if (service.serviceDeviceType === 'cloud.smarthq.device.refrigerator'
66
+ && service.serviceType === 'cloud.smarthq.service.integer') {
67
+
68
+ const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
69
+ if (state?.value == null) {
70
+ this.platform.debug('blue', 'No state.value returned from getFridgeBackLight state');
71
+ return false;
72
+ }
73
+ brightness = state?.value;
74
+ break;
75
+ }
76
+ }
77
+ return brightness;
78
+ }
79
+ //=====================================================================================
80
+ // Set handler for Brightness characteristics for Lightbulb service
81
+ //=====================================================================================
82
+ async setFridgeBackLight(value: CharacteristicValue) {
83
+
84
+ const cmdBody = {
85
+ command: {
86
+ commandType: 'cloud.smarthq.command.integer.set',
87
+ value: value as number
88
+ },
89
+ kind: 'service#command',
90
+ deviceId: this.deviceId,
91
+ serviceDeviceType: 'cloud.smarthq.device.refrigerator',
92
+ serviceType: 'cloud.smarthq.service.integer',
93
+ domainType: 'cloud.smarthq.domain.brightness.light'
94
+ };
95
+
96
+ const response = await this.smartHqApi.command(JSON.stringify(cmdBody));
97
+
98
+ if (response == null) {
99
+ this.platform.debug('blue', 'No response from setFridgeBackLight command');
100
+ return;
101
+ }
102
+ };
103
+
104
+ //=====================================================================================
105
+ async getRefrigBrightnessLightOn() {
106
+ // SmartHQ API does not have an On/Off command for the refrigerator brightness light only brightness level 0-100
107
+ return true;
108
+ }
109
+
110
+ //=====================================================================================
111
+ async setRefrigBrightnessLightOn(value: CharacteristicValue) {
112
+ // SmartHQ API does not have an On/Off command for the refrigerator brightness light only brightness level 0-100
113
+ if (value === false) {
114
+ return
115
+ }
116
+
117
+ }
118
+ }
@@ -0,0 +1,241 @@
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 Refrigerator {
12
+ // Default temperatures for a GE Profile Refrigerator
13
+ private refrigeratorTargetTemperature = 2.78; // Default 37F in Celsius
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
+ this.platform.debug('green', 'Adding Refrigerator Thermostat');
33
+
34
+ // set accessory information
35
+ this.accessory.getService(this.platform.Service.AccessoryInformation)!
36
+ .setCharacteristic(this.platform.Characteristic.Manufacturer, 'GE')
37
+ .setCharacteristic(this.platform.Characteristic.Model, accessory.context.device.model || 'Default-Model')
38
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, accessory.context.device.serial || 'Default-Serial');
39
+
40
+ //=====================================================================================
41
+ // create a new Thermostat service for the Refrigerator
42
+ //=====================================================================================
43
+ const displayName = "Refrigerator";
44
+ const refrigeratorThermostat = this.accessory.getService(displayName)
45
+ || this.accessory.addService(this.platform.Service.Thermostat, displayName, 'fridge-thermo1');
46
+ // set the service name, this is what is displayed as the default name on the Home app
47
+ refrigeratorThermostat.setCharacteristic(this.platform.Characteristic.Name, displayName);
48
+ refrigeratorThermostat.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
49
+ refrigeratorThermostat.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
50
+
51
+ const currentHeatCoolCharacteristic = refrigeratorThermostat.getCharacteristic(this.platform.Characteristic.CurrentHeatingCoolingState);
52
+ const targetHeatCoolCharacteristic = refrigeratorThermostat.getCharacteristic(this.platform.Characteristic.TargetHeatingCoolingState);
53
+ const currentTempCharacteristic = refrigeratorThermostat.getCharacteristic(this.platform.Characteristic.CurrentTemperature);
54
+ const targetTempCharacteristic = refrigeratorThermostat.getCharacteristic(this.platform.Characteristic.TargetTemperature);
55
+
56
+ // Now modify the properties for each characteristic to match the refrigerator capabilities
57
+ // Only allow COOL mode for refrigerator
58
+ currentHeatCoolCharacteristic.setProps({
59
+ minValue: this.platform.Characteristic.CurrentHeatingCoolingState.OFF,
60
+ maxValue: this.platform.Characteristic.CurrentHeatingCoolingState.COOL,
61
+ validValues: [this.platform.Characteristic.CurrentHeatingCoolingState.COOL]
62
+ });
63
+
64
+ // Only allow COOL mode for refrigerator
65
+ targetHeatCoolCharacteristic.setProps({
66
+ minValue: this.platform.Characteristic.TargetHeatingCoolingState.OFF,
67
+ maxValue: this.platform.Characteristic.TargetHeatingCoolingState.COOL,
68
+ validValues: [this.platform.Characteristic.TargetHeatingCoolingState.COOL]
69
+ });
70
+
71
+ try {
72
+ currentTempCharacteristic.setProps({
73
+ minValue: 0,
74
+ maxValue: 8.0,
75
+ minStep: 0.1
76
+ });
77
+ } catch (error) {
78
+ this.platform.debug('blue', 'Error setting Refrigerator Current Temperature properties: ' + error);
79
+ }
80
+
81
+ // Change properties for the characteristic for a GE Profile Refrigerator temperature range is 1.111C (34F) to 5.556C (42F)
82
+ // Values obtained from SmartHQ Api service config for refrigerator.freshfood.temperature see HB log output when debug is enabled
83
+ try {
84
+ targetTempCharacteristic.setProps({
85
+ minValue: 1.111,
86
+ maxValue: 5.556,
87
+ minStep: 0.1
88
+ });
89
+ } catch (error) {
90
+ this.platform.debug('blue', 'Error setting Refrigerator Target Temperature properties: ' + error);
91
+ }
92
+
93
+ // create handlers for required characteristics
94
+ refrigeratorThermostat.getCharacteristic(this.platform.Characteristic.CurrentHeatingCoolingState)
95
+ .onGet(this.getCurrentHeatingCoolingState.bind(this));
96
+ // Only allow COOL mode for refrigerator
97
+ refrigeratorThermostat.getCharacteristic(this.platform.Characteristic.TargetHeatingCoolingState)
98
+ .onGet(this.setTargetHeatingCoolingState.bind(this))
99
+ .onSet(this.setTargetHeatingCoolingState.bind(this));
100
+
101
+ refrigeratorThermostat.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
102
+ .onGet(this.getFridgeTemperature.bind(this));
103
+
104
+ refrigeratorThermostat.getCharacteristic(this.platform.Characteristic.TargetTemperature)
105
+ .onGet(this.getFridgeTemperature.bind(this))
106
+ .onSet(this.setFridgeTemperature.bind(this));
107
+
108
+ refrigeratorThermostat.getCharacteristic(this.platform.Characteristic.TemperatureDisplayUnits)
109
+ .onGet(this.handleTemperatureDisplayUnitsGet.bind(this))
110
+ .onSet(this.handleTemperatureDisplayUnitsSet.bind(this));
111
+
112
+ //=====================================================================================
113
+ // Updating characteristics values asynchronously.
114
+ //=====================================================================================
115
+
116
+ setInterval(() => {
117
+ // push the new value to HomeKit
118
+ this.getFridgeTemperature().then(temp => {
119
+ refrigeratorThermostat.getCharacteristic(this.platform.Characteristic.CurrentTemperature).updateValue(temp);
120
+ });
121
+ }, 5000);
122
+
123
+ }
124
+
125
+ //=====================================================================================
126
+ // Refrigerator Temperature Handlers using SmartHQ API commands in smartHqApi.ts
127
+ //=====================================================================================
128
+ async getFridgeTemperature(): Promise<CharacteristicValue> {
129
+ let temp = 0;
130
+ for (const service of this.deviceServices) {
131
+ if (service.serviceDeviceType === 'cloud.smarthq.device.refrigerator.freshfood'
132
+ && service.serviceType === 'cloud.smarthq.service.temperature') {
133
+
134
+ const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
135
+ if (state?.celsiusConverted == null) {
136
+ this.platform.debug('blue', 'No state.celsiusConverted returned from getFridgeTemperature state');
137
+ return 2.78; // Return 2.78C (37F) if no data
138
+ }
139
+ temp = state?.celsiusConverted;
140
+ break;
141
+ }
142
+ }
143
+
144
+ // if you need to return an error to show the device as "Not Responding" in the Home app:
145
+ // throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
146
+
147
+ return temp;
148
+
149
+ }
150
+
151
+
152
+ //=====================================================================================
153
+ async setFridgeTemperature(value: CharacteristicValue) {
154
+ if (this.platform.config.debug) {
155
+ this.log.info("Triggered setTemperature");
156
+ }
157
+ this.refrigeratorTargetTemperature = value as number;
158
+
159
+ const cmdBody = {
160
+ command: {
161
+ commandType: 'cloud.smarthq.command.temperature.set',
162
+ celsius: value as number
163
+ },
164
+ kind: 'service#command',
165
+ deviceId: this.deviceId,
166
+ serviceDeviceType: 'cloud.smarthq.device.refrigerator.freshfood',
167
+ serviceType: 'cloud.smarthq.service.temperature',
168
+ domainType: 'cloud.smarthq.domain.setpoint'
169
+ };
170
+ const response = await this.smartHqApi.command(JSON.stringify(cmdBody));
171
+
172
+ if (response == null) {
173
+ this.platform.debug('blue', 'No response from setFridgeTemperature command');
174
+ return;
175
+ }
176
+ };
177
+
178
+
179
+ //=====================================================================================
180
+ getCurrentHeatingCoolingState() {
181
+
182
+ // set this to a valid value for CurrentHeatingCoolingState
183
+ const currentValue = this.platform.Characteristic.CurrentHeatingCoolingState.COOL;
184
+
185
+ return currentValue;
186
+ }
187
+ /**
188
+ * Handle requests to get the current value of the "Target Heating Cooling State" characteristic
189
+ */
190
+ //=====================================================================================
191
+ setCurrentHeatingCoolingState() {
192
+
193
+ // set this to a valid value for TargetHeatingCoolingState
194
+ const currentValue = this.platform.Characteristic.TargetHeatingCoolingState.COOL;
195
+
196
+ return currentValue;
197
+ }
198
+ /**
199
+ * Handle requests to set the "Target Heating Cooling State" characteristic
200
+ */
201
+ //=====================================================================================
202
+ setTargetHeatingCoolingState(value: CharacteristicValue) {
203
+ // Nothing to do since refrigerator can only be in COOL mode
204
+ this.platform.debug('green', 'setTargetHeatingCoolingState called with value: ' + value);
205
+ const currentValue = this.platform.Characteristic.TargetHeatingCoolingState.COOL;
206
+
207
+ return currentValue;
208
+ }
209
+
210
+ /**
211
+ * Handle requests to get the current value of the "Target Temperature" characteristic
212
+ */
213
+ //=====================================================================================
214
+ getTargetTemperatureGet() {
215
+ const currentValue = this.refrigeratorTargetTemperature
216
+
217
+ return currentValue;
218
+ }
219
+
220
+ /**
221
+ * Handle requests to get the current value of the "Temperature Display Units" characteristic
222
+ */
223
+ //=====================================================================================
224
+ handleTemperatureDisplayUnitsGet() {
225
+
226
+ // set this to a valid value for TemperatureDisplayUnits
227
+ const currentValue = this.platform.Characteristic.TemperatureDisplayUnits.CELSIUS;
228
+
229
+ return currentValue;
230
+ }
231
+
232
+ /**
233
+ * Handle requests to set the "Temperature Display Units" characteristic
234
+ */
235
+ //=====================================================================================
236
+ handleTemperatureDisplayUnitsSet(value: CharacteristicValue) {
237
+ if (value === this.platform.Characteristic.TemperatureDisplayUnits.FAHRENHEIT) {
238
+ this.platform.debug('green', 'Temperature Display Units set to FAHRENHEIT');
239
+ }
240
+ }
241
+ }