diff --git a/CODEOWNERS b/CODEOWNERS index 48f1fc1855175..9530d03493032 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -178,6 +178,7 @@ /bundles/org.openhab.binding.snmp/ @J-N-K /bundles/org.openhab.binding.solaredge/ @alexf2015 /bundles/org.openhab.binding.solarlog/ @johannrichard +/bundles/org.openhab.binding.somfymylink/ @loungeflyz /bundles/org.openhab.binding.somfytahoma/ @octa22 /bundles/org.openhab.binding.sonos/ @kgoderis @lolodomo /bundles/org.openhab.binding.sonyaudio/ @freke diff --git a/bundles/org.openhab.binding.somfymylink/.classpath b/bundles/org.openhab.binding.somfymylink/.classpath new file mode 100644 index 0000000000000..39abf1c5e9102 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/.classpath @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.openhab.binding.somfymylink/.project b/bundles/org.openhab.binding.somfymylink/.project new file mode 100644 index 0000000000000..104819095ccf0 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/.project @@ -0,0 +1,23 @@ + + + org.openhab.binding.somfymylink + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/bundles/org.openhab.binding.somfymylink/NOTICE b/bundles/org.openhab.binding.somfymylink/NOTICE new file mode 100644 index 0000000000000..4c20ef446c1e4 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/NOTICE @@ -0,0 +1,13 @@ +This content is produced and maintained by the openHAB project. + +* Project home: https://www.openhab.org + +== Declared Project Licenses + +This program and the accompanying materials are made available under the terms +of the Eclipse Public License 2.0 which is available at +https://www.eclipse.org/legal/epl-2.0/. + +== Source Code + +https://github.com/openhab/openhab2-addons diff --git a/bundles/org.openhab.binding.somfymylink/README.md b/bundles/org.openhab.binding.somfymylink/README.md new file mode 100644 index 0000000000000..bde3b39634e62 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/README.md @@ -0,0 +1,65 @@ +# Somfy myLink Binding + +This binding supports the [Somfy myLink](https://www.somfysystems.com/en-us/products/1811403/mylink-) device for control of Somfy RTS blinds/shades. + +## Supported Things + +Currently these things are supported: + +- bridge (Somfy MyLink bridge, which can discover roller shades and scenes) +- roller shades (UP, DOWN, STOP control of a roller shade). + +This binding has been tested with myLink firmware 5.23. + +## Discovery + +To start a discovery: + +- install this binding +- open Paper UI +- add a new thing in menu Configuration/Things +- choose SomfyMyLink Binding and select Somfy MyLink Bridge +- enter it's IP Address and system id. The system id This can be found in the integration settings -> Control4 section of your My Link app + +If the supplied ip address and system id are correct, the automatic discovery starts immediately and detected roller shades appear in Paper UI inbox. + +## Thing Configuration + +### mylink + +| Parameter | Parameter ID | Required/Optional | Description | +|------------------|-------------------|-------------------|-------------| +| IP or Hostname | ipAddress | Required | Hostname or IP Address of the myLink device | +| System Id | systemId | Required | The system id configured on the myLink device | + +### shade + +| Parameter | Parameter ID | Required/Optional | Description | +|------------------|-------------------|-------------------|-------------| +| Target ID | targetId | Required | Address of shade in the Somfy system | + +### scene + +| Parameter | Parameter ID | Required/Optional | Description | +|------------------|-------------------|-------------------|-------------| +| Scene ID | sceneId | Required | Address of scene in the Somfy system | + +## Channels + +The following channels are supported by the binding. Note that specific weather station models may support only some or all of these channels. + +| Channel ID | Item Type | Description | +|---------------------------------|-------------------------|---------------------------------------------------------------| +| shadeControl | Rollershutter | Device control (UP, DOWN, STOP) | +| scenelist | String | Comma-separated list of scenes of form sceneId=sceneName | +| button | Switch | Button to trigger a scene or rule | + +## Example + +### Things + +``` +Bridge somfymylink:mylink:mylink1 "myLink Bridge" @ "Office" [ ipAddress="192.168.1.1", systemId="mysystemidhere" ] { + Thing shade shade1 "Living Room" [ targetId="CC114A21.1" ] +} +``` \ No newline at end of file diff --git a/bundles/org.openhab.binding.somfymylink/pom.xml b/bundles/org.openhab.binding.somfymylink/pom.xml new file mode 100644 index 0000000000000..fa97d7feeef9c --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/pom.xml @@ -0,0 +1,17 @@ + + + + 4.0.0 + + + org.openhab.addons.bundles + org.openhab.addons.reactor.bundles + 2.5.6-SNAPSHOT + + + org.openhab.binding.somfymylink + + openHAB Add-ons :: Bundles :: Somfy MyLink Binding + + diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/SomfyMyLinkBindingConstants.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/SomfyMyLinkBindingConstants.java new file mode 100644 index 0000000000000..69ed4b06c4972 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/SomfyMyLinkBindingConstants.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.core.thing.ThingTypeUID; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkBindingConstants { + + private static final String BINDING_ID = "somfymylink"; + + // List of all Thing Type UIDs + public static final ThingTypeUID THING_TYPE_SHADE = new ThingTypeUID(BINDING_ID, "shade"); + public static final ThingTypeUID THING_TYPE_SCENE = new ThingTypeUID(BINDING_ID, "scene"); + public static final ThingTypeUID THING_TYPE_MYLINK = new ThingTypeUID(BINDING_ID, "mylink"); + + // List of all Channel ids + public static final String CHANNEL_SHADELEVEL = "shadelevel"; + public static final String CHANNEL_SCENECONTROL = "scenecontrol"; + public static final String CHANNEL_SCENES = "sceneid"; + + // Thing config properties + public static final String TARGET_ID = "targetId"; + public static final String SCENE_ID = "sceneId"; +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/SomfyMyLinkHandlerFactory.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/SomfyMyLinkHandlerFactory.java new file mode 100644 index 0000000000000..ff9fbdd6ae631 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/SomfyMyLinkHandlerFactory.java @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal; + +import static org.openhab.binding.somfymylink.internal.SomfyMyLinkBindingConstants.*; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.thing.Bridge; +import org.eclipse.smarthome.core.thing.Thing; +import org.eclipse.smarthome.core.thing.ThingTypeUID; +import org.eclipse.smarthome.core.thing.binding.BaseThingHandlerFactory; +import org.eclipse.smarthome.core.thing.binding.ThingHandler; +import org.eclipse.smarthome.core.thing.binding.ThingHandlerFactory; +import org.openhab.binding.somfymylink.internal.handler.SomfyMyLinkBridgeHandler; +import org.openhab.binding.somfymylink.internal.handler.SomfyMyLinkStateDescriptionOptionsProvider; +import org.openhab.binding.somfymylink.internal.handler.SomfySceneHandler; +import org.openhab.binding.somfymylink.internal.handler.SomfyShadeHandler; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +@Component(configurationPid = "binding.somfymylink", service = ThingHandlerFactory.class) +public class SomfyMyLinkHandlerFactory extends BaseThingHandlerFactory { + + private static final Set SUPPORTED_THING_TYPES_UIDS = new HashSet<>( + Arrays.asList(THING_TYPE_MYLINK, THING_TYPE_SHADE, THING_TYPE_SCENE)); + + public static final Set DISCOVERABLE_DEVICE_TYPES_UIDS = new HashSet<>( + Arrays.asList(THING_TYPE_SHADE, THING_TYPE_SCENE)); + + private @Nullable SomfyMyLinkStateDescriptionOptionsProvider stateDescriptionProvider; + + @Override + public boolean supportsThingType(ThingTypeUID thingTypeUID) { + return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID); + } + + @Override + protected @Nullable ThingHandler createHandler(Thing thing) { + ThingTypeUID thingTypeUID = thing.getThingTypeUID(); + + if (thingTypeUID.equals(THING_TYPE_MYLINK)) { + return new SomfyMyLinkBridgeHandler((Bridge) thing, stateDescriptionProvider); + } + if (THING_TYPE_SHADE.equals(thingTypeUID)) { + return new SomfyShadeHandler(thing); + } + if (THING_TYPE_SCENE.equals(thingTypeUID)) { + return new SomfySceneHandler(thing); + } + + return null; + } + + @Reference + protected void setDynamicStateDescriptionProvider(SomfyMyLinkStateDescriptionOptionsProvider provider) { + this.stateDescriptionProvider = provider; + } + + protected void unsetDynamicStateDescriptionProvider(SomfyMyLinkStateDescriptionOptionsProvider provider) { + this.stateDescriptionProvider = null; + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/config/SomfyMyLinkConfiguration.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/config/SomfyMyLinkConfiguration.java new file mode 100644 index 0000000000000..7ed4569b90967 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/config/SomfyMyLinkConfiguration.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.config; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link SomfyMyLinkConfiguration} class contains fields mapping thing configuration parameters. + * + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkConfiguration { + public String ipAddress = ""; + + public String systemId = ""; +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/discovery/SomfyMyLinkDeviceDiscoveryService.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/discovery/SomfyMyLinkDeviceDiscoveryService.java new file mode 100644 index 0000000000000..f78b1ad8d8d41 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/discovery/SomfyMyLinkDeviceDiscoveryService.java @@ -0,0 +1,190 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.discovery; + +import static org.openhab.binding.somfymylink.internal.SomfyMyLinkBindingConstants.*; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.config.discovery.AbstractDiscoveryService; +import org.eclipse.smarthome.config.discovery.DiscoveryResult; +import org.eclipse.smarthome.config.discovery.DiscoveryResultBuilder; +import org.eclipse.smarthome.config.discovery.DiscoveryService; +import org.eclipse.smarthome.config.discovery.ScanListener; +import org.eclipse.smarthome.core.thing.ThingStatus; +import org.eclipse.smarthome.core.thing.ThingTypeUID; +import org.eclipse.smarthome.core.thing.ThingUID; +import org.eclipse.smarthome.core.thing.binding.ThingHandler; +import org.eclipse.smarthome.core.thing.binding.ThingHandlerService; +import org.openhab.binding.somfymylink.internal.SomfyMyLinkHandlerFactory; +import org.openhab.binding.somfymylink.internal.handler.SomfyMyLinkBridgeHandler; +import org.openhab.binding.somfymylink.internal.handler.SomfyMyLinkException; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkScene; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkShade; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Deactivate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link SomfyMyLinkDeviceDiscoveryService} is responsible discovering things connected to the mylink. + * + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkDeviceDiscoveryService extends AbstractDiscoveryService + implements DiscoveryService, ThingHandlerService { + + private static final int DISCOVERY_REFRESH_SEC = 900; + + private final Logger logger = LoggerFactory.getLogger(SomfyMyLinkDeviceDiscoveryService.class); + private @NonNullByDefault({}) SomfyMyLinkBridgeHandler mylinkHandler; + private @Nullable Future scanTask; + private @Nullable ScheduledFuture discoveryJob; + + public SomfyMyLinkDeviceDiscoveryService() { + super(SomfyMyLinkHandlerFactory.DISCOVERABLE_DEVICE_TYPES_UIDS, 10); + } + + @Override + public void setThingHandler(@Nullable ThingHandler handler) { + if (handler instanceof SomfyMyLinkBridgeHandler) { + this.mylinkHandler = (SomfyMyLinkBridgeHandler) handler; + } + } + + @Override + public @Nullable ThingHandler getThingHandler() { + return mylinkHandler; + } + + @Override + @Activate + public void activate() { + super.activate(null); + } + + @Override + @Deactivate + public void deactivate() { + super.deactivate(); + } + + @Override + protected void startBackgroundDiscovery() { + logger.debug("Starting Somfy My Link background discovery"); + + ScheduledFuture discoveryJob = this.discoveryJob; + if (discoveryJob == null || discoveryJob.isCancelled()) { + discoveryJob = scheduler.scheduleWithFixedDelay(this::discoverDevices, 10, DISCOVERY_REFRESH_SEC, + TimeUnit.SECONDS); + } + } + + @Override + protected void stopBackgroundDiscovery() { + logger.debug("Stopping Somfy MyLink background discovery"); + + ScheduledFuture discoveryJob = this.discoveryJob; + if (discoveryJob != null) { + discoveryJob.cancel(true); + this.discoveryJob = null; + } + } + + @Override + protected synchronized void startScan() { + Future scanTask = this.scanTask; + if (scanTask == null || scanTask.isDone()) { + logger.debug("Starting somfy mylink discovery scan"); + scanTask = scheduler.submit(this::discoverDevices); + } + } + + @Override + public void stopScan() { + Future scanTask = this.scanTask; + if (scanTask != null) { + logger.debug("Stopping somfy mylink discovery scan"); + scanTask.cancel(true); + } + super.stopScan(); + } + + private synchronized void discoverDevices() { + logger.info("Scanning for things..."); + + if (this.mylinkHandler.getThing().getStatus() != ThingStatus.ONLINE) { + logger.info("Skipping device discover as bridge is {}", this.mylinkHandler.getThing().getStatus()); + return; + } + + try { + // get the shade list + SomfyMyLinkShade[] shades = this.mylinkHandler.getShadeList(); + + for (SomfyMyLinkShade shade : shades) { + String id = shade.getTargetID(); + String label = "Somfy Shade " + shade.getName(); + + if (id != null) { + logger.debug("Adding device {}", id); + notifyThingDiscovery(THING_TYPE_SHADE, id, label, TARGET_ID); + } + } + + SomfyMyLinkScene[] scenes = this.mylinkHandler.getSceneList(); + + for (SomfyMyLinkScene scene : scenes) { + String id = scene.getTargetID(); + String label = "Somfy Scene " + scene.getName(); + + logger.debug("Adding device {}", id); + notifyThingDiscovery(THING_TYPE_SCENE, id, label, SCENE_ID); + } + } catch (SomfyMyLinkException e) { + logger.warn("Error scanning for devices: {}", e.getMessage(), e); + ScanListener scanListener = this.scanListener; + if (scanListener != null) { + scanListener.onErrorOccurred(e); + } + } + } + + private void notifyThingDiscovery(ThingTypeUID thingTypeUID, String id, String label, String idType) { + if (id.isEmpty()) { + logger.info("Discovered {} with no ID", label); + return; + } + + ThingUID bridgeUID = this.mylinkHandler.getThing().getUID(); + ThingUID uid = new ThingUID(thingTypeUID, bridgeUID, id); + + Map properties = new HashMap<>(); + + properties.put(idType, id); + + DiscoveryResult result = DiscoveryResultBuilder.create(uid).withBridge(bridgeUID).withLabel(label) + .withProperties(properties).withRepresentationProperty(idType).build(); + + thingDiscovered(result); + + logger.debug("Discovered {}", uid); + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/handler/SomfyMyLinkBridgeHandler.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/handler/SomfyMyLinkBridgeHandler.java new file mode 100644 index 0000000000000..ed8b02cb8e9fe --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/handler/SomfyMyLinkBridgeHandler.java @@ -0,0 +1,387 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.handler; + +import static org.openhab.binding.somfymylink.internal.SomfyMyLinkBindingConstants.*; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.common.NamedThreadFactory; +import org.eclipse.smarthome.core.library.types.StringType; +import org.eclipse.smarthome.core.thing.Bridge; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.thing.Thing; +import org.eclipse.smarthome.core.thing.ThingStatus; +import org.eclipse.smarthome.core.thing.ThingStatusDetail; +import org.eclipse.smarthome.core.thing.binding.BaseBridgeHandler; +import org.eclipse.smarthome.core.thing.binding.ThingHandlerService; +import org.eclipse.smarthome.core.types.Command; +import org.eclipse.smarthome.core.types.RefreshType; +import org.eclipse.smarthome.core.types.StateOption; +import org.openhab.binding.somfymylink.internal.SomfyMyLinkBindingConstants; +import org.openhab.binding.somfymylink.internal.config.SomfyMyLinkConfiguration; +import org.openhab.binding.somfymylink.internal.discovery.SomfyMyLinkDeviceDiscoveryService; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkCommandBase; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkCommandSceneList; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkCommandSceneSet; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkCommandShadeDown; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkCommandShadeList; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkCommandShadePing; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkCommandShadeStop; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkCommandShadeUp; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkErrorResponse; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkPingResponse; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkResponseBase; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkScene; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkScenesResponse; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkShade; +import org.openhab.binding.somfymylink.internal.model.SomfyMyLinkShadesResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +/** + * The {@link SomfyMyLinkBridgeHandler} is responsible for handling commands, which are + * sent to one of the channels. + * + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkBridgeHandler extends BaseBridgeHandler { + + private final Logger logger = LoggerFactory.getLogger(SomfyMyLinkBridgeHandler.class); + private static final int HEARTBEAT_MINUTES = 2; + private static final int MYLINK_PORT = 44100; + private static final int MYLINK_DEFAULT_TIMEOUT = 5000; + private static final int CONNECTION_DELAY = 1000; + private static final SomfyMyLinkShade[] EMPTY_SHADE_LIST = new SomfyMyLinkShade[0]; + private static final SomfyMyLinkScene[] EMPTY_SCENE_LIST = new SomfyMyLinkScene[0]; + + private SomfyMyLinkConfiguration config = new SomfyMyLinkConfiguration(); + private @Nullable ScheduledFuture heartbeat; + private @Nullable SomfyMyLinkStateDescriptionOptionsProvider stateDescriptionProvider; + private @Nullable ExecutorService commandExecutor; + + // Gson & parser + private final Gson gson = new Gson(); + + public SomfyMyLinkBridgeHandler(Bridge bridge, + @Nullable SomfyMyLinkStateDescriptionOptionsProvider stateDescriptionProvider) { + super(bridge); + this.stateDescriptionProvider = stateDescriptionProvider; + } + + @Override + public void handleCommand(ChannelUID channelUID, Command command) { + logger.debug("Command received on mylink {}", command); + + try { + if (CHANNEL_SCENES.equals(channelUID.getId())) { + if (command instanceof RefreshType) { + return; + } + + if (command instanceof StringType) { + Integer sceneId = Integer.decode(command.toString()); + commandScene(sceneId); + } + } + } catch (SomfyMyLinkException e) { + logger.info("Error handling command: {}", e.getMessage()); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage()); + } + } + + @Override + public void initialize() { + logger.info("Initializing mylink"); + config = getThing().getConfiguration().as(SomfyMyLinkConfiguration.class); + + commandExecutor = Executors.newSingleThreadExecutor(new NamedThreadFactory(thing.getUID().getAsString(), true)); + + if (validConfiguration(config)) { + // start the keepalive process + if (heartbeat == null) { + logger.info("Starting heartbeat job every {} min", HEARTBEAT_MINUTES); + heartbeat = this.scheduler.scheduleWithFixedDelay(this::sendHeartbeat, 0, HEARTBEAT_MINUTES, + TimeUnit.MINUTES); + } + } + } + + @Override + public Collection> getServices() { + return Collections.singleton(SomfyMyLinkDeviceDiscoveryService.class); + } + + private boolean validConfiguration(@Nullable SomfyMyLinkConfiguration config) { + if (config == null) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "mylink configuration missing"); + return false; + } + + if (config.ipAddress.isEmpty() || config.systemId.isEmpty()) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, + "mylink address or system id not specified"); + return false; + } + + return true; + } + + private void cancelHeartbeat() { + logger.debug("Stopping heartbeat"); + ScheduledFuture heartbeat = this.heartbeat; + + if (heartbeat != null) { + logger.debug("Cancelling heartbeat job"); + heartbeat.cancel(true); + this.heartbeat = null; + } else { + logger.debug("Heartbeat was not active"); + } + } + + private void sendHeartbeat() { + try { + logger.debug("Sending heartbeat"); + + SomfyMyLinkCommandShadePing command = new SomfyMyLinkCommandShadePing(config.systemId); + sendCommandWithResponse(command, SomfyMyLinkPingResponse.class).get(); + updateStatus(ThingStatus.ONLINE); + + } catch (SomfyMyLinkException | InterruptedException | ExecutionException e) { + logger.warn("Problem with mylink during heartbeat: {}", e.getMessage()); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage()); + } + } + + public SomfyMyLinkShade[] getShadeList() throws SomfyMyLinkException { + SomfyMyLinkCommandShadeList command = new SomfyMyLinkCommandShadeList(config.systemId); + + try { + SomfyMyLinkShadesResponse response = sendCommandWithResponse(command, SomfyMyLinkShadesResponse.class) + .get(); + + if (response != null) { + return response.getResult(); + } else { + return EMPTY_SHADE_LIST; + } + } catch (InterruptedException | ExecutionException e) { + throw new SomfyMyLinkException("Problem while getting shade list.", e); + } + } + + public SomfyMyLinkScene[] getSceneList() throws SomfyMyLinkException { + SomfyMyLinkCommandSceneList command = new SomfyMyLinkCommandSceneList(config.systemId); + SomfyMyLinkStateDescriptionOptionsProvider stateDescriptionProvider = this.stateDescriptionProvider; + + try { + SomfyMyLinkScenesResponse response = sendCommandWithResponse(command, SomfyMyLinkScenesResponse.class) + .get(); + + if (response != null && stateDescriptionProvider != null) { + List options = new ArrayList<>(); + for (SomfyMyLinkScene scene : response.result) { + options.add(new StateOption(scene.getTargetID(), scene.getName())); + } + + logger.debug("Setting {} options on bridge", options.size()); + + stateDescriptionProvider.setStateOptions( + new ChannelUID(getThing().getUID(), SomfyMyLinkBindingConstants.CHANNEL_SCENES), options); + + return response.getResult(); + } else { + return EMPTY_SCENE_LIST; + } + } catch (InterruptedException | ExecutionException e) { + throw new SomfyMyLinkException("Problem getting scene list.", e); + } + } + + public void commandShadeUp(String targetId) throws SomfyMyLinkException { + SomfyMyLinkCommandShadeUp cmd = new SomfyMyLinkCommandShadeUp(targetId, config.systemId); + sendCommand(cmd); + } + + public void commandShadeDown(String targetId) throws SomfyMyLinkException { + SomfyMyLinkCommandShadeDown cmd = new SomfyMyLinkCommandShadeDown(targetId, config.systemId); + sendCommand(cmd); + } + + public void commandShadeStop(String targetId) throws SomfyMyLinkException { + SomfyMyLinkCommandShadeStop cmd = new SomfyMyLinkCommandShadeStop(targetId, config.systemId); + sendCommand(cmd); + } + + public void commandScene(Integer sceneId) throws SomfyMyLinkException { + SomfyMyLinkCommandSceneSet cmd = new SomfyMyLinkCommandSceneSet(sceneId, config.systemId); + sendCommand(cmd); + } + + private CompletableFuture<@Nullable Void> sendCommand(SomfyMyLinkCommandBase command) { + CompletableFuture<@Nullable Void> future = new CompletableFuture<>(); + ExecutorService commandExecutor = this.commandExecutor; + if (commandExecutor != null) { + commandExecutor.execute(() -> { + String json = gson.toJson(command); + try (Socket socket = getConnection(); + Writer out = new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.US_ASCII)) { + logger.debug("Sending: {}", json); + out.write(json); + out.flush(); + logger.debug("Sent: {}", json); + + // give time for mylink to process + Thread.sleep(CONNECTION_DELAY); + } catch (SocketTimeoutException e) { + logger.warn("Timeout sending command to mylink: {} Message: {}", json, e.getMessage()); + } catch (IOException e) { + logger.warn("Problem sending command to mylink: {} Message: {}", json, e.getMessage()); + } catch (InterruptedException e) { + logger.warn("Interrupted while waiting after sending command to mylink: {} Message: {}", json, + e.getMessage()); + } catch (Exception e) { + logger.warn("Unexpected exception while sending command to mylink: {} Message: {}", json, + e.getMessage()); + } + future.complete(null); + }); + } else { + future.complete(null); + } + + return future; + } + + private CompletableFuture<@Nullable T> sendCommandWithResponse( + SomfyMyLinkCommandBase command, Class responseType) { + CompletableFuture<@Nullable T> future = new CompletableFuture<>(); + ExecutorService commandExecutor = this.commandExecutor; + if (commandExecutor != null) { + commandExecutor.submit(() -> { + String json = gson.toJson(command); + + try (Socket socket = getConnection(); + Writer out = new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.US_ASCII); + BufferedReader in = new BufferedReader( + new InputStreamReader(socket.getInputStream(), StandardCharsets.US_ASCII))) { + + // send the command + logger.debug("Sending: {}", json); + out.write(json); + out.flush(); + + // read the response + try { + T response = parseResponse(in, responseType); + future.complete(response); + Thread.sleep(CONNECTION_DELAY); + return; + } catch (SomfyMyLinkException e) { + future.completeExceptionally(e); + return; + } + } catch (SocketTimeoutException e) { + logger.warn("Timeout sending command to mylink: {} Message: {}", json, e.getMessage()); + future.completeExceptionally(new SomfyMyLinkException("Timeout sending command to mylink", e)); + } catch (IOException e) { + logger.warn("Problem sending command to mylink: {} Message: {}", json, e.getMessage()); + future.completeExceptionally(new SomfyMyLinkException("Problem sending command to mylink", e)); + } catch (InterruptedException e) { + logger.warn("Interrupted while waiting after sending command to mylink: {} Message: {}", json, + e.getMessage()); + future.complete(null); + } catch (Exception e) { + logger.warn("Unexpected exception while sending command to mylink: {} Message: {}", json, + e.getMessage()); + future.completeExceptionally(e); + } + }); + } else { + future.complete(null); + } + return future; + } + + private T parseResponse(Reader reader, Class responseType) { + JsonParser parser = new JsonParser(); + JsonObject jsonObj = parser.parse(gson.newJsonReader(reader)).getAsJsonObject(); + + logger.debug("Got full message: {}", jsonObj.toString()); + + if (jsonObj.has("error")) { + SomfyMyLinkErrorResponse errorResponse = gson.fromJson(jsonObj, SomfyMyLinkErrorResponse.class); + logger.info("Error parsing mylink response: {}", errorResponse.error.message); + throw new SomfyMyLinkException("Incomplete message."); + } + + return gson.fromJson(jsonObj, responseType); + } + + private Socket getConnection() throws IOException, SomfyMyLinkException { + try { + logger.debug("Getting connection to mylink on: {} Post: {}", config.ipAddress, MYLINK_PORT); + String myLinkAddress = config.ipAddress; + Socket socket = new Socket(myLinkAddress, MYLINK_PORT); + socket.setSoTimeout(MYLINK_DEFAULT_TIMEOUT); + return socket; + } catch (IOException e) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage()); + throw e; + } + } + + @Override + public void thingUpdated(Thing thing) { + SomfyMyLinkConfiguration newConfig = thing.getConfiguration().as(SomfyMyLinkConfiguration.class); + config = newConfig; + } + + @Override + public void dispose() { + cancelHeartbeat(); + dispose(commandExecutor); + } + + private static void dispose(@Nullable ExecutorService executor) { + if (executor != null) { + executor.shutdownNow(); + } + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/handler/SomfyMyLinkException.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/handler/SomfyMyLinkException.java new file mode 100644 index 0000000000000..374caf6125932 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/handler/SomfyMyLinkException.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.handler; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link SomfyMyLinkException} is for throwing errors from the mylink binding + * + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public SomfyMyLinkException() { + super(); + } + + public SomfyMyLinkException(String message) { + super(message); + } + + public SomfyMyLinkException(String message, Throwable cause) { + super(message, cause); + } + + public SomfyMyLinkException(Throwable cause) { + super(cause); + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/handler/SomfyMyLinkStateDescriptionOptionsProvider.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/handler/SomfyMyLinkStateDescriptionOptionsProvider.java new file mode 100644 index 0000000000000..df736baa7fe3d --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/handler/SomfyMyLinkStateDescriptionOptionsProvider.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.handler; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.core.thing.binding.BaseDynamicStateDescriptionProvider; +import org.eclipse.smarthome.core.thing.i18n.ChannelTypeI18nLocalizationService; +import org.eclipse.smarthome.core.thing.type.DynamicStateDescriptionProvider; +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 Gregory Moyer - Initial contribution + * @author Mark Hilbush - Adapted to squeezebox binding + */ +@Component(service = { DynamicStateDescriptionProvider.class, SomfyMyLinkStateDescriptionOptionsProvider.class }) +@NonNullByDefault +public class SomfyMyLinkStateDescriptionOptionsProvider extends BaseDynamicStateDescriptionProvider { + + @Reference + protected void setChannelTypeI18nLocalizationService( + final ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) { + this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService; + } + + protected void unsetChannelTypeI18nLocalizationService( + final ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) { + this.channelTypeI18nLocalizationService = null; + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/handler/SomfySceneHandler.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/handler/SomfySceneHandler.java new file mode 100644 index 0000000000000..d7f5716a64051 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/handler/SomfySceneHandler.java @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.handler; + +import static org.openhab.binding.somfymylink.internal.SomfyMyLinkBindingConstants.CHANNEL_SCENECONTROL; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.core.library.types.OnOffType; +import org.eclipse.smarthome.core.thing.Bridge; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.thing.Thing; +import org.eclipse.smarthome.core.thing.ThingStatus; +import org.eclipse.smarthome.core.thing.ThingStatusDetail; +import org.eclipse.smarthome.core.thing.binding.BaseThingHandler; +import org.eclipse.smarthome.core.thing.binding.BridgeHandler; +import org.eclipse.smarthome.core.types.Command; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link SomfySceneHandler} is responsible for handling commands for scenes + * + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfySceneHandler extends BaseThingHandler { + + private final Logger logger = LoggerFactory.getLogger(SomfySceneHandler.class); + + public SomfySceneHandler(Thing thing) { + super(thing); + } + + @Override + public void initialize() { + updateStatus(ThingStatus.ONLINE); + } + + @Override + public void handleCommand(ChannelUID channelUID, Command command) { + try { + if (CHANNEL_SCENECONTROL.equals(channelUID.getId()) && command instanceof OnOffType) { + Integer targetId = Integer.decode(channelUID.getThingUID().getId()); + + if (command.equals(OnOffType.ON)) { + getBridgeHandler().commandScene(targetId); + updateState(channelUID, OnOffType.OFF); + } + } + } catch (SomfyMyLinkException e) { + logger.warn("Error handling command: {}", e.getMessage()); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage()); + } + } + + protected SomfyMyLinkBridgeHandler getBridgeHandler() { + Bridge bridge = this.getBridge(); + if (bridge == null) { + throw new SomfyMyLinkException("No bridge was found"); + } + + BridgeHandler handler = bridge.getHandler(); + if (handler == null) { + throw new SomfyMyLinkException("No handler was found"); + } + + return (SomfyMyLinkBridgeHandler) handler; + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/handler/SomfyShadeHandler.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/handler/SomfyShadeHandler.java new file mode 100644 index 0000000000000..62c5a664e40fb --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/handler/SomfyShadeHandler.java @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.handler; + +import static org.openhab.binding.somfymylink.internal.SomfyMyLinkBindingConstants.CHANNEL_SHADELEVEL; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.core.library.types.StopMoveType; +import org.eclipse.smarthome.core.library.types.UpDownType; +import org.eclipse.smarthome.core.thing.Bridge; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.thing.Thing; +import org.eclipse.smarthome.core.thing.ThingStatus; +import org.eclipse.smarthome.core.thing.ThingStatusDetail; +import org.eclipse.smarthome.core.thing.ThingStatusInfo; +import org.eclipse.smarthome.core.thing.binding.BaseThingHandler; +import org.eclipse.smarthome.core.thing.binding.BridgeHandler; +import org.eclipse.smarthome.core.types.Command; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link SomfyShadeHandler} is responsible for handling commands for shades + * + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyShadeHandler extends BaseThingHandler { + + private final Logger logger = LoggerFactory.getLogger(SomfyShadeHandler.class); + + public SomfyShadeHandler(Thing thing) { + super(thing); + } + + @Override + public void initialize() { + initDeviceState(); + } + + @Override + public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) { + logger.info("Bridge status changed to {} updating {}", bridgeStatusInfo.getStatus(), getThing().getLabel()); + + if (bridgeStatusInfo.getStatus() == ThingStatus.ONLINE + && getThing().getStatusInfo().getStatusDetail() == ThingStatusDetail.BRIDGE_OFFLINE) { + initDeviceState(); + } else if (bridgeStatusInfo.getStatus() == ThingStatus.OFFLINE) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE); + } + } + + public void initDeviceState() { + Bridge bridge = getBridge(); + + if (bridge == null) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "No bridge configured"); + logger.debug("Initialized device state for shade {} {}", ThingStatus.OFFLINE, + ThingStatusDetail.CONFIGURATION_ERROR); + } else if (bridge.getStatus() == ThingStatus.ONLINE) { + updateStatus(ThingStatus.ONLINE); + logger.debug("Initialized device state for shade {}", ThingStatus.ONLINE); + } else { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE); + logger.debug("Initialized device state for shade {} {}", ThingStatus.OFFLINE, + ThingStatusDetail.BRIDGE_OFFLINE); + } + } + + @Override + public void handleCommand(ChannelUID channelUID, Command command) { + try { + if (CHANNEL_SHADELEVEL.equals(channelUID.getId())) { + String targetId = channelUID.getThingUID().getId(); + + if (command instanceof UpDownType) { + if (command.equals(UpDownType.DOWN)) { + getBridgeHandler().commandShadeDown(targetId); + } else { + getBridgeHandler().commandShadeUp(targetId); + } + } + + if (command instanceof StopMoveType) { + getBridgeHandler().commandShadeStop(targetId); + } + } + } catch (SomfyMyLinkException e) { + logger.warn("Error handling command: {}", e.getMessage()); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage()); + } + } + + protected SomfyMyLinkBridgeHandler getBridgeHandler() { + Bridge bridge = this.getBridge(); + if (bridge == null) { + throw new SomfyMyLinkException("No bridge was found"); + } + + BridgeHandler handler = bridge.getHandler(); + if (handler == null) { + throw new SomfyMyLinkException("No handler was found"); + } + + return (SomfyMyLinkBridgeHandler) handler; + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandBase.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandBase.java new file mode 100644 index 0000000000000..1c6c8d138b887 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandBase.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import java.util.concurrent.ThreadLocalRandom; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkCommandBase { + + public final int id; + + public SomfyMyLinkCommandBase() { + this.id = ThreadLocalRandom.current().nextInt(1, 1000); + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandParamsBase.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandParamsBase.java new file mode 100644 index 0000000000000..31f45ba4ee0bb --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandParamsBase.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkCommandParamsBase { + + public final String auth; + + public SomfyMyLinkCommandParamsBase(String auth) { + this.auth = auth; + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandSceneBase.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandSceneBase.java new file mode 100644 index 0000000000000..14a4b70b83be7 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandSceneBase.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkCommandSceneBase extends SomfyMyLinkCommandBase { + + public final String method; + public final SomfyMyLinkCommandSceneParams params; + + public SomfyMyLinkCommandSceneBase(int sceneId, String method, String auth) { + this.method = method; + this.params = new SomfyMyLinkCommandSceneParams(sceneId, auth); + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandSceneList.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandSceneList.java new file mode 100644 index 0000000000000..2c9fd70051765 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandSceneList.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkCommandSceneList extends SomfyMyLinkCommandShadeBase { + public SomfyMyLinkCommandSceneList(String auth) { + super("*.*", "mylink.scene.list", auth); + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandSceneParams.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandSceneParams.java new file mode 100644 index 0000000000000..f8e346a2d529b --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandSceneParams.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkCommandSceneParams extends SomfyMyLinkCommandParamsBase { + + public final int sceneId; + + public SomfyMyLinkCommandSceneParams(int sceneId, String auth) { + super(auth); + this.sceneId = sceneId; + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandSceneSet.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandSceneSet.java new file mode 100644 index 0000000000000..816e89d91d0fd --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandSceneSet.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkCommandSceneSet extends SomfyMyLinkCommandSceneBase { + public SomfyMyLinkCommandSceneSet(int sceneId, String auth) { + super(sceneId, "mylink.scene.run", auth); + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeBase.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeBase.java new file mode 100644 index 0000000000000..69afe9700ac0d --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeBase.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkCommandShadeBase extends SomfyMyLinkCommandBase { + + public final String method; + public final SomfyMyLinkCommandShadeParams params; + + public SomfyMyLinkCommandShadeBase(String targetId, String method, String auth) { + this.method = method; + this.params = new SomfyMyLinkCommandShadeParams(targetId, auth); + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeDown.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeDown.java new file mode 100644 index 0000000000000..61d64d0f73632 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeDown.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkCommandShadeDown extends SomfyMyLinkCommandShadeBase { + + public SomfyMyLinkCommandShadeDown(String targetId, String auth) { + super(targetId, "mylink.move.down", auth); + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeList.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeList.java new file mode 100644 index 0000000000000..951d4b855f9bd --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeList.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkCommandShadeList extends SomfyMyLinkCommandShadeBase { + + public SomfyMyLinkCommandShadeList(String auth) { + super("*.*", "mylink.status.info", auth); + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeParams.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeParams.java new file mode 100644 index 0000000000000..27719cc321c53 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeParams.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkCommandShadeParams extends SomfyMyLinkCommandParamsBase { + + public final String targetId; + + public SomfyMyLinkCommandShadeParams(String targetId, String auth) { + super(auth); + this.targetId = targetId.replace('-', '.'); + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadePing.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadePing.java new file mode 100644 index 0000000000000..723fa65ca2df0 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadePing.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkCommandShadePing extends SomfyMyLinkCommandShadeBase { + + public SomfyMyLinkCommandShadePing(String auth) { + super("*.*", "mylink.status.ping", auth); + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeStop.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeStop.java new file mode 100644 index 0000000000000..d493b2658b17d --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeStop.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkCommandShadeStop extends SomfyMyLinkCommandShadeBase { + + public SomfyMyLinkCommandShadeStop(String targetId, String auth) { + super(targetId, "mylink.move.stop", auth); + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeUp.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeUp.java new file mode 100644 index 0000000000000..9c45876280d51 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkCommandShadeUp.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkCommandShadeUp extends SomfyMyLinkCommandShadeBase { + + public SomfyMyLinkCommandShadeUp(String targetId, String auth) { + super(targetId, "mylink.move.up", auth); + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkError.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkError.java new file mode 100644 index 0000000000000..8e02254cbcaef --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkError.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkError { + + public String code = ""; + + public String message = ""; +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkErrorResponse.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkErrorResponse.java new file mode 100644 index 0000000000000..eed7ece48776b --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkErrorResponse.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkErrorResponse extends SomfyMyLinkResponseBase { + + public SomfyMyLinkError error = new SomfyMyLinkError(); + + public @Nullable SomfyMyLinkError getError() { + return error; + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkPingResponse.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkPingResponse.java new file mode 100644 index 0000000000000..5f27584417110 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkPingResponse.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkPingResponse extends SomfyMyLinkResponseBase { + + public String[] result = new String[0]; + + public String[] getResult() { + return result; + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkResponseBase.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkResponseBase.java new file mode 100644 index 0000000000000..77e4e1033c13e --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkResponseBase.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkResponseBase { + + public @Nullable String jsonrpc; + + public @Nullable String id; + + public @Nullable String getId() { + return id; + } + + public @Nullable String getJsonRpc() { + return jsonrpc; + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkScene.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkScene.java new file mode 100644 index 0000000000000..9b8810df9c046 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkScene.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkScene { + + private String sceneID = ""; + + private String name = ""; + + public String getTargetID() { + return sceneID; + } + + public String getName() { + return name; + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkScenesResponse.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkScenesResponse.java new file mode 100644 index 0000000000000..aa716d6f2729d --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkScenesResponse.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkScenesResponse extends SomfyMyLinkResponseBase { + + public SomfyMyLinkScene[] result = new SomfyMyLinkScene[0]; + + public SomfyMyLinkScene[] getResult() { + return result; + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkShade.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkShade.java new file mode 100644 index 0000000000000..f779faa52ec1f --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkShade.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkShade { + + private @Nullable String targetID; + + private @Nullable String name; + + public @Nullable String getTargetID() { + String targetID = this.targetID; + return targetID != null ? targetID.replace('.', '-') : null; + } + + public @Nullable String getName() { + return name; + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkShadesResponse.java b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkShadesResponse.java new file mode 100644 index 0000000000000..4d62c60a5d241 --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/java/org/openhab/binding/somfymylink/internal/model/SomfyMyLinkShadesResponse.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2010-2020 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.somfymylink.internal.model; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Chris Johnson - Initial contribution + */ +@NonNullByDefault +public class SomfyMyLinkShadesResponse extends SomfyMyLinkResponseBase { + + public SomfyMyLinkShade[] result = new SomfyMyLinkShade[0]; + + public SomfyMyLinkShade[] getResult() { + return result; + } +} diff --git a/bundles/org.openhab.binding.somfymylink/src/main/resources/ESH-INF/binding/binding.xml b/bundles/org.openhab.binding.somfymylink/src/main/resources/ESH-INF/binding/binding.xml new file mode 100644 index 0000000000000..32c5789abcf6e --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/resources/ESH-INF/binding/binding.xml @@ -0,0 +1,10 @@ + + + + Somfy MyLink Binding + This is the binding for Somfy MyLink. + Chris Johnson + + diff --git a/bundles/org.openhab.binding.somfymylink/src/main/resources/ESH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.somfymylink/src/main/resources/ESH-INF/thing/thing-types.xml new file mode 100644 index 0000000000000..6145de863201c --- /dev/null +++ b/bundles/org.openhab.binding.somfymylink/src/main/resources/ESH-INF/thing/thing-types.xml @@ -0,0 +1,85 @@ + + + + + + + Somfy MyLink bridge enabling communication with Somfy devices + + + + + + network-address + + The IP or hostname of the Somfy MyLink + + + + The system id of the My Link bridge. This can be found in the integration settings on your My Link app + + + + + + + + + + + Scene control + + + + + + + + Address of scene in the Somfy system + + + + + + + + + + + Controls shades + + + + + + + + Address of shade in the Somfy system + + + + + + String + + Comma-separated list of scenes of form sceneId=sceneName + + + + + Rollershutter + + Device control (UP, DOWN, MY/STOP, closure 0-100%) + + + + Switch + + Button to trigger a scene or rule + Switch + + + diff --git a/bundles/pom.xml b/bundles/pom.xml index 132ec52fca9f6..7576a2dd599af 100644 --- a/bundles/pom.xml +++ b/bundles/pom.xml @@ -215,6 +215,7 @@ org.openhab.binding.snmp org.openhab.binding.solaredge org.openhab.binding.solarlog + org.openhab.binding.somfymylink org.openhab.binding.somfytahoma org.openhab.binding.sonos org.openhab.binding.sonyaudio