version 1.0.0

This commit is contained in:
jangxx 2019-01-29 23:24:32 +01:00
commit ba32781a11
4 changed files with 313 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules/

184
HCPhilipsHue.js Normal file
View File

@ -0,0 +1,184 @@
const {
HCColorLamp,
StateUpdateManager
} = require('homecontrol-control-base');
const PhilipsHueApi = require('node-hue-api');
class HCMagicHome extends HCColorLamp {
constructor(config) {
super(config);
if (!("address" in this._configuration)) {
throw new Error(`Required configuration field "address" is missing"`);
}
if (!("username" in this._configuration)) {
throw new Error(`Required configuration field "username" is missing"`);
}
if (!("uniqueid" in this._configuration)) {
throw new Error(`Required configuration field "uniqueid" is missing"`);
}
this._api = new PhilipsHueApi.HueApi(this._configuration.address, this._configuration.username);
this._lightid = null;
this._sumanager = new StateUpdateManager(this._state);
}
// overwrite to make use of the SUManager
get state() {
return this._sumanager.state.clone();
}
get effects() {
return [
{name: "Color Loop", id: "colorloop"}
];
}
/**
* Fetch idmap and resolve uniqueId into a local id
*/
init() {
return this._api.lights().then((resp) => {
let lights = resp.lights;
for(let l of lights) {
if (l.uniqueid == this._configuration.uniqueid) {
this._lightid = l.id;
break;
}
}
if (this._lightid == null) throw new Error(`Light with unique id "${this._configuration.uniqueid}" was not found on the bridge.`);
});
}
turnOn() {
let futureState = this.state;
futureState.on = true;
let suid = this._sumanager.registerUpdate(futureState);
let lightState = PhilipsHueApi.lightState.create();
lightState.on();
return this._api.setLightState(this._lightid, lightState).then(resolveHelper(this, suid), rejectHelper(this, suid));
}
turnOff() {
let futureState = this.state;
futureState.on = false;
let suid = this._sumanager.registerUpdate(futureState);
let lightState = PhilipsHueApi.lightState.create();
lightState.off();
return this._api.setLightState(this._lightid, lightState).then(resolveHelper(this, suid), rejectHelper(this, suid));
}
setBrightness(brightness) {
let futureState = this.state;
futureState.brightness = brightness;
let suid = this._sumanager.registerUpdate(futureState);
let lightState = PhilipsHueApi.lightState.create();
lightState.bri(brightness * (255 / 100));
return this._api.setLightState(this._lightid, lightState).then(resolveHelper(this, suid), rejectHelper(this, suid));
}
setColor(color) {
let futureState = this.state;
futureState.color = fillPartialHSL(color, futureState.color);
let suid = this._sumanager.registerUpdate(futureState);
let lightState = PhilipsHueApi.lightState.create();
let { hue, sat } = convertHSLtoHue(futureState.color.hue, futureState.color.sat, futureState.color.l);
lightState.hue(hue).sat(sat);
return this._api.setLightState(this._lightid, lightState).then(resolveHelper(this, suid), rejectHelper(this, suid));
}
setEffect(id) {
let futureState = this.state;
futureState.effect = id;
let suid = this._sumanager.registerUpdate(futureState);
let lightState = PhilipsHueApi.lightState.create();
lightState.effect(id);
return this._api.setLightState(this._lightid, lightState).then(resolveHelper(this, suid), rejectHelper(this, suid));
}
pullState() {
return this._api.lightStatus(this._lightid).then((resp) => {
let lampstate = resp.state;
let currentState = this.state;
let futureState = currentState.clone();
futureState.on = lampstate.on;
futureState.color = convertHuetoHSL(lampstate.hue, lampstate.sat);
futureState.brightness = lampstate.bri * (100/255);
futureState.effect = lampstate.effect;
if (currentState.hash != futureState.hash) {
// the state of the controller has changed externally
this._sumanager.insertConfirmedState(futureState);
this.emit("state change", this.state);
}
});
}
}
module.exports = HCMagicHome;
function rejectHelper(self, suid) {
return (err) => {
self._sumanager.rejectUpdate(suid);
throw err; // rethrow so we can catch it at a higher level
};
}
function resolveHelper(self, suid) {
return () => {
self._sumanager.confirmUpdate(suid);
if (self._sumanager.highestConfirmedId == suid) {
self.emit("state change", self.state);
}
};
}
function fillPartialHSL(newcolor, oldcolor) {
//console.log(newcolor, oldcolor);
var color = {};
color["hue"] = (newcolor.hue != null) ? newcolor.hue : oldcolor.hue;
color["sat"] = (newcolor.sat != null) ? newcolor.sat : oldcolor.sat;
color["l"] = (newcolor.l != null) ? newcolor.l : oldcolor.l;
return color;
}
function convertHSLtoHue(h, s, l) {
let hue = clamp(h, 0, 360) * (65539 / 360);
let sat = clamp(s, 0, 100) * (255 / 100);
return {hue, sat};
}
function convertHuetoHSL(hue, sat) {
hue = clamp(hue, 0, 65539);
sat = clamp(sat, 0, 255);
var h = hue * (360 / 65539);
var s = sat * (100 / 255);
var l = 100 - sat * ((100-50) / 255)
return {hue: Math.round(h), sat: Math.round(s), l: Math.round(l)};
}
function clamp(value, min, max) {
return Math.min(max, Math.max(min, value));
}

109
package-lock.json generated Normal file
View File

@ -0,0 +1,109 @@
{
"name": "hc-philipshue",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"axios": {
"version": "0.15.3",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.15.3.tgz",
"integrity": "sha1-LJ1jiy4ZGgjqHWzJiOrda6W9wFM=",
"requires": {
"follow-redirects": "1.0.0"
}
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
},
"follow-redirects": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz",
"integrity": "sha1-jjQpjL0uF28lTv/sdaHHjMhJ/Tc=",
"requires": {
"debug": "^2.2.0"
}
},
"homecontrol-control-base": {
"version": "git+https://git.literalchaos.de/jan/homecontrol-control-base.git#809acfad8245dad9d974cba5b1eff2dfc5419cc9",
"from": "git+https://git.literalchaos.de/jan/homecontrol-control-base.git",
"requires": {
"merge-options": "^1.0.1",
"node-object-hash": "^1.4.1"
}
},
"is-plain-obj": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4="
},
"merge-options": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-options/-/merge-options-1.0.1.tgz",
"integrity": "sha512-iuPV41VWKWBIOpBsjoxjDZw8/GbSfZ2mk7N1453bwMrfzdrIk7EzBd+8UVR6rkw67th7xnk9Dytl3J+lHPdxvg==",
"requires": {
"is-plain-obj": "^1.1"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"node-hue-api": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/node-hue-api/-/node-hue-api-2.4.4.tgz",
"integrity": "sha512-526lV8pK2x4HW2JufXHVcFHj8Z9mOuPR37Gu+/w9Vw/CAPvzKXY5BkG8KmOLbpzjiWljN3s+JMO3n4xDra3l9Q==",
"requires": {
"axios": "~0.15.3",
"deep-extend": "^0.6.0",
"q": "~1.4",
"traits": "~0.4.0",
"xml2js": "~0.4"
}
},
"node-object-hash": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/node-object-hash/-/node-object-hash-1.4.1.tgz",
"integrity": "sha512-JQVqSM5/mOaUoUhCYR0t1vgm8RFo7qpJtPvnoFCLeqQh1xrfmr3BCD3nGBnACzpIEF7F7EVgqGD3O4lao/BY/A=="
},
"q": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz",
"integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4="
},
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"traits": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/traits/-/traits-0.4.0.tgz",
"integrity": "sha1-QW7cq9yL9kvSkQKnRT3N3YVzcaE="
},
"xml2js": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
"integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~9.0.1"
}
},
"xmlbuilder": {
"version": "9.0.7",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
}
}
}

19
package.json Normal file
View File

@ -0,0 +1,19 @@
{
"name": "hc-philipshue",
"version": "1.0.0",
"description": "Philips Hue Plugin for Homecontrol",
"main": "HCPhilipsHue.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git@git.literalchaos.de:jan/hc-philipshue.git"
},
"author": "Jan Scheiper",
"license": "UNLICENSED",
"dependencies": {
"homecontrol-control-base": "git+https://git.literalchaos.de/jan/homecontrol-control-base.git",
"node-hue-api": "^2.4.4"
}
}