mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 23:22:02 +01:00
[somfytahoma] New method to send a command to several devices in the same place (#10347)
* [somfytahoma] New method to send a command to several devices in the same place Also include the place into the inbox label (discovery) Signed-off-by: Laurent Garnier <lg.hc@free.fr> * Review comment: remove unnecessary method Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
parent
bd56fd8e5d
commit
62a0e7ac02
@ -24,7 +24,13 @@ import java.util.concurrent.TimeUnit;
|
|||||||
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.handler.SomfyTahomaBridgeHandler;
|
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaBridgeHandler;
|
||||||
import org.openhab.binding.somfytahoma.internal.model.*;
|
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaActionGroup;
|
||||||
|
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaDevice;
|
||||||
|
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaGateway;
|
||||||
|
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaRootPlace;
|
||||||
|
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaSetup;
|
||||||
|
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaState;
|
||||||
|
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaSubPlace;
|
||||||
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||||
import org.openhab.core.config.discovery.DiscoveryService;
|
import org.openhab.core.config.discovery.DiscoveryService;
|
||||||
@ -41,20 +47,21 @@ import org.slf4j.LoggerFactory;
|
|||||||
* action groups associated with your TahomaLink cloud account.
|
* action groups associated with your TahomaLink cloud account.
|
||||||
*
|
*
|
||||||
* @author Ondrej Pecta - Initial contribution
|
* @author Ondrej Pecta - Initial contribution
|
||||||
|
* @author Laurent Garnier - Include the place into the inbox label (when defined for the device)
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class SomfyTahomaItemDiscoveryService extends AbstractDiscoveryService
|
public class SomfyTahomaItemDiscoveryService extends AbstractDiscoveryService
|
||||||
implements DiscoveryService, ThingHandlerService {
|
implements DiscoveryService, ThingHandlerService {
|
||||||
|
|
||||||
|
private static final int DISCOVERY_TIMEOUT_SEC = 10;
|
||||||
|
private static final int DISCOVERY_REFRESH_SEC = 3600;
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(SomfyTahomaItemDiscoveryService.class);
|
private final Logger logger = LoggerFactory.getLogger(SomfyTahomaItemDiscoveryService.class);
|
||||||
|
|
||||||
private @Nullable SomfyTahomaBridgeHandler bridgeHandler;
|
private @Nullable SomfyTahomaBridgeHandler bridgeHandler;
|
||||||
|
|
||||||
private @Nullable ScheduledFuture<?> discoveryJob;
|
private @Nullable ScheduledFuture<?> discoveryJob;
|
||||||
|
|
||||||
private static final int DISCOVERY_TIMEOUT_SEC = 10;
|
|
||||||
private static final int DISCOVERY_REFRESH_SEC = 3600;
|
|
||||||
|
|
||||||
public SomfyTahomaItemDiscoveryService() {
|
public SomfyTahomaItemDiscoveryService() {
|
||||||
super(DISCOVERY_TIMEOUT_SEC);
|
super(DISCOVERY_TIMEOUT_SEC);
|
||||||
logger.debug("Creating discovery service");
|
logger.debug("Creating discovery service");
|
||||||
@ -124,7 +131,7 @@ public class SomfyTahomaItemDiscoveryService extends AbstractDiscoveryService
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (SomfyTahomaDevice device : setup.getDevices()) {
|
for (SomfyTahomaDevice device : setup.getDevices()) {
|
||||||
discoverDevice(device);
|
discoverDevice(device, setup);
|
||||||
}
|
}
|
||||||
for (SomfyTahomaGateway gw : setup.getGateways()) {
|
for (SomfyTahomaGateway gw : setup.getGateways()) {
|
||||||
gatewayDiscovered(gw);
|
gatewayDiscovered(gw);
|
||||||
@ -144,105 +151,106 @@ public class SomfyTahomaItemDiscoveryService extends AbstractDiscoveryService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void discoverDevice(SomfyTahomaDevice device) {
|
private void discoverDevice(SomfyTahomaDevice device, SomfyTahomaSetup setup) {
|
||||||
logger.debug("url: {}", device.getDeviceURL());
|
logger.debug("url: {}", device.getDeviceURL());
|
||||||
|
String place = getPlaceLabel(setup, device.getPlaceOID());
|
||||||
switch (device.getUiClass()) {
|
switch (device.getUiClass()) {
|
||||||
case CLASS_AWNING:
|
case CLASS_AWNING:
|
||||||
// widget: PositionableHorizontalAwning
|
// widget: PositionableHorizontalAwning
|
||||||
deviceDiscovered(device, THING_TYPE_AWNING);
|
deviceDiscovered(device, THING_TYPE_AWNING, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_CONTACT_SENSOR:
|
case CLASS_CONTACT_SENSOR:
|
||||||
// widget: ContactSensor
|
// widget: ContactSensor
|
||||||
deviceDiscovered(device, THING_TYPE_CONTACTSENSOR);
|
deviceDiscovered(device, THING_TYPE_CONTACTSENSOR, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_CURTAIN:
|
case CLASS_CURTAIN:
|
||||||
deviceDiscovered(device, THING_TYPE_CURTAIN);
|
deviceDiscovered(device, THING_TYPE_CURTAIN, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_EXTERIOR_SCREEN:
|
case CLASS_EXTERIOR_SCREEN:
|
||||||
// widget: PositionableScreen
|
// widget: PositionableScreen
|
||||||
deviceDiscovered(device, THING_TYPE_EXTERIORSCREEN);
|
deviceDiscovered(device, THING_TYPE_EXTERIORSCREEN, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_EXTERIOR_VENETIAN_BLIND:
|
case CLASS_EXTERIOR_VENETIAN_BLIND:
|
||||||
// widget: PositionableExteriorVenetianBlind
|
// widget: PositionableExteriorVenetianBlind
|
||||||
deviceDiscovered(device, THING_TYPE_EXTERIORVENETIANBLIND);
|
deviceDiscovered(device, THING_TYPE_EXTERIORVENETIANBLIND, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_GARAGE_DOOR:
|
case CLASS_GARAGE_DOOR:
|
||||||
deviceDiscovered(device, THING_TYPE_GARAGEDOOR);
|
deviceDiscovered(device, THING_TYPE_GARAGEDOOR, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_LIGHT:
|
case CLASS_LIGHT:
|
||||||
if ("DimmerLight".equals(device.getWidget())) {
|
if ("DimmerLight".equals(device.getWidget())) {
|
||||||
// widget: DimmerLight
|
// widget: DimmerLight
|
||||||
deviceDiscovered(device, THING_TYPE_DIMMER_LIGHT);
|
deviceDiscovered(device, THING_TYPE_DIMMER_LIGHT, place);
|
||||||
} else {
|
} else {
|
||||||
// widget: TimedOnOffLight
|
// widget: TimedOnOffLight
|
||||||
// widget: StatefulOnOffLight
|
// widget: StatefulOnOffLight
|
||||||
deviceDiscovered(device, THING_TYPE_LIGHT);
|
deviceDiscovered(device, THING_TYPE_LIGHT, place);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CLASS_LIGHT_SENSOR:
|
case CLASS_LIGHT_SENSOR:
|
||||||
deviceDiscovered(device, THING_TYPE_LIGHTSENSOR);
|
deviceDiscovered(device, THING_TYPE_LIGHTSENSOR, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_OCCUPANCY_SENSOR:
|
case CLASS_OCCUPANCY_SENSOR:
|
||||||
// widget: OccupancySensor
|
// widget: OccupancySensor
|
||||||
deviceDiscovered(device, THING_TYPE_OCCUPANCYSENSOR);
|
deviceDiscovered(device, THING_TYPE_OCCUPANCYSENSOR, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_ON_OFF:
|
case CLASS_ON_OFF:
|
||||||
// widget: StatefulOnOff
|
// widget: StatefulOnOff
|
||||||
deviceDiscovered(device, THING_TYPE_ONOFF);
|
deviceDiscovered(device, THING_TYPE_ONOFF, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_ROLLER_SHUTTER:
|
case CLASS_ROLLER_SHUTTER:
|
||||||
if (isSilentRollerShutter(device)) {
|
if (isSilentRollerShutter(device)) {
|
||||||
// widget: PositionableRollerShutterWithLowSpeedManagement
|
// widget: PositionableRollerShutterWithLowSpeedManagement
|
||||||
deviceDiscovered(device, THING_TYPE_ROLLERSHUTTER_SILENT);
|
deviceDiscovered(device, THING_TYPE_ROLLERSHUTTER_SILENT, place);
|
||||||
} else if (isUnoRollerShutter(device)) {
|
} else if (isUnoRollerShutter(device)) {
|
||||||
// widget: PositionableRollerShutterUno
|
// widget: PositionableRollerShutterUno
|
||||||
deviceDiscovered(device, THING_TYPE_ROLLERSHUTTER_UNO);
|
deviceDiscovered(device, THING_TYPE_ROLLERSHUTTER_UNO, place);
|
||||||
} else {
|
} else {
|
||||||
// widget: PositionableRollerShutter
|
// widget: PositionableRollerShutter
|
||||||
// widget: PositionableTiltedRollerShutter
|
// widget: PositionableTiltedRollerShutter
|
||||||
deviceDiscovered(device, THING_TYPE_ROLLERSHUTTER);
|
deviceDiscovered(device, THING_TYPE_ROLLERSHUTTER, place);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CLASS_SCREEN:
|
case CLASS_SCREEN:
|
||||||
// widget: PositionableTiltedScreen
|
// widget: PositionableTiltedScreen
|
||||||
deviceDiscovered(device, THING_TYPE_SCREEN);
|
deviceDiscovered(device, THING_TYPE_SCREEN, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_SMOKE_SENSOR:
|
case CLASS_SMOKE_SENSOR:
|
||||||
// widget: SmokeSensor
|
// widget: SmokeSensor
|
||||||
deviceDiscovered(device, THING_TYPE_SMOKESENSOR);
|
deviceDiscovered(device, THING_TYPE_SMOKESENSOR, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_VENETIAN_BLIND:
|
case CLASS_VENETIAN_BLIND:
|
||||||
deviceDiscovered(device, THING_TYPE_VENETIANBLIND);
|
deviceDiscovered(device, THING_TYPE_VENETIANBLIND, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_WINDOW:
|
case CLASS_WINDOW:
|
||||||
// widget: PositionableTiltedWindow
|
// widget: PositionableTiltedWindow
|
||||||
deviceDiscovered(device, THING_TYPE_WINDOW);
|
deviceDiscovered(device, THING_TYPE_WINDOW, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_ALARM:
|
case CLASS_ALARM:
|
||||||
if (device.getDeviceURL().startsWith("internal:")) {
|
if (device.getDeviceURL().startsWith("internal:")) {
|
||||||
// widget: TSKAlarmController
|
// widget: TSKAlarmController
|
||||||
deviceDiscovered(device, THING_TYPE_INTERNAL_ALARM);
|
deviceDiscovered(device, THING_TYPE_INTERNAL_ALARM, place);
|
||||||
} else if ("MyFoxAlarmController".equals(device.getWidget())) {
|
} else if ("MyFoxAlarmController".equals(device.getWidget())) {
|
||||||
// widget: MyFoxAlarmController
|
// widget: MyFoxAlarmController
|
||||||
deviceDiscovered(device, THING_TYPE_MYFOX_ALARM);
|
deviceDiscovered(device, THING_TYPE_MYFOX_ALARM, place);
|
||||||
} else {
|
} else {
|
||||||
deviceDiscovered(device, THING_TYPE_EXTERNAL_ALARM);
|
deviceDiscovered(device, THING_TYPE_EXTERNAL_ALARM, place);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CLASS_POD:
|
case CLASS_POD:
|
||||||
if (hasState(device, CYCLIC_BUTTON_STATE)) {
|
if (hasState(device, CYCLIC_BUTTON_STATE)) {
|
||||||
deviceDiscovered(device, THING_TYPE_POD);
|
deviceDiscovered(device, THING_TYPE_POD, place);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CLASS_HEATING_SYSTEM:
|
case CLASS_HEATING_SYSTEM:
|
||||||
if ("SomfyThermostat".equals(device.getWidget())) {
|
if ("SomfyThermostat".equals(device.getWidget())) {
|
||||||
deviceDiscovered(device, THING_TYPE_THERMOSTAT);
|
deviceDiscovered(device, THING_TYPE_THERMOSTAT, place);
|
||||||
} else if ("ValveHeatingTemperatureInterface".equals(device.getWidget())) {
|
} else if ("ValveHeatingTemperatureInterface".equals(device.getWidget())) {
|
||||||
deviceDiscovered(device, THING_TYPE_VALVE_HEATING_SYSTEM);
|
deviceDiscovered(device, THING_TYPE_VALVE_HEATING_SYSTEM, place);
|
||||||
} else if (isOnOffHeatingSystem(device)) {
|
} else if (isOnOffHeatingSystem(device)) {
|
||||||
deviceDiscovered(device, THING_TYPE_ONOFF_HEATING_SYSTEM);
|
deviceDiscovered(device, THING_TYPE_ONOFF_HEATING_SYSTEM, place);
|
||||||
} else if (isZwaveHeatingSystem(device)) {
|
} else if (isZwaveHeatingSystem(device)) {
|
||||||
deviceDiscovered(device, THING_TYPE_ZWAVE_HEATING_SYSTEM);
|
deviceDiscovered(device, THING_TYPE_ZWAVE_HEATING_SYSTEM, place);
|
||||||
} else {
|
} else {
|
||||||
logUnsupportedDevice(device);
|
logUnsupportedDevice(device);
|
||||||
}
|
}
|
||||||
@ -250,57 +258,57 @@ public class SomfyTahomaItemDiscoveryService extends AbstractDiscoveryService
|
|||||||
case CLASS_EXTERIOR_HEATING_SYSTEM:
|
case CLASS_EXTERIOR_HEATING_SYSTEM:
|
||||||
if ("DimmerExteriorHeating".equals(device.getWidget())) {
|
if ("DimmerExteriorHeating".equals(device.getWidget())) {
|
||||||
// widget: DimmerExteriorHeating
|
// widget: DimmerExteriorHeating
|
||||||
deviceDiscovered(device, THING_TYPE_EXTERIOR_HEATING_SYSTEM);
|
deviceDiscovered(device, THING_TYPE_EXTERIOR_HEATING_SYSTEM, place);
|
||||||
} else {
|
} else {
|
||||||
logUnsupportedDevice(device);
|
logUnsupportedDevice(device);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CLASS_HUMIDITY_SENSOR:
|
case CLASS_HUMIDITY_SENSOR:
|
||||||
if (hasState(device, WATER_DETECTION_STATE)) {
|
if (hasState(device, WATER_DETECTION_STATE)) {
|
||||||
deviceDiscovered(device, THING_TYPE_WATERSENSOR);
|
deviceDiscovered(device, THING_TYPE_WATERSENSOR, place);
|
||||||
} else {
|
} else {
|
||||||
// widget: RelativeHumiditySensor
|
// widget: RelativeHumiditySensor
|
||||||
deviceDiscovered(device, THING_TYPE_HUMIDITYSENSOR);
|
deviceDiscovered(device, THING_TYPE_HUMIDITYSENSOR, place);
|
||||||
}
|
}
|
||||||
case CLASS_DOOR_LOCK:
|
case CLASS_DOOR_LOCK:
|
||||||
// widget: UnlockDoorLockWithUnknownPosition
|
// widget: UnlockDoorLockWithUnknownPosition
|
||||||
deviceDiscovered(device, THING_TYPE_DOOR_LOCK);
|
deviceDiscovered(device, THING_TYPE_DOOR_LOCK, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_PERGOLA:
|
case CLASS_PERGOLA:
|
||||||
deviceDiscovered(device, THING_TYPE_PERGOLA);
|
deviceDiscovered(device, THING_TYPE_PERGOLA, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_WINDOW_HANDLE:
|
case CLASS_WINDOW_HANDLE:
|
||||||
// widget: ThreeWayWindowHandle
|
// widget: ThreeWayWindowHandle
|
||||||
deviceDiscovered(device, THING_TYPE_WINDOW_HANDLE);
|
deviceDiscovered(device, THING_TYPE_WINDOW_HANDLE, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_TEMPERATURE_SENSOR:
|
case CLASS_TEMPERATURE_SENSOR:
|
||||||
// widget: TemperatureSensor
|
// widget: TemperatureSensor
|
||||||
deviceDiscovered(device, THING_TYPE_TEMPERATURESENSOR);
|
deviceDiscovered(device, THING_TYPE_TEMPERATURESENSOR, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_GATE:
|
case CLASS_GATE:
|
||||||
deviceDiscovered(device, THING_TYPE_GATE);
|
deviceDiscovered(device, THING_TYPE_GATE, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_ELECTRICITY_SENSOR:
|
case CLASS_ELECTRICITY_SENSOR:
|
||||||
if (hasEnergyConsumption(device)) {
|
if (hasEnergyConsumption(device)) {
|
||||||
deviceDiscovered(device, THING_TYPE_ELECTRICITYSENSOR);
|
deviceDiscovered(device, THING_TYPE_ELECTRICITYSENSOR, place);
|
||||||
} else {
|
} else {
|
||||||
logUnsupportedDevice(device);
|
logUnsupportedDevice(device);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CLASS_DOCK:
|
case CLASS_DOCK:
|
||||||
// widget: Dock
|
// widget: Dock
|
||||||
deviceDiscovered(device, THING_TYPE_DOCK);
|
deviceDiscovered(device, THING_TYPE_DOCK, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_SIREN:
|
case CLASS_SIREN:
|
||||||
deviceDiscovered(device, THING_TYPE_SIREN);
|
deviceDiscovered(device, THING_TYPE_SIREN, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_ADJUSTABLE_SLATS_ROLLER_SHUTTER:
|
case CLASS_ADJUSTABLE_SLATS_ROLLER_SHUTTER:
|
||||||
deviceDiscovered(device, THING_TYPE_ADJUSTABLE_SLATS_ROLLERSHUTTER);
|
deviceDiscovered(device, THING_TYPE_ADJUSTABLE_SLATS_ROLLERSHUTTER, place);
|
||||||
break;
|
break;
|
||||||
case CLASS_CAMERA:
|
case CLASS_CAMERA:
|
||||||
if (hasMyfoxShutter(device)) {
|
if (hasMyfoxShutter(device)) {
|
||||||
// widget: MyFoxSecurityCamera
|
// widget: MyFoxSecurityCamera
|
||||||
deviceDiscovered(device, THING_TYPE_MYFOX_CAMERA);
|
deviceDiscovered(device, THING_TYPE_MYFOX_CAMERA, place);
|
||||||
} else {
|
} else {
|
||||||
logUnsupportedDevice(device);
|
logUnsupportedDevice(device);
|
||||||
}
|
}
|
||||||
@ -315,6 +323,18 @@ public class SomfyTahomaItemDiscoveryService extends AbstractDiscoveryService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private @Nullable String getPlaceLabel(SomfyTahomaSetup setup, String oid) {
|
||||||
|
SomfyTahomaRootPlace root = setup.getRootPlace();
|
||||||
|
if (!oid.isEmpty() && root != null) {
|
||||||
|
for (SomfyTahomaSubPlace place : root.getSubPlaces()) {
|
||||||
|
if (oid.equals(place.getOid())) {
|
||||||
|
return place.getLabel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isStateLess(SomfyTahomaDevice device) {
|
private boolean isStateLess(SomfyTahomaDevice device) {
|
||||||
return device.getStates().isEmpty() || (device.getStates().size() == 1 && hasState(device, STATUS_STATE));
|
return device.getStates().isEmpty() || (device.getStates().size() == 1 && hasState(device, STATUS_STATE));
|
||||||
}
|
}
|
||||||
@ -366,8 +386,12 @@ public class SomfyTahomaItemDiscoveryService extends AbstractDiscoveryService
|
|||||||
return device.getDefinition().getCommands().stream().anyMatch(cmd -> command.equals(cmd.getCommandName()));
|
return device.getDefinition().getCommands().stream().anyMatch(cmd -> command.equals(cmd.getCommandName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deviceDiscovered(SomfyTahomaDevice device, ThingTypeUID thingTypeUID) {
|
private void deviceDiscovered(SomfyTahomaDevice device, ThingTypeUID thingTypeUID, @Nullable String place) {
|
||||||
deviceDiscovered(device.getLabel(), device.getDeviceURL(), device.getOid(), thingTypeUID,
|
String label = device.getLabel();
|
||||||
|
if (place != null && !place.isBlank()) {
|
||||||
|
label += " (" + place + ")";
|
||||||
|
}
|
||||||
|
deviceDiscovered(label, device.getDeviceURL(), device.getOid(), thingTypeUID,
|
||||||
hasState(device, RSSI_LEVEL_STATE));
|
hasState(device, RSSI_LEVEL_STATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,6 +179,17 @@ public abstract class SomfyTahomaBaseThingHandler extends BaseThingHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void sendCommandToSameDevicesInPlace(String cmd) {
|
||||||
|
sendCommandToSameDevicesInPlace(cmd, "[]");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void sendCommandToSameDevicesInPlace(String cmd, String param) {
|
||||||
|
SomfyTahomaBridgeHandler handler = getBridgeHandler();
|
||||||
|
if (handler != null) {
|
||||||
|
handler.sendCommandToSameDevicesInPlace(url, cmd, param, EXEC_URL + "apply");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void refresh(String channel) {
|
protected void refresh(String channel) {
|
||||||
SomfyTahomaBridgeHandler handler = getBridgeHandler();
|
SomfyTahomaBridgeHandler handler = getBridgeHandler();
|
||||||
String stateName = stateNames.get(channel);
|
String stateName = stateNames.get(channel);
|
||||||
|
@ -126,6 +126,8 @@ public class SomfyTahomaBridgeHandler extends BaseBridgeHandler {
|
|||||||
*/
|
*/
|
||||||
private String eventsId = "";
|
private String eventsId = "";
|
||||||
|
|
||||||
|
private Map<String, SomfyTahomaDevice> devicePlaces = new HashMap<>();
|
||||||
|
|
||||||
private ExpiringCache<List<SomfyTahomaDevice>> cachedDevices = new ExpiringCache<>(Duration.ofSeconds(30),
|
private ExpiringCache<List<SomfyTahomaDevice>> cachedDevices = new ExpiringCache<>(Duration.ofSeconds(30),
|
||||||
this::getDevices);
|
this::getDevices);
|
||||||
|
|
||||||
@ -345,13 +347,19 @@ public class SomfyTahomaBridgeHandler extends BaseBridgeHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable SomfyTahomaSetup getSetup() {
|
public @Nullable SomfyTahomaSetup getSetup() {
|
||||||
return invokeCallToURL(TAHOMA_API_URL + "setup", "", HttpMethod.GET, SomfyTahomaSetup.class);
|
SomfyTahomaSetup setup = invokeCallToURL(TAHOMA_API_URL + "setup", "", HttpMethod.GET, SomfyTahomaSetup.class);
|
||||||
|
if (setup != null) {
|
||||||
|
saveDevicePlaces(setup.getDevices());
|
||||||
|
}
|
||||||
|
return setup;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SomfyTahomaDevice> getDevices() {
|
public List<SomfyTahomaDevice> getDevices() {
|
||||||
SomfyTahomaDevice[] response = invokeCallToURL(SETUP_URL + "devices", "", HttpMethod.GET,
|
SomfyTahomaDevice[] response = invokeCallToURL(SETUP_URL + "devices", "", HttpMethod.GET,
|
||||||
SomfyTahomaDevice[].class);
|
SomfyTahomaDevice[].class);
|
||||||
return response != null ? List.of(response) : List.of();
|
List<SomfyTahomaDevice> devices = response != null ? List.of(response) : List.of();
|
||||||
|
saveDevicePlaces(devices);
|
||||||
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized @Nullable SomfyTahomaDevice getCachedDevice(String url) {
|
public synchronized @Nullable SomfyTahomaDevice getCachedDevice(String url) {
|
||||||
@ -364,6 +372,18 @@ public class SomfyTahomaBridgeHandler extends BaseBridgeHandler {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void saveDevicePlaces(List<SomfyTahomaDevice> devices) {
|
||||||
|
devicePlaces.clear();
|
||||||
|
for (SomfyTahomaDevice device : devices) {
|
||||||
|
if (!device.getPlaceOID().isEmpty()) {
|
||||||
|
SomfyTahomaDevice newDevice = new SomfyTahomaDevice();
|
||||||
|
newDevice.setPlaceOID(device.getPlaceOID());
|
||||||
|
newDevice.setWidget(device.getWidget());
|
||||||
|
devicePlaces.put(device.getDeviceURL(), newDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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()) {
|
||||||
@ -648,6 +668,20 @@ public class SomfyTahomaBridgeHandler extends BaseBridgeHandler {
|
|||||||
}, thingConfig.getRetryDelay(), TimeUnit.MILLISECONDS));
|
}, thingConfig.getRetryDelay(), TimeUnit.MILLISECONDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendCommandToSameDevicesInPlace(String io, String command, String params, String url) {
|
||||||
|
SomfyTahomaDevice device = devicePlaces.get(io);
|
||||||
|
if (device != null && !device.getPlaceOID().isEmpty()) {
|
||||||
|
devicePlaces.forEach((deviceUrl, devicePlace) -> {
|
||||||
|
if (device.getPlaceOID().equals(devicePlace.getPlaceOID())
|
||||||
|
&& device.getWidget().equals(devicePlace.getWidget())) {
|
||||||
|
sendCommand(deviceUrl, command, params, url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
sendCommand(io, command, params, url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String getThingLabelByURL(String io) {
|
private String getThingLabelByURL(String io) {
|
||||||
Thing th = getThingByDeviceUrl(io);
|
Thing th = getThingByDeviceUrl(io);
|
||||||
if (th != null) {
|
if (th != null) {
|
||||||
|
@ -35,6 +35,7 @@ public class SomfyTahomaDevice {
|
|||||||
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<>();
|
private List<SomfyTahomaState> attributes = new ArrayList<>();
|
||||||
|
private String placeOID = "";
|
||||||
|
|
||||||
public String getLabel() {
|
public String getLabel() {
|
||||||
return label;
|
return label;
|
||||||
@ -56,6 +57,10 @@ public class SomfyTahomaDevice {
|
|||||||
return widget;
|
return widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setWidget(String widget) {
|
||||||
|
this.widget = widget;
|
||||||
|
}
|
||||||
|
|
||||||
public SomfyTahomaDeviceDefinition getDefinition() {
|
public SomfyTahomaDeviceDefinition getDefinition() {
|
||||||
return definition;
|
return definition;
|
||||||
}
|
}
|
||||||
@ -67,4 +72,12 @@ public class SomfyTahomaDevice {
|
|||||||
public List<SomfyTahomaState> getAttributes() {
|
public List<SomfyTahomaState> getAttributes() {
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPlaceOID() {
|
||||||
|
return placeOID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlaceOID(String placeOID) {
|
||||||
|
this.placeOID = placeOID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 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.somfytahoma.internal.model;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SomfyTahomaRootPlace} holds information about all rooms bound
|
||||||
|
* to TahomaLink account.
|
||||||
|
*
|
||||||
|
* @author Laurent Garnier - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class SomfyTahomaRootPlace {
|
||||||
|
|
||||||
|
private String label = "";
|
||||||
|
private int type;
|
||||||
|
private String oid = "";
|
||||||
|
private List<SomfyTahomaSubPlace> subPlaces = new ArrayList<>();
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOid() {
|
||||||
|
return oid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SomfyTahomaSubPlace> getSubPlaces() {
|
||||||
|
return subPlaces;
|
||||||
|
}
|
||||||
|
}
|
@ -16,12 +16,14 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link SomfyTahomaSetup} holds information about devices bound
|
* The {@link SomfyTahomaSetup} holds information about devices bound
|
||||||
* to TahomaLink account.
|
* to TahomaLink account.
|
||||||
*
|
*
|
||||||
* @author Ondrej Pecta - Initial contribution
|
* @author Ondrej Pecta - Initial contribution
|
||||||
|
* @author Laurent Garnier - Add rooms data
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class SomfyTahomaSetup {
|
public class SomfyTahomaSetup {
|
||||||
@ -30,6 +32,8 @@ public class SomfyTahomaSetup {
|
|||||||
|
|
||||||
private List<SomfyTahomaGateway> gateways = new ArrayList<>();
|
private List<SomfyTahomaGateway> gateways = new ArrayList<>();
|
||||||
|
|
||||||
|
private @Nullable SomfyTahomaRootPlace rootPlace;
|
||||||
|
|
||||||
public List<SomfyTahomaDevice> getDevices() {
|
public List<SomfyTahomaDevice> getDevices() {
|
||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
@ -37,4 +41,8 @@ public class SomfyTahomaSetup {
|
|||||||
public List<SomfyTahomaGateway> getGateways() {
|
public List<SomfyTahomaGateway> getGateways() {
|
||||||
return gateways;
|
return gateways;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @Nullable SomfyTahomaRootPlace getRootPlace() {
|
||||||
|
return rootPlace;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 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.somfytahoma.internal.model;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SomfyTahomaSubPlace} holds information about a room bound
|
||||||
|
* to TahomaLink account.
|
||||||
|
*
|
||||||
|
* @author Laurent Garnier - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class SomfyTahomaSubPlace {
|
||||||
|
|
||||||
|
private String label = "";
|
||||||
|
private int type;
|
||||||
|
private String metadata = "";
|
||||||
|
private String oid = "";
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMetadata() {
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOid() {
|
||||||
|
return oid;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user