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.
- package/LICENSE +21 -0
- package/Readme.md +138 -0
- package/config.schema.json +146 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/platform.d.ts +40 -0
- package/dist/platform.js +243 -0
- package/dist/platform.js.map +1 -0
- package/dist/refrigerator/controlLock.d.ts +19 -0
- package/dist/refrigerator/controlLock.js +85 -0
- package/dist/refrigerator/controlLock.js.map +1 -0
- package/dist/refrigerator/convertibleDrawer.d.ts +27 -0
- package/dist/refrigerator/convertibleDrawer.js +317 -0
- package/dist/refrigerator/convertibleDrawer.js.map +1 -0
- package/dist/refrigerator/dispenserLight.d.ts +19 -0
- package/dist/refrigerator/dispenserLight.js +85 -0
- package/dist/refrigerator/dispenserLight.js.map +1 -0
- package/dist/refrigerator/energy.d.ts +19 -0
- package/dist/refrigerator/energy.js +93 -0
- package/dist/refrigerator/energy.js.map +1 -0
- package/dist/refrigerator/freezer.d.ts +41 -0
- package/dist/refrigerator/freezer.js +188 -0
- package/dist/refrigerator/freezer.js.map +1 -0
- package/dist/refrigerator/iceMaker.d.ts +19 -0
- package/dist/refrigerator/iceMaker.js +81 -0
- package/dist/refrigerator/iceMaker.js.map +1 -0
- package/dist/refrigerator/interiorLight.d.ts +21 -0
- package/dist/refrigerator/interiorLight.js +100 -0
- package/dist/refrigerator/interiorLight.js.map +1 -0
- package/dist/refrigerator/refrigerator.d.ts +41 -0
- package/dist/refrigerator/refrigerator.js +204 -0
- package/dist/refrigerator/refrigerator.js.map +1 -0
- package/dist/refrigerator/refrigeratorAlerts.d.ts +36 -0
- package/dist/refrigerator/refrigeratorAlerts.js +204 -0
- package/dist/refrigerator/refrigeratorAlerts.js.map +1 -0
- package/dist/refrigerator/sabbathMode.d.ts +20 -0
- package/dist/refrigerator/sabbathMode.js +91 -0
- package/dist/refrigerator/sabbathMode.js.map +1 -0
- package/dist/refrigerator/temperatureUnits.d.ts +21 -0
- package/dist/refrigerator/temperatureUnits.js +147 -0
- package/dist/refrigerator/temperatureUnits.js.map +1 -0
- package/dist/refrigerator/turboCoolMode.d.ts +23 -0
- package/dist/refrigerator/turboCoolMode.js +134 -0
- package/dist/refrigerator/turboCoolMode.js.map +1 -0
- package/dist/refrigerator/waterFilter.d.ts +19 -0
- package/dist/refrigerator/waterFilter.js +89 -0
- package/dist/refrigerator/waterFilter.js.map +1 -0
- package/dist/refrigeratorServices.d.ts +5 -0
- package/dist/refrigeratorServices.js +54 -0
- package/dist/refrigeratorServices.js.map +1 -0
- package/dist/settings.d.ts +12 -0
- package/dist/settings.js +13 -0
- package/dist/settings.js.map +1 -0
- package/dist/smartHqApi.d.ts +29 -0
- package/dist/smartHqApi.js +267 -0
- package/dist/smartHqApi.js.map +1 -0
- package/dist/smarthq-types.d.ts +29 -0
- package/dist/smarthq-types.js +2 -0
- package/dist/smarthq-types.js.map +1 -0
- package/eslint.config.js +12 -0
- package/images/homebridge.svg +1 -0
- package/package.json +61 -0
- package/src/@types/homebridge-lib.d.ts +14 -0
- package/src/index.ts +11 -0
- package/src/platform.ts +300 -0
- package/src/refrigerator/controlLock.ts +103 -0
- package/src/refrigerator/convertibleDrawer.ts +381 -0
- package/src/refrigerator/dispenserLight.ts +103 -0
- package/src/refrigerator/energy.ts +106 -0
- package/src/refrigerator/freezer.ts +227 -0
- package/src/refrigerator/iceMaker.ts +100 -0
- package/src/refrigerator/interiorLight.ts +118 -0
- package/src/refrigerator/refrigerator.ts +241 -0
- package/src/refrigerator/refrigeratorAlerts.ts +228 -0
- package/src/refrigerator/sabbathMode.ts +111 -0
- package/src/refrigerator/temperatureUnits.ts +178 -0
- package/src/refrigerator/turboCoolMode.ts +164 -0
- package/src/refrigerator/waterFilter.ts +107 -0
- package/src/refrigeratorServices.ts +60 -0
- package/src/settings.ts +14 -0
- package/src/smartHqApi.ts +305 -0
- package/src/smarthq-types.ts +31 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,381 @@
|
|
|
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 ConvertibleDrawer {
|
|
12
|
+
private readonly smartHqApi: SmartHqApi;
|
|
13
|
+
|
|
14
|
+
//------------------- Convertible Drawer Temperature Service -----------------------
|
|
15
|
+
private convertibleDrawerMode = {
|
|
16
|
+
MEAT: "cloud.smarthq.type.mode.convertibledrawer.mode3",
|
|
17
|
+
BEVERAGES: "cloud.smarthq.type.mode.convertibledrawer.mode4",
|
|
18
|
+
SNACKS: "cloud.smarthq.type.mode.convertibledrawer.mode5",
|
|
19
|
+
WINE: "cloud.smarthq.type.mode.convertibledrawer.mode6",
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
private log : Logging;
|
|
23
|
+
|
|
24
|
+
constructor(
|
|
25
|
+
private readonly platform: SmartHqPlatform,
|
|
26
|
+
private readonly accessory: PlatformAccessory,
|
|
27
|
+
public readonly deviceServices: DevService[],
|
|
28
|
+
public readonly deviceId: string
|
|
29
|
+
) {
|
|
30
|
+
this.platform = platform;
|
|
31
|
+
this.accessory = accessory;
|
|
32
|
+
this.deviceServices = deviceServices;
|
|
33
|
+
this.deviceId = deviceId;
|
|
34
|
+
this.log = platform.log;
|
|
35
|
+
|
|
36
|
+
this.smartHqApi = new SmartHqApi(this.platform);
|
|
37
|
+
|
|
38
|
+
//=====================================================================================
|
|
39
|
+
// Check to see if the device has any supported Convertible Drawer services
|
|
40
|
+
// If not, then don't add services for device that doesn't support it
|
|
41
|
+
//=====================================================================================
|
|
42
|
+
|
|
43
|
+
if (!this.platform.deviceSupportsThisService(this.deviceServices,
|
|
44
|
+
'cloud.smarthq.device.refrigerator.convertibledrawer',
|
|
45
|
+
'cloud.smarthq.service.mode',
|
|
46
|
+
'cloud.smarthq.domain.mode.selection')) {
|
|
47
|
+
this.log.info('No supported Convertible Drawer services found for device: ' + this.accessory.displayName);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
this.platform.debug('green', 'Adding Convertible Drawer Switches');
|
|
51
|
+
|
|
52
|
+
// set accessory information
|
|
53
|
+
this.accessory.getService(this.platform.Service.AccessoryInformation)!
|
|
54
|
+
.setCharacteristic(this.platform.Characteristic.Manufacturer, 'GE')
|
|
55
|
+
.setCharacteristic(this.platform.Characteristic.Model, accessory.context.device.model || 'Default-Model')
|
|
56
|
+
.setCharacteristic(this.platform.Characteristic.SerialNumber, accessory.context.device.serial || 'Default-Serial');
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
//=====================================================================================
|
|
60
|
+
// create some new Switch services for the Refrigerator to be used like radio buttons
|
|
61
|
+
// to set the Convertible Drawer modes (Snacks, Meat, Beverages, Wine)
|
|
62
|
+
//=====================================================================================
|
|
63
|
+
let displayName = "Drawer Meat";
|
|
64
|
+
|
|
65
|
+
const convertibleDrawerMeat = this.accessory.getService(displayName)
|
|
66
|
+
|| this.accessory.addService(this.platform.Service.Switch, displayName, 'drawer-mode-3');
|
|
67
|
+
convertibleDrawerMeat.setCharacteristic(this.platform.Characteristic.Name, displayName);
|
|
68
|
+
convertibleDrawerMeat.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
|
|
69
|
+
convertibleDrawerMeat.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
|
|
70
|
+
displayName = "Drawer Beverages";
|
|
71
|
+
|
|
72
|
+
const convertibleDrawerBeverages = this.accessory.getService(displayName)
|
|
73
|
+
|| this.accessory.addService(this.platform.Service.Switch, displayName, 'drawer-mode-4');
|
|
74
|
+
convertibleDrawerBeverages.setCharacteristic(this.platform.Characteristic.Name, displayName);
|
|
75
|
+
convertibleDrawerBeverages.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
|
|
76
|
+
convertibleDrawerBeverages.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
|
|
77
|
+
|
|
78
|
+
displayName = "Drawer Snacks";
|
|
79
|
+
|
|
80
|
+
const convertibleDrawerSnacks = this.accessory.getService(displayName)
|
|
81
|
+
|| this.accessory.addService(this.platform.Service.Switch, displayName, 'drawer-mode-5');
|
|
82
|
+
convertibleDrawerSnacks.setCharacteristic(this.platform.Characteristic.Name, displayName);
|
|
83
|
+
convertibleDrawerSnacks.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
|
|
84
|
+
convertibleDrawerSnacks.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
|
|
85
|
+
|
|
86
|
+
displayName = "Drawer Wine";
|
|
87
|
+
const convertibleDrawerWine = this.accessory.getService(displayName)
|
|
88
|
+
|| this.accessory.addService(this.platform.Service.Switch, displayName, 'drawer-mode-6');
|
|
89
|
+
convertibleDrawerWine.setCharacteristic(this.platform.Characteristic.Name, displayName);
|
|
90
|
+
convertibleDrawerWine.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
|
|
91
|
+
convertibleDrawerWine.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
|
|
92
|
+
|
|
93
|
+
// create handlers for required characteristics
|
|
94
|
+
convertibleDrawerSnacks.getCharacteristic(this.platform.Characteristic.On)
|
|
95
|
+
.onGet(this.getConvertibleDrawerSnacks.bind(this))
|
|
96
|
+
.onSet(this.setConvertibleDrawerSnacks.bind(this));
|
|
97
|
+
|
|
98
|
+
convertibleDrawerMeat.getCharacteristic(this.platform.Characteristic.On)
|
|
99
|
+
.onGet(this.getConvertibleDrawerMeat.bind(this))
|
|
100
|
+
.onSet(this.setConvertibleDrawerMeat.bind(this));
|
|
101
|
+
|
|
102
|
+
convertibleDrawerBeverages.getCharacteristic(this.platform.Characteristic.On)
|
|
103
|
+
.onGet(this.getConvertibleDrawerBeverages.bind(this))
|
|
104
|
+
.onSet(this.setConvertibleDrawerBeverages.bind(this));
|
|
105
|
+
|
|
106
|
+
convertibleDrawerWine.getCharacteristic(this.platform.Characteristic.On)
|
|
107
|
+
.onGet(this.getConvertibleDrawerWine.bind(this))
|
|
108
|
+
.onSet(this.setConvertibleDrawerWine.bind(this));
|
|
109
|
+
|
|
110
|
+
// Service for Convertible Drawer Temperature Sensor
|
|
111
|
+
|
|
112
|
+
displayName = "Drawer Temp";
|
|
113
|
+
const drawerTemperature = this.accessory.getService(displayName)
|
|
114
|
+
|| this.accessory.addService(this.platform.Service.TemperatureSensor, displayName, 'drawer-temp-1');
|
|
115
|
+
drawerTemperature.setCharacteristic(this.platform.Characteristic.Name, displayName);
|
|
116
|
+
drawerTemperature.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
|
|
117
|
+
drawerTemperature.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
|
|
118
|
+
|
|
119
|
+
drawerTemperature.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
|
|
120
|
+
.onGet(this.getDrawerTemperature.bind(this));
|
|
121
|
+
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
//=====================================================================================
|
|
125
|
+
async getDrawerTemperature(): Promise<CharacteristicValue> {
|
|
126
|
+
let temp = 0;
|
|
127
|
+
let mode = '0';
|
|
128
|
+
|
|
129
|
+
// First you need to find which mode is set for the Convertible Drawer
|
|
130
|
+
|
|
131
|
+
for (const service of this.deviceServices) {
|
|
132
|
+
if (service.serviceDeviceType === 'cloud.smarthq.device.refrigerator.convertibledrawer'
|
|
133
|
+
&& service.serviceType === 'cloud.smarthq.service.mode') {
|
|
134
|
+
|
|
135
|
+
const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
|
|
136
|
+
if (state == null || !state?.mode) {
|
|
137
|
+
this.platform.debug('blue', 'No mode returned from getDrawerTemperature state');
|
|
138
|
+
break; // an invalid mode value will be used below so no match will be found
|
|
139
|
+
}
|
|
140
|
+
const result = state?.mode.lastIndexOf(".");
|
|
141
|
+
mode = state?.mode.slice(result + 1);
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Add the 'mode' to serviceDeviceType to get the correct temperature service
|
|
147
|
+
|
|
148
|
+
for (const service of this.deviceServices) {
|
|
149
|
+
if (service.serviceDeviceType === `cloud.smarthq.device.refrigerator.convertibledrawer.${mode}`
|
|
150
|
+
&& service.serviceType === 'cloud.smarthq.service.temperature') {
|
|
151
|
+
|
|
152
|
+
const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
|
|
153
|
+
if (state == null || !state?.celsiusConverted) {
|
|
154
|
+
this.platform.debug('blue', 'No celsiusConverted returned from getDrawerTemperature state');
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
temp = state?.celsiusConverted;
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return temp;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
//=====================================================================================
|
|
165
|
+
async getConvertibleDrawerSnacks(): Promise<CharacteristicValue> {
|
|
166
|
+
// Find current mode and return true if = mode5 (Snacks)
|
|
167
|
+
const snacks = 'cloud.smarthq.type.mode.convertibledrawer.mode5';
|
|
168
|
+
let isOn = false;
|
|
169
|
+
|
|
170
|
+
for (const service of this.deviceServices) {
|
|
171
|
+
if (service.serviceDeviceType === 'cloud.smarthq.device.refrigerator.convertibledrawer'
|
|
172
|
+
&& service.serviceType === 'cloud.smarthq.service.mode') {
|
|
173
|
+
|
|
174
|
+
const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
|
|
175
|
+
if (state == null || !state?.mode) {
|
|
176
|
+
this.platform.debug('blue', 'No mode returned from getConvertibleDrawerSnacks state');
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (state?.mode === snacks) {
|
|
181
|
+
isOn = true;
|
|
182
|
+
}
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return isOn;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
//=====================================================================================
|
|
190
|
+
async getConvertibleDrawerMeat(): Promise<CharacteristicValue> {
|
|
191
|
+
const meat = 'cloud.smarthq.type.mode.convertibledrawer.mode3';
|
|
192
|
+
// Find current mode and return true if = mode3 (Meat)
|
|
193
|
+
let isOn = false;
|
|
194
|
+
|
|
195
|
+
for (const service of this.deviceServices) {
|
|
196
|
+
if (service.serviceDeviceType === 'cloud.smarthq.device.refrigerator.convertibledrawer'
|
|
197
|
+
&& service.serviceType === 'cloud.smarthq.service.mode') {
|
|
198
|
+
|
|
199
|
+
const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
|
|
200
|
+
if (state == null || !state?.mode) {
|
|
201
|
+
this.platform.debug('blue', 'No mode returned from getConvertibleDrawerMeat state');
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (state?.mode === meat) {
|
|
206
|
+
isOn = true;
|
|
207
|
+
}
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return isOn;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
//=====================================================================================
|
|
215
|
+
async getConvertibleDrawerBeverages(): Promise<CharacteristicValue> {
|
|
216
|
+
const beverages = 'cloud.smarthq.type.mode.convertibledrawer.mode4';
|
|
217
|
+
// Find current mode and return true if = mode4 (Beverages)
|
|
218
|
+
let isOn = false;
|
|
219
|
+
|
|
220
|
+
for (const service of this.deviceServices) {
|
|
221
|
+
if (service.serviceDeviceType === 'cloud.smarthq.device.refrigerator.convertibledrawer'
|
|
222
|
+
&& service.serviceType === 'cloud.smarthq.service.mode') {
|
|
223
|
+
|
|
224
|
+
const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
|
|
225
|
+
if (state == null || !state?.mode) {
|
|
226
|
+
this.platform.debug('blue', 'No mode returned from getConvertibleDrawerBeverages state');
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (state.mode === beverages) {
|
|
231
|
+
isOn = true;
|
|
232
|
+
}
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return isOn;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
//=====================================================================================
|
|
240
|
+
async getConvertibleDrawerWine(): Promise<CharacteristicValue> {
|
|
241
|
+
const wine = 'cloud.smarthq.type.mode.convertibledrawer.mode6';
|
|
242
|
+
// Find current mode and return true if = mode6 (Wine)
|
|
243
|
+
let isOn = false;
|
|
244
|
+
|
|
245
|
+
for (const service of this.deviceServices) {
|
|
246
|
+
if (service.serviceDeviceType === 'cloud.smarthq.device.refrigerator.convertibledrawer'
|
|
247
|
+
&& service.serviceType === 'cloud.smarthq.service.mode') {
|
|
248
|
+
|
|
249
|
+
const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
|
|
250
|
+
if (state == null || !state?.mode) {
|
|
251
|
+
this.platform.debug('blue', 'No mode returned from getConvertibleDrawerWine state');
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (state.mode === wine) {
|
|
256
|
+
isOn = true;
|
|
257
|
+
}
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return isOn;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
//=====================================================================================
|
|
265
|
+
async setConvertibleDrawerMeat(value: CharacteristicValue) {
|
|
266
|
+
this.platform.debug('blue', "Triggered setConvertibleDrawerMeat");
|
|
267
|
+
if (value === true) {
|
|
268
|
+
const cmdBody = {
|
|
269
|
+
command: {
|
|
270
|
+
commandType: 'cloud.smarthq.command.mode.set',
|
|
271
|
+
mode: this.convertibleDrawerMode.MEAT
|
|
272
|
+
},
|
|
273
|
+
kind: 'service#command',
|
|
274
|
+
deviceId: this.deviceId,
|
|
275
|
+
serviceDeviceType: 'cloud.smarthq.device.refrigerator.convertibledrawer',
|
|
276
|
+
serviceType: 'cloud.smarthq.service.mode',
|
|
277
|
+
domainType: 'cloud.smarthq.domain.mode.selection'
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
const response = await this.smartHqApi.command(JSON.stringify(cmdBody));
|
|
281
|
+
|
|
282
|
+
if (response != null) {
|
|
283
|
+
// Update the switches for Wine, Snacks, Beverages to off
|
|
284
|
+
const switchSnacks = this.accessory.getService("Drawer Snacks");
|
|
285
|
+
switchSnacks?.getCharacteristic(this.platform.Characteristic.On).updateValue(false);
|
|
286
|
+
const switchBeverages = this.accessory.getService("Drawer Beverages");
|
|
287
|
+
switchBeverages?.getCharacteristic(this.platform.Characteristic.On).updateValue(false);
|
|
288
|
+
const switchWine = this.accessory.getService("Drawer Wine");
|
|
289
|
+
switchWine?.getCharacteristic(this.platform.Characteristic.On).updateValue(false);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
//=====================================================================================
|
|
295
|
+
async setConvertibleDrawerBeverages(value: CharacteristicValue) {
|
|
296
|
+
this.platform.debug('blue', "Triggered setConvertibleDrawerBeverages value: " + value);
|
|
297
|
+
|
|
298
|
+
const cmdBody = {
|
|
299
|
+
command: {
|
|
300
|
+
commandType: 'cloud.smarthq.command.mode.set',
|
|
301
|
+
mode: this.convertibleDrawerMode.BEVERAGES
|
|
302
|
+
},
|
|
303
|
+
kind: 'service#command',
|
|
304
|
+
deviceId: this.deviceId,
|
|
305
|
+
serviceDeviceType: 'cloud.smarthq.device.refrigerator.convertibledrawer',
|
|
306
|
+
serviceType: 'cloud.smarthq.service.mode',
|
|
307
|
+
domainType: 'cloud.smarthq.domain.mode.selection'
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
const response = await this.smartHqApi.command(JSON.stringify(cmdBody));
|
|
311
|
+
|
|
312
|
+
if (response != null) {
|
|
313
|
+
// Update the switches for Wine, Snacks, Meat to off
|
|
314
|
+
const switchSnacks = this.accessory.getService("Drawer Snacks");
|
|
315
|
+
switchSnacks?.getCharacteristic(this.platform.Characteristic.On).updateValue(false);
|
|
316
|
+
const switchWine = this.accessory.getService("Drawer Wine");
|
|
317
|
+
switchWine?.getCharacteristic(this.platform.Characteristic.On).updateValue(false);
|
|
318
|
+
const switchMeat = this.accessory.getService("Drawer Meat");
|
|
319
|
+
switchMeat?.getCharacteristic(this.platform.Characteristic.On).updateValue(false);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
//=====================================================================================
|
|
324
|
+
async setConvertibleDrawerSnacks(value: CharacteristicValue) {
|
|
325
|
+
this.platform.debug('blue', "Triggered setConvertibleDrawerSnacks value: " + value);
|
|
326
|
+
|
|
327
|
+
const cmdBody = {
|
|
328
|
+
command: {
|
|
329
|
+
commandType: 'cloud.smarthq.command.mode.set',
|
|
330
|
+
mode: this.convertibleDrawerMode.SNACKS
|
|
331
|
+
},
|
|
332
|
+
kind: 'service#command',
|
|
333
|
+
deviceId: this.deviceId,
|
|
334
|
+
serviceDeviceType: 'cloud.smarthq.device.refrigerator.convertibledrawer',
|
|
335
|
+
serviceType: 'cloud.smarthq.service.mode',
|
|
336
|
+
domainType: 'cloud.smarthq.domain.mode.selection'
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
const response = await this.smartHqApi.command(JSON.stringify(cmdBody));
|
|
340
|
+
|
|
341
|
+
if (response != null) {
|
|
342
|
+
// Update the switches for Wine, Meat, Beverages to off
|
|
343
|
+
const switchMeat = this.accessory.getService("Drawer Meat");
|
|
344
|
+
switchMeat?.getCharacteristic(this.platform.Characteristic.On).updateValue(false);
|
|
345
|
+
const switchBeverages = this.accessory.getService("Drawer Beverages");
|
|
346
|
+
switchBeverages?.getCharacteristic(this.platform.Characteristic.On).updateValue(false);
|
|
347
|
+
const switchWine = this.accessory.getService("Drawer Wine");
|
|
348
|
+
switchWine?.getCharacteristic(this.platform.Characteristic.On).updateValue(false);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
//=====================================================================================
|
|
352
|
+
async setConvertibleDrawerWine(value: CharacteristicValue) {
|
|
353
|
+
this.platform.debug('blue', "Triggered setConvertibleDrawerWine value: " + value);
|
|
354
|
+
|
|
355
|
+
const cmdBody = {
|
|
356
|
+
command: {
|
|
357
|
+
commandType: 'cloud.smarthq.command.mode.set',
|
|
358
|
+
mode: this.convertibleDrawerMode.WINE
|
|
359
|
+
},
|
|
360
|
+
kind: 'service#command',
|
|
361
|
+
deviceId: this.deviceId,
|
|
362
|
+
serviceDeviceType: 'cloud.smarthq.device.refrigerator.convertibledrawer',
|
|
363
|
+
serviceType: 'cloud.smarthq.service.mode',
|
|
364
|
+
domainType: 'cloud.smarthq.domain.mode.selection'
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
const response = await this.smartHqApi.command(JSON.stringify(cmdBody));
|
|
368
|
+
|
|
369
|
+
if (response != null) {
|
|
370
|
+
// Update the switches for Meat, Snacks, Beverages to off
|
|
371
|
+
const switchSnacks = this.accessory.getService("Drawer Snacks");
|
|
372
|
+
switchSnacks?.getCharacteristic(this.platform.Characteristic.On).updateValue(false);
|
|
373
|
+
const switchBeverages = this.accessory.getService("Drawer Beverages");
|
|
374
|
+
switchBeverages?.getCharacteristic(this.platform.Characteristic.On).updateValue(false);
|
|
375
|
+
const switchMeat = this.accessory.getService("Drawer Meat");
|
|
376
|
+
switchMeat?.getCharacteristic(this.platform.Characteristic.On).updateValue(false);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
|
|
@@ -0,0 +1,103 @@
|
|
|
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 DispenserLight {
|
|
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
|
+
// Check to see if the device has any supported Convertible Drawer services
|
|
30
|
+
// If not, then don't add services for device that doesn't support it
|
|
31
|
+
//=====================================================================================
|
|
32
|
+
|
|
33
|
+
if (!this.platform.deviceSupportsThisService(this.deviceServices,
|
|
34
|
+
'cloud.smarthq.device.refrigerator.dispenser.light',
|
|
35
|
+
'cloud.smarthq.service.toggle',
|
|
36
|
+
'cloud.smarthq.domain.activate.motion')) {
|
|
37
|
+
this.log.info('No supported Dispenser Light service found for device: ' + this.accessory.displayName);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
this.platform.debug('green', 'Adding Dispenser Light Switch');
|
|
41
|
+
|
|
42
|
+
//=====================================================================================
|
|
43
|
+
// create a Dispenser Light switch for the Refrigerator
|
|
44
|
+
//=====================================================================================
|
|
45
|
+
const displayName = "Dispenser Light";
|
|
46
|
+
|
|
47
|
+
const dispenserLight = this.accessory.getService(displayName)
|
|
48
|
+
|| this.accessory.addService(this.platform.Service.Switch, displayName, 'dispenser-light-123');
|
|
49
|
+
dispenserLight.setCharacteristic(this.platform.Characteristic.Name, displayName);
|
|
50
|
+
|
|
51
|
+
dispenserLight.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
|
|
52
|
+
dispenserLight.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
|
|
53
|
+
|
|
54
|
+
dispenserLight.getCharacteristic(this.platform.Characteristic.On)
|
|
55
|
+
.onGet(this.getdispenserLight.bind(this))
|
|
56
|
+
.onSet(this.setdispenserLight.bind(this));
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
//=====================================================================================
|
|
61
|
+
async getdispenserLight(): Promise<CharacteristicValue> {
|
|
62
|
+
|
|
63
|
+
let isOn = false;
|
|
64
|
+
|
|
65
|
+
for (const service of this.deviceServices) {
|
|
66
|
+
if (service.serviceDeviceType === 'cloud.smarthq.device.refrigerator.dispenser.light'
|
|
67
|
+
&& service.serviceType === 'cloud.smarthq.service.toggle'
|
|
68
|
+
&& service.domainType === 'cloud.smarthq.domain.activate.motion') {
|
|
69
|
+
const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
|
|
70
|
+
if (state?.on == null) {
|
|
71
|
+
this.platform.debug('blue','No On returned from getdispenserLight state');
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
isOn = state?.on;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return isOn;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
//=====================================================================================
|
|
81
|
+
async setdispenserLight(value: CharacteristicValue) {
|
|
82
|
+
|
|
83
|
+
const cmdBody = {
|
|
84
|
+
command: {
|
|
85
|
+
commandType: 'cloud.smarthq.command.toggle.set',
|
|
86
|
+
on: value
|
|
87
|
+
},
|
|
88
|
+
kind: 'service#command',
|
|
89
|
+
deviceId: this.deviceId,
|
|
90
|
+
serviceDeviceType: 'cloud.smarthq.device.refrigerator.dispenser.light',
|
|
91
|
+
serviceType: 'cloud.smarthq.service.toggle',
|
|
92
|
+
domainType: 'cloud.smarthq.domain.activate.motion'
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const response = await this.smartHqApi.command(JSON.stringify(cmdBody));
|
|
96
|
+
|
|
97
|
+
if (response == null) {
|
|
98
|
+
this.platform.debug('blue', 'No response from setdispenserLight command');
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
this.platform.debug('blue', 'setdispenserLight response: ' + response.outcome);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
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 EnergySensor {
|
|
12
|
+
|
|
13
|
+
private readonly smartHqApi: SmartHqApi;
|
|
14
|
+
private log : Logging;
|
|
15
|
+
private prevKwhReading: number = 0;
|
|
16
|
+
|
|
17
|
+
constructor(
|
|
18
|
+
private readonly platform: SmartHqPlatform,
|
|
19
|
+
private readonly accessory: PlatformAccessory,
|
|
20
|
+
public readonly deviceServices: DevService[],
|
|
21
|
+
public readonly deviceId: string
|
|
22
|
+
) {
|
|
23
|
+
this.platform = platform;
|
|
24
|
+
this.accessory = accessory;
|
|
25
|
+
this.deviceServices = deviceServices;
|
|
26
|
+
this.deviceId = deviceId;
|
|
27
|
+
this.log = platform.log;
|
|
28
|
+
|
|
29
|
+
this.smartHqApi = new SmartHqApi(this.platform);
|
|
30
|
+
|
|
31
|
+
//=====================================================================================
|
|
32
|
+
// Check to see if the device has any supported Energy Sensor services
|
|
33
|
+
// If not, then don't add a service for device that doesn't support it
|
|
34
|
+
//=====================================================================================
|
|
35
|
+
|
|
36
|
+
if (!this.platform.deviceSupportsThisService(this.deviceServices,
|
|
37
|
+
'cloud.smarthq.device.meter',
|
|
38
|
+
'cloud.smarthq.service.meter',
|
|
39
|
+
'cloud.smarthq.domain.energy')) {
|
|
40
|
+
this.log.info('No supported Energy Sensor services found for device: ' + this.accessory.displayName);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
this.platform.debug('green', 'Adding an Energy Sensor');
|
|
44
|
+
|
|
45
|
+
//=====================================================================================
|
|
46
|
+
// create a new water FilterMaintenance service for the Refrigerator
|
|
47
|
+
// This works in Homebridge and HomeKit has a native FilterMaintenance service type but the Home app does not implement it yet
|
|
48
|
+
// so no sensor/accessory will show up in the Home app for this service type.
|
|
49
|
+
//=====================================================================================
|
|
50
|
+
const displayName = "Watts/hr";
|
|
51
|
+
const energySensor = this.accessory.getService(displayName)
|
|
52
|
+
|| this.accessory.addService(this.platform.Service.TemperatureSensor, displayName, 'energy-2');
|
|
53
|
+
energySensor.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName)
|
|
54
|
+
energySensor.setCharacteristic(this.platform.Characteristic.ConfiguredName, displayName)
|
|
55
|
+
|
|
56
|
+
const energyCurrent = energySensor.getCharacteristic(this.platform.Characteristic.CurrentTemperature);
|
|
57
|
+
|
|
58
|
+
//=====================================================================================
|
|
59
|
+
// Now modify the properties for each characteristic to make the temperature sensor
|
|
60
|
+
// function as an energy readout in kWh
|
|
61
|
+
//=====================================================================================
|
|
62
|
+
try {
|
|
63
|
+
energyCurrent.setProps({
|
|
64
|
+
unit: 'kWh',
|
|
65
|
+
minValue: -30.0,
|
|
66
|
+
maxValue: 50000000.0,
|
|
67
|
+
minStep: 1.0
|
|
68
|
+
});
|
|
69
|
+
} catch (error) {
|
|
70
|
+
this.platform.debug('blue', 'Error setting Energy sensor properties: ' + error);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
//energySensor.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
|
|
74
|
+
// .onGet(this.getEnergyChange.bind(this));
|
|
75
|
+
//=====================================================================================
|
|
76
|
+
// Poll every 1800 seconds for new energy data
|
|
77
|
+
//=====================================================================================
|
|
78
|
+
setInterval(() => {
|
|
79
|
+
this.getEnergyChange().then(temp => {
|
|
80
|
+
energySensor.getCharacteristic(this.platform.Characteristic.CurrentTemperature).updateValue(temp);
|
|
81
|
+
});
|
|
82
|
+
}, 30 * 60 * 1000);
|
|
83
|
+
|
|
84
|
+
}
|
|
85
|
+
//=====================================================================================
|
|
86
|
+
async getEnergyChange(): Promise<CharacteristicValue> {
|
|
87
|
+
let kwhReading = 0
|
|
88
|
+
for (const service of this.deviceServices) {
|
|
89
|
+
if (service.serviceDeviceType === 'cloud.smarthq.device.meter'
|
|
90
|
+
&& service.serviceType === 'cloud.smarthq.service.meter') {
|
|
91
|
+
|
|
92
|
+
const state = await this.smartHqApi.getServiceState(this.deviceId, service.serviceId);
|
|
93
|
+
if (state?.meterValue == null) {
|
|
94
|
+
this.platform.debug('blue', 'No state.meterValue returned from getEnergyChange state');
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
kwhReading = state?.meterValue;
|
|
98
|
+
const intervalDelta = kwhReading - this.prevKwhReading;
|
|
99
|
+
kwhReading = (intervalDelta * 2 - 32) / 1.8; // Interval is 30 minutes so double to get hourly rate
|
|
100
|
+
this.prevKwhReading = state?.meterValue;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return kwhReading ; // Interval is 30 minutes so double to get hourly rate
|
|
105
|
+
}
|
|
106
|
+
}
|