From 1dff19d883c1420b44e06bcd13a6259ddea23860 Mon Sep 17 00:00:00 2001 From: HGlab <54232526+HGlab01@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:07:53 +0200 Subject: [PATCH 1/2] add upload meterReadings --- lib/state_attr.js | 6 ++ main.js | 259 ++++++++++++++++++++++++---------------------- 2 files changed, 142 insertions(+), 123 deletions(-) diff --git a/lib/state_attr.js b/lib/state_attr.js index 5f8267b1..d8d0f3e9 100644 --- a/lib/state_attr.js +++ b/lib/state_attr.js @@ -395,6 +395,12 @@ const state_attrb = { 'type': 'number', 'unit': '°C' }, + 'meterReadings': { + 'name': 'Meter readings', + 'role': 'json', + 'type': 'string', + 'write': true + }, 'min': { 'name': 'min. Temperature', 'role': 'value.temperature', diff --git a/main.js b/main.js index abbc9e32..1062bf0f 100644 --- a/main.js +++ b/main.js @@ -6,6 +6,7 @@ const EXPIRATION_LOGIN_WINDOW_IN_SECONDS = 10; const tado_auth_url = 'https://auth.tado.com'; const tado_url = 'https://my.tado.com'; +const tado_app_url = `https://app.tado.com/`; const tado_config = { client: { id: 'tado-web-app', @@ -28,6 +29,8 @@ let axiosInstance = axios.create({ timeout: 20000, baseURL: `${tado_url}/`, httpsAgent: new https.Agent({ keepAlive: true }), + referer: tado_app_url, + origin: tado_app_url }); const ONEHOUR = 60 * 60 * 1000; @@ -36,8 +39,8 @@ let pooltimer = []; class Tado extends utils.Adapter { /** - * @param {Partial} [options={}] - */ + * @param {Partial} [options={}] + */ constructor(options) { // @ts-ignore super({ @@ -59,8 +62,8 @@ class Tado extends utils.Adapter { } /** - * Is called when databases are connected and adapter received configuration. - */ + * Is called when databases are connected and adapter received configuration. + */ async onReady() { jsonExplorer.sendVersionInfo(version); this.log.info('Started with JSON-Explorer version ' + jsonExplorer.version); @@ -71,9 +74,9 @@ class Tado extends utils.Adapter { } /** - * Is called when adapter shuts down - callback has to be called under any circumstances! - * @param {() => void} callback - */ + * Is called when adapter shuts down - callback has to be called under any circumstances! + * @param {() => void} callback + */ onUnload(callback) { try { //this.resetTimer(); @@ -88,10 +91,10 @@ class Tado extends utils.Adapter { /* ON STATE CHANGE */ ////////////////////////////////////////////////////////////////////// /** - * Is called if a subscribed state changes - * @param {string} id - * @param {ioBroker.State | null | undefined} state - */ + * Is called if a subscribed state changes + * @param {string} id + * @param {ioBroker.State | null | undefined} state + */ async onStateChange(id, state) { if (state) { // The state was changed @@ -109,7 +112,32 @@ class Tado extends utils.Adapter { const statename = idSplitted[idSplitted.length - 1]; this.log.debug(`Attribute '${id}' changed. '${statename}' will be checked.`); - if (statename == 'offsetCelsius') { + if (statename == 'meterReadings') { + let meterReadings = {}; + try { + meterReadings = JSON.parse(String(state.val)); + } catch (error) { + this.log.error(`'${state.val}' is not a valide JSON for meterReadings - ${error}`); + return; + } + if (meterReadings.date && meterReadings.reading) { + let date = String(meterReadings.date); + if (typeof meterReadings.reading != 'number') { + this.log.error('meterReadings.reading is not a number!'); + return; + } + let regEx = /^\d{4}-\d{2}-\d{2}$/; + if (!date.match(regEx)) { + this.log.error('dmeterReadings.date hat other format thanYYYY-MM-DD'); + return; + } + await this.setReading(home_id, meterReadings); + } else { + this.log.error('meterReadings does not contain date and reading'); + return; + } + } + else if (statename == 'offsetCelsius') { const offset = state; let set_offset = (offset == null || offset == undefined || offset.val == null) ? 0 : parseFloat(offset.val.toString()); this.log.debug(`Offset changed for device '${device_id}' in home '${home_id}' to value '${set_offset}'`); @@ -337,9 +365,9 @@ class Tado extends utils.Adapter { /* API CALLS */ ////////////////////////////////////////////////////////////////////// /** - * @param {string} home_id - * @param {string} zone_id - */ + * @param {string} home_id + * @param {string} zone_id + */ async clearZoneOverlay(home_id, zone_id) { let url = `/api/v2/homes/${home_id}/zones/${zone_id}/overlay`; if (await isOnline() == false) { @@ -354,11 +382,11 @@ class Tado extends utils.Adapter { } /** - * @param {string} home_id - * @param {string} zone_id - * @param {string} device_id - * @param {number} set_offset - */ + * @param {string} home_id + * @param {string} zone_id + * @param {string} device_id + * @param {number} set_offset + */ async setTemperatureOffset(home_id, zone_id, device_id, set_offset) { if (!set_offset) set_offset = 0; if (set_offset <= -10 || set_offset > 10) this.log.warn('Offset out of range +/-10°'); @@ -386,10 +414,10 @@ class Tado extends utils.Adapter { } /** - * @param {string} home_id - * @param {string} zone_id - * @param {number} timetable_id - */ + * @param {string} home_id + * @param {string} zone_id + * @param {number} timetable_id + */ async setActiveTimeTable(home_id, zone_id, timetable_id) { if (!timetable_id) timetable_id = 0; if (!(timetable_id == 0 || timetable_id == 1 || timetable_id == 2)) { @@ -421,9 +449,9 @@ class Tado extends utils.Adapter { } /** - * @param {string} home_id - * @param {string} homePresence - */ + * @param {string} home_id + * @param {string} homePresence + */ async setPresenceLock(home_id, homePresence) { if (!homePresence) homePresence = 'HOME'; if (homePresence !== 'HOME' && homePresence !== 'AWAY' && homePresence !== 'AUTO') { @@ -458,21 +486,21 @@ class Tado extends utils.Adapter { } /** - * @param {string} home_id - * @param {string} zone_id - * @param {string} power - * @param {number} temperature - * @param {string} typeSkillBasedApp - * @param {number} durationInSeconds - * @param {string} type - * @param {string} acMode - * @param {string} fanLevel - * @param {string} horizontalSwing - * @param {string} verticalSwing - * @param {string} fanSpeed - * @param {string} swing - * @param {string} light - */ + * @param {string} home_id + * @param {string} zone_id + * @param {string} power + * @param {number} temperature + * @param {string} typeSkillBasedApp + * @param {number} durationInSeconds + * @param {string} type + * @param {string} acMode + * @param {string} fanLevel + * @param {string} horizontalSwing + * @param {string} verticalSwing + * @param {string} fanSpeed + * @param {string} swing + * @param {string} light + */ async setZoneOverlay(home_id, zone_id, power, temperature, typeSkillBasedApp, durationInSeconds, type, acMode, fanLevel, horizontalSwing, verticalSwing, fanSpeed, swing, light) { power = power.toUpperCase(); typeSkillBasedApp = typeSkillBasedApp.toUpperCase(); @@ -520,12 +548,12 @@ class Tado extends utils.Adapter { } /* Capability Management - {"1":{"type":"HEATING","temperatures":{"celsius":{"min":5,"max":25,"step":0.1},"fahrenheit":{"min":41,"max":77,"step":0.1}}}} - {"0":{"type":"HOT_WATER","canSetTemperature":true,"temperatures":{"celsius":{"min":30,"max":65,"step":1},"fahrenheit":{"min":86,"max":149,"step":1}}}} - {"0":{"type":"HOT_WATER","canSetTemperature":false}} - {"1":{"type":"AIR_CONDITIONING","COOL":{"temperatures":{"celsius":{"min":16,"max":30,"step":1},"fahrenheit":{"min":61,"max":86,"step":1}},"fanSpeeds":["AUTO","HIGH","MIDDLE","LOW"],"swings":["OFF","ON"]},"DRY":{"fanSpeeds":["MIDDLE","LOW"],"swings":["OFF","ON"]},"FAN":{"fanSpeeds":["HIGH","MIDDLE","LOW"],"swings":["OFF","ON"]},"HEAT":{"temperatures":{"celsius":{"min":16,"max":30,"step":1},"fahrenheit":{"min":61,"max":86,"step":1}},"fanSpeeds":["AUTO","HIGH","MIDDLE","LOW"],"swings":["OFF","ON"]},"initialStates":{"mode":"COOL","modes":{"COOL":{"temperature":{"celsius":23,"fahrenheit":74},"fanSpeed":"LOW","swing":"OFF"},"DRY":{"fanSpeed":"LOW","swing":"OFF"},"FAN":{"fanSpeed":"LOW","swing":"OFF"},"HEAT":{"temperature":{"celsius":23,"fahrenheit":74},"fanSpeed":"LOW","swing":"OFF"}}}},"3":{"type":"AIR_CONDITIONING","COOL":{"temperatures":{"celsius":{"min":16,"max":30,"step":1},"fahrenheit":{"min":61,"max":86,"step":1}},"fanSpeeds":["AUTO","HIGH","MIDDLE","LOW"],"swings":["OFF","ON"]},"DRY":{"fanSpeeds":["MIDDLE","LOW"],"swings":["OFF","ON"]},"FAN":{"fanSpeeds":["HIGH","MIDDLE","LOW"],"swings":["OFF","ON"]},"HEAT":{"temperatures":{"celsius":{"min":16,"max":30,"step":1},"fahrenheit":{"min":61,"max":86,"step":1}},"fanSpeeds":["AUTO","HIGH","MIDDLE","LOW"],"swings":["OFF","ON"]},"initialStates":{"mode":"COOL","modes":{"COOL":{"temperature":{"celsius":23,"fahrenheit":74},"fanSpeed":"LOW","swing":"OFF"},"DRY":{"fanSpeed":"LOW","swing":"OFF"},"FAN":{"fanSpeed":"LOW","swing":"OFF"},"HEAT":{"temperature":{"celsius":23,"fahrenheit":74},"fanSpeed":"LOW","swing":"OFF"}}}}} - {"1":{"type":"AIR_CONDITIONING","HEAT":{"temperatures":{"celsius":{"min":16,"max":32,"step":1},"fahrenheit":{"min":61,"max":90,"step":1}},"fanLevel":["LEVEL2","LEVEL3","AUTO","LEVEL1"],"verticalSwing":["OFF","ON"],"horizontalSwing":["OFF","ON"],"light":["OFF","ON"]},"COOL":{"temperatures":{"celsius":{"min":16,"max":32,"step":1},"fahrenheit":{"min":61,"max":90,"step":1}},"fanLevel":["LEVEL2","LEVEL3","AUTO","LEVEL1"],"verticalSwing":["OFF","ON"],"horizontalSwing":["OFF","ON"],"light":["OFF","ON"]},"DRY":{"temperatures":{"celsius":{"min":16,"max":32,"step":1},"fahrenheit":{"min":61,"max":90,"step":1}},"fanLevel":["LEVEL2","LEVEL3","AUTO","LEVEL1"],"verticalSwing":["OFF","ON"],"horizontalSwing":["OFF","ON"],"light":["OFF","ON"]},"FAN":{"fanLevel":["LEVEL2","LEVEL3","LEVEL1"],"verticalSwing":["OFF","ON"],"horizontalSwing":["OFF","ON"],"light":["OFF","ON"]},"AUTO":{"fanLevel":["LEVEL2","LEVEL3","LEVEL1"],"verticalSwing":["OFF","ON"],"horizontalSwing":["OFF","ON"],"light":["OFF","ON"]},"initialStates":{"mode":"COOL","modes":{"COOL":{"temperature":{"celsius":24,"fahrenheit":76},"fanSpeed":null,"swing":null,"fanLevel":"LEVEL2","verticalSwing":"OFF","horizontalSwing":"OFF"},"HEAT":{"temperature":{"celsius":24,"fahrenheit":76},"fanSpeed":null,"swing":null,"fanLevel":"LEVEL2","verticalSwing":"OFF","horizontalSwing":"OFF"},"DRY":{"temperature":{"celsius":24,"fahrenheit":76},"fanSpeed":null,"swing":null,"fanLevel":"LEVEL2","verticalSwing":"OFF","horizontalSwing":"OFF"},"FAN":{"temperature":null,"fanSpeed":null,"swing":null,"fanLevel":"LEVEL2","verticalSwing":"OFF","horizontalSwing":"OFF"},"AUTO":{"temperature":null,"fanSpeed":null,"swing":null,"fanLevel":"LEVEL2","verticalSwing":"OFF","horizontalSwing":"OFF"}},"light":"ON"}}} - */ + {"1":{"type":"HEATING","temperatures":{"celsius":{"min":5,"max":25,"step":0.1},"fahrenheit":{"min":41,"max":77,"step":0.1}}}} + {"0":{"type":"HOT_WATER","canSetTemperature":true,"temperatures":{"celsius":{"min":30,"max":65,"step":1},"fahrenheit":{"min":86,"max":149,"step":1}}}} + {"0":{"type":"HOT_WATER","canSetTemperature":false}} + {"1":{"type":"AIR_CONDITIONING","COOL":{"temperatures":{"celsius":{"min":16,"max":30,"step":1},"fahrenheit":{"min":61,"max":86,"step":1}},"fanSpeeds":["AUTO","HIGH","MIDDLE","LOW"],"swings":["OFF","ON"]},"DRY":{"fanSpeeds":["MIDDLE","LOW"],"swings":["OFF","ON"]},"FAN":{"fanSpeeds":["HIGH","MIDDLE","LOW"],"swings":["OFF","ON"]},"HEAT":{"temperatures":{"celsius":{"min":16,"max":30,"step":1},"fahrenheit":{"min":61,"max":86,"step":1}},"fanSpeeds":["AUTO","HIGH","MIDDLE","LOW"],"swings":["OFF","ON"]},"initialStates":{"mode":"COOL","modes":{"COOL":{"temperature":{"celsius":23,"fahrenheit":74},"fanSpeed":"LOW","swing":"OFF"},"DRY":{"fanSpeed":"LOW","swing":"OFF"},"FAN":{"fanSpeed":"LOW","swing":"OFF"},"HEAT":{"temperature":{"celsius":23,"fahrenheit":74},"fanSpeed":"LOW","swing":"OFF"}}}},"3":{"type":"AIR_CONDITIONING","COOL":{"temperatures":{"celsius":{"min":16,"max":30,"step":1},"fahrenheit":{"min":61,"max":86,"step":1}},"fanSpeeds":["AUTO","HIGH","MIDDLE","LOW"],"swings":["OFF","ON"]},"DRY":{"fanSpeeds":["MIDDLE","LOW"],"swings":["OFF","ON"]},"FAN":{"fanSpeeds":["HIGH","MIDDLE","LOW"],"swings":["OFF","ON"]},"HEAT":{"temperatures":{"celsius":{"min":16,"max":30,"step":1},"fahrenheit":{"min":61,"max":86,"step":1}},"fanSpeeds":["AUTO","HIGH","MIDDLE","LOW"],"swings":["OFF","ON"]},"initialStates":{"mode":"COOL","modes":{"COOL":{"temperature":{"celsius":23,"fahrenheit":74},"fanSpeed":"LOW","swing":"OFF"},"DRY":{"fanSpeed":"LOW","swing":"OFF"},"FAN":{"fanSpeed":"LOW","swing":"OFF"},"HEAT":{"temperature":{"celsius":23,"fahrenheit":74},"fanSpeed":"LOW","swing":"OFF"}}}}} + {"1":{"type":"AIR_CONDITIONING","HEAT":{"temperatures":{"celsius":{"min":16,"max":32,"step":1},"fahrenheit":{"min":61,"max":90,"step":1}},"fanLevel":["LEVEL2","LEVEL3","AUTO","LEVEL1"],"verticalSwing":["OFF","ON"],"horizontalSwing":["OFF","ON"],"light":["OFF","ON"]},"COOL":{"temperatures":{"celsius":{"min":16,"max":32,"step":1},"fahrenheit":{"min":61,"max":90,"step":1}},"fanLevel":["LEVEL2","LEVEL3","AUTO","LEVEL1"],"verticalSwing":["OFF","ON"],"horizontalSwing":["OFF","ON"],"light":["OFF","ON"]},"DRY":{"temperatures":{"celsius":{"min":16,"max":32,"step":1},"fahrenheit":{"min":61,"max":90,"step":1}},"fanLevel":["LEVEL2","LEVEL3","AUTO","LEVEL1"],"verticalSwing":["OFF","ON"],"horizontalSwing":["OFF","ON"],"light":["OFF","ON"]},"FAN":{"fanLevel":["LEVEL2","LEVEL3","LEVEL1"],"verticalSwing":["OFF","ON"],"horizontalSwing":["OFF","ON"],"light":["OFF","ON"]},"AUTO":{"fanLevel":["LEVEL2","LEVEL3","LEVEL1"],"verticalSwing":["OFF","ON"],"horizontalSwing":["OFF","ON"],"light":["OFF","ON"]},"initialStates":{"mode":"COOL","modes":{"COOL":{"temperature":{"celsius":24,"fahrenheit":76},"fanSpeed":null,"swing":null,"fanLevel":"LEVEL2","verticalSwing":"OFF","horizontalSwing":"OFF"},"HEAT":{"temperature":{"celsius":24,"fahrenheit":76},"fanSpeed":null,"swing":null,"fanLevel":"LEVEL2","verticalSwing":"OFF","horizontalSwing":"OFF"},"DRY":{"temperature":{"celsius":24,"fahrenheit":76},"fanSpeed":null,"swing":null,"fanLevel":"LEVEL2","verticalSwing":"OFF","horizontalSwing":"OFF"},"FAN":{"temperature":null,"fanSpeed":null,"swing":null,"fanLevel":"LEVEL2","verticalSwing":"OFF","horizontalSwing":"OFF"},"AUTO":{"temperature":null,"fanSpeed":null,"swing":null,"fanLevel":"LEVEL2","verticalSwing":"OFF","horizontalSwing":"OFF"}},"light":"ON"}}} + */ console.log(JSON.stringify(this.roomCapabilities)); if (!this.roomCapabilities || !this.roomCapabilities[zone_id]) { this.log.error(`No room capabilities found for room '${zone_id}'. Capabilities looks like '${JSON.stringify(this.roomCapabilities)}'`); @@ -672,10 +700,10 @@ class Tado extends utils.Adapter { } /** - * @param {string} home_id - * @param {string} zone_id - * @param {object} config - */ + * @param {string} home_id + * @param {string} zone_id + * @param {object} config + */ async poolApiCall(home_id, zone_id, config) { this.log.debug(`poolApiCall() entered for '${home_id}/${zone_id}'`); let pooltimerid = home_id + zone_id; @@ -706,10 +734,10 @@ class Tado extends utils.Adapter { } /** - * Calls the "Active Open Window" endpoint. If the tado thermostat did not detect an open window, the call does nothing. - * @param {string} home_id - * @param {string} zone_id - */ + * Calls the "Active Open Window" endpoint. If the tado thermostat did not detect an open window, the call does nothing. + * @param {string} home_id + * @param {string} zone_id + */ async activateOpenWindow(home_id, zone_id) { let url = `/api/v2/homes/${home_id}/zones/${zone_id}/state/openWindow/activate`; if (await isOnline() == false) { @@ -723,10 +751,10 @@ class Tado extends utils.Adapter { } /** - * @param {string} home_id - * @param {string} zone_id - * @param {any} config Payload needs to be an object like this {"enabled":true,"timeoutInSeconds":960} - */ + * @param {string} home_id + * @param {string} zone_id + * @param {any} config Payload needs to be an object like this {"enabled":true,"timeoutInSeconds":960} + */ async setOpenWindowDetectionSettings(home_id, zone_id, config) { let url = `/api/v2/homes/${home_id}/zones/${zone_id}/openWindowDetection`; if (await isOnline() == false) { @@ -739,11 +767,11 @@ class Tado extends utils.Adapter { } /** - * @param {string} home_id - * @param {string} zone_id - * @param {string} device_id - * @param {boolean} enabled - */ + * @param {string} home_id + * @param {string} zone_id + * @param {string} device_id + * @param {boolean} enabled + */ async setChildLock(home_id, zone_id, device_id, enabled) { let url = `/api/v2/devices/${device_id}/childLock`; if (await isOnline() == false) { @@ -798,10 +826,12 @@ class Tado extends utils.Adapter { }, 'native': {}, }); + if (outdated) { this.log.debug('Full refresh, data outdated (more than 60 minutes ago)'); this.lastupdate = now; step = 'DoHome'; + await this.create_state(homeID + '.meterReadings', 'meterReadings', JSON.stringify({})); await this.DoHome(homeID); } step = 'DoMobileDevices'; @@ -895,6 +925,17 @@ class Tado extends utils.Adapter { } } + /** + * @param {string} HomeId + * @param {any} [reading] + */ + async setReading(HomeId, reading) { + let result = await this.apiCall(`https://energy-insights.tado.com/api/homes/${HomeId}/meterReadings`, 'post', JSON.stringify(reading)); + this.log.info('setReading executed with result ' + JSON.stringify(result)); + await jsonExplorer.sleep(1000); + await this.create_state(HomeId + '.meterReadings', 'meterReadings', JSON.stringify({})); + } + async DoHome(HomeId) { // Get additional basic data for all homes if (this.Home_data === null) { @@ -914,11 +955,11 @@ class Tado extends utils.Adapter { } /** - * @param {string} HomeId - * @param {string} ZoneId - * @param {string} DeviceId - * @param {object} offset - */ + * @param {string} HomeId + * @param {string} ZoneId + * @param {string} DeviceId + * @param {object} offset + */ async DoTemperatureOffset(HomeId, ZoneId, DeviceId, offset = null) { if (offset == null) { offset = await this.getTemperatureOffset(DeviceId); @@ -999,10 +1040,10 @@ class Tado extends utils.Adapter { } /** - * @param {string} HomeId - * @param {string} ZoneId - * @param {object} TimeTables_data - */ + * @param {string} HomeId + * @param {string} ZoneId + * @param {object} TimeTables_data + */ async DoTimeTables(HomeId, ZoneId, TimeTables_data = null) { if (TimeTables_data == null) { TimeTables_data = await this.getTimeTables(HomeId, ZoneId); @@ -1047,23 +1088,6 @@ class Tado extends utils.Adapter { jsonExplorer.traverseJson(homeState_data, HomeId + '.Home.state', true, true, 1); } - //not in use - /* - async DoDevices(HomeId) { - const Devices_data = await this.getDevices(HomeId); - this.log.debug('Devices Result: ' + JSON.stringify(Devices_data)); - this.DoWriteJsonRespons(HomeId, 'Stage_03_Devices', Devices_data); - }*/ - - //not in use - /* - async DoMobileDeviceSettings(HomeId, DeviceId) { - const MobileDeviceSettings_data = await this.getMobileDeviceSettings(HomeId, DeviceId); - this.log.debug('MobileDeviceSettings_Data Result: ' + JSON.stringify(MobileDeviceSettings_data)); - this.DoWriteJsonRespons(HomeId, 'Stage_07_MobileDevicesSettings_' + DeviceId, MobileDeviceSettings_data); - jsonExplorer.traverseJson(MobileDeviceSettings_data, `${HomeId}.MobileDevices.${DeviceId}.setting`, true, true, 2); - }*/ - ////////////////////////////////////////////////////////////////////// /* MASTERSWITCH */ @@ -1162,8 +1186,8 @@ class Tado extends utils.Adapter { } /** - * @param {number} msmin - */ + * @param {number} msmin + */ async sleep(msmin, msmax = msmin) { let ms = Math.random() * (msmax - msmin) + msmin; this.log.debug('Waiting time is ' + ms + 'ms'); @@ -1173,9 +1197,11 @@ class Tado extends utils.Adapter { } /** - * @param {string} url - */ - async apiCall(url, method = 'get', data = {}) { + * @param {string} url + * @param {string} method + * @param {any} data + */ + async apiCall(url, method = 'get', data = null) { try { const waitingTime = 300; //time in ms to wait between calls // check if other call is in progress and if yes loop and wait @@ -1241,10 +1267,10 @@ class Tado extends utils.Adapter { } /** - * @param {string} state - * @param {string} name - * @param {any} value - */ + * @param {string} state + * @param {string} name + * @param {any} value + */ async create_state(state, name, value) { this.log.debug(`Create_state called for state '${state}' and name '${name}' with value '${value}'`); const intervall_time = (this.config.intervall * 4); @@ -1256,14 +1282,14 @@ class Tado extends utils.Adapter { async errorHandling(errorObject) { try { if (errorObject.message && (errorObject.message.includes('Login failed!') || - errorObject.message.includes('conflict occurred while trying to update entity null') || - errorObject.message.includes('ECONNRESET') || - errorObject.message.includes('socket hang up') || - errorObject.message.includes('with status code 504') || - errorObject.message.includes('ETIMEDOUT') || - errorObject.message.includes('EAI_AGAIN') || - errorObject.message.includes('timeout of 20000ms exceeded') || - errorObject.message.includes('No internet connection detected!'))) return; + errorObject.message.includes('conflict occurred while trying to update entity null') || + errorObject.message.includes('ECONNRESET') || + errorObject.message.includes('socket hang up') || + errorObject.message.includes('with status code 504') || + errorObject.message.includes('ETIMEDOUT') || + errorObject.message.includes('EAI_AGAIN') || + errorObject.message.includes('timeout of 20000ms exceeded') || + errorObject.message.includes('No internet connection detected!'))) return; if (this.log.level != 'debug' && this.log.level != 'silly') { if (this.supportsFeature && this.supportsFeature('PLUGINS')) { const sentryInstance = this.getPluginInstance('sentry'); @@ -1380,19 +1406,6 @@ class Tado extends utils.Adapter { getHomeState(home_id) { return this.apiCall(`/api/v2/homes/${home_id}/state`); } - - /*getDevices(home_id) { - this.log.info('getDevices called') - return this.apiCall(`/api/v2/homes/${home_id}/devices`); - }*/ - - /*getZoneOverlay(home_id, zone_id) { - return this.apiCall(`/api/v2/homes/${home_id}/zones/${zone_id}/overlay`); - }*/ - - /*getInstallations(home_id) { - return this.apiCall(`/api/v2/homes/${home_id}/installations`); - }*/ } function toBoolean(valueToBoolean) { @@ -1403,8 +1416,8 @@ function toBoolean(valueToBoolean) { if (module.parent) { // Export the constructor in compact mode /** - * @param {Partial} [options={}] - */ + * @param {Partial} [options={}] + */ module.exports = (options) => new Tado(options); } else { // otherwise start the instance directly From cbdd8e1e4418d9172a6afdf797dec7e295d584f0 Mon Sep 17 00:00:00 2001 From: HGlab <54232526+HGlab01@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:46:46 +0200 Subject: [PATCH 2/2] readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6c2045dd..29c42408 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ If someone is supporting to add Tado X functionality, raise a ticket or send an | tado.[x].[yyyyyy].Rooms.[z].setting.fanLebel | Fanlebel (only AC devices with V3+ version) | | tado.[x].[yyyyyy].Rooms.[z].setting.verticalSwing | Vertical swing (only AC devices with V3+ version) | | tado.[x].[yyyyyy].Rooms.[z].setting.horizontalSwing | Horizontal swing (only AC devices with V3 and olderversions) | +| tado.[x].[yyyyyy].meterReadings | JSON-Object with {"date":"YYYY-MM-DD","reading": 1234} can be used to upload meter-readings to Energy IQ | ## Requires * Node.js 18 or higher @@ -50,11 +51,12 @@ If someone is supporting to add Tado X functionality, raise a ticket or send an Placeholder for the next version (at the beginning of the line): ### __WORK IN PROGRESS__ --> -### 0.5.7-alpha.0 (2024-09-24) +### __WORK IN PROGRESS__ * (HGlab01) Change of attribute "light" supported * (HGlab01) Add attribute 'connection' * (HGlab01) Add attribute 'supportsFlowTemperatureOptimization' * (HGlab01) Bump axios to 1.7.7 +* (HGlab01) EnergyIQ meter-readings can be uploaded ### 0.5.6 (2024-08-06) * (HGlab01) Improve AccessToken Management