diff --git a/lib/aida.js b/lib/aida.js index 197525c..591fd5f 100644 --- a/lib/aida.js +++ b/lib/aida.js @@ -7,7 +7,7 @@ const Wemo = require('./wemo-controller'); const HS100 = require('./hs100-controller'); const Hive = require('./hive-controller'); const MqttController = require('./mqtt-controller'); -const { BedroomRecipe, BedroomLightMorning } = require('./recipes'); +const { BedroomHeaterV2, BedroomLightMorning } = require('./recipes'); logger.level = 'debug'; @@ -64,7 +64,7 @@ Aida.prototype.init = function() { // this.hive.update(); - this.BedroomRecipe = new BedroomRecipe({ 'mqtt':this.mqtt, 'wemo':this.wemo }); + this.BedroomRecipe = new BedroomHeaterV2({ 'mqtt':this.mqtt, 'wemo':this.wemo }); this.BedroomLightMorning = new BedroomLightMorning({ 'lights': this.lights }); }; diff --git a/lib/light-controller.js b/lib/light-controller.js index c225d9c..c7a0b80 100644 --- a/lib/light-controller.js +++ b/lib/light-controller.js @@ -8,7 +8,7 @@ logger.level = 'debug'; const LightController = function() { const _this = this; - const devices = new Map(); + // const devices = new Map(); client.on('light-new', light => { logger.debug('New light found.'); logger.debug(`ID: ${ light.id}`); @@ -16,10 +16,8 @@ const LightController = function() { light.getState((err, info) => { if (err) - logger.debug(err); + logger.error(err); - // if (devices.get(light.id) === undefined) - devices.set(light.id, Object.assign({}, light)); logger.debug(`Label: ${ info.label}`); logger.debug('Power:', (info.power === 1) ? 'on' : 'off'); logger.debug('Color:', info.color); @@ -33,7 +31,7 @@ const LightController = function() { light.getHardwareVersion((err, info) => { if (err) - logger.debug(err); + logger.error(err); logger.debug(`Device Info: ${ info.vendorName } - ${ info.productName}`); logger.debug('Features: ', info.productFeatures, '\n'); diff --git a/lib/recipes.js b/lib/recipes.js index 1f8bc14..948d430 100644 --- a/lib/recipes.js +++ b/lib/recipes.js @@ -3,6 +3,96 @@ const util = require('util'); const logger = require('log4js').getLogger('recipes'); logger.level = 'debug'; +const BedroomHeaterV2 = function(devices) { + const _this = this; + this.mqtt = devices.mqtt; + this.wemo = devices.wemo; + + this.globalMode = 'FanOff'; + + this.bedroom = { + 'temp': 0, + 'last': 0, + 'data': [] + }; + this.ranges = { + 'day': { 'low': 20.2, 'high': 22.5, 'max': 22.7 }, + 'night': { 'low': 20.2, 'high': 22.0, 'max': 22.7 } + }; + + this.startTimer = clearTimeout(); + + console.log('this.starttimer', this.startTimer); + + this.setMode = function() { + let n; + let mode = 'FanOff'; + const onTime = 900000; + const now = new Date; + const mod = onTime - (now.getTime() % onTime); + const day = now.getDay(); + const daytimeLimits = { 'low': 27900000, 'high': 63000000 }; + const nowMS = (now.getHours() * 3600000) + (now.getMinutes() * 60000); + const curRange = (nowMS < 25200000) ? this.ranges.night : this.ranges.day; + + if (this.globalMode === 'FanOff') { + logger.info(`Fans off, temp (${this.bedroom.temp}) should be <= ${curRange.low}`); + mode = (parseFloat(this.bedroom.temp) <= curRange.low) ? 'FanOn' : 'FanOff'; + } + else { + logger.info(`Fans on, temp (${this.bedroom.temp}) should be less than ${curRange.high}`); + mode = (parseFloat(this.bedroom.temp) <= curRange.high) ? 'FanOn' : 'FanOff'; + } + + if ((this.globalMode !== 'FanOff' || mode !== 'FanOff') && ((day >= 1 && day <= 5) && (nowMS >= daytimeLimits.low && nowMS <= daytimeLimits.high))) { + logger.info('Week day, during the day'); + mode = 'FanOff'; + this.startTimer = clearTimeout(); + } + + if (!this.startTimer && mode === 'FanOn' && this.globalMode === 'FanOff') { + logger.debug('10 Minute timer started...'); + this.startTimer = setTimeout((() => { + _this.wemo.emit('wemo', 'FanOn'); + }).bind(_this), 600000); + } + + if (this.bedroom.temp >= curRange.max && this.globalMode == 'FanOn') { + this.startTimer = clearTimeout(); + logger.warn('Max temp reached, turn off'); + _this.wemo.emit('wemo', 'FanOff'); + } + }; + + const updateTemp = (temp) => { + logger.debug(temp); + const now = new Date; + const nowMS = (now.getHours() * 3600000) + (now.getMinutes() * 60000); + const curRange = (nowMS < 25200000) ? this.ranges.night : this.ranges.day; + + this.bedroom.temp = parseFloat(temp); + this.setMode(); + // logger.info(this.bedroom.temp, this.bedroom.temp >= curRange.max); + + /* if (this.bedroom.temp >= curRange.max && this.globalMode == 'FanOn') { + this.startTimer = clearTimeout(); + logger.warn('Max temp reached, turn off'); + _this.wemo.emit('wemo', 'fanOff'); + }*/ + }; + + this.mqtt.on('bedroomTemp', (d) => { + updateTemp(d); + }); + + this.wemo.on('changeState', (d) => { + logger.debug('changeState', d); + logger.debug('fix', ((parseInt(d, 10) === 0) ? 'FanOff' : 'FanOn')); + this.globalMode = (parseInt(d, 10) === 0) ? 'FanOff' : 'FanOn'; + logger.debug('this.globalMode', this.globalMode); + }); +}; + const BedroomRecipe = function(devices) { const _this = this; this.mqtt = devices.mqtt; @@ -74,7 +164,7 @@ const BedroomRecipe = function(devices) { if (this.bedroom.temp >= curRange.max) { logger.warn('Max temp reached, turn off'); - _this.wemo.emit('wemo', 'fanOff'); + _this.wemo.emit('wemo', 'FanOff'); } }; @@ -109,6 +199,7 @@ const BedroomLightMorning = function(devices) { util.inherits(BedroomRecipe, em); util.inherits(BedroomLightMorning, em); +util.inherits(BedroomHeaterV2, em); -module.exports = { BedroomRecipe, BedroomLightMorning }; +module.exports = { BedroomRecipe, BedroomLightMorning, BedroomHeaterV2 }; diff --git a/lib/test.js b/lib/test.js new file mode 100644 index 0000000..6fed527 --- /dev/null +++ b/lib/test.js @@ -0,0 +1,49 @@ +const em = require('events').EventEmitter; +const util = require('util'); +const logger = require('log4js').getLogger('Aida'); +const Wemo = require('./wemo-controller'); +const MqttController = require('./mqtt-controller'); +const { BedroomHeaterV2 } = require('./recipes'); + +logger.level = 'debug'; + +const devices = { + 'sensors': {}, + 'lights': new Map(), + 'wemo': {}, + 'heating': {} +}; + +const Aida = function() { + logger.debug('Aida!!'); + const self = this; + + this.on('newListener', function(listener) { + logger.debug(`Event Listener: ${ listener}`); + }); + + this.init(); +}; + +util.inherits(Aida, em); + +Aida.prototype.init = function() { + this.wemo = new Wemo(); + // this.hive = new Hive(); + this.mqtt = new MqttController(); + + + this.wemo.on('found', (d) => { + logger.debug('Found Wemo switch:', d.macAddress); + }); + + this.mqtt.on('found', () => { + logger.debug('MQTT found device'); + }); + + // this.hive.update(); + + this.BedroomRecipe = new BedroomHeaterV2({ 'mqtt':this.mqtt, 'wemo':this.wemo }); +}; + +module.exports = Aida; diff --git a/lib/wemo-controller.js b/lib/wemo-controller.js index c148679..a77f37a 100644 --- a/lib/wemo-controller.js +++ b/lib/wemo-controller.js @@ -1,9 +1,13 @@ +const { promisify } = require('util'); const Wemo = require('wemo-client'); const wemo = new Wemo(); const em = require('events').EventEmitter; const util = require('util'); const logger = require('log4js').getLogger('Wemo'); + +// const getBinaryStateAsync = promisify(wemo.getBinaryState); + logger.level = 'debug'; const WemoController = function() { @@ -24,11 +28,13 @@ const WemoController = function() { // Handle BinaryState events _this.client.on('binaryState', function(value) { + _this.emit('changeState', value); logger.info('Binary State changed to: %s', value); + }); - // Turn the switch on - _this.client.setBinaryState(1); + // Turn the switch off + _this.client.setBinaryState(0); }); this.on('newListener', listener => { @@ -45,10 +51,9 @@ const WemoController = function() { this.on('wemo', function(d) { logger.debug('onWemo msg', d); - if (d === 'FanOn') + if (d === 'FanOn') this.emit('wemo-on'); - - if (d === 'FanOff') + else this.emit('wemo-off'); });