homebridge-easy-mqtt 1.0.0-beta.0 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +14 -2
  2. package/README.md +54 -25
  3. package/config.schema.json +180 -53
  4. package/dist/accessory/base.d.ts +7 -5
  5. package/dist/accessory/base.js +19 -11
  6. package/dist/accessory/base.js.map +1 -1
  7. package/dist/accessory/lightbulb.d.ts +30 -0
  8. package/dist/accessory/lightbulb.js +106 -0
  9. package/dist/accessory/lightbulb.js.map +1 -0
  10. package/dist/accessory/lock.d.ts +13 -16
  11. package/dist/accessory/lock.js +56 -85
  12. package/dist/accessory/lock.js.map +1 -1
  13. package/dist/accessory/onoff.d.ts +15 -0
  14. package/dist/accessory/onoff.js +57 -0
  15. package/dist/accessory/onoff.js.map +1 -0
  16. package/dist/accessory/outlet.d.ts +16 -0
  17. package/dist/accessory/outlet.js +59 -0
  18. package/dist/accessory/outlet.js.map +1 -0
  19. package/dist/accessory/statusActive.d.ts +14 -0
  20. package/dist/accessory/statusActive.js +41 -0
  21. package/dist/accessory/statusActive.js.map +1 -0
  22. package/dist/accessory/switch.d.ts +6 -17
  23. package/dist/accessory/switch.js +6 -86
  24. package/dist/accessory/switch.js.map +1 -1
  25. package/dist/homebridge/platform.js +12 -4
  26. package/dist/homebridge/platform.js.map +1 -1
  27. package/dist/homebridge-ui/public/index.html +1 -1
  28. package/dist/homebridge-ui/public/ui.js +1 -1
  29. package/dist/i18n/en.d.ts +45 -15
  30. package/dist/i18n/en.js +46 -16
  31. package/dist/i18n/en.js.map +1 -1
  32. package/dist/i18n/i18n.d.ts +45 -15
  33. package/dist/i18n/template.d.ts +45 -15
  34. package/dist/i18n/zz.d.ts +45 -15
  35. package/dist/model/mqtt.d.ts +0 -2
  36. package/dist/model/mqtt.js +3 -13
  37. package/dist/model/mqtt.js.map +1 -1
  38. package/dist/model/types.d.ts +34 -13
  39. package/dist/model/types.js.map +1 -1
  40. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to homebridge-dummy will be documented in this file.
4
4
 
5
- ## 1.0.0 (####-##-##)
5
+ ## 1.0.0-beta.1 (2025-06-26)
6
6
 
7
- - Initial public release
7
+ ### ⚠️ BREAKING
8
+ - Several topics were renamed for consistency so some accessories may have to be reconfigured
9
+
10
+ ### Added
11
+ - Username/password can now be set in the UI or supplied via config
12
+ - Outlet accessory type
13
+
14
+ ### Fixed
15
+ - Unnecessary idle timer in mqtt library
16
+
17
+ ## 1.0.0-beta.0 (2025-06-25)
18
+
19
+ - Initial beta release
package/README.md CHANGED
@@ -23,7 +23,7 @@ Any issues or damage resulting from use of this plugin are not the fault of the
23
23
 
24
24
  This plugin is designed to be a simple replacement for the fantastic [homebridge-mqttthing](https://github.com/arachnetech/homebridge-mqttthing) plugin which appears as though it's [no longer](https://github.com/arachnetech/homebridge-mqttthing/commits/master/) being actively developed.
25
25
 
26
- **HomebridgeEasyMQTT** currently supports just two types of accessories, `LockMechanism` and `Switch`, but will be expanded over time as more use cases are discovered. If there is an accessory type you'd like to see supported, please feel free to [create an issue in GitHub](https://github.com/mpatfield/homebridge-easy-mqtt/issues).
26
+ **HomebridgeEasyMQTT** currently supports `Lightbulb`, `LockMechanism`, `Outlet`, and `Switch`, but will be expanded over time as more use cases are discovered. If there is an accessory type you'd like to see supported, please feel free to [create an issue in GitHub](https://github.com/mpatfield/homebridge-easy-mqtt/issues/new/choose).
27
27
 
28
28
  ## Configuration
29
29
 
@@ -44,18 +44,20 @@ Using the Homebridge Config UI is the easiest way to set up this plugin. However
44
44
  },
45
45
  "mqtt": {
46
46
  "broker": "string",
47
+ "username": "string",
48
+ "password": "string",
47
49
  "options": "string"
48
50
  },
49
- "topicGetActive": "string",
50
- "topicGetCurrent": "string",
51
- "topicGetTarget": "string",
52
- "topicSetTarget": "string",
51
+ "topicGetStatusActive": "string",
52
+ "topicGetLockCurrentState": "string",
53
+ "topicGetLockTargetState": "string",
54
+ "topicSetTargetState": "string",
53
55
  "topicGetOn": "string",
54
56
  "topicSetOn": "string",
55
- "valueActive": "string",
56
- "valueSecured": "string",
57
- "valueUnsecured": "string",
58
- "valueJammed": "string",
57
+ "valueStatusActive": "string",
58
+ "valueLockStateSecured": "string",
59
+ "valueLockStateUnsecured": "string",
60
+ "valueLockStateJammed": "string",
59
61
  "valueOn": "string",
60
62
  "valueOff": "string",
61
63
  "disableLogging": false
@@ -71,7 +73,7 @@ All fields are required unless noted as "(Optional)"
71
73
 
72
74
  Info:
73
75
  - `name` - The display name for the accessory in HomeKit
74
- - `type` - The type of accessory, currently only LockMechanism and Switch are supported
76
+ - `type` - The type of accessory, currently Lightbulb, LockMechanism, Outlet, and Switch are supported
75
77
  - `manufacturer` - (Optional) The accessory manufacturer which will display in HomeKit device details
76
78
  - `model` - (Optional) The accessory model which will display in HomeKit device details
77
79
  - `serialNumber` - (Optional) The accessory serial number which will display in HomeKit device details
@@ -79,37 +81,65 @@ Info:
79
81
 
80
82
  MQTT:
81
83
  - `broker` - The URL and port to use for communicating with your MQTT device
82
- - `options` - (Optional) See [MQTT Options](https://github.com/mpatfield/homebridge-easy-mqtt#mqtt-options) below
84
+ - `username` - (Optional) Username
85
+ - `password` - (Optional) Password
86
+ - `options` - (Optional) See [MQTT Options](#mqtt-options) below
83
87
 
84
88
  Topics:
85
89
 
86
90
  You will need to make sure to populate the appropriate topics based on the type.
87
91
 
88
- You may define topics using a JSONPath dot notation to assist the parser in finding the right value within the message. See [JSONPaths](https://github.com/mpatfield/homebridge-easy-mqtt#jsonpaths) below for more details.
92
+ You may define topics using a JSONPath dot notation to assist the parser in finding the right value within the message. See [JSONPaths](#jsonpaths) below for more details.
89
93
 
90
94
  - General Purpose
91
- - `topicGetActive` - (Optional) Whether or not the accessory is connected/reachable
95
+ - `topicGetStatusActive` - (Optional) Whether or not the accessory is connected/reachable
96
+
97
+ - Lightbulb
98
+ - `topicGetBrightness` - The current brightness as a percent
99
+ - `topicSetBrightness` - For setting the brightness
100
+ - `topicGetHue` - The lightbulb's current hue
101
+ - `topicSetHue` - For setting the lightbulb's current hue
102
+ - `topicGetColorTemperature` - The current color temperature of the lightbulb
103
+ - `topicSetColorTemperature` - For setting the color temperature of the lightbulb
104
+ - `topicGetSaturation` - The current saturation setting of the lightbulb
105
+ - `topicSetSaturation` - For setting the saturation setting of the lightbulb
92
106
 
93
107
  - LockMechanism
94
- - `topicGetCurrent` - The current state of the lock, i.e. locked/unlocked
95
- - `topicGetTarget` - The target (i.e. desired) state of the lock
96
- - `topicSetTarget` - For setting the target (i.e. desired) state of the lock
108
+ - `topicGetLockCurrentState` - The current state of the lock, i.e. locked/unlocked
109
+ - `topicGetLockTargetState` - The target (i.e. desired) state of the lock
110
+ - `topicSetTargetState` - For setting the target (i.e. desired) state of the lock
111
+
112
+ - Outlet
113
+ - `topicGetOn` - The current state of the outlet, i.e. on/off
114
+ - `topicSetOn` - For setting the state of the outlet
115
+ - `topicGetOutletInUse` - Whether or not the outlet is currently being used
116
+ - `topicSetOutletInUse` - For setting whether the outlet is currently being used
97
117
 
98
118
  - Switch
99
119
  - `topicGetOn` - The current state of the switch, i.e. on/off
100
- - `topicSetOn` - For setting the desired state of the switch
120
+ - `topicSetOn` - For setting the state of the switch
101
121
 
102
122
  Values:
103
123
 
104
124
  As with Topics, you will need to populate the appropriate values based on the type. Note that while they are defined as strings, they will be auto-converted to the appropriate primitives (e.g. boolean or number) where appropriate.
105
125
 
106
126
  - General Purpose
107
- - `valueActive` - Accessory is connected/reachable, e.g. "true", "1", or "Alive"
127
+ - `valueStatusActive` - Accessory is connected/reachable, e.g. "true", "1", or "Alive"
128
+
129
+ - Lightbulb
130
+ - `valueOn` - Turned on, e.g. "true", or "1", or "On"
131
+ - `valueOff` - Turned off, e.g. "false", or "0", or "Off"
108
132
 
109
133
  - LockMechanism
110
- - `valueSecured` - Locked state, e.g. "true", "255", or "Locked"
111
- - `valueUnsecured` - Unlocked state, e.g. "false", "0", or "Unlocked"
112
- - `valueJammed` - (Optional) Lock is jammed, e.g. "254" or "Jammed"
134
+ - `valueLockStateSecured` - Locked state, e.g. "true", "255", or "Locked"
135
+ - `valueLockStateUnsecured` - Unlocked state, e.g. "false", "0", or "Unlocked"
136
+ - `valueLockStateJammed` - (Optional) Lock is jammed, e.g. "254" or "Jammed"
137
+
138
+ - Outlet
139
+ - `valueOn` - Turned on, e.g. "true", or "1", or "On"
140
+ - `valueOff` - Turned off, e.g. "false", or "0", or "Off"
141
+ - `valueOutletInUse` - Currently being used, e.g. "true", or "1", or "On"
142
+ - `valueOutletNotInUse` - Currently not being used, e.g. "false", or "0", or "Off"
113
143
 
114
144
  - Switch
115
145
  - `valueOn` - Turned on, e.g. "true", or "1", or "On"
@@ -129,10 +159,10 @@ You may also turn on additional logging if you'd like to see the MQTT messages p
129
159
 
130
160
  ## MQTT Options
131
161
 
132
- You are able to pass in any arbitrary MQTT options via `mqtt.options` in the config. This can include, among other things, username/password, keepalive, rejectUnauthorized, etc. Just make sure the value provided is valid JSON. For example:
162
+ You are able to pass in any arbitrary MQTT options via `mqtt.options` in the config. This can include, for example, such as clientId, protocolVersion, etc. Just make sure the value provided is valid JSON. For example:
133
163
 
134
164
  ```
135
- "options": "{ \"username\": \"fake@email.com\", \"password\": \"password123\", \"rejectUnauthorized\": true }"
165
+ "options": "{ \"protocolVersion\": \"4\", \"clientId\": \"my-client-id\", \"rejectUnauthorized\": true }"
136
166
  ```
137
167
 
138
168
  ## JSONPaths
@@ -172,5 +202,4 @@ would use the topic
172
202
 
173
203
  [@arachnetech](https://github.com/arachnetech) for the fantastic [homebridge-mqttthing](https://github.com/arachnetech/homebridge-mqttthing) plugin which serves as the main inspiration for this project
174
204
 
175
- And to the amazing creators/contributors of [Homebridge](https://homebridge.io) who made this plugin possible!
176
- And to the amazing creators/contributors of [Homebridge](https://homebridge.io) who made this plugin possible!
205
+ And to the amazing creators/contributors of [Homebridge](https://homebridge.io) who made this plugin possible!
@@ -4,7 +4,6 @@
4
4
  "singular": true,
5
5
  "customUi": true,
6
6
  "customUiPath": "./dist/homebridge-ui",
7
- "strictValidation": true,
8
7
  "schema": {
9
8
  "type": "object",
10
9
  "definitions": {
@@ -13,14 +12,16 @@
13
12
  "properties": {
14
13
  "name": {
15
14
  "type": "string",
16
- "title": "${config.title.name}",
15
+ "title": "${config.title.name}" ,
17
16
  "required": true
18
- },
17
+ },
19
18
  "type": {
20
19
  "type": "string",
21
20
  "title": "${config.title.type}",
22
21
  "enum": [
22
+ "Lightbulb",
23
23
  "LockMechanism",
24
+ "Outlet",
24
25
  "Switch"
25
26
  ],
26
27
  "required": true
@@ -52,11 +53,19 @@
52
53
  "placeholder": "mqtts://192.168.0.1:1883",
53
54
  "required": true
54
55
  },
56
+ "username": {
57
+ "type": "string",
58
+ "title": "${config.title.username}"
59
+ },
60
+ "password": {
61
+ "type": "string",
62
+ "title": "${config.title.password}"
63
+ },
55
64
  "options": {
56
65
  "type": "string",
57
66
  "title": "${config.title.options}",
58
67
  "description": "${config.description.options}",
59
- "placeholder": "{ \"username\": \"fake@email.com\", \"password\": \"password123\" , \"rejectUnauthorized\": true }"
68
+ "placeholder": "{ \"protocolVersion\": \"4\", \"clientId\": \"my-client-id\", \"rejectUnauthorized\": true }"
60
69
  }
61
70
  }
62
71
  }
@@ -73,52 +82,86 @@
73
82
  "properties": {
74
83
  "info": { "$ref": "#/definitions/info" },
75
84
  "mqtt": { "$ref": "#/definitions/mqtt" },
76
- "topicGetActive": {
85
+ "topicGetStatusActive": {
86
+ "type": "string",
87
+ "title": "${config.title.topicGetStatusActive}"
88
+ },
89
+ "topicGetBrightness": {
90
+ "type": "string",
91
+ "title": "${config.title.topicGetBrightness}"
92
+ },
93
+ "topicSetBrightness": {
94
+ "type": "string",
95
+ "title": "${config.title.topicSetBrightness}"
96
+ },
97
+ "topicGetHue": {
77
98
  "type": "string",
78
- "title": "${config.title.topicGetActive}",
79
- "placeholder": "zwave/door_lock/front_door/status"
99
+ "title": "${config.title.topicGetHue}"
80
100
  },
81
- "topicGetCurrent": {
101
+ "topicSetHue": {
82
102
  "type": "string",
83
- "title": "${config.title.topicGetCurrent}",
84
- "placeholder": "zwave/door_lock/front_door/currentMode"
103
+ "title": "${config.title.topicSetHue}"
85
104
  },
86
- "topicGetTarget": {
105
+ "topicGetColorTemperature": {
87
106
  "type": "string",
88
- "title": "${config.title.topicGetTarget}",
89
- "placeholder": "zwave/door_lock/front_door/targetMode"
107
+ "title": "${config.title.topicGetColorTemperature}"
90
108
  },
91
- "topicSetTarget": {
109
+ "topicSetColorTemperature": {
92
110
  "type": "string",
93
- "title": "${config.title.topicSetTarget}",
94
- "placeholder": "zwave/door_lock/front_door/targetMode/set"
111
+ "title": "${config.title.topicSetColorTemperature}"
112
+ },
113
+ "topicGetSaturation": {
114
+ "type": "string",
115
+ "title": "${config.title.topicGetSaturation}"
116
+ },
117
+ "topicSetSaturation": {
118
+ "type": "string",
119
+ "title": "${config.title.topicSetSaturation}"
120
+ },
121
+ "topicGetLockCurrentState": {
122
+ "type": "string",
123
+ "title": "${config.title.topicGetLockCurrentState}"
124
+ },
125
+ "topicGetLockTargetState": {
126
+ "type": "string",
127
+ "title": "${config.title.topicGetLockTargetState}"
128
+ },
129
+ "topicSetTargetState": {
130
+ "type": "string",
131
+ "title": "${config.title.topicSetTargetState}"
95
132
  },
96
133
  "topicGetOn": {
97
134
  "type": "string",
98
- "title": "${config.title.topicGetOn}",
99
- "placeholder": "home/living_room/lamp/state"
135
+ "title": "${config.title.topicGetOn}"
100
136
  },
101
137
  "topicSetOn": {
102
138
  "type": "string",
103
- "title": "${config.title.topicSetOn}",
104
- "placeholder": "home/living_room/lamp/state/set"
139
+ "title": "${config.title.topicSetOn}"
140
+ },
141
+ "topicGetOutletInUse": {
142
+ "type": "string",
143
+ "title": "${config.title.topicGetOutletInUse}"
105
144
  },
106
- "valueActive": {
145
+ "topicSetOutletInUse": {
107
146
  "type": "string",
108
- "title": "${config.title.valueActive}",
109
- "description": "${config.description.valueActive}"
147
+ "title": "${config.title.topicSetOutletInUse}"
110
148
  },
111
- "valueSecured": {
149
+ "valueStatusActive": {
112
150
  "type": "string",
113
- "title": "${config.title.valueSecured}"
151
+ "title": "${config.title.valueStatusActive}",
152
+ "description": "${config.description.valueStatusActive}"
114
153
  },
115
- "valueUnsecured": {
154
+ "valueLockStateSecured": {
116
155
  "type": "string",
117
- "title": "${config.title.valueUnsecured}"
156
+ "title": "${config.title.valueLockStateSecured}"
118
157
  },
119
- "valueJammed": {
158
+ "valueLockStateUnsecured": {
120
159
  "type": "string",
121
- "title": "${config.title.valueJammed}"
160
+ "title": "${config.title.valueLockStateUnsecured}"
161
+ },
162
+ "valueLockStateJammed": {
163
+ "type": "string",
164
+ "title": "${config.title.valueLockStateJammed}"
122
165
  },
123
166
  "valueOn": {
124
167
  "type": "string",
@@ -128,6 +171,14 @@
128
171
  "type": "string",
129
172
  "title": "${config.title.valueOff}"
130
173
  },
174
+ "valueOutletInUse": {
175
+ "type": "string",
176
+ "title": "${config.title.valueOutletInUse}"
177
+ },
178
+ "valueOutletNotInUse": {
179
+ "type": "string",
180
+ "title": "${config.title.valueOutletNotInUse}"
181
+ },
131
182
  "disableLogging": {
132
183
  "type": "boolean",
133
184
  "title": "${config.title.disableLogging}",
@@ -212,6 +263,21 @@
212
263
  "title": "${config.title.mqtt}",
213
264
  "items": [
214
265
  "accessories[].mqtt.broker",
266
+ {
267
+ "type": "div",
268
+ "displayFlex": true,
269
+ "flex-direction": "row",
270
+ "items": [
271
+ {
272
+ "key": "accessories[].mqtt.username",
273
+ "flex": "1 1 0"
274
+ },
275
+ {
276
+ "key": "accessories[].mqtt.password",
277
+ "flex": "1 1 0"
278
+ }
279
+ ]
280
+ },
215
281
  "accessories[].mqtt.options"
216
282
  ]
217
283
  },
@@ -221,36 +287,96 @@
221
287
  "title": "${config.title.topics}",
222
288
  "items": [
223
289
  {
224
- "key": "accessories[].topicGetCurrent",
290
+ "key": "accessories[].topicGetLockCurrentState",
225
291
  "condition": {
226
- "functionBody": "const index = arguments[1]; return model.accessories[index]?.info.type === 'LockMechanism';"
292
+ "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'LockMechanism';"
227
293
  }
228
294
  },
229
295
  {
230
- "key": "accessories[].topicGetTarget",
296
+ "key": "accessories[].topicGetLockTargetState",
231
297
  "condition": {
232
- "functionBody": "const index = arguments[1]; return model.accessories[index]?.info.type === 'LockMechanism';"
298
+ "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'LockMechanism';"
233
299
  }
234
300
  },
235
301
  {
236
- "key": "accessories[].topicSetTarget",
302
+ "key": "accessories[].topicSetTargetState",
237
303
  "condition": {
238
- "functionBody": "const index = arguments[1]; return model.accessories[index]?.info.type === 'LockMechanism';"
304
+ "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'LockMechanism';"
239
305
  }
240
306
  },
241
307
  {
242
308
  "key": "accessories[].topicGetOn",
243
309
  "condition": {
244
- "functionBody": "const index = arguments[1]; return model.accessories[index]?.info.type === 'Switch';"
310
+ "functionBody": "return ['Lightbulb', 'Outlet', 'Switch'].includes(model.accessories?.[arguments[1]]?.info?.type);"
245
311
  }
246
312
  },
247
313
  {
248
314
  "key": "accessories[].topicSetOn",
249
315
  "condition": {
250
- "functionBody": "const index = arguments[1]; return model.accessories[index]?.info.type === 'Switch';"
316
+ "functionBody": "return ['Lightbulb', 'Outlet', 'Switch'].includes(model.accessories?.[arguments[1]]?.info?.type);"
317
+ }
318
+ },
319
+ {
320
+ "key": "accessories[].topicGetBrightness",
321
+ "condition": {
322
+ "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'Lightbulb';"
323
+ }
324
+ },
325
+ {
326
+ "key": "accessories[].topicSetBrightness",
327
+ "condition": {
328
+ "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'Lightbulb';"
329
+ }
330
+ },
331
+ {
332
+ "key": "accessories[].topicGetHue",
333
+ "condition": {
334
+ "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'Lightbulb';"
335
+ }
336
+ },
337
+ {
338
+ "key": "accessories[].topicSetHue",
339
+ "condition": {
340
+ "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'Lightbulb';"
341
+ }
342
+ },
343
+ {
344
+ "key": "accessories[].topicGetColorTemperature",
345
+ "condition": {
346
+ "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'Lightbulb';"
347
+ }
348
+ },
349
+ {
350
+ "key": "accessories[].topicSetColorTemperature",
351
+ "condition": {
352
+ "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'Lightbulb';"
353
+ }
354
+ },
355
+ {
356
+ "key": "accessories[].topicGetSaturation",
357
+ "condition": {
358
+ "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'Lightbulb';"
359
+ }
360
+ },
361
+ {
362
+ "key": "accessories[].topicSetSaturation",
363
+ "condition": {
364
+ "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'Lightbulb';"
365
+ }
366
+ },
367
+ {
368
+ "key": "accessories[].topicGetOutletInUse",
369
+ "condition": {
370
+ "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'Outlet';"
371
+ }
372
+ },
373
+ {
374
+ "key": "accessories[].topicSetOutletInUse",
375
+ "condition": {
376
+ "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'Outlet';"
251
377
  }
252
378
  },
253
- "accessories[].topicGetActive"
379
+ "accessories[].topicGetStatusActive"
254
380
  ]
255
381
  },
256
382
  {
@@ -262,17 +388,21 @@
262
388
  "displayFlex": true,
263
389
  "flex-direction": "row",
264
390
  "condition": {
265
- "functionBody": "const index = arguments[1]; return model.accessories[index]?.info.type === 'LockMechanism';"
391
+ "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'LockMechanism';"
266
392
  },
267
393
  "items": [
268
394
  {
269
- "key": "accessories[].valueSecured",
395
+ "key": "accessories[].valueLockStateSecured",
270
396
  "flex": "1 1 0"
271
397
  },
272
398
  {
273
- "key": "accessories[].valueUnsecured",
399
+ "key": "accessories[].valueLockStateUnsecured",
274
400
  "flex": "1 1 0"
275
- }
401
+ },
402
+ {
403
+ "key": "accessories[].valueLockStateJammed",
404
+ "flex": "1 1 0"
405
+ }
276
406
  ]
277
407
  },
278
408
  {
@@ -280,15 +410,15 @@
280
410
  "displayFlex": true,
281
411
  "flex-direction": "row",
282
412
  "condition": {
283
- "functionBody": "const index = arguments[1]; return model.accessories[index]?.info.type === 'LockMechanism';"
413
+ "functionBody": "return ['Lightbulb', 'Outlet', 'Switch'].includes(model.accessories?.[arguments[1]]?.info?.type);"
284
414
  },
285
415
  "items": [
286
416
  {
287
- "key": "accessories[].valueJammed",
417
+ "key": "accessories[].valueOn",
288
418
  "flex": "1 1 0"
289
419
  },
290
420
  {
291
- "key": "accessories[].valueActive",
421
+ "key": "accessories[].valueOff",
292
422
  "flex": "1 1 0"
293
423
  }
294
424
  ]
@@ -298,23 +428,20 @@
298
428
  "displayFlex": true,
299
429
  "flex-direction": "row",
300
430
  "condition": {
301
- "functionBody": "const index = arguments[1]; return model.accessories[index]?.info.type === 'Switch';"
431
+ "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'Outlet';"
302
432
  },
303
433
  "items": [
304
434
  {
305
- "key": "accessories[].valueOn",
306
- "flex": "1 1 0"
307
- },
308
- {
309
- "key": "accessories[].valueOff",
435
+ "key": "accessories[].valueOutletInUse",
310
436
  "flex": "1 1 0"
311
437
  },
312
438
  {
313
- "key": "accessories[].valueActive",
439
+ "key": "accessories[].valueOutletNotInUse",
314
440
  "flex": "1 1 0"
315
441
  }
316
442
  ]
317
- }
443
+ },
444
+ "accessories[].valueStatusActive"
318
445
  ]
319
446
  }
320
447
  ]
@@ -1,5 +1,5 @@
1
1
  import { PlatformAccessory } from 'homebridge';
2
- import { AccessoryConfig, Primitive } from '../model/types.js';
2
+ import { AccessoryConfig, CharacteristicType, Primitive, ServiceType } from '../model/types.js';
3
3
  import { Log } from '../tools/log.js';
4
4
  export type TopicHandler = {
5
5
  topic: string;
@@ -7,15 +7,17 @@ export type TopicHandler = {
7
7
  };
8
8
  export declare function makeHandler(topic: string, handler: (topic: string, value: Primitive) => Promise<void>): TopicHandler;
9
9
  export declare abstract class MQTTAccessory {
10
- protected readonly Service: typeof import('homebridge').Service;
11
- protected readonly Characteristic: typeof import('homebridge').Characteristic;
12
- private readonly _config;
10
+ protected readonly Service: ServiceType;
11
+ protected readonly Characteristic: CharacteristicType;
12
+ protected readonly accessory: PlatformAccessory;
13
+ protected readonly config: AccessoryConfig;
13
14
  protected readonly log: Log;
14
15
  private readonly mqttClient;
15
- constructor(Service: typeof import('homebridge').Service, Characteristic: typeof import('homebridge').Characteristic, accessory: PlatformAccessory, _config: AccessoryConfig, log: Log, caller: string);
16
+ constructor(Service: ServiceType, Characteristic: CharacteristicType, accessory: PlatformAccessory, config: AccessoryConfig, log: Log, caller: string);
16
17
  private onMQTTConnect;
17
18
  protected abstract get topicHandlers(): TopicHandler[];
18
19
  protected publish(topic: string, value: Primitive): void;
19
20
  teardown(): void;
20
21
  protected assert(...keys: (keyof any)[]): boolean;
22
+ protected logIfDesired(message: string, ...parameters: string[]): void;
21
23
  }
@@ -8,25 +8,27 @@ export function makeHandler(topic, handler) {
8
8
  export class MQTTAccessory {
9
9
  Service;
10
10
  Characteristic;
11
- _config;
11
+ accessory;
12
+ config;
12
13
  log;
13
14
  mqttClient;
14
- constructor(Service, Characteristic, accessory, _config, log, caller) {
15
+ constructor(Service, Characteristic, accessory, config, log, caller) {
15
16
  this.Service = Service;
16
17
  this.Characteristic = Characteristic;
17
- this._config = _config;
18
+ this.accessory = accessory;
19
+ this.config = config;
18
20
  this.log = log;
19
21
  if (this.assert('mqtt')) {
20
- this.mqttClient = new MQTT(log, _config.mqtt, this.onMQTTConnect.bind(this), _config.info.name);
22
+ this.mqttClient = new MQTT(log, config.mqtt, this.onMQTTConnect.bind(this), config.info.name);
21
23
  this.mqttClient.connect();
22
24
  }
23
25
  accessory.getService(Service.AccessoryInformation)
24
- .setCharacteristic(Characteristic.Name, _config.info.name)
25
- .setCharacteristic(Characteristic.ConfiguredName, _config.info.name)
26
- .setCharacteristic(Characteristic.Manufacturer, _config.info.manufacturer ?? 'Homebridge')
27
- .setCharacteristic(Characteristic.SerialNumber, _config.info.serialNumber ?? `${PLATFORM_NAME}:${_config.info.name}`)
28
- .setCharacteristic(Characteristic.Model, _config.info.model ?? caller)
29
- .setCharacteristic(Characteristic.FirmwareRevision, _config.info.version ?? getVersion());
26
+ .setCharacteristic(Characteristic.Name, config.info.name)
27
+ .setCharacteristic(Characteristic.ConfiguredName, config.info.name)
28
+ .setCharacteristic(Characteristic.Manufacturer, config.info.manufacturer ?? 'Homebridge')
29
+ .setCharacteristic(Characteristic.SerialNumber, config.info.serialNumber ?? `${PLATFORM_NAME}:${config.info.name}`)
30
+ .setCharacteristic(Characteristic.Model, config.info.model ?? caller)
31
+ .setCharacteristic(Characteristic.FirmwareRevision, config.info.version ?? getVersion());
30
32
  }
31
33
  async onMQTTConnect() {
32
34
  this.topicHandlers.forEach(topicHandler => {
@@ -41,7 +43,13 @@ export class MQTTAccessory {
41
43
  }
42
44
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
45
  assert(...keys) {
44
- return assert(this.log, this._config.info.name, this._config, ...keys);
46
+ return assert(this.log, this.config.info.name, this.config, ...keys);
47
+ }
48
+ logIfDesired(message, ...parameters) {
49
+ if (this.config.disableLogging) {
50
+ return;
51
+ }
52
+ this.log.always(message, ...parameters);
45
53
  }
46
54
  }
47
55
  //# sourceMappingURL=base.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/accessory/base.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAIxC,OAAO,UAAU,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAIhD,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,OAA2D;IACpG,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,OAAgB,aAAa;IAKZ;IACA;IAEF;IACE;IAPJ,UAAU,CAAmB;IAE9C,YACqB,OAA4C,EAC5C,cAA0D,EAC7E,SAA4B,EACX,OAAwB,EACtB,GAAQ,EAC3B,MAAc;QALK,YAAO,GAAP,OAAO,CAAqC;QAC5C,mBAAc,GAAd,cAAc,CAA4C;QAE5D,YAAO,GAAP,OAAO,CAAiB;QACtB,QAAG,GAAH,GAAG,CAAK;QAI3B,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,UAAU,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QAC5B,CAAC;QAED,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,oBAAoB,CAAE;aAChD,iBAAiB,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;aACzD,iBAAiB,CAAC,cAAc,CAAC,cAAc,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;aACnE,iBAAiB,CAAC,cAAc,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC;aACzF,iBAAiB,CAAC,cAAc,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,IAAI,GAAG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;aACpH,iBAAiB,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC;aACrE,iBAAiB,CAAC,cAAc,CAAC,gBAAgB,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,UAAU,EAAE,CAAC,CAAC;IAC9F,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,IAAI,CAAC,aAAa,CAAC,OAAO,CAAE,YAAY,CAAC,EAAE;YACzC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;IACL,CAAC;IAIS,OAAO,CAAC,KAAa,EAAE,KAAgB;QAC/C,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACzC,CAAC;IAEM,QAAQ;QACb,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,8DAA8D;IACpD,MAAM,CAAC,GAAG,IAAmB;QACrC,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACzE,CAAC;CACF"}
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/accessory/base.ts"],"names":[],"mappings":"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"}