initial impl of transitions

This commit is contained in:
icanos 2019-12-21 15:01:15 +00:00
parent 82c4384097
commit 0c8e502b2f
3 changed files with 124 additions and 88 deletions

View file

@ -4,7 +4,7 @@ const xor = require('buffer-xor');
const _ = require('lodash');
const EventEmitter = require('events');
let debug = '';
let debug = 'console';
const getLogger = () => {
const consoleLogger = msg => console.log('plejd', msg);
@ -34,6 +34,11 @@ const STATE_DISCONNECTED = 'disconnected';
const STATE_UNINITIALIZED = 'uninitialized';
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 {
constructor(cryptoKey, keepAlive = false) {
super();
@ -51,6 +56,8 @@ class PlejdService extends EventEmitter {
this.writeQueue = [];
this.plejdDevices = {};
// Holds a reference to all characteristics
this.characteristicState = STATE_UNINITIALIZED;
this.characteristics = {
@ -64,13 +71,39 @@ class PlejdService extends EventEmitter {
this.wireEvents();
}
turnOn(id, brightness) {
logger('turning on ' + id + ' at brightness ' + brightness);
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(() => {
this._turnOn(id, (brightnessStep * i) + 1);
if (i >= steps) {
clearInterval(transitionRef);
}
i++;
}, 500);
}
else {
this._turnOn(id, brightness);
}
}
_turnOn(id, brightness) {
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');
} else {
logger('brightness is ' + brightness);
brightness = brightness << 8 | brightness;
payload = Buffer.from((id).toString(16).padStart(2, '0') + '0110009801' + (brightness).toString(16).padStart(4, '0'), 'hex');
}
@ -78,9 +111,35 @@ class PlejdService extends EventEmitter {
this.write(payload);
}
turnOff(id) {
turnOff(id, command) {
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].dim;
const steps = command.transition * 2;
const brightnessStep = initialBrightness / steps;
let currentBrightness = initialBrightness;
let i = 0;
const transitionRef = setInterval(() => {
currentBrightness = initialBrightness - (brightnessStep * i);
if (currentBrightness <= 0) {
clearInterval(transitionRef);
}
this._turnOn(id, currentBrightness);
if (i >= steps) {
clearInterval(transitionRef);
}
i++;
}, 500);
}
// finally, we turn it off
var payload = Buffer.from((id).toString(16).padStart(2, '0') + '0110009700', 'hex');
this.write(payload);
}
@ -143,7 +202,7 @@ 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(() => {
if (self.state !== STATE_CONNECTED && self.state !== STATE_AUTHENTICATED) {
if (self.deviceIdx < Object.keys(self.devices).length) {
@ -435,19 +494,39 @@ class PlejdService extends EventEmitter {
let dim = 0;
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);
dim = parseInt(decoded.toString('hex', 6, 8), 16) >> 8;
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);
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() {