matterbridge-webhooks 1.1.0-edge.2 → 1.1.0-edge.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/README.md +5 -19
- package/dist/module.js +51 -30
- package/matterbridge-webhooks.schema.json +12 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,7 @@ If you like this project and find it useful, please consider giving it a star on
|
|
|
6
6
|
|
|
7
7
|
<a href="https://www.buymeacoffee.com/luligugithub"><img src="https://matterbridge.io/bmc-button.svg" alt="Buy me a coffee" width="120"></a>
|
|
8
8
|
|
|
9
|
-
## [1.0.3
|
|
9
|
+
## [1.1.0-edge.3] - Not released
|
|
10
10
|
|
|
11
11
|
### Added Webhook devices
|
|
12
12
|
|
package/README.md
CHANGED
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
This plugin allows you to expose single webhooks or complex webhook devices to Matter.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
# Simple webhooks
|
|
21
21
|
|
|
22
22
|
Features:
|
|
23
23
|
|
|
@@ -28,13 +28,11 @@ Features:
|
|
|
28
28
|
|
|
29
29
|
# Webhook devices
|
|
30
30
|
|
|
31
|
-
It allows also to create a device based on webhooks.
|
|
32
|
-
|
|
33
31
|
Features:
|
|
34
32
|
|
|
35
33
|
- It is possible to choose the device type from the config.
|
|
36
34
|
- It is possible to set the method with a prefix 'GET#' or 'POST# in the urls. Default if omitted is GET.
|
|
37
|
-
- It is possible to use converters in the url.
|
|
35
|
+
- It is possible to use converters and attributes in the url.
|
|
38
36
|
|
|
39
37
|
## Supported device types:
|
|
40
38
|
|
|
@@ -85,21 +83,9 @@ If you like this project and find it useful, please consider giving it a star on
|
|
|
85
83
|
|
|
86
84
|
### Matterbridge
|
|
87
85
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
```
|
|
91
|
-
npm install -g matterbridge --omit=dev
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
on Linux you may need the necessary permissions:
|
|
95
|
-
|
|
96
|
-
```
|
|
97
|
-
sudo npm install -g matterbridge --omit=dev
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
See the complete guidelines on [Matterbridge](https://github.com/Luligu/matterbridge/blob/main/README.md) for more information.
|
|
86
|
+
See the complete guidelines on [Matterbridge](https://matterbridge.io/README.html) for more information.
|
|
101
87
|
|
|
102
|
-
## How to add a webhook
|
|
88
|
+
## How to add a simple webhook
|
|
103
89
|
|
|
104
90
|
In the frontend open the plugin config: add a new webhook, enter the webhook name in the first field (replace newKey with the name you want to give to the webhook), select GET or POST and enter the webhook url. The webhook name will be the device name on the controller. The webhook will be exposed like a switch, like an outlet or like a light. When you turn it on, the webhook is called and in a few seconds the switch or the outlet or the light will revert to off.
|
|
105
91
|
|
package/dist/module.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { bridgedNode, colorTemperatureLight, dimmableLight, extendedColorLight, MatterbridgeDynamicPlatform, MatterbridgeEndpoint, onOffLight, onOffOutlet, onOffSwitch, } from 'matterbridge';
|
|
1
|
+
import { bridgedNode, colorTemperatureLight, dimmableLight, extendedColorLight, MatterbridgeColorControlServer, MatterbridgeDynamicPlatform, MatterbridgeEndpoint, MatterbridgeLevelControlServer, onOffLight, onOffOutlet, onOffSwitch, } from 'matterbridge';
|
|
2
2
|
import { hslColorToRgbColor, isValidNumber, isValidObject, isValidString, miredToKelvin, wait } from 'matterbridge/utils';
|
|
3
|
+
import { rs } from 'matterbridge/logger';
|
|
3
4
|
import { fetch } from './fetch.js';
|
|
4
5
|
export default function initializePlugin(matterbridge, log, config) {
|
|
5
6
|
return new WebhooksPlatform(matterbridge, log, config);
|
|
@@ -32,7 +33,7 @@ export class WebhooksPlatform extends MatterbridgeDynamicPlatform {
|
|
|
32
33
|
.createOnOffClusterServer(false)
|
|
33
34
|
.addRequiredClusterServers()
|
|
34
35
|
.addCommandHandler('on', async () => {
|
|
35
|
-
this.log.info(`Webhook ${webhookName} triggered
|
|
36
|
+
this.log.info(`Webhook ${webhookName} triggered`);
|
|
36
37
|
await device.setAttribute('onOff', 'onOff', false, device.log);
|
|
37
38
|
this.log.debug(`Fetching ${webhook.httpUrl} with ${webhook.method}...`);
|
|
38
39
|
fetch(webhook.httpUrl, webhook.method)
|
|
@@ -81,6 +82,8 @@ export class WebhooksPlatform extends MatterbridgeDynamicPlatform {
|
|
|
81
82
|
const device = new MatterbridgeEndpoint([deviceType, bridgedNode], { id: lightName }, this.config.debug)
|
|
82
83
|
.createDefaultBridgedDeviceBasicInformationClusterServer(lightName, 'light' + i++, this.matterbridge.aggregatorVendorId, 'Matterbridge', 'Matterbridge Webhook Light', 0, this.config.version)
|
|
83
84
|
.createOnOffClusterServer(false)
|
|
85
|
+
.createDefaultColorControlClusterServer(undefined, undefined, undefined, undefined, 250, webhook.minMireds, webhook.maxMireds)
|
|
86
|
+
.createDefaultLevelControlClusterServer()
|
|
84
87
|
.addRequiredClusterServers()
|
|
85
88
|
.addCommandHandler('on', async (data) => {
|
|
86
89
|
this.parseUrl('light', lightName, 'on', webhook.onUrl, data);
|
|
@@ -175,7 +178,9 @@ export class WebhooksPlatform extends MatterbridgeDynamicPlatform {
|
|
|
175
178
|
await this.unregisterAllDevices();
|
|
176
179
|
}
|
|
177
180
|
async parseUrl(deviceType, deviceName, command, url, data) {
|
|
178
|
-
this.log.info(`Webhook ${deviceType} ${deviceName} ${command} triggered
|
|
181
|
+
this.log.info(`Webhook ${deviceType} ${deviceName} ${command} triggered`);
|
|
182
|
+
const endpoint = data.endpoint;
|
|
183
|
+
this.log.debug(`Webhook ${deviceType} ${deviceName} ${command} triggered on endpoint ${endpoint?.deviceName}`);
|
|
179
184
|
let method = 'GET';
|
|
180
185
|
let parsedUrl = url;
|
|
181
186
|
if (url.startsWith('GET#')) {
|
|
@@ -212,50 +217,66 @@ export class WebhooksPlatform extends MatterbridgeDynamicPlatform {
|
|
|
212
217
|
}
|
|
213
218
|
if ((parsedUrl.includes('${level}') || parsedUrl.includes('${level100}')) && isValidNumber(data.attributes.currentLevel, 1, 254)) {
|
|
214
219
|
await wait(100);
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
220
|
+
data.attributes = endpoint.stateOf(MatterbridgeLevelControlServer);
|
|
221
|
+
if (isValidNumber(data.attributes.currentLevel, 1, 254)) {
|
|
222
|
+
if (url.includes('${level}'))
|
|
223
|
+
parsedUrl = parsedUrl.replace('${level}', data.attributes.currentLevel.toString());
|
|
224
|
+
if (url.includes('${level100}'))
|
|
225
|
+
parsedUrl = parsedUrl.replace('${level100}', Math.round((data.attributes.currentLevel / 254) * 100).toString());
|
|
226
|
+
}
|
|
219
227
|
}
|
|
220
228
|
if ((parsedUrl.includes('${mired}') || parsedUrl.includes('${kelvin}')) &&
|
|
221
229
|
isValidNumber(data.attributes.colorTemperatureMireds, data.attributes.colorTempPhysicalMinMireds, data.attributes.colorTempPhysicalMaxMireds)) {
|
|
222
230
|
await wait(100);
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
231
|
+
data.attributes = endpoint.stateOf(MatterbridgeColorControlServer);
|
|
232
|
+
if (isValidNumber(data.attributes.colorTemperatureMireds)) {
|
|
233
|
+
const kelvin = miredToKelvin(data.attributes.colorTemperatureMireds);
|
|
234
|
+
this.log.debug(`Attribute colorTemperatureMireds is ${data.attributes.colorTemperatureMireds}, which is ${kelvin}K`);
|
|
235
|
+
if (url.includes('${mired}'))
|
|
236
|
+
parsedUrl = parsedUrl.replace('${mired}', data.attributes.colorTemperatureMireds.toString());
|
|
237
|
+
if (url.includes('${kelvin}'))
|
|
238
|
+
parsedUrl = parsedUrl.replace('${kelvin}', kelvin.toString());
|
|
239
|
+
}
|
|
229
240
|
}
|
|
230
241
|
if ((parsedUrl.includes('${hue}') || parsedUrl.includes('${saturation}') || parsedUrl.includes('${red}') || parsedUrl.includes('${green}') || parsedUrl.includes('${blue}')) &&
|
|
231
242
|
isValidNumber(data.attributes.currentHue, 0, 254) &&
|
|
232
243
|
isValidNumber(data.attributes.currentSaturation, 0, 254)) {
|
|
233
244
|
await wait(100);
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
245
|
+
data.attributes = endpoint.stateOf(MatterbridgeColorControlServer);
|
|
246
|
+
if (isValidNumber(data.attributes.currentHue, 0, 254) && isValidNumber(data.attributes.currentSaturation, 0, 254)) {
|
|
247
|
+
const rgb = hslColorToRgbColor((data.attributes.currentHue * 360) / 254, (data.attributes.currentSaturation * 100) / 254, 50);
|
|
248
|
+
this.log.debug(`Converted hue ${data.attributes.currentHue} and saturation ${data.attributes.currentSaturation} to RGB r: ${rgb.r} g: ${rgb.g} b: ${rgb.b}`);
|
|
249
|
+
if (url.includes('${hue}'))
|
|
250
|
+
parsedUrl = parsedUrl.replace('${hue}', Math.round((data.attributes.currentHue * 360) / 254).toString());
|
|
251
|
+
if (url.includes('${saturation}'))
|
|
252
|
+
parsedUrl = parsedUrl.replace('${saturation}', Math.round((data.attributes.currentSaturation * 100) / 254).toString());
|
|
253
|
+
if (url.includes('${red}') && rgb)
|
|
254
|
+
parsedUrl = parsedUrl.replace('${red}', rgb.r.toString());
|
|
255
|
+
if (url.includes('${green}') && rgb)
|
|
256
|
+
parsedUrl = parsedUrl.replace('${green}', rgb.g.toString());
|
|
257
|
+
if (url.includes('${blue}') && rgb)
|
|
258
|
+
parsedUrl = parsedUrl.replace('${blue}', rgb.b.toString());
|
|
259
|
+
}
|
|
246
260
|
}
|
|
247
261
|
if ((parsedUrl.includes('${colorX}') || parsedUrl.includes('${colorY}')) &&
|
|
248
262
|
isValidNumber(data.attributes.currentX, 0, 65279) &&
|
|
249
263
|
isValidNumber(data.attributes.currentY, 0, 65279)) {
|
|
250
264
|
await wait(100);
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
265
|
+
data.attributes = endpoint.stateOf(MatterbridgeColorControlServer);
|
|
266
|
+
if (isValidNumber(data.attributes.currentX, 0, 65279) && isValidNumber(data.attributes.currentY, 0, 65279)) {
|
|
267
|
+
if (url.includes('${colorX}'))
|
|
268
|
+
parsedUrl = parsedUrl.replace('${colorX}', this.roundTo(data.attributes.currentX / 65536, 4).toString());
|
|
269
|
+
if (url.includes('${colorY}'))
|
|
270
|
+
parsedUrl = parsedUrl.replace('${colorY}', this.roundTo(data.attributes.currentY / 65536, 4).toString());
|
|
271
|
+
}
|
|
255
272
|
}
|
|
256
273
|
this.log.debug(`Fetching ${parsedUrl} with ${method}...`);
|
|
257
274
|
fetch(parsedUrl, method)
|
|
258
|
-
.then(() =>
|
|
275
|
+
.then((response) => {
|
|
276
|
+
this.log.notice(`Webhook ${deviceType} ${deviceName} ${command} successful!`);
|
|
277
|
+
this.log.debug(`Webhook ${deviceType} ${deviceName} ${command} response:${rs}\n`, response);
|
|
278
|
+
return;
|
|
279
|
+
})
|
|
259
280
|
.catch((err) => {
|
|
260
281
|
this.log.error(`Webhook ${deviceType} ${deviceName} ${command} failed: ${err instanceof Error ? err.message : err}`);
|
|
261
282
|
});
|
|
@@ -106,6 +106,18 @@
|
|
|
106
106
|
"description": "Light parameters:",
|
|
107
107
|
"required": ["onUrl", "offUrl"],
|
|
108
108
|
"properties": {
|
|
109
|
+
"minMireds": {
|
|
110
|
+
"type": "integer",
|
|
111
|
+
"title": "Minimum Mireds",
|
|
112
|
+
"default": 154,
|
|
113
|
+
"description": "Minimum color temperature in Mireds (Kelvin = 1000000 / Mireds). Default is 154 (6500K)."
|
|
114
|
+
},
|
|
115
|
+
"maxMireds": {
|
|
116
|
+
"type": "integer",
|
|
117
|
+
"title": "Maximum Mireds",
|
|
118
|
+
"default": 500,
|
|
119
|
+
"description": "Maximum color temperature in Mireds (Kelvin = 1000000 / Mireds). Default is 500 (2000K)."
|
|
120
|
+
},
|
|
109
121
|
"onUrl": {
|
|
110
122
|
"type": "string",
|
|
111
123
|
"title": "Light On URL",
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matterbridge-webhooks",
|
|
3
|
-
"version": "1.1.0-edge.
|
|
3
|
+
"version": "1.1.0-edge.3",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "matterbridge-webhooks",
|
|
9
|
-
"version": "1.1.0-edge.
|
|
9
|
+
"version": "1.1.0-edge.3",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"node-ansi-logger": "3.1.1",
|