diff --git a/README.md b/README.md index 8e30828..84eb2e6 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ For Energy accessories it is also worth to add the custom characteristic E863F11 - [ ] Periodic sending of reference time stamp (seems not really needed if the time of your homebridge machine is correct) ### Known bugs -- There is a delay of one entry between the history and the upload to Eve.app, i.e. entry n will be uploaded only when entry n+1 is added to the history +- ~~There is a delay of one entry between the history and the upload to Eve.app, i.e. entry n will be uploaded only when entry n+1 is added to the history~~ ### How to contribute diff --git a/fakegato-history.js b/fakegato-history.js index b062fce..9f7d465 100644 --- a/fakegato-history.js +++ b/fakegato-history.js @@ -1,12 +1,21 @@ 'use strict'; +const Format = require('util').format; + +const EPOCH_OFFSET = 978307200; + +const TYPE_ENERGY = 'energy', + TYPE_ROOM = 'room', + TYPE_WEATHER = 'weather'; + var homebridge; -var Characteristic; +var Characteristic, Service; module.exports = function(pHomebridge) { - if (pHomebridge && !homebridge) { - homebridge = pHomebridge; - Characteristic = homebridge.hap.Characteristic; + if (pHomebridge && !homebridge) { + homebridge = pHomebridge; + Characteristic = homebridge.hap.Characteristic; + Service = homebridge.hap.Service; } var hexToBase64 = function(val) { @@ -22,12 +31,12 @@ module.exports = function(pHomebridge) { | ((val & 0xFF00) << 8) | ((val >>> 8) & 0xFF00) | ((val >>> 24) & 0xFF); - }, hexToHPA = function(val) { + }, hexToHPA = function(val) { return parseInt(swap16(val), 10); }, hPAtoHex = function(val) { return swap16(Math.round(val)).toString(16); }, numToHex = function(val, len) { - var s = Number(val>>>0).toString(16); + var s = Number(val >>> 0).toString(16); if(s.length % 2 != 0) { s = '0' + s; } @@ -35,12 +44,11 @@ module.exports = function(pHomebridge) { return ('0000000000000' + s).slice(-1 * len); } return s; - } class S2R1Characteristic extends Characteristic { constructor() { - super('S2R1', 'E863F116-079E-48FF-8F27-9C2605A29F52'); + super('S2R1', S2R1Characteristic.UUID); this.setProps({ format: Characteristic.Formats.DATA, perms: [ @@ -50,9 +58,11 @@ module.exports = function(pHomebridge) { } } + S2R1Characteristic.UUID = 'E863F116-079E-48FF-8F27-9C2605A29F52'; + class S2R2Characteristic extends Characteristic { constructor() { - super('S2R2', 'E863F117-079E-48FF-8F27-9C2605A29F52'); + super('S2R2', S2R2Characteristic.UUID); this.setProps({ format: Characteristic.Formats.DATA, perms: [ @@ -62,9 +72,11 @@ module.exports = function(pHomebridge) { } } + S2R2Characteristic.UUID = 'E863F117-079E-48FF-8F27-9C2605A29F52'; + class S2W1Characteristic extends Characteristic { constructor() { - super('S2W1', 'E863F11C-079E-48FF-8F27-9C2605A29F52'); + super('S2W1', S2W1Characteristic.UUID); this.setProps({ format: Characteristic.Formats.DATA, perms: [ @@ -74,9 +86,11 @@ module.exports = function(pHomebridge) { } } + S2W1Characteristic.UUID = 'E863F11C-079E-48FF-8F27-9C2605A29F52'; + class S2W2Characteristic extends Characteristic { constructor() { - super('S2W2', 'E863F121-079E-48FF-8F27-9C2605A29F52'); + super('S2W2', S2W2Characteristic.UUID); this.setProps({ format: Characteristic.Formats.DATA, perms: [ @@ -86,11 +100,13 @@ module.exports = function(pHomebridge) { } } - class FakeGatoHistoryService extends homebridge.hap.Service { + S2W2Characteristic.UUID = 'E863F121-079E-48FF-8F27-9C2605A29F52'; + + class FakeGatoHistoryService extends Service { constructor(accessoryType, accessory, size) { if (typeof size === 'undefined') { size = 4032; } - super(accessory.displayName + " History", 'E863F007-079E-48FF-8F27-9C2605A29F52'); + super(accessory.displayName + " History", FakeGatoHistoryService.UUID); var entry2address = function(val) { var temp = val % this.memorySize; @@ -98,118 +114,117 @@ module.exports = function(pHomebridge) { }.bind(this); this.log = accessory.log; - switch (accessoryType) - { - case "weather": + switch (accessoryType) { + case TYPE_WEATHER: this.accessoryType116 = "03"; this.accessoryType117 = "07"; break; - case "energy": + case TYPE_ENERGY: this.accessoryType116 = "07"; this.accessoryType117 = "1f"; break; - case "room": + case TYPE_ROOM: this.accessoryType116 = "04"; this.accessoryType117 = "0f"; break; } - - - this.accessoryType=accessoryType; + this.accessoryType = accessoryType; this.firstEntry = 0; this.lastEntry = 0; this.history = []; this.memorySize = size; - this.usedMemory=0; + this.usedMemory = 0; this.currentEntry = 1; - this.transfer=false; - this.setTime=true; - this.refTime=0; - this.memoryAddress=0; - this.dataStream=''; + this.transfer = false; + this.setTime = true; + this.refTime = 0; + this.memoryAddress = 0; + this.dataStream = ''; this.addCharacteristic(S2R1Characteristic); - + this.addCharacteristic(S2R2Characteristic) .on('get', (callback) => { - if ((this.currentEntry this.lastEntry) { break; } } - this.log.debug("Data " + this.accessoryType + ": " + this.dataStream); - callback(null,hexToBase64(this.dataStream)); - this.dataStream=''; - } + this.log.debug("Data %s: %s", this.accessoryType, this.dataStream); + callback(null, hexToBase64(this.dataStream)); + this.dataStream = ''; + } } - else - { - this.transfer=false; - callback(null,hexToBase64('00')); + else { + this.transfer = false; + callback(null, hexToBase64('00')); } - - }); - - + }); + this.addCharacteristic(S2W1Characteristic) .on('set', this.setCurrentS2W1.bind(this)); - + this.addCharacteristic(S2W2Characteristic) .on('set', this.setCurrentS2W2.bind(this)); - - } sendHistory(address){ var hexAddress= address.toString('16'); - if (address!=0) + if (address != 0) { this.currentEntry = address; - else + } + else { this.currentEntry = 1; + } this.transfer=true; } - + //in order to be consistent with Eve, entry address start from 1 addEntry(entry){ @@ -217,69 +232,75 @@ module.exports = function(pHomebridge) { return val % this.memorySize; }.bind(this); - if (this.usedMemory