[openwebnet] Fix update of Thermo Central Unit atLeastOneProbeX channels and refactoring (#15269)

* [openwebnet] Fixes changing and startup value for Weekly/Scenario modes
Fixes #12599
* [openwebnet] Thermo: Fixed CU setpointTemp not restored
Fixes #14449
* [openwebnet] fix update of atLeastOneProbeX channels for CU Fixes #15103
Bumped lib openwebnet4j to 0.10.1

Signed-off-by: Massimo Valla <mvcode00@gmail.com>
This commit is contained in:
M Valla 2023-07-18 22:15:33 +02:00 committed by GitHub
parent 6b4ec31348
commit 005d594073
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 210 additions and 206 deletions

View File

@ -23,7 +23,7 @@
<dependency> <dependency>
<groupId>io.github.openwebnet4j</groupId> <groupId>io.github.openwebnet4j</groupId>
<artifactId>openwebnet4j</artifactId> <artifactId>openwebnet4j</artifactId>
<version>0.10.0</version> <version>0.10.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>

View File

@ -14,10 +14,12 @@ package org.openhab.binding.openwebnet.internal.handler;
import static org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants.*; import static org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants.*;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants; import org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants;
import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
@ -36,6 +38,7 @@ import org.openwebnet4j.message.BaseOpenMessage;
import org.openwebnet4j.message.FrameException; import org.openwebnet4j.message.FrameException;
import org.openwebnet4j.message.MalformedFrameException; import org.openwebnet4j.message.MalformedFrameException;
import org.openwebnet4j.message.Thermoregulation; import org.openwebnet4j.message.Thermoregulation;
import org.openwebnet4j.message.Thermoregulation.DimThermo;
import org.openwebnet4j.message.Thermoregulation.WhatThermo; import org.openwebnet4j.message.Thermoregulation.WhatThermo;
import org.openwebnet4j.message.Where; import org.openwebnet4j.message.Where;
import org.openwebnet4j.message.WhereThermo; import org.openwebnet4j.message.WhereThermo;
@ -45,12 +48,13 @@ import org.slf4j.LoggerFactory;
/** /**
* The {@link OpenWebNetThermoregulationHandler} is responsible for handling * The {@link OpenWebNetThermoregulationHandler} is responsible for handling
* commands/messages for Thermoregulation * commands/messages for Thermoregulation Things. It extends the abstract
* Things. It extends the abstract {@link OpenWebNetThingHandler}. * {@link OpenWebNetThingHandler}.
* *
* @author Massimo Valla - Initial contribution. Added support for 4-zone CU * @author Massimo Valla - Initial contribution. Added support for 4-zones CU.
* @author Andrea Conte - Thermoregulation * Rafactoring and fixed CU state channels updates.
* @author Gilberto Cocchi - Thermoregulation * @author Gilberto Cocchi - Initial contribution.
* @author Andrea Conte - Added support for 99-zone CU and CU state channels.
*/ */
@NonNullByDefault @NonNullByDefault
public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler { public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
@ -59,27 +63,30 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = OpenWebNetBindingConstants.THERMOREGULATION_SUPPORTED_THING_TYPES; public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = OpenWebNetBindingConstants.THERMOREGULATION_SUPPORTED_THING_TYPES;
private double currentSetPointTemp = 11.5d; // 11.5 is the default setTemp used in MyHomeUP mobile app private double currentSetPointTemp = 20.0d;
private Thermoregulation.Function currentFunction = Thermoregulation.Function.GENERIC; private Thermoregulation.@Nullable Function currentFunction = null;
private Thermoregulation.OperationMode currentMode = Thermoregulation.OperationMode.MANUAL; private Thermoregulation.@Nullable OperationMode currentMode = null;
private int currentWeeklyPrgNum = 1;
private int currentScenarioPrgNum = 1;
private boolean isStandAlone = true; // true if zone is not associated to a CU private boolean isStandAlone = true; // true if zone is not associated to a CU
private boolean isCentralUnit = false; private boolean isCentralUnit = false;
private String programNumber = "1"; private boolean cuAtLeastOneProbeOff = false;
private boolean cuAtLeastOneProbeProtection = false;
private boolean cuAtLeastOneProbeManual = false;
private String cuBatteryStatus = CU_BATTERY_OK;
private boolean cuFailureDiscovered = false;
private static Set<String> probesInProtection = new HashSet<String>(); private @Nullable ScheduledFuture<?> cuStateChannelsUpdateSchedule;
private static Set<String> probesInOFF = new HashSet<String>();
private static Set<String> probesInManual = new HashSet<String>(); public static final int CU_STATE_CHANNELS_UPDATE_DELAY = 1500; // msec
private static final String CU_REMOTE_CONTROL_ENABLED = "ENABLED"; private static final String CU_REMOTE_CONTROL_ENABLED = "ENABLED";
private static final String CU_REMOTE_CONTROL_DISABLED = "DISABLED"; private static final String CU_REMOTE_CONTROL_DISABLED = "DISABLED";
private static final String CU_BATTERY_OK = "OK"; private static final String CU_BATTERY_OK = "OK";
private static final String CU_BATTERY_KO = "KO"; 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) { public OpenWebNetThermoregulationHandler(Thing thing) {
super(thing); super(thing);
@ -88,18 +95,17 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
@Override @Override
public void initialize() { public void initialize() {
super.initialize(); super.initialize();
ThingTypeUID thingType = thing.getThingTypeUID(); ThingTypeUID thingType = thing.getThingTypeUID();
isCentralUnit = OpenWebNetBindingConstants.THING_TYPE_BUS_THERMO_CU.equals(thingType); isCentralUnit = OpenWebNetBindingConstants.THING_TYPE_BUS_THERMO_CU.equals(thingType);
if (!isCentralUnit) { if (!isCentralUnit) {
Object standAloneConfig = getConfig().get(OpenWebNetBindingConstants.CONFIG_PROPERTY_STANDALONE); if (!((WhereThermo) deviceWhere).isProbe()) {
if (standAloneConfig != null) { Object standAloneConfig = getConfig().get(OpenWebNetBindingConstants.CONFIG_PROPERTY_STANDALONE);
isStandAlone = Boolean.parseBoolean(standAloneConfig.toString()); if (standAloneConfig != null) {
isStandAlone = Boolean.parseBoolean(standAloneConfig.toString());
}
logger.debug("@@@@ THERMO ZONE INITIALIZE isStandAlone={}", isStandAlone);
} }
logger.debug("@@@@ THERMO ZONE INITIALIZE isStandAlone={}", isStandAlone);
} else { } else {
// central unit must have WHERE=#0 or WHERE=0 or WHERE=#0#n // central unit must have WHERE=#0 or WHERE=0 or WHERE=#0#n
String w = deviceWhere.value(); String w = deviceWhere.value();
if (w == null || !("0".equals(w) || "#0".equals(w) || w.startsWith("#0#"))) { if (w == null || !("0".equals(w) || "#0".equals(w) || w.startsWith("#0#"))) {
@ -108,14 +114,6 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
"@text/offline.conf-error-where"); "@text/offline.conf-error-where");
return; return;
} }
// 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));
updateState(CHANNEL_CU_FAILURE_DISCOVERED, OnOffType.OFF);
} }
} }
@ -136,7 +134,7 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
break; break;
case CHANNEL_CU_WEEKLY_PROGRAM_NUMBER: case CHANNEL_CU_WEEKLY_PROGRAM_NUMBER:
case CHANNEL_CU_SCENARIO_PROGRAM_NUMBER: case CHANNEL_CU_SCENARIO_PROGRAM_NUMBER:
handleSetProgramNumber(command); handleSetProgramNumber(channel, command);
break; break;
default: { default: {
logger.warn("handleChannelCommand() Unsupported ChannelUID {}", channel.getId()); logger.warn("handleChannelCommand() Unsupported ChannelUID {}", channel.getId());
@ -180,23 +178,32 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
} }
} }
private void handleSetProgramNumber(Command command) { private void handleSetProgramNumber(ChannelUID channel, Command command) {
if (command instanceof DecimalType) { if (command instanceof DecimalType) {
if (!isCentralUnit) { if (!isCentralUnit) {
logger.warn("handleSetProgramNumber() This command can be sent only for a Central Unit."); logger.warn("handleSetProgramNumber() This command can be sent only for a Central Unit.");
return; return;
} }
int programNumber = ((DecimalType) command).intValue();
boolean updateOpMode = false;
programNumber = command.toString(); if (CHANNEL_CU_WEEKLY_PROGRAM_NUMBER.equals(channel.getId())) {
logger.debug("handleSetProgramNumber() Program number set to {}", programNumber); updateOpMode = currentMode.isWeekly();
currentWeeklyPrgNum = programNumber;
logger.debug("handleSetProgramNumber() currentWeeklyPrgNum changed to: {}", programNumber);
} else {
updateOpMode = currentMode.isScenario();
currentScenarioPrgNum = programNumber;
logger.debug("handleSetProgramNumber() currentScenarioPrgNum changed to: {}", programNumber);
}
// force OperationMode update if we are already in SCENARIO o WEEKLY mode // force OperationMode update if we are already in SCENARIO or WEEKLY mode
if (currentMode.isScenario() || currentMode.isWeekly()) { if (updateOpMode) {
try { try {
Thermoregulation.OperationMode new_mode = Thermoregulation.OperationMode Thermoregulation.OperationMode newMode = Thermoregulation.OperationMode
.valueOf(currentMode.mode() + "_" + programNumber); .valueOf(currentMode.mode() + "_" + programNumber);
logger.debug("handleSetProgramNumber() new mode {}", new_mode); logger.debug("handleSetProgramNumber() new mode {}", newMode);
send(Thermoregulation.requestWriteMode(getWhere(deviceWhere.value()), new_mode, currentFunction, send(Thermoregulation.requestWriteMode(getWhere(deviceWhere.value()), newMode, currentFunction,
currentSetPointTemp)); currentSetPointTemp));
} catch (OWNException e) { } catch (OWNException e) {
logger.warn("handleSetProgramNumber() {}", e.getMessage()); logger.warn("handleSetProgramNumber() {}", e.getMessage());
@ -204,8 +211,9 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
logger.warn("handleSetProgramNumber() Unsupported command {} for thing {}", command, logger.warn("handleSetProgramNumber() Unsupported command {} for thing {}", command,
getThing().getUID()); getThing().getUID());
} }
} else { // just update channel
updateState(channel, new DecimalType(programNumber));
} }
} else { } else {
logger.warn("handleSetProgramNumber() Unsupported command {} for thing {}", command, getThing().getUID()); logger.warn("handleSetProgramNumber() Unsupported command {} for thing {}", command, getThing().getUID());
} }
@ -241,17 +249,21 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
Where w = deviceWhere; Where w = deviceWhere;
if (w != null) { if (w != null) {
try { try {
Thermoregulation.OperationMode new_mode = Thermoregulation.OperationMode.OFF; Thermoregulation.OperationMode newMode = Thermoregulation.OperationMode.OFF;
if (isCentralUnit && WhatThermo.isComplex(command.toString())) { if (isCentralUnit && WhatThermo.isComplex(command.toString())) {
new_mode = Thermoregulation.OperationMode.valueOf(command.toString() + "_" + programNumber); int programNumber = 0;
if ("WEEKLY".equalsIgnoreCase(command.toString())) {
// store current mode programNumber = currentWeeklyPrgNum;
currentMode = new_mode; } else {
programNumber = currentScenarioPrgNum;
}
newMode = Thermoregulation.OperationMode.valueOf(command.toString() + "_" + programNumber);
currentMode = newMode;
} else { } else {
new_mode = Thermoregulation.OperationMode.valueOf(command.toString()); newMode = Thermoregulation.OperationMode.valueOf(command.toString());
} }
send(Thermoregulation.requestWriteMode(getWhere(w.value()), new_mode, currentFunction, send(Thermoregulation.requestWriteMode(getWhere(w.value()), newMode, currentFunction,
currentSetPointTemp)); currentSetPointTemp));
} catch (OWNException e) { } catch (OWNException e) {
logger.warn("handleMode() {}", e.getMessage()); logger.warn("handleMode() {}", e.getMessage());
@ -299,149 +311,139 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
@Override @Override
protected void handleMessage(BaseOpenMessage msg) { protected void handleMessage(BaseOpenMessage msg) {
super.handleMessage(msg); super.handleMessage(msg);
logger.debug("@@@@ Thermo.handleMessage(): {}", msg.toStringVerbose()); logger.debug("@@@@ Thermo.handleMessage(): {}", msg.toStringVerbose());
Thermoregulation tmsg = (Thermoregulation) msg;
if (isCentralUnit) { if (isCentralUnit) {
if (msg.getWhat() == null) { WhatThermo tWhat = (WhatThermo) msg.getWhat();
if (tWhat == null) {
logger.debug("handleMessage() Ignoring unsupported WHAT {}. Frame={}", tWhat, msg);
return; return;
} }
if (tWhat.value() > 40) {
// there isn't a message used for setting OK for battery status so let's assume // it's a CU mode event, CU state events will follow shortly, so let's reset
// it's OK and then change to KO if according message is received // their values
updateCUBatteryStatus(CU_BATTERY_OK); resetCUState();
}
// same in case of Failure Discovered switch (tWhat) {
updateCUFailureDiscovered(OnOffType.OFF); case AT_LEAST_ONE_PROBE_ANTIFREEZE:
cuAtLeastOneProbeProtection = true;
if (msg.getWhat() == Thermoregulation.WhatThermo.REMOTE_CONTROL_DISABLED) { break;
updateCURemoteControlStatus(CU_REMOTE_CONTROL_DISABLED); case AT_LEAST_ONE_PROBE_MANUAL:
} else if (msg.getWhat() == Thermoregulation.WhatThermo.REMOTE_CONTROL_ENABLED) { cuAtLeastOneProbeManual = true;
updateCURemoteControlStatus(CU_REMOTE_CONTROL_ENABLED); break;
} else if (msg.getWhat() == Thermoregulation.WhatThermo.BATTERY_KO) { case AT_LEAST_ONE_PROBE_OFF:
updateCUBatteryStatus(CU_BATTERY_KO); cuAtLeastOneProbeOff = true;
} else if (msg.getWhat() == Thermoregulation.WhatThermo.AT_LEAST_ONE_PROBE_OFF) { break;
updateCUAtLeastOneProbeOff(OnOffType.ON); case BATTERY_KO:
} else if (msg.getWhat() == Thermoregulation.WhatThermo.AT_LEAST_ONE_PROBE_ANTIFREEZE) { cuBatteryStatus = CU_BATTERY_KO;
updateCUAtLeastOneProbeProtection(OnOffType.ON); break;
} else if (msg.getWhat() == Thermoregulation.WhatThermo.AT_LEAST_ONE_PROBE_MANUAL) { case FAILURE_DISCOVERED:
updateCUAtLeastOneProbeManual(OnOffType.ON); cuFailureDiscovered = true;
} else if (msg.getWhat() == Thermoregulation.WhatThermo.FAILURE_DISCOVERED) { break;
updateCUFailureDiscovered(OnOffType.ON); case RELEASE_SENSOR_LOCAL_ADJUST:
} // must intercept all possibile WHATs logger.debug("handleMessage(): Ignoring unsupported WHAT {}. Frame={}", tWhat, msg);
else if (msg.getWhat() == Thermoregulation.WhatThermo.RELEASE_SENSOR_LOCAL_ADJUST) { // will be implemented break;
// soon case REMOTE_CONTROL_DISABLED:
logger.debug("handleMessage() Ignoring unsupported WHAT {}. Frame={}", msg.getWhat(), msg); updateCURemoteControlStatus(CU_REMOTE_CONTROL_DISABLED);
} else if (msg.getWhat().value() == UNDOCUMENTED_WHAT_4001) { break;
logger.debug("handleMessage() Ignoring unsupported WHAT {}. Frame={}", msg.getWhat(), msg); case REMOTE_CONTROL_ENABLED:
} else if (msg.getWhat().value() == UNDOCUMENTED_WHAT_4002) { updateCURemoteControlStatus(CU_REMOTE_CONTROL_ENABLED);
logger.debug("handleMessage() Ignoring unsupported WHAT {}. Frame={}", msg.getWhat(), msg); break;
} else { default:
// check and update values of other channel (mode, function, temp) // check and update values of other channels (mode, function, temp)
updateModeAndFunction((Thermoregulation) msg); updateModeAndFunction(tmsg);
updateSetpoint((Thermoregulation) msg); updateSetpoint(tmsg);
break;
} }
return; return;
} }
if (msg.isCommand()) { if (tmsg.isCommand()) {
updateModeAndFunction((Thermoregulation) msg); updateModeAndFunction(tmsg);
} else { } else {
if (msg.getDim() == null) { DimThermo dim = (DimThermo) tmsg.getDim();
return; switch (dim) {
} case TEMP_SETPOINT:
if (msg.getDim() == Thermoregulation.DimThermo.TEMPERATURE case COMPLETE_PROBE_STATUS:
|| msg.getDim() == Thermoregulation.DimThermo.PROBE_TEMPERATURE) { updateSetpoint(tmsg);
updateTemperature((Thermoregulation) msg); break;
} else if (msg.getDim() == Thermoregulation.DimThermo.TEMP_SETPOINT case PROBE_TEMPERATURE:
|| msg.getDim() == Thermoregulation.DimThermo.COMPLETE_PROBE_STATUS) { case TEMPERATURE:
updateSetpoint((Thermoregulation) msg); updateTemperature(tmsg);
} else if (msg.getDim() == Thermoregulation.DimThermo.VALVES_STATUS) { break;
updateValveStatus((Thermoregulation) msg); case ACTUATOR_STATUS:
} else if (msg.getDim() == Thermoregulation.DimThermo.ACTUATOR_STATUS) { updateActuatorStatus(tmsg);
updateActuatorStatus((Thermoregulation) msg); break;
} else if (msg.getDim() == Thermoregulation.DimThermo.FAN_COIL_SPEED) { case FAN_COIL_SPEED:
updateFanCoilSpeed((Thermoregulation) msg); updateFanCoilSpeed(tmsg);
} else if (msg.getDim() == Thermoregulation.DimThermo.OFFSET) { break;
updateLocalOffset((Thermoregulation) msg); case OFFSET:
} else { updateLocalOffset(tmsg);
logger.debug("handleMessage() Ignoring unsupported DIM {} for thing {}. Frame={}", msg.getDim(), break;
getThing().getUID(), msg); case VALVES_STATUS:
updateValveStatus(tmsg);
break;
default:
logger.debug("handleMessage() Ignoring unsupported DIM {} for thing {}. Frame={}", tmsg.getDim(),
getThing().getUID(), tmsg);
break;
} }
} }
} }
private void updateModeAndFunction(Thermoregulation tmsg) { private void updateModeAndFunction(Thermoregulation tmsg) {
if (tmsg.getWhat() == null) { if (tmsg.getWhat() == null) {
logger.debug("updateModeAndFunction() Could not parse Mode or Function from {} (what is null)", logger.warn("updateModeAndFunction() Could not parse Mode or Function from {} (WHAT is null)",
tmsg.getFrameValue()); tmsg.getFrameValue());
return; return;
} }
Thermoregulation.WhatThermo w = Thermoregulation.WhatThermo.fromValue(tmsg.getWhat().value()); Thermoregulation.WhatThermo w = Thermoregulation.WhatThermo.fromValue(tmsg.getWhat().value());
if (w.getMode() == null) { if (w.getMode() == null) {
logger.debug("updateModeAndFunction() Could not parse Mode from: {}", tmsg.getFrameValue()); logger.warn("updateModeAndFunction() Could not parse Mode from: {}", tmsg.getFrameValue());
return; return;
} }
if (w.getFunction() == null) { if (w.getFunction() == null) {
logger.debug("updateModeAndFunction() Could not parse Function from: {}", tmsg.getFrameValue()); logger.warn("updateModeAndFunction() Could not parse Function from: {}", tmsg.getFrameValue());
return; return;
} }
Thermoregulation.OperationMode operationMode = w.getMode(); Thermoregulation.OperationMode operationMode = null;
Thermoregulation.Function function = w.getFunction(); if (w != WhatThermo.HEATING && w != WhatThermo.CONDITIONING) {
// *4*1*z## and *4*0*z## do not tell us which mode is the zone now
// keep track of thermostats (zones) status operationMode = w.getMode();
if (!isCentralUnit && (!((WhereThermo) deviceWhere).isProbe())) {
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 (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 (operationMode == Thermoregulation.OperationMode.MANUAL) {
probesInProtection.remove(tmsg.getWhere().value());
probesInOFF.remove(tmsg.getWhere().value());
if (probesInManual.add(tmsg.getWhere().value())) {
logger.debug("atLeastOneProbeInManual: added WHERE ---> {}", tmsg.getWhere());
}
}
if (probesInOFF.isEmpty()) {
updateCUAtLeastOneProbeOff(OnOffType.OFF);
}
if (probesInProtection.isEmpty()) {
updateCUAtLeastOneProbeProtection(OnOffType.OFF);
}
if (probesInManual.isEmpty()) {
updateCUAtLeastOneProbeManual(OnOffType.OFF);
}
} }
Thermoregulation.Function function = w.getFunction();
updateState(CHANNEL_FUNCTION, new StringType(function.toString())); updateState(CHANNEL_FUNCTION, new StringType(function.toString()));
// must convert from OperationMode to Mode and set ProgramNumber when necessary // must convert from OperationMode to Mode and set ProgramNumber when necessary
updateState(CHANNEL_MODE, new StringType(operationMode.mode())); if (operationMode != null) {
if (operationMode.isScenario()) { updateState(CHANNEL_MODE, new StringType(operationMode.mode()));
logger.debug("updateModeAndFunction() set SCENARIO program to: {}", operationMode.programNumber()); Integer programN = 0;
updateState(CHANNEL_CU_SCENARIO_PROGRAM_NUMBER, new DecimalType(operationMode.programNumber())); try {
@Nullable
Integer prNum = operationMode.programNumber();
if (prNum != null) {
programN = prNum;
}
} catch (Exception e) {
logger.warn("updateModeAndFunction() Could not parse program number from: {}", tmsg.getFrameValue());
return;
}
if (operationMode.isScenario()) {
logger.debug("{} - updateModeAndFunction() set SCENARIO program to: {}", getThing().getUID(), programN);
updateState(CHANNEL_CU_SCENARIO_PROGRAM_NUMBER, new DecimalType(programN));
currentScenarioPrgNum = programN;
}
if (operationMode.isWeekly()) {
logger.debug("{} - updateModeAndFunction() set WEEKLY program to: {}", getThing().getUID(), programN);
updateState(CHANNEL_CU_WEEKLY_PROGRAM_NUMBER, new DecimalType(programN));
currentWeeklyPrgNum = programN;
}
} }
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 // store current function
currentFunction = function; currentFunction = function;
// in case of Central Unit store also current operation mode
// in case of central unit store also current operation mode
if (isCentralUnit) { if (isCentralUnit) {
currentMode = operationMode; currentMode = operationMode;
} }
@ -459,26 +461,27 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
private void updateSetpoint(Thermoregulation tmsg) { private void updateSetpoint(Thermoregulation tmsg) {
try { try {
double temp = 11.5d; double newTemp = -1;
if (isCentralUnit) { if (isCentralUnit) {
if (tmsg.getWhat() == null) { if (tmsg.getWhat() == null) {
// it should be like *4*WHAT#TTTT*#0## logger.warn("updateSetpoint() Could not parse function from {} (what is null)",
logger.debug("updateSetpoint() Could not parse function from {} (what is null)",
tmsg.getFrameValue()); tmsg.getFrameValue());
return; return;
} }
String[] parameters = tmsg.getWhatParams(); String[] parameters = tmsg.getWhatParams();
if (parameters.length > 0) { if (parameters.length > 0) {
temp = Thermoregulation.decodeTemperature(parameters[0]); // it should be like *4*WHAT#TTTT*#0##
newTemp = Thermoregulation.decodeTemperature(parameters[0]);
logger.debug("updateSetpoint() parsed temperature from {}: {} ---> {}", tmsg.toStringVerbose(), logger.debug("updateSetpoint() parsed temperature from {}: {} ---> {}", tmsg.toStringVerbose(),
parameters[0], temp); parameters[0], newTemp);
} }
} else { } else {
temp = Thermoregulation.parseTemperature(tmsg); newTemp = Thermoregulation.parseTemperature(tmsg);
}
if (newTemp > 0) {
updateState(CHANNEL_TEMP_SETPOINT, getAsQuantityTypeOrNull(newTemp, SIUnits.CELSIUS));
currentSetPointTemp = newTemp;
} }
updateState(CHANNEL_TEMP_SETPOINT, getAsQuantityTypeOrNull(temp, SIUnits.CELSIUS));
currentSetPointTemp = temp;
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
logger.warn("updateSetpoint() NumberFormatException on frame {}: {}", tmsg, e.getMessage()); logger.warn("updateSetpoint() NumberFormatException on frame {}: {}", tmsg, e.getMessage());
updateState(CHANNEL_TEMP_SETPOINT, UnDefType.UNDEF); updateState(CHANNEL_TEMP_SETPOINT, UnDefType.UNDEF);
@ -492,6 +495,9 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
try { try {
Thermoregulation.FanCoilSpeed speed = Thermoregulation.parseFanCoilSpeed(tmsg); Thermoregulation.FanCoilSpeed speed = Thermoregulation.parseFanCoilSpeed(tmsg);
updateState(CHANNEL_FAN_SPEED, new StringType(speed.toString())); updateState(CHANNEL_FAN_SPEED, new StringType(speed.toString()));
} catch (NumberFormatException e) {
logger.warn("updateFanCoilSpeed() NumberFormatException on frame {}: {}", tmsg, e.getMessage());
updateState(CHANNEL_FAN_SPEED, UnDefType.UNDEF);
} catch (FrameException e) { } catch (FrameException e) {
logger.warn("updateFanCoilSpeed() FrameException on frame {}: {}", tmsg, e.getMessage()); logger.warn("updateFanCoilSpeed() FrameException on frame {}: {}", tmsg, e.getMessage());
updateState(CHANNEL_FAN_SPEED, UnDefType.UNDEF); updateState(CHANNEL_FAN_SPEED, UnDefType.UNDEF);
@ -541,35 +547,26 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
logger.debug("updateCURemoteControlStatus(): {}", status); logger.debug("updateCURemoteControlStatus(): {}", status);
} }
private void updateCUBatteryStatus(String status) { private void resetCUState() {
updateState(CHANNEL_CU_BATTERY_STATUS, new StringType(status)); logger.debug("########### resetting CU state");
cuAtLeastOneProbeOff = false;
cuAtLeastOneProbeProtection = false;
cuAtLeastOneProbeManual = false;
cuBatteryStatus = CU_BATTERY_OK;
cuFailureDiscovered = false;
if (status == CU_BATTERY_KO) { // do not log default value (which is automatically setted) cuStateChannelsUpdateSchedule = scheduler.schedule(() -> {
logger.debug("updateCUBatteryStatus(): {}", status); updateCUStateChannels();
} }, CU_STATE_CHANNELS_UPDATE_DELAY, TimeUnit.MILLISECONDS);
} }
private void updateCUFailureDiscovered(OnOffType status) { private void updateCUStateChannels() {
updateState(CHANNEL_CU_FAILURE_DISCOVERED, status); logger.debug("@@@@ updating CU state channels");
updateState(CHANNEL_CU_AT_LEAST_ONE_PROBE_OFF, OnOffType.from(cuAtLeastOneProbeOff));
if (status == OnOffType.ON) { // do not log default value (which is automatically setted) updateState(CHANNEL_CU_AT_LEAST_ONE_PROBE_PROTECTION, OnOffType.from(cuAtLeastOneProbeProtection));
logger.debug("updateCUFailureDiscovered(): {}", status); updateState(CHANNEL_CU_AT_LEAST_ONE_PROBE_MANUAL, OnOffType.from(cuAtLeastOneProbeManual));
} updateState(CHANNEL_CU_BATTERY_STATUS, new StringType(cuBatteryStatus));
} updateState(CHANNEL_CU_FAILURE_DISCOVERED, OnOffType.from(cuFailureDiscovered));
private void updateCUAtLeastOneProbeOff(OnOffType status) {
updateState(CHANNEL_CU_AT_LEAST_ONE_PROBE_OFF, status);
logger.debug("updateCUAtLeastOneProbeOff(): {}", status);
}
private void updateCUAtLeastOneProbeProtection(OnOffType status) {
updateState(CHANNEL_CU_AT_LEAST_ONE_PROBE_PROTECTION, status);
logger.debug("updateCUAtLeastOneProbeProtection(): {}", status);
}
private void updateCUAtLeastOneProbeManual(OnOffType status) {
updateState(CHANNEL_CU_AT_LEAST_ONE_PROBE_MANUAL, status);
logger.debug("updateCUAtLeastOneProbeManual(): {}", status);
} }
private Boolean channelExists(String channelID) { private Boolean channelExists(String channelID) {
@ -581,11 +578,11 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
logger.debug("--- refreshDevice() : refreshing SINGLE... ({})", thing.getUID()); logger.debug("--- refreshDevice() : refreshing SINGLE... ({})", thing.getUID());
if (deviceWhere != null) { if (deviceWhere != null) {
String w = deviceWhere.value(); String whereStr = deviceWhere.value();
if (isCentralUnit) { if (isCentralUnit) {
try { try {
send(Thermoregulation.requestStatus(getWhere(w))); send(Thermoregulation.requestStatus(getWhere(whereStr)));
} catch (OWNException e) { } catch (OWNException e) {
logger.warn("refreshDevice() central unit returned OWNException {}", e.getMessage()); logger.warn("refreshDevice() central unit returned OWNException {}", e.getMessage());
} }
@ -593,35 +590,42 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
} }
try { try {
send(Thermoregulation.requestTemperature(w)); send(Thermoregulation.requestTemperature(whereStr));
if (!((WhereThermo) deviceWhere).isProbe()) { if (!((WhereThermo) deviceWhere).isProbe()) {
// for bus_thermo_zone request also other single channels updates // for bus_thermo_zone request also other single channels updates
send(Thermoregulation.requestSetPointTemperature(w)); send(Thermoregulation.requestSetPointTemperature(whereStr));
send(Thermoregulation.requestMode(w)); send(Thermoregulation.requestMode(whereStr));
// refresh ONLY subscribed channels // refresh ONLY subscribed channels
if (channelExists(CHANNEL_FAN_SPEED)) { if (channelExists(CHANNEL_FAN_SPEED)) {
send(Thermoregulation.requestFanCoilSpeed(w)); send(Thermoregulation.requestFanCoilSpeed(whereStr));
} }
if (channelExists(CHANNEL_CONDITIONING_VALVES) || channelExists(CHANNEL_HEATING_VALVES)) { if (channelExists(CHANNEL_CONDITIONING_VALVES) || channelExists(CHANNEL_HEATING_VALVES)) {
send(Thermoregulation.requestValvesStatus(w)); send(Thermoregulation.requestValvesStatus(whereStr));
} }
if (channelExists(CHANNEL_ACTUATORS)) { if (channelExists(CHANNEL_ACTUATORS)) {
send(Thermoregulation.requestActuatorsStatus(w)); send(Thermoregulation.requestActuatorsStatus(whereStr));
} }
if (channelExists(CHANNEL_LOCAL_OFFSET)) { if (channelExists(CHANNEL_LOCAL_OFFSET)) {
send(Thermoregulation.requestLocalOffset(w)); send(Thermoregulation.requestLocalOffset(whereStr));
} }
} }
} catch (OWNException e) { } catch (OWNException e) {
logger.warn("refreshDevice() where='{}' returned OWNException {}", w, e.getMessage()); logger.warn("refreshDevice() where='{}' returned OWNException {}", whereStr, e.getMessage());
} }
} else { } else {
logger.debug("refreshDevice() where is null"); logger.debug("refreshDevice() where is null");
} }
} }
@Override
public void dispose() {
ScheduledFuture<?> s = cuStateChannelsUpdateSchedule;
if (s != null) {
s.cancel(false);
logger.debug("dispose() - scheduler stopped.");
}
super.dispose();
}
} }