From 4774f8a7e76f6b5fbf3ea8e41fe3f14758c4de0c Mon Sep 17 00:00:00 2001 From: Conte Andrea Date: Fri, 25 Mar 2022 17:32:10 +0100 Subject: [PATCH] [openwebnet] fixing support for central unit (#12514) * - read Temperature set in central unit at startup * - ignoring what 4002 which may lead to unpredicted behaviours - usage of own 0.8.0 from mvalla (new getWhatParameter method) * attempt to integrate own 0.8.0 * - read setTemp (MANUAL mode) at startup - read mode (OFF/PROTECTION/WEEKLY/SCENARIO/MANUAL) at startup - persist selected mode (see issue 12401) * remove unnecessary logs * - fix typo - own4j 0.8.1 * fix placeholder count Signed-off-by: Conte Andrea --- .../org.openhab.binding.openwebnet/pom.xml | 2 +- .../OpenWebNetThermoregulationHandler.java | 101 +++++++++++++++--- 2 files changed, 89 insertions(+), 14 deletions(-) diff --git a/bundles/org.openhab.binding.openwebnet/pom.xml b/bundles/org.openhab.binding.openwebnet/pom.xml index 24b732b72..56dfaefc0 100644 --- a/bundles/org.openhab.binding.openwebnet/pom.xml +++ b/bundles/org.openhab.binding.openwebnet/pom.xml @@ -23,7 +23,7 @@ io.github.openwebnet4j openwebnet4j - 0.7.1 + 0.8.1 compile diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetThermoregulationHandler.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetThermoregulationHandler.java index 21a0a4ac8..c25211937 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetThermoregulationHandler.java +++ b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetThermoregulationHandler.java @@ -77,12 +77,13 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler { private double currentSetPointTemp = 11.5d; // 11.5 is the default setTemp used in MyHomeUP mobile app private Thermoregulation.Function currentFunction = Thermoregulation.Function.GENERIC; + private Thermoregulation.OperationMode currentMode = Thermoregulation.OperationMode.MANUAL; private boolean isStandAlone = false; private boolean isCentralUnit = false; - private String programNumber = ""; + private String programNumber = "1"; private static Set probesInProtection = new HashSet(); private static Set probesInOFF = new HashSet(); @@ -92,6 +93,8 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler { private static final String CU_REMOTE_CONTROL_DISABLED = "DISABLED"; private static final String CU_BATTERY_OK = "OK"; private static final String CU_BATTERY_KO = "KO"; + private static final Integer UNDOCUMENTED_WHAT_4001 = 4001; + private static final Integer UNDOCUMENTED_WHAT_4002 = 4002; public OpenWebNetThermoregulationHandler(Thing thing) { super(thing); @@ -118,6 +121,13 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "@text/offline.conf-error-where"); } + + // reset state of signal channels (they will be setted when specific messages are received) + updateState(CHANNEL_CU_AT_LEAST_ONE_PROBE_MANUAL, OnOffType.OFF); + updateState(CHANNEL_CU_AT_LEAST_ONE_PROBE_OFF, OnOffType.OFF); + updateState(CHANNEL_CU_AT_LEAST_ONE_PROBE_PROTECTION, OnOffType.OFF); + updateState(CHANNEL_CU_SCENARIO_PROGRAM_NUMBER, new DecimalType(programNumber)); + updateState(CHANNEL_CU_WEEKLY_PROGRAM_NUMBER, new DecimalType(programNumber)); } } @@ -192,6 +202,22 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler { programNumber = command.toString(); logger.debug("handleSetProgramNumber() Program number set to {}", programNumber); + // force OperationMode update if we are already in SCENARIO o WEEKLY mode + if (currentMode.isScenario() || currentMode.isWeekly()) { + try { + Thermoregulation.OperationMode new_mode = Thermoregulation.OperationMode + .valueOf(currentMode.mode() + "_" + programNumber); + logger.debug("handleSetProgramNumber() new mode {}", new_mode); + send(Thermoregulation.requestWriteMode(getWhere(""), new_mode, currentFunction, + currentSetPointTemp)); + } catch (OWNException e) { + logger.warn("handleSetProgramNumber() {}", e.getMessage()); + } catch (IllegalArgumentException e) { + logger.warn("handleSetProgramNumber() Unsupported command {} for thing {}", command, + getThing().getUID()); + } + } + } else { logger.warn("handleSetProgramNumber() Unsupported command {} for thing {}", command, getThing().getUID()); } @@ -229,11 +255,14 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler { try { Thermoregulation.OperationMode new_mode = Thermoregulation.OperationMode.OFF; - if (isCentralUnit && WhatThermo.isComplex(command.toString())) + if (isCentralUnit && WhatThermo.isComplex(command.toString())) { new_mode = Thermoregulation.OperationMode.valueOf(command.toString() + "_" + programNumber); - else - new_mode = Thermoregulation.OperationMode.valueOf(command.toString()); + // store current mode + currentMode = new_mode; + } else { + new_mode = Thermoregulation.OperationMode.valueOf(command.toString()); + } send(Thermoregulation.requestWriteMode(getWhere(w.value()), new_mode, currentFunction, currentSetPointTemp)); } catch (OWNException e) { @@ -280,6 +309,10 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler { super.handleMessage(msg); if (isCentralUnit) { + if (msg.getWhat() == null) { + return; + } + // there isn't a message used for setting OK for battery status so let's assume // it's OK and then change to KO if according message is received updateCUBatteryStatus(CU_BATTERY_OK); @@ -301,12 +334,18 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler { updateCUAtLeastOneProbeManual(OnOffType.ON); } else if (msg.getWhat() == Thermoregulation.WhatThermo.FAILURE_DISCOVERED) { updateCUFailureDiscovered(OnOffType.ON); - } // must intercept all possibile WHATs (will be implemented soon) - else if (msg.getWhat() == Thermoregulation.WhatThermo.RELEASE_SENSOR_LOCAL_ADJUST) { + } // must intercept all possibile WHATs + else if (msg.getWhat() == Thermoregulation.WhatThermo.RELEASE_SENSOR_LOCAL_ADJUST) { // will be implemented + // soon + logger.debug("handleMessage() Ignoring unsupported WHAT {}. Frame={}", msg.getWhat(), msg); + } else if (msg.getWhat().value() == UNDOCUMENTED_WHAT_4001) { + logger.debug("handleMessage() Ignoring unsupported WHAT {}. Frame={}", msg.getWhat(), msg); + } else if (msg.getWhat().value() == UNDOCUMENTED_WHAT_4002) { logger.debug("handleMessage() Ignoring unsupported WHAT {}. Frame={}", msg.getWhat(), msg); } else { - // check and eventually parse mode and function + // check and update values of other channel (mode, function, temp) updateModeAndFunction((Thermoregulation) msg); + updateSetpoint((Thermoregulation) msg); } return; } @@ -350,29 +389,30 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler { logger.debug("updateModeAndFunction() Could not parse Mode from: {}", tmsg.getFrameValue()); return; } + if (w.getFunction() == null) { logger.debug("updateModeAndFunction() Could not parse Function from: {}", tmsg.getFrameValue()); return; } - Thermoregulation.OperationMode mode = w.getMode(); + Thermoregulation.OperationMode operationMode = w.getMode(); Thermoregulation.Function function = w.getFunction(); // keep track of thermostats (zones) status if (!isCentralUnit && (!((WhereThermo) deviceWhere).isProbe())) { - if (mode == Thermoregulation.OperationMode.OFF) { + if (operationMode == Thermoregulation.OperationMode.OFF) { probesInManual.remove(tmsg.getWhere().value()); probesInProtection.remove(tmsg.getWhere().value()); if (probesInOFF.add(tmsg.getWhere().value())) { logger.debug("atLeastOneProbeInOFF: added WHERE ---> {}", tmsg.getWhere()); } - } else if (mode == Thermoregulation.OperationMode.PROTECTION) { + } else if (operationMode == Thermoregulation.OperationMode.PROTECTION) { probesInManual.remove(tmsg.getWhere().value()); probesInOFF.remove(tmsg.getWhere().value()); if (probesInProtection.add(tmsg.getWhere().value())) { logger.debug("atLeastOneProbeInProtection: added WHERE ---> {}", tmsg.getWhere()); } - } else if (mode == Thermoregulation.OperationMode.MANUAL) { + } else if (operationMode == Thermoregulation.OperationMode.MANUAL) { probesInProtection.remove(tmsg.getWhere().value()); probesInOFF.remove(tmsg.getWhere().value()); if (probesInManual.add(tmsg.getWhere().value())) { @@ -392,10 +432,25 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler { } updateState(CHANNEL_FUNCTION, new StringType(function.toString())); - updateState(CHANNEL_MODE, new StringType(mode.toString())); + + // must convert from OperationMode to Mode and set ProgramNumber when necessary + updateState(CHANNEL_MODE, new StringType(operationMode.mode())); + if (operationMode.isScenario()) { + logger.debug("updateModeAndFunction() set SCENARIO program to: {}", operationMode.programNumber()); + updateState(CHANNEL_CU_SCENARIO_PROGRAM_NUMBER, new DecimalType(operationMode.programNumber())); + } + if (operationMode.isWeekly()) { + logger.debug("updateModeAndFunction() set WEEKLY program to: {}", operationMode.programNumber()); + updateState(CHANNEL_CU_WEEKLY_PROGRAM_NUMBER, new DecimalType(operationMode.programNumber())); + } // store current function currentFunction = function; + + // in case of central unit store also current operation mode + if (isCentralUnit) { + currentMode = operationMode; + } } private void updateTemperature(Thermoregulation tmsg) { @@ -410,9 +465,29 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler { private void updateSetpoint(Thermoregulation tmsg) { try { - double temp = Thermoregulation.parseTemperature(tmsg); + double temp = 11.5d; + if (isCentralUnit) { + if (tmsg.getWhat() == null) { + // it should be like *4*WHAT#TTTT*#0## + logger.debug("updateSetpoint() Could not parse function from {} (what is null)", + tmsg.getFrameValue()); + return; + } + + String[] parameters = tmsg.getWhatParams(); + if (parameters.length > 0) { + temp = Thermoregulation.decodeTemperature(parameters[0]); + logger.debug("updateSetpoint() parsed temperature from {}: {} ---> {}", tmsg.toStringVerbose(), + parameters[0], temp); + } + } else { + temp = Thermoregulation.parseTemperature(tmsg); + } updateState(CHANNEL_TEMP_SETPOINT, getAsQuantityTypeOrNull(temp, SIUnits.CELSIUS)); currentSetPointTemp = temp; + } catch (NumberFormatException e) { + logger.warn("updateSetpoint() NumberFormatException on frame {}: {}", tmsg, e.getMessage()); + updateState(CHANNEL_TEMP_SETPOINT, UnDefType.UNDEF); } catch (FrameException e) { logger.warn("updateSetpoint() FrameException on frame {}: {}", tmsg, e.getMessage()); updateState(CHANNEL_TEMP_SETPOINT, UnDefType.UNDEF);