finished first version

This commit is contained in:
jangxx 2019-03-02 14:45:30 +01:00
commit 1010d2e47f
5 changed files with 294 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules/

3
.jshintrc Normal file
View File

@ -0,0 +1,3 @@
{
"esversion": 6
}

207
HCmilight.js Normal file
View File

@ -0,0 +1,207 @@
const {
HCColorLamp,
StateUpdateManager
} = require('homecontrol-control-base');
const {
MilightController,
commands2,
} = require('node-milight-promise');
const mergeOptions = require('merge-options');
class HCmilight extends HCColorLamp {
constructor(config) {
super(config);
if (!("address" in this._configuration)) {
throw new Error(`Required configuration field "address" is missing"`);
}
this._zone = (this._configuration.zone !== undefined) ? this._configuration.zone : 1;
let opts = {
ip: this._configuration.address
};
opts = mergeOptions(opts, {
commandRepeat: 2,
}, this._configuration.controllerOpts);
this._state.brightness = 100;
this._state.color.l = 100;
this._state.color.sat = 0;
this._light = new MilightController(opts);
this._sumanager = new StateUpdateManager(this._state);
}
// overwrite to make use of the SUManager
get state() {
return this._sumanager.state.clone();
}
get effects() {
return [
{name: "Disco Mode", id: "disco"}
];
}
turnOn() {
let futureState = this.state;
futureState.on = true;
let suid = this._sumanager.registerUpdate(futureState);
this._light.sendCommands(commands2.rgbw.on(this._zone));
return this._light.close().then(() => {
this._sumanager.confirmUpdate(suid);
if (this._sumanager.highestConfirmedId == suid) {
this.emit("state change", this.state);
}
}).catch(err => {
this._sumanager.rejectUpdate(suid);
throw err;
});
}
turnOff() {
let futureState = this.state;
futureState.on = false;
let suid = this._sumanager.registerUpdate(futureState);
this._light.sendCommands(commands2.rgbw.off(this._zone));
return this._light.close().then(() => {
this._sumanager.confirmUpdate(suid);
if (this._sumanager.highestConfirmedId == suid) {
this.emit("state change", this.state);
}
}).catch(err => {
this._sumanager.rejectUpdate(suid);
throw err;
});
}
setBrightness(brightness) {
let futureState = this.state;
futureState.brightness = brightness;
let suid = this._sumanager.registerUpdate(futureState);
this._light.sendCommands(
commands2.rgbw.on(this._zone),
commands2.rgbw.brightness(brightness)
);
return this._light.close().then(() => {
this._sumanager.confirmUpdate(suid);
if (this._sumanager.highestConfirmedId == suid) {
this.emit("state change", this.state);
}
}).catch(err => {
this._sumanager.rejectUpdate(suid);
throw err;
});
}
setColor(color) {
let futureState = this.state;
futureState.color = fillPartialHSL(color, futureState.color);
futureState.effect = 'none';
let suid = this._sumanager.registerUpdate(futureState);
if (futureState.color.sat < 60) {
this._light.sendCommands(
commands2.rgbw.on(this._zone),
commands2.rgbw.whiteMode(this._zone)
);
} else {
let hue = Math.round(convertHue(futureState.color.hue) * (255/360));
this._light.sendCommands(
commands2.rgbw.on(this._zone),
commands2.rgbw.hue(hue)
);
}
return this._light.close().then(() => {
this._sumanager.confirmUpdate(suid);
if (this._sumanager.highestConfirmedId == suid) {
this.emit("state change", this.state);
}
}).catch(err => {
this._sumanager.rejectUpdate(suid);
throw err;
});
}
setEffect(id) {
let futureState = this.state;
if (id == 'none') {
if (futureState.color.sat < 60) {
this._light.sendCommands(
commands2.rgbw.on(this._zone),
commands2.rgbw.whiteMode(this._zone)
);
} else {
let hue = Math.round(convertHue(futureState.color.hue) * (255/360));
this._light.sendCommands(
commands2.rgbw.on(this._zone),
commands2.rgbw.hue(hue)
);
}
futureState.effect = "none";
} else if (id == 'disco') {
this._light.sendCommands(
commands2.rgbw.on(this._zone),
commands2.rgbw.effectModeNext()
);
futureState.effect = 'disco';
} else {
return Promise.reject(new Error("Invalid effect id"));
}
let suid = this._sumanager.registerUpdate(futureState);
return this._light.close().then(() => {
this._sumanager.confirmUpdate(suid);
if (this._sumanager.highestConfirmedId == suid) {
this.emit("state change", this.state);
}
}).catch(err => {
this._sumanager.rejectUpdate(suid);
throw err;
});
}
}
module.exports = HCmilight;
//the milight hue values are fucking stupid
function convertHue(hue) {
if(hue < 240) {
return 240 - hue;
} else {
return 600 - hue;
}
}
function fillPartialHSL(newcolor, oldcolor) {
if(newcolor.sat != undefined && newcolor.l == undefined) {
newcolor.l = (newcolor.sat > 50) ? 50 : 100 - newcolor.sat;
}
//console.log(newcolor, oldcolor);
let 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;
}

60
package-lock.json generated Normal file
View File

@ -0,0 +1,60 @@
{
"name": "hc-milight",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"bluebird": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz",
"integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw=="
},
"homecontrol-control-base": {
"version": "git+https://git.literalchaos.de/jan/homecontrol-control-base.git#b7ed807affe888d61efd9dbff3d55bcc128215b7",
"requires": {
"merge-options": "1.0.1",
"node-object-hash": "1.4.2"
}
},
"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.0"
}
},
"node-milight-promise": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/node-milight-promise/-/node-milight-promise-0.3.2.tgz",
"integrity": "sha512-AyWLXGQ8SIDkAhirSZe8kh1g1t5MJAaRBPNlWGxKuztYDCdtZID+IASamvQtGaWgb0FvGvVWs8aMXSP5Rx2a7Q==",
"requires": {
"bluebird": "3.5.3",
"promise-retryer": "0.0.1"
}
},
"node-object-hash": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/node-object-hash/-/node-object-hash-1.4.2.tgz",
"integrity": "sha512-UdS4swXs85fCGWWf6t6DMGgpN/vnlKeSGEQ7hJcrs7PBFoxoKLmibc3QRb7fwiYsjdL7PX8iI/TMSlZ90dgHhQ=="
},
"promise-object": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/promise-object/-/promise-object-0.1.7.tgz",
"integrity": "sha1-MsQ6Fn38xq6NIKiu47GAc14yYQc="
},
"promise-retryer": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/promise-retryer/-/promise-retryer-0.0.1.tgz",
"integrity": "sha1-H8QiUAN++keClmKNmnOKynobIEk=",
"requires": {
"promise-object": "0.1.7"
}
}
}
}

23
package.json Normal file
View File

@ -0,0 +1,23 @@
{
"name": "hc-milight",
"version": "1.0.0",
"description": "Homecontrol plugin for milight bulbs",
"main": "HCmilight.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git@git.literalchaos.de:jan/hc-milight.git"
},
"keywords": [
"homecontrol-plugin"
],
"author": "Jan Scheiper",
"license": "UNLICENSED",
"dependencies": {
"homecontrol-control-base": "git+https://git.literalchaos.de/jan/homecontrol-control-base.git",
"merge-options": "^1.0.1",
"node-milight-promise": "^0.3.2"
}
}