]> git.basschouten.com Git - openhab-addons.git/commitdiff
[myStrom] Added Motionsensor and API Token (#13201)
authorPumpur <stefan@navratil.ch>
Tue, 9 Aug 2022 14:03:29 +0000 (16:03 +0200)
committerGitHub <noreply@github.com>
Tue, 9 Aug 2022 14:03:29 +0000 (16:03 +0200)
* Added API Token to configuration.
* Added motionsensor to myStrom binding.
* Added SPDX Header.
* fix: removed unnecessary updateStatus().

Signed-off-by: Stefan Navratil <stefan@navratil.ch>
bundles/org.openhab.binding.mystrom/README.md
bundles/org.openhab.binding.mystrom/src/main/java/org/openhab/binding/mystrom/internal/AbstractMyStromHandler.java
bundles/org.openhab.binding.mystrom/src/main/java/org/openhab/binding/mystrom/internal/MyStromBindingConstants.java
bundles/org.openhab.binding.mystrom/src/main/java/org/openhab/binding/mystrom/internal/MyStromConfiguration.java
bundles/org.openhab.binding.mystrom/src/main/java/org/openhab/binding/mystrom/internal/MyStromHandlerFactory.java
bundles/org.openhab.binding.mystrom/src/main/java/org/openhab/binding/mystrom/internal/MyStromPIRHandler.java [new file with mode: 0644]
bundles/org.openhab.binding.mystrom/src/main/resources/OH-INF/i18n/mystrom.properties
bundles/org.openhab.binding.mystrom/src/main/resources/OH-INF/thing/thing-types.xml

index a0389947e8f20b8e26fcbfd7d290fc772a6d9160..57ecf5c87d65bd290d197b83c0fdf40ee56e7258 100644 (file)
@@ -1,15 +1,17 @@
 # myStrom Binding
 
-This extension adds support for the myStrom devices. Currently only the smart plug is implemented.
+This extension adds support for the myStrom devices.
+As of today only the Smart Plug, Bulb and the Motionsensor are implemented.
 
 ## Supported Things
 
 This bundle adds the following thing types:
 
-| Thing              | ThingTypeID | Description                                        |
-| ------------------ | ----------- | -------------------------------------------------- |
-| myStrom Smart Plug | mystromplug | A myStrom smart plug                               |
-| myStrom Bulb       | mystrombulb | A myStrom bulb                                     |
+| Thing                 | ThingTypeID | Description                                        |
+| ----------------------| ----------- | -------------------------------------------------- |
+| myStrom Smart Plug    | mystromplug | A myStrom smart plug                               |
+| myStrom Bulb          | mystrombulb | A myStrom bulb                                     |
+| myStrom Motion Sensor | mystrompir  | A myStrom bulb                                     |
 
 According to the myStrom API documentation all request specific to the myStrom Bulb are also work on the LED strip.
 
@@ -26,6 +28,7 @@ The following parameters are valid for all thing types:
 | --------- | ------- | -------- | ------------------ | -------------------------------------------------------------------------- |
 | hostname  | string  | yes      | localhost          | The IP address or hostname of the myStrom smart plug                       |
 | refresh   | integer | no       | 10                 | Poll interval in seconds. Increase this if you encounter connection errors |
+| apiToken  | string  | no       |                    | Specifies the API Token, if required.                                      |
 
 ## Properties
 
@@ -52,12 +55,14 @@ Disabling/enabling the thing can be used to update the properties.
 | ---------------- | -------------------- | --------- | --------------------------------------------------------------------- |-------------------------------------|
 | switch           | Switch               | false     | Turn the device on or off                                             | mystromplug, mystrombulb            |
 | power            | Number:Power         | true      | The currently delivered power                                         | mystromplug, mystrombulb            |
-| temperature      | Number:Temperature   | true      | The temperature at the plug                                           | mystromplug                         |
+| temperature      | Number:Temperature   | true      | The temperature at the plug                                           | mystromplug, mystrompir             |
 | color            | Color                | false     | The color we set the bulb to (mode 'hsv')                             | mystrombulb                         |
 | colorTemperature | Dimmer               | false     | The color temperature of the bulb in mode 'mono' (percentage)         | mystrombulb                         |
 | brightness       | Dimmer               | false     | The brightness of the bulb in mode 'mono'                             | mystrombulb                         |
 | ramp             | Number:Time          | false     | Transition time from the light’s current state to the new state. [ms] | mystrombulb                         |
 | mode             | String               | false     | The color mode we want the Bulb to set to (rgb, hsv or mono)          | mystrombulb                         |
+| light            | Dimmer               | true      | The brightness of the Room.                                           | mystrompir                          |
+| motion           | Switch               | true      | Motionstatus of the sensor                                            | mystrompir                          |
 
 ## Full Example
 
index 78186f24c2b26e87c9062384594d8aff05cb67b8..cdca5d2dc2771013c1bf936ae8485cd9014f06bb 100644 (file)
  */
 package org.openhab.binding.mystrom.internal;
 
-import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.PROPERTY_CONNECTED;
-import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.PROPERTY_DNS;
-import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.PROPERTY_GW;
-import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.PROPERTY_IP;
-import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.PROPERTY_LAST_REFRESH;
-import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.PROPERTY_MAC;
-import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.PROPERTY_MASK;
-import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.PROPERTY_SSID;
-import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.PROPERTY_STATIC;
-import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.PROPERTY_TYPE;
-import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.PROPERTY_VERSION;
+import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.*;
 
 import java.text.DateFormat;
 import java.util.Calendar;
@@ -61,10 +51,9 @@ import com.google.gson.JsonSyntaxException;
 @NonNullByDefault
 public abstract class AbstractMyStromHandler extends BaseThingHandler {
     protected static final String COMMUNICATION_ERROR = "Error while communicating to the myStrom plug: ";
-    protected static final String HTTP_REQUEST_URL_PREFIX = "http://";
+    protected MyStromConfiguration config;
 
     protected final HttpClient httpClient;
-    protected String hostname = "";
     protected String mac = "";
 
     private final Logger logger = LoggerFactory.getLogger(AbstractMyStromHandler.class);
@@ -73,14 +62,13 @@ public abstract class AbstractMyStromHandler extends BaseThingHandler {
 
     public AbstractMyStromHandler(Thing thing, HttpClient httpClient) {
         super(thing);
+        config = getConfigAs(MyStromConfiguration.class);
         this.httpClient = httpClient;
     }
 
     @Override
     public final void initialize() {
-        MyStromConfiguration config = getConfigAs(MyStromConfiguration.class);
-        this.hostname = HTTP_REQUEST_URL_PREFIX + config.hostname;
-
+        config = getConfigAs(MyStromConfiguration.class);
         updateStatus(ThingStatus.UNKNOWN);
         scheduler.schedule(this::initializeInternal, 0, TimeUnit.SECONDS);
     }
@@ -135,9 +123,12 @@ public abstract class AbstractMyStromHandler extends BaseThingHandler {
      */
     protected final String sendHttpRequest(HttpMethod method, String path, @Nullable String requestData)
             throws MyStromException {
-        String url = hostname + path;
+        String url = config.getHostname() + path;
         try {
             Request request = httpClient.newRequest(url).timeout(10, TimeUnit.SECONDS).method(method);
+            if (!config.getApiToken().isEmpty()) {
+                request.getHeaders().add("Token", config.getApiToken());
+            }
             if (requestData != null) {
                 request = request.content(new StringContentProvider(requestData)).header(HttpHeader.CONTENT_TYPE,
                         "application/x-www-form-urlencoded");
@@ -157,9 +148,7 @@ public abstract class AbstractMyStromHandler extends BaseThingHandler {
         try {
             updateProperties();
             checkRequiredInfo();
-            updateStatus(ThingStatus.ONLINE);
-            MyStromConfiguration config = getConfigAs(MyStromConfiguration.class);
-            pollingJob = scheduler.scheduleWithFixedDelay(this::pollDevice, 0, config.refresh, TimeUnit.SECONDS);
+            pollingJob = scheduler.scheduleWithFixedDelay(this::pollDevice, 0, config.getRefresh(), TimeUnit.SECONDS);
         } catch (MyStromException e) {
             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
         }
index d76daad88efb11714c7c5279e8f3598328d587a3..9954caaafc7c2b6616b155202006a43493bf1d28 100644 (file)
@@ -26,12 +26,14 @@ import org.openhab.core.thing.ThingTypeUID;
 public class MyStromBindingConstants {
 
     public static final int DEFAULT_REFRESH_RATE_SECONDS = 10;
+    public static final int DEFAULT_BACKOFF_TIME_SECONDS = 10;
 
     private static final String BINDING_ID = "mystrom";
 
     // List of all Thing Type UIDs
     public static final ThingTypeUID THING_TYPE_PLUG = new ThingTypeUID(BINDING_ID, "mystromplug");
     public static final ThingTypeUID THING_TYPE_BULB = new ThingTypeUID(BINDING_ID, "mystrombulb");
+    public static final ThingTypeUID THING_TYPE_PIR = new ThingTypeUID(BINDING_ID, "mystrompir");
 
     // List of all Channel ids
     public static final String CHANNEL_SWITCH = "switch";
@@ -42,6 +44,8 @@ public class MyStromBindingConstants {
     public static final String CHANNEL_MODE = "mode";
     public static final String CHANNEL_COLOR_TEMPERATURE = "colorTemperature";
     public static final String CHANNEL_BRIGHTNESS = "brightness";
+    public static final String CHANNEL_MOTION = "motion";
+    public static final String CHANNEL_LIGHT = "light";
 
     // Config
     public static final String CONFIG_MAC = "mac";
index 3a7d7632ca0a879b2b826891c6945c2b2568b9fe..19a15ce34febc14a90c85a45d409162a87c19fbb 100644 (file)
@@ -12,7 +12,7 @@
  */
 package org.openhab.binding.mystrom.internal;
 
-import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.DEFAULT_REFRESH_RATE_SECONDS;
+import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.*;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 
@@ -20,16 +20,69 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
  * The {@link MyStromConfiguration} class contains fields mapping thing configuration parameters.
  *
  * @author Paul Frank - Initial contribution
+ * @author Stefan Navratil - Added configuration for myStrom PIR
  */
 @NonNullByDefault
 public class MyStromConfiguration {
 
+    private final String urlPrefix = "http://";
+
+    private String hostname = "localhost";
+
+    private String apiToken = "";
+
+    private int refresh = DEFAULT_REFRESH_RATE_SECONDS;
+
+    private int backoffTime = DEFAULT_BACKOFF_TIME_SECONDS;
+
+    private boolean ledEnable = true;
+
+    /**
+     * Returns the hostname with http prefix if missing.
+     *
+     * @return hostname
+     */
+    public String getHostname() {
+        String prefix = "";
+        if (!this.hostname.contains(urlPrefix)) {
+            prefix = urlPrefix;
+        }
+        return prefix + this.hostname;
+    }
+
+    /**
+     * returns API Token
+     *
+     * @return apiToken
+     */
+    public String getApiToken() {
+        return apiToken;
+    }
+
     /**
-     * Hostname of the myStrom device.
+     * Returns the refreshrate in SECONDS.
+     *
+     * @return refresh
      */
-    public String hostname = "localhost";
+    public int getRefresh() {
+        return refresh;
+    }
+
+    /**
+     * Returns the Backoff time of the MotionSensor in SECONDS.
+     *
+     * @return backoff_time
+     */
+    public int getBackoffTime() {
+        return backoffTime;
+    }
+
     /**
-     * Number of seconds in between refreshes from the myStrom device.
+     * Returns the Status LED Configuration.
+     *
+     * @return led_enable
      */
-    public int refresh = DEFAULT_REFRESH_RATE_SECONDS;
+    public boolean getLedEnable() {
+        return ledEnable;
+    }
 }
index eb8955ffea9e07afb46821c213ea702d487e7471..ce32a5713db7f89bba9d38a2e01913680a632476 100644 (file)
@@ -12,8 +12,7 @@
  */
 package org.openhab.binding.mystrom.internal;
 
-import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.THING_TYPE_BULB;
-import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.THING_TYPE_PLUG;
+import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.*;
 
 import java.util.Set;
 
@@ -40,7 +39,8 @@ import org.osgi.service.component.annotations.Reference;
 @Component(configurationPid = "binding.mystrom", service = ThingHandlerFactory.class)
 public class MyStromHandlerFactory extends BaseThingHandlerFactory {
 
-    private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_PLUG, THING_TYPE_BULB);
+    private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_PLUG, THING_TYPE_BULB,
+            THING_TYPE_PIR);
 
     private final HttpClientFactory httpClientFactory;
 
@@ -62,6 +62,8 @@ public class MyStromHandlerFactory extends BaseThingHandlerFactory {
             return new MyStromPlugHandler(thing, httpClientFactory.getCommonHttpClient());
         } else if (THING_TYPE_BULB.equals(thingTypeUID)) {
             return new MyStromBulbHandler(thing, httpClientFactory.getCommonHttpClient());
+        } else if (THING_TYPE_PIR.equals(thingTypeUID)) {
+            return new MyStromPIRHandler(thing, httpClientFactory.getCommonHttpClient());
         }
 
         return null;
diff --git a/bundles/org.openhab.binding.mystrom/src/main/java/org/openhab/binding/mystrom/internal/MyStromPIRHandler.java b/bundles/org.openhab.binding.mystrom/src/main/java/org/openhab/binding/mystrom/internal/MyStromPIRHandler.java
new file mode 100644 (file)
index 0000000..16da560
--- /dev/null
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2010-2022 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.mystrom.internal;
+
+import static org.openhab.binding.mystrom.internal.MyStromBindingConstants.*;
+import static org.openhab.core.library.unit.SIUnits.CELSIUS;
+import static org.openhab.core.library.unit.Units.PERCENT;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.http.HttpMethod;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
+import org.openhab.core.types.Command;
+
+import com.google.gson.JsonParseException;
+
+/**
+ *
+ * @author Stefan Navratil - Initial Contribution
+ *
+ */
+
+@NonNullByDefault
+public class MyStromPIRHandler extends AbstractMyStromHandler {
+
+    private static class MyStromReport {
+
+        public float light;
+        public boolean motion;
+        public float temperature;
+    }
+
+    public MyStromPIRHandler(Thing thing, HttpClient httpClient) {
+        super(thing, httpClient);
+        try {
+            sendHttpRequest(HttpMethod.POST, "/api/v1/settings/pir",
+                    "{\"backoff_time\":" + config.getBackoffTime() + ",\"led_enable\":" + config.getLedEnable() + "}");
+        } catch (MyStromException e) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
+        }
+    }
+
+    @Override
+    public void handleCommand(ChannelUID channelUID, Command command) {
+    }
+
+    @Override
+    protected void pollDevice() {
+        MyStromReport report = getReport();
+        if (report != null) {
+            updateState(CHANNEL_MOTION, OnOffType.from(report.motion));
+            updateState(CHANNEL_TEMPERATURE, QuantityType.valueOf(report.temperature, CELSIUS));
+            // The Default Light thresholds are from 30 to 300.
+            updateState(CHANNEL_LIGHT, QuantityType.valueOf(report.light / 3, PERCENT));
+        }
+    }
+
+    private @Nullable MyStromReport getReport() {
+        try {
+            String json = sendHttpRequest(HttpMethod.GET, "/api/v1/sensors", null);
+            MyStromReport report = gson.fromJson(json, MyStromReport.class);
+            updateStatus(ThingStatus.ONLINE);
+            return report;
+        } catch (MyStromException | JsonParseException e) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
+            return null;
+        }
+    }
+}
index 23f72e7cb1ca436891a6bdad7e8ab4e24377864b..b5c44019da87bd17964802fda9fd020da29146c5 100644 (file)
@@ -7,17 +7,32 @@ binding.mystrom.description = This is the binding for myStrom devices.
 
 thing-type.mystrom.mystrombulb.label = myStrom Bulb
 thing-type.mystrom.mystrombulb.description = Controls the myStrom bulb
+thing-type.mystrom.mystrompir.label = myStrom Motion Sensor
 thing-type.mystrom.mystromplug.label = myStrom Smart Plug
 thing-type.mystrom.mystromplug.description = Controls the myStrom smart plug
 
 # thing types config
 
+thing-type.config.mystrom.mystrombulb.apiToken.label = API Token
+thing-type.config.mystrom.mystrombulb.apiToken.description = Specifies the API token, if required (optional).
 thing-type.config.mystrom.mystrombulb.hostname.label = Hostname
-thing-type.config.mystrom.mystrombulb.hostname.description = The host name or IP address of the myStrom bulb.
+thing-type.config.mystrom.mystrombulb.hostname.description = The hostname or IP address of the myStrom bulb.
 thing-type.config.mystrom.mystrombulb.refresh.label = Refresh Interval
 thing-type.config.mystrom.mystrombulb.refresh.description = Specifies the refresh interval in seconds.
+thing-type.config.mystrom.mystrompir.apiToken.label = API Token
+thing-type.config.mystrom.mystrompir.apiToken.description = Specifies the API token, if required (optional).
+thing-type.config.mystrom.mystrompir.backoffTime.label = Backoff Time
+thing-type.config.mystrom.mystrompir.backoffTime.description = Specifies the minimum frequency between successive motion detections in seconds.
+thing-type.config.mystrom.mystrompir.hostname.label = Hostname
+thing-type.config.mystrom.mystrompir.hostname.description = The hostname or IP address of the myStrom sensor.
+thing-type.config.mystrom.mystrompir.ledEnable.label = LED Enabled
+thing-type.config.mystrom.mystrompir.ledEnable.description = Enables the status LED on the device.
+thing-type.config.mystrom.mystrompir.refresh.label = Refresh Interval
+thing-type.config.mystrom.mystrompir.refresh.description = Specifies the refresh interval in seconds.
+thing-type.config.mystrom.mystromplug.apiToken.label = API Token
+thing-type.config.mystrom.mystromplug.apiToken.description = Specifies the API token, if required (optional).
 thing-type.config.mystrom.mystromplug.hostname.label = Hostname
-thing-type.config.mystrom.mystromplug.hostname.description = The host name or IP address of the myStrom plug.
+thing-type.config.mystrom.mystromplug.hostname.description = The hostname or IP address of the myStrom plug.
 thing-type.config.mystrom.mystromplug.refresh.label = Refresh Interval
 thing-type.config.mystrom.mystromplug.refresh.description = Specifies the refresh interval in seconds.
 
index b60710d94d18811ae06c81ee506f977270b0a0c2..92998051f2e7ec892972f88ce17090f2f40293a4 100644 (file)
@@ -32,7 +32,7 @@
                <config-description>
                        <parameter name="hostname" type="text">
                                <label>Hostname</label>
-                               <description>The host name or IP address of the myStrom plug.</description>
+                               <description>The hostname or IP address of the myStrom plug.</description>
                                <context>network-address</context>
                                <default>localhost</default>
                        </parameter>
                                <description>Specifies the refresh interval in seconds.</description>
                                <default>10</default>
                        </parameter>
+                       <parameter name="apiToken" type="text">
+                               <label>API Token</label>
+                               <description>Specifies the API token, if required (optional).</description>
+                       </parameter>
                </config-description>
 
        </thing-type>
@@ -77,7 +81,7 @@
                <config-description>
                        <parameter name="hostname" type="text" required="true">
                                <label>Hostname</label>
-                               <description>The host name or IP address of the myStrom bulb.</description>
+                               <description>The hostname or IP address of the myStrom bulb.</description>
                                <context>network-address</context>
                                <default>localhost</default>
                        </parameter>
                                <description>Specifies the refresh interval in seconds.</description>
                                <default>10</default>
                        </parameter>
+                       <parameter name="apiToken" type="text">
+                               <label>API Token</label>
+                               <description>Specifies the API token, if required (optional).</description>
+                       </parameter>
                </config-description>
 
        </thing-type>
 
+       <thing-type id="mystrompir">
+
+               <label>myStrom Motion Sensor</label>
+               <channels>
+                       <channel id="motion" typeId="system.motion"/>
+                       <channel id="temperature" typeId="system.indoor-temperature"></channel>
+                       <channel id="light" typeId="system.brightness"></channel>
+               </channels>
+               <properties>
+                       <property name="mac"/>
+                       <property name="version"/>
+                       <property name="type"/>
+                       <property name="ssid"/>
+                       <property name="ip"/>
+                       <property name="mask"/>
+                       <property name="gw"/>
+                       <property name="dns"/>
+                       <property name="static"/>
+                       <property name="connected"/>
+               </properties>
+
+               <representation-property>mac</representation-property>
+
+               <config-description>
+                       <parameter name="hostname" type="text">
+                               <label>Hostname</label>
+                               <description>The hostname or IP address of the myStrom sensor.</description>
+                               <context>network-address</context>
+                               <default>localhost</default>
+                       </parameter>
+                       <parameter name="refresh" type="integer" unit="s" min="1">
+                               <label>Refresh Interval</label>
+                               <description>Specifies the refresh interval in seconds.</description>
+                               <default>10</default>
+                       </parameter>
+                       <parameter name="apiToken" type="text">
+                               <label>API Token</label>
+                               <description>Specifies the API token, if required (optional).</description>
+                       </parameter>
+                       <parameter name="backoffTime" type="integer" unit="s" min="1">
+                               <default>10</default>
+                               <label>Backoff Time</label>
+                               <description>Specifies the minimum frequency between successive motion detections in seconds.</description>
+                       </parameter>
+                       <parameter name="ledEnable" type="boolean">
+                               <default>true</default>
+                               <label>LED Enabled</label>
+                               <description>Enables the status LED on the device.</description>
+                       </parameter>
+               </config-description>
+       </thing-type>
 
        <channel-type id="power-channel">
                <item-type>Number:Power</item-type>