node-red-contrib-deconz
Advanced tools
Comparing version 2.0.0-rc.1 to 2.0.0-rc.2
@@ -5,63 +5,114 @@ # Changelog | ||
:memo: The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
:memo: The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres | ||
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
## [Unreleased] :construction: | ||
## [2.0.0-beta.9] - 2021-09-22 ![Relative date](https://img.shields.io/date/1632343413?label=) | ||
## [2.0.0-rc.1] - 2021-10-05 ![Relative date](https://img.shields.io/date/1633461456?label=) | ||
### Migrate from 1.3.4 | ||
Make sure you backup your flow before updating, you will not be able to downgrade if the configuration is migrated. | ||
Everything should be seamless, all your configuration will be migrated with the new save format. It's will save the | ||
updated configuration only when you open the node configuration and click Deploy. If you don't do it the node will | ||
migrate the configuration on each start of Node-Red. Check the Node-Red log if you have any errors that showes up. If | ||
you have any issues you can come on the [Deconz-Community Discord](https://discord.gg/3XGEYY9) server or open | ||
an [issue on Github](https://github.com/deconz-community/node-red-contrib-deconz/issues). | ||
### Added | ||
- The nodes now allow multiple device selection. | ||
- The nodes accept [queries](https://github.com/deconz-community/node-red-contrib-deconz/wiki/Device-queries) instead of a device list. | ||
- The nodes accept [queries](https://github.com/deconz-community/node-red-contrib-deconz/wiki/Device-queries) instead of | ||
a device list. | ||
- Each outputs of nodes is now customizable. If you don't need the homekit output just remove it ! | ||
#### Input node | ||
- Rework the Auto configuration of server. It's now look for Home-Assistant installations too. | ||
#### Input and Battey nodes | ||
- New output types | ||
- Attribute | ||
- Config | ||
- Attribute - Contain all information about device, include State and Config. | ||
- Config - Contain configuration data. | ||
- Scene Call - Called when a scene is called. | ||
- New properties on messages | ||
- payload_format - The name of the value or __complete__ if the selected payload is "Complete payload. | ||
- meta_changed - List of param path that changed since last message. Exemple : "state.lastupdated" | ||
- payload_format - The name of the value or __complete__ if the selected payload is "Complete payload". | ||
- payload_type - The option selected in the output type. | ||
- meta_changed - List of param path that changed since last message. Exemple : "state.lastupdated". | ||
- Connexion preview, you can press the top right button of each output rule to see what nodes are connected. | ||
- Start output is now configurable for each type. To avoid fake button events you should disable it for switch devices. | ||
#### Get node | ||
- New output types | ||
- Attribute | ||
- Config | ||
- Attribute | ||
- Config | ||
- New output formats | ||
- Single - The node will send a message per device that send data. | ||
- Array - The node will send a message with all payload inside an array. The message will contain a payload that is an array of single message. Ex msg.payload[0].payload is the payload of the first device. Each element will contain only the properties payload, meta, meta_changed. The properties topic, payload_format, payload_raw will be on the msg directly. | ||
- Sum - All properties of the devices will be added individually. | ||
- Average - All properties of the devices will be added recursively and then divided by the amount of device that have that property. | ||
- Min - The result will be a set of minimal value of each property. | ||
- Max - The result will be a set of maximal value of each property. | ||
- Single - The node will send a message per device that send data. | ||
- Array - The node will send a message with all payload inside an array. The message will contain a payload that is | ||
an array of single message. Ex msg.payload[0].payload is the payload of the first device. Each element will | ||
contain only the properties payload, meta, meta_changed. The properties topic, payload_format, payload_raw will be | ||
on the msg directly. | ||
- Sum - All properties of the devices will be added individually. | ||
- Average - All properties of the devices will be added recursively and then divided by the amount of device that | ||
have that property. | ||
- Min - The result will be a set of minimal value of each property. | ||
- Max - The result will be a set of maximal value of each property. | ||
#### Output node | ||
- New output to see the result of the api request. | ||
- All options can be set in one command. | ||
- New command types | ||
- Windows Cover - For easier comprehension of commands. | ||
- Custom command - For thoses tricky things that don't fit in a Deconz state command. | ||
- Target - Set where you wan't to send data. Can be 'attribute', 'state' or 'config'. | ||
- Command - Set the option name. Can be object if the payload contains an object with keys and values. | ||
- Payload - Set the value. | ||
- Pause - Add delay between 2 commands. | ||
- Added output to see the result of the api request. | ||
- All options can be set in one command. You can now set brightness and color in one command. | ||
- Multiple commands can be added and executed one by one. | ||
- Command preview, you can press the top right button of each command to run it instantly. | ||
#### Event node | ||
- New message property meta with the device configuration. | ||
#### Battery node | ||
- Same rework as the input node. | ||
- New message property meta associated to the event with the device configuration. | ||
- Now display the event count since last deploy. | ||
## [1.3.4] - 2021-09-28 ![Relative date](https://img.shields.io/date/1632782604?label=) | ||
### Changed | ||
- Update readme for 2.0 version. | ||
## [1.3.3] - 2021-06-20 ![Relative date](https://img.shields.io/date/1624190689?label=) | ||
### Fixed | ||
- Update multi-select to 1.15.2 for monaco-editor compatibility in node-red 2.0. #140 | ||
## [1.3.2] - 2021-03-06 ![Relative date](https://img.shields.io/date/1615059740?label=) | ||
### Fixed | ||
- Device list was empty. #89 | ||
## [1.3.1] - 2021-02-20 ![Relative date](https://img.shields.io/date/1613827429?label=) | ||
### Fixed | ||
- Removed unwanted transition time on out node when the transition time is not set. #118 | ||
## [1.3.0] - 2021-02-19 ![Relative date](https://img.shields.io/date/1613738128?label=) | ||
### Added | ||
- Adding the possibility to change progamatically the "Transition Time". #107 | ||
### Security | ||
Please edit server configuration and click on update to save the API Key in node-red credentials. | ||
- API Key is now stored in node-red credentials. #94 | ||
## [1.2.0] - 2020-07-12 ![Relative date](https://img.shields.io/date/1594559914?label=) | ||
- Lastest version from [@andreypopov](https://github.com/andreypopov). | ||
- Lastest version from [@andreypopov](https://github.com/andreypopov). |
@@ -99,2 +99,9 @@ const OutputMsgFormatter = require("../src/runtime/OutputMsgFormatter"); | ||
}, opt); | ||
if (options.errorEvent === true) { | ||
node.status(options.errorCode || "Unknown Error"); | ||
node.error(options.errorMsg || "Unknown Error"); | ||
return; | ||
} | ||
this.config.output_rules.forEach((saved_rule, index) => { | ||
@@ -101,0 +108,0 @@ // Make sure that all expected config are defined |
@@ -21,2 +21,13 @@ module.exports = function (RED) { | ||
let node = this; | ||
let options = Object.assign({ | ||
initialEvent: false, | ||
errorEvent: false | ||
}, opt); | ||
if (options.errorEvent === true) { | ||
node.status(options.errorCode || "Unknown Error"); | ||
node.error(options.errorMsg || "Unknown Error"); | ||
return; | ||
} | ||
node.send({ | ||
@@ -23,0 +34,0 @@ payload: rawEvent, |
@@ -101,2 +101,9 @@ const dotProp = require('dot-prop'); | ||
}, opt); | ||
if (options.errorEvent === true) { | ||
node.status(options.errorCode || "Unknown Error"); | ||
node.error(options.errorMsg || "Unknown Error"); | ||
return; | ||
} | ||
this.config.output_rules.forEach((saved_rule, index) => { | ||
@@ -103,0 +110,0 @@ // Make sure that all expected config are defined |
@@ -8,3 +8,3 @@ { | ||
"websocket_port": "WebSocket Port", | ||
"get_settings": "Get Settings", | ||
"get_settings": "Auto fetch all settings", | ||
"use_secured_ssl": "Use secured SSL connection", | ||
@@ -11,0 +11,0 @@ "magick": "Magick", |
@@ -34,3 +34,3 @@ const got = require('got'); | ||
port: node.config.port, | ||
key: node.credentials.secured_apikey | ||
apikey: node.credentials.secured_apikey | ||
}); | ||
@@ -54,14 +54,16 @@ | ||
await node.discoverDevices({ | ||
forceRefresh: true | ||
}); | ||
this.refreshDiscoverTimer = setInterval(() => { | ||
node.discoverDevices({ | ||
let pooling = async () => { | ||
let result = await node.discoverDevices({ | ||
forceRefresh: true | ||
}); | ||
}, node.refreshDiscoverInterval); | ||
// Wait for a valid device discovery before connecting to the websocket | ||
if (result === true) { | ||
if (node.socket === undefined) this.setupDeconzSocket(node); | ||
node.ready = true; | ||
} | ||
}; | ||
node.ready = true; | ||
await pooling(); | ||
this.refreshDiscoverTimer = setInterval(pooling, node.refreshDiscoverInterval); | ||
this.setupDeconzSocket(node); | ||
} catch (e) { | ||
@@ -119,3 +121,3 @@ node.ready = false; | ||
if (options.forceRefresh === false || node.discoverProcessRunning === true) { | ||
if (node.ready && (options.forceRefresh === false || node.discoverProcessRunning === true)) { | ||
node.log('discoverDevices: Using cached devices'); | ||
@@ -130,6 +132,9 @@ return; | ||
node.log(`discoverDevices: Updated ${node.device_list.count}`); | ||
node.discoverProcessRunning = false; | ||
return true; | ||
} catch (e) { | ||
node.error(`discoverDevices: Can't connect to deconz API.`); | ||
node.discoverProcessRunning = false; | ||
return false; | ||
} | ||
node.discoverProcessRunning = false; | ||
} | ||
@@ -187,2 +192,3 @@ | ||
let node = this; | ||
if (!reason) return; | ||
@@ -255,2 +261,18 @@ // Node with device selected | ||
let target = RED.nodes.getNode(nodeID); | ||
// Check if device exist | ||
if (news.device === undefined) { | ||
target.handleDeconzEvent( | ||
news.device, | ||
[], | ||
{}, | ||
{ | ||
errorEvent: true, | ||
errorCode: "DEVICE_NOT_FOUND", | ||
errorMsg: "Device not found, please check server configuration" | ||
} | ||
); | ||
continue; | ||
} | ||
// If the target does not exist we remove it from the node list | ||
@@ -408,6 +430,6 @@ if (!target) { | ||
let node = this; | ||
clearInterval(node.refreshDiscoverTimer); | ||
node.ready = false; | ||
node.log('WebSocket connection closed'); | ||
node.emit('onClose'); | ||
clearInterval(node.refreshDiscoverTimer); | ||
node.socket.close(); | ||
@@ -418,33 +440,19 @@ node.socket = undefined; | ||
onSocketPongTimeout() { | ||
let that = this; | ||
that.warn('WebSocket connection timeout, reconnecting'); | ||
that.emit('onSocketPongTimeout'); | ||
let node = this; | ||
node.warn('WebSocket connection timeout, reconnecting'); | ||
node.emit('onSocketPongTimeout'); | ||
} | ||
onSocketUnauthorized() { | ||
let that = this; | ||
that.warn('WebSocket authentication failed'); | ||
that.emit('onSocketUnauthorized'); | ||
let node = this; | ||
node.warn('WebSocket authentication failed'); | ||
node.emit('onSocketUnauthorized'); | ||
} | ||
onSocketError(err) { | ||
let that = this; | ||
that.warn(`WebSocket error: ${err}`); | ||
that.emit('onSocketError'); | ||
let node = this; | ||
node.error(`WebSocket error: ${err}`); | ||
node.emit('onSocketError'); | ||
} | ||
onSocketClose(code, reason) { | ||
let that = this; | ||
if (reason) { // don't bother the user unless there's a reason | ||
that.warn(`WebSocket disconnected: ${code} - ${reason}`); | ||
} | ||
that.emit('onSocketClose'); | ||
} | ||
onSocketOpen(err) { | ||
let that = this; | ||
that.log(`WebSocket opened`); | ||
that.emit('onSocketOpen'); | ||
} | ||
updateDevice(device, dataParsed) { | ||
@@ -451,0 +459,0 @@ let node = this; |
@@ -51,3 +51,3 @@ { | ||
}, | ||
"version": "2.0.0-rc.1", | ||
"version": "2.0.0-rc.2", | ||
"devDependencies": { | ||
@@ -54,0 +54,0 @@ "grunt": "^1.3.0", |
# Node-Red deCONZ | ||
[![GitHub](https://img.shields.io/github/license/deconz-community/node-red-contrib-deconz)](https://github.com/deconz-community/node-red-contrib-deconz/blob/main/LICENSE) | ||
@@ -12,29 +13,32 @@ [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/deconz-community/node-red-contrib-deconz/NPM%20Publish)](https://github.com/deconz-community/node-red-contrib-deconz/actions) | ||
## The new 2.0 beta version is out [![npm](https://img.shields.io/npm/v/node-red-contrib-deconz/dev)](https://www.npmjs.com/package/node-red-contrib-deconz/dev) ![GitHub commits since latest release (by date)](https://img.shields.io/github/commits-since/deconz-community/node-red-contrib-deconz/v1.3.3/develop) | ||
## The new 2.0 version is out | ||
Hi it's [@Zehir](https://github.com/Zehir) here, I worked hard for months on a complete rework of this plugin. There is a ton of new features, it's will be easier to do stuff on node-red. If you have any issue with this beta version, feel free to open issues on [GitHub](https://github.com/deconz-community/node-red-contrib-deconz/issues). | ||
Hi it's [@Zehir](https://github.com/Zehir) here, I worked hard for months on a complete rework of this plugin. There is | ||
a ton of new features, it's will be easier to do stuff on node-red. If you have any issue with this beta version, feel | ||
free to open issues on [GitHub](https://github.com/deconz-community/node-red-contrib-deconz/issues). | ||
This new version requires Node-Red version 2.0 or newer. (It's could work with lasted 1.X version of Node-Red). | ||
This new version requires Node-Red version 2.0 or newer. | ||
Some new features ([Changelog](https://github.com/deconz-community/node-red-contrib-deconz/blob/develop/CHANGELOG.md)): | ||
* Multiple device selection | ||
* Select device using [queries](https://github.com/deconz-community/node-red-contrib-deconz/wiki/Device-queries) | ||
* Multiple commands at once | ||
* Query multiple devices and merge the result | ||
* Many more to come | ||
If you want to try the beta version you can install it from npm using the dev `tag` but you **should** backup your flow and be able to restore your flow if anything goes wrong. | ||
* Multiple device selection. | ||
* Select device using [queries](https://github.com/deconz-community/node-red-contrib-deconz/wiki/Device-queries). | ||
* Multiple commands at once. | ||
* Query multiple devices and merge the result. | ||
As the current beta.8 everything should keep working after the update. The migration should be seamless, if it's not the case for you please open an [issue](https://github.com/deconz-community/node-red-contrib-deconz/issues). | ||
### Migrate from 1.3.4 | ||
## Legacy version | ||
Make sure you backup your flow before updating, you will not be able to downgrade if the configuration is migrated. | ||
The last version of the "legacy" version will by 1.3.3. This version was originally created | ||
by [@Andreypopov](https://github.com/andreypopov), he mentioned that he stopped development. Dennis the Community Manager of deCONZ asked him to transfer the repository so we can advance on it later. Please bear with us. | ||
Everything should be seamless, all your configuration will be migrated with the new save format. It's will save the | ||
updated configuration only when you open the node configuration and click Deploy. If you don't do it the node will | ||
migrate the configuration on each start of Node-Red. Check the Node-Red log if you have any errors that showes up. If | ||
you have any issues you can come on the [Deconz-Community Discord](https://discord.gg/3XGEYY9) server or open | ||
an [issue on Github](https://github.com/deconz-community/node-red-contrib-deconz/issues). | ||
Available nodes are: | ||
## Available nodes | ||
* deconz-in: A node to subscribe to deCONZ devices | ||
* deconz-get: get state of device or group | ||
* deconz-out: send data to device or group | ||
* deconz-in: A node to subscribe to deCONZ events. | ||
* deconz-get: get state of device or group. | ||
* deconz-out: send actions or data to device or group. | ||
* deconz-battery: get battery status of device | ||
@@ -51,5 +55,6 @@ * deconz-event: get all deconz events | ||
[![Watch YouTube video](https://img.youtube.com/vi/i3TiZiuNofM/0.jpg)](https://www.youtube.com/watch?v=i3TiZiuNofM) | ||
<br>Watch YouTube video | ||
## Legacy version | ||
The last version of the "legacy" version will be 1.3.4. This version was originally created | ||
by [@Andreypopov](https://github.com/andreypopov), he mentioned that he stopped development. Dennis the Community | ||
Manager of deCONZ asked him to transfer the repository so we can advance on it later. Please bear with us. |
@@ -14,3 +14,3 @@ const got = require('got'); | ||
this.ws_port = options.ws_port; | ||
this.key = options.key !== undefined ? options.key : '<nouser>'; | ||
this.apikey = options.apikey !== undefined ? options.apikey : '<nouser>'; | ||
this.secured = options.secured; | ||
@@ -27,3 +27,3 @@ this.version = options.version; | ||
challenge: () => `${this.url.api()}/challenge`, // Undocumented | ||
main: () => `${this.url.api()}/${this.key}`, | ||
main: () => `${this.url.api()}/${this.apikey}`, | ||
config: { | ||
@@ -174,5 +174,5 @@ main: () => `/config`, | ||
if ((this.key === undefined || String(this.key).length === 0) || this.key === '<nouser>') { | ||
if ((this.apikey === undefined || String(this.apikey).length === 0) || this.apikey === '<nouser>') { | ||
response.log.push("No valid API key provided, trying acquiring one."); | ||
this.key = '<nouser>'; | ||
this.apikey = '<nouser>'; | ||
let apiQuery; | ||
@@ -228,3 +228,3 @@ let guesses = [ | ||
response.log.push("Successfully got a key."); | ||
this.key = apiQuery.success.username; | ||
this.apikey = apiQuery.success.username; | ||
} | ||
@@ -306,2 +306,7 @@ | ||
async getApiKeyMeta() { | ||
let whitelist = await this.getConfig('whitelist'); | ||
return (whitelist === undefined) ? undefined : whitelist[this.apikey]; | ||
} | ||
get settings() { | ||
@@ -312,3 +317,3 @@ console.log({ | ||
port: this.port, | ||
apikey: this.key, | ||
apikey: this.apikey, | ||
ws_port: this.ws_port, | ||
@@ -322,3 +327,3 @@ secure: this.secured, | ||
port: this.port, | ||
apikey: this.key, | ||
apikey: this.apikey, | ||
ws_port: this.ws_port, | ||
@@ -325,0 +330,0 @@ secure: this.secured, |
@@ -184,19 +184,26 @@ const dotProp = require('dot-prop'); | ||
case 'attribute': | ||
msg.payload = this.formatDevicePayload(device.data, payloadFormat, options); | ||
if (dotProp.has(device, 'data')) | ||
msg.payload = this.formatDevicePayload(device.data, payloadFormat, options); | ||
break; | ||
case 'state': | ||
msg.payload = this.formatDevicePayload(device.data.state, payloadFormat, options); | ||
if (dotProp.has(device, 'data.state')) | ||
msg.payload = this.formatDevicePayload(device.data.state, payloadFormat, options); | ||
break; | ||
case 'config': | ||
msg.payload = this.formatDevicePayload(device.data.config, payloadFormat, options); | ||
if (dotProp.has(device, 'data.config')) | ||
msg.payload = this.formatDevicePayload(device.data.config, payloadFormat, options); | ||
break; | ||
case 'homekit': | ||
msg = this.formatHomeKit(device.data, device.changed, rawEvent, options); | ||
if (msg === null) return null; | ||
if (dotProp.has(device, 'data')) | ||
msg = this.formatHomeKit(device.data, device.changed, rawEvent, options); | ||
break; | ||
case 'scene_call': | ||
msg.payload = device.data.scenes.filter((v) => v.id === rawEvent.scid).shift(); | ||
if (dotProp.has(device, 'data.scenes')) | ||
msg.payload = device.data.scenes.filter((v) => v.id === rawEvent.scid).shift(); | ||
break; | ||
} | ||
// If we don't have payload drop the msg | ||
if (msg === null || msg.payload === undefined) return null; | ||
if (['deconz-input', 'deconz-battery'].includes(this.node_type)) msg.topic = this.config.topic; | ||
@@ -203,0 +210,0 @@ if (payloadFormat !== undefined) msg.payload_format = payloadFormat; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
477544
6601
59