[miio] Allow for quantity Type (#8756)
* [miio] Allow for quantity Type in the basic handler This extends the miio:basic handler with the option to define channels with QuantityType e.g. to use number:temperature * [miio] add missing breaks Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com>
This commit is contained in:
parent
9f22e64ffd
commit
918408eac1
|
@ -3122,13 +3122,13 @@ e.g. `smarthome:send actionCommand 'upd_timer["1498595904821", "on"]'` would ena
|
|||
| Channel | Type | Description | Comment |
|
||||
|------------------|---------|-------------------------------------|------------|
|
||||
| power | Switch | Power | |
|
||||
| target_temperature | Number | Target Temperature | |
|
||||
| target_temperature | Number:Temperature | Target Temperature | |
|
||||
| brightness | Number | Brightness | |
|
||||
| buzzer | Switch | Buzzer Status | |
|
||||
| relative_humidity | Number | Relative Humidity | |
|
||||
| childlock | Switch | Child Lock | |
|
||||
| HWSwitch | Switch | HW Switch | |
|
||||
| temperature | Number | Temperature | |
|
||||
| temperature | Number:Temperature | Temperature | |
|
||||
| usedhours | Number | Run Time | |
|
||||
|
||||
|
||||
|
@ -6429,13 +6429,13 @@ note: Autogenerated example. Replace the id (heater) in the channel with your ow
|
|||
```java
|
||||
Group G_heater "Zhimi Heater" <status>
|
||||
Switch power "Power" (G_heater) {channel="miio:basic:heater:power"}
|
||||
Number target_temperature "Target Temperature" (G_heater) {channel="miio:basic:heater:target_temperature"}
|
||||
Number:Temperature target_temperature "Target Temperature" (G_heater) {channel="miio:basic:heater:target_temperature"}
|
||||
Number brightness "Brightness" (G_heater) {channel="miio:basic:heater:brightness"}
|
||||
Switch buzzer "Buzzer Status" (G_heater) {channel="miio:basic:heater:buzzer"}
|
||||
Number relative_humidity "Relative Humidity" (G_heater) {channel="miio:basic:heater:relative_humidity"}
|
||||
Switch childlock "Child Lock" (G_heater) {channel="miio:basic:heater:childlock"}
|
||||
Switch HWSwitch "HW Switch" (G_heater) {channel="miio:basic:heater:HWSwitch"}
|
||||
Number temperature "Temperature" (G_heater) {channel="miio:basic:heater:temperature"}
|
||||
Number:Temperature temperature "Temperature" (G_heater) {channel="miio:basic:heater:temperature"}
|
||||
Number usedhours "Run Time" (G_heater) {channel="miio:basic:heater:usedhours"}
|
||||
```
|
||||
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.miio.internal;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.measure.Unit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.unit.ImperialUnits;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
import org.openhab.core.library.unit.SmartHomeUnits;
|
||||
|
||||
/**
|
||||
* Enum of the units used in the miio protocol
|
||||
* Used to find the right {@link javax.measure.Unit} given the string of the unit
|
||||
*
|
||||
* @author Marcel Verpaalen - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum MiIoQuantiyTypes {
|
||||
|
||||
CELCIUS(SIUnits.CELSIUS),
|
||||
FAHRENHEIT(ImperialUnits.FAHRENHEIT),
|
||||
SECOND(SmartHomeUnits.SECOND),
|
||||
MINUTE(SmartHomeUnits.MINUTE),
|
||||
HOUR(SmartHomeUnits.HOUR),
|
||||
AMPERE(SmartHomeUnits.AMPERE),
|
||||
WATT(SmartHomeUnits.WATT);
|
||||
|
||||
private final Unit<?> unit;
|
||||
|
||||
private static Map<String, Unit<?>> stringMap = Arrays.stream(values())
|
||||
.collect(Collectors.toMap(Enum::toString, MiIoQuantiyTypes::getUnit));
|
||||
|
||||
private MiIoQuantiyTypes(Unit<?> unit) {
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
public Unit<?> getUnit() {
|
||||
return unit;
|
||||
}
|
||||
|
||||
public static @Nullable Unit<?> get(String unitName) {
|
||||
return stringMap.get(unitName.toUpperCase());
|
||||
}
|
||||
}
|
|
@ -53,6 +53,9 @@ public class MiIoBasicChannel {
|
|||
@SerializedName("type")
|
||||
@Expose
|
||||
private @Nullable String type;
|
||||
@SerializedName("unit")
|
||||
@Expose
|
||||
private @Nullable String unit;
|
||||
@SerializedName("refresh")
|
||||
@Expose
|
||||
private @Nullable Boolean refresh;
|
||||
|
@ -155,6 +158,15 @@ public class MiIoBasicChannel {
|
|||
this.type = type;
|
||||
}
|
||||
|
||||
public String getUnit() {
|
||||
final @Nullable String unit = this.unit;
|
||||
return unit != null ? unit : "";
|
||||
}
|
||||
|
||||
public void setUnit(String unit) {
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
public Boolean getRefresh() {
|
||||
final @Nullable Boolean rf = refresh;
|
||||
return rf != null && rf.booleanValue() && !getProperty().isEmpty();
|
||||
|
|
|
@ -23,11 +23,15 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.measure.Unit;
|
||||
import javax.measure.format.ParserException;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.miio.internal.MiIoBindingConfiguration;
|
||||
import org.openhab.binding.miio.internal.MiIoCommand;
|
||||
import org.openhab.binding.miio.internal.MiIoCryptoException;
|
||||
import org.openhab.binding.miio.internal.MiIoQuantiyTypes;
|
||||
import org.openhab.binding.miio.internal.MiIoSendCommand;
|
||||
import org.openhab.binding.miio.internal.Utils;
|
||||
import org.openhab.binding.miio.internal.basic.ActionConditions;
|
||||
|
@ -44,7 +48,10 @@ import org.openhab.core.library.types.DecimalType;
|
|||
import org.openhab.core.library.types.HSBType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.PercentType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
import org.openhab.core.library.unit.SmartHomeUnits;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
|
@ -105,7 +112,8 @@ public class MiIoBasicHandler extends MiIoAbstractHandler {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
public void handleCommand(ChannelUID channelUID, Command receivedCommand) {
|
||||
Command command = receivedCommand;
|
||||
if (command == RefreshType.REFRESH) {
|
||||
if (updateDataCache.isExpired()) {
|
||||
logger.debug("Refreshing {}", channelUID);
|
||||
|
@ -119,7 +127,7 @@ public class MiIoBasicHandler extends MiIoAbstractHandler {
|
|||
cmds.put(sendCommand(command.toString()), command.toString());
|
||||
return;
|
||||
}
|
||||
logger.debug("Locating action for channel '{}': '{}'", channelUID.getId(), command);
|
||||
logger.debug("Locating action for {} channel '{}': '{}'", getThing().getUID(), channelUID.getId(), command);
|
||||
if (!actions.isEmpty()) {
|
||||
if (actions.containsKey(channelUID)) {
|
||||
int valuePos = 0;
|
||||
|
@ -137,6 +145,25 @@ public class MiIoBasicHandler extends MiIoAbstractHandler {
|
|||
}
|
||||
String cmd = action.getCommand();
|
||||
CommandParameterType paramType = action.getparameterType();
|
||||
if (command instanceof QuantityType) {
|
||||
QuantityType<?> qtc = null;
|
||||
try {
|
||||
if (!miIoBasicChannel.getUnit().isBlank()) {
|
||||
Unit<?> unit = MiIoQuantiyTypes.get(miIoBasicChannel.getUnit());
|
||||
if (unit != null) {
|
||||
qtc = ((QuantityType<?>) command).toUnit(unit);
|
||||
}
|
||||
}
|
||||
} catch (ParserException e) {
|
||||
// swallow
|
||||
}
|
||||
if (qtc != null) {
|
||||
command = new DecimalType(qtc.toBigDecimal());
|
||||
} else {
|
||||
logger.debug("Could not convert QuantityType to '{}'", miIoBasicChannel.getUnit());
|
||||
command = new DecimalType(((QuantityType<?>) command).toBigDecimal());
|
||||
}
|
||||
}
|
||||
if (paramType == CommandParameterType.COLOR) {
|
||||
if (command instanceof HSBType) {
|
||||
HSBType hsb = (HSBType) command;
|
||||
|
@ -505,9 +532,10 @@ public class MiIoBasicHandler extends MiIoAbstractHandler {
|
|||
val = transformed;
|
||||
}
|
||||
try {
|
||||
switch (basicChannel.getType().toLowerCase()) {
|
||||
String[] chType = basicChannel.getType().toLowerCase().split(":");
|
||||
switch (chType[0]) {
|
||||
case "number":
|
||||
updateState(basicChannel.getChannel(), new DecimalType(val.getAsBigDecimal()));
|
||||
quantityTypeUpdate(basicChannel, val, chType.length > 1 ? chType[1] : "");
|
||||
break;
|
||||
case "dimmer":
|
||||
updateState(basicChannel.getChannel(), new PercentType(val.getAsBigDecimal()));
|
||||
|
@ -534,6 +562,39 @@ public class MiIoBasicHandler extends MiIoAbstractHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private void quantityTypeUpdate(MiIoBasicChannel basicChannel, JsonElement val, String type) {
|
||||
if (!basicChannel.getUnit().isBlank()) {
|
||||
Unit<?> unit = MiIoQuantiyTypes.get(basicChannel.getUnit());
|
||||
if (unit != null) {
|
||||
logger.debug("'{}' channel '{}' has unit '{}' with symbol '{}'.", getThing().getUID(),
|
||||
basicChannel.getChannel(), basicChannel.getUnit(), unit);
|
||||
updateState(basicChannel.getChannel(), new QuantityType<>(val.getAsBigDecimal(), unit));
|
||||
} else {
|
||||
logger.debug("Unit '{}' used by '{}' channel '{}' is not found.. using default unit.",
|
||||
getThing().getUID(), basicChannel.getUnit(), basicChannel.getChannel());
|
||||
}
|
||||
}
|
||||
// if no unit is provided or unit not found use default units, these units have so far been seen for miio
|
||||
// devices
|
||||
switch (type.toLowerCase()) {
|
||||
case "temperature":
|
||||
updateState(basicChannel.getChannel(), new QuantityType<>(val.getAsBigDecimal(), SIUnits.CELSIUS));
|
||||
break;
|
||||
case "electriccurrent":
|
||||
updateState(basicChannel.getChannel(),
|
||||
new QuantityType<>(val.getAsBigDecimal(), SmartHomeUnits.AMPERE));
|
||||
break;
|
||||
case "energy":
|
||||
updateState(basicChannel.getChannel(), new QuantityType<>(val.getAsBigDecimal(), SmartHomeUnits.WATT));
|
||||
break;
|
||||
case "time":
|
||||
updateState(basicChannel.getChannel(), new QuantityType<>(val.getAsBigDecimal(), SmartHomeUnits.HOUR));
|
||||
break;
|
||||
default:
|
||||
updateState(basicChannel.getChannel(), new DecimalType(val.getAsBigDecimal()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageReceived(MiIoSendCommand response) {
|
||||
super.onMessageReceived(response);
|
||||
|
|
|
@ -154,6 +154,11 @@
|
|||
<label>Temperature</label>
|
||||
<state pattern="%.1f" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="temperatureC">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Temperature</label>
|
||||
<state readOnly="true" pattern="%.1f %unit%"/>
|
||||
</channel-type>
|
||||
<channel-type id="humidity">
|
||||
<item-type>Number</item-type>
|
||||
<label>Humidity</label>
|
||||
|
|
|
@ -42,8 +42,9 @@
|
|||
"property": "temperature",
|
||||
"friendlyName": "Temperature",
|
||||
"channel": "temperature",
|
||||
"channelType": "temperature",
|
||||
"type": "Number",
|
||||
"channelType": "temperatureC",
|
||||
"unit": "CELCIUS",
|
||||
"type": "Number:Temperature",
|
||||
"refresh": true,
|
||||
"ChannelGroup": "",
|
||||
"actions": []
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
"property": "target_temperature",
|
||||
"friendlyName": "Target Temperature",
|
||||
"channel": "target_temperature",
|
||||
"type": "Number",
|
||||
"type": "Number:Temperature",
|
||||
"channelType": "temperatureC",
|
||||
"refresh": true,
|
||||
"actions": [
|
||||
{
|
||||
|
@ -100,8 +101,8 @@
|
|||
"property": "temperature",
|
||||
"friendlyName": "Temperature",
|
||||
"channel": "temperature",
|
||||
"channelType": "temperature",
|
||||
"type": "Number",
|
||||
"channelType": "temperatureC",
|
||||
"type": "Number:Temperature",
|
||||
"refresh": true,
|
||||
"actions": []
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue