added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
49
bundles/org.openhab.binding.somfymylink/.classpath
Normal file
49
bundles/org.openhab.binding.somfymylink/.classpath
Normal file
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="target/generated-sources/annotations">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="ignore_optional_problems" value="true"/>
|
||||
<attribute name="m2e-apt" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="ignore_optional_problems" value="true"/>
|
||||
<attribute name="m2e-apt" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
23
bundles/org.openhab.binding.somfymylink/.project
Normal file
23
bundles/org.openhab.binding.somfymylink/.project
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.openhab.binding.somfymylink</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
13
bundles/org.openhab.binding.somfymylink/NOTICE
Normal file
13
bundles/org.openhab.binding.somfymylink/NOTICE
Normal file
@@ -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
|
||||
65
bundles/org.openhab.binding.somfymylink/README.md
Normal file
65
bundles/org.openhab.binding.somfymylink/README.md
Normal file
@@ -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" ]
|
||||
}
|
||||
```
|
||||
17
bundles/org.openhab.binding.somfymylink/pom.xml
Normal file
17
bundles/org.openhab.binding.somfymylink/pom.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.binding.somfymylink</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Bundles :: Somfy MyLink Binding</name>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.somfymylink-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-binding-somfymylink" description="Somfy MyLink Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.somfymylink/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -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.openhab.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";
|
||||
}
|
||||
@@ -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.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.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
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<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = new HashSet<>(
|
||||
Arrays.asList(THING_TYPE_MYLINK, THING_TYPE_SHADE, THING_TYPE_SCENE));
|
||||
|
||||
public static final Set<ThingTypeUID> 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;
|
||||
}
|
||||
}
|
||||
@@ -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 = "";
|
||||
}
|
||||
@@ -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.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.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.config.discovery.DiscoveryService;
|
||||
import org.openhab.core.config.discovery.ScanListener;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||
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<String, Object> 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);
|
||||
}
|
||||
}
|
||||
@@ -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.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.openhab.core.common.NamedThreadFactory;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseBridgeHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.StateOption;
|
||||
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<Class<? extends ThingHandlerService>> 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<StateOption> 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 <T extends SomfyMyLinkResponseBase> CompletableFuture<@Nullable T> sendCommandWithResponse(
|
||||
SomfyMyLinkCommandBase command, Class<T> 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 extends SomfyMyLinkResponseBase> T parseResponse(Reader reader, Class<T> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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.openhab.core.thing.binding.BaseDynamicStateDescriptionProvider;
|
||||
import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService;
|
||||
import org.openhab.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;
|
||||
}
|
||||
}
|
||||
@@ -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.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.binding.BridgeHandler;
|
||||
import org.openhab.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;
|
||||
}
|
||||
}
|
||||
@@ -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.openhab.core.library.types.StopMoveType;
|
||||
import org.openhab.core.library.types.UpDownType;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingStatusInfo;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.binding.BridgeHandler;
|
||||
import org.openhab.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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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('-', '.');
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 = "";
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="somfymylink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||
|
||||
<name>Somfy MyLink Binding</name>
|
||||
<description>This is the binding for Somfy MyLink.</description>
|
||||
<author>Chris Johnson</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="somfymylink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<!-- Bridge -->
|
||||
<bridge-type id="mylink">
|
||||
<label>Somfy MyLink</label>
|
||||
<description>Somfy MyLink bridge enabling communication with Somfy devices</description>
|
||||
<channels>
|
||||
<channel id="sceneid" typeId="scenelist"/>
|
||||
</channels>
|
||||
<config-description>
|
||||
<parameter name="ipAddress" type="text" required="true">
|
||||
<context>network-address</context>
|
||||
<label>IP or Hostname</label>
|
||||
<description>The IP or hostname of the Somfy MyLink</description>
|
||||
</parameter>
|
||||
<parameter name="systemId" type="text">
|
||||
<label>System Id</label>
|
||||
<description>The system id of the My Link bridge. This can be found in the integration settings on your My Link app</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</bridge-type>
|
||||
|
||||
<!-- Scene Type -->
|
||||
<thing-type id="scene">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="mylink"/>
|
||||
</supported-bridge-type-refs>
|
||||
<label>Somfy Scene</label>
|
||||
<description>Scene control</description>
|
||||
<channels>
|
||||
<channel id="scenecontrol" typeId="button"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="sceneId" type="text" required="true">
|
||||
<label>Scene ID</label>
|
||||
<description>Address of scene in the Somfy system</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
<!-- Shade Type -->
|
||||
<thing-type id="shade">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="mylink"/>
|
||||
</supported-bridge-type-refs>
|
||||
<label>Somfy Shade</label>
|
||||
<description>Controls shades</description>
|
||||
<channels>
|
||||
<channel id="shadelevel" typeId="shadeControl"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="targetId" type="text" required="true">
|
||||
<label>Target ID</label>
|
||||
<description>Address of shade in the Somfy system</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
<channel-type id="scenelist">
|
||||
<item-type>String</item-type>
|
||||
<label>Scene List</label>
|
||||
<description>Comma-separated list of scenes of form sceneId=sceneName</description>
|
||||
<state pattern="%s"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="shadeControl">
|
||||
<item-type>Rollershutter</item-type>
|
||||
<label>Control</label>
|
||||
<description>Device control (UP, DOWN, MY/STOP, closure 0-100%)</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="button">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Scene button</label>
|
||||
<description>Button to trigger a scene or rule</description>
|
||||
<category>Switch</category>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
Reference in New Issue
Block a user