homebridge-dummy 1.0.0-alpha.3 → 1.0.0-alpha.4
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 +1 -1
- package/README.md +47 -10
- package/config.schema.json +68 -15
- package/dist/accessory/base.d.ts +9 -8
- package/dist/accessory/base.js +19 -7
- package/dist/accessory/base.js.map +1 -1
- package/dist/accessory/group.d.ts +14 -0
- package/dist/accessory/group.js +39 -0
- package/dist/accessory/group.js.map +1 -0
- package/dist/accessory/helpers.d.ts +5 -0
- package/dist/accessory/helpers.js +22 -0
- package/dist/accessory/helpers.js.map +1 -0
- package/dist/accessory/lightbulb.d.ts +7 -7
- package/dist/accessory/lightbulb.js +21 -15
- package/dist/accessory/lightbulb.js.map +1 -1
- package/dist/accessory/lock.d.ts +15 -0
- package/dist/accessory/lock.js +63 -0
- package/dist/accessory/lock.js.map +1 -0
- package/dist/accessory/onoff.d.ts +4 -5
- package/dist/accessory/onoff.js +16 -15
- package/dist/accessory/onoff.js.map +1 -1
- package/dist/accessory/outlet.d.ts +5 -0
- package/dist/accessory/outlet.js +8 -0
- package/dist/accessory/outlet.js.map +1 -0
- package/dist/accessory/sensor.d.ts +19 -0
- package/dist/accessory/sensor.js +68 -0
- package/dist/accessory/sensor.js.map +1 -0
- package/dist/accessory/switch.d.ts +3 -6
- package/dist/accessory/switch.js +3 -5
- package/dist/accessory/switch.js.map +1 -1
- package/dist/homebridge/platform.js +6 -16
- package/dist/homebridge/platform.js.map +1 -1
- package/dist/homebridge-ui/public/index.html +1 -1
- package/dist/i18n/en.d.ts +50 -1
- package/dist/i18n/en.js +50 -1
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/i18n.d.ts +50 -1
- package/dist/i18n/template.d.ts +50 -1
- package/dist/i18n/zz.d.ts +50 -1
- package/dist/model/types.d.ts +36 -6
- package/dist/model/types.js +22 -0
- package/dist/model/types.js.map +1 -1
- package/dist/tools/configMigration.d.ts +2 -2
- package/dist/tools/configMigration.js +1 -1
- package/dist/tools/configMigration.js.map +1 -1
- package/dist/tools/storage.d.ts +2 -2
- package/dist/tools/storage.js +2 -2
- package/dist/tools/storage.js.map +1 -1
- package/package.json +1 -1
- package/src/homebridge-ui/public/index.html +0 -35
package/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,7 @@ All notable changes to homebridge-dummy will be documented in this file.
|
|
|
6
6
|
|
|
7
7
|
Please report any issues you encounter here: https://github.com/mpatfield/homebridge-dummy/issues
|
|
8
8
|
|
|
9
|
-
## 1.0.0-alpha.
|
|
9
|
+
## 1.0.0-alpha.4 (2025-07-03)
|
|
10
10
|
|
|
11
11
|
### ‼️ BREAKING This version is a complete code rewrite. Automations using Homebridge Dummy accessories will need to be reconfigured.
|
|
12
12
|
|
package/README.md
CHANGED
|
@@ -71,7 +71,7 @@ The first thing the flow does is create a backup called `config.json.bak` in you
|
|
|
71
71
|
|
|
72
72
|
With this plugin, you can create any number of fake accessories that will do nothing when triggered. This can be very useful for advanced automation with HomeKit scenes.
|
|
73
73
|
|
|
74
|
-
Currently, only Lightbulbs and Switches are supported
|
|
74
|
+
Currently, only Lightbulbs, Locks, Outlets, and Switches are supported. If there is a particular device you'd like to see supported, please [create an issue](https://github.com/mpatfield/homebridge-dummy/issues/new?template=new-issue.md).
|
|
75
75
|
|
|
76
76
|
## Configuration
|
|
77
77
|
|
|
@@ -83,15 +83,18 @@ Using the Homebridge Config UI is the easiest way to set up this plugin. However
|
|
|
83
83
|
"accessories": [
|
|
84
84
|
{
|
|
85
85
|
"name": "string",
|
|
86
|
-
"type": "Lightbulb | Switch",
|
|
86
|
+
"type": "Lightbulb | LockMechanism | Outlet | Switch",
|
|
87
87
|
"timer": {
|
|
88
|
-
"delay":
|
|
88
|
+
"delay": number,
|
|
89
89
|
"units": "SECONDS | MINUTES | HOURS",
|
|
90
|
-
"random": false
|
|
90
|
+
"random": true | false
|
|
91
91
|
},
|
|
92
|
-
"
|
|
93
|
-
"defaultBrightness": 100,
|
|
94
|
-
"
|
|
92
|
+
"defaultOnOff": 1 | 0,
|
|
93
|
+
"defaultBrightness": 0-100,
|
|
94
|
+
"defaultLockState": 0 | 1,
|
|
95
|
+
"sensor": "CarbonDioxideSensor | CarbonMonoxideSensor | ContactSensor | LeakSensor | MotionSensor | OccupancySensor | SmokeSensor",
|
|
96
|
+
"resetOnRestart": true | false,
|
|
97
|
+
"disableLogging": true | false
|
|
95
98
|
}
|
|
96
99
|
// ...additional accessories...
|
|
97
100
|
],
|
|
@@ -102,16 +105,24 @@ Using the Homebridge Config UI is the easiest way to set up this plugin. However
|
|
|
102
105
|
All fields are optional unless noted with an asterisk (*)
|
|
103
106
|
|
|
104
107
|
- `name`* - The display name for the accessory in HomeKit
|
|
105
|
-
- `type`* - The type of accessory, currently `Lightbulb` and `Switch` are supported
|
|
108
|
+
- `type`* - The type of accessory, currently `Lightbulb`, `LockMechanism`, `Outlet`, and `Switch` are supported
|
|
106
109
|
|
|
107
110
|
- `timer.delay` — If defined, the switch will automatically toggle after this many seconds/minutes/hours
|
|
108
111
|
- `timer.units` — The units to use for delay above (`SECONDS`, `MINUTES`, or `HOURS`). *Required if delay is set.
|
|
109
112
|
- `timer.random` — If true, the delay will be randomized with a maximum value of `timer.delay`
|
|
110
113
|
|
|
111
|
-
- `
|
|
114
|
+
- `defaultOnOff` — Initial value. Default _ON_ = 1, default _OFF_ = 0
|
|
112
115
|
|
|
113
116
|
- `defaultBrightness` — If set, lightbulb will have additional dimmer settings with this default brightness percentage
|
|
114
117
|
|
|
118
|
+
- `defaultLockState` - The initial value for the lock. UNSECURED (Unlocked) = 0, SECURED (Locked) = 1
|
|
119
|
+
|
|
120
|
+
- `sensor` - Optionally attach a sensor that mirrors the state of the parent accessory
|
|
121
|
+
- Only works with `Lightbulb`, `Outlet`, and `Switch`
|
|
122
|
+
- Valid values are `CarbonDioxideSensor`, `CarbonMonoxideSensor`, `ContactSensor`, `LeakSensor`, `MotionSensor`, `OccupancySensor`, or `SmokeSensor`
|
|
123
|
+
|
|
124
|
+
- `resetOnRestart` _ If true, all values return to defaults when Homebridge restarts. Ignored when timer is defined.
|
|
125
|
+
|
|
115
126
|
- `disableLogging` — If true, state changes will not be logged
|
|
116
127
|
|
|
117
128
|
## Examples
|
|
@@ -145,7 +156,7 @@ All fields are optional unless noted with an asterisk (*)
|
|
|
145
156
|
"delay": 5,
|
|
146
157
|
"units": "SECONDS"
|
|
147
158
|
},
|
|
148
|
-
"
|
|
159
|
+
"defaultOnOff": true
|
|
149
160
|
}
|
|
150
161
|
```
|
|
151
162
|
|
|
@@ -183,6 +194,32 @@ All fields are optional unless noted with an asterisk (*)
|
|
|
183
194
|
}
|
|
184
195
|
```
|
|
185
196
|
|
|
197
|
+
### Lock
|
|
198
|
+
```json
|
|
199
|
+
{
|
|
200
|
+
"name": "Lock",
|
|
201
|
+
"type": "LockMechanism",
|
|
202
|
+
"timer": {
|
|
203
|
+
"delay": 10,
|
|
204
|
+
"units": "MINUTES"
|
|
205
|
+
},
|
|
206
|
+
"defaultLockState": 0
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Motion Sensor Switch
|
|
211
|
+
```json
|
|
212
|
+
{
|
|
213
|
+
"name": "Motion Switch",
|
|
214
|
+
"type": "Switch",
|
|
215
|
+
"timer": {
|
|
216
|
+
"delay": 3,
|
|
217
|
+
"units": "MINUTES"
|
|
218
|
+
},
|
|
219
|
+
"sensor": "MotionSensor"
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
186
223
|
## Credits
|
|
187
224
|
|
|
188
225
|
Special thanks to [@nfarina](https://github.com/nfarina) for creating the original version of this plugin and maintaining it for almost 10 (!!!) years
|
package/config.schema.json
CHANGED
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"type": {
|
|
48
48
|
"type": "string",
|
|
49
49
|
"title": "${config.title.type}",
|
|
50
|
-
"enum": ["Lightbulb", "Switch"],
|
|
51
|
-
"enumNames": ["${config.enumNames.lightbulb}", "${config.enumNames.switch}"],
|
|
50
|
+
"enum": ["Lightbulb", "LockMechanism", "Outlet", "Switch"],
|
|
51
|
+
"enumNames": ["${config.enumNames.lightbulb}", "${config.enumNames.lockMechanism}", "${config.enumNames.outlet}", "${config.enumNames.switch}"],
|
|
52
52
|
"required": true
|
|
53
53
|
},
|
|
54
54
|
"timer": { "$ref": "#/definitions/timer" },
|
|
@@ -58,9 +58,27 @@
|
|
|
58
58
|
"maximum": 100,
|
|
59
59
|
"title": "${config.title.defaultBrightness}"
|
|
60
60
|
},
|
|
61
|
-
"
|
|
61
|
+
"defaultOnOff": {
|
|
62
|
+
"type": "number",
|
|
63
|
+
"title": "${config.title.defaultState}",
|
|
64
|
+
"enum": [1, 0],
|
|
65
|
+
"enumNames": ["${config.enumNames.on}", "${config.enumNames.off}"]
|
|
66
|
+
},
|
|
67
|
+
"defaultLockState": {
|
|
68
|
+
"type": "number",
|
|
69
|
+
"title": "${config.title.defaultState}",
|
|
70
|
+
"enum": [1, 0],
|
|
71
|
+
"enumNames": ["${config.enumNames.secured}", "${config.enumNames.unsecured}"]
|
|
72
|
+
},
|
|
73
|
+
"sensor": {
|
|
74
|
+
"type": "string",
|
|
75
|
+
"title": "${config.title.sensor}",
|
|
76
|
+
"enum": ["CarbonDioxideSensor", "CarbonMonoxideSensor", "ContactSensor", "LeakSensor", "MotionSensor", "OccupancySensor", "SmokeSensor"],
|
|
77
|
+
"enumNames": ["${config.enumNames.carbonDioxideSensor}", "${config.enumNames.carbonMonoxideSensor}", "${config.enumNames.contactSensor}", "${config.enumNames.leakSensor}", "${config.enumNames.motionSensor}", "${config.enumNames.occupancySensor}", "${config.enumNames.smokeSensor}"]
|
|
78
|
+
},
|
|
79
|
+
"resetOnRestart": {
|
|
62
80
|
"type": "boolean",
|
|
63
|
-
"title": "${config.title.
|
|
81
|
+
"title": "${config.title.resetOnRestart}"
|
|
64
82
|
},
|
|
65
83
|
"disableLogging": {
|
|
66
84
|
"title": "${config.title.disableLogging}",
|
|
@@ -102,7 +120,7 @@
|
|
|
102
120
|
"title": "${config.title.timer}",
|
|
103
121
|
"description": "${config.description.timer}",
|
|
104
122
|
"condition": {
|
|
105
|
-
"functionBody": "return model.accessories?.[arguments[1]]?.type;"
|
|
123
|
+
"functionBody": "return model.accessories?.[arguments[1]]?.type !== undefined;"
|
|
106
124
|
},
|
|
107
125
|
"items": [
|
|
108
126
|
{
|
|
@@ -132,30 +150,65 @@
|
|
|
132
150
|
"type": "fieldset",
|
|
133
151
|
"title": "${config.title.options}",
|
|
134
152
|
"condition": {
|
|
135
|
-
"functionBody": "return
|
|
153
|
+
"functionBody": "return model.accessories?.[arguments[1]]?.type !== undefined;"
|
|
136
154
|
},
|
|
137
155
|
"items": [
|
|
138
156
|
{
|
|
139
157
|
"type": "div",
|
|
140
158
|
"displayFlex": true,
|
|
141
159
|
"flex-direction": "row",
|
|
160
|
+
"condition": {
|
|
161
|
+
"functionBody": "return ['Lightbulb','Outlet','Switch'].includes(model.accessories?.[arguments[1]]?.type);"
|
|
162
|
+
},
|
|
142
163
|
"items": [
|
|
143
164
|
{
|
|
144
|
-
"key": "accessories[].
|
|
145
|
-
"flex": "
|
|
165
|
+
"key": "accessories[].defaultOnOff",
|
|
166
|
+
"flex": "0 0 25%"
|
|
146
167
|
},
|
|
147
168
|
{
|
|
148
|
-
"key": "accessories[].
|
|
149
|
-
"flex": "
|
|
150
|
-
}
|
|
169
|
+
"key": "accessories[].sensor",
|
|
170
|
+
"flex": "0 0 25%"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"key": "accessories[].defaultBrightness",
|
|
174
|
+
"flex": "0 0 25%",
|
|
175
|
+
"condition": {
|
|
176
|
+
"functionBody": "return ['Lightbulb'].includes(model.accessories?.[arguments[1]]?.type);"
|
|
177
|
+
}
|
|
178
|
+
}
|
|
151
179
|
]
|
|
152
180
|
},
|
|
153
181
|
{
|
|
154
|
-
"
|
|
155
|
-
"
|
|
182
|
+
"type": "div",
|
|
183
|
+
"displayFlex": true,
|
|
184
|
+
"flex-direction": "row",
|
|
156
185
|
"condition": {
|
|
157
|
-
"functionBody": "return ['
|
|
158
|
-
}
|
|
186
|
+
"functionBody": "return ['LockMechanism'].includes(model.accessories?.[arguments[1]]?.type);"
|
|
187
|
+
},
|
|
188
|
+
"items": [
|
|
189
|
+
{
|
|
190
|
+
"key": "accessories[].defaultLockState",
|
|
191
|
+
"flex": "0 0 25%"
|
|
192
|
+
}
|
|
193
|
+
]
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"type": "div",
|
|
197
|
+
"displayFlex": true,
|
|
198
|
+
"flex-direction": "row",
|
|
199
|
+
"items": [
|
|
200
|
+
{
|
|
201
|
+
"key": "accessories[].disableLogging",
|
|
202
|
+
"flex": "0 1 25%"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"key": "accessories[].resetOnRestart",
|
|
206
|
+
"flex": "0 1 25%",
|
|
207
|
+
"condition": {
|
|
208
|
+
"functionBody": "return model.accessories?.[arguments[1]]?.timer?.delay === undefined;"
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
]
|
|
159
212
|
}
|
|
160
213
|
]
|
|
161
214
|
}
|
package/dist/accessory/base.d.ts
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import { PlatformAccessory, Service } from 'homebridge';
|
|
2
|
-
import { CharacteristicType,
|
|
2
|
+
import { AccessoryType, CharacteristicType, DummyConfig, ServiceType } from '../model/types.js';
|
|
3
3
|
import { Log } from '../tools/log.js';
|
|
4
|
-
export declare abstract class DummyAccessory {
|
|
4
|
+
export declare abstract class DummyAccessory<C extends DummyConfig> {
|
|
5
5
|
protected readonly Service: ServiceType;
|
|
6
6
|
protected readonly Characteristic: CharacteristicType;
|
|
7
7
|
protected readonly accessory: PlatformAccessory;
|
|
8
|
-
protected readonly config:
|
|
8
|
+
protected readonly config: C;
|
|
9
9
|
protected readonly log: Log;
|
|
10
10
|
protected readonly persistPath: string;
|
|
11
|
-
|
|
12
|
-
static identifier(config: DummyAccessoryConfig): string;
|
|
11
|
+
static identifier(config: DummyConfig): string;
|
|
13
12
|
protected readonly accessoryService: Service;
|
|
14
13
|
private readonly timer;
|
|
15
|
-
constructor(Service: ServiceType, Characteristic: CharacteristicType, accessory: PlatformAccessory, config:
|
|
16
|
-
protected abstract
|
|
14
|
+
constructor(Service: ServiceType, Characteristic: CharacteristicType, accessory: PlatformAccessory, config: C, log: Log, persistPath: string, isGrouped: boolean);
|
|
15
|
+
protected abstract getAccessoryType(): AccessoryType;
|
|
17
16
|
teardown(): void;
|
|
18
17
|
protected get identifier(): string;
|
|
18
|
+
protected get isStateful(): boolean;
|
|
19
|
+
protected get defaultStateStorageKey(): string;
|
|
19
20
|
protected startTimer(callback: () => Promise<void>): void;
|
|
20
21
|
protected cancelTimer(): void;
|
|
21
|
-
protected assert(...keys: (keyof
|
|
22
|
+
protected assert(...keys: (keyof C)[]): boolean;
|
|
22
23
|
protected logIfDesired(message: string, ...parameters: string[]): void;
|
|
23
24
|
}
|
package/dist/accessory/base.js
CHANGED
|
@@ -2,6 +2,7 @@ import { PLATFORM_NAME, PLUGIN_ALIAS } from '../homebridge/settings.js';
|
|
|
2
2
|
import getVersion from '../tools/version.js';
|
|
3
3
|
import { Timer } from '../model/timer.js';
|
|
4
4
|
import { assert } from '../tools/validation.js';
|
|
5
|
+
import { STORAGE_KEY_SUFFIX_DEFAULT_STATE } from '../tools/storage.js';
|
|
5
6
|
export class DummyAccessory {
|
|
6
7
|
Service;
|
|
7
8
|
Characteristic;
|
|
@@ -9,28 +10,34 @@ export class DummyAccessory {
|
|
|
9
10
|
config;
|
|
10
11
|
log;
|
|
11
12
|
persistPath;
|
|
12
|
-
caller;
|
|
13
13
|
static identifier(config) {
|
|
14
14
|
return `${PLATFORM_NAME}:${config.type}:${config.name.replace(/\s+/g, '')}`;
|
|
15
15
|
}
|
|
16
16
|
accessoryService;
|
|
17
17
|
timer;
|
|
18
|
-
constructor(Service, Characteristic, accessory, config, log, persistPath,
|
|
18
|
+
constructor(Service, Characteristic, accessory, config, log, persistPath, isGrouped) {
|
|
19
19
|
this.Service = Service;
|
|
20
20
|
this.Characteristic = Characteristic;
|
|
21
21
|
this.accessory = accessory;
|
|
22
22
|
this.config = config;
|
|
23
23
|
this.log = log;
|
|
24
24
|
this.persistPath = persistPath;
|
|
25
|
-
this.caller = caller;
|
|
26
25
|
this.timer = new Timer(config.name, config.disableLogging ? undefined : log);
|
|
26
|
+
const serviceInstance = Service[this.getAccessoryType()];
|
|
27
|
+
if (isGrouped) {
|
|
28
|
+
this.accessoryService =
|
|
29
|
+
accessory.getServiceById(serviceInstance, this.identifier) ||
|
|
30
|
+
accessory.addService(serviceInstance, config.name, this.identifier);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
27
33
|
accessory.getService(Service.AccessoryInformation)
|
|
28
34
|
.setCharacteristic(Characteristic.Name, config.name)
|
|
29
35
|
.setCharacteristic(Characteristic.ConfiguredName, config.name)
|
|
30
36
|
.setCharacteristic(Characteristic.Manufacturer, PLUGIN_ALIAS)
|
|
31
|
-
.setCharacteristic(Characteristic.Model,
|
|
37
|
+
.setCharacteristic(Characteristic.Model, config.type)
|
|
38
|
+
.setCharacteristic(Characteristic.SerialNumber, accessory.UUID)
|
|
32
39
|
.setCharacteristic(Characteristic.FirmwareRevision, getVersion());
|
|
33
|
-
this.accessoryService =
|
|
40
|
+
this.accessoryService = accessory.getService(serviceInstance) || accessory.addService(serviceInstance);
|
|
34
41
|
}
|
|
35
42
|
teardown() {
|
|
36
43
|
this.timer.teardown();
|
|
@@ -38,11 +45,17 @@ export class DummyAccessory {
|
|
|
38
45
|
get identifier() {
|
|
39
46
|
return DummyAccessory.identifier(this.config);
|
|
40
47
|
}
|
|
48
|
+
get isStateful() {
|
|
49
|
+
return this.config.timer?.delay === undefined && !this.config.resetOnRestart;
|
|
50
|
+
}
|
|
51
|
+
get defaultStateStorageKey() {
|
|
52
|
+
return `${this.identifier}:${STORAGE_KEY_SUFFIX_DEFAULT_STATE}`;
|
|
53
|
+
}
|
|
41
54
|
startTimer(callback) {
|
|
42
55
|
if (!this.config.timer?.delay) {
|
|
43
56
|
return;
|
|
44
57
|
}
|
|
45
|
-
if (!assert(this.log, this.
|
|
58
|
+
if (!assert(this.log, this.config.name, this.config.timer, 'units')) {
|
|
46
59
|
return;
|
|
47
60
|
}
|
|
48
61
|
this.timer.start(this.config.timer, callback);
|
|
@@ -50,7 +63,6 @@ export class DummyAccessory {
|
|
|
50
63
|
cancelTimer() {
|
|
51
64
|
this.timer.cancel();
|
|
52
65
|
}
|
|
53
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
54
66
|
assert(...keys) {
|
|
55
67
|
return assert(this.log, this.config.name, this.config, ...keys);
|
|
56
68
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/accessory/base.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAKxE,OAAO,UAAU,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/accessory/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { PlatformAccessory } from 'homebridge';
|
|
2
|
+
import { CharacteristicType, GroupConfig, ServiceType } from '../model/types.js';
|
|
3
|
+
import { Log } from '../tools/log.js';
|
|
4
|
+
export declare class GroupAccessory {
|
|
5
|
+
protected readonly Service: ServiceType;
|
|
6
|
+
protected readonly Characteristic: CharacteristicType;
|
|
7
|
+
protected readonly accessory: PlatformAccessory;
|
|
8
|
+
protected readonly config: GroupConfig;
|
|
9
|
+
protected readonly log: Log;
|
|
10
|
+
protected readonly persistPath: string;
|
|
11
|
+
private readonly accessories;
|
|
12
|
+
constructor(Service: ServiceType, Characteristic: CharacteristicType, accessory: PlatformAccessory, config: GroupConfig, log: Log, persistPath: string);
|
|
13
|
+
teardown(): void;
|
|
14
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createAccessory } from './helpers.js';
|
|
2
|
+
import { PLUGIN_ALIAS } from '../homebridge/settings.js';
|
|
3
|
+
import getVersion from '../tools/version.js';
|
|
4
|
+
export class GroupAccessory {
|
|
5
|
+
Service;
|
|
6
|
+
Characteristic;
|
|
7
|
+
accessory;
|
|
8
|
+
config;
|
|
9
|
+
log;
|
|
10
|
+
persistPath;
|
|
11
|
+
accessories = [];
|
|
12
|
+
constructor(Service, Characteristic, accessory, config, log, persistPath) {
|
|
13
|
+
this.Service = Service;
|
|
14
|
+
this.Characteristic = Characteristic;
|
|
15
|
+
this.accessory = accessory;
|
|
16
|
+
this.config = config;
|
|
17
|
+
this.log = log;
|
|
18
|
+
this.persistPath = persistPath;
|
|
19
|
+
accessory.getService(Service.AccessoryInformation)
|
|
20
|
+
.setCharacteristic(Characteristic.Manufacturer, PLUGIN_ALIAS)
|
|
21
|
+
.setCharacteristic(Characteristic.Model, GroupAccessory.name)
|
|
22
|
+
.setCharacteristic(Characteristic.SerialNumber, accessory.UUID)
|
|
23
|
+
.setCharacteristic(Characteristic.FirmwareRevision, getVersion());
|
|
24
|
+
for (const dummyConfig of config.accessories) {
|
|
25
|
+
const dummyAccessory = createAccessory(this.Service, this.Characteristic, accessory, dummyConfig, this.log, persistPath, true);
|
|
26
|
+
if (!dummyAccessory) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
this.accessories.push(dummyAccessory);
|
|
30
|
+
}
|
|
31
|
+
;
|
|
32
|
+
}
|
|
33
|
+
teardown() {
|
|
34
|
+
this.accessories.forEach(accessory => {
|
|
35
|
+
accessory.teardown();
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group.js","sourceRoot":"","sources":["../../src/accessory/group.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAK/C,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,UAAU,MAAM,qBAAqB,CAAC;AAE7C,MAAM,OAAO,cAAc;IAKJ;IACA;IACA;IACA;IACA;IACA;IARJ,WAAW,GAAoC,EAAE,CAAC;IAEnE,YACqB,OAAoB,EACpB,cAAkC,EAClC,SAA4B,EAC5B,MAAmB,EACnB,GAAQ,EACR,WAAmB;QALnB,YAAO,GAAP,OAAO,CAAa;QACpB,mBAAc,GAAd,cAAc,CAAoB;QAClC,cAAS,GAAT,SAAS,CAAmB;QAC5B,WAAM,GAAN,MAAM,CAAa;QACnB,QAAG,GAAH,GAAG,CAAK;QACR,gBAAW,GAAX,WAAW,CAAQ;QAGtC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,oBAAoB,CAAE;aAChD,iBAAiB,CAAC,cAAc,CAAC,YAAY,EAAE,YAAY,CAAC;aAC5D,iBAAiB,CAAC,cAAc,CAAC,KAAK,EAAE,cAAc,CAAC,IAAI,CAAC;aAC5D,iBAAiB,CAAC,cAAc,CAAC,YAAY,EAAE,SAAS,CAAC,IAAI,CAAC;aAC9D,iBAAiB,CAAC,cAAc,CAAC,gBAAgB,EAAE,UAAU,EAAE,CAAC,CAAC;QAEpE,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YAE7C,MAAM,cAAc,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;YAC/H,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,SAAS;YACX,CAAC;YAED,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACxC,CAAC;QAAA,CAAC;IACJ,CAAC;IAEM,QAAQ;QACb,IAAI,CAAC,WAAW,CAAC,OAAO,CAAE,SAAS,CAAC,EAAE;YACpC,SAAS,CAAC,QAAQ,EAAE,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { PlatformAccessory } from 'homebridge';
|
|
2
|
+
import { DummyAccessory } from './base.js';
|
|
3
|
+
import * as Types from '../model/types.js';
|
|
4
|
+
import { Log } from '../tools/log.js';
|
|
5
|
+
export declare function createAccessory(Service: Types.ServiceType, Characteristic: Types.CharacteristicType, accessory: PlatformAccessory, config: Types.DummyConfig, log: Log, persistPath: string, isGrouped?: boolean): DummyAccessory<Types.DummyConfig> | null;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { LightbulbAccessory } from './lightbulb.js';
|
|
2
|
+
import { LockAccessory } from './lock.js';
|
|
3
|
+
import { OutletAccessory } from './outlet.js';
|
|
4
|
+
import { SwitchAccessory } from './switch.js';
|
|
5
|
+
import { strings } from '../i18n/i18n.js';
|
|
6
|
+
import * as Types from '../model/types.js';
|
|
7
|
+
export function createAccessory(Service, Characteristic, accessory, config, log, persistPath, isGrouped = false) {
|
|
8
|
+
switch (config.type) {
|
|
9
|
+
case Types.AccessoryType.Lightbulb:
|
|
10
|
+
return new LightbulbAccessory(Service, Characteristic, accessory, config, log, persistPath, isGrouped);
|
|
11
|
+
case Types.AccessoryType.LockMechanism:
|
|
12
|
+
return new LockAccessory(Service, Characteristic, accessory, config, log, persistPath, isGrouped);
|
|
13
|
+
case Types.AccessoryType.Outlet:
|
|
14
|
+
return new OutletAccessory(Service, Characteristic, accessory, config, log, persistPath, isGrouped);
|
|
15
|
+
case Types.AccessoryType.Switch:
|
|
16
|
+
return new SwitchAccessory(Service, Characteristic, accessory, config, log, persistPath, isGrouped);
|
|
17
|
+
default:
|
|
18
|
+
log.error(strings.startup.unsupportedType, `'${config.type}'`);
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/accessory/helpers.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAI3C,MAAM,UAAU,eAAe,CAC7B,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,SAAS;YAChC,OAAO,IAAI,kBAAkB,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAA+B,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QAClI,KAAK,KAAK,CAAC,aAAa,CAAC,aAAa;YACpC,OAAO,IAAI,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAA0B,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACxH,KAAK,KAAK,CAAC,aAAa,CAAC,MAAM;YAC7B,OAAO,IAAI,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAA4B,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QAC5H,KAAK,KAAK,CAAC,aAAa,CAAC,MAAM;YAC7B,OAAO,IAAI,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAA4B,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QAC5H;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,14 +1,14 @@
|
|
|
1
|
-
import { CharacteristicValue, PlatformAccessory
|
|
1
|
+
import { CharacteristicValue, PlatformAccessory } from 'homebridge';
|
|
2
2
|
import { OnOffAccessory } from './onoff.js';
|
|
3
|
-
import { CharacteristicType, LightbulbConfig, ServiceType } from '../model/types.js';
|
|
3
|
+
import { AccessoryType, CharacteristicType, LightbulbConfig, ServiceType } from '../model/types.js';
|
|
4
4
|
import { Log } from '../tools/log.js';
|
|
5
|
-
export declare class LightbulbAccessory extends OnOffAccessory {
|
|
6
|
-
private isDimmer;
|
|
5
|
+
export declare class LightbulbAccessory extends OnOffAccessory<LightbulbConfig> {
|
|
7
6
|
private brightness;
|
|
8
|
-
constructor(Service: ServiceType, Characteristic: CharacteristicType, accessory: PlatformAccessory,
|
|
9
|
-
private get
|
|
7
|
+
constructor(Service: ServiceType, Characteristic: CharacteristicType, accessory: PlatformAccessory, config: LightbulbConfig, log: Log, persistPath: string, isGrouped: boolean);
|
|
8
|
+
private get isDimmer();
|
|
9
|
+
private get defaultBrightnessStorageKey();
|
|
10
|
+
protected getAccessoryType(): AccessoryType;
|
|
10
11
|
private initializeBrightness;
|
|
11
|
-
protected getAccessoryService(): Service;
|
|
12
12
|
logOnState(value: CharacteristicValue): void;
|
|
13
13
|
protected getBrightness(): Promise<CharacteristicValue>;
|
|
14
14
|
protected setBrightness(value: CharacteristicValue): Promise<void>;
|
|
@@ -1,31 +1,35 @@
|
|
|
1
1
|
import { OnOffAccessory } from './onoff.js';
|
|
2
2
|
import { strings } from '../i18n/i18n.js';
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { AccessoryType } from '../model/types.js';
|
|
4
|
+
import { STORAGE_KEY_SUFFIX_DEFAULT_BRIGHTNESS, storageGet, storageSet } from '../tools/storage.js';
|
|
5
|
+
const NO_BRIGHTNESS = -1;
|
|
5
6
|
export class LightbulbAccessory extends OnOffAccessory {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
this.isDimmer = lightbulbConfig.defaultBrightness !== undefined;
|
|
7
|
+
brightness;
|
|
8
|
+
constructor(Service, Characteristic, accessory, config, log, persistPath, isGrouped) {
|
|
9
|
+
super(Service, Characteristic, accessory, config, log, persistPath, isGrouped);
|
|
10
|
+
this.brightness = this.config.defaultBrightness ?? NO_BRIGHTNESS;
|
|
11
11
|
if (this.isDimmer) {
|
|
12
|
-
this.brightness = lightbulbConfig.defaultBrightness;
|
|
13
12
|
this.accessoryService.getCharacteristic(this.Characteristic.Brightness)
|
|
14
13
|
.onGet(this.getBrightness.bind(this))
|
|
15
14
|
.onSet(this.setBrightness.bind(this));
|
|
16
15
|
this.initializeBrightness();
|
|
17
16
|
}
|
|
18
17
|
}
|
|
19
|
-
get
|
|
20
|
-
return
|
|
18
|
+
get isDimmer() {
|
|
19
|
+
return this.brightness !== NO_BRIGHTNESS;
|
|
20
|
+
}
|
|
21
|
+
get defaultBrightnessStorageKey() {
|
|
22
|
+
return `${this.identifier}:${STORAGE_KEY_SUFFIX_DEFAULT_BRIGHTNESS}`;
|
|
23
|
+
}
|
|
24
|
+
getAccessoryType() {
|
|
25
|
+
return AccessoryType.Lightbulb;
|
|
21
26
|
}
|
|
22
27
|
async initializeBrightness() {
|
|
23
|
-
|
|
28
|
+
if (this.isStateful) {
|
|
29
|
+
this.brightness = await storageGet(this.persistPath, this.defaultBrightnessStorageKey) ?? this.brightness;
|
|
30
|
+
}
|
|
24
31
|
this.accessoryService.updateCharacteristic(this.Characteristic.Brightness, this.brightness);
|
|
25
32
|
}
|
|
26
|
-
getAccessoryService() {
|
|
27
|
-
return this.accessory.getService(this.Service.Lightbulb) || this.accessory.addService(this.Service.Lightbulb);
|
|
28
|
-
}
|
|
29
33
|
logOnState(value) {
|
|
30
34
|
if (this.isDimmer && value) {
|
|
31
35
|
this.logIfDesired(strings.accessory.lightbulb.stateOn, this.config.name, this.brightness.toLocaleString());
|
|
@@ -43,7 +47,9 @@ export class LightbulbAccessory extends OnOffAccessory {
|
|
|
43
47
|
}
|
|
44
48
|
this.brightness = value;
|
|
45
49
|
this.logIfDesired(strings.accessory.lightbulb.brightness, this.config.name, this.brightness.toString());
|
|
46
|
-
|
|
50
|
+
if (this.isStateful) {
|
|
51
|
+
await storageSet(this.persistPath, this.defaultBrightnessStorageKey, this.brightness);
|
|
52
|
+
}
|
|
47
53
|
this.accessoryService.updateCharacteristic(this.Characteristic.Brightness, this.brightness);
|
|
48
54
|
}
|
|
49
55
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lightbulb.js","sourceRoot":"","sources":["../../src/accessory/lightbulb.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"lightbulb.js","sourceRoot":"","sources":["../../src/accessory/lightbulb.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CharacteristicValue, PlatformAccessory } from 'homebridge';
|
|
2
|
+
import { DummyAccessory } from './base.js';
|
|
3
|
+
import { AccessoryType, CharacteristicType, LockConfig, ServiceType } from '../model/types.js';
|
|
4
|
+
import { Log } from '../tools/log.js';
|
|
5
|
+
export declare class LockAccessory extends DummyAccessory<LockConfig> {
|
|
6
|
+
private state;
|
|
7
|
+
constructor(Service: ServiceType, Characteristic: CharacteristicType, accessory: PlatformAccessory, config: LockConfig, log: Log, persistPath: string, isGrouped: boolean);
|
|
8
|
+
private initializeState;
|
|
9
|
+
protected getAccessoryType(): AccessoryType;
|
|
10
|
+
private get defaultState();
|
|
11
|
+
protected getState(): Promise<CharacteristicValue>;
|
|
12
|
+
protected setState(value: CharacteristicValue): Promise<void>;
|
|
13
|
+
private flip;
|
|
14
|
+
protected logLockStateState(value: CharacteristicValue): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { DummyAccessory } from './base.js';
|
|
2
|
+
import { strings } from '../i18n/i18n.js';
|
|
3
|
+
import { AccessoryType } from '../model/types.js';
|
|
4
|
+
import { storageGet, storageSet } from '../tools/storage.js';
|
|
5
|
+
export class LockAccessory extends DummyAccessory {
|
|
6
|
+
state;
|
|
7
|
+
constructor(Service, Characteristic, accessory, config, log, persistPath, isGrouped) {
|
|
8
|
+
super(Service, Characteristic, accessory, config, log, persistPath, isGrouped);
|
|
9
|
+
this.state = this.defaultState;
|
|
10
|
+
this.accessoryService.getCharacteristic(Characteristic.LockTargetState)
|
|
11
|
+
.onGet(this.getState.bind(this))
|
|
12
|
+
.onSet(this.setState.bind(this));
|
|
13
|
+
this.accessoryService.getCharacteristic(Characteristic.LockCurrentState)
|
|
14
|
+
.onGet(this.getState.bind(this));
|
|
15
|
+
this.initializeState();
|
|
16
|
+
}
|
|
17
|
+
async initializeState() {
|
|
18
|
+
if (this.isStateful) {
|
|
19
|
+
this.state = await storageGet(this.persistPath, this.defaultStateStorageKey) ?? this.state;
|
|
20
|
+
}
|
|
21
|
+
this.accessoryService.updateCharacteristic(this.Characteristic.LockTargetState, this.state);
|
|
22
|
+
this.accessoryService.updateCharacteristic(this.Characteristic.LockCurrentState, this.state);
|
|
23
|
+
}
|
|
24
|
+
getAccessoryType() {
|
|
25
|
+
return AccessoryType.LockMechanism;
|
|
26
|
+
}
|
|
27
|
+
get defaultState() {
|
|
28
|
+
return this.config.defaultLockState === undefined ? this.Characteristic.LockTargetState.SECURED : this.config.defaultLockState;
|
|
29
|
+
}
|
|
30
|
+
async getState() {
|
|
31
|
+
return this.state;
|
|
32
|
+
}
|
|
33
|
+
async setState(value) {
|
|
34
|
+
if (this.state !== value) {
|
|
35
|
+
this.logLockStateState(value);
|
|
36
|
+
}
|
|
37
|
+
this.state = value;
|
|
38
|
+
if (this.isStateful) {
|
|
39
|
+
await storageSet(this.persistPath, this.defaultStateStorageKey, this.state);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
if (this.state !== this.defaultState) {
|
|
43
|
+
this.startTimer(this.flip.bind(this));
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
this.cancelTimer();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
this.accessoryService.updateCharacteristic(this.Characteristic.LockTargetState, this.state);
|
|
50
|
+
this.accessoryService.updateCharacteristic(this.Characteristic.LockCurrentState, this.state);
|
|
51
|
+
}
|
|
52
|
+
async flip() {
|
|
53
|
+
const opposite = this.state === this.Characteristic.LockTargetState.SECURED ?
|
|
54
|
+
this.Characteristic.LockTargetState.UNSECURED : this.Characteristic.LockTargetState.SECURED;
|
|
55
|
+
await this.setState(opposite);
|
|
56
|
+
}
|
|
57
|
+
logLockStateState(value) {
|
|
58
|
+
const message = value === this.Characteristic.LockTargetState.SECURED ?
|
|
59
|
+
strings.accessory.lock.secured : strings.accessory.lock.unsecured;
|
|
60
|
+
this.logIfDesired(message, this.config.name);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=lock.js.map
|