homebridge-easy-mqtt 1.2.0 → 1.3.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.
- package/CHANGELOG.md +11 -1
- package/README.md +72 -5
- package/config.schema.json +37 -0
- package/dist/accessory/abstract/base.d.ts +1 -5
- package/dist/accessory/abstract/base.js +24 -28
- package/dist/accessory/abstract/base.js.map +1 -1
- package/dist/accessory/abstract/customCharacteristic.d.ts +17 -0
- package/dist/accessory/abstract/customCharacteristic.js +65 -0
- package/dist/accessory/abstract/customCharacteristic.js.map +1 -0
- package/dist/accessory/abstract/mqtt.d.ts +7 -10
- package/dist/accessory/abstract/mqtt.js +55 -48
- package/dist/accessory/abstract/mqtt.js.map +1 -1
- package/dist/accessory/lock.d.ts +0 -3
- package/dist/accessory/lock.js +11 -26
- package/dist/accessory/lock.js.map +1 -1
- package/dist/accessory/onoff/lightbulb.d.ts +1 -13
- package/dist/accessory/onoff/lightbulb.js +9 -66
- package/dist/accessory/onoff/lightbulb.js.map +1 -1
- package/dist/accessory/onoff/onoff.d.ts +0 -2
- package/dist/accessory/onoff/onoff.js +1 -11
- package/dist/accessory/onoff/onoff.js.map +1 -1
- package/dist/accessory/onoff/outlet.d.ts +0 -3
- package/dist/accessory/onoff/outlet.js +1 -13
- package/dist/accessory/onoff/outlet.js.map +1 -1
- package/dist/accessory/security.d.ts +0 -7
- package/dist/accessory/security.js +4 -40
- package/dist/accessory/security.js.map +1 -1
- package/dist/accessory/temperatureSensor.d.ts +0 -3
- package/dist/accessory/temperatureSensor.js +5 -17
- package/dist/accessory/temperatureSensor.js.map +1 -1
- package/dist/homebridge-ui/public/index.html +4 -4
- package/dist/homebridge-ui/public/ui.js +1 -1
- package/dist/i18n/en.d.ts +5 -5
- package/dist/i18n/en.js +14 -14
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/i18n.d.ts +5 -5
- package/dist/i18n/template.d.ts +5 -5
- package/dist/model/enums.d.ts +1 -0
- package/dist/model/enums.js +1 -0
- package/dist/model/enums.js.map +1 -1
- package/dist/model/mqtt.d.ts +1 -1
- package/dist/model/mqtt.js +60 -32
- package/dist/model/mqtt.js.map +1 -1
- package/dist/model/types.d.ts +14 -0
- package/img/banner.png +0 -0
- package/img/banner.xcf +0 -0
- package/img/icon.png +0 -0
- package/img/icon.xcf +0 -0
- package/img/screenshot_1.png +0 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,12 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to homebridge-dummy will be documented in this file.
|
|
4
4
|
|
|
5
|
-
## 1.
|
|
5
|
+
## 1.3.0-beta.0 (2025-09-XX)
|
|
6
6
|
|
|
7
7
|
### HELP NEEDED! (no coding experience required)
|
|
8
8
|
|
|
9
9
|
Would you like to see Homebridge Easy MQTT in your language? Please consider [getting involved](https://github.com/mpatfield/homebridge-easy-mqtt/issues/4).
|
|
10
10
|
|
|
11
|
+
### Added
|
|
12
|
+
- Support for arbitrary custom characteristics ([documentation](https://github.com/mpatfield/homebridge-easy-mqtt#custom-characteristics))
|
|
13
|
+
- JSONPath support in setter topics ([documentation](https://github.com/mpatfield/homebridge-easy-mqtt#jsonpaths))
|
|
14
|
+
- Banner image in config UI
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- Significant under-the-hood DRY cleanup to speed future development
|
|
18
|
+
|
|
19
|
+
## 1.2.0 (2025-09-02)
|
|
20
|
+
|
|
11
21
|
### Added
|
|
12
22
|
- Security System accessory type
|
|
13
23
|
- Support for battery and status
|
package/README.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
<!--
|
|
2
1
|
<p align="center">
|
|
3
|
-
<img src="https://
|
|
2
|
+
<img src="https://raw.githubusercontent.com/mpatfield/homebridge-easy-mqtt/refs/heads/latest/img/banner.png" width="600">
|
|
4
3
|
</p>
|
|
5
|
-
-->
|
|
6
4
|
|
|
7
5
|
<span align="center">
|
|
8
6
|
|
|
@@ -51,6 +49,15 @@ Using the Homebridge Config UI is the easiest way to set up this plugin. However
|
|
|
51
49
|
"password": "string",
|
|
52
50
|
"options": "string"
|
|
53
51
|
},
|
|
52
|
+
"customCharacteristics": [
|
|
53
|
+
{
|
|
54
|
+
"uuid": "string",
|
|
55
|
+
"name": "string",
|
|
56
|
+
"getTopic": "string",
|
|
57
|
+
"units": "string",
|
|
58
|
+
}
|
|
59
|
+
…
|
|
60
|
+
],
|
|
54
61
|
"topicGetStatusActive": "string",
|
|
55
62
|
"topicGetCurrentLockState": "string",
|
|
56
63
|
"topicGetTargetLockState": "string",
|
|
@@ -65,7 +72,7 @@ Using the Homebridge Config UI is the easiest way to set up this plugin. However
|
|
|
65
72
|
"valueOff": "string",
|
|
66
73
|
"disableLogging": false
|
|
67
74
|
}
|
|
68
|
-
|
|
75
|
+
…
|
|
69
76
|
],
|
|
70
77
|
"verbose": false,
|
|
71
78
|
"platform": "HomebridgeEasyMQTT"
|
|
@@ -189,7 +196,7 @@ You are able to pass in any arbitrary MQTT options via `mqtt.options` in the con
|
|
|
189
196
|
|
|
190
197
|
## JSONPaths
|
|
191
198
|
|
|
192
|
-
For some devices, the desired values in the MQTT messages
|
|
199
|
+
For some devices, the desired values in the MQTT messages are embedded within a JSON object. For example, here is the MQTT message for my door lock that is received when the door is locked:
|
|
193
200
|
|
|
194
201
|
```json
|
|
195
202
|
{ "time": 1750870005853, "state": 255 }
|
|
@@ -220,8 +227,68 @@ would use the topic
|
|
|
220
227
|
|
|
221
228
|
`zwave/1/door_lock/currentMode$.state.number.value`
|
|
222
229
|
|
|
230
|
+
You can do the same for the set topic if the device is expecting a JSON object rather than a raw value.
|
|
231
|
+
|
|
232
|
+
If, for example, your device is expecting this message:
|
|
233
|
+
|
|
234
|
+
```json
|
|
235
|
+
{
|
|
236
|
+
"target": "away"
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
instead of just the raw value "away" you can use:
|
|
241
|
+
|
|
242
|
+
`zwave/4/security/set$.target`
|
|
243
|
+
|
|
244
|
+
Again, the `$.target` at the end tells the MQTT client to wrap the value a JSON object.
|
|
245
|
+
|
|
246
|
+
As with get topics, you can have an arbitrarily complex chain. So if, for example, you want this object:
|
|
247
|
+
|
|
248
|
+
```json
|
|
249
|
+
{
|
|
250
|
+
"target": {
|
|
251
|
+
"mode": {
|
|
252
|
+
"value": "away"
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
then you would use the topic
|
|
259
|
+
|
|
260
|
+
`zwave/4/security/set$.target.mode.value`
|
|
261
|
+
|
|
262
|
+
## Custom Characteristics
|
|
263
|
+
|
|
264
|
+
If you use a more advanced HomeKit app like [Eve](https://apps.apple.com/us/app/eve-for-matter-homekit/id917695792) or [Controller for Homekit](https://apps.apple.com/us/app/controller-for-homekit/id1198176727), you can add custom characteristics to display any arbitrary numeric information. Unfortunately, Apple currently doesn't offer a way to display this in the Home app.
|
|
265
|
+
|
|
266
|
+
<img src="https://raw.githubusercontent.com/mpatfield/homebridge-easy-mqtt/refs/heads/latest/img/screenshot_1.png">
|
|
267
|
+
|
|
268
|
+
Due to the complexity, this was intentionally left out of the plugin config UI, so this can only be configured manually.
|
|
269
|
+
|
|
270
|
+
```json
|
|
271
|
+
"customCharacteristics": [
|
|
272
|
+
{
|
|
273
|
+
"uuid": "string",
|
|
274
|
+
"name": "string",
|
|
275
|
+
"getTopic": "string",
|
|
276
|
+
"units": "string",
|
|
277
|
+
}
|
|
278
|
+
]
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
- `uuid` — A unique string (recommend using a (UUID generator)[https://www.uuidgenerator.net/])
|
|
282
|
+
- `name` — The display name for the characteristic
|
|
283
|
+
- `getTopic` — The topic which provides the numeric value
|
|
284
|
+
- `units` — (Optional) The units which will be displayed at the end of the numeric value
|
|
285
|
+
|
|
286
|
+
Since `customCharacteristics` is an array, you may define as many custom characteristics as you wish.
|
|
287
|
+
|
|
223
288
|
## Credits
|
|
224
289
|
|
|
225
290
|
[@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
|
|
226
291
|
|
|
292
|
+
[Keryan Belahcene](https://www.instagram.com/keryan.me) for creating the [Flume](https://github.com/homebridge-plugins/homebridge-flume) header logo which I adapted for this plugin
|
|
293
|
+
|
|
227
294
|
And to the amazing creators/contributors of [Homebridge](https://homebridge.io) who made this plugin possible!
|
package/config.schema.json
CHANGED
|
@@ -24,6 +24,22 @@
|
|
|
24
24
|
"enum": [ "Lightbulb", "LockMechanism", "Outlet", "SecuritySystem", "Switch", "TemperatureSensor"],
|
|
25
25
|
"enumNames": ["${config.enumNames.lightbulb}", "${config.enumNames.lockMechanism}", "${config.enumNames.outlet}", "${config.enumNames.securitySystem}", "${config.enumNames.switch}", "${config.enumNames.temperatureSensor}"],
|
|
26
26
|
"required": true
|
|
27
|
+
},
|
|
28
|
+
"manufacturer": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"title": "${config.title.manufacturer}"
|
|
31
|
+
},
|
|
32
|
+
"model": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"title": "${config.title.model}"
|
|
35
|
+
},
|
|
36
|
+
"serialNumber": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"title": "${config.title.serialNumber}"
|
|
39
|
+
},
|
|
40
|
+
"version": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"title": "${config.title.version}"
|
|
27
43
|
}
|
|
28
44
|
}
|
|
29
45
|
},
|
|
@@ -51,6 +67,23 @@
|
|
|
51
67
|
"placeholder": "{ \"protocolVersion\": \"4\", \"clientId\": \"my-client-id\", \"rejectUnauthorized\": true }"
|
|
52
68
|
}
|
|
53
69
|
}
|
|
70
|
+
},
|
|
71
|
+
"customCharacteristic": {
|
|
72
|
+
"type": "object",
|
|
73
|
+
"properties": {
|
|
74
|
+
"uuid": {
|
|
75
|
+
"type": "string"
|
|
76
|
+
},
|
|
77
|
+
"name": {
|
|
78
|
+
"type": "string"
|
|
79
|
+
},
|
|
80
|
+
"getTopic": {
|
|
81
|
+
"type": "string"
|
|
82
|
+
},
|
|
83
|
+
"units": {
|
|
84
|
+
"type": "string"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
54
87
|
}
|
|
55
88
|
},
|
|
56
89
|
"properties": {
|
|
@@ -65,6 +98,10 @@
|
|
|
65
98
|
"properties": {
|
|
66
99
|
"info": { "$ref": "#/definitions/info" },
|
|
67
100
|
"mqtt": { "$ref": "#/definitions/mqtt" },
|
|
101
|
+
"customCharacteristics": {
|
|
102
|
+
"type": "array",
|
|
103
|
+
"items": { "$ref": "#/definitions/customCharacteristic" }
|
|
104
|
+
},
|
|
68
105
|
"temperatureUnits": {
|
|
69
106
|
"type": "string",
|
|
70
107
|
"enum": ["C", "F"],
|
|
@@ -4,11 +4,7 @@ import { CharacteristicType, BaseAccessoryConfig, ServiceType } from '../../mode
|
|
|
4
4
|
import { Log } from '../../tools/log.js';
|
|
5
5
|
export declare abstract class BaseAccessory<C extends BaseAccessoryConfig = BaseAccessoryConfig> extends MQTTAccessory<C> {
|
|
6
6
|
constructor(Service: ServiceType, Characteristic: CharacteristicType, accessory: PlatformAccessory, config: C, log: Log);
|
|
7
|
-
|
|
8
|
-
private getBatteryLevel;
|
|
9
|
-
private getBatteryLow;
|
|
10
|
-
private getStatusActive;
|
|
11
|
-
private onBatteryLevelUpdate;
|
|
7
|
+
private handleCustomCharacteristics;
|
|
12
8
|
private onBatteryLowUpdate;
|
|
13
9
|
private onStatusActiveUpdate;
|
|
14
10
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MQTTAccessory } from './mqtt.js';
|
|
2
|
+
import { CustomCharacteristic } from './customCharacteristic.js';
|
|
2
3
|
import { PLATFORM_NAME } from '../../homebridge/settings.js';
|
|
3
4
|
import { strings } from '../../i18n/i18n.js';
|
|
4
5
|
import { CharacteristicKey } from '../../model/enums.js';
|
|
@@ -10,35 +11,30 @@ export class BaseAccessory extends MQTTAccessory {
|
|
|
10
11
|
accessory.getService(Service.AccessoryInformation)
|
|
11
12
|
.setCharacteristic(Characteristic.Name, config.info.name)
|
|
12
13
|
.setCharacteristic(Characteristic.ConfiguredName, config.info.name)
|
|
13
|
-
.setCharacteristic(Characteristic.Manufacturer, PLATFORM_NAME)
|
|
14
|
-
.setCharacteristic(Characteristic.Model, config.info.type)
|
|
15
|
-
.setCharacteristic(Characteristic.SerialNumber, config.info.id)
|
|
16
|
-
.setCharacteristic(Characteristic.FirmwareRevision, getVersion());
|
|
17
|
-
this.
|
|
18
|
-
this.
|
|
19
|
-
this.
|
|
20
|
-
this.
|
|
21
|
-
this.set(CharacteristicKey.StatusActive, true);
|
|
22
|
-
this.bind(Characteristic.StatusActive, 'topicGetStatusActive', this.getStatusActive.bind(this));
|
|
14
|
+
.setCharacteristic(Characteristic.Manufacturer, config.info.manufacturer ?? PLATFORM_NAME)
|
|
15
|
+
.setCharacteristic(Characteristic.Model, config.info.model ?? config.info.type)
|
|
16
|
+
.setCharacteristic(Characteristic.SerialNumber, config.info.serialNumber ?? config.info.id)
|
|
17
|
+
.setCharacteristic(Characteristic.FirmwareRevision, config.info.version ?? getVersion());
|
|
18
|
+
this.setupCharacteristic(CharacteristicKey.BatteryLevel, 100, 'topicGetBatteryLevel', this.bindOnUpdateNumeric(CharacteristicKey.BatteryLevel, strings.accessory.batteryLevel), false);
|
|
19
|
+
this.setupCharacteristic(CharacteristicKey.StatusLowBattery, false, 'topicGetBatteryLow', this.onBatteryLowUpdate.bind(this), false);
|
|
20
|
+
this.setupCharacteristic(CharacteristicKey.StatusActive, true, 'topicGetStatusActive', this.onStatusActiveUpdate.bind(this), false);
|
|
21
|
+
this.handleCustomCharacteristics();
|
|
23
22
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (this.assertNumber(value, strings.accessory.badBatteryLevel)) {
|
|
40
|
-
const logString = strings.accessory.batteryLevel.replace('%d', `${value.toString()}%`);
|
|
41
|
-
this.onUpdate(CharacteristicKey.BatteryLevel, value, logString);
|
|
23
|
+
handleCustomCharacteristics() {
|
|
24
|
+
const keepUUIDs = new Set(Object.values(CharacteristicKey).map((key) => this.Characteristic[key].UUID));
|
|
25
|
+
const toRemove = this.accessoryService.characteristics.filter((characteristic) => !keepUUIDs.has(characteristic.UUID));
|
|
26
|
+
for (const characteristic of toRemove) {
|
|
27
|
+
characteristic.updateValue(null);
|
|
28
|
+
this.accessoryService.removeCharacteristic(characteristic);
|
|
29
|
+
}
|
|
30
|
+
if (!this.config.customCharacteristics) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
for (const config of this.config.customCharacteristics) {
|
|
34
|
+
const customChar = CustomCharacteristic.create(this.accessoryService, this.Characteristic, config, this.name, this.log, this.config.disableLogging);
|
|
35
|
+
if (customChar !== undefined) {
|
|
36
|
+
this.addTopicHandler(customChar.topic, customChar.onUpdateHandler);
|
|
37
|
+
}
|
|
42
38
|
}
|
|
43
39
|
}
|
|
44
40
|
async onBatteryLowUpdate(topic, value) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/accessory/abstract/base.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,OAAO,EAAO,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,UAAU,MAAM,wBAAwB,CAAC;AAEhD,MAAM,OAAgB,aAAmE,SAAQ,aAAgB;IAE/G,YAAY,OAAoB,EAAE,cAAkC,EAAE,SAA4B,EAAE,MAAS,EAAE,GAAQ;QACrH,KAAK,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;QAEvD,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,oBAAoB,CAAE;aAChD,iBAAiB,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;aACxD,iBAAiB,CAAC,cAAc,CAAC,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;aAClE,iBAAiB,CAAC,cAAc,CAAC,YAAY,EAAE,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/accessory/abstract/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { PrimitiveTypes, Service } from 'homebridge';
|
|
2
|
+
import { CharacteristicType, CustomCharacteristicConfig } from '../../model/types.js';
|
|
3
|
+
import { Log } from '../../tools/log.js';
|
|
4
|
+
export declare class CustomCharacteristic {
|
|
5
|
+
private readonly config;
|
|
6
|
+
private readonly caller;
|
|
7
|
+
private readonly log;
|
|
8
|
+
private readonly disableLogging;
|
|
9
|
+
private characteristic;
|
|
10
|
+
private value;
|
|
11
|
+
static create(Service: Service, Characteristic: CharacteristicType, config: CustomCharacteristicConfig, caller: string, log: Log, disableLogging: boolean): CustomCharacteristic | undefined;
|
|
12
|
+
private constructor();
|
|
13
|
+
get topic(): string;
|
|
14
|
+
get onUpdateHandler(): (topic: string, value: PrimitiveTypes) => Promise<void>;
|
|
15
|
+
private getValue;
|
|
16
|
+
private onValueUpdate;
|
|
17
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { strings } from '../../i18n/i18n.js';
|
|
2
|
+
import { assert } from '../../tools/validation.js';
|
|
3
|
+
export class CustomCharacteristic {
|
|
4
|
+
config;
|
|
5
|
+
caller;
|
|
6
|
+
log;
|
|
7
|
+
disableLogging;
|
|
8
|
+
characteristic;
|
|
9
|
+
value = null;
|
|
10
|
+
static create(Service, Characteristic, config, caller, log, disableLogging) {
|
|
11
|
+
if (!assert(log, config.name ?? CustomCharacteristic.name, config, 'name', 'uuid', 'getTopic')) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
return new CustomCharacteristic(Service, Characteristic, config, caller, log, disableLogging);
|
|
15
|
+
}
|
|
16
|
+
constructor(Service, Characteristic, config, caller, log, disableLogging) {
|
|
17
|
+
this.config = config;
|
|
18
|
+
this.caller = caller;
|
|
19
|
+
this.log = log;
|
|
20
|
+
this.disableLogging = disableLogging;
|
|
21
|
+
if (Service.testCharacteristic(config.name)) {
|
|
22
|
+
this.characteristic = Service.getCharacteristic(config.name);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const customCharacteristic = class CustomCharacteristic extends Characteristic {
|
|
26
|
+
constructor() {
|
|
27
|
+
super(config.name, config.uuid, {
|
|
28
|
+
format: "uint32" /* Formats.UINT32 */,
|
|
29
|
+
perms: ["pr" /* Perms.PAIRED_READ */, "ev" /* Perms.NOTIFY */],
|
|
30
|
+
unit: config.units,
|
|
31
|
+
});
|
|
32
|
+
this.value = this.getDefaultValue();
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
this.characteristic = Service.addCharacteristic(customCharacteristic);
|
|
36
|
+
this.characteristic.UUID = config.uuid;
|
|
37
|
+
}
|
|
38
|
+
this.characteristic.onGet(this.getValue.bind(this));
|
|
39
|
+
}
|
|
40
|
+
get topic() {
|
|
41
|
+
return this.config.getTopic;
|
|
42
|
+
}
|
|
43
|
+
get onUpdateHandler() {
|
|
44
|
+
return this.onValueUpdate.bind(this);
|
|
45
|
+
}
|
|
46
|
+
async getValue() {
|
|
47
|
+
return this.value;
|
|
48
|
+
}
|
|
49
|
+
async onValueUpdate(topic, value) {
|
|
50
|
+
if (typeof value !== 'number') {
|
|
51
|
+
this.log.error(strings.characteristic.badValue, this.caller, this.characteristic.displayName, `'${value}'`);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (value === this.value) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
this.value = value;
|
|
58
|
+
this.characteristic.updateValue(this.value);
|
|
59
|
+
if (this.disableLogging) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
this.log.always(strings.characteristic.updated, this.caller, this.characteristic.displayName, `'${value}'`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=customCharacteristic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customCharacteristic.js","sourceRoot":"","sources":["../../../src/accessory/abstract/customCharacteristic.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Characteristic,
|
|
1
|
+
import { Characteristic, CharacteristicSetHandler, CharacteristicValue, PlatformAccessory, PrimitiveTypes, Service } from 'homebridge';
|
|
2
2
|
import { CharacteristicKey } from '../../model/enums.js';
|
|
3
3
|
import { CharacteristicType, MQTTAccessoryConfig, ServiceType } from '../../model/types.js';
|
|
4
4
|
import { Log, LogType } from '../../tools/log.js';
|
|
5
|
+
type OnUpdateHandler = (topic: string, value: PrimitiveTypes) => (Promise<void>);
|
|
5
6
|
export declare abstract class MQTTAccessory<C extends MQTTAccessoryConfig> {
|
|
6
7
|
protected readonly Service: ServiceType;
|
|
7
8
|
protected readonly Characteristic: CharacteristicType;
|
|
@@ -13,24 +14,20 @@ export declare abstract class MQTTAccessory<C extends MQTTAccessoryConfig> {
|
|
|
13
14
|
private readonly topicHandlers;
|
|
14
15
|
protected readonly accessoryService: Service;
|
|
15
16
|
constructor(Service: ServiceType, Characteristic: CharacteristicType, accessory: PlatformAccessory, config: C, log: Log);
|
|
16
|
-
private onMQTTConnect;
|
|
17
17
|
protected abstract getAccessoryService(): Service;
|
|
18
|
-
protected bind(constructor: WithUUID<{
|
|
19
|
-
new (): Characteristic;
|
|
20
|
-
}>, getTopic: keyof C, getHandler: CharacteristicGetHandler, setTopic?: keyof C | undefined, setHandler?: CharacteristicSetHandler | undefined): void;
|
|
21
|
-
protected abstract addTopicHandlers(): void;
|
|
22
|
-
protected addTopicHandler(topicKey: keyof C, handler: (topic: string, value: PrimitiveTypes) => Promise<void>, assert?: boolean): void;
|
|
23
18
|
protected get name(): string;
|
|
19
|
+
protected setupCharacteristic(characteristicKey: CharacteristicKey, defaultValue: CharacteristicValue, getTopicKey: keyof C, onUpdateHandler: OnUpdateHandler, assertGetTopic: boolean, setTopicKey?: keyof C | undefined, onSetHandler?: CharacteristicSetHandler | undefined): Characteristic | undefined;
|
|
20
|
+
protected bindOnUpdateNumeric(charKey: CharacteristicKey, logTemplate: string): OnUpdateHandler;
|
|
21
|
+
protected bindOnUpdateNumericBoolean(charKey: CharacteristicKey, valueKey: keyof C, logTrue: string, logFalse: string): OnUpdateHandler;
|
|
22
|
+
protected addTopicHandler(topic: string, handler: (topic: string, value: PrimitiveTypes) => Promise<void>): void;
|
|
24
23
|
protected getRawValue(property: keyof C, assert?: boolean): string | undefined;
|
|
25
24
|
protected getPrimitiveValue(property: keyof C, assert?: boolean): PrimitiveTypes | undefined;
|
|
26
25
|
protected publish(topic: string, value: PrimitiveTypes): void;
|
|
27
26
|
teardown(): void;
|
|
28
|
-
protected get(key: CharacteristicKey): CharacteristicValue;
|
|
29
|
-
protected set(key: CharacteristicKey, value: CharacteristicValue): void;
|
|
30
27
|
protected assert(...keys: (keyof C)[]): boolean;
|
|
31
|
-
protected assertNumber(value: PrimitiveTypes, error: string): boolean;
|
|
32
28
|
protected onUpdate(key: CharacteristicKey, value: CharacteristicValue, logString?: string | undefined): boolean;
|
|
33
29
|
protected onSet(key: CharacteristicKey, value: CharacteristicValue, publish: PrimitiveTypes, topic: keyof C, logString: string | undefined): void;
|
|
34
30
|
protected logIfDesired(message: string, ...parameters: string[]): void;
|
|
35
31
|
protected logIfDesired(level: LogType, message: string, ...parameters: string[]): void;
|
|
36
32
|
}
|
|
33
|
+
export {};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { strings } from '../../i18n/i18n.js';
|
|
1
2
|
import { AccessoryType } from '../../model/enums.js';
|
|
2
3
|
import { MQTT } from '../../model/mqtt.js';
|
|
3
4
|
import { LogType } from '../../tools/log.js';
|
|
4
|
-
import { assert } from '../../tools/validation.js';
|
|
5
5
|
import { toPrimitive } from '../../tools/primitive.js';
|
|
6
|
+
import { assert } from '../../tools/validation.js';
|
|
6
7
|
export class MQTTAccessory {
|
|
7
8
|
Service;
|
|
8
9
|
Characteristic;
|
|
@@ -10,7 +11,7 @@ export class MQTTAccessory {
|
|
|
10
11
|
config;
|
|
11
12
|
log;
|
|
12
13
|
mqttClient;
|
|
13
|
-
properties =
|
|
14
|
+
properties = new Map();
|
|
14
15
|
topicHandlers = [];
|
|
15
16
|
accessoryService;
|
|
16
17
|
constructor(Service, Characteristic, accessory, config, log) {
|
|
@@ -21,7 +22,11 @@ export class MQTTAccessory {
|
|
|
21
22
|
this.log = log;
|
|
22
23
|
const name = config.info.name;
|
|
23
24
|
if (this.assert('mqtt')) {
|
|
24
|
-
this.mqttClient = new MQTT(log, config.mqtt,
|
|
25
|
+
this.mqttClient = new MQTT(log, config.mqtt, () => {
|
|
26
|
+
this.topicHandlers.forEach(topicHandler => {
|
|
27
|
+
this.mqttClient?.subscribe(topicHandler.topic, topicHandler.handler);
|
|
28
|
+
});
|
|
29
|
+
}, name);
|
|
25
30
|
this.mqttClient.connect();
|
|
26
31
|
}
|
|
27
32
|
this.accessoryService = this.getAccessoryService();
|
|
@@ -31,46 +36,61 @@ export class MQTTAccessory {
|
|
|
31
36
|
accessory.removeService(existingService);
|
|
32
37
|
}
|
|
33
38
|
}
|
|
34
|
-
this.addTopicHandlers();
|
|
35
39
|
}
|
|
36
|
-
|
|
37
|
-
this.
|
|
38
|
-
this.mqttClient?.subscribe(topicHandler.topic, topicHandler.handler);
|
|
39
|
-
});
|
|
40
|
+
get name() {
|
|
41
|
+
return this.config.info.name;
|
|
40
42
|
}
|
|
41
|
-
|
|
42
|
-
if (
|
|
43
|
+
setupCharacteristic(characteristicKey, defaultValue, getTopicKey, onUpdateHandler, assertGetTopic, setTopicKey = undefined, onSetHandler = undefined) {
|
|
44
|
+
if (!getTopicKey.toString().startsWith('topic')) {
|
|
45
|
+
throw new Error(`Trying to fetch topic with unexpected property name '${getTopicKey.toString()}'`);
|
|
46
|
+
}
|
|
47
|
+
if (assertGetTopic) {
|
|
48
|
+
this.assert(getTopicKey);
|
|
49
|
+
}
|
|
50
|
+
if (this.config[getTopicKey] === undefined) {
|
|
43
51
|
for (const characteristic of this.accessoryService.characteristics) {
|
|
44
|
-
if (characteristic.UUID ===
|
|
52
|
+
if (characteristic.UUID === this.Characteristic[characteristicKey].UUID) {
|
|
45
53
|
this.accessoryService.removeCharacteristic(characteristic);
|
|
46
54
|
break;
|
|
47
55
|
}
|
|
48
56
|
}
|
|
49
57
|
return;
|
|
50
58
|
}
|
|
51
|
-
const characteristic = this.accessoryService.getCharacteristic(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
const characteristic = this.accessoryService.getCharacteristic(this.Characteristic[characteristicKey]);
|
|
60
|
+
this.properties.set(characteristicKey, defaultValue);
|
|
61
|
+
characteristic.onGet(async () => {
|
|
62
|
+
return this.properties.get(characteristicKey) ?? null;
|
|
63
|
+
});
|
|
64
|
+
this.addTopicHandler(this.config[getTopicKey], onUpdateHandler);
|
|
65
|
+
if (setTopicKey !== undefined) {
|
|
66
|
+
if (!setTopicKey.toString().startsWith('topic')) {
|
|
67
|
+
throw new Error(`Trying to fetch topic with unexpected property name '${setTopicKey.toString()}'`);
|
|
68
|
+
}
|
|
69
|
+
if (!onSetHandler) {
|
|
70
|
+
throw new Error(`Missing onSetHandler for topic '${setTopicKey.toString()}'`);
|
|
71
|
+
}
|
|
72
|
+
characteristic.onSet(onSetHandler);
|
|
57
73
|
}
|
|
74
|
+
return characteristic;
|
|
58
75
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
this.topicHandlers.push({ topic: topic, handler });
|
|
76
|
+
bindOnUpdateNumeric(charKey, logTemplate) {
|
|
77
|
+
return (async (_topic, value) => {
|
|
78
|
+
if (typeof value !== 'number') {
|
|
79
|
+
this.log.error(strings.accessory.badNumericValue, this.name, charKey, `'${value.toString()}'`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const logString = logTemplate.replace('%d', value.toString());
|
|
83
|
+
this.onUpdate(charKey, value, logString);
|
|
84
|
+
}).bind(this);
|
|
71
85
|
}
|
|
72
|
-
|
|
73
|
-
return
|
|
86
|
+
bindOnUpdateNumericBoolean(charKey, valueKey, logTrue, logFalse) {
|
|
87
|
+
return (async (_topic, value) => {
|
|
88
|
+
const numeric = value === this.getPrimitiveValue(valueKey) ? 1 : 0;
|
|
89
|
+
this.onUpdate(charKey, numeric, numeric ? logTrue : logFalse);
|
|
90
|
+
}).bind(this);
|
|
91
|
+
}
|
|
92
|
+
addTopicHandler(topic, handler) {
|
|
93
|
+
this.topicHandlers.push({ topic: topic, handler: handler });
|
|
74
94
|
}
|
|
75
95
|
getRawValue(property, assert = true) {
|
|
76
96
|
if (!property.toString().startsWith('value')) {
|
|
@@ -91,27 +111,14 @@ export class MQTTAccessory {
|
|
|
91
111
|
teardown() {
|
|
92
112
|
this.mqttClient?.teardown();
|
|
93
113
|
}
|
|
94
|
-
get(key) {
|
|
95
|
-
return this.properties[key];
|
|
96
|
-
}
|
|
97
|
-
set(key, value) {
|
|
98
|
-
this.properties[key] = value;
|
|
99
|
-
}
|
|
100
114
|
assert(...keys) {
|
|
101
115
|
return assert(this.log, this.name, this.config, ...keys);
|
|
102
116
|
}
|
|
103
|
-
assertNumber(value, error) {
|
|
104
|
-
if (typeof value === 'number') {
|
|
105
|
-
return true;
|
|
106
|
-
}
|
|
107
|
-
this.log.error(error, this.name, `'${value}'`);
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
117
|
onUpdate(key, value, logString = undefined) {
|
|
111
|
-
if (value === this.get(key)) {
|
|
118
|
+
if (value === this.properties.get(key)) {
|
|
112
119
|
return false;
|
|
113
120
|
}
|
|
114
|
-
this.set(key, value);
|
|
121
|
+
this.properties.set(key, value);
|
|
115
122
|
this.accessoryService.updateCharacteristic(this.Characteristic[key], value);
|
|
116
123
|
if (logString) {
|
|
117
124
|
this.logIfDesired(logString);
|
|
@@ -122,10 +129,10 @@ export class MQTTAccessory {
|
|
|
122
129
|
if (!this.assert(topic)) {
|
|
123
130
|
return;
|
|
124
131
|
}
|
|
125
|
-
if (logString && value !== this.get(key)) {
|
|
132
|
+
if (logString && value !== this.properties.get(key)) {
|
|
126
133
|
this.logIfDesired(logString);
|
|
127
134
|
}
|
|
128
|
-
this.set(key, value);
|
|
135
|
+
this.properties.set(key, value);
|
|
129
136
|
this.accessoryService.updateCharacteristic(this.Characteristic[key], value);
|
|
130
137
|
this.publish(this.config[topic], publish);
|
|
131
138
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mqtt.js","sourceRoot":"","sources":["../../../src/accessory/abstract/mqtt.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mqtt.js","sourceRoot":"","sources":["../../../src/accessory/abstract/mqtt.ts"],"names":[],"mappings":"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"}
|
package/dist/accessory/lock.d.ts
CHANGED
|
@@ -5,9 +5,6 @@ import { Log } from '../tools/log.js';
|
|
|
5
5
|
export declare class LockMechanismAccessory extends BaseAccessory<LockMechanismConfig> {
|
|
6
6
|
constructor(Service: ServiceType, Characteristic: CharacteristicType, accessory: PlatformAccessory, config: LockMechanismConfig, log: Log);
|
|
7
7
|
protected getAccessoryService(): Service;
|
|
8
|
-
addTopicHandlers(): void;
|
|
9
|
-
private getCurrentState;
|
|
10
|
-
private getTargetState;
|
|
11
8
|
private onCurrentStateUpdate;
|
|
12
9
|
private onTargetStateUpdate;
|
|
13
10
|
private onSetTargetState;
|