From f3e5d446f319022f4563f2c94dc5b37f07391327 Mon Sep 17 00:00:00 2001 From: foxthefox <16841643+foxthefox@users.noreply.github.com> Date: Sun, 15 Oct 2023 14:13:13 +0200 Subject: [PATCH 1/4] 2.5.3a --- admin/index_m.html | 4 ++-- main.js | 55 ++++++++++++++++++++++++---------------------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/admin/index_m.html b/admin/index_m.html index a2adf712..26875ee5 100644 --- a/admin/index_m.html +++ b/admin/index_m.html @@ -37,7 +37,7 @@ $('#testd').click(testd); $('#testg').click(testg); $('#testt').click(testt); - //$('#tests').click(tests); //hier muß es eine Übergabe der ain geben + $('#tests').click(tests); $('#testc').click(testc); $('#testo').click(testo); $('#testr').click(testr); @@ -330,7 +330,7 @@
FritzBox Adapter Debugging
My Templates
- My Color + My Stats
My Rights diff --git a/main.js b/main.js index 92b58943..1051e4fb 100644 --- a/main.js +++ b/main.js @@ -238,10 +238,10 @@ class Fritzdect extends utils.Adapter { }); if (deviceswithstat && deviceswithstat.val) { - this.log.info('glob state ' + deviceswithstat.val); + this.log.debug('glob state ' + deviceswithstat.val); let devstat = [].concat([], JSON.parse(String(deviceswithstat.val))); for (let i = 0; i < devstat.length; i++) { - this.log.debug('updating device ' + devstat[i]); + this.log.debug('updating Stats of device ' + devstat[i]); await this.updateStats(devstat[i], this.fritz); } } @@ -1020,7 +1020,7 @@ class Fritzdect extends utils.Adapter { // device.identifier = device.identifier.replace(/\s/g, ''); return device; }); - result = devices; + result.push(devices); }) .then(async () => { if (obj.callback) this.sendTo(obj.from, obj.command, result, obj.callback); @@ -1046,7 +1046,7 @@ class Fritzdect extends utils.Adapter { // group.identifier = group.identifier.replace(/\s/g, ''); return group; }); - result = groups; + result.push(groups); }) .then(async () => { if (obj.callback) this.sendTo(obj.from, obj.command, result, obj.callback); @@ -1073,7 +1073,7 @@ class Fritzdect extends utils.Adapter { // template.identifier = group.identifier.replace(/\s/g, ''); return template; }); - result = templates; + result.push(templates); }) .then(async () => { if (obj.callback) this.sendTo(obj.from, obj.command, result, obj.callback); @@ -1096,7 +1096,7 @@ class Fritzdect extends utils.Adapter { trigger = [].concat((trigger.triggerlist || {}).trigger || []).map((trigger) => { return trigger; }); - result = trigger; + result.push(trigger); }) .then(async () => { if (obj.callback) this.sendTo(obj.from, obj.command, result, obj.callback); @@ -1112,24 +1112,27 @@ class Fritzdect extends utils.Adapter { wait = true; break; case 'statistic': - this.fritz - .getBasicDeviceStats(obj.message) //ain muß übergeben werden aus message - .then(function(statisticinfos) { - //obj.message should be ain of device requested - const devicestats = parser.xml2json(statisticinfos); - result = devicestats; - }) - .then(async () => { - if (obj.callback) this.sendTo(obj.from, obj.command, result, obj.callback); - }) - .catch((e) => { - this.log.debug('error calling in msgbox'); - throw { - msg: 'issue getting statistics', - function: 'onMessage', - error: e - }; - }); + const deviceswithstat = await this.getStateAsync('global.statdevices').catch((e) => { + this.log.warn('problem getting statdevices ' + e); + }); + //let result = ''; + if (deviceswithstat && deviceswithstat.val) { + this.log.debug('msg statistics ' + deviceswithstat.val); + let devstat = [].concat([], JSON.parse(String(deviceswithstat.val))); + for (let i = 0; i < devstat.length; i++) { + let stats = await this.fritz.getBasicDeviceStats(devstat[i]).catch((e) => { + this.log.debug('error calling in msgbox'); + throw { + msg: 'issue getting statistics', + function: 'onMessage', + error: e + }; + }); + let statsobj = parser.xml2json(stats); + result.push(statsobj); + } + } + if (obj.callback) this.sendTo(obj.from, obj.command, result, obj.callback); wait = true; break; case 'color': @@ -1137,7 +1140,7 @@ class Fritzdect extends utils.Adapter { .getColorDefaults() .then(function(colorinfos) { let colors = parser.xml2json(colorinfos); - result = colors; + result.push(colors); }) .then(async () => { if (obj.callback) this.sendTo(obj.from, obj.command, result, obj.callback); @@ -1157,7 +1160,7 @@ class Fritzdect extends utils.Adapter { .getUserPermissions() .then(function(rights) { const permission = parser.xml2json(rights); - result = permission; + result.push(permission); }) .then(async () => { if (obj.callback) this.sendTo(obj.from, obj.command, result, obj.callback); From 0388a17880ea045c836c247e784db82282bfbcd0 Mon Sep 17 00:00:00 2001 From: foxthefox <16841643+foxthefox@users.noreply.github.com> Date: Thu, 19 Oct 2023 12:32:36 +0200 Subject: [PATCH 2/4] 2.5.3 count error --- main.js | 238 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 131 insertions(+), 107 deletions(-) diff --git a/main.js b/main.js index 1051e4fb..509a9bd7 100644 --- a/main.js +++ b/main.js @@ -1112,25 +1112,31 @@ class Fritzdect extends utils.Adapter { wait = true; break; case 'statistic': - const deviceswithstat = await this.getStateAsync('global.statdevices').catch((e) => { - this.log.warn('problem getting statdevices ' + e); - }); - //let result = ''; - if (deviceswithstat && deviceswithstat.val) { - this.log.debug('msg statistics ' + deviceswithstat.val); - let devstat = [].concat([], JSON.parse(String(deviceswithstat.val))); - for (let i = 0; i < devstat.length; i++) { - let stats = await this.fritz.getBasicDeviceStats(devstat[i]).catch((e) => { - this.log.debug('error calling in msgbox'); - throw { - msg: 'issue getting statistics', - function: 'onMessage', - error: e - }; - }); - let statsobj = parser.xml2json(stats); - result.push(statsobj); + let statfeedback = {}; + try { + const deviceswithstat = await this.getStateAsync('global.statdevices').catch((e) => { + this.log.warn('problem getting statdevices ' + e); + }); + if (deviceswithstat && deviceswithstat.val) { + this.log.debug('msg statistics ' + deviceswithstat.val); + let devstat = [].concat([], JSON.parse(String(deviceswithstat.val))); + for (let i = 0; i < devstat.length; i++) { + let stats = await this.fritz.getBasicDeviceStats(devstat[i]).catch((e) => { + this.log.debug('error calling in msgbox'); + throw { + msg: 'issue getting statistics', + function: 'onMessage', + error: e + }; + }); + let statsobj = parser.xml2json(stats); + this.log.debug('processed ' + devstat[i]); + statfeedback[devstat[i]] = statsobj; + } } + result.push(statfeedback); + } catch (error) { + this.log.warn('problem msg statistics' + error); } if (obj.callback) this.sendTo(obj.from, obj.command, result, obj.callback); wait = true; @@ -1263,14 +1269,22 @@ class Fritzdect extends utils.Adapter { this.log.debug('update routines ' + routines.length); await Promise.all( routines.map(async (routine) => { - this.log.debug('__________________________'); - this.log.debug('updating Routine ' + routine.name); let active = routine.active == 0 ? false : true; - await this.setStateAsync('routine_' + routine.identifier.replace(/\s/g, '') + '.active', { - val: active, - ack: true - }); - this.log.debug('activation is ' + active); + let old = await this.getStateAsync( + 'routine_' + routine.identifier.replace(/\s/g, '') + '.active' + ); + if (old.val !== active || !this.config.fritz_writeonhyst) { + this.log.debug('__________________________'); + this.log.debug('updating Routine ' + routine.name); + await this.setStateAsync( + 'routine_' + routine.identifier.replace(/\s/g, '') + '.active', + { + val: active, + ack: true + } + ); + this.log.debug('activation is ' + active); + } }) ); } @@ -1503,93 +1517,103 @@ class Fritzdect extends utils.Adapter { this.log.debug('update Stats objects ' + identifier); let devstat = await fritz.getBasicDeviceStats(identifier).catch((e) => this.errorHandlerApi(e)); let statsobj = parser.xml2json(devstat); + this.log.debug('With ' + identifier + 'got the following to parse' + JSON.stringify(statsobj)); + // when device is not plugged in, the temperature and voltage objects are empty await Promise.all( Object.entries(statsobj.devicestats).map(async ([ key, obj ]) => { if (key !== 'temperature') { if (key == 'energy') { //months - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.countm', { - val: parseInt(obj['stats'][0]['count']), - ack: true - }); - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.gridm', { - val: parseInt(obj['stats'][0]['grid']), - ack: true - }); - let datatimem = parseInt(obj['stats'][0]['datatime']); - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.datatimem', { - val: datatimem, - ack: true - }); - let montharr = obj['stats'][0]['_@attribute'].split(',').map(Number); - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.stats_months', { - val: JSON.stringify(montharr), - ack: true - }); - let last12m = montharr.reduce((pv, cv) => pv + cv, 0); - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.energy_last12m', { - val: last12m, - ack: true - }); - let monthnum = parseInt(new Date(datatimem * 1000).toISOString().slice(6, 8)); - let ytd = montharr.splice(0, monthnum).reduce((pv, cv) => pv + cv, 0); - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.energy_ytd', { - val: ytd, - ack: true - }); - // days - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.countd', { - val: parseInt(obj['stats'][1]['count']), - ack: true - }); - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.gridd', { - val: parseInt(obj['stats'][1]['grid']), - ack: true - }); - let datatimed = parseInt(obj['stats'][1]['datatime']); - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.datatimed', { - val: datatimed, - ack: true - }); - let dayarr = obj['stats'][1]['_@attribute'].split(',').map(Number); - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.stats_days', { - val: JSON.stringify(dayarr), - ack: true - }); - // dayvalue here, because the mtd alters the array - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.energy_dtd', { - val: parseInt(dayarr[0]), - ack: true - }); - let last31d = dayarr.reduce((pv, cv) => pv + cv, 0); - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.energy_last31d', { - val: last31d, - ack: true - }); - let daynum = parseInt(new Date(datatimed * 1000).toISOString().slice(8, 10)); - let mtd = dayarr.splice(0, daynum).reduce((pv, cv) => pv + cv, 0); - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.energy_mtd', { - val: mtd, - ack: true - }); + if (obj['stats']) { + if (obj['stats'][0]) { + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.countm', { + val: parseInt(obj['stats'][0]['count']), + ack: true + }); + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.gridm', { + val: parseInt(obj['stats'][0]['grid']), + ack: true + }); + let datatimem = parseInt(obj['stats'][0]['datatime']); + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.datatimem', { + val: datatimem, + ack: true + }); + let montharr = obj['stats'][0]['_@attribute'].split(',').map(Number); + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.stats_months', { + val: JSON.stringify(montharr), + ack: true + }); + let last12m = montharr.reduce((pv, cv) => pv + cv, 0); + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.energy_last12m', { + val: last12m, + ack: true + }); + let monthnum = parseInt(new Date(datatimem * 1000).toISOString().slice(6, 8)); + let ytd = montharr.splice(0, monthnum).reduce((pv, cv) => pv + cv, 0); + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.energy_ytd', { + val: ytd, + ack: true + }); + } + // days + if (obj['stats'][1]) { + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.countd', { + val: parseInt(obj['stats'][1]['count']), + ack: true + }); + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.gridd', { + val: parseInt(obj['stats'][1]['grid']), + ack: true + }); + let datatimed = parseInt(obj['stats'][1]['datatime']); + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.datatimed', { + val: datatimed, + ack: true + }); + let dayarr = obj['stats'][1]['_@attribute'].split(',').map(Number); + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.stats_days', { + val: JSON.stringify(dayarr), + ack: true + }); + // dayvalue here, because the mtd alters the array + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.energy_dtd', { + val: parseInt(dayarr[0]), + ack: true + }); + let last31d = dayarr.reduce((pv, cv) => pv + cv, 0); + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.energy_last31d', { + val: last31d, + ack: true + }); + let daynum = parseInt(new Date(datatimed * 1000).toISOString().slice(8, 10)); + let mtd = dayarr.splice(0, daynum).reduce((pv, cv) => pv + cv, 0); + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.energy_mtd', { + val: mtd, + ack: true + }); + } + } } else { - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.count', { - val: parseInt(obj['stats']['count']), - ack: true - }); - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.grid', { - val: parseInt(obj['stats']['grid']), - ack: true - }); - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.datatime', { - val: parseInt(obj['stats']['datatime']), - ack: true - }); - let otherarr = obj['stats']['_@attribute'].split(',').map(Number); - await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.stats', { - val: JSON.stringify(otherarr), - ack: true - }); + if (obj['stats']) { + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.count', { + val: parseInt(obj['stats']['count']), + ack: true + }); + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.grid', { + val: parseInt(obj['stats']['grid']), + ack: true + }); + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.datatime', { + val: parseInt(obj['stats']['datatime']), + ack: true + }); + let otherarr = obj['stats']['_@attribute'].split(',').map(Number); + await this.setStateAsync('DECT_' + identifier + '.' + key + '_stats.stats', { + val: JSON.stringify(otherarr), + ack: true + }); + } } } }) @@ -1785,7 +1809,7 @@ class Fritzdect extends utils.Adapter { }); */ } else if (value == 253) { - this.log.debug('DECT_' + ain + ' (tsoll) : ' + 'mode: Closed'); + this.log.debug('DECT_' + ain + ' (tsoll) : ' + 'mode: Off'); // this.setStateAsync('DECT_'+ ain +'.tsoll', {val: 7, ack: true}); // zum setzen der Temperatur außerhalb der Anzeige? targettemp = await this.getStateAsync('DECT_' + ain + '.tsoll').catch((e) => { this.log.warn('problem getting the tsoll status ' + e); From b490b5dea821e2b58e285eef45749e65f86e54a8 Mon Sep 17 00:00:00 2001 From: foxthefox <16841643+foxthefox@users.noreply.github.com> Date: Thu, 19 Oct 2023 20:56:45 +0200 Subject: [PATCH 3/4] 2.5.3 exclusions and corr --- README.md | 8 +- admin/index_m.html | 14 +++ io-package.json | 5 +- main.js | 280 +++++++++++++++++++++++++++++++-------------- 4 files changed, 221 insertions(+), 86 deletions(-) diff --git a/README.md b/README.md index b59f89dd..89c8379d 100644 --- a/README.md +++ b/README.md @@ -217,7 +217,13 @@ otherwise it is more complex and individually to be parametrized. * blind alert state -> decode bit array ## Changelog -### 2.5.2 +### 2.5.3 (npm) +* correction for updating komfort, absenk +* corrections for the statistics polling when device is not plugged in +* correction for year to date energy value (not recognizing two digit month) +* new possibility in admin page to exclude templates/routines/statistics for compatibility with older FB + +### 2.5.2 (npm) * correction for komfort, absenk if receiving 253/254 for OFF/ON it will be NaN see issue #164 ### 2.5.1 diff --git a/admin/index_m.html b/admin/index_m.html index 26875ee5..e4f80b38 100644 --- a/admin/index_m.html +++ b/admin/index_m.html @@ -304,6 +304,20 @@
Write only Changes to Objects
Adapter Options
+
+
+ + exclude templates (check if older FB) +
+
+ + exclude routines (check if older FB) +
+
+ + exclude statistics (check if older FB) +
+