more work on the specification and functionality of base classes, added StateUpdateManager utility, to simplify partial state updates
This commit is contained in:
parent
58891b99f4
commit
5d58715922
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
node_modules/
|
||||||
@ -10,6 +10,10 @@ class HCColorlamp extends HCControlBase {
|
|||||||
return "colorlamp";
|
return "colorlamp";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get effects() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
turnOn() {
|
turnOn() {
|
||||||
return Promise.reject();
|
return Promise.reject();
|
||||||
}
|
}
|
||||||
@ -26,7 +30,19 @@ class HCColorlamp extends HCControlBase {
|
|||||||
return Promise.reject();
|
return Promise.reject();
|
||||||
}
|
}
|
||||||
|
|
||||||
changeColor(hue, sat, light) {
|
/**
|
||||||
|
* Sets the color to the values given in the colors object
|
||||||
|
* Also accepts partial values (only update hue and sat for example)
|
||||||
|
* @param {Object} color
|
||||||
|
* @param {Number} color.hue Hue
|
||||||
|
* @param {Number} color.sat Saturation
|
||||||
|
* @param {Number} color.l Lightness
|
||||||
|
*/
|
||||||
|
changeColor(color) {
|
||||||
|
return Promise.reject();
|
||||||
|
}
|
||||||
|
|
||||||
|
setEffect(id) {
|
||||||
return Promise.reject();
|
return Promise.reject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,8 +9,12 @@ class HCControlBase extends EventEmitter {
|
|||||||
constructor(configuration, state) {
|
constructor(configuration, state) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
if (!configuration.name) throw new Error("Device name is missing");
|
||||||
|
|
||||||
this._configuration = configuration;
|
this._configuration = configuration;
|
||||||
this._state = state;
|
this._state = state;
|
||||||
|
|
||||||
|
this._name = this._configuration.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
get state() {
|
get state() {
|
||||||
@ -21,6 +25,10 @@ class HCControlBase extends EventEmitter {
|
|||||||
return "none";
|
return "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return this._name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the state by polling the controlled device
|
* Updates the state by polling the controlled device
|
||||||
* @returns A promise which resolves when the state has been pulled
|
* @returns A promise which resolves when the state has been pulled
|
||||||
|
|||||||
92
StateUpdateManager.js
Normal file
92
StateUpdateManager.js
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
* Optional utility classes can use when states need to be partially updated
|
||||||
|
*/
|
||||||
|
|
||||||
|
class StateUpdateManager {
|
||||||
|
constructor(initialState) {
|
||||||
|
this._highestConfirmedId = 0;
|
||||||
|
this._currentId = 0;
|
||||||
|
this._nextId = 1;
|
||||||
|
|
||||||
|
this._updateHistory = [{ id: 0, state: initialState }];
|
||||||
|
}
|
||||||
|
|
||||||
|
get highestConfirmedId() {
|
||||||
|
return this._highestConfirmedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the latest (unconfirmed state)
|
||||||
|
*/
|
||||||
|
get state() {
|
||||||
|
return this._updateHistory.find(su => su.id == this._currentId).state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the latest confirmed state
|
||||||
|
*/
|
||||||
|
get confirmedState() {
|
||||||
|
return this._updateHistory.find(su => su.id == this._highestConfirmedId).state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the potential update of the state
|
||||||
|
* @param {Object} state
|
||||||
|
* @returns {Number} id which is used to confirm or reject the update later
|
||||||
|
*/
|
||||||
|
registerUpdate(state) {
|
||||||
|
let updateId = this._nextId;
|
||||||
|
this._nextId += 1;
|
||||||
|
this._currentId = updateId; // until rejected, this is the most recent id
|
||||||
|
|
||||||
|
this._updateHistory.push({
|
||||||
|
id: updateId,
|
||||||
|
state
|
||||||
|
});
|
||||||
|
|
||||||
|
return updateId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new state and instantly confirm it
|
||||||
|
* @param {Object} state
|
||||||
|
*/
|
||||||
|
insertConfirmedState(state) {
|
||||||
|
let suid = this.registerUpdate();
|
||||||
|
this.confirmUpdate(suid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirm the update with the specified id
|
||||||
|
* Also remove all updates with lower ids, as these are now confirmed to be outdated
|
||||||
|
* @param {Number} uid
|
||||||
|
*/
|
||||||
|
confirmUpdate(uid) {
|
||||||
|
if (uid < this._highestConfirmedId) return; // already outdated
|
||||||
|
|
||||||
|
this._highestConfirmedId = uid;
|
||||||
|
|
||||||
|
// remove history entries with lower ids
|
||||||
|
this._updateHistory = this._updateHistory.filter(su => su.id >= this._highestConfirmedId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rejects the update with the specified id
|
||||||
|
* If the id is outdated it is ignored
|
||||||
|
* Otherwise it is thrown out, and the currentId decremented if required
|
||||||
|
* @param {Number} uid
|
||||||
|
*/
|
||||||
|
rejectUpdate(uid) {
|
||||||
|
if (uid < this._highestConfirmedId) return; // already outdated
|
||||||
|
|
||||||
|
// remove element from history
|
||||||
|
this._updateHistory = this._updateHistory.filter(su => su.id != uid);
|
||||||
|
|
||||||
|
if (this._currentId == uid) {
|
||||||
|
// set current id to highest known uid
|
||||||
|
this._currentId = this._updateHistory.reduce((highest, su) => (su.id > highest) ? su.id : highest, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = StateUpdateManager;
|
||||||
1
index.js
1
index.js
@ -1,4 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
HCColorLamp: require('./ColorlampBase'),
|
HCColorLamp: require('./ColorlampBase'),
|
||||||
HCSwitch: require('./SwitchBase'),
|
HCSwitch: require('./SwitchBase'),
|
||||||
|
StateUpdateManager: require('./StateUpdateManager'),
|
||||||
};
|
};
|
||||||
5
package-lock.json
generated
5
package-lock.json
generated
@ -16,6 +16,11 @@
|
|||||||
"requires": {
|
"requires": {
|
||||||
"is-plain-obj": "1.1.0"
|
"is-plain-obj": "1.1.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"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=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
"author": "Jan Scheiper",
|
"author": "Jan Scheiper",
|
||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"merge-options": "^1.0.1"
|
"merge-options": "^1.0.1",
|
||||||
|
"node-object-hash": "^1.4.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
const objectHash = require('node-object-hash');
|
||||||
|
|
||||||
class BaseState {
|
class BaseState {
|
||||||
constructor(cloneObj) {
|
constructor(cloneObj) {
|
||||||
}
|
}
|
||||||
@ -6,12 +8,16 @@ class BaseState {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get hash() {
|
||||||
|
return objectHash(this.asObj);
|
||||||
|
}
|
||||||
|
|
||||||
static get default() {
|
static get default() {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
clone() {
|
clone() {
|
||||||
return this(this.asObj);
|
return new this.constructor(this.asObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,7 @@ class ColorlampState extends BaseState {
|
|||||||
sat: cloneState.color.sat,
|
sat: cloneState.color.sat,
|
||||||
l: cloneState.color.l
|
l: cloneState.color.l
|
||||||
};
|
};
|
||||||
|
this.effect = cloneState.effect;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get default() {
|
static get default() {
|
||||||
@ -23,7 +24,8 @@ class ColorlampState extends BaseState {
|
|||||||
hue: 0,
|
hue: 0,
|
||||||
sat: 0,
|
sat: 0,
|
||||||
l: 0
|
l: 0
|
||||||
}
|
},
|
||||||
|
effect: "none"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +37,8 @@ class ColorlampState extends BaseState {
|
|||||||
hue: this.color.hue,
|
hue: this.color.hue,
|
||||||
sat: this.color.sat,
|
sat: this.color.sat,
|
||||||
l: this.color.l
|
l: this.color.l
|
||||||
}
|
},
|
||||||
|
effect: this.effect
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user