Skip to content

Commit

Permalink
[opensprinkler] Refactoring of code (openhab#5862)
Browse files Browse the repository at this point in the history
* Refactoring to match openHAB thing/item model

The opensprinkler binding kind of misused the thing -> channel -> item
architecture of openHAB from my point of view. Instead of having one
thing per openSprinkler device and each station as a (pre-defined)
channel on this thing, this commit changes it to the following:
The http and pi interface are bridges now, as these communicate with the
stations, otherwise they support the same things for each station. This
makes them a necessary communication brdige, let's treat them like that.

Each channel (in the old model) is it's own thing, which can be attached
to a registered bridge type. The thing has the necessary data channels
(currently just the state, open or closed) which can be connected to
things.

This refactoring enables us to easily add more channels, e.g. the
remaining time the station is open, without the hessle of having to copy
a channel 48 times and so on.

Signed-off-by: Florian <[email protected]>

* Update README

Signed-off-by: Florian <[email protected]>

* Implemented review comments

Signed-off-by: Florian <[email protected]>
Signed-off-by: J-N-K <[email protected]>

* Implement review comments

Signed-off-by: Florian <[email protected]>

* Implement review comments

Signed-off-by: Florian <[email protected]>

* Do not log sensitive data

Signed-off-by: Florian <[email protected]>

* Bring bridge back online after failed API call

Signed-off-by: Florian <[email protected]>

* Better naming for manual mode enabling

Signed-off-by: Florian <[email protected]>
Signed-off-by: Tim Roberts <[email protected]>
  • Loading branch information
FlorianSW authored and tmrobert8 committed Jan 21, 2020
1 parent 510c21e commit 36595d2
Show file tree
Hide file tree
Showing 23 changed files with 693 additions and 1,157 deletions.
2 changes: 1 addition & 1 deletion CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
/bundles/org.openhab.binding.onewiregpio/ @aogorek
/bundles/org.openhab.binding.onewire/ @J-N-K
/bundles/org.openhab.binding.onkyo/ @pail23 @paulianttila
/bundles/org.openhab.binding.opensprinkler/ @CrackerStealth
/bundles/org.openhab.binding.opensprinkler/ @CrackerStealth @FlorianSW
/bundles/org.openhab.binding.openuv/ @clinique
/bundles/org.openhab.binding.openweathermap/ @cweitkamp
/bundles/org.openhab.binding.orvibo/ @tavalin
Expand Down
111 changes: 40 additions & 71 deletions bundles/org.openhab.binding.opensprinkler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@
This binding allows allows basic control of the OpenSprinkler and OpenSprinkler PI (Plus) devices.
Stations can be controlled to be turned on or off and rain sensor state can be read.

## Supported Bridges

* HTTP (`http`) - The http bridge allows to communicate with an OpenSprinkler device through the network
* Pi (`pi`) - With the pi bridge, openHAB can communicate with an OpenSprinkler device which is installed on the same Pi as the openHAB system.

## Supported Things

* OpenSprinkler using the HTTP API access on the network.
* OpenSprinkler PI (Plus) through the GPIO when openHAB is installed on the same Raspberry Pi used in the OpenSprinkler PI.
* OpenSprinkler Station (`station`) - to control a single station of a device, e.g. to turn it on or off
* OpenSprinkler Device (`device`) - for getting device-specific infos, e.g. if rain was detected

## Discovery

Expand All @@ -15,83 +20,42 @@ Discovery needs to be run manually as this is a brute force method of finding de

## Thing Configuration

OpenSprinkler
OpenSprinkler using the HTTP interface

```
opensprinkler:http:1 [ hostname="127.0.0.1", port=80, password="opendoor", refresh=60 ]
Bridge opensprinkler:http:http [hostname="127.0.0.1", port=80, pasword="opendoor", refresh=60] {
Thing station 01 [stationIndex=1]
}
```

- hostname: Hostname or IP address of the OpenSprinkler HTTP API.
- port: Port the OpenSprinkler device is listening on. Usually 80.
- password: Admin password of the API. Factory default is: opendoor
- refresh: Number of seconds in between refreshing the Thing state with the API.
- stationIndex: The index of the station to communicate with, starting with 0 for the first station

OpenSprinkler PI
OpenSprinkler using the Pi interface

```
opensprinkler:pi:1 [ stations=8, refresh=60 ]
Bridge opensprinkler:http:http [stations=8, refresh=60] {
Thing station 01 [stationIndex=1]
}
```

- stations: Number of stations to control.
- refresh: Number of seconds in between refreshing the Thing state with the API.

## Channels

The following channels are supported by all devices.
The following channel is supported by the station thing.

| Channel Type ID | Item Type | | Description |
|-----------------|-----------|----|---------------------------------------------------------|
| station01 | Switch | RW | This channel indicates whether station 01 is on or off. |
| station02 | Switch | RW | This channel indicates whether station 02 is on or off. |
| station03 | Switch | RW | This channel indicates whether station 03 is on or off. |
| station04 | Switch | RW | This channel indicates whether station 04 is on or off. |
| station05 | Switch | RW | This channel indicates whether station 05 is on or off. |
| station06 | Switch | RW | This channel indicates whether station 06 is on or off. |
| station07 | Switch | RW | This channel indicates whether station 07 is on or off. |
| station08 | Switch | RW | This channel indicates whether station 08 is on or off. |
| station09 | Switch | RW | This channel indicates whether station 09 is on or off. |
| station10 | Switch | RW | This channel indicates whether station 10 is on or off. |
| station11 | Switch | RW | This channel indicates whether station 11 is on or off. |
| station12 | Switch | RW | This channel indicates whether station 12 is on or off. |
| station13 | Switch | RW | This channel indicates whether station 13 is on or off. |
| station14 | Switch | RW | This channel indicates whether station 14 is on or off. |
| station15 | Switch | RW | This channel indicates whether station 15 is on or off. |
| station16 | Switch | RW | This channel indicates whether station 16 is on or off. |
| station17 | Switch | RW | This channel indicates whether station 17 is on or off. |
| station18 | Switch | RW | This channel indicates whether station 18 is on or off. |
| station19 | Switch | RW | This channel indicates whether station 19 is on or off. |
| station20 | Switch | RW | This channel indicates whether station 20 is on or off. |
| station21 | Switch | RW | This channel indicates whether station 21 is on or off. |
| station22 | Switch | RW | This channel indicates whether station 22 is on or off. |
| station23 | Switch | RW | This channel indicates whether station 23 is on or off. |
| station24 | Switch | RW | This channel indicates whether station 24 is on or off. |
| station25 | Switch | RW | This channel indicates whether station 25 is on or off. |
| station26 | Switch | RW | This channel indicates whether station 26 is on or off. |
| station27 | Switch | RW | This channel indicates whether station 27 is on or off. |
| station28 | Switch | RW | This channel indicates whether station 28 is on or off. |
| station29 | Switch | RW | This channel indicates whether station 29 is on or off. |
| station30 | Switch | RW | This channel indicates whether station 30 is on or off. |
| station31 | Switch | RW | This channel indicates whether station 31 is on or off. |
| station32 | Switch | RW | This channel indicates whether station 32 is on or off. |
| station33 | Switch | RW | This channel indicates whether station 33 is on or off. |
| station34 | Switch | RW | This channel indicates whether station 34 is on or off. |
| station35 | Switch | RW | This channel indicates whether station 35 is on or off. |
| station36 | Switch | RW | This channel indicates whether station 36 is on or off. |
| station37 | Switch | RW | This channel indicates whether station 37 is on or off. |
| station38 | Switch | RW | This channel indicates whether station 38 is on or off. |
| station39 | Switch | RW | This channel indicates whether station 39 is on or off. |
| station40 | Switch | RW | This channel indicates whether station 40 is on or off. |
| station41 | Switch | RW | This channel indicates whether station 41 is on or off. |
| station42 | Switch | RW | This channel indicates whether station 42 is on or off. |
| station43 | Switch | RW | This channel indicates whether station 43 is on or off. |
| station44 | Switch | RW | This channel indicates whether station 44 is on or off. |
| station45 | Switch | RW | This channel indicates whether station 45 is on or off. |
| station46 | Switch | RW | This channel indicates whether station 46 is on or off. |
| station47 | Switch | RW | This channel indicates whether station 47 is on or off. |
| station48 | Switch | RW | This channel indicates whether station 48 is on or off. |


The following are only support by the OpenSprinkler using the HTTP API interface.
| stationState | Switch | RW | This channel indicates whether station 01 is on or off. |



The following is supported by the device thing, but only when connected using the http interface.

| Channel Type ID | Item Type | | Description |
|-----------------|-----------|----|-----------------------------------------------------------------------|
Expand All @@ -102,23 +66,29 @@ The following are only support by the OpenSprinkler using the HTTP API interface
demo.Things:

```
opensprinkler:http:1 [ hostname="192.168.1.23", port=80, password="opendoor", refresh=60 ]
Bridge opensprinkler:http:http [hostname="127.0.0.1", port=81, password="opendoor"] {
Thing station 01 [stationIndex=0]
Thing station 02 [stationIndex=1]
Thing station 03 [stationIndex=2]
Thing station 04 [stationIndex=3]
Thing station 05 [stationIndex=4]
Thing station 06 [stationIndex=5]
Thing device device
}
```

demo.items:

```
Group stations
Switch Station01 (stations) { channel="opensprinkler:http:1:station01" }
Switch Station02 (stations) { channel="opensprinkler:http:1:station02" }
Switch Station03 (stations) { channel="opensprinkler:http:1:station03" }
Switch Station04 (stations) { channel="opensprinkler:http:1:station04" }
Switch Station05 (stations) { channel="opensprinkler:http:1:station05" }
Switch Station06 (stations) { channel="opensprinkler:http:1:station06" }
Switch Station07 (stations) { channel="opensprinkler:http:1:station07" }
Switch Station08 (stations) { channel="opensprinkler:http:1:station08" }
Switch RainSensor { channel="opensprinkler:http:1:rainsensor" }
Switch Station01 (stations) { channel="opensprinkler:station:http:01:stationState" }
Switch Station02 (stations) { channel="opensprinkler:station:http:02:stationState" }
Switch Station03 (stations) { channel="opensprinkler:station:http:03:stationState" }
Switch Station04 (stations) { channel="opensprinkler:station:http:04:stationState" }
Switch Station05 (stations) { channel="opensprinkler:station:http:05:stationState" }
Switch Station06 (stations) { channel="opensprinkler:station:http:06:stationState" }
Switch RainSensor { channel="opensprinkler:station:http:device:rainsensor" }
```

demo.sitemap:
Expand All @@ -127,8 +97,7 @@ demo.sitemap:
sitemap demo label="Main Menu"
{
Frame {
Text item=RainSensor label="Rain [%s]"
Group item=stations label="Water Stations"
Switch item=Station01
}
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -20,175 +20,33 @@
* used across the whole binding.
*
* @author Chris Graham - Initial contribution
* @author Florian Schmidt - Split channels to their own things
*/
@NonNullByDefault
public class OpenSprinklerBindingConstants {
public static final String BINDING_ID = "opensprinkler";

// List of all Thing ids
public static final String OPENSPRINKLER = "http";
public static final String OPENSPRINKLERPI = "pi";
public static final String HTTP_BRIDGE = "http";
public static final String PI_BRIDGE = "pi";
public static final String STATION_THING = "station";
public static final String DEVICE_THING = "device";

// List of all Thing Type UIDs
public static final ThingTypeUID OPENSPRINKLER_THING = new ThingTypeUID(BINDING_ID, OPENSPRINKLER);
public static final ThingTypeUID OPENSPRINKLERPI_THING = new ThingTypeUID(BINDING_ID, OPENSPRINKLERPI);
public static final ThingTypeUID OPENSPRINKLER_HTTP_BRIDGE = new ThingTypeUID(BINDING_ID, HTTP_BRIDGE);
public static final ThingTypeUID OPENSPRINKLER_STATION = new ThingTypeUID(BINDING_ID, STATION_THING);
public static final ThingTypeUID OPENSPRINKLER_DEVICE = new ThingTypeUID(BINDING_ID, DEVICE_THING);
public static final ThingTypeUID OPENSPRINKLER_PI_BRIDGE = new ThingTypeUID(BINDING_ID, PI_BRIDGE);

public static final int DEFAULT_WAIT_BEFORE_INITIAL_REFRESH = 30;
public static final int DEFAULT_REFRESH_RATE = 60;
public static final short DISCOVERY_SUBNET_MASK = 24;
public static final int DISCOVERY_THREAD_POOL_SIZE = 15;
public static final int DISCOVERY_THREAD_POOL_SHUTDOWN_WAIT_TIME_SECONDS = 300;
public static final boolean DISCOVERY_DEFAULT_AUTO_DISCOVER = false;
public static final int DISCOVERY_DEFAULT_TIMEOUT_RATE = 500;
public static final int DISCOVERY_DEFAULT_IP_TIMEOUT_RATE = 750;

// List of all Channel ids
public static final String SENSOR_RAIN = "rainsensor";

public static final String STATION_01 = "station01";
public static final String STATION_02 = "station02";
public static final String STATION_03 = "station03";
public static final String STATION_04 = "station04";
public static final String STATION_05 = "station05";
public static final String STATION_06 = "station06";
public static final String STATION_07 = "station07";
public static final String STATION_08 = "station08";
public static final String STATION_09 = "station09";
public static final String STATION_10 = "station10";
public static final String STATION_11 = "station11";
public static final String STATION_12 = "station12";
public static final String STATION_13 = "station13";
public static final String STATION_14 = "station14";
public static final String STATION_15 = "station15";
public static final String STATION_16 = "station16";
public static final String STATION_17 = "station17";
public static final String STATION_18 = "station18";
public static final String STATION_19 = "station19";
public static final String STATION_20 = "station20";
public static final String STATION_21 = "station21";
public static final String STATION_22 = "station22";
public static final String STATION_23 = "station23";
public static final String STATION_24 = "station24";
public static final String STATION_25 = "station25";
public static final String STATION_26 = "station26";
public static final String STATION_27 = "station27";
public static final String STATION_28 = "station28";
public static final String STATION_29 = "station29";
public static final String STATION_30 = "station30";
public static final String STATION_31 = "station31";
public static final String STATION_32 = "station32";
public static final String STATION_33 = "station33";
public static final String STATION_34 = "station34";
public static final String STATION_35 = "station35";
public static final String STATION_36 = "station36";
public static final String STATION_37 = "station37";
public static final String STATION_38 = "station38";
public static final String STATION_39 = "station39";
public static final String STATION_40 = "station40";
public static final String STATION_41 = "station41";
public static final String STATION_42 = "station42";
public static final String STATION_43 = "station43";
public static final String STATION_44 = "station44";
public static final String STATION_45 = "station45";
public static final String STATION_46 = "station46";
public static final String STATION_47 = "station47";
public static final String STATION_48 = "station48";

/**
* Enumeration of station constants for mapping station channel names to ints and back.
*
* @author CrackerStealth
*/
public enum Station {
STATION01(0, STATION_01),
STATION02(1, STATION_02),
STATION03(2, STATION_03),
STATION04(3, STATION_04),
STATION05(4, STATION_05),
STATION06(5, STATION_06),
STATION07(6, STATION_07),
STATION08(7, STATION_08),
STATION09(8, STATION_09),
STATION10(9, STATION_10),
STATION11(10, STATION_11),
STATION12(11, STATION_12),
STATION13(12, STATION_13),
STATION14(13, STATION_14),
STATION15(14, STATION_15),
STATION16(15, STATION_16),
STATION17(16, STATION_17),
STATION18(17, STATION_18),
STATION19(18, STATION_19),
STATION20(19, STATION_20),
STATION21(20, STATION_21),
STATION22(21, STATION_22),
STATION23(22, STATION_23),
STATION24(23, STATION_24),
STATION25(24, STATION_25),
STATION26(25, STATION_26),
STATION27(26, STATION_27),
STATION28(27, STATION_28),
STATION29(28, STATION_29),
STATION30(29, STATION_30),
STATION31(30, STATION_31),
STATION32(31, STATION_32),
STATION33(32, STATION_33),
STATION34(33, STATION_34),
STATION35(34, STATION_35),
STATION36(35, STATION_36),
STATION37(36, STATION_37),
STATION38(37, STATION_38),
STATION39(38, STATION_39),
STATION40(39, STATION_40),
STATION41(40, STATION_41),
STATION42(41, STATION_42),
STATION43(42, STATION_43),
STATION44(43, STATION_44),
STATION45(44, STATION_45),
STATION46(45, STATION_46),
STATION47(46, STATION_47),
STATION48(47, STATION_48),
SENSORRAIN(-1, SENSOR_RAIN);

private final int number;
private final String id;

private Station(final int number, final String id) {
this.number = number;
this.id = id;
}

@Override
public String toString() {
return String.valueOf(number);
}

public int toNumber() {
return number;
}

public static Station get(int valueSelectorNumber) throws IllegalArgumentException {
for (Station c : Station.values()) {
if (c.number == valueSelectorNumber) {
return c;
}
}

throw new IllegalArgumentException("Not a valid value selector.");
}

public static Station get(String valueSelectorText) throws IllegalArgumentException {
for (Station c : Station.values()) {
if (c.id.equals(valueSelectorText)) {
return c;
}
}

throw new IllegalArgumentException("Not a valid value selector.");
}

public String channelID() {
return this.id;
}
}
public static final String STATION_STATE = "stationState";
}
Loading

0 comments on commit 36595d2

Please sign in to comment.