diff --git a/CHANGELOG.md b/CHANGELOG.md index b5a8b43..57f909f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,75 +1,103 @@ # Changelog +# v6.0.12 - 2021-07-08 + +## Notable Changes +- **Smarthome** + - Changed "Humidity Sensor" from built-in sensor to a separate humidity sensor accessory + - Added new `externTemperatureSensor` option for thermostat accessories to use the temperature value from the external temperature sensor setted up in the FritzBox GUI + +## Other Changes +- Reduced minimum polling timer to `1` + +## Bugfixes +- Fixed an issue where enabling temperature or humidity doesnt work for several smarthome accessories +- Fixed an issue where receiving an error during sending a telegram message caused homebridge to crash +- Fixed an issue where thermostat `open window switch` caused a warning on startup +- Minor bug fixes + # v6.0.11 - 2021-07-04 ## Other Changes -- Fixed an issue where buttons with 4 channels didnt work properly - Updated dependencies + +## Bugfixes +- Fixed an issue where buttons with 4 channels didnt work properly # v6.0.10 - 2021-06-28 -## Other Changes +## Bugfixes - Fixed an issue where authentication with a complex password didnt work # v6.0.9 - 2021-06-28 -## Other Changes +## Bugfixes - Fixed an issue where changing lightbulb color didnt work # v6.0.8 - 2021-06-27 -## Other Changes +## Bugfixes - Fixed an issue where restarting a router failed - Minor bug fixes # v6.0.7 - 2021-06-27 -## Other Changes +## Bugfixes - Fixed an issue where presence user throw an erorr if it could not be found manually or in the hosts list - Minor bug fixes # v6.0.6 - 2021-06-27 ## Other Changes -- Fixed an issue where broadband received wrong state/value - Updated dependencies +## Bugfixes +- Fixed an issue where restarting a router failed +- Minor bug fixes + # v6.0.5 - 2021-06-23 ## Other Changes -- Fixed an issue where callmonitor (outgoing) not triggered correctly - Improved logging + +## Bugfixes +- Fixed an issue where callmonitor (outgoing) not triggered correctly # v6.0.4 - 2021-06-22 -## Other Changes -- Bug fixes - +## Bugfixes +- Minor bug fixes + # v6.0.3 - 2021-06-22 ## Notable Changes -- **Log**: Added multiple logging functions to config to allow adjusting the logging output. +- **Log**: + - Added multiple logging functions to config to allow adjusting the logging output. - **Smarthome**: - **Buttons**: Added support for Telekom Wandtaster - **Config**: - **Buttons**: Added `longPress` option to smarthome buttons ## Other Changes +- Updated dependencies + +## Bugfixes - Fixed an issue where presence devices with an ip address in the config could not be exposed to HomeKit. - Minor bug fixes -- Updated dependencies # v6.0.2 - 2021-06-22 ## Other Changes - Better error handling in the backend + +## Bugfixes - Fixed an issue where extra characteristics was not polling - Fixed an issue with Telegram where also the subtypes of an accessory was shown in the message - Minor bug fixes # v6.0.1 - 2021-06-21 -## Other Changes +## Bugfixes - Minor bug fixes - Cleaned up config.schema.json @@ -120,9 +148,11 @@ This update is by far the biggest update for `homebridge-fritz-platform`. To mak ## Other Changes - The code has been refactored (again) - Adjusted config.schema.json to reflect the changes mentioned above -- Bug fixes - Updated dependencies +## Bugfixes +- Minor bug fixes + # v5.1.2 - 2021-05-30 - Fix CreateUrlSID for DECT diff --git a/config.schema.json b/config.schema.json index cc88b5c..dc2b3fc 100644 --- a/config.schema.json +++ b/config.schema.json @@ -538,6 +538,14 @@ "description": "Current power consumption when the device is active. Used for notification via telegram when started (current power consumption above this value) or ended (current power consumption below this value).", "minimum": 1 }, + "externTemperatureSensor": { + "title": "Use Extern Temperature Sensor", + "type": "boolean", + "condition": { + "functionBody": "return model.smarthome[arrayIndices[0]].accType === 'thermostat';" + }, + "description": "Enable this, if you want to show the temperature value from the extern temperature sensor setted up in your FritzBox GUI as the current temperature." + }, "temperature": { "title": "Temperature Sensor", "type": "boolean", @@ -552,7 +560,7 @@ "condition": { "functionBody": "return model.smarthome[arrayIndices[0]].accType === 'button' || model.smarthome[arrayIndices[0]].accType === 'thermostat' || model.smarthome[arrayIndices[0]].accType === 'switch' || model.smarthome[arrayIndices[0]].accTypeGroup === 'switch' || model.smarthome[arrayIndices[0]].accTypeGroup === 'switch-lightbulb';" }, - "description": "Enable this, if the device(s) has a built in humidity sensor. This adds an additional humidity sensor to the temperature sensor." + "description": "Enable this, if the device(s) has a built in humidty sensor. This exposes an additional humidty sensor as an accessory to HomeKit." }, "window": { "title": "Window Sensor", @@ -1738,6 +1746,7 @@ "smarthome[].readOnly", "smarthome[].energy", "smarthome[].startValue", + "smarthome[].externTemperatureSensor", "smarthome[].temperature", "smarthome[].humidity", "smarthome[].window", diff --git a/package-lock.json b/package-lock.json index c4a3626..2f3d592 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "homebridge-fritz-platform", - "version": "6.0.11", + "version": "6.0.12", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 5035deb..0454f63 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "homebridge-fritz-platform", - "version": "6.0.11", + "version": "6.0.12", "description": "Homebridge Plugin to control FritzBox router, smarthome devices and more.", "main": "index.js", "funding": [ diff --git a/src/accessories/smarthome/humidity/humidity.accessory.js b/src/accessories/smarthome/humidity/humidity.accessory.js new file mode 100644 index 0000000..c2857dc --- /dev/null +++ b/src/accessories/smarthome/humidity/humidity.accessory.js @@ -0,0 +1,90 @@ +'use strict'; + +const moment = require('moment'); +const logger = require('../../../utils/logger'); +const Handler = require('../smarthome.handler'); + +const timeout = (ms) => new Promise((res) => setTimeout(res, ms)); + +class Accessory { + constructor(api, accessory, accessories, meshMaster, HistoryService) { + this.api = api; + this.accessory = accessory; + this.HistoryService = HistoryService; + + this.handler = Handler.configure(api, accessories, accessory.context.config.polling, meshMaster); + this.getService(); + } + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + // Services + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + + async getService() { + let service = this.accessory.getService(this.api.hap.Service.HumiditySensor); + + if (!service) { + logger.info( + 'Adding HumiditySensor service', + `${this.accessory.displayName} (${this.accessory.context.config.subtype})` + ); + service = this.accessory.addService( + this.api.hap.Service.HumiditySensor, + this.accessory.displayName, + this.accessory.context.config.subtype + ); + } + + if (this.accessory.context.config.battery) { + let batteryService = this.accessory.getService(this.api.hap.Service.BatteryService); + + if (!batteryService) { + logger.info( + 'Adding Battery service', + `${this.accessory.displayName} (${this.accessory.context.config.subtype})` + ); + batteryService = this.accessory.addService(this.api.hap.Service.BatteryService); + } + + batteryService.setCharacteristic( + this.api.hap.Characteristic.ChargingState, + this.api.hap.Characteristic.ChargingState.NOT_CHARGEABLE + ); + } else { + if (this.accessory.getService(this.api.hap.Service.BatteryService)) { + this.accessory.removeService(this.accessory.getService(this.api.hap.Service.BatteryService)); + } + } + + this.historyService = new this.HistoryService('room', this.accessory, { + storage: 'fs', + path: this.api.user.storagePath() + '/fritzbox/', + disableTimer: true, + }); + + await timeout(250); //wait for historyService to load + + service + .getCharacteristic(this.api.hap.Characteristic.CurrentRelativeHumidity) + .on('change', (context) => this.handler.change(context, this.accessory, null, this.historyService)); + + this.refreshHistory(service); + } + + async refreshHistory(service) { + let state = service.getCharacteristic(this.api.hap.Characteristic.CurrentRelativeHumidity).value; + + this.historyService.addEntry({ + time: moment().unix(), + temp: 0, + humidity: state, + ppm: 0, + }); + + setTimeout(() => { + this.refreshHistory(service); + }, 10 * 60 * 1000); + } +} + +module.exports = Accessory; diff --git a/src/accessories/smarthome/smarthome.config.js b/src/accessories/smarthome/smarthome.config.js index 152074d..8cec171 100644 --- a/src/accessories/smarthome/smarthome.config.js +++ b/src/accessories/smarthome/smarthome.config.js @@ -18,6 +18,7 @@ const Config = (smarthomeConfig) => { energy: smarthomeConfig.energy || false, startValue: parseInt(smarthomeConfig.startValue) > 0 ? parseInt(smarthomeConfig.startValue) : false, temperature: smarthomeConfig.temperature || false, + externTemperatureSensor: smarthomeConfig.externTemperatureSensor || false, humidity: smarthomeConfig.humidity || false, window: smarthomeConfig.window || false, openWindow: smarthomeConfig.openWindow || false, diff --git a/src/accessories/smarthome/smarthome.handler.js b/src/accessories/smarthome/smarthome.handler.js index 796bfc2..91ba211 100644 --- a/src/accessories/smarthome/smarthome.handler.js +++ b/src/accessories/smarthome/smarthome.handler.js @@ -45,7 +45,7 @@ class Handler { subtype = subtype || accessory.context.config.subtype; switch (subtype) { - case 'smarthome-switch-lightbulb': + case 'smarthome-switch-lightbulb': { if (historyService) { historyService.addEntry({ time: moment().unix(), power: context.newValue }); @@ -64,127 +64,141 @@ class Handler { } } break; + } case 'smarthome-lightbulb': break; - case 'smarthome-switch': - { - if (historyService) { - historyService.addEntry({ time: moment().unix(), power: context.newValue }); - - if (accessory.context.config.startValue) { - if (context.newValue >= accessory.context.config.startValue && !accessory.context.started) { - logger.info('Started!', `${accessory.displayName} (${accessory.context.config.subtype})`); - accessory.context.started = true; - - Telegram.send('outlet', 'started', accessory.displayName, context.newValue); - } else if (context.newValue < accessory.context.config.startValue && accessory.context.started) { - logger.info('Finished!', `${accessory.displayName} (${accessory.context.config.subtype})`); - accessory.context.started = false; - - Telegram.send('outlet', 'finished', accessory.displayName, context.newValue); - } + case 'smarthome-switch': { + if (historyService) { + historyService.addEntry({ time: moment().unix(), power: context.newValue }); + + if (accessory.context.config.startValue) { + if (context.newValue >= accessory.context.config.startValue && !accessory.context.started) { + logger.info('Started!', `${accessory.displayName} (${accessory.context.config.subtype})`); + accessory.context.started = true; + + Telegram.send('outlet', 'started', accessory.displayName, context.newValue); + } else if (context.newValue < accessory.context.config.startValue && accessory.context.started) { + logger.info('Finished!', `${accessory.displayName} (${accessory.context.config.subtype})`); + accessory.context.started = false; + + Telegram.send('outlet', 'finished', accessory.displayName, context.newValue); } } } break; + } + case 'smarthome-humidity': { + if (historyService) { + historyService.addEntry({ time: moment().unix(), temp: 0, humidity: context.newValue, ppm: 0 }); + } + break; + } case 'smarthome-temperature': { - historyService.addEntry({ time: moment().unix(), temp: context.newValue, humidity: 0, ppm: 0 }); + if (historyService) { + historyService.addEntry({ time: moment().unix(), temp: context.newValue, humidity: 0, ppm: 0 }); + } break; } case 'smarthome-contact': { - if (context.newValue) { - accessory.context.timesOpened = accessory.context.timesOpened || 0; - accessory.context.timesOpened += 1; + if (historyService) { + if (context.newValue) { + accessory.context.timesOpened = accessory.context.timesOpened || 0; + accessory.context.timesOpened += 1; - let lastActivation = moment().unix() - historyService.getInitialTime(); - let closeDuration = moment().unix() - historyService.getInitialTime(); + let lastActivation = moment().unix() - historyService.getInitialTime(); + let closeDuration = moment().unix() - historyService.getInitialTime(); - accessory - .getService(this.api.hap.Service.ContactSensor) - .getCharacteristic(this.api.hap.Characteristic.LastActivation) - .updateValue(lastActivation); + accessory + .getService(this.api.hap.Service.ContactSensor) + .getCharacteristic(this.api.hap.Characteristic.LastActivation) + .updateValue(lastActivation); - accessory - .getService(this.api.hap.Service.ContactSensor) - .getCharacteristic(this.api.hap.Characteristic.TimesOpened) - .updateValue(accessory.context.timesOpened); + accessory + .getService(this.api.hap.Service.ContactSensor) + .getCharacteristic(this.api.hap.Characteristic.TimesOpened) + .updateValue(accessory.context.timesOpened); - accessory - .getService(this.api.hap.Service.ContactSensor) - .getCharacteristic(this.api.hap.Characteristic.ClosedDuration) - .updateValue(closeDuration); - } else { - let openDuration = moment().unix() - historyService.getInitialTime(); + accessory + .getService(this.api.hap.Service.ContactSensor) + .getCharacteristic(this.api.hap.Characteristic.ClosedDuration) + .updateValue(closeDuration); + } else { + let openDuration = moment().unix() - historyService.getInitialTime(); - accessory - .getService(this.api.hap.Service.ContactSensor) - .getCharacteristic(this.api.hap.Characteristic.ClosedDuration) - .updateValue(openDuration); - } + accessory + .getService(this.api.hap.Service.ContactSensor) + .getCharacteristic(this.api.hap.Characteristic.ClosedDuration) + .updateValue(openDuration); + } - historyService.addEntry({ time: moment().unix(), status: context.newValue ? 1 : 0 }); + historyService.addEntry({ time: moment().unix(), status: context.newValue ? 1 : 0 }); + } break; } case 'smarthome-window': { - if (context.newValue) { - accessory.context.timesOpened = accessory.context.timesOpened || 0; - accessory.context.timesOpened += 1; + if (historyService) { + if (context.newValue) { + accessory.context.timesOpened = accessory.context.timesOpened || 0; + accessory.context.timesOpened += 1; - let lastActivation = moment().unix() - historyService.getInitialTime(); - let closeDuration = moment().unix() - historyService.getInitialTime(); + let lastActivation = moment().unix() - historyService.getInitialTime(); + let closeDuration = moment().unix() - historyService.getInitialTime(); - accessory - .getService(this.api.hap.Service.ContactSensor) - .getCharacteristic(this.api.hap.Characteristic.LastActivation) - .updateValue(lastActivation); + accessory + .getService(this.api.hap.Service.ContactSensor) + .getCharacteristic(this.api.hap.Characteristic.LastActivation) + .updateValue(lastActivation); - accessory - .getService(this.api.hap.Service.ContactSensor) - .getCharacteristic(this.api.hap.Characteristic.TimesOpened) - .updateValue(accessory.context.timesOpened); + accessory + .getService(this.api.hap.Service.ContactSensor) + .getCharacteristic(this.api.hap.Characteristic.TimesOpened) + .updateValue(accessory.context.timesOpened); - accessory - .getService(this.api.hap.Service.ContactSensor) - .getCharacteristic(this.api.hap.Characteristic.ClosedDuration) - .updateValue(closeDuration); - } else { - let openDuration = moment().unix() - historyService.getInitialTime(); + accessory + .getService(this.api.hap.Service.ContactSensor) + .getCharacteristic(this.api.hap.Characteristic.ClosedDuration) + .updateValue(closeDuration); + } else { + let openDuration = moment().unix() - historyService.getInitialTime(); - accessory - .getService(this.api.hap.Service.ContactSensor) - .getCharacteristic(this.api.hap.Characteristic.ClosedDuration) - .updateValue(openDuration); - } + accessory + .getService(this.api.hap.Service.ContactSensor) + .getCharacteristic(this.api.hap.Characteristic.ClosedDuration) + .updateValue(openDuration); + } - historyService.addEntry({ time: moment().unix(), status: context.newValue ? 1 : 0 }); + historyService.addEntry({ time: moment().unix(), status: context.newValue ? 1 : 0 }); + } break; } case 'smarthome-window-switch': break; case 'smarthome-thermostat': { - let currentState = accessory - .getService(this.api.hap.Service.HeaterCooler) - .getCharacteristic(this.api.hap.Characteristic.CurrentHeaterCoolerState).value; - - let currentTemp = accessory - .getService(this.api.hap.Service.HeaterCooler) - .getCharacteristic(this.api.hap.Characteristic.CurrentTemperature).value; - - let targetTemp = accessory - .getService(this.api.hap.Service.HeaterCooler) - .getCharacteristic(this.api.hap.Characteristic.HeatingThresholdTemperature).value; - - let valvePos = - currentTemp <= targetTemp && currentState !== 0 - ? Math.round(targetTemp - currentTemp >= 5 ? 100 : (targetTemp - currentTemp) * 20) - : 0; - - historyService.addEntry({ - time: moment().unix(), - currentTemp: currentTemp, - setTemp: targetTemp, - valvePosition: valvePos, - }); + if (historyService) { + let currentState = accessory + .getService(this.api.hap.Service.HeaterCooler) + .getCharacteristic(this.api.hap.Characteristic.CurrentHeaterCoolerState).value; + + let currentTemp = accessory + .getService(this.api.hap.Service.HeaterCooler) + .getCharacteristic(this.api.hap.Characteristic.CurrentTemperature).value; + + let targetTemp = accessory + .getService(this.api.hap.Service.HeaterCooler) + .getCharacteristic(this.api.hap.Characteristic.HeatingThresholdTemperature).value; + + let valvePos = + currentTemp <= targetTemp && currentState !== 0 + ? Math.round(targetTemp - currentTemp >= 5 ? 100 : (targetTemp - currentTemp) * 20) + : 0; + + historyService.addEntry({ + time: moment().unix(), + currentTemp: currentTemp, + setTemp: targetTemp, + valvePosition: valvePos, + }); + } break; } case 'smarthome-blind': @@ -660,10 +674,10 @@ class Handler { return state; } - case 'smarthome-temperature': { + case 'smarthome-humidity': { let state = accessory - .getService(this.api.hap.Service.TemperatureSensor) - .getCharacteristic(this.api.hap.Characteristic.CurrentTemperature).value; + .getService(this.api.hap.Service.HumiditySensor) + .getCharacteristic(this.api.hap.Characteristic.CurrentRelativeHumidity).value; try { let device = this.smarthomeList.devices.find((device) => device.ain.includes(accessory.context.config.ain)); @@ -673,30 +687,83 @@ class Handler { accessory.context.config.ain = device.ain; if (device.online) { - if (device.temperature) { - state = device.temperature.value; + if (device.humidity) { + state = device.humidity.value || 0; + + accessory + .getService(this.api.hap.Service.HumiditySensor) + .getCharacteristic(this.api.hap.Characteristic.CurrentRelativeHumidity) + .updateValue(state); } else { logger.warn( - 'Can not find temperature data - "accType" and/or options correct?', + 'Can not find humidity data - "accType" and/or options correct?', `${accessory.displayName} (${subtype})` ); } - if (accessory.context.config.humidity) { - if (device.humidity) { - let humidity = device.humidity.value || 0; + if (accessory.context.config.battery) { + if (device.battery) { + let batteryLevel = device.battery.value || 0; + let lowBattery = device.battery.low || 0; accessory - .getService(this.api.hap.Service.HumiditySensor) - .getCharacteristic(this.api.hap.Characteristic.CurrentRelativeHumidity) - .updateValue(humidity); + .getService(this.api.hap.Service.BatteryService) + .getCharacteristic(this.api.hap.Characteristic.BatteryLevel) + .updateValue(batteryLevel); + + accessory + .getService(this.api.hap.Service.BatteryService) + .getCharacteristic(this.api.hap.Characteristic.StatusLowBattery) + .updateValue(lowBattery); } else { logger.warn( - 'Can not find humidity data - "accType" and/or options correct?', + 'Can not find battery data - "accType" and/or options correct?', `${accessory.displayName} (${subtype})` ); } } + } else { + logger.warn('Device offline!', `${accessory.displayName} (${subtype})`); + } + } else { + logger.warn( + `Can not find device with AIN: ${accessory.context.config.ain}`, + `${accessory.displayName} (${subtype})` + ); + } + } catch (err) { + logger.warn('An error occured during getting state!', `${accessory.displayName} (${subtype})`); + logger.error(err, `${accessory.displayName} (${subtype})`); + } + + accessory + .getService(this.api.hap.Service.HumiditySensor) + .getCharacteristic(this.api.hap.Characteristic.CurrentRelativeHumidity) + .updateValue(state); + + return state; + } + case 'smarthome-temperature': { + let state = accessory + .getService(this.api.hap.Service.TemperatureSensor) + .getCharacteristic(this.api.hap.Characteristic.CurrentTemperature).value; + + try { + let device = this.smarthomeList.devices.find((device) => device.ain.includes(accessory.context.config.ain)); + logger.debug(device, `${accessory.displayName} (${subtype})`); + + if (device) { + accessory.context.config.ain = device.ain; + + if (device.online) { + if (device.temperature) { + state = device.temperature.value; + } else { + logger.warn( + 'Can not find temperature data - "accType" and/or options correct?', + `${accessory.displayName} (${subtype})` + ); + } if (accessory.context.config.battery) { if (device.battery) { @@ -942,15 +1009,17 @@ class Handler { currentTemp = device.thermostat.current; targetTemp = device.thermostat.target; - /*currentTemp = (device.thermostat.current === 'on' || device.thermostat.current === 'off') - ? currentTemp - : device.thermostat.current; + /* + currentTemp = (device.thermostat.current === 'on' || device.thermostat.current === 'off') + ? currentTemp + : device.thermostat.current; - targetTemp = (device.thermostat.target === 'on' || device.thermostat.target === 'off') - ? targetTemp - : device.thermostat.target;*/ + targetTemp = (device.thermostat.target === 'on' || device.thermostat.target === 'off') + ? targetTemp + : device.thermostat.target; + */ - if (device.temperature) { + if (device.externTemperatureSensor) { currentTemp = device.temperature.value || currentTemp; } diff --git a/src/accessories/smarthome/smarthome.js b/src/accessories/smarthome/smarthome.js index a44d2bb..50fc810 100644 --- a/src/accessories/smarthome/smarthome.js +++ b/src/accessories/smarthome/smarthome.js @@ -4,6 +4,7 @@ module.exports = { SHBlindAccessory: require('./blind/blind.accessory'), SHButtonAccessory: require('./button/button.accessory'), SHContactAccessory: require('./contact/contact.accessory'), + SHHumidityAccessory: require('./humidity/humidity.accessory'), SHLightbulbAccessory: require('./lightbulb/lightbulb.accessory'), SHOutletAccessory: require('./outlet/outlet.accessory'), SHOutletLightbulbAccessory: require('./outlet-lightbulb/outlet-lightbulb.accessory'), diff --git a/src/accessories/smarthome/smarthome.setup.js b/src/accessories/smarthome/smarthome.setup.js index b86fe74..e827111 100644 --- a/src/accessories/smarthome/smarthome.setup.js +++ b/src/accessories/smarthome/smarthome.setup.js @@ -59,66 +59,96 @@ const Setup = (devices, smarthomeConfig) => { devices.set(uuid, device); } - if (!device.group && device.temperature && device.accType === 'switch') { - let tempDevice = { - name: device.name + ' Temperature', - type: 'smarthome', - subtype: 'smarthome-temperature', - battery: device.battery, - humidity: device.humidity, - ain: device.ain, - }; + if (!device.group) { + if ( + device.temperature && + (device.accType === 'switch' || device.accType === 'button' || device.accType === 'thermostat') + ) { + let tempDevice = { + name: device.name + ' Temperature', + type: 'smarthome', + subtype: 'smarthome-temperature', + battery: device.battery, + ain: device.ain, + }; - const uuidTemp = UUIDgenerate(tempDevice.name); - if (devices.has(uuidTemp)) { - logger.warn( - 'Multiple devices are configured with this name. Duplicate devices will be skipped.', - tempDevice.name - ); - } else { - logger.debug('New device added!', tempDevice.name); - devices.set(uuidTemp, tempDevice); + const uuidTemp = UUIDgenerate(tempDevice.name); + if (devices.has(uuidTemp)) { + logger.warn( + 'Multiple devices are configured with this name. Duplicate devices will be skipped.', + tempDevice.name + ); + } else { + logger.debug('New device added!', tempDevice.name); + devices.set(uuidTemp, tempDevice); + } } - } - if (!device.group && device.window && device.accType === 'thermostat') { - let windowDevice = { - name: device.name + ' Window', - type: 'smarthome', - subtype: 'smarthome-window', - battery: device.battery, - ain: device.ain, - }; + if ( + device.humidity && + (device.accType === 'switch' || device.accType === 'button' || device.accType === 'thermostat') + ) { + let humidityDevice = { + name: device.name + ' Humidity', + type: 'smarthome', + subtype: 'smarthome-humidity', + battery: device.battery, + ain: device.ain, + }; - const uuidWindow = UUIDgenerate(windowDevice.name); - if (devices.has(uuidWindow)) { - logger.warn( - 'Multiple devices are configured with this name. Duplicate devices will be skipped.', - windowDevice.name - ); - } else { - logger.debug('New device added!', windowDevice.name); - devices.set(uuidWindow, windowDevice); + const uuidTemp = UUIDgenerate(humidityDevice.name); + if (devices.has(uuidTemp)) { + logger.warn( + 'Multiple devices are configured with this name. Duplicate devices will be skipped.', + humidityDevice.name + ); + } else { + logger.debug('New device added!', humidityDevice.name); + devices.set(uuidTemp, humidityDevice); + } } - } - if (!device.group && device.openWindow && device.accType === 'thermostat') { - let openWindowDevice = { - name: device.name + ' Open Window', - type: 'smarthome', - subtype: 'smarthome-window-switch', - ain: device.ain, - }; + if (device.accType === 'thermostat') { + if (device.window) { + let windowDevice = { + name: device.name + ' Window', + type: 'smarthome', + subtype: 'smarthome-window', + battery: device.battery, + ain: device.ain, + }; + + const uuidWindow = UUIDgenerate(windowDevice.name); + if (devices.has(uuidWindow)) { + logger.warn( + 'Multiple devices are configured with this name. Duplicate devices will be skipped.', + windowDevice.name + ); + } else { + logger.debug('New device added!', windowDevice.name); + devices.set(uuidWindow, windowDevice); + } + } + + if (device.openWindow) { + let openWindowDevice = { + name: device.name + ' Open Window', + type: 'smarthome', + subtype: 'smarthome-window-switch', + ain: device.ain, + }; - const uuidWindow = UUIDgenerate(openWindowDevice.name); - if (devices.has(uuidWindow)) { - logger.warn( - 'Multiple devices are configured with this name. Duplicate devices will be skipped.', - openWindowDevice.name - ); - } else { - logger.debug('New device added!', openWindowDevice.name); - devices.set(uuidWindow, openWindowDevice); + const uuidWindow = UUIDgenerate(openWindowDevice.name); + if (devices.has(uuidWindow)) { + logger.warn( + 'Multiple devices are configured with this name. Duplicate devices will be skipped.', + openWindowDevice.name + ); + } else { + logger.debug('New device added!', openWindowDevice.name); + devices.set(uuidWindow, openWindowDevice); + } + } } } } diff --git a/src/accessories/smarthome/window-switch/window-switch.accessory.js b/src/accessories/smarthome/window-switch/window-switch.accessory.js index 11cd1c4..7d274e3 100644 --- a/src/accessories/smarthome/window-switch/window-switch.accessory.js +++ b/src/accessories/smarthome/window-switch/window-switch.accessory.js @@ -30,7 +30,6 @@ class Accessory { service .getCharacteristic(this.api.hap.Characteristic.On) - .onGet(() => this.handler.get(this.accessory)) .onSet((state) => this.handler.set(state, this.accessory)) .on('change', (context) => this.handler.change(context, this.accessory)); } diff --git a/src/lib/telegram.js b/src/lib/telegram.js index fd2c9d4..be55286 100644 --- a/src/lib/telegram.js +++ b/src/lib/telegram.js @@ -57,14 +57,17 @@ class Telegram { if (err) { logger.error('An error occured during sending telegram message!'); logger.error(err); + return; } - if (res.statusCode < 200 || res.statusCode > 200) { - logger.error('A response error occured during sending telegram message!'); - logger.error({ - code: res.statusCode, - message: res.statusMessage, - }); + if (res) { + if (res.statusCode < 200 || res.statusCode > 200) { + logger.error('A response error occured during sending telegram message!'); + logger.error({ + code: res.statusCode, + message: res.statusMessage, + }); + } } }); } else { diff --git a/src/platform.js b/src/platform.js index 758c3a2..6721915 100644 --- a/src/platform.js +++ b/src/platform.js @@ -22,6 +22,7 @@ const { SHBlindAccessory, SHButtonAccessory, SHContactAccessory, + SHHumidityAccessory, SHLightbulbAccessory, SHOutletAccessory, SHOutletLightbulbAccessory, @@ -193,6 +194,8 @@ FritzPlatform.prototype = { new SHOutletAccessory(this.api, accessory, this.accessories, this.meshMaster, HistoryService); else if (device.subtype === 'smarthome-switch' && !device.energy) new SHSwitchAccessory(this.api, accessory, this.accessories, this.meshMaster); + else if (device.subtype === 'smarthome-humidity') + new SHHumidityAccessory(this.api, accessory, this.accessories, this.meshMaster, HistoryService); else if (device.subtype === 'smarthome-temperature') new SHTemperatureAccessory(this.api, accessory, this.accessories, this.meshMaster, HistoryService); else if (device.subtype === 'smarthome-thermostat') diff --git a/src/utils/utils.js b/src/utils/utils.js index 6f88dac..1ae5b33 100644 --- a/src/utils/utils.js +++ b/src/utils/utils.js @@ -26,12 +26,12 @@ exports.generateConfig = (config) => { options: { polling: { timer: - config.options && config.options.polling && parseInt(config.options.polling.timer) > 14 - ? parseInt(config.options.polling.timer) + config.options && config.options.polling && config.options.polling.timer > 0 + ? config.options.polling.timer : 15, timerSmarthomeButtons: - config.options && config.options.polling && parseInt(config.options.polling.timerSmarthomeButtons) > 0 - ? parseInt(config.options.polling.timerSmarthomeButtons) + config.options && config.options.polling && config.options.polling.timerSmarthomeButtons > 0 + ? config.options.polling.timerSmarthomeButtons : 5, exclude: config.options && config.options.polling && config.options.polling.exclude