[somfytahoma] New channel on the gateway to execute scenes (#10346)
* [somfytahoma] New channel on the bridge to execute scenes Signed-off-by: Laurent Garnier <lg.hc@free.fr> * Review comment: documentation updated Signed-off-by: Laurent Garnier <lg.hc@free.fr> * Console command added to list the scenarios IDs Signed-off-by: Laurent Garnier <lg.hc@free.fr> * Update state of new channel Signed-off-by: Laurent Garnier <lg.hc@free.fr> * Review comment: set auto update policy to recommend Signed-off-by: Laurent Garnier <lg./hc@free.fr>
This commit is contained in:
parent
4ff238d3f4
commit
3525c9123e
@ -62,6 +62,7 @@ Please see the example below.
|
||||
|-------------------------------------------------------------------------------|------------------------------|-----------------------------------------------------------------------------------------------------------------------------|
|
||||
| bridge | N.A | bridge does not expose any channel |
|
||||
| gateway | status | status of your Tahoma gateway |
|
||||
| gateway | scenarios | used to run the scenarios defined in the cloud portal |
|
||||
| gate | gate_command | used for controlling your gate (open, close, stop, pedestrian) |
|
||||
| gate | gate_state | get state of your gate (open, closed, pedestrian) |
|
||||
| gate | gate_position | get position (0-100%) of your gate (where supported) |
|
||||
@ -120,6 +121,9 @@ Please see the example below.
|
||||
| myfox camera | shutter | controlling of the camera shutter |
|
||||
| myfox alarm | myfox_alarm_command | used for sending commands to Somfy Myfox alarm device |
|
||||
|
||||
To run a scenario inside a rule for example, the ID of the scenario will be required.
|
||||
You can list all the scenarios IDs with the following console command: `somfytahoma <bridgeUID> scenarios`.
|
||||
|
||||
### Remarks
|
||||
|
||||
All things which have a RSSI (relative received signal) state, expose a channel "rssi".
|
||||
|
||||
@ -12,7 +12,11 @@
|
||||
*/
|
||||
package org.openhab.binding.somfytahoma.internal;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
@ -156,6 +160,7 @@ public class SomfyTahomaBindingConstants {
|
||||
|
||||
// Gateway
|
||||
public static final String STATUS = "status";
|
||||
public static final String SCENARIOS = "scenarios";
|
||||
|
||||
// Roller shutter, Awning, Screen, Blind, Garage door, Window, Curtain
|
||||
public static final String CONTROL = "control";
|
||||
|
||||
@ -16,7 +16,43 @@ import static org.openhab.binding.somfytahoma.internal.SomfyTahomaBindingConstan
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.*;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaActionGroupHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaAdjustableSlatsRollerShutterHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaAwningHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaBridgeHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaContactSensorHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaCurtainHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaDimmerLightHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaDockHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaDoorLockHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaElectricitySensorHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaExteriorHeatingSystemHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaExternalAlarmHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaGateHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaGatewayHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaHumiditySensorHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaInternalAlarmHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaLightSensorHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaMyfoxAlarmHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaMyfoxCameraHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaOccupancySensorHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaOnOffHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaOnOffHeatingSystemHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaPergolaHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaPodHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaRollerShutterHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaSilentRollerShutterHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaSirenHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaSmokeSensorHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaTemperatureSensorHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaThermostatHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaUnoRollerShutterHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaValveHeatingSystemHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaVenetianBlindHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaWaterSensorHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaWindowHandleHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaWindowHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaZwaveHeatingSystemHandler;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Thing;
|
||||
@ -43,10 +79,13 @@ public class SomfyTahomaHandlerFactory extends BaseThingHandlerFactory {
|
||||
private final Logger logger = LoggerFactory.getLogger(SomfyTahomaHandlerFactory.class);
|
||||
|
||||
private final HttpClientFactory httpClientFactory;
|
||||
private final SomfyTahomaStateDescriptionOptionProvider stateDescriptionProvider;
|
||||
|
||||
@Activate
|
||||
public SomfyTahomaHandlerFactory(@Reference HttpClientFactory httpClientFactory) {
|
||||
public SomfyTahomaHandlerFactory(@Reference HttpClientFactory httpClientFactory,
|
||||
final @Reference SomfyTahomaStateDescriptionOptionProvider stateDescriptionProvider) {
|
||||
this.httpClientFactory = httpClientFactory;
|
||||
this.stateDescriptionProvider = stateDescriptionProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -64,7 +103,7 @@ public class SomfyTahomaHandlerFactory extends BaseThingHandlerFactory {
|
||||
if (thingTypeUID.equals(THING_TYPE_BRIDGE)) {
|
||||
return new SomfyTahomaBridgeHandler((Bridge) thing, httpClientFactory);
|
||||
} else if (thingTypeUID.equals(THING_TYPE_GATEWAY)) {
|
||||
return new SomfyTahomaGatewayHandler(thing);
|
||||
return new SomfyTahomaGatewayHandler(thing, stateDescriptionProvider);
|
||||
} else if (thingTypeUID.equals(THING_TYPE_ROLLERSHUTTER)) {
|
||||
return new SomfyTahomaRollerShutterHandler(thing);
|
||||
} else if (thingTypeUID.equals(THING_TYPE_ROLLERSHUTTER_SILENT)) {
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.binding.BaseDynamicStateDescriptionProvider;
|
||||
import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService;
|
||||
import org.openhab.core.thing.type.DynamicStateDescriptionProvider;
|
||||
import org.openhab.core.types.StateOption;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* Dynamic provider of state options while leaving other state description fields as original.
|
||||
*
|
||||
* @author Laurent Garnier - Initial contribution
|
||||
*/
|
||||
@Component(service = { DynamicStateDescriptionProvider.class, SomfyTahomaStateDescriptionOptionProvider.class })
|
||||
@NonNullByDefault
|
||||
public class SomfyTahomaStateDescriptionOptionProvider extends BaseDynamicStateDescriptionProvider {
|
||||
|
||||
public @Nullable List<StateOption> getStateOptions(ChannelUID channelUID) {
|
||||
return channelOptionsMap.get(channelUID);
|
||||
}
|
||||
|
||||
@Reference
|
||||
protected void setChannelTypeI18nLocalizationService(
|
||||
final ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) {
|
||||
this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService;
|
||||
}
|
||||
|
||||
protected void unsetChannelTypeI18nLocalizationService(
|
||||
final ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) {
|
||||
this.channelTypeI18nLocalizationService = null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
/**
|
||||
* 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.console;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.somfytahoma.internal.handler.SomfyTahomaBridgeHandler;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaActionGroup;
|
||||
import org.openhab.core.io.console.Console;
|
||||
import org.openhab.core.io.console.extensions.AbstractConsoleCommandExtension;
|
||||
import org.openhab.core.io.console.extensions.ConsoleCommandExtension;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingRegistry;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* The {@link SomfyTahomaCommandExtension} is responsible for handling console commands
|
||||
*
|
||||
* @author Laurent Garnier - Initial contribution
|
||||
*/
|
||||
|
||||
@NonNullByDefault
|
||||
@Component(service = ConsoleCommandExtension.class)
|
||||
public class SomfyTahomaCommandExtension extends AbstractConsoleCommandExtension {
|
||||
|
||||
private static final String SCENARIOS = "scenarios";
|
||||
|
||||
private final ThingRegistry thingRegistry;
|
||||
|
||||
@Activate
|
||||
public SomfyTahomaCommandExtension(final @Reference ThingRegistry thingRegistry) {
|
||||
super("somfytahoma", "Interact with the Somfy Tahoma binding.");
|
||||
this.thingRegistry = thingRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(String[] args, Console console) {
|
||||
if (args.length == 2) {
|
||||
Thing thing = null;
|
||||
try {
|
||||
ThingUID thingUID = new ThingUID(args[0]);
|
||||
thing = thingRegistry.get(thingUID);
|
||||
} catch (IllegalArgumentException e) {
|
||||
thing = null;
|
||||
}
|
||||
ThingHandler thingHandler = null;
|
||||
SomfyTahomaBridgeHandler bridgeHandler = null;
|
||||
if (thing != null) {
|
||||
thingHandler = thing.getHandler();
|
||||
if (thingHandler instanceof SomfyTahomaBridgeHandler) {
|
||||
bridgeHandler = (SomfyTahomaBridgeHandler) thingHandler;
|
||||
}
|
||||
}
|
||||
if (thing == null) {
|
||||
console.println("Bad thing id '" + args[0] + "'");
|
||||
printUsage(console);
|
||||
} else if (thingHandler == null) {
|
||||
console.println("No handler initialized for the thingUID '" + args[0] + "'");
|
||||
printUsage(console);
|
||||
} else if (bridgeHandler == null) {
|
||||
console.println("'" + args[0] + "' is not a Somfy Tahoma bridgeUID");
|
||||
printUsage(console);
|
||||
} else if (args[1].equals(SCENARIOS)) {
|
||||
for (SomfyTahomaActionGroup actionGroup : bridgeHandler.listActionGroups()) {
|
||||
console.println("Id is \"" + actionGroup.getOid() + "\" for the scenario \""
|
||||
+ actionGroup.getLabel() + "\"");
|
||||
}
|
||||
} else {
|
||||
printUsage(console);
|
||||
}
|
||||
} else {
|
||||
printUsage(console);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUsages() {
|
||||
return List.of(buildCommandUsage("<bridgeUID> " + SCENARIOS, "list all the scenarios with their id"));
|
||||
}
|
||||
}
|
||||
@ -12,17 +12,26 @@
|
||||
*/
|
||||
package org.openhab.binding.somfytahoma.internal.handler;
|
||||
|
||||
import static org.openhab.binding.somfytahoma.internal.SomfyTahomaBindingConstants.STATUS;
|
||||
import static org.openhab.binding.somfytahoma.internal.SomfyTahomaBindingConstants.*;
|
||||
import static org.openhab.core.thing.Thing.PROPERTY_FIRMWARE_VERSION;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.somfytahoma.internal.SomfyTahomaStateDescriptionOptionProvider;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaActionGroup;
|
||||
import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaStatus;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
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.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.StateOption;
|
||||
|
||||
/**
|
||||
* The {@link SomfyTahomaGatewayHandler} is responsible for handling commands,
|
||||
@ -33,8 +42,11 @@ import org.openhab.core.thing.ThingStatusDetail;
|
||||
@NonNullByDefault
|
||||
public class SomfyTahomaGatewayHandler extends SomfyTahomaBaseThingHandler {
|
||||
|
||||
public SomfyTahomaGatewayHandler(Thing thing) {
|
||||
private final SomfyTahomaStateDescriptionOptionProvider stateDescriptionProvider;
|
||||
|
||||
public SomfyTahomaGatewayHandler(Thing thing, SomfyTahomaStateDescriptionOptionProvider stateDescriptionProvider) {
|
||||
super(thing);
|
||||
this.stateDescriptionProvider = stateDescriptionProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -42,6 +54,7 @@ public class SomfyTahomaGatewayHandler extends SomfyTahomaBaseThingHandler {
|
||||
if (bridgeStatus != null) {
|
||||
if (bridgeStatus == ThingStatus.ONLINE) {
|
||||
refresh(STATUS);
|
||||
refresh(SCENARIOS);
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
||||
}
|
||||
@ -52,21 +65,46 @@ public class SomfyTahomaGatewayHandler extends SomfyTahomaBaseThingHandler {
|
||||
|
||||
@Override
|
||||
public void refresh(String channel) {
|
||||
String id = getGateWayId();
|
||||
SomfyTahomaStatus status = getTahomaStatus(id);
|
||||
String tahomaStatus = status.getStatus();
|
||||
Channel ch = thing.getChannel(channel);
|
||||
if (ch != null) {
|
||||
updateState(ch.getUID(), new StringType(tahomaStatus));
|
||||
}
|
||||
// update the firmware property
|
||||
String fw = status.getProtocolVersion();
|
||||
updateProperty(PROPERTY_FIRMWARE_VERSION, fw);
|
||||
if (channel.equals(STATUS)) {
|
||||
String id = getGateWayId();
|
||||
SomfyTahomaStatus status = getTahomaStatus(id);
|
||||
String tahomaStatus = status.getStatus();
|
||||
Channel ch = thing.getChannel(channel);
|
||||
if (ch != null) {
|
||||
updateState(ch.getUID(), new StringType(tahomaStatus));
|
||||
}
|
||||
// update the firmware property
|
||||
String fw = status.getProtocolVersion();
|
||||
updateProperty(PROPERTY_FIRMWARE_VERSION, fw);
|
||||
|
||||
updateStatus("DISCONNECTED".equals(tahomaStatus) ? ThingStatus.OFFLINE : ThingStatus.ONLINE);
|
||||
updateStatus("DISCONNECTED".equals(tahomaStatus) ? ThingStatus.OFFLINE : ThingStatus.ONLINE);
|
||||
} else if (channel.equals(SCENARIOS)) {
|
||||
SomfyTahomaBridgeHandler handler = getBridgeHandler();
|
||||
if (handler != null) {
|
||||
List<StateOption> options = new ArrayList<>();
|
||||
for (SomfyTahomaActionGroup actionGroup : handler.listActionGroups()) {
|
||||
options.add(new StateOption(actionGroup.getOid(), actionGroup.getLabel()));
|
||||
}
|
||||
stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), channel), options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getGateWayId() {
|
||||
return getThing().getConfiguration().get("id").toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
super.handleCommand(channelUID, command);
|
||||
if (command instanceof RefreshType) {
|
||||
return;
|
||||
}
|
||||
if (channelUID.getId().equals(SCENARIOS)) {
|
||||
SomfyTahomaBridgeHandler handler = getBridgeHandler();
|
||||
if (handler != null && command instanceof StringType) {
|
||||
handler.executeActionGroup(command.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -389,4 +389,11 @@
|
||||
<description>Operating mode of the Somfy thermostatic valve</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="scenarios">
|
||||
<item-type>String</item-type>
|
||||
<label>Scenarios</label>
|
||||
<description>The scenarios defined in the cloud portal</description>
|
||||
<autoUpdatePolicy>recommend</autoUpdatePolicy>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
<label>Somfy Tahoma Gateway</label>
|
||||
<channels>
|
||||
<channel id="status" typeId="status"></channel>
|
||||
<channel id="scenarios" typeId="scenarios"></channel>
|
||||
</channels>
|
||||
<representation-property>id</representation-property>
|
||||
<config-description-ref uri="thing-type:somfytahoma:gateway"/>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user