[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.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.measure.Unit;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
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.SomfyTahomaState;
|
||||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaStatus;
|
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaStatus;
|
||||||
import org.openhab.core.library.types.*;
|
import org.openhab.core.library.CoreItemFactory;
|
||||||
import org.openhab.core.thing.*;
|
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.BaseThingHandler;
|
||||||
import org.openhab.core.thing.binding.builder.ChannelBuilder;
|
import org.openhab.core.thing.binding.builder.ChannelBuilder;
|
||||||
import org.openhab.core.thing.binding.builder.ThingBuilder;
|
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.
|
* The {@link SomfyTahomaBaseThingHandler} is base thing handler for all things.
|
||||||
*
|
*
|
||||||
* @author Ondrej Pecta - Initial contribution
|
* @author Ondrej Pecta - Initial contribution
|
||||||
|
* @author Laurent Garnier - Setting of channels at init + UoM for channels
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public abstract class SomfyTahomaBaseThingHandler extends BaseThingHandler {
|
public abstract class SomfyTahomaBaseThingHandler extends BaseThingHandler {
|
||||||
@ -46,23 +65,57 @@ public abstract class SomfyTahomaBaseThingHandler extends BaseThingHandler {
|
|||||||
private HashMap<String, Integer> typeTable = new HashMap<>();
|
private HashMap<String, Integer> typeTable = new HashMap<>();
|
||||||
protected HashMap<String, String> stateNames = new HashMap<>();
|
protected HashMap<String, String> stateNames = new HashMap<>();
|
||||||
|
|
||||||
|
protected String url = "";
|
||||||
|
|
||||||
|
private Map<String, Unit<?>> units = new HashMap<>();
|
||||||
|
|
||||||
public SomfyTahomaBaseThingHandler(Thing thing) {
|
public SomfyTahomaBaseThingHandler(Thing thing) {
|
||||||
super(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() {
|
public HashMap<String, String> getStateNames() {
|
||||||
return stateNames;
|
return stateNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String url = "";
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
url = getURL();
|
Bridge bridge = getBridge();
|
||||||
if (getThing().getProperties().containsKey(RSSI_LEVEL_STATE)) {
|
initializeThing(bridge != null ? bridge.getStatus() : null);
|
||||||
createRSSIChannel();
|
}
|
||||||
|
|
||||||
|
@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() {
|
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) {
|
protected @Nullable State parseTahomaState(@Nullable SomfyTahomaState state) {
|
||||||
return parseTahomaState(null, 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) {
|
if (state == null) {
|
||||||
return UnDefType.NULL;
|
return UnDefType.NULL;
|
||||||
}
|
}
|
||||||
@ -205,14 +296,32 @@ public abstract class SomfyTahomaBaseThingHandler extends BaseThingHandler {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case TYPE_PERCENT:
|
case TYPE_PERCENT:
|
||||||
Double valPct = Double.parseDouble(state.getValue().toString());
|
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));
|
return new PercentType(normalizePercent(valPct));
|
||||||
case TYPE_DECIMAL:
|
case TYPE_DECIMAL:
|
||||||
Double valDec = Double.parseDouble(state.getValue().toString());
|
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);
|
return new DecimalType(valDec);
|
||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
case TYPE_BOOLEAN:
|
case TYPE_BOOLEAN:
|
||||||
String value = state.getValue().toString();
|
String value = state.getValue().toString();
|
||||||
if ("String".equals(acceptedState)) {
|
if ("String".equals(acceptedItemType)) {
|
||||||
return new StringType(value);
|
return new StringType(value);
|
||||||
} else {
|
} else {
|
||||||
return parseStringState(value);
|
return parseStringState(value);
|
||||||
@ -247,9 +356,11 @@ public abstract class SomfyTahomaBaseThingHandler extends BaseThingHandler {
|
|||||||
switch (value.toLowerCase()) {
|
switch (value.toLowerCase()) {
|
||||||
case "on":
|
case "on":
|
||||||
case "true":
|
case "true":
|
||||||
|
case "active":
|
||||||
return OnOffType.ON;
|
return OnOffType.ON;
|
||||||
case "off":
|
case "off":
|
||||||
case "false":
|
case "false":
|
||||||
|
case "inactive":
|
||||||
return OnOffType.OFF;
|
return OnOffType.OFF;
|
||||||
case "notdetected":
|
case "notdetected":
|
||||||
case "nopersoninside":
|
case "nopersoninside":
|
||||||
|
|||||||
@ -17,7 +17,12 @@ import static org.openhab.binding.somfytahoma.internal.SomfyTahomaBindingConstan
|
|||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
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.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
@ -35,9 +40,25 @@ import org.eclipse.jetty.http.HttpHeader;
|
|||||||
import org.eclipse.jetty.http.HttpMethod;
|
import org.eclipse.jetty.http.HttpMethod;
|
||||||
import org.openhab.binding.somfytahoma.internal.config.SomfyTahomaConfig;
|
import org.openhab.binding.somfytahoma.internal.config.SomfyTahomaConfig;
|
||||||
import org.openhab.binding.somfytahoma.internal.discovery.SomfyTahomaItemDiscoveryService;
|
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.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.BaseBridgeHandler;
|
||||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||||
import org.openhab.core.types.Command;
|
import org.openhab.core.types.Command;
|
||||||
@ -106,6 +127,9 @@ public class SomfyTahomaBridgeHandler extends BaseBridgeHandler {
|
|||||||
*/
|
*/
|
||||||
private String eventsId = "";
|
private String eventsId = "";
|
||||||
|
|
||||||
|
private ExpiringCache<List<SomfyTahomaDevice>> cachedDevices = new ExpiringCache<>(Duration.ofSeconds(30),
|
||||||
|
this::getDevices);
|
||||||
|
|
||||||
// Gson & parser
|
// Gson & parser
|
||||||
private final Gson gson = new Gson();
|
private final Gson gson = new Gson();
|
||||||
|
|
||||||
@ -331,6 +355,16 @@ public class SomfyTahomaBridgeHandler extends BaseBridgeHandler {
|
|||||||
return response != null ? List.of(response) : List.of();
|
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() {
|
private void getTahomaUpdates() {
|
||||||
logger.debug("Getting Tahoma Updates...");
|
logger.debug("Getting Tahoma Updates...");
|
||||||
if (ThingStatus.OFFLINE == thing.getStatus() && !reLogin()) {
|
if (ThingStatus.OFFLINE == thing.getStatus() && !reLogin()) {
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
|||||||
* to TahomaLink account.
|
* to TahomaLink account.
|
||||||
*
|
*
|
||||||
* @author Ondrej Pecta - Initial contribution
|
* @author Ondrej Pecta - Initial contribution
|
||||||
|
* @author Laurent Garnier - Add attributes data
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class SomfyTahomaDevice {
|
public class SomfyTahomaDevice {
|
||||||
@ -33,6 +34,7 @@ public class SomfyTahomaDevice {
|
|||||||
private String oid = "";
|
private String oid = "";
|
||||||
private SomfyTahomaDeviceDefinition definition = new SomfyTahomaDeviceDefinition();
|
private SomfyTahomaDeviceDefinition definition = new SomfyTahomaDeviceDefinition();
|
||||||
private List<SomfyTahomaState> states = new ArrayList<>();
|
private List<SomfyTahomaState> states = new ArrayList<>();
|
||||||
|
private List<SomfyTahomaState> attributes = new ArrayList<>();
|
||||||
|
|
||||||
public String getLabel() {
|
public String getLabel() {
|
||||||
return label;
|
return label;
|
||||||
@ -61,4 +63,8 @@ public class SomfyTahomaDevice {
|
|||||||
public List<SomfyTahomaState> getStates() {
|
public List<SomfyTahomaState> getStates() {
|
||||||
return states;
|
return states;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<SomfyTahomaState> getAttributes() {
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user