| Channel Type ID | Item Type | | Description |
|-----------------|------------------------|----|------------------------------------------------------------------------------------|
-| rainsensor | Switch | RO | This channel indicates whether rain is detected by the device or not. |
-| sensor2 | Switch | RO | This channel is for the second sensor (if your hardware supports it). |
+| cloudConnected | Switch | RO | If the device is fully connected to the OpenSprinkler cloud this will show as 'ON'.|
| currentDraw | Number:ElectricCurrent | RO | Shows the current draw of the device. |
-| waterlevel | Number:Dimensionless | RO | This channel shows the current water level in percent (0-250%). The water level is |
-| | | | calculated based on the weather and influences the duration of the water programs. |
-| signalStrength | Number | RO | Shows how strong the WiFi Signal is. |
+| enablePrograms | Switch | RW | Allow programs to auto run. When OFF, manually started stations will still work. |
| flowSensorCount | Number:Dimensionless | RO | Shows the number of pulses the optional water flow sensor has reported. |
+| nextDuration | Number:Time | RW | The time the station will open for when any stations are selected from the |
+| | | | `stations` channel. Defaults to 30 minutes if not set. |
+| pausePrograms | Number:Time | RW | Sets/Shows the amount of time that programs will be paused for. |
| programs | String | RW | Displays a list of the programs that are setup in your OpenSprinkler and when |
| | | | selected will start that program for you. |
+| rainDelay | Number:Time | RW | Sets/Shows the amount of time (hours) that rain has caused programs to be delayed. |
+| rainsensor | Switch | RO | This channel indicates whether rain is detected by the device or not. |
+| resetStations | Switch | RW | The ON command will stop all stations immediately, including those waiting to run. |
+| sensor2 | Switch | RO | This channel is for the second sensor (if your hardware supports it). |
+| signalStrength | Number | RO | Shows how strong the WiFi Signal is. |
| stations | String | RW | Display a list of stations that can be run when selected to the length of time set |
| | | | in the `nextDuration` channel. |
-| nextDuration | Number:Time | RW | The time the station will open for when any stations are selected from the |
-| | | | `stations` channel. Defaults to 30 minutes if not set. |
-| resetStations | Switch | RW | The ON command will stop all stations immediately, including those waiting to run. |
-| enablePrograms | Switch | RW | Allow programs to auto run. When OFF, manually started stations will still work. |
-| rainDelay | Number:Time | RW | Sets/Shows the amount of time (hours) that rain has caused programs to be delayed. |
+| waterlevel | Number:Dimensionless | RO | This channel shows the current water level in percent (0-250%). The water level is |
+| | | | calculated based on the weather and influences the duration of the water programs. |
+| queuedZones | Number | RO | A count of how many zones are running and also waiting to run in the queue. |
## Textual Example
<artifactId>org.openhab.binding.opensprinkler</artifactId>
<name>openHAB Add-ons :: Bundles :: OpenSprinkler Binding</name>
-
</project>
public static final String NEXT_DURATION = "nextDuration";
public static final String CHANNEL_IGNORE_RAIN = "ignoreRain";
public static final String CHANNEL_RAIN_DELAY = "rainDelay";
+ public static final String CHANNEL_QUEUED_ZONES = "queuedZones";
+ public static final String CHANNEL_CLOUD_CONNECTED = "cloudConnected";
+ public static final String CHANNEL_PAUSE_PROGRAMS = "pausePrograms";
}
public int rssi = 1;
public int flcrt = -1;
public int curr = -1;
+ public int pt = -1;
+ public int nq = -1;
+ public int otcs = -1;
}
public static class JnResponse {
* @return {@code QuantityType<Time>}
*/
QuantityType<Time> getRainDelay();
+
+ /**
+ * Returns the Number of zones in the queue as an int.
+ *
+ * @return Number of zones in the queue as an int.
+ */
+ int getQueuedZones();
+
+ /**
+ * Returns the connection status of the OpenSprinkler Cloud.
+ *
+ * @return Connection state 0: not enabled, 1: connecting, 2: disconnected, 3: connected
+ */
+ int getCloudConnected();
+
+ /**
+ * Returns the paused status of the OpenSprinkler.
+ *
+ * @return int 0 to 600 seconds
+ */
+ int getPausedState();
+
+ /**
+ * Sets the amount of time that the OpenSprinkler will stop/pause zones.
+ *
+ * @param seconds for the pause duration in seconds (0 to 600)
+ * @throws UnauthorizedApiException
+ * @throws CommunicationApiException
+ */
+ void setPausePrograms(int seconds) throws UnauthorizedApiException, CommunicationApiException;
}
return new OpenSprinklerHttpApiV213(this.httpClient, config);
} else if (version >= 217 && version < 219) {
return new OpenSprinklerHttpApiV217(this.httpClient, config);
- } else if (version >= 219) {
+ } else if (version >= 219 && version < 220) {
return new OpenSprinklerHttpApiV219(this.httpClient, config);
+ } else if (version >= 220) {
+ return new OpenSprinklerHttpApiV220(this.httpClient, config);
} else {
/* Need to make sure we have an older OpenSprinkler device by checking the first station. */
try {
return response.getContentAsString();
}
}
+
+ @Override
+ public int getQueuedZones() {
+ return state.jcReply.nq;
+ }
+
+ @Override
+ public int getCloudConnected() {
+ return state.jcReply.otcs;
+ }
+
+ @Override
+ public int getPausedState() {
+ return state.jcReply.pt;
+ }
+
+ @Override
+ public void setPausePrograms(int seconds) throws UnauthorizedApiException, CommunicationApiException {
+ }
}
/**
* The {@link OpenSprinklerHttpApiV219} class is used for communicating with
- * the firmware versions 2.1.9 and up.
+ * the firmware versions 2.1.9
*
* @author Matthew Skinner - Initial contribution
*/
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 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.opensprinkler.internal.api;
+
+import static org.openhab.binding.opensprinkler.internal.OpenSprinklerBindingConstants.CMD_PROGRAM_DATA;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jetty.client.HttpClient;
+import org.openhab.binding.opensprinkler.internal.OpenSprinklerState.JpResponse;
+import org.openhab.binding.opensprinkler.internal.api.exception.CommunicationApiException;
+import org.openhab.binding.opensprinkler.internal.api.exception.GeneralApiException;
+import org.openhab.binding.opensprinkler.internal.api.exception.UnauthorizedApiException;
+import org.openhab.binding.opensprinkler.internal.config.OpenSprinklerHttpInterfaceConfig;
+import org.openhab.core.types.StateOption;
+
+import com.google.gson.JsonParseException;
+
+/**
+ * The {@link OpenSprinklerHttpApiV220} class is used for communicating with
+ * the firmware versions 2.2.0 and up.
+ *
+ * @author Matthew Skinner - Initial contribution
+ */
+@NonNullByDefault
+public class OpenSprinklerHttpApiV220 extends OpenSprinklerHttpApiV219 {
+
+ OpenSprinklerHttpApiV220(HttpClient httpClient, OpenSprinklerHttpInterfaceConfig config)
+ throws GeneralApiException, CommunicationApiException {
+ super(httpClient, config);
+ }
+
+ @Override
+ public void getProgramData() throws CommunicationApiException, UnauthorizedApiException {
+ String returnContent;
+ try {
+ returnContent = http.sendHttpGet(getBaseUrl() + CMD_PROGRAM_DATA, getRequestRequiredOptions());
+ } catch (CommunicationApiException exp) {
+ throw new CommunicationApiException(
+ "There was a problem in the HTTP communication with the OpenSprinkler API: " + exp.getMessage());
+ }
+ try {
+ JpResponse resp = gson.fromJson(returnContent, JpResponse.class);
+ if (resp != null && resp.pd.length > 0) {
+ state.programs = new ArrayList<>();
+ int counter = 0;
+ for (Object x : resp.pd) {
+ String temp = x.toString();
+ logger.trace("Program Data:{}", temp);
+ int end = temp.lastIndexOf('[') - 2;
+ int start = temp.lastIndexOf((','), end - 1) + 2;
+ if (start > -1 && end > -1) {
+ temp = temp.substring(start, end);
+ state.programs.add(new StateOption(Integer.toString(counter++), temp));
+ }
+ }
+ }
+ } catch (JsonParseException e) {
+ logger.debug("Following json could not be parsed:{}", returnContent);
+ }
+ }
+
+ @Override
+ public void setPausePrograms(int seconds) throws UnauthorizedApiException, CommunicationApiException {
+ http.sendHttpGet(getBaseUrl() + "pq", getRequestRequiredOptions() + "&dur=" + seconds);
+ }
+}
break;
case CHANNEL_RESET_STATIONS:
break;
+ case CHANNEL_QUEUED_ZONES:
+ updateState(channel, new DecimalType(localAPI.getQueuedZones()));
+ break;
+ case CHANNEL_CLOUD_CONNECTED:
+ updateState(channel, OnOffType.from(localAPI.getCloudConnected() == 3));
+ break;
+ case CHANNEL_PAUSE_PROGRAMS:
+ updateState(channel, new QuantityType<>(localAPI.getPausedState(), Units.SECOND));
+ break;
default:
logger.debug("Can not update the unknown channel {}", channel);
}
if (localAPI.getSensor2State() == -1 && channel != null) {
removeChannels.add(channel);
}
+ channel = thing.getChannel(CHANNEL_QUEUED_ZONES);
+ if (localAPI.getQueuedZones() == -1 && channel != null) {
+ removeChannels.add(channel);
+ }
+ channel = thing.getChannel(CHANNEL_CLOUD_CONNECTED);
+ if (localAPI.getCloudConnected() == -1 && channel != null) {
+ removeChannels.add(channel);
+ }
+ channel = thing.getChannel(CHANNEL_PAUSE_PROGRAMS);
+ if (localAPI.getPausedState() == -1 && channel != null) {
+ removeChannels.add(channel);
+ }
if (!removeChannels.isEmpty()) {
ThingBuilder thingBuilder = editThing();
thingBuilder.withoutChannels(removeChannels);
case CHANNEL_RAIN_DELAY:
handleRainDelayCommand(channelUID, command, api);
break;
+ case CHANNEL_PAUSE_PROGRAMS:
+ if (command == OnOffType.OFF) {
+ api.setPausePrograms(0);
+ } else if (command instanceof DecimalType) {
+ api.setPausePrograms(((BigDecimal) command).intValue());
+ } else if (command instanceof QuantityType<?>) {
+ QuantityType<?> quantity = (QuantityType<?>) command;
+ quantity = quantity.toUnit(Units.SECOND);
+ if (quantity != null) {
+ api.setPausePrograms(quantity.toBigDecimal().intValue());
+ }
+ } else {
+ logger.warn(
+ "The CHANNEL_PAUSE_PROGRAMS only supports QuanityType in seconds, DecimalType and OFF");
+ return;
+ }
+ break;
}
localBridge.delayedRefresh();// update sensors and controls after command is sent
}
# channel types
+channel-type.opensprinkler.cloudConnected.label = Cloud Connected
+channel-type.opensprinkler.cloudConnected.description = If the device is fully connected to the OpenSprinkler cloud this will show as 'ON'.
channel-type.opensprinkler.currentDraw.label = Current Draw
channel-type.opensprinkler.currentDraw.description = The current draw in mA
channel-type.opensprinkler.enablePrograms.label = Enable Programs
channel-type.opensprinkler.nextDuration.state.option.2h = 2 Hours
channel-type.opensprinkler.nextDuration.state.option.3h = 3 Hours
channel-type.opensprinkler.nextDuration.state.option.4h = 4 Hours
+channel-type.opensprinkler.pausePrograms.label = Pause Programs
+channel-type.opensprinkler.pausePrograms.description = The duration that all zones will be paused for before resuming the watering.
+channel-type.opensprinkler.pausePrograms.state.option.0s = Not Paused
+channel-type.opensprinkler.pausePrograms.state.option.15s = 15 Seconds
+channel-type.opensprinkler.pausePrograms.state.option.30s = 30 Seconds
+channel-type.opensprinkler.pausePrograms.state.option.1min = 1 Minute
+channel-type.opensprinkler.pausePrograms.state.option.2min = 2 Minutes
+channel-type.opensprinkler.pausePrograms.state.option.3min = 3 Minutes
+channel-type.opensprinkler.pausePrograms.state.option.4min = 4 Minutes
+channel-type.opensprinkler.pausePrograms.state.option.5min = 5 Minutes
+channel-type.opensprinkler.pausePrograms.state.option.10min = 10 Minutes
channel-type.opensprinkler.programs.label = Run Program
channel-type.opensprinkler.programs.description = Run a program that is saved inside the OpenSprinkler Device.
channel-type.opensprinkler.queued.label = Queued
channel-type.opensprinkler.queued.description = Indicates if the station is queued to be turned on. Can be removed from the queue by turning off. ON is read-only.
+channel-type.opensprinkler.queuedZones.label = Number Of Queued Zones
+channel-type.opensprinkler.queuedZones.description = A count of how many zones are running and also waiting to run in the queue.
channel-type.opensprinkler.rainDelay.label = Rain Delay
channel-type.opensprinkler.rainDelay.description = The amount of time in hours to delay the running of any program.
channel-type.opensprinkler.rainDelay.state.option.0s = Off
<channel id="resetStations" typeId="resetStations"></channel>
<channel id="enablePrograms" typeId="enablePrograms"></channel>
<channel id="rainDelay" typeId="rainDelay"></channel>
+ <channel id="queuedZones" typeId="queuedZones"></channel>
+ <channel id="cloudConnected" typeId="cloudConnected"></channel>
+ <channel id="pausePrograms" typeId="pausePrograms"></channel>
</channels>
+
+ <properties>
+ <property name="thingTypeVersion">1</property>
+ </properties>
+
</thing-type>
<channel-type id="rainsensor">
<state readOnly="true"/>
</channel-type>
+ <channel-type id="cloudConnected">
+ <item-type>Switch</item-type>
+ <label>Cloud Connected</label>
+ <description>If the device is fully connected to the OpenSprinkler cloud this will show as 'ON'.</description>
+ <category>Sensor</category>
+ <state readOnly="true"/>
+ </channel-type>
+
<channel-type id="waterlevel">
<item-type>Number:Dimensionless</item-type>
<label>Water Level</label>
<state readOnly="true"/>
</channel-type>
+ <channel-type id="queuedZones">
+ <item-type>Number</item-type>
+ <label>Number Of Queued Zones</label>
+ <description>A count of how many zones are running and also waiting to run in the queue.</description>
+ <state readOnly="true"/>
+ </channel-type>
+
<channel-type id="currentDraw">
<item-type>Number:ElectricCurrent</item-type>
<label>Current Draw</label>
<state readOnly="true" pattern="%.0f min"/>
</channel-type>
+ <channel-type id="pausePrograms">
+ <item-type>Number:Time</item-type>
+ <label>Pause Programs</label>
+ <description>The duration that all zones will be paused for before resuming the watering.</description>
+ <category>Time</category>
+ <state>
+ <options>
+ <option value="0s">Not Paused</option>
+ <option value="15s">15 Seconds</option>
+ <option value="30s">30 Seconds</option>
+ <option value="1min">1 Minute</option>
+ <option value="2min">2 Minutes</option>
+ <option value="3min">3 Minutes</option>
+ <option value="4min">4 Minutes</option>
+ <option value="5min">5 Minutes</option>
+ <option value="10min">10 Minutes</option>
+ </options>
+ </state>
+ </channel-type>
+
<channel-type id="nextDuration">
<item-type>Number:Time</item-type>
<label>Next Duration</label>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
+ xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">
+
+ <thing-type uid="opensprinkler:device">
+
+ <instruction-set targetVersion="1">
+ <add-channel id="queuedZones">
+ <type>opensprinkler:queuedZones</type>
+ </add-channel>
+ <add-channel id="cloudConnected">
+ <type>opensprinkler:cloudConnected</type>
+ </add-channel>
+ <add-channel id="pausePrograms">
+ <type>opensprinkler:pausePrograms</type>
+ </add-channel>
+ </instruction-set>
+
+ </thing-type>
+
+</update:update-descriptions>