commit
3fa3c52913
5 changed files with 202 additions and 86 deletions
17
plejd/api.js
17
plejd/api.js
|
|
@ -8,7 +8,7 @@ API_LOGIN_URL = 'login';
|
||||||
API_SITES_URL = 'functions/getSites';
|
API_SITES_URL = 'functions/getSites';
|
||||||
|
|
||||||
// #region logging
|
// #region logging
|
||||||
const debug = '';
|
let debug = '';
|
||||||
|
|
||||||
const getLogger = () => {
|
const getLogger = () => {
|
||||||
const consoleLogger = msg => console.log('plejd-api', msg);
|
const consoleLogger = msg => console.log('plejd-api', msg);
|
||||||
|
|
@ -34,6 +34,15 @@ class PlejdApi extends EventEmitter {
|
||||||
this.site = null;
|
this.site = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateSettings(settings) {
|
||||||
|
if (settings.debug) {
|
||||||
|
debug = 'console';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debug = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
login() {
|
login() {
|
||||||
logger('login()');
|
logger('login()');
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
@ -55,7 +64,7 @@ class PlejdApi extends EventEmitter {
|
||||||
'password': this.password
|
'password': this.password
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
logger('got session token response');
|
console.log('plejd-api: got session token response');
|
||||||
self.sessionToken = response.data.sessionToken;
|
self.sessionToken = response.data.sessionToken;
|
||||||
self.emit('loggedIn');
|
self.emit('loggedIn');
|
||||||
})
|
})
|
||||||
|
|
@ -86,14 +95,14 @@ class PlejdApi extends EventEmitter {
|
||||||
|
|
||||||
instance.post(API_SITES_URL)
|
instance.post(API_SITES_URL)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
logger('got sites response');
|
console.log('plejd-api: got sites response');
|
||||||
self.site = response.data.result.find(x => x.site.title == self.siteName);
|
self.site = response.data.result.find(x => x.site.title == self.siteName);
|
||||||
self.cryptoKey = self.site.plejdMesh.cryptoKey;
|
self.cryptoKey = self.site.plejdMesh.cryptoKey;
|
||||||
|
|
||||||
callback(self.cryptoKey);
|
callback(self.cryptoKey);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.log('error: unable to retrieve the crypto key. error: ' + error);
|
console.log('error: unable to retrieve the crypto key. error: ' + error + ' (code: ' + error.response.status + ')');
|
||||||
return Promise.reject('unable to retrieve the crypto key. error: ' + error);
|
return Promise.reject('unable to retrieve the crypto key. error: ' + error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
127
plejd/ble.js
127
plejd/ble.js
|
|
@ -34,6 +34,11 @@ const STATE_DISCONNECTED = 'disconnected';
|
||||||
const STATE_UNINITIALIZED = 'uninitialized';
|
const STATE_UNINITIALIZED = 'uninitialized';
|
||||||
const STATE_INITIALIZED = 'initialized';
|
const STATE_INITIALIZED = 'initialized';
|
||||||
|
|
||||||
|
const BLE_CMD_DIM_CHANGE = '00c8';
|
||||||
|
const BLE_CMD_DIM2_CHANGE = '0098';
|
||||||
|
const BLE_CMD_STATE_CHANGE = '0097';
|
||||||
|
const BLE_CMD_SCENE_TRIG = '0021';
|
||||||
|
|
||||||
class PlejdService extends EventEmitter {
|
class PlejdService extends EventEmitter {
|
||||||
constructor(cryptoKey, keepAlive = false) {
|
constructor(cryptoKey, keepAlive = false) {
|
||||||
super();
|
super();
|
||||||
|
|
@ -51,6 +56,8 @@ class PlejdService extends EventEmitter {
|
||||||
|
|
||||||
this.writeQueue = [];
|
this.writeQueue = [];
|
||||||
|
|
||||||
|
this.plejdDevices = {};
|
||||||
|
|
||||||
// Holds a reference to all characteristics
|
// Holds a reference to all characteristics
|
||||||
this.characteristicState = STATE_UNINITIALIZED;
|
this.characteristicState = STATE_UNINITIALIZED;
|
||||||
this.characteristics = {
|
this.characteristics = {
|
||||||
|
|
@ -64,13 +71,53 @@ class PlejdService extends EventEmitter {
|
||||||
this.wireEvents();
|
this.wireEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
turnOn(id, brightness) {
|
updateSettings(settings) {
|
||||||
logger('turning on ' + id + ' at brightness ' + brightness);
|
if (settings.debug) {
|
||||||
|
debug = 'console';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debug = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
turnOn(id, command) {
|
||||||
|
logger('turning on ' + id + ' at brightness ' + (!command.brightness ? 255 : command.brightness));
|
||||||
|
const brightness = command.brightness ? command.brightness : 0;
|
||||||
|
|
||||||
|
if (command.transition) {
|
||||||
|
// we have a transition time, split the target brightness
|
||||||
|
// into pieces spread of the transition time
|
||||||
|
const steps = command.transition * 2;
|
||||||
|
const brightnessStep = brightness / steps;
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
const transitionRef = setInterval(() => {
|
||||||
|
let currentBrightness = parseInt((brightnessStep * i) + 1);
|
||||||
|
if (currentBrightness > 254) {
|
||||||
|
currentBrightness = 254;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._turnOn(id, currentBrightness);
|
||||||
|
|
||||||
|
if (i >= steps) {
|
||||||
|
clearInterval(transitionRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._turnOn(id, brightness);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_turnOn(id, brightness) {
|
||||||
var payload;
|
var payload;
|
||||||
if (!brightness) {
|
if (!brightness || brightness === 0) {
|
||||||
|
logger('no brightness specified, setting to previous known.');
|
||||||
payload = Buffer.from((id).toString(16).padStart(2, '0') + '0110009701', 'hex');
|
payload = Buffer.from((id).toString(16).padStart(2, '0') + '0110009701', 'hex');
|
||||||
} else {
|
} else {
|
||||||
|
logger('brightness is ' + brightness);
|
||||||
brightness = brightness << 8 | brightness;
|
brightness = brightness << 8 | brightness;
|
||||||
payload = Buffer.from((id).toString(16).padStart(2, '0') + '0110009801' + (brightness).toString(16).padStart(4, '0'), 'hex');
|
payload = Buffer.from((id).toString(16).padStart(2, '0') + '0110009801' + (brightness).toString(16).padStart(4, '0'), 'hex');
|
||||||
}
|
}
|
||||||
|
|
@ -78,9 +125,39 @@ class PlejdService extends EventEmitter {
|
||||||
this.write(payload);
|
this.write(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
turnOff(id) {
|
turnOff(id, command) {
|
||||||
logger('turning off ' + id);
|
logger('turning off ' + id);
|
||||||
|
|
||||||
|
if (command.transition) {
|
||||||
|
// we have a transition time, split the target brightness (which will be 0)
|
||||||
|
// into pieces spread of the transition time
|
||||||
|
const initialBrightness = this.plejdDevices[id] ? this.plejdDevices[id].dim : 250;
|
||||||
|
const steps = command.transition * 2;
|
||||||
|
const brightnessStep = initialBrightness / steps;
|
||||||
|
let currentBrightness = initialBrightness;
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
const transitionRef = setInterval(() => {
|
||||||
|
currentBrightness = parseInt(initialBrightness - (brightnessStep * i));
|
||||||
|
if (currentBrightness <= 0 || i >= steps) {
|
||||||
|
clearInterval(transitionRef);
|
||||||
|
|
||||||
|
// finally, we turn it off
|
||||||
|
this._turnOff(id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._turnOn(id, currentBrightness);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._turnOff(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_turnOff(id) {
|
||||||
var payload = Buffer.from((id).toString(16).padStart(2, '0') + '0110009700', 'hex');
|
var payload = Buffer.from((id).toString(16).padStart(2, '0') + '0110009700', 'hex');
|
||||||
this.write(payload);
|
this.write(payload);
|
||||||
}
|
}
|
||||||
|
|
@ -143,11 +220,15 @@ class PlejdService extends EventEmitter {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
logger('connecting to ' + this.device.id + ' with addr ' + this.device.address + ' and rssi ' + this.device.rssi);
|
console.log('connecting to ' + this.device.id + ' with addr ' + this.device.address + ' and rssi ' + this.device.rssi);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (self.state !== STATE_CONNECTED && self.state !== STATE_AUTHENTICATED) {
|
if (self.state !== STATE_CONNECTED && self.state !== STATE_AUTHENTICATED) {
|
||||||
if (self.deviceIdx < Object.keys(self.devices).length) {
|
if (self.deviceIdx < Object.keys(self.devices).length) {
|
||||||
logger('connection timed out after 10 s. trying next.');
|
logger('connection timed out after 10 s. cleaning up and trying next.');
|
||||||
|
|
||||||
|
self.device.removeAllListeners('servicesDiscover');
|
||||||
|
self.device.removeAllListeners('connect');
|
||||||
|
self.device.removeAllListeners('disconnect');
|
||||||
|
|
||||||
self.deviceIdx++;
|
self.deviceIdx++;
|
||||||
self.connect();
|
self.connect();
|
||||||
|
|
@ -168,12 +249,16 @@ class PlejdService extends EventEmitter {
|
||||||
|
|
||||||
disconnect() {
|
disconnect() {
|
||||||
logger('disconnect()');
|
logger('disconnect()');
|
||||||
if (this.state !== STATE_CONNECTED) {
|
if (this.state !== STATE_CONNECTED && this.state !== STATE_AUTHENTICATED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
clearInterval(this.pingRef);
|
clearInterval(this.pingRef);
|
||||||
|
|
||||||
|
this.device.removeAllListeners('servicesDiscover');
|
||||||
|
this.device.removeAllListeners('connect');
|
||||||
|
this.device.removeAllListeners('disconnect');
|
||||||
|
|
||||||
this.unsubscribeCharacteristics();
|
this.unsubscribeCharacteristics();
|
||||||
this.device.disconnect();
|
this.device.disconnect();
|
||||||
|
|
||||||
|
|
@ -435,19 +520,39 @@ class PlejdService extends EventEmitter {
|
||||||
let dim = 0;
|
let dim = 0;
|
||||||
let device = parseInt(decoded[0], 10);
|
let device = parseInt(decoded[0], 10);
|
||||||
|
|
||||||
if (decoded.toString('hex', 3, 5) === '00c8' || decoded.toString('hex', 3, 5) === '0098') {
|
if (decoded.length < 5) {
|
||||||
|
// ignore the notification since too small
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cmd = decoded.toString('hex', 3, 5);
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
logger('raw event received: ' + decoded.toString('hex'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd === BLE_CMD_DIM_CHANGE || cmd === BLE_CMD_DIM2_CHANGE) {
|
||||||
state = parseInt(decoded.toString('hex', 5, 6), 10);
|
state = parseInt(decoded.toString('hex', 5, 6), 10);
|
||||||
dim = parseInt(decoded.toString('hex', 6, 8), 16) >> 8;
|
dim = parseInt(decoded.toString('hex', 6, 8), 16) >> 8;
|
||||||
|
|
||||||
logger('d: ' + device + ' got state+dim update: ' + state + ' - ' + dim);
|
logger('d: ' + device + ' got state+dim update: ' + state + ' - ' + dim);
|
||||||
this.emit('dimChanged', device, state, dim);
|
this.emit('stateChanged', device, { state: state, brightness: dim });
|
||||||
}
|
}
|
||||||
else if (decoded.toString('hex', 3, 5) === '0097') {
|
else if (cmd === BLE_CMD_STATE_CHANGE) {
|
||||||
state = parseInt(decoded.toString('hex', 5, 6), 10);
|
state = parseInt(decoded.toString('hex', 5, 6), 10);
|
||||||
|
|
||||||
logger('d: ' + device + ' got state update: ' + state);
|
logger('d: ' + device + ' got state update: ' + state);
|
||||||
this.emit('stateChanged', device, state);
|
this.emit('stateChanged', device, { state: state });
|
||||||
}
|
}
|
||||||
|
else if (cmd === BLE_CMD_SCENE_TRIG) {
|
||||||
|
const scene = parseInt(decoded.toString('hex', 5, 6), 10);
|
||||||
|
this.emit('sceneTriggered', device, scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.plejdDevices[device] = {
|
||||||
|
state: state,
|
||||||
|
dim: dim
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
wireEvents() {
|
wireEvents() {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Plejd",
|
"name": "Plejd",
|
||||||
"version": "0.1.1",
|
"version": "0.2.0",
|
||||||
"slug": "plejd",
|
"slug": "plejd",
|
||||||
"description": "Adds support for the Swedish home automation devices from Plejd.",
|
"description": "Adds support for the Swedish home automation devices from Plejd.",
|
||||||
"url": "https://github.com/icanos/hassio-plejd/",
|
"url": "https://github.com/icanos/hassio-plejd/",
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,11 @@ const mqtt = require('./mqtt');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const PlejdService = require('./ble');
|
const PlejdService = require('./ble');
|
||||||
|
|
||||||
|
const version = "0.2.0";
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
console.log('starting Plejd add-on v. ' + version);
|
||||||
|
|
||||||
const rawData = fs.readFileSync('/data/plejd.json');
|
const rawData = fs.readFileSync('/data/plejd.json');
|
||||||
const config = JSON.parse(rawData);
|
const config = JSON.parse(rawData);
|
||||||
|
|
||||||
|
|
@ -28,29 +32,33 @@ async function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// subscribe to changes from Plejd
|
// subscribe to changes from Plejd
|
||||||
plejd.on('stateChanged', (deviceId, state) => {
|
plejd.on('stateChanged', (deviceId, command) => {
|
||||||
client.updateState(deviceId, state);
|
client.updateState(deviceId, command);
|
||||||
});
|
});
|
||||||
plejd.on('dimChanged', (deviceId, state, dim) => {
|
|
||||||
client.updateState(deviceId, state);
|
plejd.on('sceneTriggered', (scene) => {
|
||||||
client.updateBrightness(deviceId, dim);
|
client.sceneTriggered(scene);
|
||||||
});
|
});
|
||||||
|
|
||||||
// subscribe to changes from HA
|
// subscribe to changes from HA
|
||||||
client.on('stateChanged', (deviceId, state) => {
|
client.on('stateChanged', (deviceId, command) => {
|
||||||
if (state) {
|
if (command.state === 'ON') {
|
||||||
plejd.turnOn(deviceId);
|
plejd.turnOn(deviceId, command);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
plejd.turnOff(deviceId);
|
plejd.turnOff(deviceId, command);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
client.on('brightnessChanged', (deviceId, brightness) => {
|
|
||||||
if (brightness > 0) {
|
client.on('settingsChanged', (settings) => {
|
||||||
plejd.turnOn(deviceId, brightness);
|
if (settings.module === 'mqtt') {
|
||||||
|
client.updateSettings(settings);
|
||||||
}
|
}
|
||||||
else {
|
else if (settings.module === 'ble') {
|
||||||
plejd.turnOff(deviceId);
|
plejd.updateSettings(settings);
|
||||||
|
}
|
||||||
|
else if (settings.module === 'api') {
|
||||||
|
plejdApi.updateSettings(settings);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
104
plejd/mqtt.js
104
plejd/mqtt.js
|
|
@ -5,7 +5,7 @@ const _ = require('lodash');
|
||||||
const startTopic = 'hass/status';
|
const startTopic = 'hass/status';
|
||||||
|
|
||||||
// #region logging
|
// #region logging
|
||||||
const debug = '';
|
let debug = '';
|
||||||
|
|
||||||
const getLogger = () => {
|
const getLogger = () => {
|
||||||
const consoleLogger = msg => console.log('plejd-mqtt', msg);
|
const consoleLogger = msg => console.log('plejd-mqtt', msg);
|
||||||
|
|
@ -27,32 +27,19 @@ const getSubscribePath = () => `${discoveryPrefix}/+/${nodeId}/#`;
|
||||||
const getPath = ({ id, type }) =>
|
const getPath = ({ id, type }) =>
|
||||||
`${discoveryPrefix}/${type}/${nodeId}/${id}`;
|
`${discoveryPrefix}/${type}/${nodeId}/${id}`;
|
||||||
const getConfigPath = plug => `${getPath(plug)}/config`;
|
const getConfigPath = plug => `${getPath(plug)}/config`;
|
||||||
const getAvailabilityTopic = plug => `${getPath(plug)}/availability`;
|
|
||||||
const getStateTopic = plug => `${getPath(plug)}/state`;
|
const getStateTopic = plug => `${getPath(plug)}/state`;
|
||||||
const getBrightnessCommandTopic = plug => `${getPath(plug)}/setBrightness`;
|
|
||||||
const getBrightnessTopic = plug => `${getPath(plug)}/brightness`;
|
|
||||||
const getCommandTopic = plug => `${getPath(plug)}/set`;
|
const getCommandTopic = plug => `${getPath(plug)}/set`;
|
||||||
|
const getSceneEventTopic = () => `plejd/event/scene`;
|
||||||
const getDiscoveryDimmablePayload = device => ({
|
const getSettingsTopic = () => `plejd/settings`;
|
||||||
name: device.name,
|
|
||||||
unique_id: `light.plejd.${device.name.toLowerCase().replace(/ /g, '')}`,
|
|
||||||
state_topic: getStateTopic(device),
|
|
||||||
command_topic: getCommandTopic(device),
|
|
||||||
brightness_command_topic: getBrightnessCommandTopic(device),
|
|
||||||
brightness_state_topic: getBrightnessTopic(device),
|
|
||||||
payload_on: 1,
|
|
||||||
payload_off: 0,
|
|
||||||
optimistic: false
|
|
||||||
});
|
|
||||||
|
|
||||||
const getDiscoveryPayload = device => ({
|
const getDiscoveryPayload = device => ({
|
||||||
|
schema: 'json',
|
||||||
name: device.name,
|
name: device.name,
|
||||||
unique_id: `light.plejd.${device.name.toLowerCase().replace(/ /g, '')}`,
|
unique_id: `light.plejd.${device.name.toLowerCase().replace(/ /g, '')}`,
|
||||||
state_topic: getStateTopic(device),
|
state_topic: getStateTopic(device),
|
||||||
command_topic: getCommandTopic(device),
|
command_topic: getCommandTopic(device),
|
||||||
payload_on: 1,
|
optimistic: false,
|
||||||
payload_off: 0,
|
brightness: `${device.dimmable}`
|
||||||
optimistic: false
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
@ -92,6 +79,12 @@ class MqttClient extends EventEmitter {
|
||||||
logger('error: unable to subscribe to control topics');
|
logger('error: unable to subscribe to control topics');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.client.subscribe(getSettingsTopic(), (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.log('error: could not subscribe to settings topic');
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.client.on('close', () => {
|
this.client.on('close', () => {
|
||||||
|
|
@ -99,28 +92,33 @@ class MqttClient extends EventEmitter {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.client.on('message', (topic, message) => {
|
this.client.on('message', (topic, message) => {
|
||||||
const command = message.toString();
|
//const command = message.toString();
|
||||||
|
const command = JSON.parse(message.toString());
|
||||||
|
|
||||||
if (topic === startTopic) {
|
if (topic === startTopic) {
|
||||||
logger('home assistant has started. lets do discovery.');
|
logger('home assistant has started. lets do discovery.');
|
||||||
self.emit('connected');
|
self.emit('connected');
|
||||||
}
|
}
|
||||||
|
else if (topic === getSettingsTopic()) {
|
||||||
if (_.includes(topic, 'setBrightness')) {
|
self.emit('settingsChanged', command);
|
||||||
const device = self.devices.find(x => getBrightnessCommandTopic(x) === topic);
|
|
||||||
logger('got brightness update for ' + device.name + ' with brightness: ' + command);
|
|
||||||
|
|
||||||
self.emit('brightnessChanged', device.id, parseInt(command));
|
|
||||||
}
|
}
|
||||||
else if (_.includes(topic, 'set') && _.includes(['0', '1'], command)) {
|
|
||||||
const device = self.devices.find(x => getCommandTopic(x) === topic);
|
|
||||||
logger('got state update for ' + device.name + ' with state: ' + command);
|
|
||||||
|
|
||||||
self.emit('stateChanged', device.id, parseInt(command));
|
if (_.includes(topic, 'set')) {
|
||||||
|
const device = self.devices.find(x => getCommandTopic(x) === topic);
|
||||||
|
self.emit('stateChanged', device.id, command);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateSettings(settings) {
|
||||||
|
if (settings.debug) {
|
||||||
|
debug = 'console';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debug = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
reconnect() {
|
reconnect() {
|
||||||
this.client.reconnect();
|
this.client.reconnect();
|
||||||
}
|
}
|
||||||
|
|
@ -134,16 +132,8 @@ class MqttClient extends EventEmitter {
|
||||||
devices.forEach((device) => {
|
devices.forEach((device) => {
|
||||||
logger(`sending discovery for ${device.name}`);
|
logger(`sending discovery for ${device.name}`);
|
||||||
|
|
||||||
let payload = null;
|
let payload = getDiscoveryPayload(device);
|
||||||
|
console.log(`discovered ${device.type}: ${device.name} with Plejd ID ${device.id}.`);
|
||||||
if (device.type === 'switch') {
|
|
||||||
payload = getDiscoveryPayload(device);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
payload = device.dimmable ? getDiscoveryDimmablePayload(device) : getDiscoveryPayload(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`discovered ${device.name} with Plejd ID ${device.id}.`);
|
|
||||||
|
|
||||||
self.deviceMap[device.id] = payload.unique_id;
|
self.deviceMap[device.id] = payload.unique_id;
|
||||||
|
|
||||||
|
|
@ -154,7 +144,7 @@ class MqttClient extends EventEmitter {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateState(deviceId, state) {
|
updateState(deviceId, data) {
|
||||||
const device = this.devices.find(x => x.id === deviceId);
|
const device = this.devices.find(x => x.id === deviceId);
|
||||||
|
|
||||||
if (!device) {
|
if (!device) {
|
||||||
|
|
@ -162,27 +152,31 @@ class MqttClient extends EventEmitter {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger('updating state for ' + device.name + ': ' + state);
|
logger('updating state for ' + device.name + ': ' + data.state);
|
||||||
|
let payload = null;
|
||||||
|
|
||||||
|
if (device.dimmable) {
|
||||||
|
payload = {
|
||||||
|
state: data.state === 1 ? 'ON' : 'OFF',
|
||||||
|
brightness: data.brightness
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
payload = {
|
||||||
|
state: data.state === 1 ? 'ON' : 'OFF'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.client.publish(
|
this.client.publish(
|
||||||
getStateTopic(device),
|
getStateTopic(device),
|
||||||
state.toString()
|
JSON.stringify(payload)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBrightness(deviceId, brightness) {
|
sceneTriggered(scene) {
|
||||||
const device = this.devices.find(x => x.id === deviceId);
|
|
||||||
|
|
||||||
if (!device) {
|
|
||||||
logger('error: ' + deviceId + ' is not handled by us.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
logger('updating brightness for ' + device.name + ': ' + brightness);
|
|
||||||
|
|
||||||
this.client.publish(
|
this.client.publish(
|
||||||
getBrightnessTopic(device),
|
getSceneEventTopic(),
|
||||||
brightness.toString()
|
JSON.stringify({ scene: scene })
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue