|-------------------------------------------------------------------------------|------------------------------|-----------------------------------------------------------------------------------------------------------------------------|
| 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) |
| 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".
*/
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;
// 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";
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;
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
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)) {
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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"));
+ }
+}
*/
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,
@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
if (bridgeStatus != null) {
if (bridgeStatus == ThingStatus.ONLINE) {
refresh(STATUS);
+ refresh(SCENARIOS);
} else {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
}
@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());
+ }
+ }
+ }
}
<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>
<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"/>