2
0

feat(yeelight): handle yeelights

This commit is contained in:
Pierre CLEMENT
2018-03-21 22:52:10 +01:00
parent 50df65d7fc
commit c5afb43b47
31 changed files with 219 additions and 310 deletions

View File

@@ -1,104 +0,0 @@
<!-- The "on" Node -->
<script type="text/javascript">
RED.nodes.registerType('mi-devices-actions on',{
category: 'xiaomi actions',
color: '#64C4CD',
defaults: {
name: {value:""}
},
inputs:1,
outputs:1,
paletteLabel: "on",
icon: "mi-on.png",
label: function() {
return this.name||"power on";
}
});
</script>
<script type="text/x-red" data-template-name="mi-devices-actions on">
<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="mi-devices-actions on">
<p>
Turn input device to on.
</p>
<h3>Outputs</h3>
<ol class="node-ports">
<li>Message to connect to a gateway/yeelight out node.</li>
</ol>
</script>
<!-- The "off" Node -->
<script type="text/javascript">
RED.nodes.registerType('mi-devices-actions off',{
category: 'xiaomi actions',
color: '#64C4CD',
defaults: {
name: {value:""}
},
inputs:1,
outputs:1,
paletteLabel: "off",
icon: "mi-off.png",
label: function() {
return this.name||"power off";
}
});
</script>
<script type="text/x-red" data-template-name="mi-devices-actions off">
<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="mi-devices-actions off">
<p>
Turn input device to off.
</p>
<h3>Outputs</h3>
<ol class="node-ports">
<li>Message to connect to a gateway/yeelight out node.</li>
</ol>
</script>
<!-- The "toggle" Node -->
<script type="text/javascript">
RED.nodes.registerType('mi-devices-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="mi-devices-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="mi-devices-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

@@ -1,57 +0,0 @@
const miDevicesUtils = require('../src/utils');
module.exports = (RED) => {
/*********************************************
Turn device on
*********************************************/
function XiaomiActionPowerOn(config) {
RED.nodes.createNode(this, config);
this.on('input', (msg) => {
if(msg.sid){
msg.payload = {
cmd: "write",
data: { status: "on", sid: msg.sid }
};
}
else {
msg.payload = "on";
}
this.send(msg);
});
}
RED.nodes.registerType("mi-devices-actions on", XiaomiActionPowerOn);
/*********************************************
Turn device off
*********************************************/
function XiaomiActionPowerOff(config) {
RED.nodes.createNode(this, config);
this.on('input', (msg) => {
if(msg.sid){
msg.payload = {
cmd: "write",
data: { status: "off", sid: msg.sid }
};
}
else {
msg.payload = "off";
}
this.send(msg);
});
}
RED.nodes.registerType("mi-devices-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("mi-devices-actions toggle", XiaomiActionToggle);
}

View File

@@ -46,8 +46,7 @@
}, },
"dependencies": { "dependencies": {
"cryptojs": "^2.5.3", "cryptojs": "^2.5.3",
"lumi-aqara": "^1.4.0", "miio": "^0.15.4",
"miio": "^0.15.2",
"yeelight-wifi": "^2.3.0" "yeelight-wifi": "^2.3.0"
}, },
"engines": { "engines": {

View File

@@ -4,7 +4,7 @@ import * as crypto from 'crypto';
import {GatewayServer} from "./GatewayServer"; import {GatewayServer} from "./GatewayServer";
import {GatewayMessage, GatewaySubdevice, Magnet, Motion, Switch, Weather} from "./"; import {GatewayMessage, GatewaySubdevice, Magnet, Motion, Switch, Weather} from "./";
import * as MessageData from "./GatewayMessageData"; import * as MessageData from "./GatewayMessageData";
import {Color} from "../utils/Color"; import {Color} from "../../utils/Color";
export class Gateway extends events.EventEmitter { export class Gateway extends events.EventEmitter {
static iv: Buffer = Buffer.from([0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58, 0x56, 0x2e]); static iv: Buffer = Buffer.from([0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58, 0x56, 0x2e]);

View File

@@ -1,6 +1,6 @@
import * as events from 'events'; import * as events from 'events';
import * as dgram from "dgram"; import * as dgram from "dgram";
import {Gateway} from "./Gateway"; import {Gateway} from "./";
import Timer = NodeJS.Timer; import Timer = NodeJS.Timer;
import {GatewayMessage} from "./GatewayMessage"; import {GatewayMessage} from "./GatewayMessage";
@@ -92,36 +92,6 @@ export class GatewayServer extends events.EventEmitter {
} }
gatewaySid && this._gateways[gatewaySid] && this._gateways[gatewaySid].handleMessage(msg); gatewaySid && this._gateways[gatewaySid] && this._gateways[gatewaySid].handleMessage(msg);
/*if(remote.address == this.addr) {
var msg = message.toString('utf8');
var jsonMsg = JSON.parse(msg);
if(jsonMsg.data) {
jsonMsg.data = JSON.parse(jsonMsg.data) || jsonMsg.data;
if(jsonMsg.data.voltage) {
jsonMsg.data.batteryLevel = miDevicesUtils.computeBatteryLevel(jsonMsg.data.voltage);
}
}
msg = { payload: jsonMsg };
if(this.gateway && jsonMsg.data.ip && jsonMsg.data.ip === this.gateway.ip) {
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);
}*/
}); });
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {

View File

@@ -1,3 +1,4 @@
export * from './';
export * from './Gateway'; export * from './Gateway';
export * from './GatewayMessage'; export * from './GatewayMessage';
export * from './GatewayServer'; export * from './GatewayServer';

View File

@@ -0,0 +1,47 @@
import * as events from 'events';
import * as YeelightSearch from 'yeelight-wifi';
export class YeelightServer extends events.EventEmitter {
private static instance: YeelightServer;
private _bulbs: { [sid: string]: any } = {};
private _bulbsJson: { [sid: string]: any } = {};
static getInstance() {
if (!this.instance) {
this.instance = new YeelightServer();
}
return this.instance;
}
get bulbs(): { [sid: string]: any } {
return this._bulbsJson;
}
getBulb(sid) {
return this._bulbs[sid];
}
discover() {
new Promise(() => {
(new YeelightSearch()).on('found', (bulb: any) => {
bulb.sid = parseInt(bulb.id);
if (!this._bulbs[bulb.sid]) {
this._bulbs[bulb.sid] = bulb;
this._bulbsJson[bulb.sid] = YeelightServer.bulbToJSON(bulb);
this.emit("yeelight-online", bulb.sid);
}
});
});
// TODO: disconected ?
}
static bulbToJSON(bulb) {
return {
sid: bulb.sid,
ip: bulb.hostname,
name: bulb.name,
model: bulb.model
};
}
}

View File

View File

@@ -15,13 +15,11 @@ export default (RED: Red) => {
protected setListeners() { protected setListeners() {
(<any> this).on('input', (msg) => { (<any> this).on('input', (msg) => {
if (msg.sid) { msg.payload = {
msg.payload = { action: "setLight",
action: "setLight", color: msg.color || this.color,
color: msg.color || this.color, brightness: msg.brightness || this.brightness
brightness: msg.brightness || this.brightness };
};
}
(<any> this).send(msg); (<any> this).send(msg);
}); });
} }

View File

@@ -0,0 +1,20 @@
import {Red, NodeProperties} from "node-red";
import {Constants} from "../constants";
export default (RED: Red, action: string) => {
class ToggleAction {
constructor(props: NodeProperties) {
RED.nodes.createNode(<any> this, props);
(<any> this).setListeners();
}
protected setListeners() {
(<any> this).on('input', (msg) => {
msg.payload = { action };
(<any> this).send(msg);
});
}
}
RED.nodes.registerType(`${Constants.NODES_PREFIX}-actions ${action}`, <any> ToggleAction);
};

View File

@@ -32,4 +32,28 @@
<%- include('./Light', {}) %> <%- include('./Light', {}) %>
<%- include('./GatewayPlaySound', {}) %> <%- include('./GatewayPlaySound', {}) %>
<%- include('./GatewayStopSound', {}) %> <%- include('./GatewayStopSound', {}) %>
<%# ---------------------------------- turn_on ---------------------------------- %>
<%- include('./Action', {
type: "turn_on",
label: "turn on",
icon: "mi-on",
docTitle: "Turn device on."
}) %>
<%# ---------------------------------- double_click ---------------------------------- %>
<%- include('./Action', {
type: "turn_off",
label: "turn off",
icon: "mi-off",
docTitle: "Turn device off."
}) %>
<%# ---------------------------------- double_click ---------------------------------- %>
<%- include('./Action', {
type: "toggle",
label: "toggle",
icon: "mi-toggle",
docTitle: "Toggle device."
}) %>

View File

@@ -5,6 +5,7 @@ import {default as WriteAction} from './WriteAction';
import {default as Light} from './Light'; import {default as Light} from './Light';
import {default as GatewayPlaySound} from './GatewayPlaySound'; import {default as GatewayPlaySound} from './GatewayPlaySound';
import {default as GatewayStopSound} from './GatewayStopSound'; import {default as GatewayStopSound} from './GatewayStopSound';
import {default as ToggleAction} from './ToggleAction';
export = (RED: Red) => { export = (RED: Red) => {
["read", "get_id_list"].forEach((action) => { ["read", "get_id_list"].forEach((action) => {
@@ -17,4 +18,7 @@ export = (RED: Red) => {
Light(RED); Light(RED);
GatewayPlaySound(RED); GatewayPlaySound(RED);
GatewayStopSound(RED); GatewayStopSound(RED);
["turn_on", "turn_off", "toggle"].forEach(action => {
ToggleAction(RED, action);
});
}; };

View File

@@ -1,5 +1,4 @@
import { Red, NodeProperties } from "node-red"; import { Red } from "node-red";
import * as LumiAqara from 'lumi-aqara';
import {default as All} from "./All"; import {default as All} from "./All";
import {default as Plug} from "./Plug"; import {default as Plug} from "./Plug";

View File

@@ -1,5 +1,4 @@
import { Red, Node, NodeProperties } from "node-red"; import { Red, Node, NodeProperties } from "node-red";
import { LumiAqara } from "../../../typings/index";
import { Constants } from "../constants"; import { Constants } from "../constants";
export interface IGatewayNode extends Node { export interface IGatewayNode extends Node {

View File

@@ -1,8 +1,8 @@
import {Red, Node, NodeProperties} from "node-red"; import {Red, Node, NodeProperties} from "node-red";
import {Constants} from "../constants"; import {Constants} from "../constants";
import {GatewayServer} from "../../devices/GatewayServer"; import {GatewayServer} from "../../devices/gateway/GatewayServer";
import {Gateway} from "../../devices/Gateway"; import {Gateway} from "../../devices/gateway/Gateway";
import {GatewaySubdevice} from "../../devices/GatewaySubdevice"; import {GatewaySubdevice} from "../../devices/gateway/GatewaySubdevice";
import {isString} from "util"; import {isString} from "util";
export interface IGatewayConfiguratorNode extends Node { export interface IGatewayConfiguratorNode extends Node {

View File

@@ -1,6 +1,6 @@
import {Red, Node, NodeProperties} from 'node-red'; import {Red, Node, NodeProperties} from 'node-red';
import {Constants} from '../constants'; import {Constants} from '../constants';
import {Gateway} from "../../devices/Gateway"; import {Gateway} from "../../devices/gateway/Gateway";
export interface IGatewayInNode extends Node { export interface IGatewayInNode extends Node {
gatewayConf: any; gatewayConf: any;

View File

@@ -1,6 +1,6 @@
import {Red, NodeProperties} from "node-red"; import {Red, NodeProperties} from "node-red";
import {Constants} from "../constants"; import {Constants} from "../constants";
import {GatewayServer} from "../../devices/GatewayServer"; import {GatewayServer} from "../../devices/gateway/GatewayServer";
export default (RED: Red) => { export default (RED: Red) => {
class GatewayOut { class GatewayOut {

View File

@@ -1,7 +1,6 @@
import { Red, NodeProperties } from "node-red"; import { Red } from "node-red";
import * as LumiAqara from 'lumi-aqara';
import { GatewayServer } from "../../devices/GatewayServer"; import { GatewayServer } from "../../devices/gateway/GatewayServer";
import {default as GatewayConfigurator} from "./GatewayConfigurator"; import {default as GatewayConfigurator} from "./GatewayConfigurator";
import {default as Gateway} from "./Gateway"; import {default as Gateway} from "./Gateway";
import {default as GatewayIn} from "./GatewayIn"; import {default as GatewayIn} from "./GatewayIn";

View File

@@ -1,34 +0,0 @@
import { Red } from "node-red";
import * as YeelightSearch from 'yeelight-wifi';
import { Constants } from "../constants";
import { IYeelightConfiguratorNode } from "./YeelightConfigurator";
export class Searcher {
static _bulbs:any[] = [];
static discover(RED:Red) {
new Promise(() => {
(new YeelightSearch()).on('found', (bulb:any) => {
this._bulbs.push({
name: bulb.name,
model: bulb.model,
sid: parseInt(bulb.id),
ip: bulb.hostname
});
RED.nodes.eachNode((tmpNode) => {
if(tmpNode.type.indexOf(`${Constants.NODES_PREFIX}-yeelight configurator`) === 0) {
let tmpNodeInst = <IYeelightConfiguratorNode> RED.nodes.getNode(tmpNode.id);
if(tmpNodeInst.ip == bulb.hostname || tmpNodeInst.sid == parseInt(bulb.id)) {
tmpNodeInst.bulb = bulb;
}
}
});
});
});
}
static get bulbs() {
return this._bulbs;
}
}

View File

@@ -3,23 +3,22 @@
category: 'config', category: 'config',
defaults: { defaults: {
name: {value: ""}, name: {value: ""},
ip: {value: ""},
sid: {value: ""} sid: {value: ""}
}, },
label: function () { label: function () {
return this.name || "yeelight conf"; return this.name || "yeelight conf";
}, },
oneditprepare: function() { oneditprepare: function() {
RED.settings.miDevicesYeelightConfiguratorDiscoveredBulbs.forEach(function(bulb, index) { var foundBulbs = RED.settings.miDevicesYeelightConfiguratorDiscoveredBulbs;
Object.keys(foundBulbs).forEach(function(sid) {
var bulb = foundBulbs[sid];
$('#discovered-bulbs').append('<option value="' + bulb.sid + '">' + (bulb.name || bulb.sid) + ' - ' + bulb.model + ' - ' + bulb.ip + '</option>'); $('#discovered-bulbs').append('<option value="' + bulb.sid + '">' + (bulb.name || bulb.sid) + ' - ' + bulb.model + ' - ' + bulb.ip + '</option>');
}); });
var node = this;
$('#discovered-bulbs').on('change', function() { $('#discovered-bulbs').on('change', function() {
var sid = $('#discovered-bulbs').val(); var sid = $('#discovered-bulbs').val();
var bulb = sid && RED.settings.miDevicesYeelightConfiguratorDiscoveredBulbs.filter(function(e) { return e.sid == sid })[0]; var bulb = foundBulbs[sid];
$("#node-config-input-name").val(bulb && bulb.name); $("#node-config-input-name").val(bulb && bulb.name);
$("#node-config-input-sid").val(bulb && bulb.sid); $("#node-config-input-sid").val(bulb && bulb.sid);
$("#node-config-input-ip").val("");
}); });
} }
}); });
@@ -37,15 +36,10 @@
<label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label> <label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-config-input-name" placeholder="Name"> <input type="text" id="node-config-input-name" placeholder="Name">
</div> </div>
<div class="form-row">
<label for="node-config-input-ip"><i class="fa fa-compass"></i> IP</label>
<input type="text" id="node-config-input-ip" placeholder="IP">
</div>
<div class="form-row"> <div class="form-row">
<label for="node-config-input-sid"><i class="fa fa-barcode"></i> SID</label> <label for="node-config-input-sid"><i class="fa fa-barcode"></i> SID</label>
<input type="text" id="node-config-input-sid" placeholder="sid"> <input type="text" id="node-config-input-sid" placeholder="sid">
</div> </div>
<p>Note: use <code>ip</code> or <code>sid</code> - <code>sid</code> is better.</p>
</script> </script>
<script type="text/x-red" data-help-name="<%= NODES_PREFIX %>-yeelight configurator"> <script type="text/x-red" data-help-name="<%= NODES_PREFIX %>-yeelight configurator">

View File

@@ -1,31 +1,49 @@
import { Red, Node, NodeProperties, NodeStatus, ClearNodeStatus } from "node-red"; import {Red, Node, NodeProperties, NodeStatus, ClearNodeStatus} from "node-red";
import { Constants } from "../constants"; import {Constants} from "../constants";
import { Searcher } from "./Searcher"; import {YeelightServer} from "../../devices/yeelight/YeelightServer";
export interface IYeelightConfiguratorNode extends Node { export interface IYeelightConfiguratorNode extends Node {
ip:string; ip: string;
sid:number; sid: number;
bulb:any; bulb: any;
on(event: "bulbFound", listener: () => void): any; on(event: "bulb-online", listener: () => void): any;
on(event: "bulb-offline", listener: () => void): any;
} }
export default (RED:Red) => { export default (RED: Red) => {
class YeelightConfigurator { class YeelightConfigurator {
ip:string; ip: string;
sid:number; sid: number;
_bulb:any; _bulb: any;
constructor(props: NodeProperties) { constructor(props: NodeProperties) {
RED.nodes.createNode(<any> this, props); RED.nodes.createNode(<any> this, props);
let {ip, sid} = <any> props; let {sid} = <any> props;
this.sid = sid; this.sid = parseInt(sid);
this.ip = ip;
if (this.sid) {
this.setBulb();
}
let server = YeelightServer.getInstance();
server.on('yeelight-online', (sid) => {
if (sid === this.sid) {
this.setBulb();
(<any> this).emit('bulb-online');
}
});
server.on('yeelight-offline', (sid) => {
if (sid === this.sid) {
this._bulb = null;
(<any> this).emit('bulb-offline');
}
});
} }
set bulb(bulb) { protected setBulb() {
this._bulb = bulb; this._bulb = YeelightServer.getInstance().getBulb(this.sid);
(<any> this).emit('bulbFound');
} }
get bulb() { get bulb() {
@@ -35,7 +53,10 @@ export default (RED:Red) => {
RED.nodes.registerType(`${Constants.NODES_PREFIX}-yeelight configurator`, <any> YeelightConfigurator, { RED.nodes.registerType(`${Constants.NODES_PREFIX}-yeelight configurator`, <any> YeelightConfigurator, {
settings: { settings: {
miDevicesYeelightConfiguratorDiscoveredBulbs: { value: Searcher.bulbs, exportable: true } miDevicesYeelightConfiguratorDiscoveredBulbs: {
value: YeelightServer.getInstance().bulbs,
exportable: true
}
} }
}); });
}; };

View File

@@ -1,50 +1,79 @@
import { Red, Node, NodeProperties, NodeStatus, ClearNodeStatus } from "node-red"; import {Red, Node, NodeProperties, NodeStatus, ClearNodeStatus} from "node-red";
import { Constants } from "../constants"; import {Constants} from "../constants";
import { IYeelightConfiguratorNode } from "./YeelightConfigurator"; import {IYeelightConfiguratorNode} from "./YeelightConfigurator";
export interface IYeelightOutNode { export interface IYeelightOutNode {
yeelightConfNode:IYeelightConfiguratorNode; yeelightConf: IYeelightConfiguratorNode;
} }
export default (RED:Red) => { export default (RED: Red) => {
class YeelightOut implements IYeelightOutNode { class YeelightOut implements IYeelightOutNode {
yeelightConfNode:IYeelightConfiguratorNode; yeelightConf: IYeelightConfiguratorNode;
constructor(props: NodeProperties) { constructor(props: NodeProperties) {
RED.nodes.createNode(<any> this, props); RED.nodes.createNode(<any> this, props);
this.yeelightConfNode = <any> RED.nodes.getNode((<any> props).yeelight); this.yeelightConf = <any> RED.nodes.getNode((<any> props).yeelight);
(<any> this).status({fill: "red", shape: "ring", text: "offline"});
this.yeelightConfNode && this.yeelightConfNode.on('bulbFound', () => { (<any>this).status({fill: "red", shape: "ring", text: "offline"});
(<any>this).status({fill:"blue", shape:"dot", text: "online"});
}); if (this.yeelightConf.bulb) {
this.yeelightOnline();
}
this.yeelightConf.on('bulb-online', () => this.yeelightOnline());
this.yeelightConf.on('bulb-offline', () => this.yeelightOffline());
this.setListener(); this.setListener();
} }
protected yeelightOnline() {
(<any>this).status({fill: "blue", shape: "dot", text: "online"});
}
protected yeelightOffline() {
(<any>this).status({fill: "red", shape: "ring", text: "offline"});
}
protected setListener() { protected setListener() {
(<any> this).on('input', (msg) => { (<any> this).on("input", (msg) => {
if (this.yeelightConfNode.bulb) { let bulb = this.yeelightConf.bulb;
if(msg.payload === "on") { if (msg.hasOwnProperty("payload") && bulb) {
this.yeelightConfNode.bulb.turnOn(); switch (msg.payload.action) {
} case 'turn_on':
else if(msg.payload === "off") { bulb.turnOn();
this.yeelightConfNode.bulb.turnOff(); break;
} case 'turn_off':
else if(msg.payload === "toggle") { bulb.turnOff();
this.yeelightConfNode.bulb.toggle(); break;
} case 'toggle':
bulb.toggle();
if(msg.payload.color !== undefined) { break;
// TODO: revoir la couleur case 'setLight':
this.yeelightConfNode.bulb.setRGB(msg.payload.color); if (msg.payload.color !== undefined) {
} let rgb = msg.payload.color.blue | (msg.payload.color.green << 8) | (msg.payload.color.red << 16);
if(msg.payload.brightness !== undefined) { let hex = '#' + (0x1000000 + rgb).toString(16).slice(1);
this.yeelightConfNode.bulb.setBrightness(msg.payload.brightness); bulb.setRGB(hex);
}
(msg.payload.brightness !== undefined) && bulb.setBrightness(Math.max(1, msg.payload.brightness));
break;
} }
} }
}); });
/*(<any> this).on('input', (msg) => {
if (this.yeelightConf.bulb) {
if(msg.payload.color !== undefined) {
// TODO: revoir la couleur
this.yeelightConf.bulb.setRGB(msg.payload.color);
}
if(msg.payload.brightness !== undefined) {
this.yeelightConf.bulb.setBrightness(msg.payload.brightness);
}
}
});*/
} }
} }

View File

@@ -1,12 +1,11 @@
import { Red, NodeProperties } from "node-red"; import { Red } from "node-red";
import * as YeelightSearch from 'yeelight-wifi';
import { Searcher } from "./Searcher"; import { YeelightServer } from "../../devices/yeelight/YeelightServer";
import {default as YeelightConfigurator} from "./YeelightConfigurator"; import {default as YeelightConfigurator} from "./YeelightConfigurator";
import {default as YeelightOut} from "./YeelightOut"; import {default as YeelightOut} from "./YeelightOut";
export = (RED:Red) => { export = (RED:Red) => {
Searcher.discover(RED); YeelightServer.getInstance().discover();
YeelightConfigurator(RED); YeelightConfigurator(RED);
YeelightOut(RED); YeelightOut(RED);

View File

@@ -5,7 +5,8 @@
"inlineSourceMap": false, "inlineSourceMap": false,
"outDir": "dist/", "outDir": "dist/",
"rootDir": "./src", "rootDir": "./src",
"moduleResolution": "node" "moduleResolution": "node",
"noImplicitAny": false
}, },
"include": [ "include": [
"src/**/*.ts", "src/**/*.ts",