feat(devices): handle yeelight basic support

Delete gateway in action config.
Close #4, close #8 and close #9
This commit is contained in:
Pierre CLEMENT
2018-01-11 00:41:54 +01:00
parent c85e131bc1
commit 6a9863814b
18 changed files with 286 additions and 1163 deletions

View File

@@ -14,6 +14,8 @@ The following devices are currently supported:
* Motion sensor
* Power plug (zigbee)
* Power plug (wifi)
* Yeelight White (mono)
* Yeelight RGB
## Preperation
@@ -42,13 +44,13 @@ Tip: use the configurator from the side-panel (hamburger menu, configuration nod
### How to use different nodes
Here an example of how to use the different nodes (screenshot of [importable flows-overview.json](flows-overview.json "Mi Devices overview")):
Here an example of how to use the different nodes (screenshot of [importable flows-overview.json](flows-overview.json?raw=true "Mi Devices overview")):
![Mi devices example in node-red](resources/mi-devices-overview.png?raw=true "Mi devices example in node-red")
### Sample flows
Here are different flow (screenshot of [importable flows-sample.json](flows-sample.json "Different flows using Mi Devices")):
Here are different flow (screenshot of [importable flows-sample.json](flows-sample.json?raw=true "Different flows using Mi Devices")):
![Mi devices example in node-red](resources/mi-devices-sample.png?raw=true "Mi devices flow sample")
## Enable LAN mode
@@ -59,7 +61,7 @@ Here are different flow (screenshot of [importable flows-sample.json](flows-samp
2. Make sure you set your region to: Mainland China under settings -> Locale - required for the moment.
Mainland China and language can set on English.
3. Select your Gateway in Mi Home
4. Then the 3 dots at the top right of the screen
4. Then click the 3 dots at the top right of the screen
5. Then click on about
6. Tap under Tutorial menu (on the blank part) repeatedly
7. You should see now 3 extra options listed in Chinese until you did now enable the developer mode (like the first screenshot below, if not try all steps again!)
@@ -72,6 +74,19 @@ If you change here something, you lose your password!
![Gateway advanced mode](resources/xiaomi-gateway-advanced-mode.png?raw=true "Gateway advanced mode")
![Gateway LAN mode enabled](resources/xiaomi-gateway-lan-enabled.png?raw=true "Gateway LAN mode enabled")
### Yeelight
1. Install Yeelight App
2. Select your Yeelight in Mi Home
3. Then click the third icon at the bottom of the screen
4. Then click on the lightning icon "LAN control"
5. In the new panel, toggle the switch to "on"
The lightning icon should be underline un yellow.
![Yeelight options](resources/xiaomi-yeelight-options.png?raw=true "Yeelight options")
![Yeelight LAN mode enabled](resources/xiaomi-yeelight-lan-enabled.png?raw=true "Yeelight LAN mode enabled")
## Sources
* [Harald Rietman node-red module](https://github.com/hrietman/node-red-contrib-xiaomi-devices)
@@ -79,6 +94,7 @@ If you change here something, you lose your password!
* [louisZl Gateway Local API](https://github.com/louisZL/lumi-gateway-local-api)
* [Domoticz Gateway Code](https://github.com/domoticz/domoticz/blob/development/hardware/XiaomiGateway.cpp)
* [Node-red UDP nodes](https://github.com/node-red/node-red/blob/master/nodes/core/io/32-udp.js)
* [Yeelight specs](http://www.yeelight.com/download/Yeelight_Inter-Operation_Spec.pdf)
## Credits

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -86,10 +86,7 @@
</script>
<script type="text/x-red" data-help-name="xiaomi-actions click">
<p>
Virtual single click for switch.
Note: a gateway input node must be present and have receive a message to get gateway tokens and be able to do the action.
</p>
<p>Virtual single click for switch.</p>
<h3>Inputs</h3>
<dl class="message-properties">
@@ -136,10 +133,7 @@
</script>
<script type="text/x-red" data-help-name="xiaomi-actions double_click">
<p>
Virtual double click for switch.
Note: a gateway input node must be present and have receive a message to get gateway tokens and be able to do the action.
</p>
<p>Virtual double click for switch.</p>
<h3>Inputs</h3>
<dl class="message-properties">
@@ -183,7 +177,6 @@
category: 'xiaomi actions',
color: '#64C4CD',
defaults: {
gateway: {value:"", type:"xiaomi-configurator"},
name: {value: ""},
brightness: {value: 100},
hexRgbColor: {value: "#ffffff"},
@@ -211,10 +204,6 @@
</script>
<script type="text/x-red" data-template-name="xiaomi-actions gateway_light">
<div class="form-row">
<label for="node-input-gateway"><i class="icon-tag"></i> Gateway</label>
<input type="text" id="node-input-gateway" placeholder="xiaomi gateway">
</div>
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
@@ -230,9 +219,7 @@
</script>
<script type="text/x-red" data-help-name="xiaomi-actions gateway_light">
<p>Change the light of the gateway.
Note: a gateway input node must be present and have receive a message to get gateway tokens and be able to do the action.
</p>
<p>Change the light of the gateway.</p>
<h3>Inputs</h3>
<dl class="message-properties">
@@ -271,7 +258,6 @@
category: 'xiaomi actions',
color: '#64C4CD',
defaults: {
gateway: {value:"", type:"xiaomi-configurator"},
name: {value: ""},
mid: {value: ""},
volume: {value: ""}
@@ -287,10 +273,6 @@
</script>
<script type="text/x-red" data-template-name="xiaomi-actions gateway_sound">
<div class="form-row">
<label for="node-input-gateway"><i class="icon-tag"></i> Gateway</label>
<input type="text" id="node-input-gateway" placeholder="xiaomi gateway">
</div>
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
@@ -330,9 +312,7 @@
</script>
<script type="text/x-red" data-help-name="xiaomi-actions gateway_sound">
<p>Play a sound on the gateway.
Note: a gateway input node must be present and have receive a message to get gateway tokens and be able to do the action.
</p>
<p>Play a sound on the gateway.</p>
<h3>Inputs</h3>
<dl class="message-properties">
@@ -359,7 +339,6 @@
category: 'xiaomi actions',
color: '#64C4CD',
defaults: {
gateway: {value:"", type:"xiaomi-configurator"},
name: {value:""}
},
inputs:1,
@@ -372,10 +351,6 @@
});
</script>
<script type="text/x-red" data-template-name="xiaomi-actions gateway_stop_sound">
<div class="form-row">
<label for="node-input-gateway"><i class="icon-tag"></i> Gateway</label>
<input type="text" id="node-input-gateway" placeholder="xiaomi gateway">
</div>
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
@@ -385,7 +360,6 @@
<script type="text/x-red" data-help-name="xiaomi-actions gateway_stop_sound">
<p>
Stop current playing sound on the gateway.
Note: a gateway input node must be present and have receive a message to get gateway tokens and be able to do the action.
</p>
<h3>Outputs</h3>
@@ -395,13 +369,12 @@
</script>
<!-- The plug "on" Node -->
<!-- The "on" Node -->
<script type="text/javascript">
RED.nodes.registerType('xiaomi-actions on',{
category: 'xiaomi actions',
color: '#64C4CD',
defaults: {
gateway: {value:"", type:"xiaomi-configurator"},
name: {value:""}
},
inputs:1,
@@ -414,10 +387,6 @@
});
</script>
<script type="text/x-red" data-template-name="xiaomi-actions on">
<div class="form-row">
<label for="node-input-gateway"><i class="icon-tag"></i> Gateway</label>
<input type="text" id="node-input-gateway" placeholder="xiaomi gateway">
</div>
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
@@ -427,23 +396,21 @@
<script type="text/x-red" data-help-name="xiaomi-actions on">
<p>
Turn input device to on.
Note: a gateway input node must be present and have receive a message to get gateway tokens and be able to do the action.
</p>
<h3>Outputs</h3>
<ol class="node-ports">
<li>Message to connect to a gateway out node.</li>
<li>Message to connect to a gateway/yeelight out node.</li>
</ol>
</script>
<!-- The plug "off" Node -->
<!-- The "off" Node -->
<script type="text/javascript">
RED.nodes.registerType('xiaomi-actions off',{
category: 'xiaomi actions',
color: '#64C4CD',
defaults: {
gateway: {value:"", type:"xiaomi-configurator"},
name: {value:""}
},
inputs:1,
@@ -456,10 +423,6 @@
});
</script>
<script type="text/x-red" data-template-name="xiaomi-actions off">
<div class="form-row">
<label for="node-input-gateway"><i class="icon-tag"></i> Gateway</label>
<input type="text" id="node-input-gateway" placeholder="xiaomi gateway">
</div>
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
@@ -469,11 +432,44 @@
<script type="text/x-red" data-help-name="xiaomi-actions off">
<p>
Turn input device to off.
Note: a gateway input node must be present and have receive a message to get gateway tokens and be able to do the action.
</p>
<h3>Outputs</h3>
<ol class="node-ports">
<li>Message to connect to a gateway out node.</li>
<li>Message to connect to a gateway/yeelight out node.</li>
</ol>
</script>
<!-- The "toggle" Node -->
<script type="text/javascript">
RED.nodes.registerType('xiaomi-actions toggle',{
category: 'xiaomi actions',
color: '#64C4CD',
defaults: {
name: {value:""}
},
inputs:1,
outputs:1,
paletteLabel: "toggle",
icon: "mi-toggle.png",
label: function() {
return this.name||"toggle power";
}
});
</script>
<script type="text/x-red" data-template-name="xiaomi-actions toggle">
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
</script>
<script type="text/x-red" data-help-name="xiaomi-actions toggle">
<p>Toggle device.</p>
<h3>Outputs</h3>
<ol class="node-ports">
<li>Message to connect to a gateway/yeelight out node.</li>
</ol>
</script>

View File

@@ -36,8 +36,11 @@ module.exports = (RED) => {
RED.nodes.createNode(this, config);
this.on('input', (msg) => {
this.gateway = msg.gateway;
miDevicesUtils.sendWritePayloadToGateway(this, msg, {status: "click", sid: msg.sid});
msg.payload = {
cmd: "write",
data: { status: "click", sid: msg.sid }
};
this.send(msg);
});
}
RED.nodes.registerType("xiaomi-actions click", XiaomiActionSingleClick);
@@ -49,7 +52,11 @@ module.exports = (RED) => {
RED.nodes.createNode(this, config);
this.on('input', (msg) => {
miDevicesUtils.sendWritePayloadToGateway(this, msg, {status: "double_click", sid: msg.sid});
msg.payload = {
cmd: "write",
data: { status: "double_click", sid: msg.sid }
};
this.send(msg);
});
}
RED.nodes.registerType("xiaomi-actions double_click", XiaomiActionDoubleClick);
@@ -59,15 +66,26 @@ module.exports = (RED) => {
*********************************************/
function XiaomiActionGatewayLight(config) {
RED.nodes.createNode(this, config);
this.gateway = RED.nodes.getNode(config.gateway);
this.color = RED.nodes.getNode(config.color);
this.brightness = RED.nodes.getNode(config.brightness);
this.color = config.color;
this.brightness = config.brightness;
this.on('input', (msg) => {
let color = msg.color || this.color;
let brightness = msg.brightness || this.brightness;
let rgb = miDevicesUtils.computeColorValue(brightness, color.red, color.green, color.blue);
miDevicesUtils.sendWritePayloadToGateway(this, msg, {rgb: rgb});
if(msg.sid) {
let rgb = miDevicesUtils.computeColorValue(color.red, color.green, color.blue, brightness);
msg.payload = {
cmd: "write",
data: { rgb: rgb, sid: msg.sid }
};
}
else {
msg.payload = {
color: miDevicesUtils.computeColorValue(color.red, color.green, color.blue),
brightness: brightness
};
}
this.send(msg);
});
}
RED.nodes.registerType("xiaomi-actions gateway_light", XiaomiActionGatewayLight);
@@ -77,15 +95,19 @@ module.exports = (RED) => {
*********************************************/
function XiaomiActionGatewaySound(config) {
RED.nodes.createNode(this, config);
this.gateway = RED.nodes.getNode(config.gateway);
this.mid = config.mid;
this.volume = config.volume;
this.on('input', (msg) => {
miDevicesUtils.sendWritePayloadToGateway(this, msg, {
mid: parseInt(msg.mid || this.mid),
volume: parseInt(msg.volume || this.volume)
});
msg.payload = {
cmd: "write",
data: {
mid: parseInt(msg.mid || this.mid),
volume: parseInt(msg.volume || this.volume),
sid: msg.sid
}
};
this.send(msg);
});
}
RED.nodes.registerType("xiaomi-actions gateway_sound", XiaomiActionGatewaySound);
@@ -95,10 +117,13 @@ module.exports = (RED) => {
*********************************************/
function XiaomiActionGatewayStopSound(config) {
RED.nodes.createNode(this, config);
this.gateway = RED.nodes.getNode(config.gateway);
this.on('input', (msg) => {
miDevicesUtils.sendWritePayloadToGateway(this, msg, { mid: 1000 });
msg.payload = {
cmd: "write",
data: { mid: 1000, sid: msg.sid }
};
this.send(msg);
});
}
RED.nodes.registerType("xiaomi-actions gateway_stop_sound", XiaomiActionGatewayStopSound);
@@ -108,16 +133,18 @@ module.exports = (RED) => {
*********************************************/
function XiaomiActionPowerOn(config) {
RED.nodes.createNode(this, config);
this.gateway = RED.nodes.getNode(config.gateway);
this.on('input', (msg) => {
if(msg.sid){
miDevicesUtils.sendWritePayloadToGateway(this, msg, { status: "on", sid: msg.sid});
msg.payload = {
cmd: "write",
data: { status: "on", sid: msg.sid }
};
}
else {
msg.payload = "off";
this.send(msg);
msg.payload = "on";
}
this.send(msg);
});
}
RED.nodes.registerType("xiaomi-actions on", XiaomiActionPowerOn);
@@ -127,17 +154,32 @@ module.exports = (RED) => {
*********************************************/
function XiaomiActionPowerOff(config) {
RED.nodes.createNode(this, config);
this.gateway = RED.nodes.getNode(config.gateway);
this.on('input', (msg) => {
if(msg.sid){
miDevicesUtils.sendWritePayloadToGateway(this, msg, { status: "off", sid: msg.sid});
msg.payload = {
cmd: "write",
data: { status: "off", sid: msg.sid }
};
}
else {
msg.payload = "off";
this.send(msg);
}
this.send(msg);
});
}
RED.nodes.registerType("xiaomi-actions off", XiaomiActionPowerOff);
/*********************************************
Toggle device
*********************************************/
function XiaomiActionToggle(config) {
RED.nodes.createNode(this, config);
this.on('input', (msg) => {
msg.payload = "toggle";
this.send(msg);
});
}
RED.nodes.registerType("xiaomi-actions toggle", XiaomiActionToggle);
}

View File

@@ -12,11 +12,9 @@ module.exports = (RED) => {
this.gateway = RED.nodes.getNode(config.gateway);
this.onlyModels = getOnlyModelsValue(config.onlyModels || []);
this.excludedSids = config.excludedSids;
console.log(this.onlyModels);
this.isDeviceValid = (device) => {
console.log(device.sid, device.model, this.onlyModels, this.excludeSids);
if((!this.onlyModels || this.onlyModels.length == 0) && (!this.excludedSids || this.excludedSids.length == 0)) {
return true;
}

View File

@@ -88,18 +88,21 @@ module.exports = (RED) => {
}
msg = { payload: jsonMsg };
if(this.gateway && jsonMsg.data.ip && jsonMsg.data.ip === this.gateway.ip) {
RED.nodes.eachNode((tmpNode) => {
if(tmpNode.type.indexOf("xiaomi-gateway") === 0 && tmpNode.gateway == this.gatewayNodeId) {
let tmpNodeInst = RED.nodes.getNode(tmpNode.id);
tmpNodeInst.status({fill:"blue", shape:"dot", text: "online"});
}
});
if(jsonMsg.token) {
this.gateway.lastToken = jsonMsg.token;
if(!this.gateway.sid) {
this.gateway.sid = jsonMsg.sid;
}
}
RED.nodes.eachNode((tmpNode) => {
if(tmpNode.type.indexOf("xiaomi-gateway") === 0 && tmpNode.gateway == this.gatewayNodeId) {
let tmpNodeInst = RED.nodes.getNode(tmpNode.id);
if(tmpNode.type === "xiaomi-gateway out" && !this.gateway.lastToken) {
tmpNodeInst.status({fill:"yellow", shape:"ring", text: "waiting input"});
}
tmpNodeInst.status({fill:"blue", shape:"dot", text: "online"});
}
});
}
this.send(msg);
}
@@ -155,6 +158,9 @@ module.exports = (RED) => {
this.ipv = this.ip && this.ip.indexOf(":") >= 0 ? "udp6" : "udp4";
this.multicast = false;
this.gatewayNodeId = n.gateway;
this.gateway = RED.nodes.getNode(n.gateway);
this.status({fill:"red", shape:"ring", text: "offline"});
var opts = {type:this.ipv, reuseAddr:true};
@@ -193,6 +199,9 @@ module.exports = (RED) => {
} else if (isNaN(por) || (por < 1) || (por > 65535)) {
this.warn(RED._("udp.errors.port-invalid"));
} else {
if(msg.payload.cmd === "write" && !msg.payload.data.key && this.gateway && this.gateway.sid && this.gateway.key && this.gateway.lastToken) {
msg.payload.data.key = miDevicesUtils.getGatewayKey(this.gateway.key, this.gateway.lastToken);
}
var message = Buffer.from(JSON.stringify(msg.payload));
sock.send(message, 0, message.length, por, add, (err, bytes) => {
if (err) {

View File

@@ -5,10 +5,7 @@
defaults: {
gateway: {value:"", type:"xiaomi-configurator"},
name: {value: ""},
sid: {value: "", required: true},
outmsg: {value: "{{click}}"},
outmsgdbcl: {value: "{{double_click}}"},
output: {value: "0"}
sid: {value: "", required: true}
},
inputs: 1,
outputs: 1,

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,79 @@
<script type="text/javascript">
RED.nodes.registerType('xiaomi-yeelight out', {
category: 'xiaomi in out',
color: '#087F8A',
defaults: {
name: {value: ""},
ip: {value: ""},
port: {value:55443, required: true}
},
inputs: 1,
outputs: 0,
paletteLabel: "yeelight out",
icon: "mi-yeelight.png",
align: "right",
label: function () {
return this.name || "yeelight out";
}
});
</script>
<script type="text/x-red" data-template-name="xiaomi-yeelight out">
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div class="form-row">
<label for="node-input-ip"><i class="icon-tag"></i> IP</label>
<input type="text" id="node-input-ip" placeholder="IP">
</div>
<div class="form-row">
<label for="node-input-port"><i class="icon-tag"></i> Port</label>
<input type="text" id="node-input-port" placeholder="Port">
</div>
</script>
<script type="text/x-red" data-help-name="xiaomi-yeelight out">
<p>The Xiaomi Yeelight node</p>
<h3>Inputs</h3>
<dl class="message-properties">
<dt>payload
<span class="property-type">object</span>
</dt>
<dd>
When the message contains a <code>sid</code> field, the node will filter the input and output only if the <code>sid</code> is the device's sid.<br>
<hr>
If the message doesn't contain a <code>sid</code> field, the node will be used to inject <code>sid</code> and <code>gateway</code> fields in the incoming <code>msg</code>.<br>
<hr>
Input Gateway node produces message of type <code>read_ack</code>, <code>heartbeat</code> or <code>report</code>.
</dd>
</dl>
<h3>Outputs</h3>
<ol class="node-ports">
<dl class="message-properties">
<dt>payload <span class="property-type">object</span></dt>
<dd>Data from gateway when used as a filter (see below).</dd>
<dt>sid <span class="property-type">string</span></dt>
<dd>Device SID.</dd>
<dt>gateway <span class="property-type">object</span></dt>
<dd>The <code>xiaomi-configurator</code> object where the device is registred.</dd>
</dl>
</ol>
<h4>Details</h4>
<p>The incoming message is processed if the input <code>sid</code> matches the configured value for this device.</p>
<p>Sample message:</p>
<p><pre>{
cmd: "report"
model: "switch"
sid: "158d000128b124"
short_id: 56773
data: {
status: "click",
batteryLevel: 23
}
}</pre></p>
</script>

View File

@@ -0,0 +1,57 @@
const miDevicesUtils = require('../src/utils');
const Yeelight = require("yeelight2");
module.exports = (RED) => {
function XiaomiYeelightOutputNode(config) {
RED.nodes.createNode(this, config);
this.ip = config.ip;
this.port = config.port;
this.status({fill:"grey", shape:"ring", text:"na"});
this.setupConnection = function(){
try {
this.light = Yeelight(`yeelight://${this.ip}:${this.port}`);
this.status({fill:"blue", shape:"dot", text:"connected"});
} catch(err) {
this.status({fill:"red",shape:"ring",text:err.message});
this.light = null;
this.error(err);
// try to reconnect in 5 minutes
window.setTimeout((function(self) {
return function() {
self.setupConnection.apply(self, arguments);
}
})(this), 1000*60*5);
}
}
if (this.ip && this.port) {
this.setupConnection();
this.on('input', (msg) => {
if(msg.payload === "on") {
this.light && this.light.set_power('on');
}
else if(msg.payload === "off") {
this.light && this.light.set_power('off');
}
else if(msg.payload === "toggle") {
this.light && this.light.toggle();
}
if(msg.payload.color !== undefined) {
this.light && this.light.set_rgb(msg.payload.color);
}
if(msg.payload.brightness !== undefined) {
this.light && this.light.set_bright(msg.payload.brightness);
}
});
this.on('close', () => {
this.light && this.light.exit();
});
}
}
RED.nodes.registerType("xiaomi-yeelight out", XiaomiYeelightOutputNode);
};

View File

@@ -1,6 +1,6 @@
{
"name": "node-red-contrib-mi-devices",
"version": "1.0.6",
"version": "1.1.0",
"description": "A set of nodes to control some of the popular Xiaomi sensors which are connected to the Xiaomi Gateway, and the Gateway itself.",
"repository": {
"type": "git",
@@ -23,7 +23,8 @@
"xiaomi-all": "node-red-contrib-xiaomi-all/xiaomi-all.js",
"xiaomi-configurator": "node-red-contrib-xiaomi-configurator/xiaomi-configurator.js",
"xiaomi-gateway": "node-red-contrib-xiaomi-gateway/xiaomi-gateway.js",
"xiaomi-actions": "node-red-contrib-xiaomi-actions/xiaomi-actions.js"
"xiaomi-actions": "node-red-contrib-xiaomi-actions/xiaomi-actions.js",
"xiaomi-yeelight": "node-red-contrib-xiaomi-yeelight/xiaomi-yeelight.js"
}
},
"author": "Pierre CLEMENT",
@@ -32,7 +33,8 @@
},
"dependencies": {
"cryptojs": "^2.5.3",
"miio": "0.13.0"
"miio": "0.13.0",
"yeelight2": "^1.3.5"
},
"engines": {
"node": ">=4.4.5"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -39,24 +39,12 @@ module.exports = {
return key;
},
sendWritePayloadToGateway: function(node, msg, data) {
let gateway = node.gateway;
if(gateway && gateway.sid && gateway.key && gateway.lastToken) {
data.sid = data.sid || gateway.sid;
data.key = this.getGatewayKey(gateway.key, gateway.lastToken);
msg.payload = {
cmd: "write",
data: data
};
node.send(msg);
}
},
prepareForGatewayRequest: function(node, msg) {
msg.sid = node.sid;
msg.gateway = node.gateway;
},
computeColorValue: function (brightness, red, green, blue) {
return Math.round(256*256*256*brightness) + (256*256*red) + (256*green) + blue;
computeColorValue: function (red, green, blue, brightness) {
return (brightness !== undefined ? 256*256*256*brightness : 0) + (256*256*red) + (256*green) + blue;
},
computeColor: function (rgb) {
var blue = rgb % 256;