[somfytahoma] Setting of channels at init + UoM for channels (#10300)
Fix #10291 Fix #10285 Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
parent
286bced20e
commit
849442cd47
@ -18,12 +18,30 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.measure.Unit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaDevice;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaState;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaStatus;
|
||||
import org.openhab.core.library.types.*;
|
||||
import org.openhab.core.thing.*;
|
||||
import org.openhab.core.library.CoreItemFactory;
|
||||
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.PercentType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.library.unit.ImperialUnits;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingStatusInfo;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.binding.builder.ChannelBuilder;
|
||||
import org.openhab.core.thing.binding.builder.ThingBuilder;
|
||||
@ -38,6 +56,7 @@ import org.slf4j.LoggerFactory;
|
||||
* The {@link SomfyTahomaBaseThingHandler} is base thing handler for all things.
|
||||
*
|
||||
* @author Ondrej Pecta - Initial contribution
|
||||
* @author Laurent Garnier - Setting of channels at init + UoM for channels
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public abstract class SomfyTahomaBaseThingHandler extends BaseThingHandler {
|
||||
@ -46,23 +65,57 @@ public abstract class SomfyTahomaBaseThingHandler extends BaseThingHandler {
|
||||
private HashMap<String, Integer> typeTable = new HashMap<>();
|
||||
protected HashMap<String, String> stateNames = new HashMap<>();
|
||||
|
||||
protected String url = "";
|
||||
|
||||
private Map<String, Unit<?>> units = new HashMap<>();
|
||||
|
||||
public SomfyTahomaBaseThingHandler(Thing thing) {
|
||||
super(thing);
|
||||
// Define default units
|
||||
units.put("Number:Temperature", SIUnits.CELSIUS);
|
||||
units.put("Number:Energy", Units.WATT_HOUR);
|
||||
units.put("Number:Illuminance", Units.LUX);
|
||||
units.put("Number:Dimensionless", Units.PERCENT);
|
||||
}
|
||||
|
||||
public HashMap<String, String> getStateNames() {
|
||||
return stateNames;
|
||||
}
|
||||
|
||||
protected String url = "";
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
url = getURL();
|
||||
if (getThing().getProperties().containsKey(RSSI_LEVEL_STATE)) {
|
||||
createRSSIChannel();
|
||||
Bridge bridge = getBridge();
|
||||
initializeThing(bridge != null ? bridge.getStatus() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
|
||||
initializeThing(bridgeStatusInfo.getStatus());
|
||||
}
|
||||
|
||||
public void initializeThing(@Nullable ThingStatus bridgeStatus) {
|
||||
SomfyTahomaBridgeHandler bridgeHandler = getBridgeHandler();
|
||||
if (bridgeHandler != null && bridgeStatus != null) {
|
||||
url = getURL();
|
||||
if (getThing().getProperties().containsKey(RSSI_LEVEL_STATE)) {
|
||||
createRSSIChannel();
|
||||
}
|
||||
if (bridgeStatus == ThingStatus.ONLINE) {
|
||||
SomfyTahomaDevice device = bridgeHandler.getCachedDevice(url);
|
||||
if (device != null) {
|
||||
updateUnits(device.getAttributes());
|
||||
List<SomfyTahomaState> states = device.getStates();
|
||||
updateThingStatus(states);
|
||||
updateThingChannels(states);
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, UNAVAILABLE);
|
||||
}
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
||||
}
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED);
|
||||
}
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
|
||||
private void createRSSIChannel() {
|
||||
@ -178,11 +231,49 @@ public abstract class SomfyTahomaBaseThingHandler extends BaseThingHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUnits(List<SomfyTahomaState> attributes) {
|
||||
for (SomfyTahomaState attr : attributes) {
|
||||
if ("core:MeasuredValueType".equals(attr.getName()) && attr.getType() == TYPE_STRING) {
|
||||
switch ((String) attr.getValue()) {
|
||||
case "core:TemperatureInCelcius":
|
||||
case "core:TemperatureInCelsius":
|
||||
units.put("Number:Temperature", SIUnits.CELSIUS);
|
||||
break;
|
||||
case "core:TemperatureInKelvin":
|
||||
units.put("Number:Temperature", Units.KELVIN);
|
||||
break;
|
||||
case "core:TemperatureInFahrenheit":
|
||||
units.put("Number:Temperature", ImperialUnits.FAHRENHEIT);
|
||||
break;
|
||||
case "core:RelativeValueInPercentage":
|
||||
units.put("Number:Dimensionless", Units.PERCENT);
|
||||
break;
|
||||
case "core:LuminanceInLux":
|
||||
units.put("Number:Illuminance", Units.LUX);
|
||||
break;
|
||||
case "core:ElectricalEnergyInWh":
|
||||
units.put("Number:Energy", Units.WATT_HOUR);
|
||||
break;
|
||||
case "core:ElectricalEnergyInKWh":
|
||||
units.put("Number:Energy", Units.KILOWATT_HOUR);
|
||||
break;
|
||||
case "core:ElectricalEnergyInMWh":
|
||||
units.put("Number:Energy", Units.MEGAWATT_HOUR);
|
||||
break;
|
||||
default:
|
||||
logger.warn("Unhandled value \"{}\" for attribute \"core:MeasuredValueType\"", attr.getValue());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected @Nullable State parseTahomaState(@Nullable SomfyTahomaState state) {
|
||||
return parseTahomaState(null, state);
|
||||
}
|
||||
|
||||
protected @Nullable State parseTahomaState(@Nullable String acceptedState, @Nullable SomfyTahomaState state) {
|
||||
protected @Nullable State parseTahomaState(@Nullable String acceptedItemType, @Nullable SomfyTahomaState state) {
|
||||
if (state == null) {
|
||||
return UnDefType.NULL;
|
||||
}
|
||||
@ -205,14 +296,32 @@ public abstract class SomfyTahomaBaseThingHandler extends BaseThingHandler {
|
||||
switch (type) {
|
||||
case TYPE_PERCENT:
|
||||
Double valPct = Double.parseDouble(state.getValue().toString());
|
||||
if (acceptedItemType != null && acceptedItemType.startsWith(CoreItemFactory.NUMBER + ":")) {
|
||||
Unit<?> unit = units.get(acceptedItemType);
|
||||
if (unit != null) {
|
||||
return new QuantityType<>(normalizePercent(valPct), unit);
|
||||
} else {
|
||||
logger.warn("Do not return a quantity for {} because the unit is unknown",
|
||||
acceptedItemType);
|
||||
}
|
||||
}
|
||||
return new PercentType(normalizePercent(valPct));
|
||||
case TYPE_DECIMAL:
|
||||
Double valDec = Double.parseDouble(state.getValue().toString());
|
||||
if (acceptedItemType != null && acceptedItemType.startsWith(CoreItemFactory.NUMBER + ":")) {
|
||||
Unit<?> unit = units.get(acceptedItemType);
|
||||
if (unit != null) {
|
||||
return new QuantityType<>(valDec, unit);
|
||||
} else {
|
||||
logger.warn("Do not return a quantity for {} because the unit is unknown",
|
||||
acceptedItemType);
|
||||
}
|
||||
}
|
||||
return new DecimalType(valDec);
|
||||
case TYPE_STRING:
|
||||
case TYPE_BOOLEAN:
|
||||
String value = state.getValue().toString();
|
||||
if ("String".equals(acceptedState)) {
|
||||
if ("String".equals(acceptedItemType)) {
|
||||
return new StringType(value);
|
||||
} else {
|
||||
return parseStringState(value);
|
||||
@ -247,9 +356,11 @@ public abstract class SomfyTahomaBaseThingHandler extends BaseThingHandler {
|
||||
switch (value.toLowerCase()) {
|
||||
case "on":
|
||||
case "true":
|
||||
case "active":
|
||||
return OnOffType.ON;
|
||||
case "off":
|
||||
case "false":
|
||||
case "inactive":
|
||||
return OnOffType.OFF;
|
||||
case "notdetected":
|
||||
case "nopersoninside":
|
||||
|
||||
@ -17,7 +17,12 @@ import static org.openhab.binding.somfytahoma.internal.SomfyTahomaBindingConstan
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
@ -35,9 +40,25 @@ import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.openhab.binding.somfytahoma.internal.config.SomfyTahomaConfig;
|
||||
import org.openhab.binding.somfytahoma.internal.discovery.SomfyTahomaItemDiscoveryService;
|
||||
import org.openhab.binding.somfytahoma.internal.model.*;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaAction;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaActionGroup;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaApplyResponse;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaDevice;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaEvent;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaLoginResponse;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaRegisterEventsResponse;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaSetup;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaState;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaStatus;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaStatusResponse;
|
||||
import org.openhab.core.cache.ExpiringCache;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.thing.*;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingStatusInfo;
|
||||
import org.openhab.core.thing.binding.BaseBridgeHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||
import org.openhab.core.types.Command;
|
||||
@ -106,6 +127,9 @@ public class SomfyTahomaBridgeHandler extends BaseBridgeHandler {
|
||||
*/
|
||||
private String eventsId = "";
|
||||
|
||||
private ExpiringCache<List<SomfyTahomaDevice>> cachedDevices = new ExpiringCache<>(Duration.ofSeconds(30),
|
||||
this::getDevices);
|
||||
|
||||
// Gson & parser
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
@ -331,6 +355,16 @@ public class SomfyTahomaBridgeHandler extends BaseBridgeHandler {
|
||||
return response != null ? List.of(response) : List.of();
|
||||
}
|
||||
|
||||
public synchronized @Nullable SomfyTahomaDevice getCachedDevice(String url) {
|
||||
List<SomfyTahomaDevice> devices = cachedDevices.getValue();
|
||||
for (SomfyTahomaDevice device : devices) {
|
||||
if (url.equals(device.getDeviceURL())) {
|
||||
return device;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void getTahomaUpdates() {
|
||||
logger.debug("Getting Tahoma Updates...");
|
||||
if (ThingStatus.OFFLINE == thing.getStatus() && !reLogin()) {
|
||||
|
||||
@ -22,6 +22,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
* to TahomaLink account.
|
||||
*
|
||||
* @author Ondrej Pecta - Initial contribution
|
||||
* @author Laurent Garnier - Add attributes data
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SomfyTahomaDevice {
|
||||
@ -33,6 +34,7 @@ public class SomfyTahomaDevice {
|
||||
private String oid = "";
|
||||
private SomfyTahomaDeviceDefinition definition = new SomfyTahomaDeviceDefinition();
|
||||
private List<SomfyTahomaState> states = new ArrayList<>();
|
||||
private List<SomfyTahomaState> attributes = new ArrayList<>();
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
@ -61,4 +63,8 @@ public class SomfyTahomaDevice {
|
||||
public List<SomfyTahomaState> getStates() {
|
||||
return states;
|
||||
}
|
||||
|
||||
public List<SomfyTahomaState> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user