homebridge-broadlink-rm-blaster 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/README.md +19 -149
- package/config.schema.json +121 -42
- package/dist/accessories/temperatureHumiditySensorAccessory.d.ts +3 -1
- package/dist/accessories/temperatureHumiditySensorAccessory.js +35 -22
- package/dist/accessories/temperatureHumiditySensorAccessory.js.map +1 -1
- package/dist/broadlinkClient.js +1 -1
- package/dist/broadlinkClient.js.map +1 -1
- package/dist/configTypes.d.ts +7 -0
- package/dist/mqttPublisher.d.ts +11 -0
- package/dist/mqttPublisher.js +53 -0
- package/dist/mqttPublisher.js.map +1 -0
- package/dist/ntfyNotifier.d.ts +1 -1
- package/dist/ntfyNotifier.js +2 -2
- package/dist/ntfyNotifier.js.map +1 -1
- package/dist/platform.d.ts +2 -0
- package/dist/platform.js +17 -6
- package/dist/platform.js.map +1 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## [1.3.0] - 2026-08-02
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- Optional MQTT publishing of temperature/humidity readings, so other
|
|
13
|
+
plugins (e.g. `homebridge-mqttthing`) can subscribe to them. Controlled by
|
|
14
|
+
an `enableMqtt` checkbox plus `mqttHost`/`mqttPort` (and optional
|
|
15
|
+
`mqttUsername`/`mqttPassword`/`mqttBaseTopic`), and a separate
|
|
16
|
+
`enableMqttPublish` checkbox per RM device, independent of the existing
|
|
17
|
+
`enableTemperatureHumidity` HomeKit sensor checkbox - either, both, or
|
|
18
|
+
neither can be enabled.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- Reorganized the Config UI X settings form: Accessories, Dimmer Lights, TVs
|
|
22
|
+
(and Dimmer Lights' Brightness Levels), and new Notifications/MQTT fields
|
|
23
|
+
are now collapsed fieldsets, so the form isn't a huge wall of fields by
|
|
24
|
+
default.
|
|
25
|
+
- Trimmed redundant field descriptions and tightened several labels across
|
|
26
|
+
the config form.
|
|
27
|
+
|
|
28
|
+
## [1.2.1] - 2026-07-27
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
- The `ntfyTopic` config field's description only mentioned the
|
|
32
|
+
RM-connection-failure trigger, not the temperature/humidity sensor's
|
|
33
|
+
5-consecutive-failed-readings trigger.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
- ntfy notification bodies now use a short, fixed message pointing at the
|
|
37
|
+
Homebridge logs, instead of the raw error text (which included the RM's
|
|
38
|
+
IP address).
|
|
39
|
+
|
|
9
40
|
## [1.2.0] - 2026-07-26
|
|
10
41
|
|
|
11
42
|
### Changed
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Homebridge Broadlink RM Blaster Plugin 1.
|
|
1
|
+
# Homebridge Broadlink RM Blaster Plugin 1.3.0
|
|
2
2
|
|
|
3
3
|
**This Homebridge plugin has been 100% vibe coded with Claude.**
|
|
4
4
|
|
|
@@ -9,166 +9,34 @@ autodiscover devices. To capture hex codes from your own remotes, see
|
|
|
9
9
|
|
|
10
10
|
## Requirements
|
|
11
11
|
|
|
12
|
-
- A Broadlink RM device, unlocked using the official Broadlink app
|
|
13
|
-
devices ship locked, which blocks local API access).
|
|
14
|
-
- Node.js `^18.15.0 || ^20.7.0 || ^22 || ^24`
|
|
15
|
-
- Homebridge `^1.8.0 || ^2.0.0`
|
|
12
|
+
- A Broadlink RM device, unlocked using the official Broadlink app
|
|
16
13
|
|
|
17
14
|
## Installation
|
|
18
15
|
|
|
19
16
|
```bash
|
|
20
|
-
npm install
|
|
17
|
+
npm install homebridge-broadlink-rm-blaster
|
|
18
|
+
hb-service add homebridge-broadlink-rm-blaster
|
|
21
19
|
```
|
|
22
20
|
|
|
23
|
-
##
|
|
21
|
+
## Features
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
**
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
TV from your config later, it has to be removed from the Home app manually
|
|
36
|
-
too since Homebridge can't unpair it for you.
|
|
37
|
-
|
|
38
|
-
### Features
|
|
39
|
-
|
|
40
|
-
- **Multiple RM devices** configure several Broadlink RMs and assign each
|
|
41
|
-
accessory to whichever one it's actually near.
|
|
42
|
-
- **Basic accessories** power on/off via a hex signal.
|
|
43
|
-
- **Dimmer lights** one hex signal per discrete brightness level
|
|
44
|
-
- **TVs** power on/off plus a usable remote (arrows, select, back, exit, info,
|
|
45
|
-
volume, mute) in the iOS Remote app
|
|
46
|
-
- **Temperature/humidity sensor** polls the RM every 60 seconds, on by default.
|
|
47
|
-
- **ntfy.sh notifications** optional push notification the first time an RM
|
|
48
|
-
device fails to connect.
|
|
49
|
-
- Fully configurable via the Homebridge Config UI X plugin settings form.
|
|
50
|
-
|
|
51
|
-
### Configuration
|
|
23
|
+
- **Multiple RM devices** configure several Broadlink RMs and assign each accessory to whichever one
|
|
24
|
+
- **Basic accessories** power on/off
|
|
25
|
+
- **Dimmer lights** one signal per discrete brightness level
|
|
26
|
+
- **TVs** power on/off plus a usable remote in the iOS Remote app
|
|
27
|
+
- **Temperature/humidity sensor** optionally expose sensor data
|
|
28
|
+
- **ntfy.sh notifications** push notification when a RM fails to connect
|
|
29
|
+
- **MQTT publishing** optionally publish sensor data to a MQTT broker
|
|
30
|
+
- Fully configurable via the Homebridge Config UI X plugin settings form
|
|
31
|
+
|
|
32
|
+
## Configuration
|
|
52
33
|
|
|
53
34
|
This plugin can be fully configured from the Homebridge Config UI X plugin
|
|
54
35
|
settings form.
|
|
55
36
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
If you'd rather edit the config file directly, here's an example
|
|
59
|
-
`config.json` platform block:
|
|
60
|
-
|
|
61
|
-
```json
|
|
62
|
-
{
|
|
63
|
-
"platform": "BroadlinkRMBlaster",
|
|
64
|
-
"ntfyTopic": "my-homebridge-alerts",
|
|
65
|
-
"rmDevices": [
|
|
66
|
-
{
|
|
67
|
-
"name": "Default RM",
|
|
68
|
-
"ip": "192.168.1.50",
|
|
69
|
-
"enableTemperatureHumidity": true
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
"name": "Bedroom RM",
|
|
73
|
-
"ip": "192.168.1.60"
|
|
74
|
-
}
|
|
75
|
-
],
|
|
76
|
-
"accessories": [
|
|
77
|
-
{
|
|
78
|
-
"name": "Living Room Lamp",
|
|
79
|
-
"rmDevice": "Default RM",
|
|
80
|
-
"accessoryType": "light",
|
|
81
|
-
"powerOnCode": "2600...",
|
|
82
|
-
"powerOffCode": "2600..."
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
"name": "Fan",
|
|
86
|
-
"rmDevice": "Bedroom RM",
|
|
87
|
-
"accessoryType": "fan",
|
|
88
|
-
"powerOnCode": "2600..."
|
|
89
|
-
}
|
|
90
|
-
],
|
|
91
|
-
"dimmers": [
|
|
92
|
-
{
|
|
93
|
-
"name": "Bedroom Dimmer",
|
|
94
|
-
"rmDevice": "Bedroom RM",
|
|
95
|
-
"powerOnCode": "2600...",
|
|
96
|
-
"powerOffCode": "2600...",
|
|
97
|
-
"zeroPercentCode": "2600...",
|
|
98
|
-
"hundredPercentCode": "2600...",
|
|
99
|
-
"debounceSeconds": 0.5,
|
|
100
|
-
"useLastKnownBrightness": true,
|
|
101
|
-
"useDefaultBrightnessLevel": true,
|
|
102
|
-
"defaultBrightnessLevel": 75,
|
|
103
|
-
"useMaxBrightnessLevel": true,
|
|
104
|
-
"maxBrightnessLevel": 50,
|
|
105
|
-
"levels": [
|
|
106
|
-
{ "level": 25, "code": "2600..." },
|
|
107
|
-
{ "level": 50, "code": "2600..." },
|
|
108
|
-
{ "level": 75, "code": "2600..." }
|
|
109
|
-
]
|
|
110
|
-
}
|
|
111
|
-
],
|
|
112
|
-
"tvs": [
|
|
113
|
-
{
|
|
114
|
-
"name": "Living Room TV",
|
|
115
|
-
"rmDevice": "Default RM",
|
|
116
|
-
"powerOnCode": "2600...",
|
|
117
|
-
"volumeUpCode": "2600...",
|
|
118
|
-
"volumeDownCode": "2600...",
|
|
119
|
-
"muteCode": "2600...",
|
|
120
|
-
"arrowUpCode": "2600...",
|
|
121
|
-
"selectCode": "2600..."
|
|
122
|
-
}
|
|
123
|
-
]
|
|
124
|
-
}
|
|
125
|
-
```
|
|
37
|
+
## Debugging
|
|
126
38
|
|
|
127
|
-
|
|
128
|
-
`https://ntfy.sh/<topic>` the first time a given RM device fails to
|
|
129
|
-
connect - subscribe to the same topic in the [ntfy](https://ntfy.sh) app to
|
|
130
|
-
receive it. Only fires once per outage; it resets once that device
|
|
131
|
-
connects successfully again. The temperature/humidity sensor also triggers
|
|
132
|
-
this after 5 consecutive failed readings (see below), reusing the same
|
|
133
|
-
once-per-outage behavior.
|
|
134
|
-
- `rmDevices`: at least one required. Each needs a unique `name` and `ip`;
|
|
135
|
-
`enableTemperatureHumidity` (defaults to `true`) adds a temperature/humidity
|
|
136
|
-
sensor accessory for that specific device. If a reading fails 5 times in a
|
|
137
|
-
row, the sensor shows "No Response" in Home (rather than a frozen stale
|
|
138
|
-
value) and, if `ntfyTopic` is set, sends a notification.
|
|
139
|
-
- `rmDevice` on every accessory/dimmer/TV below is a plain text field that
|
|
140
|
-
must exactly match the `name` of one of the devices above. There's no
|
|
141
|
-
live dropdown, since Homebridge's config UI can't populate one from
|
|
142
|
-
sibling array data. Save your RM devices first, then reference them by
|
|
143
|
-
name; a typo just makes that accessory get skipped with a warning in the
|
|
144
|
-
log rather than silently misbehaving.
|
|
145
|
-
- `accessories[].powerOffCode`: optional; if omitted, the power-on signal is
|
|
146
|
-
reused for both on and off (useful for toggle-only remotes).
|
|
147
|
-
- `dimmers[].powerOnCode` / `powerOffCode`: required fields, but currently
|
|
148
|
-
unused by the plugin - power on/off is done with the resolved brightness
|
|
149
|
-
level and `zeroPercentCode` instead, as an ongoing experiment to reduce RF
|
|
150
|
-
traffic. Still required so this can be reverted without a config change.
|
|
151
|
-
- `dimmers[].defaultBrightnessLevel` / `maxBrightnessLevel`: independent target
|
|
152
|
-
percentages, not tied to a specific configured level. The nearest configured
|
|
153
|
-
signal is sent, but the percentage shown in Home stays the configured target.
|
|
154
|
-
- `dimmers[].hundredPercentCode`: required, like `zeroPercentCode`: the true,
|
|
155
|
-
uncapped 100% signal, always reachable regardless of any max brightness cap.
|
|
156
|
-
- `dimmers[].debounceSeconds`: defaults to `0.5`. A slider drag fires many
|
|
157
|
-
rapid updates; the actual signal only sends after this long of no movement.
|
|
158
|
-
- `tvs[].powerOnCode` is the only required TV field. Everything else
|
|
159
|
-
(`powerOffCode`, `volumeUpCode`/`volumeDownCode`, `muteCode`,
|
|
160
|
-
`arrowUpCode`/`arrowDownCode`/`arrowLeftCode`/`arrowRightCode`,
|
|
161
|
-
`selectCode`, `infoCode`, `backCode`, `exitCode`) is optional; pressing a
|
|
162
|
-
remote button with no signal configured for it just does nothing.
|
|
163
|
-
`muteCode` is sent as-is for both muting and unmuting, since most remotes
|
|
164
|
-
use a single toggle button rather than distinct on/off signals.
|
|
165
|
-
|
|
166
|
-
### Debugging
|
|
167
|
-
|
|
168
|
-
To send a single hex code straight to your RM, bypassing Homebridge/HomeKit
|
|
169
|
-
entirely (useful for isolating whether a signal behaves oddly on the device
|
|
170
|
-
itself vs. through the plugin), run this in the Homebridge Config UI X
|
|
171
|
-
terminal:
|
|
39
|
+
To send a single hex code straight to your RM, bypassing Homebridge/HomeKit entirely run this in the Homebridge shell:
|
|
172
40
|
|
|
173
41
|
```bash
|
|
174
42
|
broadlink-rm-blaster <ip> <hexCode>
|
|
@@ -182,4 +50,6 @@ Inspired by [homebridge-broadlink-rm](https://github.com/kiwi-cam/homebridge-bro
|
|
|
182
50
|
built on [kiwicam-broadlinkjs-rm](https://www.npmjs.com/package/kiwicam-broadlinkjs-rm)
|
|
183
51
|
for the underlying device communication.
|
|
184
52
|
|
|
53
|
+
## Links
|
|
54
|
+
|
|
185
55
|
[LICENSE](https://github.com/LuudJacobs/homebridge-broadlink-rm-blaster/blob/main/LICENSE) · [CHANGELOG](https://github.com/LuudJacobs/homebridge-broadlink-rm-blaster/blob/main/CHANGELOG.md)
|
package/config.schema.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"pluginAlias": "BroadlinkRMBlaster",
|
|
3
3
|
"pluginType": "platform",
|
|
4
4
|
"singular": true,
|
|
5
|
-
"headerDisplay": "Blasts pre-recorded IR/RF hex signals via a Broadlink RM.
|
|
5
|
+
"headerDisplay": "Blasts pre-recorded IR/RF hex signals via a Broadlink RM.",
|
|
6
6
|
"schema": {
|
|
7
7
|
"type": "object",
|
|
8
8
|
"properties": {
|
|
@@ -10,7 +10,60 @@
|
|
|
10
10
|
"title": "ntfy.sh Notification Topic",
|
|
11
11
|
"type": "string",
|
|
12
12
|
"required": false,
|
|
13
|
-
"description": "
|
|
13
|
+
"description": "If set, sends a push notification via ntfy.sh the first time an RM device fails to connect, or after 5 consecutive failed temperature/humidity readings."
|
|
14
|
+
},
|
|
15
|
+
"enableMqtt": {
|
|
16
|
+
"title": "Enable MQTT",
|
|
17
|
+
"type": "boolean",
|
|
18
|
+
"default": false,
|
|
19
|
+
"required": false,
|
|
20
|
+
"description": "Publish temperature/humidity readings from RM devices to an MQTT broker."
|
|
21
|
+
},
|
|
22
|
+
"mqttHost": {
|
|
23
|
+
"title": "Host",
|
|
24
|
+
"type": "string",
|
|
25
|
+
"default": "localhost",
|
|
26
|
+
"required": false,
|
|
27
|
+
"description": "Broker hostname or IP address.",
|
|
28
|
+
"condition": {
|
|
29
|
+
"functionBody": "return model.enableMqtt === true;"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"mqttPort": {
|
|
33
|
+
"title": "Port",
|
|
34
|
+
"type": "integer",
|
|
35
|
+
"default": 1883,
|
|
36
|
+
"required": false,
|
|
37
|
+
"condition": {
|
|
38
|
+
"functionBody": "return model.enableMqtt === true;"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"mqttUsername": {
|
|
42
|
+
"title": "Username",
|
|
43
|
+
"type": "string",
|
|
44
|
+
"required": false,
|
|
45
|
+
"condition": {
|
|
46
|
+
"functionBody": "return model.enableMqtt === true;"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"mqttPassword": {
|
|
50
|
+
"title": "Password",
|
|
51
|
+
"type": "string",
|
|
52
|
+
"required": false,
|
|
53
|
+
"condition": {
|
|
54
|
+
"functionBody": "return model.enableMqtt === true;"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"mqttBaseTopic": {
|
|
58
|
+
"title": "Base Topic",
|
|
59
|
+
"type": "string",
|
|
60
|
+
"default": "broadlinkrm",
|
|
61
|
+
"placeholder": "broadlinkrm",
|
|
62
|
+
"required": false,
|
|
63
|
+
"description": "Readings are published to <base topic>/<device name>. For example, with the default base topic, a device named \"Blaster\" publishes to \"broadlinkrm/blaster\".",
|
|
64
|
+
"condition": {
|
|
65
|
+
"functionBody": "return model.enableMqtt === true;"
|
|
66
|
+
}
|
|
14
67
|
},
|
|
15
68
|
"rmDevices": {
|
|
16
69
|
"title": "Broadlink RM Devices",
|
|
@@ -24,7 +77,6 @@
|
|
|
24
77
|
"title": "Name",
|
|
25
78
|
"type": "string",
|
|
26
79
|
"required": true,
|
|
27
|
-
"default": "Default RM",
|
|
28
80
|
"description": "Referenced by name from each accessory below - must be unique."
|
|
29
81
|
},
|
|
30
82
|
"ip": {
|
|
@@ -34,17 +86,24 @@
|
|
|
34
86
|
"required": true
|
|
35
87
|
},
|
|
36
88
|
"enableTemperatureHumidity": {
|
|
37
|
-
"title": "
|
|
89
|
+
"title": "HomeKit thermometer accessory",
|
|
90
|
+
"type": "boolean",
|
|
91
|
+
"default": false,
|
|
92
|
+
"required": false,
|
|
93
|
+
"description": "Exposes this device's temperature/humidity as a HomeKit thermometer accessory."
|
|
94
|
+
},
|
|
95
|
+
"enableMqttPublish": {
|
|
96
|
+
"title": "Publish temperature and humidity to MQTT",
|
|
38
97
|
"type": "boolean",
|
|
39
|
-
"default":
|
|
98
|
+
"default": false,
|
|
40
99
|
"required": false,
|
|
41
|
-
"description": "
|
|
100
|
+
"description": "Requires MQTT to be enabled and configured below"
|
|
42
101
|
}
|
|
43
102
|
}
|
|
44
103
|
}
|
|
45
104
|
},
|
|
46
105
|
"accessories": {
|
|
47
|
-
"title": "Accessories",
|
|
106
|
+
"title": "Basic Accessories",
|
|
48
107
|
"type": "array",
|
|
49
108
|
"items": {
|
|
50
109
|
"type": "object",
|
|
@@ -58,8 +117,7 @@
|
|
|
58
117
|
"title": "RM Device",
|
|
59
118
|
"type": "string",
|
|
60
119
|
"required": true,
|
|
61
|
-
"
|
|
62
|
-
"description": "Must match the Name of one of the RM devices configured above."
|
|
120
|
+
"description": "Must match the name of one of the configured RM devices exactly."
|
|
63
121
|
},
|
|
64
122
|
"accessoryType": {
|
|
65
123
|
"title": "Accessory Type",
|
|
@@ -76,14 +134,12 @@
|
|
|
76
134
|
"powerOnCode": {
|
|
77
135
|
"title": "Power On Signal",
|
|
78
136
|
"type": "string",
|
|
79
|
-
"required": true
|
|
80
|
-
"description": "Hex code sent to turn the accessory on."
|
|
137
|
+
"required": true
|
|
81
138
|
},
|
|
82
139
|
"powerOffCode": {
|
|
83
|
-
"title": "Power Off Signal",
|
|
140
|
+
"title": "Power Off Signal (leave empty to use Power On Signal)",
|
|
84
141
|
"type": "string",
|
|
85
|
-
"required": false
|
|
86
|
-
"description": "Hex code sent to turn the accessory off. Leave empty to reuse the Power On signal (useful for toggle-only remotes)."
|
|
142
|
+
"required": false
|
|
87
143
|
}
|
|
88
144
|
}
|
|
89
145
|
}
|
|
@@ -103,26 +159,22 @@
|
|
|
103
159
|
"title": "RM Device",
|
|
104
160
|
"type": "string",
|
|
105
161
|
"required": true,
|
|
106
|
-
"
|
|
107
|
-
"description": "Must match the Name of one of the RM devices configured above."
|
|
162
|
+
"description": "Must match the name of one of the configured RM devices exactly."
|
|
108
163
|
},
|
|
109
164
|
"powerOnCode": {
|
|
110
165
|
"title": "Power On Signal",
|
|
111
166
|
"type": "string",
|
|
112
|
-
"required": true
|
|
113
|
-
"description": "Hex code sent to turn the light on. Always used for powering on, regardless of the resolved brightness level."
|
|
167
|
+
"required": true
|
|
114
168
|
},
|
|
115
169
|
"powerOffCode": {
|
|
116
170
|
"title": "Power Off Signal",
|
|
117
171
|
"type": "string",
|
|
118
|
-
"required": true
|
|
119
|
-
"description": "Hex code sent to turn the light off. Always used, instead of the Brightness 0% signal."
|
|
172
|
+
"required": true
|
|
120
173
|
},
|
|
121
174
|
"useLastKnownBrightness": {
|
|
122
175
|
"title": "Use Last Known Brightness",
|
|
123
176
|
"type": "boolean",
|
|
124
|
-
"required": false
|
|
125
|
-
"description": "When turning on, restore the last brightness this light was set to instead of a default/max/highest level."
|
|
177
|
+
"required": false
|
|
126
178
|
},
|
|
127
179
|
"useDefaultBrightnessLevel": {
|
|
128
180
|
"title": "Set Default Brightness Level",
|
|
@@ -142,10 +194,9 @@
|
|
|
142
194
|
}
|
|
143
195
|
},
|
|
144
196
|
"useMaxBrightnessLevel": {
|
|
145
|
-
"title": "
|
|
197
|
+
"title": "Cap Maximum Brightness Level",
|
|
146
198
|
"type": "boolean",
|
|
147
|
-
"required": false
|
|
148
|
-
"description": "Caps and remaps the 0-100% slider onto this percentage."
|
|
199
|
+
"required": false
|
|
149
200
|
},
|
|
150
201
|
"maxBrightnessLevel": {
|
|
151
202
|
"title": "Max Brightness Level (%)",
|
|
@@ -161,14 +212,12 @@
|
|
|
161
212
|
"zeroPercentCode": {
|
|
162
213
|
"title": "Brightness 0% Signal",
|
|
163
214
|
"type": "string",
|
|
164
|
-
"required": true
|
|
165
|
-
"description": "Hex code for the lowest (0%) brightness level."
|
|
215
|
+
"required": true
|
|
166
216
|
},
|
|
167
217
|
"hundredPercentCode": {
|
|
168
218
|
"title": "Brightness 100% Signal",
|
|
169
219
|
"type": "string",
|
|
170
|
-
"required": true
|
|
171
|
-
"description": "Hex code for true 100% brightness. Always the actual full-brightness signal, regardless of any max brightness cap set above."
|
|
220
|
+
"required": true
|
|
172
221
|
},
|
|
173
222
|
"debounceSeconds": {
|
|
174
223
|
"title": "Debounce (seconds)",
|
|
@@ -176,7 +225,7 @@
|
|
|
176
225
|
"minimum": 0,
|
|
177
226
|
"default": 0.5,
|
|
178
227
|
"required": false,
|
|
179
|
-
"description": "Wait this long after the slider stops moving before sending a signal
|
|
228
|
+
"description": "Wait this long after the slider stops moving before sending a signal"
|
|
180
229
|
},
|
|
181
230
|
"levels": {
|
|
182
231
|
"title": "Brightness Levels",
|
|
@@ -218,20 +267,17 @@
|
|
|
218
267
|
"title": "RM Device",
|
|
219
268
|
"type": "string",
|
|
220
269
|
"required": true,
|
|
221
|
-
"
|
|
222
|
-
"description": "Must match the Name of one of the RM devices configured above."
|
|
270
|
+
"description": "Must match the name of one of the configured RM devices exactly."
|
|
223
271
|
},
|
|
224
272
|
"powerOnCode": {
|
|
225
273
|
"title": "Power On Signal",
|
|
226
274
|
"type": "string",
|
|
227
|
-
"required": true
|
|
228
|
-
"description": "Hex code sent to turn the TV on."
|
|
275
|
+
"required": true
|
|
229
276
|
},
|
|
230
277
|
"powerOffCode": {
|
|
231
|
-
"title": "Power Off Signal",
|
|
278
|
+
"title": "Power Off Signal (leave empty to use Power On Signal)",
|
|
232
279
|
"type": "string",
|
|
233
|
-
"required": false
|
|
234
|
-
"description": "Hex code sent to turn the TV off. Leave empty to reuse the Power On signal (useful for toggle-only remotes)."
|
|
280
|
+
"required": false
|
|
235
281
|
},
|
|
236
282
|
"volumeUpCode": {
|
|
237
283
|
"title": "Volume Up Signal",
|
|
@@ -246,8 +292,7 @@
|
|
|
246
292
|
"muteCode": {
|
|
247
293
|
"title": "Mute Signal",
|
|
248
294
|
"type": "string",
|
|
249
|
-
"required": false
|
|
250
|
-
"description": "Most remotes use a single toggle button for mute - the same signal is sent whether muting or unmuting."
|
|
295
|
+
"required": false
|
|
251
296
|
},
|
|
252
297
|
"arrowUpCode": {
|
|
253
298
|
"title": "Arrow Up Signal",
|
|
@@ -295,7 +340,6 @@
|
|
|
295
340
|
}
|
|
296
341
|
},
|
|
297
342
|
"layout": [
|
|
298
|
-
"ntfyTopic",
|
|
299
343
|
{
|
|
300
344
|
"type": "array",
|
|
301
345
|
"key": "rmDevices",
|
|
@@ -303,13 +347,33 @@
|
|
|
303
347
|
"items": [
|
|
304
348
|
"rmDevices[].name",
|
|
305
349
|
"rmDevices[].ip",
|
|
306
|
-
"rmDevices[].enableTemperatureHumidity"
|
|
350
|
+
"rmDevices[].enableTemperatureHumidity",
|
|
351
|
+
"rmDevices[].enableMqttPublish"
|
|
352
|
+
]
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
"type": "fieldset",
|
|
356
|
+
"title": "MQTT",
|
|
357
|
+
"expandable": true,
|
|
358
|
+
"expanded": false,
|
|
359
|
+
"items": [
|
|
360
|
+
"enableMqtt",
|
|
361
|
+
"mqttHost",
|
|
362
|
+
"mqttPort",
|
|
363
|
+
"mqttUsername",
|
|
364
|
+
{
|
|
365
|
+
"key": "mqttPassword",
|
|
366
|
+
"type": "password"
|
|
367
|
+
},
|
|
368
|
+
"mqttBaseTopic"
|
|
307
369
|
]
|
|
308
370
|
},
|
|
309
371
|
{
|
|
310
372
|
"type": "array",
|
|
311
373
|
"key": "accessories",
|
|
312
|
-
"title": "Accessories",
|
|
374
|
+
"title": "Basic Accessories",
|
|
375
|
+
"expandable": true,
|
|
376
|
+
"expanded": false,
|
|
313
377
|
"items": [
|
|
314
378
|
"accessories[].name",
|
|
315
379
|
"accessories[].rmDevice",
|
|
@@ -322,6 +386,8 @@
|
|
|
322
386
|
"type": "array",
|
|
323
387
|
"key": "dimmers",
|
|
324
388
|
"title": "Dimmer Lights",
|
|
389
|
+
"expandable": true,
|
|
390
|
+
"expanded": false,
|
|
325
391
|
"items": [
|
|
326
392
|
"dimmers[].name",
|
|
327
393
|
"dimmers[].rmDevice",
|
|
@@ -339,6 +405,8 @@
|
|
|
339
405
|
"type": "array",
|
|
340
406
|
"key": "dimmers[].levels",
|
|
341
407
|
"title": "Brightness Levels",
|
|
408
|
+
"expandable": true,
|
|
409
|
+
"expanded": false,
|
|
342
410
|
"items": [
|
|
343
411
|
"dimmers[].levels[].level",
|
|
344
412
|
"dimmers[].levels[].code"
|
|
@@ -350,6 +418,8 @@
|
|
|
350
418
|
"type": "array",
|
|
351
419
|
"key": "tvs",
|
|
352
420
|
"title": "TVs",
|
|
421
|
+
"expandable": true,
|
|
422
|
+
"expanded": false,
|
|
353
423
|
"items": [
|
|
354
424
|
"tvs[].name",
|
|
355
425
|
"tvs[].rmDevice",
|
|
@@ -367,6 +437,15 @@
|
|
|
367
437
|
"tvs[].backCode",
|
|
368
438
|
"tvs[].exitCode"
|
|
369
439
|
]
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
"type": "fieldset",
|
|
443
|
+
"title": "Notifications",
|
|
444
|
+
"expandable": true,
|
|
445
|
+
"expanded": true,
|
|
446
|
+
"items": [
|
|
447
|
+
"ntfyTopic"
|
|
448
|
+
]
|
|
370
449
|
}
|
|
371
450
|
]
|
|
372
451
|
}
|
|
@@ -5,8 +5,10 @@ export declare class TemperatureHumiditySensorAccessory {
|
|
|
5
5
|
private readonly accessory;
|
|
6
6
|
private readonly ip;
|
|
7
7
|
private readonly name;
|
|
8
|
+
private readonly deviceName;
|
|
9
|
+
private readonly publishToMqtt;
|
|
8
10
|
private consecutiveFailures;
|
|
9
|
-
constructor(platform: BroadlinkRMBlasterPlatform, accessory: PlatformAccessory, ip: string, name: string);
|
|
11
|
+
constructor(platform: BroadlinkRMBlasterPlatform, accessory: PlatformAccessory | undefined, ip: string, name: string, deviceName: string, publishToMqtt: boolean);
|
|
10
12
|
private getTemperature;
|
|
11
13
|
private getHumidity;
|
|
12
14
|
private throwNoResponse;
|
|
@@ -11,22 +11,28 @@ class TemperatureHumiditySensorAccessory {
|
|
|
11
11
|
accessory;
|
|
12
12
|
ip;
|
|
13
13
|
name;
|
|
14
|
+
deviceName;
|
|
15
|
+
publishToMqtt;
|
|
14
16
|
consecutiveFailures = 0;
|
|
15
|
-
constructor(platform, accessory, ip, name) {
|
|
17
|
+
constructor(platform, accessory, ip, name, deviceName, publishToMqtt) {
|
|
16
18
|
this.platform = platform;
|
|
17
19
|
this.accessory = accessory;
|
|
18
20
|
this.ip = ip;
|
|
19
21
|
this.name = name;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
this.deviceName = deviceName;
|
|
23
|
+
this.publishToMqtt = publishToMqtt;
|
|
24
|
+
if (this.accessory) {
|
|
25
|
+
const temperatureService = this.accessory.getService(this.platform.Service.TemperatureSensor)
|
|
26
|
+
?? this.accessory.addService(this.platform.Service.TemperatureSensor);
|
|
27
|
+
temperatureService.setCharacteristic(this.platform.Characteristic.Name, this.name);
|
|
28
|
+
temperatureService.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
|
|
29
|
+
.onGet(() => this.getTemperature());
|
|
30
|
+
const humidityService = this.accessory.getService(this.platform.Service.HumiditySensor)
|
|
31
|
+
?? this.accessory.addService(this.platform.Service.HumiditySensor);
|
|
32
|
+
humidityService.setCharacteristic(this.platform.Characteristic.Name, this.name);
|
|
33
|
+
humidityService.getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity)
|
|
34
|
+
.onGet(() => this.getHumidity());
|
|
35
|
+
}
|
|
30
36
|
// Not all RM units actually report real sensor data ("if available" in
|
|
31
37
|
// the todo) - an immediate poll plus a recurring one lets a supported unit
|
|
32
38
|
// start reporting quickly, while an unsupported one just keeps failing
|
|
@@ -35,14 +41,14 @@ class TemperatureHumiditySensorAccessory {
|
|
|
35
41
|
setInterval(() => this.poll(), POLL_INTERVAL_MS);
|
|
36
42
|
}
|
|
37
43
|
getTemperature() {
|
|
38
|
-
const temperature = this.accessory
|
|
44
|
+
const temperature = this.accessory?.context.temperature;
|
|
39
45
|
if (temperature === undefined) {
|
|
40
46
|
this.throwNoResponse();
|
|
41
47
|
}
|
|
42
48
|
return temperature;
|
|
43
49
|
}
|
|
44
50
|
getHumidity() {
|
|
45
|
-
const humidity = this.accessory
|
|
51
|
+
const humidity = this.accessory?.context.humidity;
|
|
46
52
|
if (humidity === undefined) {
|
|
47
53
|
this.throwNoResponse();
|
|
48
54
|
}
|
|
@@ -57,20 +63,27 @@ class TemperatureHumiditySensorAccessory {
|
|
|
57
63
|
const { temperature, humidity } = await this.platform.broadlinkClient.readTemperatureHumidity(this.ip);
|
|
58
64
|
this.consecutiveFailures = 0;
|
|
59
65
|
this.platform.notifier.notifyConnectionRecovered(this.ip);
|
|
60
|
-
this.accessory
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
if (this.accessory) {
|
|
67
|
+
this.accessory.context.temperature = temperature;
|
|
68
|
+
this.accessory.context.humidity = humidity;
|
|
69
|
+
this.accessory.getService(this.platform.Service.TemperatureSensor)
|
|
70
|
+
?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, temperature);
|
|
71
|
+
this.accessory.getService(this.platform.Service.HumiditySensor)
|
|
72
|
+
?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, humidity);
|
|
73
|
+
}
|
|
74
|
+
if (this.publishToMqtt) {
|
|
75
|
+
this.platform.mqttPublisher.publishReading(this.deviceName, temperature, humidity);
|
|
76
|
+
}
|
|
66
77
|
}
|
|
67
78
|
catch (error) {
|
|
68
79
|
this.platform.log.warn(`Failed to read temperature/humidity from ${this.ip}: ${error.message}`);
|
|
69
80
|
this.consecutiveFailures++;
|
|
70
81
|
if (this.consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
|
|
71
|
-
this.accessory
|
|
72
|
-
|
|
73
|
-
|
|
82
|
+
if (this.accessory) {
|
|
83
|
+
this.accessory.context.temperature = undefined;
|
|
84
|
+
this.accessory.context.humidity = undefined;
|
|
85
|
+
}
|
|
86
|
+
this.platform.notifier.notifyConnectionFailure(this.ip, 'Timed out reading temperature and humidity. Check Homebridge logs for more details.');
|
|
74
87
|
}
|
|
75
88
|
}
|
|
76
89
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"temperatureHumiditySensorAccessory.js","sourceRoot":"","sources":["../../src/accessories/temperatureHumiditySensorAccessory.ts"],"names":[],"mappings":";;;AAIA,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC,6EAA6E;AAC7E,6EAA6E;AAC7E,2EAA2E;AAC3E,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAEnC,MAAa,kCAAkC;IAI1B;IACA;IACA;IACA;
|
|
1
|
+
{"version":3,"file":"temperatureHumiditySensorAccessory.js","sourceRoot":"","sources":["../../src/accessories/temperatureHumiditySensorAccessory.ts"],"names":[],"mappings":"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"}
|
package/dist/broadlinkClient.js
CHANGED
|
@@ -58,7 +58,7 @@ class BroadlinkClient {
|
|
|
58
58
|
const timeout = setTimeout(() => {
|
|
59
59
|
broadlink.removeListener('deviceReady', onReady);
|
|
60
60
|
const error = new Error(`Timed out authenticating with Broadlink RM at ${ip}`);
|
|
61
|
-
this.notifier?.notifyConnectionFailure(ip,
|
|
61
|
+
this.notifier?.notifyConnectionFailure(ip, 'Timed out authenticating with Broadlink RM. Check Homebridge logs for more details.');
|
|
62
62
|
reject(error);
|
|
63
63
|
}, AUTH_TIMEOUT_MS);
|
|
64
64
|
const onReady = (device) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broadlinkClient.js","sourceRoot":"","sources":["../src/broadlinkClient.ts"],"names":[],"mappings":";;;;;;AAWA,oCAEC;AAbD,oFAA2D;AAI3D,8EAA8E;AAC9E,2EAA2E;AAC3E,MAAM,qBAAqB,GAAG,MAAM,CAAC;AACrC,MAAM,cAAc,GAAG,EAAE,CAAC;AAC1B,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,MAAM,eAAe,GAAG,MAAM,CAAC;AAE/B,SAAgB,YAAY,CAAC,OAAe;IAC1C,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;AACzD,CAAC;AAED,6EAA6E;AAC7E,2EAA2E;AAC3E,yEAAyE;AACzE,0EAA0E;AAC1E,uEAAuE;AACvE,4EAA4E;AAC5E,+BAA+B;AAC/B,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAO3C,MAAa,eAAe;IAYG;IAA8B;IAX3D,uEAAuE;IACvE,yEAAyE;IACzE,0EAA0E;IAC1E,mEAAmE;IACnE,mEAAmE;IACnE,yEAAyE;IACzE,qEAAqE;IACrE,iDAAiD;IAChC,kBAAkB,GAAG,IAAI,GAAG,EAAqB,CAAC;IAClD,OAAO,GAAG,IAAI,GAAG,EAA2B,CAAC;IAE9D,YAA6B,GAAW,EAAmB,QAAuB;QAArD,QAAG,GAAH,GAAG,CAAQ;QAAmB,aAAQ,GAAR,QAAQ,CAAe;IAAG,CAAC;IAE9E,YAAY,CAAC,EAAU;QAC7B,IAAI,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG,IAAI,gCAAS,EAAE,CAAC;YAC3B,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEO,SAAS,CAAC,EAAU;QAC1B,IAAI,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzC,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO,aAAa,CAAC;QACvB,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAExC,aAAa,GAAG,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACtD,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC9B,SAAS,CAAC,cAAc,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;gBACjD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,iDAAiD,EAAE,EAAE,CAAC,CAAC;gBAC/E,IAAI,CAAC,QAAQ,EAAE,uBAAuB,
|
|
1
|
+
{"version":3,"file":"broadlinkClient.js","sourceRoot":"","sources":["../src/broadlinkClient.ts"],"names":[],"mappings":"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"}
|
package/dist/configTypes.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export interface RmDeviceConfig {
|
|
|
3
3
|
name: string;
|
|
4
4
|
ip: string;
|
|
5
5
|
enableTemperatureHumidity?: boolean;
|
|
6
|
+
enableMqttPublish?: boolean;
|
|
6
7
|
}
|
|
7
8
|
export type BasicAccessoryType = 'light' | 'switch' | 'outlet' | 'fan';
|
|
8
9
|
export interface BasicAccessoryConfig {
|
|
@@ -54,4 +55,10 @@ export interface BlasterPlatformConfig extends PlatformConfig {
|
|
|
54
55
|
dimmers?: DimmerAccessoryConfig[];
|
|
55
56
|
tvs?: TvAccessoryConfig[];
|
|
56
57
|
ntfyTopic?: string;
|
|
58
|
+
enableMqtt?: boolean;
|
|
59
|
+
mqttHost?: string;
|
|
60
|
+
mqttPort?: number;
|
|
61
|
+
mqttUsername?: string;
|
|
62
|
+
mqttPassword?: string;
|
|
63
|
+
mqttBaseTopic?: string;
|
|
57
64
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Logger } from 'homebridge';
|
|
2
|
+
export declare const DEFAULT_MQTT_BASE_TOPIC = "broadlinkrm";
|
|
3
|
+
export declare function buildTopic(baseTopic: string, deviceName: string): string;
|
|
4
|
+
export declare class MqttPublisher {
|
|
5
|
+
private readonly log;
|
|
6
|
+
private readonly baseTopic;
|
|
7
|
+
private client?;
|
|
8
|
+
private loggedConnectionError;
|
|
9
|
+
constructor(log: Logger, enabled: boolean, host: string | undefined, port: number | undefined, baseTopic: string, username?: string, password?: string);
|
|
10
|
+
publishReading(deviceName: string, temperature: number, humidity: number): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MqttPublisher = exports.DEFAULT_MQTT_BASE_TOPIC = void 0;
|
|
7
|
+
exports.buildTopic = buildTopic;
|
|
8
|
+
const mqtt_1 = __importDefault(require("mqtt"));
|
|
9
|
+
exports.DEFAULT_MQTT_BASE_TOPIC = 'broadlinkrm';
|
|
10
|
+
function buildTopic(baseTopic, deviceName) {
|
|
11
|
+
const slug = deviceName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
12
|
+
return `${baseTopic}/${slug}`;
|
|
13
|
+
}
|
|
14
|
+
// Publishes sensor readings to MQTT so other plugins (e.g. homebridge-mqttthing)
|
|
15
|
+
// can subscribe to them independently of HomeKit. Mirrors NtfyNotifier: a total
|
|
16
|
+
// no-op unless enabled with a host/port, and never lets a connection/publish
|
|
17
|
+
// failure crash or affect the rest of the plugin.
|
|
18
|
+
class MqttPublisher {
|
|
19
|
+
log;
|
|
20
|
+
baseTopic;
|
|
21
|
+
client;
|
|
22
|
+
loggedConnectionError = false;
|
|
23
|
+
constructor(log, enabled, host, port, baseTopic, username, password) {
|
|
24
|
+
this.log = log;
|
|
25
|
+
this.baseTopic = baseTopic;
|
|
26
|
+
if (!enabled || !host || !port) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
this.client = mqtt_1.default.connect(`mqtt://${host}:${port}`, { username, password });
|
|
30
|
+
this.client.on('error', (error) => {
|
|
31
|
+
if (!this.loggedConnectionError) {
|
|
32
|
+
this.log.warn(`MQTT connection error: ${error.message}`);
|
|
33
|
+
this.loggedConnectionError = true;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
this.client.on('connect', () => {
|
|
37
|
+
this.loggedConnectionError = false;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
publishReading(deviceName, temperature, humidity) {
|
|
41
|
+
if (!this.client) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const topic = buildTopic(this.baseTopic, deviceName);
|
|
45
|
+
this.client.publish(topic, JSON.stringify({ temperature, humidity }), { retain: true }, (error) => {
|
|
46
|
+
if (error) {
|
|
47
|
+
this.log.warn(`Failed to publish MQTT reading: ${error.message}`);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.MqttPublisher = MqttPublisher;
|
|
53
|
+
//# sourceMappingURL=mqttPublisher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mqttPublisher.js","sourceRoot":"","sources":["../src/mqttPublisher.ts"],"names":[],"mappings":";;;;;;AAKA,gCAGC;AARD,gDAAwC;AAG3B,QAAA,uBAAuB,GAAG,aAAa,CAAC;AAErD,SAAgB,UAAU,CAAC,SAAiB,EAAE,UAAkB;IAC9D,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC1F,OAAO,GAAG,SAAS,IAAI,IAAI,EAAE,CAAC;AAChC,CAAC;AAED,iFAAiF;AACjF,gFAAgF;AAChF,6EAA6E;AAC7E,kDAAkD;AAClD,MAAa,aAAa;IAKL;IAIA;IARX,MAAM,CAAc;IACpB,qBAAqB,GAAG,KAAK,CAAC;IAEtC,YACmB,GAAW,EAC5B,OAAgB,EAChB,IAAwB,EACxB,IAAwB,EACP,SAAiB,EAClC,QAAiB,EACjB,QAAiB;QANA,QAAG,GAAH,GAAG,CAAQ;QAIX,cAAS,GAAT,SAAS,CAAQ;QAIlC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,cAAI,CAAC,OAAO,CAAC,UAAU,IAAI,IAAI,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC7E,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAChC,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAChC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,0BAA0B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBACzD,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;YACpC,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YAC7B,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,cAAc,CAAC,UAAkB,EAAE,WAAmB,EAAE,QAAgB;QACtE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QACrD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE;YAChG,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,mCAAmC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACpE,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAzCD,sCAyCC"}
|
package/dist/ntfyNotifier.d.ts
CHANGED
|
@@ -5,6 +5,6 @@ export declare class NtfyNotifier {
|
|
|
5
5
|
private readonly deviceNames;
|
|
6
6
|
private readonly notifiedIps;
|
|
7
7
|
constructor(log: Logger, topic: string | undefined, deviceNames: Map<string, string>);
|
|
8
|
-
notifyConnectionFailure(ip: string,
|
|
8
|
+
notifyConnectionFailure(ip: string, message: string): void;
|
|
9
9
|
notifyConnectionRecovered(ip: string): void;
|
|
10
10
|
}
|
package/dist/ntfyNotifier.js
CHANGED
|
@@ -16,7 +16,7 @@ class NtfyNotifier {
|
|
|
16
16
|
this.topic = topic;
|
|
17
17
|
this.deviceNames = deviceNames;
|
|
18
18
|
}
|
|
19
|
-
notifyConnectionFailure(ip,
|
|
19
|
+
notifyConnectionFailure(ip, message) {
|
|
20
20
|
if (!this.topic || this.notifiedIps.has(ip)) {
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
@@ -25,7 +25,7 @@ class NtfyNotifier {
|
|
|
25
25
|
fetch(`${NTFY_BASE_URL}/${this.topic}`, {
|
|
26
26
|
method: 'POST',
|
|
27
27
|
headers: { Title: `Homebridge: Connection to Broadlink ${deviceName} Failed!` },
|
|
28
|
-
body:
|
|
28
|
+
body: message,
|
|
29
29
|
}).catch((notifyError) => {
|
|
30
30
|
const message = notifyError instanceof Error ? notifyError.message : String(notifyError);
|
|
31
31
|
this.log.warn(`Failed to send ntfy notification: ${message}`);
|
package/dist/ntfyNotifier.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ntfyNotifier.js","sourceRoot":"","sources":["../src/ntfyNotifier.ts"],"names":[],"mappings":";;;AAEA,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAExC,4EAA4E;AAC5E,6EAA6E;AAC7E,wEAAwE;AACxE,2CAA2C;AAC3C,MAAa,YAAY;IAIJ;IACA;IACA;IALF,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IAEjD,YACmB,GAAW,EACX,KAAyB,EACzB,WAAgC;QAFhC,QAAG,GAAH,GAAG,CAAQ;QACX,UAAK,GAAL,KAAK,CAAoB;QACzB,gBAAW,GAAX,WAAW,CAAqB;IAChD,CAAC;IAEJ,uBAAuB,CAAC,EAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"ntfyNotifier.js","sourceRoot":"","sources":["../src/ntfyNotifier.ts"],"names":[],"mappings":";;;AAEA,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAExC,4EAA4E;AAC5E,6EAA6E;AAC7E,wEAAwE;AACxE,2CAA2C;AAC3C,MAAa,YAAY;IAIJ;IACA;IACA;IALF,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IAEjD,YACmB,GAAW,EACX,KAAyB,EACzB,WAAgC;QAFhC,QAAG,GAAH,GAAG,CAAQ;QACX,UAAK,GAAL,KAAK,CAAoB;QACzB,gBAAW,GAAX,WAAW,CAAqB;IAChD,CAAC;IAEJ,uBAAuB,CAAC,EAAU,EAAE,OAAe;QACjD,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAC5C,OAAO;QACT,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEzB,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;QAClD,KAAK,CAAC,GAAG,aAAa,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE;YACtC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,KAAK,EAAE,uCAAuC,UAAU,UAAU,EAAE;YAC/E,IAAI,EAAE,OAAO;SACd,CAAC,CAAC,KAAK,CAAC,CAAC,WAAoB,EAAE,EAAE;YAChC,MAAM,OAAO,GAAG,WAAW,YAAY,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YACzF,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,qCAAqC,OAAO,EAAE,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACL,CAAC;IAED,yBAAyB,CAAC,EAAU;QAClC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;CACF;AA7BD,oCA6BC"}
|
package/dist/platform.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { API, Characteristic, DynamicPlatformPlugin, Logger, PlatformAccessory, PlatformConfig, Service } from 'homebridge';
|
|
2
2
|
import { BroadlinkClient } from './broadlinkClient';
|
|
3
3
|
import { NtfyNotifier } from './ntfyNotifier';
|
|
4
|
+
import { MqttPublisher } from './mqttPublisher';
|
|
4
5
|
export declare class BroadlinkRMBlasterPlatform implements DynamicPlatformPlugin {
|
|
5
6
|
readonly log: Logger;
|
|
6
7
|
readonly config: PlatformConfig;
|
|
@@ -10,6 +11,7 @@ export declare class BroadlinkRMBlasterPlatform implements DynamicPlatformPlugin
|
|
|
10
11
|
readonly accessories: PlatformAccessory[];
|
|
11
12
|
readonly broadlinkClient: BroadlinkClient;
|
|
12
13
|
readonly notifier: NtfyNotifier;
|
|
14
|
+
readonly mqttPublisher: MqttPublisher;
|
|
13
15
|
private readonly activeUuids;
|
|
14
16
|
constructor(log: Logger, config: PlatformConfig, api: API);
|
|
15
17
|
configureAccessory(accessory: PlatformAccessory): void;
|
package/dist/platform.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.BroadlinkRMBlasterPlatform = void 0;
|
|
4
4
|
const broadlinkClient_1 = require("./broadlinkClient");
|
|
5
5
|
const ntfyNotifier_1 = require("./ntfyNotifier");
|
|
6
|
+
const mqttPublisher_1 = require("./mqttPublisher");
|
|
6
7
|
const settings_1 = require("./settings");
|
|
7
8
|
const basicAccessory_1 = require("./accessories/basicAccessory");
|
|
8
9
|
const dimmerAccessory_1 = require("./accessories/dimmerAccessory");
|
|
@@ -17,6 +18,7 @@ class BroadlinkRMBlasterPlatform {
|
|
|
17
18
|
accessories = [];
|
|
18
19
|
broadlinkClient;
|
|
19
20
|
notifier;
|
|
21
|
+
mqttPublisher;
|
|
20
22
|
activeUuids = new Set();
|
|
21
23
|
constructor(log, config, api) {
|
|
22
24
|
this.log = log;
|
|
@@ -30,6 +32,7 @@ class BroadlinkRMBlasterPlatform {
|
|
|
30
32
|
deviceNames.set(rmDevice.ip, rmDevice.name);
|
|
31
33
|
}
|
|
32
34
|
this.notifier = new ntfyNotifier_1.NtfyNotifier(this.log, blasterConfig.ntfyTopic, deviceNames);
|
|
35
|
+
this.mqttPublisher = new mqttPublisher_1.MqttPublisher(this.log, !!blasterConfig.enableMqtt, blasterConfig.mqttHost, blasterConfig.mqttPort, blasterConfig.mqttBaseTopic ?? mqttPublisher_1.DEFAULT_MQTT_BASE_TOPIC, blasterConfig.mqttUsername, blasterConfig.mqttPassword);
|
|
33
36
|
this.broadlinkClient = new broadlinkClient_1.BroadlinkClient(this.log, this.notifier);
|
|
34
37
|
this.api.on('didFinishLaunching', () => {
|
|
35
38
|
this.discoverAccessories();
|
|
@@ -71,14 +74,22 @@ class BroadlinkRMBlasterPlatform {
|
|
|
71
74
|
}
|
|
72
75
|
this.publishTvAccessories(config);
|
|
73
76
|
for (const rmDevice of config.rmDevices ?? []) {
|
|
74
|
-
|
|
77
|
+
const showInHomeKit = !!rmDevice.enableTemperatureHumidity;
|
|
78
|
+
const publishToMqtt = !!rmDevice.enableMqttPublish;
|
|
79
|
+
if (!showInHomeKit && !publishToMqtt) {
|
|
75
80
|
continue;
|
|
76
81
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
if (showInHomeKit) {
|
|
83
|
+
const sensorName = `${rmDevice.name} Sensor`;
|
|
84
|
+
const uuid = this.api.hap.uuid.generate(`${settings_1.PLUGIN_NAME}:sensor:${rmDevice.name}`);
|
|
85
|
+
this.upsertAccessory(uuid, sensorName, (accessory) => {
|
|
86
|
+
new temperatureHumiditySensorAccessory_1.TemperatureHumiditySensorAccessory(this, accessory, rmDevice.ip, sensorName, rmDevice.name, publishToMqtt);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
// MQTT-only: no HomeKit accessory needed, just poll and publish.
|
|
91
|
+
new temperatureHumiditySensorAccessory_1.TemperatureHumiditySensorAccessory(this, undefined, rmDevice.ip, rmDevice.name, rmDevice.name, publishToMqtt);
|
|
92
|
+
}
|
|
82
93
|
}
|
|
83
94
|
this.pruneStaleAccessories();
|
|
84
95
|
}
|
package/dist/platform.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":";;;AAUA,uDAAoD;AACpD,iDAA8C;AAC9C,yCAAwD;AAExD,iEAA8D;AAC9D,mEAAgE;AAChE,2DAAwD;AACxD,yGAAsG;AAEtG,MAAa,0BAA0B;
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-broadlink-rm-blaster",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Blast RF and IR signals from Broadlink RM devices using Homebridge",
|
|
5
5
|
"author": "Luud Jacobs",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,7 +43,8 @@
|
|
|
43
43
|
"prepublishOnly": "npm run lint && npm run build"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"kiwicam-broadlinkjs-rm": "^0.9.22"
|
|
46
|
+
"kiwicam-broadlinkjs-rm": "^0.9.22",
|
|
47
|
+
"mqtt": "^5.15.2"
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
49
50
|
"@types/node": "^22.10.5",
|