Skip to content

Commit

Permalink
Better error handling for getMaxIR
Browse files Browse the repository at this point in the history
  • Loading branch information
jdomeij committed Jan 22, 2018
1 parent 60b23e7 commit d8eea85
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 22 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ jspm_packages

# Optional REPL history
.node_repl_history
package-lock.json
38 changes: 38 additions & 0 deletions example/dump_lights.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use strict';

var Lifx = require('node-lifx').Client;
var client = new Lifx();

client.on('error', function(err) {
console.log('LIFX error:\n' + err.stack);
client.destroy();
});

client.on('light-new', function(light) {
light.getHardwareVersion((err, data) => {
console.log('getHardwareVersion', light.id, err ? err.message : data);
});

light.getMaxIR((err, data) => {
console.log('getMaxIR', light.id, err ? err.message : data);
});

light.getState((err, data) => {
console.log('getState', light.id, err ? err.message : data);
})
});


client.on('listening', function() {
var address = client.address();
console.log(
'Started LIFX listening on ' +
address.address + ':' + address.port + '\n'
);
});

client.init({
//broadcast: "192.168.1.255",
messageHandlerTimeout: 1000,
//debug: true,
});
55 changes: 46 additions & 9 deletions lib/lifx-light.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ function LightItem(lightID, lifxLight, config) {
address: lifxLight.address,
label: lifxLight.label,
reachable: true,
messageHandlerTimeout: 5000,
maxIRLevel: 0, // Only valid for IR capable lights
getMaxIR_Error: false, // do we get an error when querying for maxIRLevel
}

// Default state
Expand Down Expand Up @@ -151,7 +153,14 @@ LightItem.prototype.initialize = function initialize(callback) {
(done) => {
if (!(capability & LightCapability.INFRARED))
return done(null, null);
self.lifx.getMaxIR(done);
self.lifx.getMaxIR((err, data) => {
// getMaxIR generates an error, stop using it and use static value
if (err) {
self.info.getMaxIR_Error = true;
data = { brightness: self.info.maxIRLevel };
}
done(null, data);
});
},

], (err, data) => {
Expand All @@ -171,8 +180,11 @@ LightItem.prototype.initialize = function initialize(callback) {
self.state = convertLifxState(lifxInfo);

// Infrared
if (self.info.capability | LightCapability.INFRARED)
self.info.maxIRLevel = lifxMaxIR;
if (self.info.capability | LightCapability.INFRARED &&
_.isPlainObject(lifxMaxIR) &&
_.isFinite(lifxMaxIR.brightness)) {
self.info.maxIRLevel = limitValue(Math.round(lifxMaxIR.brightness), 0, 100);
}

// Update label
self.info.label = lifxInfo.label;
Expand Down Expand Up @@ -201,10 +213,15 @@ LightItem.prototype.stop = function stop() {

/**
* Poll light for changes
* @param {?function} callback Optional function to call when done
*/
LightItem.prototype.pollChanges = function pollChanges() {
LightItem.prototype.pollChanges = function pollChanges(callback) {
var self = this;

// Ensure callback is an function
if (typeof callback !== 'function')
callback = function() {}

async.series([
// Get state info
(done) => {
Expand All @@ -213,21 +230,37 @@ LightItem.prototype.pollChanges = function pollChanges() {

// Get IR info (if we have the capability)
(done) => {
// Check capability
if (!(self.info.capability & LightCapability.INFRARED))
return done(null, null);
self.lifx.getMaxIR(done);

// Check if getMaxIR returns error
if (!self.info.getMaxIR_Error)
return done(null, { brightness: self.info.maxIRLevel } );

// Get IR level
self.lifx.getMaxIR((err, data) => {
// Ignore errors
if (err) {
data = { brightness: self.info.maxIRLevel };
}
done(null, data);
});
}
], (err, data) => {
if (err) {
callback(err);
return;
}

var lifxState = data[0];
var lifxMaxIR = data[1];

// We need to ignore the changes for this light until modified value has expired
if (self.modified >= process.uptime())
if (self.modified >= process.uptime()) {
callback();
return;
}

var newState = convertLifxState(lifxState);
var isUpdated = false;
Expand All @@ -237,9 +270,11 @@ LightItem.prototype.pollChanges = function pollChanges() {
if (isUpdated)
self.state = newState;

if (self.info.capability & LightCapability.INFRARED && _.isFinite(lifxMaxIR)) {
isUpdated = (self.info.maxIRLevel !== lifxMaxIR) || isUpdated;
self.info.maxIRLevel = limitValue(Math.round(lifxMaxIR), 0, 100);
if (self.info.capability & LightCapability.INFRARED &&
_.isPlainObject(lifxMaxIR) &&
_.isFinite(lifxMaxIR.brightness)) {
isUpdated = (self.info.maxIRLevel !== lifxMaxIR.lifxMaxIR) || isUpdated;
self.info.maxIRLevel = limitValue(Math.round(lifxMaxIR.brightness), 0, 100);
}

// Copy label
Expand All @@ -248,6 +283,8 @@ LightItem.prototype.pollChanges = function pollChanges() {
// Values/state has been updated
if (isUpdated)
self.emit('update');

callback();
});
}

Expand Down
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "node-red-contrib-node-lifx",
"version": "0.9.1",
"version": "0.9.2",
"description": "Control Lifx lights using Node-RED.",
"author": "jdomeij",
"homepage": "https://github.com/jdomeij/node-red-contrib-node-lifx",
Expand All @@ -27,16 +27,16 @@
"main": "lib/lifx-server.js",
"license": "Apache-2.0",
"devDependencies": {
"chai": "^3.5.0",
"chai-spies": "^0.7.1",
"mocha": "^3.2.0"
"chai": "^4.1.2",
"chai-spies": "^1.0.0",
"mocha": "^3.5.3"
},
"dependencies": {
"async": "^2.1.4",
"color-convert": "^1.9.0",
"color-space": "^1.14.7",
"async": "^2.6.0",
"color-convert": "^1.9.1",
"color-space": "^1.15.0",
"color-temp": "0.0.2",
"enum": "^2.3.0",
"enum": "^2.5.0",
"lodash": "^4.17.3",
"node-lifx": "^0.8.0"
},
Expand Down
69 changes: 64 additions & 5 deletions test/lifx-light.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -496,8 +496,9 @@ describe('Lifx-Light', () => {
});

it('Basic test', (done) => {
lightItem.pollChanges();
done();
lightItem.pollChanges((err) => {
done(err);
});
});
});

Expand Down Expand Up @@ -537,14 +538,70 @@ describe('Lifx-Light', () => {

});

describe('IR Support: Error Handling', () => {
it('getMaxIR init error', (done) => {
var lightItem, lifxItem;
lifxItem = new LifxEmulator();
lifxItem._getHWVerData.productFeatures.infrared = true;

// Emulate error message from getMaxIR
lifxItem.getMaxIR = function(callback) {
callback(new Error('test'));
};

lightItem = new LifxLight(lifxItem.id, lifxItem, {});
lightItem.initialize((err) => {
if (err)
return done(err);

expect(lightItem.info.getMaxIR_Error).to.be.true;
lightItem.stop();

done();
});
});


it('getMaxIR poll error', (done) => {
var lightItem, lifxItem;
lifxItem = new LifxEmulator();
lifxItem._getHWVerData.productFeatures.infrared = true;

// Initialize can call getMaxIR
lifxItem.getMaxIR = function(callback) {
callback(null, {brightness: 33});
};

lightItem = new LifxLight(lifxItem.id, lifxItem, {});
lightItem.initialize((err) => {
if (err)
return done(err);

expect(lightItem.info.maxIRLevel).to.equal(33);
expect(lightItem.info.getMaxIR_Error).to.be.false;

// Poll will generate error
lightItem.getMaxIR = function(callback) {
callback(new Error('test'));
};

lightItem.stop();
lightItem.pollChanges((err) => {
done(err);
})
});
});
});


describe('IR Support', () => {
var lightItem, lifxItem;
beforeEach((done) => {
lifxItem = new LifxEmulator();
lifxItem._getHWVerData.productFeatures.infrared = true;

lifxItem.getMaxIR = function(callback) {
callback(null, 33);
callback(null, { brightness: 33 });
};

lightItem = new LifxLight(lifxItem.id, lifxItem, {});
Expand Down Expand Up @@ -583,9 +640,11 @@ describe('Lifx-Light', () => {
});

it('pollChanges', (done) => {
lightItem.pollChanges();
lightItem.pollChanges((err) => {
done(err);

});

done();
});
});
});

0 comments on commit d8eea85

Please sign in to comment.