[haywardomnilogic] Added filter & pump RPM & state channels (#11223)

* Update unit formating

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Updates per last review

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Updated units to decimal

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Removed erroneous chlorinator code from filterhandler

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Adding pump support, added body of water to xml paths to prevent detection of terminal or other items

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Added getApiDef call to initialize when debug=trace

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Fixed typo on README

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Cleanup pump xml spotless checks

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Fix typos in README

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Fixed a couple typos in pump discovery

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Fixed README typo

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Fix untested pump typos

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Fix pump typo

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Add thing properties and max filter/pump speed command

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Add support for relays to exist in the backyard

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Update README

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Add support for colorLogicLights to exist in the backyard

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Remove sensor thing and associated handler.  Hayward does not expose data for stand alone sensors.  Packaged in other things (backyard air temp, body of water temp, etc.)

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Added heater states

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Updated heater state in readme

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Added dynamic state description updates to set pump & filter minimum and maximum speeds.

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Moved dynamicStateDescription updates to thing initialize routine

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Code checks

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Add min/max limits to filter, pump and heater setpoints

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Add virtual heater dynamic state descriptions.  Change filter & pump speeds back to number:dimensionless

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Add pump & filter speed RPM channels

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Fixed typo in pump handler

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Elaborate on filter/pump handler initialize exception

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Update bow.xml property intit's to empty values (fix typos)

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Added debug flag to inject XML until appropriate integration tests are setup

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Pump and Filter enable to last speed

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Removed tatus file

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Update readme

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* format readMe

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Update ReadMe

Signed-off-by: Matt Myers <mmyers75@icloud.com>

* Remove xml debug code

Signed-off-by: Matt Myers <mmyers75@icloud.com>
pull/11953/head
Matt 2022-01-03 10:49:36 -05:00 committed by GitHub
parent 45ce201813
commit 770e897f36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 975 additions and 269 deletions

View File

@ -41,15 +41,16 @@ Hayward OmniLogic Connection Parameters:
### Backyard Channels
| backyardAirTemp | Number:Temperature | Backyard air temp sensor reading | R |
|-----------------|--------------------|----------------------------------|:-:|
| backyardStatus | String | Backyard status | R |
| backyardState | String | Backyard state | R |
| backyardAlarm1 | String | Backyard alarm #1 | R |
| backyardAlarm2 | String | Backyard alarm #2 | R |
| backyardAlarm3 | String | Backyard alarm #3 | R |
| backyardAlarm4 | String | Backyard alarm #4 | R |
| backyardAlarm5 | String | Backyard alarm #5 | R |
| Channel Type ID | Item Type | Description | Read Write |
|-----------------|--------------------|----------------------------------|:----------:|
| backyardAirTemp | Number:Temperature | Backyard air temp sensor reading | R |
| backyardStatus | String | Backyard status | R |
| backyardState | String | Backyard state | R |
| backyardAlarm1 | String | Backyard alarm #1 | R |
| backyardAlarm2 | String | Backyard alarm #2 | R |
| backyardAlarm3 | String | Backyard alarm #3 | R |
| backyardAlarm4 | String | Backyard alarm #4 | R |
| backyardAlarm5 | String | Backyard alarm #5 | R |
### Body of Water Channels
@ -87,7 +88,9 @@ Hayward OmniLogic Connection Parameters:
|---------------------|----------------------|------------------------|:----------:|
| filterEnable | Switch | Filter enable | R/W |
| filterValvePosition | String | Filter valve position | R |
| filterSpeed | Number:Dimensionless | Filter speed in % | R/W |
| filterSpeedPercent | Number:Dimensionless | Filter speed in % | R/W |
| filterSpeedRpm | Number | Filter speed in RPM | R/W |
| filterSpeedSelect | String | Filter speed presets | R/W |
| filterState | String | Filter state | R |
| filterLastSpeed | Number:Dimensionless | Filter last speed in % | R |
@ -95,15 +98,19 @@ Hayward OmniLogic Connection Parameters:
| Channel Type ID | Item Type | Description | Read Write |
|-----------------|-----------|---------------|:----------:|
| heaterState | Number | Heater state | R |
| heaterState | String | Heater state | R |
| heaterEnable | Switch | Heater enable | R |
### Pump Channels
| Channel Type ID | Item Type | Description | Read Write |
|-----------------|----------------------|-----------------|:----------:|
| pumpEnable | Switch | Pump enable | R |
| pumpSpeed | Number:Dimensionless | Pump speed in % | R |
| Channel Type ID | Item Type | Description | Read Write |
|------------------|----------------------|----------------------|:----------:|
| pumpEnable | Switch | Pump enable | R/W |
| pumpSpeedPercent | Number:Dimensionless | Pump speed in % | R/W |
| pumpSpeedRpm | Number | Pump speed in RPM | R/W |
| pumpSpeedSelect | String | Pump speed presets | R/W |
| pumpState | String | Pump state | R |
| pumpLastSpeed | Number:Dimensionless | Pump last speed in % | R |
### Relay Channels
@ -115,57 +122,11 @@ Hayward OmniLogic Connection Parameters:
| Channel Type ID | Item Type | Description | Read Write |
|-----------------------|--------------------|-------------------------|:----------:|
| heaterEnable | Number | Heater enable | R |
| heaterEnable | Switch | Heater enable | R |
| heaterCurrentSetpoint | Number:Temperature | Heater Current Setpoint | R/W |
## Full Example
After installing the binding, you will need to manually add the Hayward Connection thing and enter your credentials.
All pool items can be autmatically discovered by scanning the bridge
All pool items can be automatically discovered by scanning the bridge.
Goto the inbox and add the things.
### demo.items:
```text
Group gPool "Pool" ["Location"]
Group gHaywardChlorinator "Hayward Chlorinator" (gPool) ["Equipment"]
Switch HaywardChlorinator_Power "Power" (gHaywardChlorinator) ["Point"] { channel="haywardomnilogic:chlorinator:3766402f00:34:chlorEnable" }
String HaywardChlorinator_OperatingMode "Operating Mode" (gHaywardChlorinator) ["Point"] { channel="haywardomnilogic:chlorinator:3766402f00:34:chlorOperatingMode" }
Number:Dimensionless HaywardChlorinator_SaltOutput "Salt Output (%)" (gHaywardChlorinator) ["Point"] { channel="haywardomnilogic:chlorinator:3766402f00:34:chlorTimedPercent" }
String HaywardChlorinator_scMode "scMode" (gHaywardChlorinator) ["Point"] { channel="haywardomnilogic:chlorinator:3766402f00:34:chlorScMode" }
Number HaywardChlorinator_ChlorinatorError "Chlorinator Error" (gHaywardChlorinator) ["Point"] { channel="haywardomnilogic:chlorinator:3766402f00:34:chlorError" }
String HaywardChlorinator_ChlorinatorAlert "Chlorinator Alert" (gHaywardChlorinator) ["Point"] { channel="haywardomnilogic:chlorinator:3766402f00:34:chlorAlert" }
Number:Dimensionless HaywardChlorinator_AverageSaltLevel "Average Salt Level" (gHaywardChlorinator) ["Point"] { channel="haywardomnilogic:chlorinator:3766402f00:34:chlorAvgSaltLevel" }
Number:Dimensionless HaywardChlorinator_InstantSaltLevel "Instant Salt Level" (gHaywardChlorinator) ["Point"] { channel="haywardomnilogic:chlorinator:3766402f00:34:chlorInstantSaltLevel" }
Number HaywardChlorinator_Status "Status" (gHaywardChlorinator) ["Point"] { channel="haywardomnilogic:chlorinator:3766402f00:34:chlorStatus" }
Group gHaywardBackyard "Hayward Backyard" (gPool) ["Equipment"]
Number:Temperature HaywardBackyard_AirTemp "Air Temp" (gHaywardBackyard) ["Point"] { channel="haywardomnilogic:backyard:3766402f00:35940:backyardAirTemp" }
String HaywardBackyard_Status "Status" (gHaywardBackyard) ["Point"] { channel="haywardomnilogic:backyard:3766402f00:35940:backyardStatus" }
String HaywardBackyard_State "State" (gHaywardBackyard) ["Point"] { channel="haywardomnilogic:backyard:3766402f00:35940:backyardState" }
String HaywardBackyard_BackyardAlarm1 "Alarm" (gHaywardBackyard) ["Point"] { channel="haywardomnilogic:backyard:3766402f00:35940:backyardAlarm1" }
String HaywardBackyard_BackyardAlarm2 "Alarm" (gHaywardBackyard) ["Point"] { channel="haywardomnilogic:backyard:3766402f00:35940:backyardAlarm2" }
String HaywardBackyard_BackyardAlarm3 "Alarm" (gHaywardBackyard) ["Point"] { channel="haywardomnilogic:backyard:3766402f00:35940:backyardAlarm3" }
String HaywardBackyard_BackyardAlarm4 "Alarm" (gHaywardBackyard) ["Point"] { channel="haywardomnilogic:backyard:3766402f00:35940:backyardAlarm4" }
String HaywardBackyard_BackyardAlarm5 "Alarm" (gHaywardBackyard) ["Point"] { channel="haywardomnilogic:backyard:3766402f00:35940:backyardAlarm5" }
Group gHaywardGas "Hayward Gas" (gPool) ["Equipment"]
Number HaywardGas_HeaterState "Heater State" (gHaywardGas) ["Point"] { channel="haywardomnilogic:heater:3766402f00:33:heaterState" }
Switch HaywardGas_HeaterEnable "Heater Enable" (gHaywardGas) ["Point"] { channel="haywardomnilogic:heater:3766402f00:33:heaterEnable" }
Group gHaywardJets "Hayward Jets" (gPool) ["Equipment"]
Switch HaywardJets_Power "Power" (gHaywardJets) ["Point"] { channel="haywardomnilogic:relay:3766402f00:37:relayState" }
Group gHaywardPool "Hayward Pool" (gPool) ["Equipment"]
Switch HaywardPool_FlowSensor "Flow Sensor" (gHaywardPool) ["Point"] { channel="haywardomnilogic:bow:3766402f00:30:bowFlow" }
Number:Temperature HaywardPool_WaterTemp "Water Temp" (gHaywardPool) ["Point"] { channel="haywardomnilogic:bow:3766402f00:30:bowWaterTemp" }
Group gHaywardPoolLight "Hayward Pool Light" (gPool) ["Equipment"]
Switch HaywardPoolLight_Power "Power" (gHaywardPoolLight) ["Point"] { channel="haywardomnilogic:colorlogic:3766402f00:38:colorLogicLightEnable" }
String HaywardPoolLight_LightState "Light State" (gHaywardPoolLight) ["Point"] { channel="haywardomnilogic:colorlogic:3766402f00:38:colorLogicLightState" }
String HaywardPoolLight_CurrentShow "Current Show" (gHaywardPoolLight) ["Point"] { channel="haywardomnilogic:colorlogic:3766402f00:38:colorLogicLightCurrentShow" }
```

View File

@ -63,6 +63,13 @@ public class HaywardBindingConstants {
public static final String CHANNEL_BOW_WATERTEMP = "bowWaterTemp";
public static final String CHANNEL_BOW_FLOW = "bowFlow";
public static final String PROPERTY_BOW_TYPE = "type";
public static final String PROPERTY_BOW_SHAREDTYPE = "sharedType";
public static final String PROPERTY_BOW_SHAREDPRIORITY = "sharedPriority";
public static final String PROPERTY_BOW_SHAREDEQUIPID = "sharedEquipmentSystemID";
public static final String PROPERTY_BOW_SUPPORTSSPILLOVER = "supportsSpillover";
public static final String PROPERTY_BOW_SIZEINGALLONS = "sizeInGallons";
// List of all Channel ids (chlorinator)
public static final String CHANNEL_CHLORINATOR_ENABLE = "chlorEnable";
public static final String CHANNEL_CHLORINATOR_OPERATINGMODE = "chlorOperatingMode";
@ -74,52 +81,95 @@ public class HaywardBindingConstants {
public static final String CHANNEL_CHLORINATOR_INSTANTSALTLEVEL = "chlorInstantSaltLevel";
public static final String CHANNEL_CHLORINATOR_STATUS = "chlorStatus";
public static final String PROPERTY_CHLORINATOR_SHAREDTYPE = "chlorSharedType";
public static final String PROPERTY_CHLORINATOR_MODE = "chlorMode";
public static final String PROPERTY_CHLORINATOR_CELLTYPE = "cellType";
public static final String PROPERTY_CHLORINATOR_DISPENSERTYPE = "dispenserType";
// List of all Channel ids (colorlogic)
public static final String CHANNEL_COLORLOGIC_ENABLE = "colorLogicLightEnable";
public static final String CHANNEL_COLORLOGIC_LIGHTSTATE = "colorLogicLightState";
public static final String CHANNEL_COLORLOGIC_CURRENTSHOW = "colorLogicLightCurrentShow";
public static final String PROPERTY_COLORLOGIC_TYPE = "colorlogicType";
// List of all Channel ids (filter)
public static final String CHANNEL_FILTER_ENABLE = "filterEnable";
public static final String CHANNEL_FILTER_VALVEPOSITION = "filterValvePosition";
public static final String CHANNEL_FILTER_SPEED = "filterSpeed";
public static final String CHANNEL_FILTER_SPEEDPERCENT = "filterSpeedPercent";
public static final String CHANNEL_FILTER_SPEEDRPM = "filterSpeedRpm";
public static final String CHANNEL_FILTER_SPEEDSELECT = "filterSpeedSelect";
public static final String CHANNEL_FILTER_STATE = "filterState";
public static final String CHANNEL_FILTER_LASTSPEED = "filterLastSpeed";
public static final String PROPERTY_FILTER_MINPUMPSPEED = "Min Pump Percent";
public static final String PROPERTY_FILTER_MAXPUMPSPEED = "Max Pump Percent";
public static final String PROPERTY_FILTER_MINPUMPRPM = "Min Pump RPM";
public static final String PROPERTY_FILTER_MAXPUMPRPM = "Max Pump RPM";
public static final String PROPERTY_FILTER_SHAREDTYPE = "filterSharedType";
public static final String PROPERTY_FILTER_FILTERTYPE = "filterType";
public static final String PROPERTY_FILTER_PRIMINGENABLED = "primingEnabled";
public static final String PROPERTY_FILTER_MINSPEED = "minFilterPercent";
public static final String PROPERTY_FILTER_MAXSPEED = "maxFilterPercent";
public static final String PROPERTY_FILTER_MINRPM = "minFilterRPM";
public static final String PROPERTY_FILTER_MAXRPM = "maxFilterRPM";
public static final String PROPERTY_FILTER_LOWSPEED = "lowFilterSpeed";
public static final String PROPERTY_FILTER_MEDSPEED = "mediumFilterSpeed";
public static final String PROPERTY_FILTER_HIGHSPEED = "highFilterSpeed";
public static final String PROPERTY_FILTER_CUSTOMSPEED = "customFilterSpeed";
public static final String PROPERTY_FILTER_FREEZEPROTECTOVERRIDEINTERVAL = "freezeProtectOverrideInterval";
// List of all Channel ids (heater)
public static final String CHANNEL_HEATER_STATE = "heaterState";
public static final String CHANNEL_HEATER_TEMP = "heaterTemp";
public static final String CHANNEL_HEATER_ENABLE = "heaterEnable";
public static final String PROPERTY_HEATER_TYPE = "type";
public static final String PROPERTY_HEATER_HEATERTYPE = "heaterType";
public static final String PROPERTY_HEATER_SHAREDEQUIPID = "sharedEquipmentSystemID";
// List of all Channel ids (pump)
public static final String CHANNEL_PUMP_ENABLE = "pumpEnable";
public static final String CHANNEL_PUMP_SPEED = "pumpSpeed";
public static final String CHANNEL_PUMP_SPEEDPERCENT = "pumpSpeedPercent";
public static final String CHANNEL_PUMP_SPEEDRPM = "pumpSpeedRpm";
public static final String CHANNEL_PUMP_SPEEDSELECT = "pumpSpeedSelect";
public static final String CHANNEL_PUMP_STATE = "pumpState";
public static final String CHANNEL_PUMP_LASTSPEED = "pumpLastSpeed";
public static final String PROPERTY_PUMP_MINPUMPSPEED = "Min Pump Speed";
public static final String PROPERTY_PUMP_MAXPUMPSPEED = "Min Pump Speed";
public static final String PROPERTY_PUMP_MINPUMPRPM = "Min Pump RPM";
public static final String PROPERTY_PUMP_MAXPUMPRPM = "Max Pump RPM";
public static final String PROPERTY_PUMP_TYPE = "pumpType";
public static final String PROPERTY_PUMP_FUNCTION = "pumpFunction";
public static final String PROPERTY_PUMP_PRIMINGENABLED = "pumpPrimingEnabled";
public static final String PROPERTY_PUMP_MINSPEED = "minPumpPercent";
public static final String PROPERTY_PUMP_MAXSPEED = "maxPumpPercent";
public static final String PROPERTY_PUMP_MINRPM = "minPumpRPM";
public static final String PROPERTY_PUMP_MAXRPM = "maxPumpRPM";
public static final String PROPERTY_PUMP_LOWSPEED = "lowPumpSpeed";
public static final String PROPERTY_PUMP_MEDSPEED = "mediumPumpSpeed";
public static final String PROPERTY_PUMP_HIGHSPEED = "highPumpSpeed";
public static final String PROPERTY_PUMP_CUSTOMSPEED = "customPumpSpeed";
// List of all Channel ids (relay)
public static final String CHANNEL_RELAY_STATE = "relayState";
public static final String PROPERTY_RELAY_TYPE = "relayType";
public static final String PROPERTY_RELAY_FUNCTION = "relayFunction";
// List of all Channel ids (sensor)
public static final String CHANNEL_SENSOR_DATA = "sensorData";
public static final String PROPERTY_SENSOR_TYPE = "sensorType";
public static final String PROPERTY_SENSOR_UNITS = "sensorUnits";
// List of all Channel ids (virtualHeater)
public static final String CHANNEL_VIRTUALHEATER_CURRENTSETPOINT = "virtualHeaterCurrentSetpoint";
public static final String CHANNEL_VIRTUALHEATER_ENABLE = "virtualHeaterEnable";
public static final String PROPERTY_VIRTUALHEATER_SHAREDTYPE = "sharedType";
public static final String PROPERTY_VIRTUALHEATER_MINSETTABLEWATERTEMP = "minSettableWaterTemp";
public static final String PROPERTY_VIRTUALHEATER_MAXSETTABLEWATERTEMP = "maxSettableWaterTemp";
public static final String PROPERTY_VIRTUALHEATER_MAXWATERTEMP = "maxWaterTemp";
// The properties associated with all things
public static final String PROPERTY_SYSTEM_ID = "Property system ID";
public static final String PROPERTY_TYPE = "propertyType";
public static final String PROPERTY_BOWNAME = "BOW Name";
public static final String PROPERTY_BOWID = "BOW ID";
public static final String PROPERTY_SYSTEM_ID = "systemID";
public static final String PROPERTY_TYPE = "thingType";
public static final String PROPERTY_BOWNAME = "bowName";
public static final String PROPERTY_BOWID = "bowID";
// Hayward Command html
public static final String COMMAND_PARAMETERS = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Request>";

View File

@ -0,0 +1,74 @@
/**
* Copyright (c) 2010-2021 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.haywardomnilogic.internal;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.events.EventPublisher;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.binding.BaseDynamicStateDescriptionProvider;
import org.openhab.core.thing.events.ThingEventFactory;
import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService;
import org.openhab.core.thing.link.ItemChannelLinkRegistry;
import org.openhab.core.thing.type.DynamicStateDescriptionProvider;
import org.openhab.core.types.StateDescription;
import org.openhab.core.types.StateDescriptionFragment;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/**
* Dynamic provider of state options for {@link HueBridgeHandler} while leaving other state description fields as
* original.
*
* @author Matt Myers - Initial contribution
*/
@Component(service = { DynamicStateDescriptionProvider.class, HaywardDynamicStateDescriptionProvider.class })
@NonNullByDefault
public class HaywardDynamicStateDescriptionProvider extends BaseDynamicStateDescriptionProvider {
private final Map<ChannelUID, StateDescriptionFragment> stateDescriptionFragments = new ConcurrentHashMap<>();
@Activate
public HaywardDynamicStateDescriptionProvider(final @Reference EventPublisher eventPublisher, //
final @Reference ItemChannelLinkRegistry itemChannelLinkRegistry, //
final @Reference ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) {
this.eventPublisher = eventPublisher;
this.itemChannelLinkRegistry = itemChannelLinkRegistry;
this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService;
}
public void setStateDescriptionFragment(ChannelUID channelUID, StateDescriptionFragment stateDescriptionFragment) {
StateDescriptionFragment oldStateDescriptionFragment = stateDescriptionFragments.get(channelUID);
if (!stateDescriptionFragment.equals(oldStateDescriptionFragment)) {
stateDescriptionFragments.put(channelUID, stateDescriptionFragment);
postEvent(ThingEventFactory.createChannelDescriptionChangedEvent(channelUID,
itemChannelLinkRegistry != null ? itemChannelLinkRegistry.getLinkedItemNames(channelUID) : Set.of(),
stateDescriptionFragment, oldStateDescriptionFragment));
}
}
@Override
public @Nullable StateDescription getStateDescription(Channel channel,
@Nullable StateDescription originalStateDescription, @Nullable Locale locale) {
StateDescriptionFragment stateDescriptionFragment = stateDescriptionFragments.get(channel.getUID());
return stateDescriptionFragment != null ? stateDescriptionFragment.toStateDescription()
: super.getStateDescription(channel, originalStateDescription, locale);
}
}

View File

@ -29,8 +29,8 @@ import org.openhab.binding.haywardomnilogic.internal.handler.HaywardChlorinatorH
import org.openhab.binding.haywardomnilogic.internal.handler.HaywardColorLogicHandler;
import org.openhab.binding.haywardomnilogic.internal.handler.HaywardFilterHandler;
import org.openhab.binding.haywardomnilogic.internal.handler.HaywardHeaterHandler;
import org.openhab.binding.haywardomnilogic.internal.handler.HaywardPumpHandler;
import org.openhab.binding.haywardomnilogic.internal.handler.HaywardRelayHandler;
import org.openhab.binding.haywardomnilogic.internal.handler.HaywardSensorHandler;
import org.openhab.binding.haywardomnilogic.internal.handler.HaywardVirtualHeaterHandler;
import org.openhab.core.io.net.http.HttpClientFactory;
import org.openhab.core.thing.Bridge;
@ -56,6 +56,7 @@ public class HaywardHandlerFactory extends BaseThingHandlerFactory {
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet(
Stream.concat(BRIDGE_THING_TYPES_UIDS.stream(), THING_TYPES_UIDS.stream()).collect(Collectors.toSet()));
private final HaywardDynamicStateDescriptionProvider stateDescriptionProvider;
private final HttpClient httpClient;
@Override
@ -64,7 +65,9 @@ public class HaywardHandlerFactory extends BaseThingHandlerFactory {
}
@Activate
public HaywardHandlerFactory(@Reference HttpClientFactory httpClientFactory) {
public HaywardHandlerFactory(final @Reference HaywardDynamicStateDescriptionProvider stateDescriptionProvider,
@Reference HttpClientFactory httpClientFactory) {
this.stateDescriptionProvider = stateDescriptionProvider;
this.httpClient = httpClientFactory.getCommonHttpClient();
}
@ -76,7 +79,7 @@ public class HaywardHandlerFactory extends BaseThingHandlerFactory {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (thingTypeUID.equals(HaywardBindingConstants.THING_TYPE_BRIDGE)) {
return new HaywardBridgeHandler((Bridge) thing, httpClient);
return new HaywardBridgeHandler(stateDescriptionProvider, (Bridge) thing, httpClient);
}
if (thingTypeUID.equals(HaywardBindingConstants.THING_TYPE_BACKYARD)) {
return new HaywardBackyardHandler(thing);
@ -96,11 +99,12 @@ public class HaywardHandlerFactory extends BaseThingHandlerFactory {
if (thingTypeUID.equals(HaywardBindingConstants.THING_TYPE_HEATER)) {
return new HaywardHeaterHandler(thing);
}
if (thingTypeUID.equals(HaywardBindingConstants.THING_TYPE_PUMP)) {
return new HaywardPumpHandler(thing);
}
if (thingTypeUID.equals(HaywardBindingConstants.THING_TYPE_RELAY)) {
return new HaywardRelayHandler(thing);
}
if (thingTypeUID.equals(HaywardBindingConstants.THING_TYPE_SENSOR)) {
return new HaywardSensorHandler(thing);
}
if (thingTypeUID.equals(HaywardBindingConstants.THING_TYPE_VIRTUALHEATER)) {
return new HaywardVirtualHeaterHandler(thing);

View File

@ -13,6 +13,9 @@
package org.openhab.binding.haywardomnilogic.internal;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.haywardomnilogic.internal.handler.HaywardBridgeHandler;
import org.openhab.core.library.types.DecimalType;
@ -56,6 +59,9 @@ public abstract class HaywardThingHandler extends BaseThingHandler {
public abstract void getTelemetry(String xmlResponse) throws HaywardException;
public void setStateDescriptions() throws HaywardException {
}
public State toState(String type, String channelID, String value) throws NumberFormatException {
switch (type) {
case "Number":
@ -65,14 +71,22 @@ public abstract class HaywardThingHandler extends BaseThingHandler {
return Integer.parseInt(value) > 0 ? OnOffType.ON : OnOffType.OFF;
case "Number:Dimensionless":
switch (channelID) {
case "chlorTimedPercent":
case "filterSpeed":
case "pumpSpeed":
case "filterLastSpeed":
return new QuantityType<>(Integer.parseInt(value), Units.PERCENT);
case "chlorAvgSaltLevel":
case "chlorInstantSaltLevel":
case HaywardBindingConstants.CHANNEL_CHLORINATOR_AVGSALTLEVEL:
return new QuantityType<>(Integer.parseInt(value), Units.PARTS_PER_MILLION);
case HaywardBindingConstants.CHANNEL_CHLORINATOR_INSTANTSALTLEVEL:
return new QuantityType<>(Integer.parseInt(value), Units.PARTS_PER_MILLION);
case HaywardBindingConstants.CHANNEL_CHLORINATOR_TIMEDPERCENT:
return new QuantityType<>(Integer.parseInt(value), Units.PERCENT);
case HaywardBindingConstants.CHANNEL_FILTER_LASTSPEED:
return new QuantityType<>(Integer.parseInt(value), Units.PERCENT);
case HaywardBindingConstants.CHANNEL_FILTER_SPEEDPERCENT:
return new QuantityType<>(Integer.parseInt(value), Units.PERCENT);
case HaywardBindingConstants.CHANNEL_FILTER_SPEEDRPM:
case HaywardBindingConstants.CHANNEL_PUMP_LASTSPEED:
return new QuantityType<>(Integer.parseInt(value), Units.PERCENT);
case HaywardBindingConstants.CHANNEL_PUMP_SPEEDPERCENT:
return new QuantityType<>(Integer.parseInt(value), Units.PERCENT);
case HaywardBindingConstants.CHANNEL_PUMP_SPEEDRPM:
}
return StringType.valueOf(value);
case "Number:Temperature":
@ -108,14 +122,17 @@ public abstract class HaywardThingHandler extends BaseThingHandler {
}
}
public void updateData(String channelID, String data) {
public Map<String, State> updateData(String channelID, String data) {
Map<String, State> channelStates = new HashMap<>();
Channel chan = getThing().getChannel(channelID);
if (chan != null) {
String acceptedItemType = chan.getAcceptedItemType();
if (acceptedItemType != null) {
State state = toState(acceptedItemType, channelID, data);
updateState(chan.getUID(), state);
channelStates.put(channelID, state);
}
}
return channelStates;
}
}

View File

@ -103,70 +103,192 @@ public class HaywardDiscoveryService extends AbstractDiscoveryService implements
systemIDs = bridgehandler.evaluateXPath("//Body-of-water/System-Id/text()", xmlResponse);
names = bridgehandler.evaluateXPath("//Body-of-water/Name/text()", xmlResponse);
final List<String> bowProperty1 = bridgehandler.evaluateXPath("//Body-of-water/Type/text()", xmlResponse);
final List<String> bowProperty2 = bridgehandler.evaluateXPath("//Body-of-water/Shared-Type/text()",
xmlResponse);
final List<String> bowProperty3 = bridgehandler.evaluateXPath("//Body-of-water/Shared-Priority/text()",
xmlResponse);
final List<String> bowProperty4 = bridgehandler
.evaluateXPath("//Body-of-water/Shared-Equipment-System-ID/text()", xmlResponse);
final List<String> bowProperty5 = bridgehandler.evaluateXPath("//Body-of-water/Supports-Spillover/text()",
xmlResponse);
final List<String> bowProperty6 = bridgehandler.evaluateXPath("//Body-of-water/Size-In-Gallons/text()",
xmlResponse);
for (int i = 0; i < systemIDs.size(); i++) {
bowProperties.put(HaywardBindingConstants.PROPERTY_TYPE, HaywardTypeToRequest.BOW);
bowProperties.put(HaywardBindingConstants.PROPERTY_SYSTEM_ID, systemIDs.get(i));
bowProperties.put(HaywardBindingConstants.PROPERTY_BOW_TYPE, bowProperty1.get(i));
bowProperties.put(HaywardBindingConstants.PROPERTY_BOW_SHAREDTYPE, bowProperty2.get(i));
bowProperties.put(HaywardBindingConstants.PROPERTY_BOW_SHAREDPRIORITY, bowProperty3.get(i));
bowProperties.put(HaywardBindingConstants.PROPERTY_BOW_SHAREDEQUIPID, bowProperty4.get(i));
bowProperties.put(HaywardBindingConstants.PROPERTY_BOW_SUPPORTSSPILLOVER, bowProperty5.get(i));
bowProperties.put(HaywardBindingConstants.PROPERTY_BOW_SIZEINGALLONS, bowProperty6.get(i));
onDeviceDiscovered(HaywardBindingConstants.THING_TYPE_BOW, names.get(i), bowProperties);
}
// Find Chlorinators
final List<String> chlorinatorProperty1 = bridgehandler
.evaluateXPath("//Body-of-water/Chlorinator/Shared-Type/text()", xmlResponse);
final List<String> chlorinatorProperty2 = bridgehandler.evaluateXPath("//Body-of-water/Chlorinator/Mode/text()",
xmlResponse);
final List<String> chlorinatorProperty3 = bridgehandler
.evaluateXPath("//Body-of-water/Chlorinator/Cell-Type/text()", xmlResponse);
final List<String> chlorinatorProperty4 = bridgehandler
.evaluateXPath("//Body-of-water/Chlorinator/Dispenser-Type/text()", xmlResponse);
discoverDevices(bridgehandler, xmlResponse, "Chlorinator", HaywardTypeToRequest.CHLORINATOR,
HaywardBindingConstants.THING_TYPE_CHLORINATOR, null);
HaywardBindingConstants.THING_TYPE_CHLORINATOR, (props, i) -> {
props.put(HaywardBindingConstants.PROPERTY_CHLORINATOR_SHAREDTYPE, chlorinatorProperty1.get(i));
props.put(HaywardBindingConstants.PROPERTY_CHLORINATOR_MODE, chlorinatorProperty2.get(i));
props.put(HaywardBindingConstants.PROPERTY_CHLORINATOR_CELLTYPE, chlorinatorProperty3.get(i));
props.put(HaywardBindingConstants.PROPERTY_CHLORINATOR_DISPENSERTYPE, chlorinatorProperty4.get(i));
});
// Find ColorLogic Lights
final List<String> colorLogicProperty1 = bridgehandler.evaluateXPath("//Backyard//ColorLogic-Light/Type/text()",
xmlResponse);
discoverDevices(bridgehandler, xmlResponse, "ColorLogic-Light", HaywardTypeToRequest.COLORLOGIC,
HaywardBindingConstants.THING_TYPE_COLORLOGIC, null);
HaywardBindingConstants.THING_TYPE_COLORLOGIC, (props, i) -> {
props.put(HaywardBindingConstants.PROPERTY_COLORLOGIC_TYPE, colorLogicProperty1.get(i));
});
// Find Filters
final List<String> filterProperty1 = bridgehandler.evaluateXPath("//Filter/Min-Pump-Speed/text()", xmlResponse);
final List<String> filterProperty2 = bridgehandler.evaluateXPath("//Filter/Max-Pump-Speed/text()", xmlResponse);
final List<String> filterProperty3 = bridgehandler.evaluateXPath("//Filter/Min-Pump-RPM/text()", xmlResponse);
final List<String> filterProperty4 = bridgehandler.evaluateXPath("//Filter/Max-Pump-RPM/text()", xmlResponse);
final List<String> filterProperty1 = bridgehandler.evaluateXPath("//Body-of-water/Filter/Shared-Type/text()",
xmlResponse);
final List<String> filterProperty2 = bridgehandler.evaluateXPath("//Body-of-water/Filter/Filter-Type/text()",
xmlResponse);
final List<String> filterProperty3 = bridgehandler
.evaluateXPath("//Body-of-water/Filter/Priming-Enabled/text()", xmlResponse);
final List<String> filterProperty4 = bridgehandler.evaluateXPath("//Body-of-water/Filter/Min-Pump-Speed/text()",
xmlResponse);
final List<String> filterProperty5 = bridgehandler.evaluateXPath("//Body-of-water/Filter/Max-Pump-Speed/text()",
xmlResponse);
final List<String> filterProperty6 = bridgehandler.evaluateXPath("//Body-of-water/Filter/Min-Pump-RPM/text()",
xmlResponse);
final List<String> filterProperty7 = bridgehandler.evaluateXPath("//Body-of-water/Filter/Max-Pump-RPM/text()",
xmlResponse);
final List<String> filterProperty8 = bridgehandler
.evaluateXPath("//Body-of-water/Filter/Vsp-Low-Pump-Speed/text()", xmlResponse);
final List<String> filterProperty9 = bridgehandler
.evaluateXPath("//Body-of-water/Filter/Vsp-Medium-Pump-Speed/text()", xmlResponse);
final List<String> filterProperty10 = bridgehandler
.evaluateXPath("//Body-of-water/Filter/Vsp-High-Pump-Speed/text()", xmlResponse);
final List<String> filterProperty11 = bridgehandler
.evaluateXPath("//Body-of-water/Filter/Vsp-Custom-Pump-Speed/text()", xmlResponse);
final List<String> filterProperty12 = bridgehandler
.evaluateXPath("//Body-of-water/Filter/Freeze-Protect-Override-Interval/text()", xmlResponse);
discoverDevices(bridgehandler, xmlResponse, "Filter", HaywardTypeToRequest.FILTER,
HaywardBindingConstants.THING_TYPE_FILTER, (props, i) -> {
props.put(HaywardBindingConstants.PROPERTY_FILTER_MINPUMPSPEED, filterProperty1.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_MAXPUMPSPEED, filterProperty2.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_MINPUMPRPM, filterProperty3.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_MAXPUMPRPM, filterProperty4.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_SHAREDTYPE, filterProperty1.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_FILTERTYPE, filterProperty2.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_PRIMINGENABLED, filterProperty3.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_MINSPEED, filterProperty4.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_MAXSPEED, filterProperty5.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_MINRPM, filterProperty6.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_MAXRPM, filterProperty7.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_LOWSPEED, filterProperty8.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_MEDSPEED, filterProperty9.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_HIGHSPEED, filterProperty10.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_CUSTOMSPEED, filterProperty11.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_FREEZEPROTECTOVERRIDEINTERVAL,
filterProperty12.get(i));
});
// Find Heaters
final List<String> heaterProperty1 = bridgehandler
.evaluateXPath("//Body-of-water/Heater/Operation/Heater-Equipment/Type/text()", xmlResponse);
final List<String> heaterProperty2 = bridgehandler
.evaluateXPath("//Body-of-water/Heater/Operation/Heater-Equipment/Heater-Type/text()", xmlResponse);
final List<String> heaterProperty3 = bridgehandler.evaluateXPath(
"//Body-of-water/Heater/Operation/Heater-Equipment/Shared-Equipment-System-ID/text()", xmlResponse);
discoverDevices(bridgehandler, xmlResponse, "Heater-Equipment", HaywardTypeToRequest.HEATER,
HaywardBindingConstants.THING_TYPE_HEATER, null);
HaywardBindingConstants.THING_TYPE_HEATER, (props, i) -> {
props.put(HaywardBindingConstants.PROPERTY_HEATER_TYPE, heaterProperty1.get(i));
props.put(HaywardBindingConstants.PROPERTY_HEATER_HEATERTYPE, heaterProperty2.get(i));
props.put(HaywardBindingConstants.PROPERTY_HEATER_SHAREDEQUIPID, heaterProperty3.get(i));
});
// Find Pumps
final List<String> pumpProperty1 = bridgehandler.evaluateXPath("//Pump/Min-Pump-Speed/text()", xmlResponse);
final List<String> pumpProperty2 = bridgehandler.evaluateXPath("//Pump/Max-Pump-Speed/text()", xmlResponse);
final List<String> pumpProperty3 = bridgehandler.evaluateXPath("//Pump/Min-Pump-RPM/text()", xmlResponse);
final List<String> pumpProperty4 = bridgehandler.evaluateXPath("//Pump/Max-Pump-RPM/text()", xmlResponse);
final List<String> pumpProperty1 = bridgehandler.evaluateXPath("//Body-of-water/Pump/Type/text()", xmlResponse);
final List<String> pumpProperty2 = bridgehandler.evaluateXPath("//Body-of-water/Pump/Function/text()",
xmlResponse);
final List<String> pumpProperty3 = bridgehandler.evaluateXPath("//Body-of-water/Pump/Priming-Enabled/text()",
xmlResponse);
final List<String> pumpProperty4 = bridgehandler.evaluateXPath("//Body-of-water/Pump/Min-Pump-Speed/text()",
xmlResponse);
final List<String> pumpProperty5 = bridgehandler.evaluateXPath("//Body-of-water/Pump/Max-Pump-Speed/text()",
xmlResponse);
final List<String> pumpProperty6 = bridgehandler.evaluateXPath("//Body-of-water/Pump/Min-Pump-RPM/text()",
xmlResponse);
final List<String> pumpProperty7 = bridgehandler.evaluateXPath("//Body-of-water/Pump/Max-Pump-RPM/text()",
xmlResponse);
final List<String> pumpProperty8 = bridgehandler.evaluateXPath("//Body-of-water/Pump/Vsp-Low-Pump-Speed/text()",
xmlResponse);
final List<String> pumpProperty9 = bridgehandler
.evaluateXPath("//Body-of-water/Pump/Vsp-Medium-Pump-Speed/text()", xmlResponse);
final List<String> pumpProperty10 = bridgehandler
.evaluateXPath("//Body-of-water/Pump/Vsp-High-Pump-Speed/text()", xmlResponse);
final List<String> pumpProperty11 = bridgehandler
.evaluateXPath("//Body-of-water/Pump/Vsp-Custom-Pump-Speed/text()", xmlResponse);
discoverDevices(bridgehandler, xmlResponse, "Pump", HaywardTypeToRequest.PUMP,
HaywardBindingConstants.THING_TYPE_FILTER, (props, i) -> {
props.put(HaywardBindingConstants.PROPERTY_FILTER_MINPUMPSPEED, pumpProperty1.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_MAXPUMPSPEED, pumpProperty2.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_MINPUMPRPM, pumpProperty3.get(i));
props.put(HaywardBindingConstants.PROPERTY_FILTER_MAXPUMPRPM, pumpProperty4.get(i));
HaywardBindingConstants.THING_TYPE_PUMP, (props, i) -> {
props.put(HaywardBindingConstants.PROPERTY_PUMP_TYPE, pumpProperty1.get(i));
props.put(HaywardBindingConstants.PROPERTY_PUMP_FUNCTION, pumpProperty2.get(i));
props.put(HaywardBindingConstants.PROPERTY_PUMP_PRIMINGENABLED, pumpProperty3.get(i));
props.put(HaywardBindingConstants.PROPERTY_PUMP_MINSPEED, pumpProperty4.get(i));
props.put(HaywardBindingConstants.PROPERTY_PUMP_MAXSPEED, pumpProperty5.get(i));
props.put(HaywardBindingConstants.PROPERTY_PUMP_MINRPM, pumpProperty6.get(i));
props.put(HaywardBindingConstants.PROPERTY_PUMP_MAXRPM, pumpProperty7.get(i));
props.put(HaywardBindingConstants.PROPERTY_PUMP_LOWSPEED, pumpProperty8.get(i));
props.put(HaywardBindingConstants.PROPERTY_PUMP_MEDSPEED, pumpProperty9.get(i));
props.put(HaywardBindingConstants.PROPERTY_PUMP_HIGHSPEED, pumpProperty10.get(i));
props.put(HaywardBindingConstants.PROPERTY_PUMP_CUSTOMSPEED, pumpProperty11.get(i));
});
// Find Relays
final List<String> relayProperty1 = bridgehandler.evaluateXPath("//Backyard//Relay/Type/text()", xmlResponse);
final List<String> relayProperty2 = bridgehandler.evaluateXPath("//Backyard//Relay/Function/text()",
xmlResponse);
discoverDevices(bridgehandler, xmlResponse, "Relay", HaywardTypeToRequest.RELAY,
HaywardBindingConstants.THING_TYPE_RELAY, null);
HaywardBindingConstants.THING_TYPE_RELAY, (props, i) -> {
props.put(HaywardBindingConstants.PROPERTY_RELAY_TYPE, relayProperty1.get(i));
props.put(HaywardBindingConstants.PROPERTY_RELAY_FUNCTION, relayProperty2.get(i));
});
// Find Virtual Heaters
discoverDevices(bridgehandler, xmlResponse, "Heater", HaywardTypeToRequest.VIRTUALHEATER,
HaywardBindingConstants.THING_TYPE_VIRTUALHEATER, null);
final List<String> virtualHeaterProperty1 = bridgehandler
.evaluateXPath("//Body-of-water/Heater/Shared-Type/text()", xmlResponse);
final List<String> virtualHeaterProperty2 = bridgehandler
.evaluateXPath("//Body-of-water/Heater/Min-Settable-Water-Temp/text()", xmlResponse);
final List<String> virtualHeaterProperty3 = bridgehandler
.evaluateXPath("//Body-of-water/Heater/Max-Settable-Water-Temp/text()", xmlResponse);
final List<String> virtualHeaterProperty4 = bridgehandler
.evaluateXPath("//Body-of-water/Heater/Max-Water-Temp/text()", xmlResponse);
// Find Sensors
discoverDevices(bridgehandler, xmlResponse, "Sensor", HaywardTypeToRequest.SENSOR,
HaywardBindingConstants.THING_TYPE_SENSOR, null);
discoverDevices(bridgehandler, xmlResponse, "Heater", HaywardTypeToRequest.VIRTUALHEATER,
HaywardBindingConstants.THING_TYPE_VIRTUALHEATER, (props, i) -> {
props.put(HaywardBindingConstants.PROPERTY_VIRTUALHEATER_SHAREDTYPE, virtualHeaterProperty1.get(i));
props.put(HaywardBindingConstants.PROPERTY_VIRTUALHEATER_MINSETTABLEWATERTEMP,
virtualHeaterProperty2.get(i));
props.put(HaywardBindingConstants.PROPERTY_VIRTUALHEATER_MAXSETTABLEWATERTEMP,
virtualHeaterProperty3.get(i));
props.put(HaywardBindingConstants.PROPERTY_VIRTUALHEATER_MAXWATERTEMP,
virtualHeaterProperty4.get(i));
});
}
private void discoverDevices(HaywardBridgeHandler bridgehandler, String xmlResponse, String xmlSearchTerm,
HaywardTypeToRequest type, ThingTypeUID thingType,
@Nullable BiConsumer<Map<String, Object>, Integer> additionalPropertyConsumer) {
List<String> systemIDs = bridgehandler.evaluateXPath("//" + xmlSearchTerm + "/System-Id/text()", xmlResponse);
List<String> systemIDs = bridgehandler.evaluateXPath("//Backyard//" + xmlSearchTerm + "/System-Id/text()",
xmlResponse);
List<String> names;
// Set Virtual Heater Name
@ -174,7 +296,7 @@ public class HaywardDiscoveryService extends AbstractDiscoveryService implements
names = new ArrayList<>(systemIDs);
Collections.fill(names, "Heater");
} else {
names = bridgehandler.evaluateXPath("//" + xmlSearchTerm + "/Name/text()", xmlResponse);
names = bridgehandler.evaluateXPath("//Backyard//" + xmlSearchTerm + "/Name/text()", xmlResponse);
}
for (int i = 0; i < systemIDs.size(); i++) {
@ -184,19 +306,28 @@ public class HaywardDiscoveryService extends AbstractDiscoveryService implements
List<String> bowName = bridgehandler.evaluateXPath(
"//*[System-Id=" + systemIDs.get(i) + "]/ancestor::Body-of-water/Name/text()", xmlResponse);
// skip system sensors with no BOW
if (bowID.isEmpty()) {
continue;
}
Map<String, Object> properties = new HashMap<>();
properties.put(HaywardBindingConstants.PROPERTY_TYPE, type);
properties.put(HaywardBindingConstants.PROPERTY_SYSTEM_ID, systemIDs.get(i));
properties.put(HaywardBindingConstants.PROPERTY_BOWID, bowID.get(0));
properties.put(HaywardBindingConstants.PROPERTY_BOWNAME, bowName.get(0));
if (!bowID.isEmpty()) {
properties.put(HaywardBindingConstants.PROPERTY_BOWID, bowID.get(0));
} else {
// Set BOWID = 0 for backyard items
properties.put(HaywardBindingConstants.PROPERTY_BOWID, "0");
}
if (!bowName.isEmpty()) {
properties.put(HaywardBindingConstants.PROPERTY_BOWNAME, bowName.get(0));
} else {
// Set BOWNAME = Backyard for backyard items
properties.put(HaywardBindingConstants.PROPERTY_BOWNAME, "Backyard");
}
if (additionalPropertyConsumer != null) {
additionalPropertyConsumer.accept(properties, i);
}
onDeviceDiscovered(thingType, names.get(i), properties);
}
}

View File

@ -39,6 +39,7 @@ import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpVersion;
import org.openhab.binding.haywardomnilogic.internal.HaywardAccount;
import org.openhab.binding.haywardomnilogic.internal.HaywardBindingConstants;
import org.openhab.binding.haywardomnilogic.internal.HaywardDynamicStateDescriptionProvider;
import org.openhab.binding.haywardomnilogic.internal.HaywardException;
import org.openhab.binding.haywardomnilogic.internal.HaywardThingHandler;
import org.openhab.binding.haywardomnilogic.internal.HaywardTypeToRequest;
@ -46,6 +47,7 @@ import org.openhab.binding.haywardomnilogic.internal.config.HaywardConfig;
import org.openhab.binding.haywardomnilogic.internal.discovery.HaywardDiscoveryService;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
@ -53,6 +55,7 @@ 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.StateDescriptionFragment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.NodeList;
@ -68,6 +71,7 @@ import org.xml.sax.InputSource;
@NonNullByDefault
public class HaywardBridgeHandler extends BaseBridgeHandler {
private final Logger logger = LoggerFactory.getLogger(HaywardBridgeHandler.class);
private final HaywardDynamicStateDescriptionProvider stateDescriptionProvider;
private final HttpClient httpClient;
private @Nullable ScheduledFuture<?> initializeFuture;
private @Nullable ScheduledFuture<?> pollTelemetryFuture;
@ -81,9 +85,11 @@ public class HaywardBridgeHandler extends BaseBridgeHandler {
return Collections.singleton(HaywardDiscoveryService.class);
}
public HaywardBridgeHandler(Bridge bridge, HttpClient httpClient) {
public HaywardBridgeHandler(HaywardDynamicStateDescriptionProvider stateDescriptionProvider, Bridge bridge,
HttpClient httpClient) {
super(bridge);
this.httpClient = httpClient;
this.stateDescriptionProvider = stateDescriptionProvider;
}
@Override
@ -142,6 +148,18 @@ public class HaywardBridgeHandler extends BaseBridgeHandler {
return;
}
if (logger.isTraceEnabled()) {
if (!(getApiDef())) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"Unable to getApiDef from Hayward's server");
clearPolling(pollTelemetryFuture);
clearPolling(pollAlarmsFuture);
commFailureCount = 50;
initPolling(60);
return;
}
}
if (this.thing.getStatus() != ThingStatus.ONLINE) {
updateStatus(ThingStatus.ONLINE);
}
@ -199,7 +217,7 @@ public class HaywardBridgeHandler extends BaseBridgeHandler {
public synchronized boolean getApiDef() throws HaywardException, InterruptedException {
String xmlResponse;
// *****getConfig from Hayward server
// *****getApiDef from Hayward server
String urlParameters = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Request><Name>GetAPIDef</Name><Parameters>"
+ "<Parameter name=\"Token\" dataType=\"String\">" + account.token + "</Parameter>"
+ "<Parameter name=\"MspSystemID\" dataType=\"int\">" + account.mspSystemID + "</Parameter>;"
@ -258,11 +276,6 @@ public class HaywardBridgeHandler extends BaseBridgeHandler {
String xmlResponse = httpXmlResponse(urlParameters);
// Debug: Inject xml file for testing
// String path =
// "C:/Users/Controls/openhab-2-5-x/git/openhab-addons/bundles/org.openhab.binding.haywardomnilogic/getConfig.xml";
// xmlResponse = new String(Files.readAllBytes(Paths.get(path)));
if (xmlResponse.isEmpty()) {
logger.debug("Hayward Connection thing: requestConfig XML response was null");
return "Fail";
@ -469,6 +482,11 @@ public class HaywardBridgeHandler extends BaseBridgeHandler {
return e.getMethodName();
}
void updateChannelStateDescriptionFragment(Channel channel, StateDescriptionFragment descriptionFragment) {
ChannelUID channelId = channel.getUID();
stateDescriptionProvider.setStateDescriptionFragment(channelId, descriptionFragment);
}
public int convertCommand(Command command) {
if (command == OnOffType.ON) {
return 1;

View File

@ -12,8 +12,11 @@
*/
package org.openhab.binding.haywardomnilogic.internal.handler;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.haywardomnilogic.internal.HaywardBindingConstants;
@ -21,12 +24,17 @@ import org.openhab.binding.haywardomnilogic.internal.HaywardException;
import org.openhab.binding.haywardomnilogic.internal.HaywardThingHandler;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Channel;
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 org.openhab.core.types.RefreshType;
import org.openhab.core.types.State;
import org.openhab.core.types.StateDescriptionFragment;
import org.openhab.core.types.StateDescriptionFragmentBuilder;
import org.openhab.core.types.StateOption;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -38,6 +46,7 @@ import org.slf4j.LoggerFactory;
@NonNullByDefault
public class HaywardFilterHandler extends HaywardThingHandler {
private final Logger logger = LoggerFactory.getLogger(HaywardFilterHandler.class);
private Map<String, State> channelStates = new HashMap<>();
public HaywardFilterHandler(Thing thing) {
super(thing);
@ -45,7 +54,75 @@ public class HaywardFilterHandler extends HaywardThingHandler {
@Override
public void initialize() {
updateStatus(ThingStatus.ONLINE);
try {
setStateDescriptions();
updateStatus(ThingStatus.ONLINE);
} catch (HaywardException e) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"Unable to set FilterHandler StateDescriptions");
}
}
@Override
public void setStateDescriptions() throws HaywardException {
List<StateOption> options = new ArrayList<>();
String option;
Bridge bridge = getBridge();
if (bridge != null) {
HaywardBridgeHandler bridgehandler = (HaywardBridgeHandler) bridge.getHandler();
if (bridgehandler != null) {
// Set Filter Speed % min and max speeds
Channel ch = thing.getChannel(HaywardBindingConstants.CHANNEL_FILTER_SPEEDPERCENT);
if (ch != null) {
StateDescriptionFragment stateDescriptionFragment = StateDescriptionFragmentBuilder.create()
.withMinimum(new BigDecimal(
getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_MINSPEED)))
.withMaximum(new BigDecimal(
getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_MAXSPEED)))
.build();
bridgehandler.updateChannelStateDescriptionFragment(ch, stateDescriptionFragment);
}
// Set Filter Speed RPM min and max speeds
ch = thing.getChannel(HaywardBindingConstants.CHANNEL_FILTER_SPEEDRPM);
if (ch != null) {
StateDescriptionFragment stateDescriptionFragment = StateDescriptionFragmentBuilder.create()
.withMinimum(new BigDecimal(
getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_MINRPM)))
.withMaximum(new BigDecimal(
getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_MAXRPM)))
.build();
bridgehandler.updateChannelStateDescriptionFragment(ch, stateDescriptionFragment);
}
// Set Filter Speed States
ch = thing.getChannel(HaywardBindingConstants.CHANNEL_FILTER_SPEEDSELECT);
if (ch != null) {
options.add(new StateOption("0", "Off"));
option = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_LOWSPEED);
if (option != null) {
options.add(new StateOption(option, "Low"));
}
option = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_MEDSPEED);
if (option != null) {
options.add(new StateOption(option, "Medium"));
}
option = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_HIGHSPEED);
if (option != null) {
options.add(new StateOption(option, "High"));
}
option = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_CUSTOMSPEED);
if (option != null) {
options.add(new StateOption(option, "Custom"));
}
StateDescriptionFragment stateDescriptionFragment = StateDescriptionFragmentBuilder.create()
.withOptions(options).build();
bridgehandler.updateChannelStateDescriptionFragment(ch, stateDescriptionFragment);
}
}
}
}
@Override
@ -65,9 +142,17 @@ public class HaywardFilterHandler extends HaywardThingHandler {
data = bridgehandler.evaluateXPath("//Filter/@valvePosition", xmlResponse);
updateData(HaywardBindingConstants.CHANNEL_FILTER_VALVEPOSITION, data.get(i));
// Speed
// Speed percent
data = bridgehandler.evaluateXPath("//Filter/@filterSpeed", xmlResponse);
updateData(HaywardBindingConstants.CHANNEL_FILTER_SPEED, data.get(i));
updateData(HaywardBindingConstants.CHANNEL_FILTER_SPEEDPERCENT, data.get(i));
// Speed rpm
String filterMaxRpm = getThing().getProperties()
.get(HaywardBindingConstants.PROPERTY_FILTER_MAXRPM);
if (filterMaxRpm != null) {
Integer rpmSpeed = (Integer.parseInt(data.get(i))) * (Integer.parseInt(filterMaxRpm)) / 100;
updateData(HaywardBindingConstants.CHANNEL_FILTER_SPEEDRPM, rpmSpeed.toString());
}
if (data.get(i).equals("0")) {
updateData(HaywardBindingConstants.CHANNEL_FILTER_ENABLE, "0");
@ -75,6 +160,10 @@ public class HaywardFilterHandler extends HaywardThingHandler {
updateData(HaywardBindingConstants.CHANNEL_FILTER_ENABLE, "1");
}
// Speed Select
data = bridgehandler.evaluateXPath("//Filter/@filterSpeed", xmlResponse);
updateData(HaywardBindingConstants.CHANNEL_FILTER_SPEEDSELECT, data.get(i));
// State
data = bridgehandler.evaluateXPath("//Filter/@filterState", xmlResponse);
updateData(HaywardBindingConstants.CHANNEL_FILTER_STATE, data.get(i));
@ -82,6 +171,7 @@ public class HaywardFilterHandler extends HaywardThingHandler {
// lastSpeed
data = bridgehandler.evaluateXPath("//Filter/@lastSpeed", xmlResponse);
updateData(HaywardBindingConstants.CHANNEL_FILTER_LASTSPEED, data.get(i));
channelStates.putAll(updateData(HaywardBindingConstants.CHANNEL_FILTER_LASTSPEED, data.get(i)));
}
}
this.updateStatus(ThingStatus.ONLINE);
@ -99,6 +189,9 @@ public class HaywardFilterHandler extends HaywardThingHandler {
String systemID = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_SYSTEM_ID);
String poolID = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_BOWID);
String filterMinSpeed = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_MINSPEED);
String filterMaxSpeed = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_MAXSPEED);
String filterMaxRpm = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_MAXRPM);
Bridge bridge = getBridge();
if (bridge != null) {
@ -109,12 +202,36 @@ public class HaywardFilterHandler extends HaywardThingHandler {
switch (channelUID.getId()) {
case HaywardBindingConstants.CHANNEL_FILTER_ENABLE:
if (command == OnOffType.ON) {
cmdString = "100";
cmdString = channelStates.get(HaywardBindingConstants.CHANNEL_FILTER_LASTSPEED)
.format("%d");
} else {
cmdString = "0";
}
break;
case HaywardBindingConstants.CHANNEL_FILTER_SPEED:
case HaywardBindingConstants.CHANNEL_FILTER_SPEEDPERCENT:
if (filterMinSpeed != null && filterMaxSpeed != null) {
if (Integer.parseInt(cmdString) > 0
&& Integer.parseInt(cmdString) < Integer.parseInt(filterMinSpeed)) {
cmdString = filterMinSpeed;
} else if (Integer.parseInt(cmdString) > Integer.parseInt(filterMaxSpeed)) {
cmdString = filterMaxSpeed;
}
}
break;
case HaywardBindingConstants.CHANNEL_FILTER_SPEEDRPM:
// Convert cmdString from RPM to Percent
if (filterMaxRpm != null && filterMaxSpeed != null && filterMinSpeed != null) {
cmdString = Integer
.toString((Integer.parseInt(cmdString) * 100 / Integer.parseInt(filterMaxRpm)));
if (Integer.parseInt(cmdString) > 0
&& Integer.parseInt(cmdString) < Integer.parseInt(filterMinSpeed)) {
cmdString = filterMinSpeed;
} else if (Integer.parseInt(cmdString) > Integer.parseInt(filterMaxSpeed)) {
cmdString = filterMaxSpeed;
}
}
break;
case HaywardBindingConstants.CHANNEL_FILTER_SPEEDSELECT:
break;
default:
logger.warn("haywardCommand Unsupported type {}", channelUID);

View File

@ -0,0 +1,267 @@
/**
* Copyright (c) 2010-2021 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.haywardomnilogic.internal.handler;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.haywardomnilogic.internal.HaywardBindingConstants;
import org.openhab.binding.haywardomnilogic.internal.HaywardException;
import org.openhab.binding.haywardomnilogic.internal.HaywardThingHandler;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Channel;
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 org.openhab.core.types.RefreshType;
import org.openhab.core.types.State;
import org.openhab.core.types.StateDescriptionFragment;
import org.openhab.core.types.StateDescriptionFragmentBuilder;
import org.openhab.core.types.StateOption;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Pump Handler
*
* @author Matt Myers - Initial contribution
*/
@NonNullByDefault
public class HaywardPumpHandler extends HaywardThingHandler {
private final Logger logger = LoggerFactory.getLogger(HaywardPumpHandler.class);
private Map<String, State> channelStates = new HashMap<>();
public HaywardPumpHandler(Thing thing) {
super(thing);
}
@Override
public void initialize() {
try {
setStateDescriptions();
updateStatus(ThingStatus.ONLINE);
} catch (HaywardException e) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"Unable to setPumpHandler StateDescriptions");
}
}
@Override
public void setStateDescriptions() throws HaywardException {
List<StateOption> options = new ArrayList<>();
String option;
Bridge bridge = getBridge();
if (bridge != null) {
HaywardBridgeHandler bridgehandler = (HaywardBridgeHandler) bridge.getHandler();
if (bridgehandler != null) {
// Set Pump % min and max speeds
Channel ch = thing.getChannel(HaywardBindingConstants.CHANNEL_PUMP_SPEEDPERCENT);
if (ch != null) {
StateDescriptionFragment stateDescriptionFragment = StateDescriptionFragmentBuilder.create()
.withMinimum(new BigDecimal(
getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_MINSPEED)))
.withMaximum(new BigDecimal(
getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_MAXSPEED)))
.build();
bridgehandler.updateChannelStateDescriptionFragment(ch, stateDescriptionFragment);
}
// Set Pump Speed RPM min and max speeds
ch = thing.getChannel(HaywardBindingConstants.CHANNEL_PUMP_SPEEDRPM);
if (ch != null) {
StateDescriptionFragment stateDescriptionFragment = StateDescriptionFragmentBuilder.create()
.withMinimum(new BigDecimal(
getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_MINRPM)))
.withMaximum(new BigDecimal(
getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_MAXRPM)))
.build();
bridgehandler.updateChannelStateDescriptionFragment(ch, stateDescriptionFragment);
}
// Set Pump Speed States
ch = thing.getChannel(HaywardBindingConstants.CHANNEL_PUMP_SPEEDSELECT);
if (ch != null) {
options.add(new StateOption("0", "Off"));
option = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_LOWSPEED);
if (option != null) {
options.add(new StateOption(option, "Low"));
}
option = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_MEDSPEED);
if (option != null) {
options.add(new StateOption(option, "Medium"));
}
option = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_HIGHSPEED);
if (option != null) {
options.add(new StateOption(option, "High"));
}
option = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_CUSTOMSPEED);
if (option != null) {
options.add(new StateOption(option, "Custom"));
}
StateDescriptionFragment stateDescriptionFragment = StateDescriptionFragmentBuilder.create()
.withOptions(options).build();
bridgehandler.updateChannelStateDescriptionFragment(ch, stateDescriptionFragment);
}
}
}
}
@Override
public void getTelemetry(String xmlResponse) throws HaywardException {
List<String> systemIDs = new ArrayList<>();
List<String> data = new ArrayList<>();
Bridge bridge = getBridge();
if (bridge != null) {
HaywardBridgeHandler bridgehandler = (HaywardBridgeHandler) bridge.getHandler();
if (bridgehandler != null) {
systemIDs = bridgehandler.evaluateXPath("//Pump/@systemId", xmlResponse);
String thingSystemID = getThing().getUID().getId();
for (int i = 0; i < systemIDs.size(); i++) {
if (systemIDs.get(i).equals(thingSystemID)) {
// Speed percent
data = bridgehandler.evaluateXPath("//Pump/@pumpSpeed", xmlResponse);
updateData(HaywardBindingConstants.CHANNEL_PUMP_SPEEDPERCENT, data.get(i));
// Speed rpm
String pumpMaxRpm = getThing().getProperties()
.get(HaywardBindingConstants.PROPERTY_PUMP_MAXRPM);
if (pumpMaxRpm != null) {
Integer rpmSpeed = (Integer.parseInt(data.get(i))) * (Integer.parseInt(pumpMaxRpm)) / 100;
updateData(HaywardBindingConstants.CHANNEL_PUMP_SPEEDRPM, rpmSpeed.toString());
}
if (data.get(i).equals("0")) {
updateData(HaywardBindingConstants.CHANNEL_PUMP_ENABLE, "0");
} else {
updateData(HaywardBindingConstants.CHANNEL_PUMP_ENABLE, "1");
}
// Speed Select
data = bridgehandler.evaluateXPath("//Pump/@pumpSpeed", xmlResponse);
updateData(HaywardBindingConstants.CHANNEL_PUMP_SPEEDSELECT, data.get(i));
// State
data = bridgehandler.evaluateXPath("//Pump/@pumpState", xmlResponse);
updateData(HaywardBindingConstants.CHANNEL_PUMP_STATE, data.get(i));
// lastSpeed
data = bridgehandler.evaluateXPath("//Pump/@lastSpeed", xmlResponse);
updateData(HaywardBindingConstants.CHANNEL_PUMP_LASTSPEED, data.get(i));
channelStates.putAll(updateData(HaywardBindingConstants.CHANNEL_PUMP_LASTSPEED, data.get(i)));
}
}
this.updateStatus(ThingStatus.ONLINE);
} else {
this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED);
}
}
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
if ((command instanceof RefreshType)) {
return;
}
String systemID = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_SYSTEM_ID);
String poolID = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_BOWID);
String pumpMinSpeed = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_MINSPEED);
String pumpMaxSpeed = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_MAXSPEED);
String pumpMaxRpm = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_MAXRPM);
Bridge bridge = getBridge();
if (bridge != null) {
HaywardBridgeHandler bridgehandler = (HaywardBridgeHandler) bridge.getHandler();
if (bridgehandler != null) {
String cmdString = this.cmdToString(command);
try {
switch (channelUID.getId()) {
case HaywardBindingConstants.CHANNEL_PUMP_ENABLE:
if (command == OnOffType.ON) {
cmdString = channelStates.get(HaywardBindingConstants.CHANNEL_PUMP_LASTSPEED)
.format("%d");
} else {
cmdString = "0";
}
break;
case HaywardBindingConstants.CHANNEL_PUMP_SPEEDPERCENT:
if (pumpMinSpeed != null && pumpMaxSpeed != null) {
if (Integer.parseInt(cmdString) > 0
&& Integer.parseInt(cmdString) < Integer.parseInt(pumpMinSpeed)) {
cmdString = pumpMinSpeed;
} else if (Integer.parseInt(cmdString) > Integer.parseInt(pumpMaxSpeed)) {
cmdString = pumpMaxSpeed;
}
}
case HaywardBindingConstants.CHANNEL_PUMP_SPEEDRPM:
// Convert cmdString from RPM to Percent
if (pumpMaxRpm != null && pumpMaxSpeed != null && pumpMinSpeed != null) {
cmdString = Integer
.toString((Integer.parseInt(cmdString) * 100 / Integer.parseInt(pumpMaxSpeed)));
if (Integer.parseInt(cmdString) > 0
&& Integer.parseInt(cmdString) < Integer.parseInt(pumpMinSpeed)) {
cmdString = pumpMinSpeed;
} else if (Integer.parseInt(cmdString) > Integer.parseInt(pumpMaxSpeed)) {
cmdString = pumpMaxSpeed;
}
}
break;
case HaywardBindingConstants.CHANNEL_PUMP_SPEEDSELECT:
break;
default:
logger.warn("haywardCommand Unsupported type {}", channelUID);
return;
}
String cmdURL = HaywardBindingConstants.COMMAND_PARAMETERS
+ "<Name>SetUIEquipmentCmd</Name><Parameters>"
+ "<Parameter name=\"Token\" dataType=\"String\">" + bridgehandler.account.token
+ "</Parameter>" + "<Parameter name=\"MspSystemID\" dataType=\"int\">"
+ bridgehandler.account.mspSystemID + "</Parameter>"
+ "<Parameter name=\"PoolID\" dataType=\"int\">" + poolID + "</Parameter>"
+ "<Parameter name=\"EquipmentID\" dataType=\"int\">" + systemID + "</Parameter>"
+ "<Parameter name=\"IsOn\" dataType=\"int\">" + cmdString + "</Parameter>"
+ HaywardBindingConstants.COMMAND_SCHEDULE + "</Parameters></Request>";
// *****Send Command to Hayward server
String xmlResponse = bridgehandler.httpXmlResponse(cmdURL);
String status = bridgehandler.evaluateXPath("//Parameter[@name='Status']/text()", xmlResponse)
.get(0);
if (!("0".equals(status))) {
logger.debug("haywardCommand XML response: {}", xmlResponse);
return;
}
} catch (HaywardException e) {
logger.debug("Unable to send command to Hayward's server {}:{}:{}",
bridgehandler.config.endpointUrl, bridgehandler.config.username, e.getMessage());
} catch (InterruptedException e) {
return;
}
this.updateStatus(ThingStatus.ONLINE);
} else {
this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED);
}
}
}
}

View File

@ -1,62 +0,0 @@
/**
* Copyright (c) 2010-2021 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.haywardomnilogic.internal.handler;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.haywardomnilogic.internal.HaywardBindingConstants;
import org.openhab.binding.haywardomnilogic.internal.HaywardException;
import org.openhab.binding.haywardomnilogic.internal.HaywardThingHandler;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
/**
* The Sensor Handler
*
* @author Matt Myers - Initial contribution
*/
@NonNullByDefault
public class HaywardSensorHandler extends HaywardThingHandler {
public HaywardSensorHandler(Thing thing) {
super(thing);
}
@Override
public void getTelemetry(String xmlResponse) throws HaywardException {
List<String> systemIDs = new ArrayList<>();
List<String> data = new ArrayList<>();
Bridge bridge = getBridge();
if (bridge != null) {
HaywardBridgeHandler bridgehandler = (HaywardBridgeHandler) bridge.getHandler();
if (bridgehandler != null) {
systemIDs = bridgehandler.evaluateXPath("//Sensor/@systemId", xmlResponse);
data = bridgehandler.evaluateXPath("//Sensor/@relayState", xmlResponse);
String thingSystemID = getThing().getUID().getId();
for (int i = 0; i < systemIDs.size(); i++) {
if (systemIDs.get(i).equals(thingSystemID)) {
updateData(HaywardBindingConstants.CHANNEL_RELAY_STATE, data.get(i));
}
}
this.updateStatus(ThingStatus.ONLINE);
} else {
this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED);
}
}
}
}

View File

@ -12,6 +12,7 @@
*/
package org.openhab.binding.haywardomnilogic.internal.handler;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
@ -21,12 +22,15 @@ import org.openhab.binding.haywardomnilogic.internal.HaywardException;
import org.openhab.binding.haywardomnilogic.internal.HaywardThingHandler;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Channel;
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 org.openhab.core.types.RefreshType;
import org.openhab.core.types.StateDescriptionFragment;
import org.openhab.core.types.StateDescriptionFragmentBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -43,6 +47,37 @@ public class HaywardVirtualHeaterHandler extends HaywardThingHandler {
super(thing);
}
@Override
public void initialize() {
try {
setStateDescriptions();
updateStatus(ThingStatus.ONLINE);
} catch (HaywardException e) {
updateStatus(ThingStatus.OFFLINE);
}
}
@Override
public void setStateDescriptions() throws HaywardException {
Bridge bridge = getBridge();
if (bridge != null) {
HaywardBridgeHandler bridgehandler = (HaywardBridgeHandler) bridge.getHandler();
if (bridgehandler != null) {
// Set heater min and max speeds
Channel ch = thing.getChannel(HaywardBindingConstants.CHANNEL_VIRTUALHEATER_CURRENTSETPOINT);
if (ch != null) {
StateDescriptionFragment stateDescriptionFragment = StateDescriptionFragmentBuilder.create()
.withMinimum(new BigDecimal(getThing().getProperties()
.get(HaywardBindingConstants.PROPERTY_VIRTUALHEATER_MINSETTABLEWATERTEMP)))
.withMaximum(new BigDecimal(getThing().getProperties()
.get(HaywardBindingConstants.PROPERTY_VIRTUALHEATER_MAXSETTABLEWATERTEMP)))
.build();
bridgehandler.updateChannelStateDescriptionFragment(ch, stateDescriptionFragment);
}
}
}
}
@Override
public void getTelemetry(String xmlResponse) throws HaywardException {
List<String> systemIDs = new ArrayList<>();
@ -82,6 +117,10 @@ public class HaywardVirtualHeaterHandler extends HaywardThingHandler {
String systemID = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_SYSTEM_ID);
String poolID = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_BOWID);
String heaterMinSetTemp = getThing().getProperties()
.get(HaywardBindingConstants.PROPERTY_VIRTUALHEATER_MINSETTABLEWATERTEMP);
String heaterMaxSetTemp = getThing().getProperties()
.get(HaywardBindingConstants.PROPERTY_VIRTUALHEATER_MAXSETTABLEWATERTEMP);
Bridge bridge = getBridge();
if (bridge != null) {
@ -111,6 +150,14 @@ public class HaywardVirtualHeaterHandler extends HaywardThingHandler {
break;
case HaywardBindingConstants.CHANNEL_VIRTUALHEATER_CURRENTSETPOINT:
if (heaterMinSetTemp != null && heaterMaxSetTemp != null) {
if (Integer.parseInt(cmdString) < Integer.parseInt(heaterMinSetTemp)) {
cmdString = heaterMinSetTemp;
} else if (Integer.parseInt(cmdString) > Integer.parseInt(heaterMaxSetTemp)) {
cmdString = heaterMaxSetTemp;
}
}
cmdURL = HaywardBindingConstants.COMMAND_PARAMETERS
+ "<Name>SetUIHeaterCmd</Name><Parameters>"
+ "<Parameter name=\"Token\" dataType=\"String\">" + bridgehandler.account.token

View File

@ -23,7 +23,7 @@
</channels>
<properties>
<property name="Vendor">Hayward</property>
<property name="vendor">Hayward</property>
</properties>
<representation-property>systemID</representation-property>

View File

@ -17,7 +17,14 @@
</channels>
<properties>
<property name="Vendor">Hayward</property>
<property name="vendor">Hayward</property>
<property name="type"></property>
<property name="sharedType"></property>
<property name="sharedPriority"></property>
<property name="sharedEquipmentSystemID"></property>
<property name="supportsSpillover"></property>
<property name="sizeInGallons"></property>
</properties>
<representation-property>systemID</representation-property>

View File

@ -24,7 +24,11 @@
</channels>
<properties>
<property name="Vendor">Hayward</property>
<property name="vendor">Hayward</property>
<property name="chlorSharedType"></property>
<property name="chlorMode"></property>
<property name="cellType"></property>
<property name="dispenserType"></property>
</properties>
<representation-property>systemID</representation-property>

View File

@ -18,7 +18,8 @@
</channels>
<properties>
<property name="Vendor">Hayward</property>
<property name="vendor">Hayward</property>
<property name="colorlogicType"></property>
</properties>
<representation-property>systemID</representation-property>

View File

@ -14,17 +14,27 @@
<channels>
<channel id="filterEnable" typeId="system.power"/>
<channel id="filterValvePosition" typeId="valvePosition"/>
<channel id="filterSpeed" typeId="filterSpeed"/>
<channel id="filterSpeedPercent" typeId="filterSpeedPercent"/>
<channel id="filterSpeedRpm" typeId="filterSpeedRpm"/>
<channel id="filterSpeedSelect" typeId="filterSpeedSelect"/>
<channel id="filterState" typeId="filterState"/>
<channel id="filterLastSpeed" typeId="filterLastSpeed"/>
</channels>
<properties>
<property name="Vendor">Hayward</property>
<property name="Min Pump Percent"></property>
<property name="Max Pump Percent"></property>
<property name="Min Pump RPM"></property>
<property name="Max Pump RPM"></property>
<property name="vendor">Hayward</property>
<property name="filterSharedType"></property>
<property name="filterType"></property>
<property name="primingEnabled"></property>
<property name="minFilterPercent"></property>
<property name="maxFilterPercent"></property>
<property name="minFilterRPM"></property>
<property name="maxFilterRPM"></property>
<property name="lowFilterSpeed"></property>
<property name="mediumFilterSpeed"></property>
<property name="highFilterSpeed"></property>
<property name="customFilterSpeed"></property>
<property name="freezeProtectOverrideInterval"></property>
</properties>
<representation-property>systemID</representation-property>
@ -44,11 +54,33 @@
</state>
</channel-type>
<channel-type id="filterSpeed">
<channel-type id="filterSpeedPercent">
<item-type>Number:Dimensionless</item-type>
<label>Filter Speed</label>
<description>Filter Speed in %</description>
<state min="0" max="100" step="1.0" pattern="%d %unit%" readOnly="false"/>
<label>Filter Speed %</label>
<description>Filter Speed (%)</description>
<state min="0" max="100" step="5" pattern="%d %unit%" readOnly="false"/>
</channel-type>
<channel-type id="filterSpeedRpm">
<item-type>Number</item-type>
<label>Filter Speed RPM</label>
<description>Filter Speed (RPM)</description>
<state min="0" max="3600" step="200" pattern="%d" readOnly="false"/>
</channel-type>
<channel-type id="filterSpeedSelect">
<item-type>String</item-type>
<label>Filter Speed States</label>
<description>Filter Speed States</description>
<state readOnly="false">
<options>
<option value="0">Off</option>
<option value="33">Low</option>
<option value="66">Medium</option>
<option value="100">High</option>
<option value="100">Custom</option>
</options>
</state>
</channel-type>
<channel-type id="filterState">
@ -76,7 +108,7 @@
<channel-type id="filterLastSpeed">
<item-type>Number:Dimensionless</item-type>
<label>Last Speed</label>
<description>Last Speed</description>
<description>Last Speed (%)</description>
<state pattern="%d %unit%" readOnly="true"/>
</channel-type>

View File

@ -17,16 +17,25 @@
</channels>
<properties>
<property name="Vendor">Hayward</property>
<property name="vendor">Hayward</property>
<property name="type"></property>
<property name="heaterType"></property>
<property name="sharedEquipmentSystemID"></property>
</properties>
<representation-property>systemID</representation-property>
</thing-type>
<channel-type id="state">
<item-type>Number</item-type>
<item-type>String</item-type>
<label>Heater State</label>
<description>Heater State</description>
<state readOnly="true"/>
<state readOnly="true">
<options>
<option value="0">Off</option>
<option value="1">Heating</option>
<option value="2">Paused</option>
</options>
</state>
</channel-type>
<channel-type id="enable">

View File

@ -13,25 +13,87 @@
<description>Pump</description>
<channels>
<channel id="pumpEnable" typeId="system.power"/>
<channel id="pumpSpeed" typeId="pumpSpeed"/>
<channel id="pumpSpeedPercent" typeId="pumpSpeedPercent"/>
<channel id="pumpSpeedRpm" typeId="pumpSpeedRpm"/>
<channel id="pumpSpeedSelect" typeId="pumpSpeedSelect"/>
<channel id="pumpState" typeId="pumpState"/>
<channel id="pumpLastSpeed" typeId="pumpLastSpeed"/>
</channels>
<properties>
<property name="Vendor">Hayward</property>
<property name="Min Pump Percent"></property>
<property name="Max Pump Percent"></property>
<property name="Min Pump RPM"></property>
<property name="Max Pump RPM"></property>
<property name="vendor">Hayward</property>
<property name="pumpType"></property>
<property name="pumpFunction"></property>
<property name="pumpPrimingEnabled"></property>
<property name="minPumpPercent"></property>
<property name="maxPumpPercent"></property>
<property name="minPumpRPM"></property>
<property name="maxPumpRPM"></property>
<property name="lowPumpSpeed"></property>
<property name="mediumPumpSpeed"></property>
<property name="highPumpSpeed"></property>
<property name="customPumpSpeed"></property>
</properties>
<representation-property>systemID</representation-property>
</thing-type>
<channel-type id="pumpSpeed">
<channel-type id="pumpSpeedPercent">
<item-type>Number:Dimensionless</item-type>
<label>Pump Speed in %</label>
<description>Pump Speed</description>
<state min="0" max="100" step="1.0" pattern="%d %unit%" readOnly="false"/>
<label>Pump Speed %</label>
<description>Pump Speed (%)</description>
<state min="0" max="100" step="1" pattern="%d %unit%" readOnly="false"/>
</channel-type>
<channel-type id="pumpSpeedRpm">
<item-type>Number:Dimensionless</item-type>
<label>Pump Speed RPM</label>
<description>Pump Speed (RPM)</description>
<state min="0" max="3600" step="200" pattern="%d" readOnly="false"/>
</channel-type>
<channel-type id="pumpSpeedSelect">
<item-type>String</item-type>
<label>Pump Speed States</label>
<description>Pump Speed States</description>
<state readOnly="false">
<options>
<option value="0">Off</option>
<option value="33">Low</option>
<option value="66">Medium</option>
<option value="100">High</option>
<option value="100">Custom</option>
</options>
</state>
</channel-type>
<channel-type id="pumpState">
<item-type>String</item-type>
<label>Pump State</label>
<description>Pump State</description>
<state readOnly="true">
<options>
<option value="0">Off</option>
<option value="1">Running</option>
<option value="2">Priming</option>
<option value="3">Waiting to Turn Off</option>
<option value="4">Waiting to Turn Off Manual</option>
<option value="5">Heater Extend</option>
<option value="6">Heater Cool Down</option>
<option value="7">Suspended</option>
<option value="8">CSAD Extend</option>
<option value="9">Superchlorinate</option>
<option value="10">Force Priming</option>
<option value="11">Waiting for Pump to Turn Off</option>
</options>
</state>
</channel-type>
<channel-type id="pumpLastSpeed">
<item-type>Number:Dimensionless</item-type>
<label>Last Speed</label>
<description>Last Speed (%)</description>
<state pattern="%d %unit%" readOnly="true"/>
</channel-type>
</thing:thing-descriptions>

View File

@ -16,7 +16,9 @@
</channels>
<properties>
<property name="Vendor">Hayward</property>
<property name="vendor">Hayward</property>
<property name="relayType"></property>
<property name="relayFunction"></property>
</properties>
<representation-property>systemID</representation-property>

View File

@ -1,39 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="haywardomnilogic"
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">
<thing-type id="sensor" listed="false">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>
<label>Sensor</label>
<description>Sensor</description>
<channels>
<channel id="sensorData" typeId="data"/>
</channels>
<properties>
<property name="Vendor">Hayward</property>
</properties>
<representation-property>systemID</representation-property>
</thing-type>
<channel-type id="bow">
<item-type>Number</item-type>
<label>Body of Water</label>
<description>The Body of Water ID</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="data">
<item-type>Number</item-type>
<label>Data</label>
<description>Sensor Data</description>
<state readOnly="true"/>
</channel-type>
</thing:thing-descriptions>

View File

@ -18,7 +18,11 @@
</channels>
<properties>
<property name="Vendor">Hayward</property>
<property name="vendor">Hayward</property>
<property name="sharedType"></property>
<property name="minSettableWaterTemp"></property>
<property name="maxSettableWaterTemp"></property>
<property name="maxWaterTemp"></property>
</properties>
<representation-property>systemID</representation-property>
</thing-type>