[miele] Fix supercool/superfreeze for fridges/fridge-freezers (#11321)

* Fix typos.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Do not expose getTypeClass through interface.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Fix channel supercool for fridges and partially fix supercool/superfreeze for fridge-freezers.

Fixes #11320

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>

* Fix two-way channel synchronization for supercool/superfreeze for fridge-freezer.

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
This commit is contained in:
jlaur 2021-09-30 09:00:26 +02:00 committed by GitHub
parent ff272bc828
commit b28413c6f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 80 additions and 71 deletions

View File

@ -39,7 +39,7 @@ public class ExtendedDeviceStateUtil {
/**
* Convert string consisting of 8 bit characters to byte array.
* Note: This simple operation has been extracted and pure here to document
* Note: This simple operation has been extracted and put here to document
* and ensure correct behavior for 8 bit characters that should be turned
* into single bytes without any UTF-8 encoding.
*/

View File

@ -32,8 +32,11 @@ public class MieleBindingConstants {
public static final String PROTOCOL_PROPERTY_NAME = "protocol";
public static final String SERIAL_NUMBER_PROPERTY_NAME = "serialNumber";
public static final String EXTENDED_DEVICE_STATE_PROPERTY_NAME = "extendedDeviceState";
public static final String STATE_PROPERTY_NAME = "state";
// Shared Channel ID's
public static final String SUPERCOOL_CHANNEL_ID = "supercool";
public static final String SUPERFREEZE_CHANNEL_ID = "superfreeze";
public static final String POWER_CONSUMPTION_CHANNEL_ID = "powerConsumption";
public static final String WATER_CONSUMPTION_CHANNEL_ID = "waterConsumption";
@ -51,6 +54,12 @@ public class MieleBindingConstants {
// Miele devices classes
public static final String MIELE_DEVICE_CLASS_COFFEE_SYSTEM = "CoffeeSystem";
public static final String MIELE_DEVICE_CLASS_FRIDGE = "Fridge";
public static final String MIELE_DEVICE_CLASS_FRIDGE_FREEZER = "FridgeFreezer";
// Miele appliance states
public static final int STATE_SUPER_FREEZING = 13;
public static final int STATE_SUPER_COOLING = 14;
// Bridge config properties
public static final String HOST = "ipAddress";

View File

@ -14,7 +14,6 @@ package org.openhab.binding.miele.internal.handler;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData;
import org.openhab.core.types.State;
import org.openhab.core.types.Type;
/**
* The {@link ApplianceChannelSelector} class defines a common interface for
@ -62,9 +61,4 @@ public interface ApplianceChannelSelector {
* @param dmd - the device meta data
*/
State getState(String s, DeviceMetaData dmd);
/**
* Returns "compatible" Type for this datapoint
*/
Class<? extends Type> getTypeClass();
}

View File

@ -52,14 +52,14 @@ public interface ApplianceStatusListener {
void onAppliancePropertyChanged(String serialNumber, DeviceProperty dp);
/**
* This method us called whenever an appliance is removed.
* This method is called whenever an appliance is removed.
*
* @param appliance The XGW homedevice definition of the appliance that was removed
*/
void onApplianceRemoved(HomeDevice appliance);
/**
* This method us called whenever an appliance is added.
* This method is called whenever an appliance is added.
*
* @param appliance The XGW homedevice definition of the appliance that was removed
*/

View File

@ -89,11 +89,6 @@ public enum CoffeeMachineChannelSelector implements ApplianceChannelSelector {
return channelID;
}
@Override
public Class<? extends Type> getTypeClass() {
return typeClass;
}
@Override
public boolean isProperty() {
return isProperty;

View File

@ -160,11 +160,6 @@ public enum DishwasherChannelSelector implements ApplianceChannelSelector {
return channelID;
}
@Override
public Class<? extends Type> getTypeClass() {
return typeClass;
}
@Override
public boolean isProperty() {
return isProperty;

View File

@ -12,6 +12,8 @@
*/
package org.openhab.binding.miele.internal.handler;
import static org.openhab.binding.miele.internal.MieleBindingConstants.SUPERCOOL_CHANNEL_ID;
import java.lang.reflect.Method;
import java.util.Map.Entry;
@ -40,7 +42,7 @@ public enum FridgeChannelSelector implements ApplianceChannelSelector {
BRAND_ID("brandId", "brandId", StringType.class, true),
COMPANY_ID("companyId", "companyId", StringType.class, true),
STATE("state", "state", StringType.class, false),
SUPERCOOL(null, "supercool", OnOffType.class, false),
SUPERCOOL(null, SUPERCOOL_CHANNEL_ID, OnOffType.class, false),
FRIDGECURRENTTEMP("currentTemperature", "current", DecimalType.class, false) {
@Override
public State getState(String s, DeviceMetaData dmd) {
@ -99,11 +101,6 @@ public enum FridgeChannelSelector implements ApplianceChannelSelector {
return channelID;
}
@Override
public Class<? extends Type> getTypeClass() {
return typeClass;
}
@Override
public boolean isProperty() {
return isProperty;

View File

@ -12,6 +12,9 @@
*/
package org.openhab.binding.miele.internal.handler;
import static org.openhab.binding.miele.internal.MieleBindingConstants.SUPERCOOL_CHANNEL_ID;
import static org.openhab.binding.miele.internal.MieleBindingConstants.SUPERFREEZE_CHANNEL_ID;
import java.lang.reflect.Method;
import java.util.Map.Entry;
@ -43,8 +46,8 @@ public enum FridgeFreezerChannelSelector implements ApplianceChannelSelector {
STATE("state", "state", StringType.class, false),
FREEZERSTATE("freezerState", "freezerstate", StringType.class, false),
FRIDGESTATE("fridgeState", "fridgestate", StringType.class, false),
SUPERCOOL(null, "supercool", OnOffType.class, false),
SUPERFREEZE(null, "superfreeze", OnOffType.class, false),
SUPERCOOL(null, SUPERCOOL_CHANNEL_ID, OnOffType.class, false),
SUPERFREEZE(null, SUPERFREEZE_CHANNEL_ID, OnOffType.class, false),
FREEZERCURRENTTEMP("freezerCurrentTemperature", "freezercurrent", DecimalType.class, false) {
@Override
public State getState(String s, DeviceMetaData dmd) {
@ -116,11 +119,6 @@ public enum FridgeFreezerChannelSelector implements ApplianceChannelSelector {
return channelID;
}
@Override
public Class<? extends Type> getTypeClass() {
return typeClass;
}
@Override
public boolean isProperty() {
return isProperty;

View File

@ -12,10 +12,10 @@
*/
package org.openhab.binding.miele.internal.handler;
import static org.openhab.binding.miele.internal.MieleBindingConstants.APPLIANCE_ID;
import static org.openhab.binding.miele.internal.MieleBindingConstants.PROTOCOL_PROPERTY_NAME;
import static org.openhab.binding.miele.internal.MieleBindingConstants.*;
import org.openhab.binding.miele.internal.FullyQualifiedApplianceIdentifier;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceProperty;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
@ -39,7 +39,7 @@ public class FridgeFreezerHandler extends MieleApplianceHandler<FridgeFreezerCha
private final Logger logger = LoggerFactory.getLogger(FridgeFreezerHandler.class);
public FridgeFreezerHandler(Thing thing) {
super(thing, FridgeFreezerChannelSelector.class, "FridgeFreezer");
super(thing, FridgeFreezerChannelSelector.class, MIELE_DEVICE_CLASS_FRIDGE_FREEZER);
}
@Override
@ -89,4 +89,34 @@ public class FridgeFreezerHandler extends MieleApplianceHandler<FridgeFreezerCha
channelID, command.toString());
}
}
@Override
protected void onAppliancePropertyChanged(DeviceProperty dp) {
super.onAppliancePropertyChanged(dp);
if (!dp.Name.equals(STATE_PROPERTY_NAME)) {
return;
}
// Supercool/superfreeze is not exposed directly as property, but can be deduced from state.
OnOffType superCoolState, superFreezeState;
if (dp.Value.equals(String.valueOf(STATE_SUPER_COOLING))) {
superCoolState = OnOffType.ON;
superFreezeState = OnOffType.OFF;
} else if (dp.Value.equals(String.valueOf(STATE_SUPER_FREEZING))) {
superCoolState = OnOffType.OFF;
superFreezeState = OnOffType.ON;
} else {
superCoolState = OnOffType.OFF;
superFreezeState = OnOffType.OFF;
}
ChannelUID superCoolChannelUid = new ChannelUID(getThing().getUID(), SUPERCOOL_CHANNEL_ID);
logger.trace("Update state of {} to {} through '{}'", superCoolChannelUid, superCoolState, dp.Name);
updateState(superCoolChannelUid, superCoolState);
ChannelUID superFreezeChannelUid = new ChannelUID(getThing().getUID(), SUPERFREEZE_CHANNEL_ID);
logger.trace("Update state of {} to {} through '{}'", superFreezeChannelUid, superFreezeState, dp.Name);
updateState(superFreezeChannelUid, superFreezeState);
}
}

View File

@ -12,15 +12,16 @@
*/
package org.openhab.binding.miele.internal.handler;
import static org.openhab.binding.miele.internal.MieleBindingConstants.APPLIANCE_ID;
import static org.openhab.binding.miele.internal.MieleBindingConstants.PROTOCOL_PROPERTY_NAME;
import static org.openhab.binding.miele.internal.MieleBindingConstants.*;
import org.openhab.binding.miele.internal.FullyQualifiedApplianceIdentifier;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceProperty;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
import org.openhab.core.types.State;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -39,7 +40,7 @@ public class FridgeHandler extends MieleApplianceHandler<FridgeChannelSelector>
private final Logger logger = LoggerFactory.getLogger(FridgeHandler.class);
public FridgeHandler(Thing thing) {
super(thing, FridgeChannelSelector.class, "Fridge");
super(thing, FridgeChannelSelector.class, MIELE_DEVICE_CLASS_FRIDGE);
}
@Override
@ -89,4 +90,19 @@ public class FridgeHandler extends MieleApplianceHandler<FridgeChannelSelector>
channelID, command.toString());
}
}
@Override
protected void onAppliancePropertyChanged(DeviceProperty dp) {
super.onAppliancePropertyChanged(dp);
if (!dp.Name.equals(STATE_PROPERTY_NAME)) {
return;
}
// Supercool is not exposed directly as property, but can be deduced from state.
ChannelUID channelUid = new ChannelUID(getThing().getUID(), SUPERCOOL_CHANNEL_ID);
State state = dp.Value.equals(String.valueOf(STATE_SUPER_COOLING)) ? OnOffType.ON : OnOffType.OFF;
logger.trace("Update state of {} to {} through '{}'", channelUid, state, dp.Name);
updateState(channelUid, state);
}
}

View File

@ -119,11 +119,6 @@ public enum HobChannelSelector implements ApplianceChannelSelector {
return channelID;
}
@Override
public Class<? extends Type> getTypeClass() {
return typeClass;
}
@Override
public boolean isProperty() {
return isProperty;

View File

@ -86,11 +86,6 @@ public enum HoodChannelSelector implements ApplianceChannelSelector {
return channelID;
}
@Override
public Class<? extends Type> getTypeClass() {
return typeClass;
}
@Override
public boolean isProperty() {
return isProperty;

View File

@ -192,7 +192,7 @@ public abstract class MieleApplianceHandler<E extends Enum<E> & ApplianceChannel
this.onAppliancePropertyChanged(dp);
}
private void onAppliancePropertyChanged(DeviceProperty dp) {
protected void onAppliancePropertyChanged(DeviceProperty dp) {
try {
DeviceMetaData dmd = null;
if (dp.Metadata == null) {

View File

@ -281,7 +281,7 @@ public class MieleBridgeHandler extends BaseBridgeHandler {
listener.onApplianceStateChanged(applianceIdentifier, dco);
}
} catch (Exception e) {
logger.debug("An exception occurred while quering an appliance : '{}'",
logger.debug("An exception occurred while querying an appliance : '{}'",
e.getMessage());
}
}
@ -387,7 +387,7 @@ public class MieleBridgeHandler extends BaseBridgeHandler {
break;
}
case "value": {
dp.Value = subparts[1];
dp.Value = StringUtils.trim(StringUtils.strip(subparts[1]));
break;
}
case "id": {
@ -600,7 +600,7 @@ public class MieleBridgeHandler extends BaseBridgeHandler {
/**
* This method is called whenever the connection to the given {@link MieleBridge} is resumed.
*
* @param bridge the hue bridge the connection is resumed to
* @param bridge the Miele bridge the connection is resumed to
*/
public void onConnectionResumed() {
updateStatus(ThingStatus.ONLINE);

View File

@ -175,11 +175,6 @@ public enum OvenChannelSelector implements ApplianceChannelSelector {
return channelID;
}
@Override
public Class<? extends Type> getTypeClass() {
return typeClass;
}
@Override
public boolean isProperty() {
return isProperty;

View File

@ -157,11 +157,6 @@ public enum TumbleDryerChannelSelector implements ApplianceChannelSelector {
return channelID;
}
@Override
public Class<? extends Type> getTypeClass() {
return typeClass;
}
@Override
public boolean isProperty() {
return isProperty;

View File

@ -182,11 +182,6 @@ public enum WashingMachineChannelSelector implements ApplianceChannelSelector {
return channelID;
}
@Override
public Class<? extends Type> getTypeClass() {
return typeClass;
}
@Override
public boolean isProperty() {
return isProperty;

View File

@ -108,10 +108,10 @@
</channel-type>
<channel-type id="supercool" advanced="false">
<item-type>String</item-type>
<item-type>Switch</item-type>
<label>Super Cool</label>
<description>Start Super Cooling</description>
<state readOnly="true"></state>
<state readOnly="false"></state>
</channel-type>
<channel-type id="current" advanced="false">
@ -136,10 +136,10 @@
</channel-type>
<channel-type id="superfreeze" advanced="false">
<item-type>String</item-type>
<item-type>Switch</item-type>
<label>Super Freeze</label>
<description>Start Super Freezing</description>
<state readOnly="true"></state>
<state readOnly="false"></state>
</channel-type>
<channel-type id="freezercurrent" advanced="false">