Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[miele] State/program/phase: Add raw channels and improve text channels #11341

Merged
merged 8 commits into from
Oct 10, 2021
309 changes: 299 additions & 10 deletions bundles/org.openhab.binding.miele/README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,22 @@ public class MieleBindingConstants {
public static final String APPLIANCE_ID = "uid";
public static final String DEVICE_CLASS = "dc";
public static final String PROTOCOL_PROPERTY_NAME = "protocol";

// JSON-RPC property names
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";
public static final String PROGRAM_ID_PROPERTY_NAME = "programId";
public static final String PHASE_PROPERTY_NAME = "phase";
public static final String RAW_PHASE_PROPERTY_NAME = "rawPhase";

// Shared Channel ID's
public static final String STATE_TEXT_CHANNEL_ID = "state";
public static final String STATE_CHANNEL_ID = "rawState";
public static final String PROGRAM_TEXT_CHANNEL_ID = "program";
public static final String PROGRAM_CHANNEL_ID = "rawProgram";
public static final String PHASE_TEXT_CHANNEL_ID = "phase";
public static final String PHASE_CHANNEL_ID = "rawPhase";
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";
Expand Down Expand Up @@ -77,6 +88,10 @@ public class MieleBindingConstants {
public static final int STATE_LOCKED = 145;
public static final int STATE_NOT_CONNECTED = 255;

// Miele missing string prefixes
public static final String MISSING_PROGRAM_TEXT_PREFIX = "program.";
public static final String MISSING_PHASE_TEXT_PREFIX = "phase.";

// Bridge config properties
public static final String HOST = "ipAddress";
public static final String INTERFACE = "interface";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ public interface ApplianceChannelSelector {
boolean isExtendedState();

/**
*
* Returns a State for the given string, taking into
* account the metadata provided. The meta data is sent by
* the Miele appliance and is used to decide the State type
Expand All @@ -61,4 +60,12 @@ public interface ApplianceChannelSelector {
* @param dmd - the device meta data
*/
State getState(String s, DeviceMetaData dmd);

/**
* Returns a raw State for the given string, not taking into
* account any metadata.
*
* @param s - the value to be used to instantiate the State
*/
State getState(String s);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@
*/
package org.openhab.binding.miele.internal.handler;

import static org.openhab.binding.miele.internal.MieleBindingConstants.*;

import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;

import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.OpenClosedType;
import org.openhab.core.library.types.StringType;
Expand All @@ -31,17 +36,39 @@
* The {@link ApplianceChannelSelector} for coffee machines
*
* @author Stephan Esch - Initial contribution
* @author Jacob Laursen - Added raw channels
*/
public enum CoffeeMachineChannelSelector implements ApplianceChannelSelector {

PRODUCT_TYPE("productTypeId", "productType", StringType.class, true),
DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true),
BRAND_ID("brandId", "brandId", StringType.class, true),
COMPANY_ID("companyId", "companyId", StringType.class, true),
STATE("state", "state", StringType.class, false),
PROGRAMID("programId", "program", StringType.class, false),
STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false),
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false),
PROGRAM_TEXT(PROGRAM_ID_PROPERTY_NAME, PROGRAM_TEXT_CHANNEL_ID, StringType.class, false) {
@Override
public State getState(String s, DeviceMetaData dmd) {
State state = getTextState(s, dmd, programs, MISSING_PROGRAM_TEXT_PREFIX);
if (state != null) {
return state;
}
return super.getState(s, dmd);
}
},
PROGRAM(null, PROGRAM_CHANNEL_ID, DecimalType.class, false),
PROGRAMTYPE("programType", "type", StringType.class, false),
PROGRAMPHASE("phase", "phase", StringType.class, false),
PROGRAM_PHASE_TEXT(PHASE_PROPERTY_NAME, PHASE_TEXT_CHANNEL_ID, StringType.class, false) {
@Override
public State getState(String s, DeviceMetaData dmd) {
State state = getTextState(s, dmd, phases, MISSING_PHASE_TEXT_PREFIX);
if (state != null) {
return state;
}
return super.getState(s, dmd);
}
},
PROGRAM_PHASE(RAW_PHASE_PROPERTY_NAME, PHASE_CHANNEL_ID, DecimalType.class, false),
// lightingStatus signalFailure signalInfo
DOOR("signalDoor", "door", OpenClosedType.class, false) {
@Override
Expand All @@ -61,6 +88,10 @@ public State getState(String s, DeviceMetaData dmd) {

private final Logger logger = LoggerFactory.getLogger(CoffeeMachineChannelSelector.class);

private final static Map<String, String> programs = Collections.<String, String> emptyMap();

private final static Map<String, String> phases = Collections.<String, String> emptyMap();

private final String mieleID;
private final String channelID;
private final Class<? extends Type> typeClass;
Expand Down Expand Up @@ -130,6 +161,24 @@ public State getState(String s) {
return null;
}

public State getTextState(String s, DeviceMetaData dmd, Map<String, String> valueMap, String prefix) {
if ("0".equals(s)) {
return UnDefType.UNDEF;
}

if (dmd == null || dmd.LocalizedValue == null || dmd.LocalizedValue.startsWith(prefix)) {
String text = valueMap.get(s);
if (text != null) {
return getState(text);
}
if (dmd == null || dmd.LocalizedValue == null) {
return getState(prefix + s);
}
}

return null;
}

public String getMieleEnum(String s, DeviceMetaData dmd) {
if (dmd.MieleEnum != null) {
for (Entry<String, JsonElement> enumEntry : dmd.MieleEnum.entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,19 @@
*/
package org.openhab.binding.miele.internal.handler;

import static org.openhab.binding.miele.internal.MieleBindingConstants.EXTENDED_DEVICE_STATE_PROPERTY_NAME;
import static org.openhab.binding.miele.internal.MieleBindingConstants.POWER_CONSUMPTION_CHANNEL_ID;
import static org.openhab.binding.miele.internal.MieleBindingConstants.WATER_CONSUMPTION_CHANNEL_ID;
import static java.util.Map.entry;
import static org.openhab.binding.miele.internal.MieleBindingConstants.*;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TimeZone;

import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData;
import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.OpenClosedType;
import org.openhab.core.library.types.QuantityType;
Expand All @@ -41,17 +42,38 @@
*
* @author Karel Goderis - Initial contribution
* @author Kai Kreuzer - Changed START_TIME to DateTimeType
* @author Jacob Laursen - Added power/water consumption channels
* @author Jacob Laursen - Added power/water consumption channels, raw channels
*/
public enum DishwasherChannelSelector implements ApplianceChannelSelector {

PRODUCT_TYPE("productTypeId", "productType", StringType.class, true, false),
DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true, false),
BRAND_ID("brandId", "brandId", StringType.class, true, false),
COMPANY_ID("companyId", "companyId", StringType.class, true, false),
STATE("state", "state", StringType.class, false, false),
PROGRAMID("programId", "program", StringType.class, false, false),
PROGRAMPHASE("phase", "phase", StringType.class, false, false),
STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false, false),
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false, false),
PROGRAM_TEXT(PROGRAM_ID_PROPERTY_NAME, PROGRAM_TEXT_CHANNEL_ID, StringType.class, false, false) {
@Override
public State getState(String s, DeviceMetaData dmd) {
State state = getTextState(s, dmd, programs, MISSING_PROGRAM_TEXT_PREFIX);
if (state != null) {
return state;
}
return super.getState(s, dmd);
}
},
PROGRAM(null, PROGRAM_CHANNEL_ID, DecimalType.class, false, false),
PROGRAM_PHASE_TEXT(PHASE_PROPERTY_NAME, PHASE_TEXT_CHANNEL_ID, StringType.class, false, false) {
@Override
public State getState(String s, DeviceMetaData dmd) {
State state = getTextState(s, dmd, phases, MISSING_PHASE_TEXT_PREFIX);
if (state != null) {
return state;
}
return super.getState(s, dmd);
}
},
PROGRAM_PHASE(RAW_PHASE_PROPERTY_NAME, PHASE_CHANNEL_ID, DecimalType.class, false, false),
START_TIME("startTime", "start", DateTimeType.class, false, false) {
@Override
public State getState(String s, DeviceMetaData dmd) {
Expand Down Expand Up @@ -130,6 +152,14 @@ public State getState(String s, DeviceMetaData dmd) {

private final Logger logger = LoggerFactory.getLogger(DishwasherChannelSelector.class);

private final static Map<String, String> programs = Map.ofEntries(entry("26", "Pots & Pans"),
entry("27", "Clean Machine"), entry("28", "Economy"), entry("30", "Normal"), entry("32", "Sensor Wash"),
entry("34", "Energy Saver"), entry("35", "China & Crystal"), entry("36", "Extra Quiet"),
entry("37", "SaniWash"), entry("38", "QuickPowerWash"), entry("42", "Tall items"));

private final static Map<String, String> phases = Map.ofEntries(entry("2", "Pre-Wash"), entry("3", "Main Wash"),
entry("4", "Rinses"), entry("6", "Final rinse"), entry("7", "Drying"));

private final String mieleID;
private final String channelID;
private final Class<? extends Type> typeClass;
Expand Down Expand Up @@ -201,6 +231,24 @@ public State getState(String s) {
return null;
}

public State getTextState(String s, DeviceMetaData dmd, Map<String, String> valueMap, String prefix) {
if ("0".equals(s)) {
return UnDefType.UNDEF;
}

if (dmd == null || dmd.LocalizedValue == null || dmd.LocalizedValue.startsWith(prefix)) {
String text = valueMap.get(s);
if (text != null) {
return getState(text);
}
if (dmd == null || dmd.LocalizedValue == null) {
return getState(prefix + s);
}
}

return null;
}

public String getMieleEnum(String s, DeviceMetaData dmd) {
if (dmd.MieleEnum != null) {
for (Entry<String, JsonElement> enumEntry : dmd.MieleEnum.entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
*/
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.*;

import java.lang.reflect.Method;
import java.util.Map.Entry;

import org.openhab.binding.miele.internal.ExtendedDeviceStateUtil;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.OpenClosedType;
import org.openhab.core.library.types.QuantityType;
Expand All @@ -35,14 +36,16 @@
* The {@link ApplianceChannelSelector} for fridges
*
* @author Karel Goderis - Initial contribution
* @author Jacob Laursen - Added UoM for temperatures, raw channels
*/
public enum FridgeChannelSelector implements ApplianceChannelSelector {

PRODUCT_TYPE("productTypeId", "productType", StringType.class, true),
DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true),
BRAND_ID("brandId", "brandId", StringType.class, true),
COMPANY_ID("companyId", "companyId", StringType.class, true),
STATE("state", "state", StringType.class, false),
STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false),
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false),
SUPERCOOL(null, SUPERCOOL_CHANNEL_ID, OnOffType.class, false),
FRIDGECURRENTTEMP("currentTemperature", "current", QuantityType.class, false) {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
*/
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 static org.openhab.binding.miele.internal.MieleBindingConstants.*;

import java.lang.reflect.Method;
import java.util.Map.Entry;

import org.openhab.binding.miele.internal.ExtendedDeviceStateUtil;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.OpenClosedType;
import org.openhab.core.library.types.QuantityType;
Expand All @@ -37,14 +37,16 @@
* a freezer compartment
*
* @author Karel Goderis - Initial contribution
* @author Jacob Laursen - Added UoM for temperatures, raw channels
*/
public enum FridgeFreezerChannelSelector implements ApplianceChannelSelector {

PRODUCT_TYPE("productTypeId", "productType", StringType.class, true),
DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true),
BRAND_ID("brandId", "brandId", StringType.class, true),
COMPANY_ID("companyId", "companyId", StringType.class, true),
STATE("state", "state", StringType.class, false),
STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false),
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false),
FREEZERSTATE("freezerState", "freezerstate", StringType.class, false),
FRIDGESTATE("fridgeState", "fridgestate", StringType.class, false),
SUPERCOOL(null, SUPERCOOL_CHANNEL_ID, OnOffType.class, false),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
*/
package org.openhab.binding.miele.internal.handler;

import static org.openhab.binding.miele.internal.MieleBindingConstants.*;

import java.lang.reflect.Method;
import java.util.Map.Entry;

Expand All @@ -29,14 +31,16 @@
* The {@link ApplianceChannelSelector} for hobs
*
* @author Karel Goderis - Initial contribution
* @author Jacob Laursen - Added raw channels
*/
public enum HobChannelSelector implements ApplianceChannelSelector {

PRODUCT_TYPE("productTypeId", "productType", StringType.class, true),
DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true),
BRAND_ID("brandId", "brandId", StringType.class, true),
COMPANY_ID("companyId", "companyId", StringType.class, true),
STATE("state", "state", StringType.class, false),
STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false),
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false),
PLATES("plateNumbers", "plates", DecimalType.class, true),
PLATE1_POWER("plate1PowerStep", "plate1power", DecimalType.class, false),
PLATE1_HEAT("plate1RemainingHeat", "plate1heat", DecimalType.class, false) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
*/
package org.openhab.binding.miele.internal.handler;

import static org.openhab.binding.miele.internal.MieleBindingConstants.*;

import java.lang.reflect.Method;
import java.util.Map.Entry;

Expand All @@ -31,14 +33,16 @@
* The {@link ApplianceChannelSelector} for ventilation hoods
*
* @author Karel Goderis - Initial contribution
* @author Jacob Laursen - Added raw channels
*/
public enum HoodChannelSelector implements ApplianceChannelSelector {

PRODUCT_TYPE("productTypeId", "productType", StringType.class, true),
DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true),
BRAND_ID("brandId", "brandId", StringType.class, true),
COMPANY_ID("companyId", "companyId", StringType.class, true),
STATE("state", "state", StringType.class, false),
STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false),
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false),
VENTILATION("ventilationPower", "ventilation", DecimalType.class, false),
LIGHT("lightingStatus", "light", OnOffType.class, false) {
@Override
Expand Down
Loading