homebridge-dummy 1.1.0-beta.1 → 1.1.0-beta.2

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/CHANGELOG.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  All notable changes to homebridge-dummy will be documented in this file.
4
4
 
5
- ## 1.1.0-beta.1 (2025-07-29)
5
+ ## 1.1.0-beta.2 (2025-07-31)
6
6
 
7
7
  ### ‼️ WARNING — Read this if upgrading from v0.9.2 or earlier…
8
8
 
@@ -14,6 +14,8 @@ Automations and scenes using Homebridge Dummy accessories will need to be reconf
14
14
  - Groups (Beta) - Items sharing the same group name will be collected together in the Home app UI
15
15
  - ⚠️ Adding/removing/changing the group name for an accessory will require you to reconfigure any HomeKit scenes or automations
16
16
  - Auto-Trigger feature to invoke accessory at a specified interval or times
17
+ - Support for Thermostats
18
+ - Manual control only, no auto-trigger or auto-reset functionality
17
19
 
18
20
  ### Changed
19
21
  - Reorganized plugin config UI and renamed "Timer" to "Auto-Reset"
package/README.md CHANGED
@@ -85,8 +85,8 @@ Using the Homebridge Config UI is the easiest way to set up this plugin. However
85
85
  {
86
86
  "id": "string",
87
87
  "name": "string",
88
+ "type": "Door | Lightbulb | LockMechanism | Outlet | Switch | Thermostat | Window | WindoCovering",
88
89
  "groupName": "string",
89
- "type": "Door | Lightbulb | LockMechanism | Outlet | Switch | Window | WindoCovering",
90
90
  "timer": {
91
91
  "delay": number,
92
92
  "units": "SECONDS | MINUTES | HOURS",
@@ -100,14 +100,20 @@ Using the Homebridge Config UI is the easiest way to set up this plugin. However
100
100
  "cron": "string"
101
101
  },
102
102
  "sensor": "CarbonDioxideSensor | CarbonMonoxideSensor | ContactSensor | LeakSensor | MotionSensor | OccupancySensor | SmokeSensor",
103
+ "temperatureUnits": "C" | "F",
103
104
  "defaultOn": true | false,
104
105
  "defaultBrightness": 0-100,
105
106
  "defaultLockState": "locked" | "unlocked",
106
107
  "defaultPosition": "open" | "closed",
107
- "onCommand": "string",
108
- "offCommand": "string",
109
- "lockCommand": "string",
110
- "unlockCommand": "string",
108
+ "defaultThermostatState": "auto" | "heat" | "cool" | "off",
109
+ "defaultTemperature": number,
110
+ "commandOn": "string",
111
+ "commandOff": "string",
112
+ "commandLock": "string",
113
+ "commandUnlock": "string",
114
+ "commandOpen": "string",
115
+ "commandClose": "string",
116
+ "commandTemperature": "string",
111
117
  "resetOnRestart": true | false,
112
118
  "disableLogging": true | false
113
119
  }
@@ -122,7 +128,7 @@ All fields are optional unless noted with an asterisk (*)
122
128
  - `id`* - A unique identifier for the accessory. Changing this value will create a new accessory.
123
129
 
124
130
  - `name`* - The display name for the accessory in HomeKit
125
- - `type`* - The type of accessory: `Door`, `Lightbulb`, `LockMechanism`, `Outlet`, `Switch`, `Window`, or `WindowCovering`
131
+ - `type`* - The type of accessory: `Door`, `Lightbulb`, `LockMechanism`, `Outlet`, `Switch`, `Thermostat`, `Window`, or `WindowCovering`
126
132
 
127
133
  - `groupName` - (Beta) Items sharing the same group name will be collected together in the Home app UI
128
134
  - ⚠️ Adding/removing/changing the group name will require you to reconfigure any HomeKit scenes or automations
@@ -142,6 +148,8 @@ All fields are optional unless noted with an asterisk (*)
142
148
  - Only works with `Lightbulb`, `Outlet`, and `Switch`
143
149
  - Valid values are `CarbonDioxideSensor`, `CarbonMonoxideSensor`, `ContactSensor`, `LeakSensor`, `MotionSensor`, `OccupancySensor`, or `SmokeSensor`
144
150
 
151
+ - `temperatureUnits` - Units to use for thermostats, either 'C' or 'F'
152
+
145
153
  - `defaultOn` — Initial value. Default _ON_ = true, default _OFF_ = false
146
154
 
147
155
  - `defaultBrightness` — If set, lightbulb will have additional dimmer settings with this default brightness percentage
@@ -150,12 +158,18 @@ All fields are optional unless noted with an asterisk (*)
150
158
 
151
159
  - `defaultPosition` — Initial position for the door/window/blinds, "open" or "closed"
152
160
 
153
- - `onCommand` - Arbitraty command to execute when lightbulb/outlet/switch turns on
154
- - `offCommand` - Arbitraty command to execute when lightbulb/outlet/switch turns off
161
+ - `defaultThermostatState` - The initial state for the thermostat, "auto", "heat", "cool", or "off"
162
+
163
+ - `defaultTemperature` - The default temperature for the thermostat in `temperatureUnits` defined above
164
+
165
+ - `onCommand` - Arbitraty command to execute when lightbulb/outlet/switch/thermostat turns on
166
+ - `offCommand` - Arbitraty command to execute when lightbulb/outlet/switch/thermostat turns off
155
167
 
156
168
  - `lockCommand` - Arbitraty command to execute when lock mechanism is locked
157
169
  - `unlockCommand` - Arbitraty command to execute when lock mechanism is unlocked
158
170
 
171
+ - `commandTemperature` - Arbitrary command to execute when temperature changes
172
+
159
173
  - `resetOnRestart` _ If true, accessory will return to default state when Homebridge restarts
160
174
 
161
175
  - `disableLogging` — If true, state changes will not be logged
@@ -304,6 +318,17 @@ All fields are optional unless noted with an asterisk (*)
304
318
  }
305
319
  ```
306
320
 
321
+ ### Thermostat
322
+ ```json
323
+ {
324
+ "name": "Thermostat",
325
+ "type": "Thermostat",
326
+ "temperatureUnits": "F",
327
+ "defaultThermostatState": "heat",
328
+ "defaultTemperature": 78
329
+ }
330
+ ```
331
+
307
332
  ## Credits
308
333
 
309
334
  Special thanks to [@nfarina](https://github.com/sponsors/nfarina) for creating the original version of this plugin and maintaining it for almost 10 (!!!) years
@@ -84,8 +84,8 @@
84
84
  "type": {
85
85
  "type": "string",
86
86
  "title": "${config.title.type}",
87
- "enum": ["Door", "Lightbulb", "LockMechanism", "Outlet", "Switch", "Window", "WindowCovering"],
88
- "enumNames": ["${config.enumNames.door}", "${config.enumNames.lightbulb}", "${config.enumNames.lockMechanism}", "${config.enumNames.outlet}", "${config.enumNames.switch}", "${config.enumNames.window}", "${config.enumNames.windowCovering}"]
87
+ "enum": ["Door", "Lightbulb", "LockMechanism", "Outlet", "Switch", "Thermostat", "Window", "WindowCovering"],
88
+ "enumNames": ["${config.enumNames.door}", "${config.enumNames.lightbulb}", "${config.enumNames.lockMechanism}", "${config.enumNames.outlet}", "${config.enumNames.switch}", "${config.enumNames.thermostat}", "${config.enumNames.window}", "${config.enumNames.windowCovering}"]
89
89
  },
90
90
  "groupName": {
91
91
  "type": "string",
@@ -99,6 +99,12 @@
99
99
  "enum": ["CarbonDioxideSensor", "CarbonMonoxideSensor", "ContactSensor", "LeakSensor", "MotionSensor", "OccupancySensor", "SmokeSensor"],
100
100
  "enumNames": ["${config.enumNames.carbonDioxideSensor}", "${config.enumNames.carbonMonoxideSensor}", "${config.enumNames.contactSensor}", "${config.enumNames.leakSensor}", "${config.enumNames.motionSensor}", "${config.enumNames.occupancySensor}", "${config.enumNames.smokeSensor}"]
101
101
  },
102
+ "temperatureUnits": {
103
+ "type": "string",
104
+ "title": "${config.title.units}",
105
+ "enum": ["C", "F"],
106
+ "enumNames": ["${config.enumNames.celsius}", "${config.enumNames.fahrenheit}"]
107
+ },
102
108
  "defaultBrightness": {
103
109
  "type": "number",
104
110
  "title": "${config.title.defaultBrightness}",
@@ -123,6 +129,16 @@
123
129
  "enum": ["open", "closed"],
124
130
  "enumNames": ["${config.enumNames.open}", "${config.enumNames.closed}"]
125
131
  },
132
+ "defaultThermostatState": {
133
+ "type": "string",
134
+ "title": "${config.title.defaultState}",
135
+ "enum": ["auto", "heat", "cool", "off"],
136
+ "enumNames": ["${config.enumNames.auto}", "${config.enumNames.heat}", "${config.enumNames.cool}", "${config.enumNames.off}"]
137
+ },
138
+ "defaultTemperature": {
139
+ "type": "number",
140
+ "title": "${config.title.defaultTemperature}"
141
+ },
126
142
  "commandOn": {
127
143
  "type": "string",
128
144
  "title": "${config.title.commandOn}"
@@ -147,6 +163,10 @@
147
163
  "type": "string",
148
164
  "title": "${config.title.commandClose}"
149
165
  },
166
+ "commandTemperature": {
167
+ "type": "string",
168
+ "title": "${config.title.commandTemperature}"
169
+ },
150
170
  "resetOnRestart": {
151
171
  "type": "boolean",
152
172
  "title": "${config.title.resetOnRestart}"
@@ -178,15 +198,15 @@
178
198
  "items": [
179
199
  {
180
200
  "key": "accessories[].name",
181
- "flex": "1 1 0"
201
+ "flex": "1 1 33%"
182
202
  },
183
203
  {
184
204
  "key": "accessories[].type",
185
- "flex": "1 1 0"
205
+ "flex": "1 1 33%"
186
206
  },
187
207
  {
188
208
  "key": "accessories[].groupName",
189
- "flex": "1 1 0"
209
+ "flex": "1 1 33%"
190
210
  }
191
211
  ]
192
212
  },
@@ -207,15 +227,15 @@
207
227
  "items": [
208
228
  {
209
229
  "key": "accessories[].defaultOn",
210
- "flex": "0 0 25%"
230
+ "flex": "0 0 33%"
211
231
  },
212
232
  {
213
233
  "key": "accessories[].sensor",
214
- "flex": "0 0 25%"
234
+ "flex": "0 0 33%"
215
235
  },
216
236
  {
217
237
  "key": "accessories[].defaultBrightness",
218
- "flex": "0 0 25%",
238
+ "flex": "0 0 33%",
219
239
  "condition": {
220
240
  "functionBody": "return ['Lightbulb'].includes(model.accessories?.[arguments[1]]?.type);"
221
241
  }
@@ -232,7 +252,7 @@
232
252
  "items": [
233
253
  {
234
254
  "key": "accessories[].defaultLockState",
235
- "flex": "0 0 25%"
255
+ "flex": "0 0 33%"
236
256
  }
237
257
  ]
238
258
  },
@@ -246,10 +266,32 @@
246
266
  "items": [
247
267
  {
248
268
  "key": "accessories[].defaultPosition",
249
- "flex": "0 0 25%"
269
+ "flex": "0 0 33%"
250
270
  }
251
271
  ]
252
- },
272
+ },
273
+ {
274
+ "type": "div",
275
+ "displayFlex": true,
276
+ "flex-direction": "row",
277
+ "condition": {
278
+ "functionBody": "return ['Thermostat'].includes(model.accessories?.[arguments[1]]?.type);"
279
+ },
280
+ "items": [
281
+ {
282
+ "key": "accessories[].temperatureUnits",
283
+ "flex": "0 0 33%"
284
+ },
285
+ {
286
+ "key": "accessories[].defaultThermostatState",
287
+ "flex": "0 0 33%"
288
+ },
289
+ {
290
+ "key": "accessories[].defaultTemperature",
291
+ "flex": "0 0 33%"
292
+ }
293
+ ]
294
+ },
253
295
  {
254
296
  "type": "div",
255
297
  "displayFlex": true,
@@ -257,11 +299,11 @@
257
299
  "items": [
258
300
  {
259
301
  "key": "accessories[].disableLogging",
260
- "flex": "0 1 25%"
302
+ "flex": "0 1 33%"
261
303
  },
262
304
  {
263
305
  "key": "accessories[].resetOnRestart",
264
- "flex": "0 1 25%",
306
+ "flex": "0 1 33%",
265
307
  "condition": {
266
308
  "functionBody": "return model.accessories?.[arguments[1]]?.timer?.delay === undefined;"
267
309
  }
@@ -275,7 +317,7 @@
275
317
  "title": "${config.title.trigger}",
276
318
  "description": "${config.description.trigger}",
277
319
  "condition": {
278
- "functionBody": "return model.accessories?.[arguments[1]]?.type !== undefined;"
320
+ "functionBody": "const type = model.accessories?.[arguments[1]]?.type; return type !== undefined && type !== 'Thermostat';"
279
321
  },
280
322
  "items": [
281
323
  {
@@ -285,18 +327,18 @@
285
327
  "items": [
286
328
  {
287
329
  "key": "accessories[].trigger.type",
288
- "flex": "1 1 0"
330
+ "flex": "1 1 33%"
289
331
  },
290
332
  {
291
333
  "key": "accessories[].trigger.interval",
292
- "flex": "1 1 0",
334
+ "flex": "1 1 33%",
293
335
  "condition": {
294
336
  "functionBody": "return model.accessories?.[arguments[1]]?.trigger?.type === 'INTERVAL';"
295
337
  }
296
338
  },
297
339
  {
298
340
  "key": "accessories[].trigger.units",
299
- "flex": "1 1 0",
341
+ "flex": "1 1 33%",
300
342
  "condition": {
301
343
  "functionBody": "return model.accessories?.[arguments[1]]?.trigger?.type === 'INTERVAL';"
302
344
  }
@@ -322,7 +364,7 @@
322
364
  "title": "${config.title.timer}",
323
365
  "description": "${config.description.timer}",
324
366
  "condition": {
325
- "functionBody": "return model.accessories?.[arguments[1]]?.type !== undefined;"
367
+ "functionBody": "const type = model.accessories?.[arguments[1]]?.type; return type !== undefined && type !== 'Thermostat';"
326
368
  },
327
369
  "items": [
328
370
  {
@@ -332,14 +374,14 @@
332
374
  "items": [
333
375
  {
334
376
  "key": "accessories[].timer.delay",
335
- "flex": "1 1 0"
377
+ "flex": "1 1 33%"
336
378
  },
337
379
  {
338
380
  "key": "accessories[].timer.units",
339
- "flex": "1 1 0"
381
+ "flex": "1 1 33%"
340
382
  },
341
383
  {
342
- "flex": "1 1 0"
384
+ "flex": "1 1 33%"
343
385
  }
344
386
  ]
345
387
  },
@@ -350,38 +392,51 @@
350
392
  "type": "fieldset",
351
393
  "title": "${config.title.commands}",
352
394
  "description": "${config.description.commands}",
353
- "condition": {
354
- "functionBody": "return ['Lightbulb','Outlet','Switch'].includes(model.accessories?.[arguments[1]]?.type);"
355
- },
356
395
  "items": [
357
- "accessories[].commandOn",
358
- "accessories[].commandOff"
359
- ]
360
- },
361
- {
362
- "type": "fieldset",
363
- "title": "${config.title.commands}",
364
- "description": "${config.description.commands}",
365
- "condition": {
366
- "functionBody": "return ['LockMechanism'].includes(model.accessories?.[arguments[1]]?.type);"
367
- },
368
- "items": [
369
- "accessories[].commandLock",
370
- "accessories[].commandUnlock"
371
- ]
372
- },
373
- {
374
- "type": "fieldset",
375
- "title": "${config.title.commands}",
376
- "description": "${config.description.commands}",
377
- "condition": {
378
- "functionBody": "return ['Door', 'Window', 'WindowCovering'].includes(model.accessories?.[arguments[1]]?.type);"
379
- },
380
- "items": [
381
- "accessories[].commandOpen",
382
- "accessories[].commandClose"
396
+ {
397
+ "key": "accessories[].commandOn",
398
+ "condition": {
399
+ "functionBody": "return ['Lightbulb','Outlet','Switch','Thermostat'].includes(model.accessories?.[arguments[1]]?.type);"
400
+ }
401
+ },
402
+ {
403
+ "key": "accessories[].commandOff",
404
+ "condition": {
405
+ "functionBody": "return ['Lightbulb','Outlet','Switch','Thermostat'].includes(model.accessories?.[arguments[1]]?.type);"
406
+ }
407
+ },
408
+ {
409
+ "key": "accessories[].commandLock",
410
+ "condition": {
411
+ "functionBody": "return ['LockMechanism'].includes(model.accessories?.[arguments[1]]?.type);"
412
+ }
413
+ },
414
+ {
415
+ "key": "accessories[].commandUnlock",
416
+ "condition": {
417
+ "functionBody": "return ['LockMechanism'].includes(model.accessories?.[arguments[1]]?.type);"
418
+ }
419
+ },
420
+ {
421
+ "key": "accessories[].commandOpen",
422
+ "condition": {
423
+ "functionBody": "return ['Door', 'Window', 'WindowCovering'].includes(model.accessories?.[arguments[1]]?.type);"
424
+ }
425
+ },
426
+ {
427
+ "key": "accessories[].commandClose",
428
+ "condition": {
429
+ "functionBody": "return ['Door', 'Window', 'WindowCovering'].includes(model.accessories?.[arguments[1]]?.type);"
430
+ }
431
+ },
432
+ {
433
+ "key": "accessories[].commandTemperature",
434
+ "condition": {
435
+ "functionBody": "return ['Thermostat'].includes(model.accessories?.[arguments[1]]?.type);"
436
+ }
437
+ }
383
438
  ]
384
- }
439
+ }
385
440
  ]
386
441
  }
387
442
  ]
@@ -10,7 +10,8 @@ export declare abstract class DummyAccessory<C extends DummyConfig> {
10
10
  protected readonly persistPath: string;
11
11
  static identifier(config: DummyConfig): string;
12
12
  protected readonly accessoryService: Service;
13
- private readonly timer;
13
+ private readonly _timer?;
14
+ private readonly _trigger?;
14
15
  constructor(Service: ServiceType, Characteristic: CharacteristicType, accessory: PlatformAccessory, config: C, log: Log, persistPath: string, isGrouped: boolean);
15
16
  protected abstract getAccessoryType(): AccessoryType;
16
17
  protected abstract trigger(): Promise<void>;
@@ -23,5 +24,5 @@ export declare abstract class DummyAccessory<C extends DummyConfig> {
23
24
  protected startTimer(): void;
24
25
  protected cancelTimer(): void;
25
26
  protected executeCommand(command: string): void;
26
- protected logIfDesired(message: string, ...parameters: string[]): void;
27
+ protected logIfDesired(message: string, ...parameters: (string | number)[]): void;
27
28
  }
@@ -16,7 +16,8 @@ export class DummyAccessory {
16
16
  return config.id ?? `${PLATFORM_NAME}:${config.type}:${config.name.replace(/\s+/g, '')}`;
17
17
  }
18
18
  accessoryService;
19
- timer = undefined;
19
+ _timer;
20
+ _trigger;
20
21
  constructor(Service, Characteristic, accessory, config, log, persistPath, isGrouped) {
21
22
  this.Service = Service;
22
23
  this.Characteristic = Characteristic;
@@ -25,10 +26,10 @@ export class DummyAccessory {
25
26
  this.log = log;
26
27
  this.persistPath = persistPath;
27
28
  if (config.timer) {
28
- this.timer = Timer.new(config.timer, config.name, log, config.disableLogging === true);
29
+ this._timer = Timer.new(config.timer, config.name, log, config.disableLogging === true);
29
30
  }
30
31
  if (config.trigger) {
31
- new Trigger(config.trigger, config.name, log, config.disableLogging === true, this.trigger.bind(this));
32
+ this._trigger = Trigger.new(config.trigger, config.name, log, config.disableLogging === true, this.trigger.bind(this));
32
33
  }
33
34
  const serviceInstance = Service[this.getAccessoryType()];
34
35
  if (isGrouped) {
@@ -53,22 +54,23 @@ export class DummyAccessory {
53
54
  return this.accessoryService.subtype;
54
55
  }
55
56
  teardown() {
56
- this.timer?.teardown();
57
+ this._timer?.teardown();
58
+ this._trigger?.teardown();
57
59
  }
58
60
  get identifier() {
59
61
  return DummyAccessory.identifier(this.config);
60
62
  }
61
63
  get isStateful() {
62
- return this.config.timer?.delay === undefined && !this.config.resetOnRestart;
64
+ return this._timer === undefined && this._trigger === undefined && !this.config.resetOnRestart;
63
65
  }
64
66
  get defaultStateStorageKey() {
65
67
  return `${this.identifier}:${STORAGE_KEY_SUFFIX_DEFAULT_STATE}`;
66
68
  }
67
69
  startTimer() {
68
- this.timer?.start(this.reset.bind(this));
70
+ this._timer?.start(this.reset.bind(this));
69
71
  }
70
72
  cancelTimer() {
71
- this.timer?.cancel();
73
+ this._timer?.cancel();
72
74
  }
73
75
  executeCommand(command) {
74
76
  exec(command, (_error, stdout, stderr) => {
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/accessory/base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/accessory/base.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import { LightbulbAccessory } from './onoff/lightbulb.js';
4
4
  import { LockAccessory } from './lock.js';
5
5
  import { OutletAccessory } from './onoff/outlet.js';
6
6
  import { SwitchAccessory } from './onoff/switch.js';
7
+ import { ThermostatAccessory } from './thermostat.js';
7
8
  import { WindowAccessory } from './position/window.js';
8
9
  import { strings } from '../i18n/i18n.js';
9
10
  import * as Types from '../model/types.js';
@@ -19,6 +20,8 @@ export function createDummyAccessory(Service, Characteristic, accessory, config,
19
20
  return new OutletAccessory(Service, Characteristic, accessory, config, log, persistPath, isGrouped);
20
21
  case Types.AccessoryType.Switch:
21
22
  return new SwitchAccessory(Service, Characteristic, accessory, config, log, persistPath, isGrouped);
23
+ case Types.AccessoryType.Thermostat:
24
+ return new ThermostatAccessory(Service, Characteristic, accessory, config, log, persistPath, isGrouped);
22
25
  case Types.AccessoryType.Window:
23
26
  return new WindowAccessory(Service, Characteristic, accessory, config, log, persistPath, isGrouped);
24
27
  case Types.AccessoryType.WindowCovering:
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/accessory/helpers.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAI3C,MAAM,UAAU,oBAAoB,CAClC,OAA0B,EAC1B,cAAwC,EACxC,SAA4B,EAC5B,MAAyB,EACzB,GAAQ,EACR,WAAmB,EACnB,YAAqB,KAAK;IAG1B,QAAO,MAAM,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,KAAK,CAAC,aAAa,CAAC,IAAI;YAC3B,OAAO,IAAI,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACpG,KAAK,KAAK,CAAC,aAAa,CAAC,SAAS;YAChC,OAAO,IAAI,kBAAkB,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACzG,KAAK,KAAK,CAAC,aAAa,CAAC,aAAa;YACpC,OAAO,IAAI,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACpG,KAAK,KAAK,CAAC,aAAa,CAAC,MAAM;YAC7B,OAAO,IAAI,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACtG,KAAK,KAAK,CAAC,aAAa,CAAC,MAAM;YAC7B,OAAO,IAAI,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACtG,KAAK,KAAK,CAAC,aAAa,CAAC,MAAM;YAC7B,OAAO,IAAI,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACtG,KAAK,KAAK,CAAC,aAAa,CAAC,cAAc;YACrC,OAAO,IAAI,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACrG;YACE,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;YAC/D,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/accessory/helpers.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAI3C,MAAM,UAAU,oBAAoB,CAClC,OAA0B,EAC1B,cAAwC,EACxC,SAA4B,EAC5B,MAAyB,EACzB,GAAQ,EACR,WAAmB,EACnB,YAAqB,KAAK;IAG1B,QAAO,MAAM,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,KAAK,CAAC,aAAa,CAAC,IAAI;YAC3B,OAAO,IAAI,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACpG,KAAK,KAAK,CAAC,aAAa,CAAC,SAAS;YAChC,OAAO,IAAI,kBAAkB,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACzG,KAAK,KAAK,CAAC,aAAa,CAAC,aAAa;YACpC,OAAO,IAAI,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACpG,KAAK,KAAK,CAAC,aAAa,CAAC,MAAM;YAC7B,OAAO,IAAI,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACtG,KAAK,KAAK,CAAC,aAAa,CAAC,MAAM;YAC7B,OAAO,IAAI,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACtG,KAAK,KAAK,CAAC,aAAa,CAAC,UAAU;YACjC,OAAO,IAAI,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QAC1G,KAAK,KAAK,CAAC,aAAa,CAAC,MAAM;YAC7B,OAAO,IAAI,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACtG,KAAK,KAAK,CAAC,aAAa,CAAC,cAAc;YACrC,OAAO,IAAI,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACrG;YACE,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;YAC/D,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { CharacteristicValue, PlatformAccessory } from 'homebridge';
2
+ import { DummyAccessory } from './base.js';
3
+ import { AccessoryType, CharacteristicType, ServiceType, ThermostatConfig } from '../model/types.js';
4
+ import { Log } from '../tools/log.js';
5
+ export declare class ThermostatAccessory extends DummyAccessory<ThermostatConfig> {
6
+ private readonly STATE_AUTO;
7
+ private readonly STATE_COOL;
8
+ private readonly STATE_HEAT;
9
+ private readonly STATE_OFF;
10
+ private state;
11
+ private temperature;
12
+ constructor(Service: ServiceType, Characteristic: CharacteristicType, accessory: PlatformAccessory, config: ThermostatConfig, log: Log, persistPath: string, isGrouped: boolean);
13
+ private initializeThermostat;
14
+ private get defaulTemperatureStorageKey();
15
+ protected getAccessoryType(): AccessoryType;
16
+ private get defaultState();
17
+ private get defaultTemperature();
18
+ private getUnits;
19
+ protected getCurrentState(): Promise<CharacteristicValue>;
20
+ private getState;
21
+ private setState;
22
+ private getTemperature;
23
+ private setTemperature;
24
+ trigger(): Promise<void>;
25
+ reset(): Promise<void>;
26
+ protected logState(value: CharacteristicValue): void;
27
+ protected logTemperature(value: CharacteristicValue): void;
28
+ }