diff --git a/bundles/org.openhab.binding.haywardomnilogic/README.md b/bundles/org.openhab.binding.haywardomnilogic/README.md index 0d7fa6dc347..24090354ca3 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/README.md +++ b/bundles/org.openhab.binding.haywardomnilogic/README.md @@ -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" } - -``` - diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/HaywardBindingConstants.java b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/HaywardBindingConstants.java index 2346547e93e..be71e04934e 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/HaywardBindingConstants.java +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/HaywardBindingConstants.java @@ -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 = ""; diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/HaywardDynamicStateDescriptionProvider.java b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/HaywardDynamicStateDescriptionProvider.java new file mode 100644 index 00000000000..2e44ff1f6c8 --- /dev/null +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/HaywardDynamicStateDescriptionProvider.java @@ -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 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); + } +} diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/HaywardHandlerFactory.java b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/HaywardHandlerFactory.java index cba37b0749d..06f4af1320d 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/HaywardHandlerFactory.java +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/HaywardHandlerFactory.java @@ -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 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); diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/HaywardThingHandler.java b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/HaywardThingHandler.java index 89f311fccff..5bbbe9dfc53 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/HaywardThingHandler.java +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/HaywardThingHandler.java @@ -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 updateData(String channelID, String data) { + Map 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; } } diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/discovery/HaywardDiscoveryService.java b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/discovery/HaywardDiscoveryService.java index a6bea2b114e..f40dd4a17c6 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/discovery/HaywardDiscoveryService.java +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/discovery/HaywardDiscoveryService.java @@ -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 bowProperty1 = bridgehandler.evaluateXPath("//Body-of-water/Type/text()", xmlResponse); + final List bowProperty2 = bridgehandler.evaluateXPath("//Body-of-water/Shared-Type/text()", + xmlResponse); + final List bowProperty3 = bridgehandler.evaluateXPath("//Body-of-water/Shared-Priority/text()", + xmlResponse); + final List bowProperty4 = bridgehandler + .evaluateXPath("//Body-of-water/Shared-Equipment-System-ID/text()", xmlResponse); + final List bowProperty5 = bridgehandler.evaluateXPath("//Body-of-water/Supports-Spillover/text()", + xmlResponse); + final List 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 chlorinatorProperty1 = bridgehandler + .evaluateXPath("//Body-of-water/Chlorinator/Shared-Type/text()", xmlResponse); + final List chlorinatorProperty2 = bridgehandler.evaluateXPath("//Body-of-water/Chlorinator/Mode/text()", + xmlResponse); + final List chlorinatorProperty3 = bridgehandler + .evaluateXPath("//Body-of-water/Chlorinator/Cell-Type/text()", xmlResponse); + final List 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 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 filterProperty1 = bridgehandler.evaluateXPath("//Filter/Min-Pump-Speed/text()", xmlResponse); - final List filterProperty2 = bridgehandler.evaluateXPath("//Filter/Max-Pump-Speed/text()", xmlResponse); - final List filterProperty3 = bridgehandler.evaluateXPath("//Filter/Min-Pump-RPM/text()", xmlResponse); - final List filterProperty4 = bridgehandler.evaluateXPath("//Filter/Max-Pump-RPM/text()", xmlResponse); + final List filterProperty1 = bridgehandler.evaluateXPath("//Body-of-water/Filter/Shared-Type/text()", + xmlResponse); + final List filterProperty2 = bridgehandler.evaluateXPath("//Body-of-water/Filter/Filter-Type/text()", + xmlResponse); + final List filterProperty3 = bridgehandler + .evaluateXPath("//Body-of-water/Filter/Priming-Enabled/text()", xmlResponse); + final List filterProperty4 = bridgehandler.evaluateXPath("//Body-of-water/Filter/Min-Pump-Speed/text()", + xmlResponse); + final List filterProperty5 = bridgehandler.evaluateXPath("//Body-of-water/Filter/Max-Pump-Speed/text()", + xmlResponse); + final List filterProperty6 = bridgehandler.evaluateXPath("//Body-of-water/Filter/Min-Pump-RPM/text()", + xmlResponse); + final List filterProperty7 = bridgehandler.evaluateXPath("//Body-of-water/Filter/Max-Pump-RPM/text()", + xmlResponse); + final List filterProperty8 = bridgehandler + .evaluateXPath("//Body-of-water/Filter/Vsp-Low-Pump-Speed/text()", xmlResponse); + final List filterProperty9 = bridgehandler + .evaluateXPath("//Body-of-water/Filter/Vsp-Medium-Pump-Speed/text()", xmlResponse); + final List filterProperty10 = bridgehandler + .evaluateXPath("//Body-of-water/Filter/Vsp-High-Pump-Speed/text()", xmlResponse); + final List filterProperty11 = bridgehandler + .evaluateXPath("//Body-of-water/Filter/Vsp-Custom-Pump-Speed/text()", xmlResponse); + final List 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 heaterProperty1 = bridgehandler + .evaluateXPath("//Body-of-water/Heater/Operation/Heater-Equipment/Type/text()", xmlResponse); + final List heaterProperty2 = bridgehandler + .evaluateXPath("//Body-of-water/Heater/Operation/Heater-Equipment/Heater-Type/text()", xmlResponse); + final List 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 pumpProperty1 = bridgehandler.evaluateXPath("//Pump/Min-Pump-Speed/text()", xmlResponse); - final List pumpProperty2 = bridgehandler.evaluateXPath("//Pump/Max-Pump-Speed/text()", xmlResponse); - final List pumpProperty3 = bridgehandler.evaluateXPath("//Pump/Min-Pump-RPM/text()", xmlResponse); - final List pumpProperty4 = bridgehandler.evaluateXPath("//Pump/Max-Pump-RPM/text()", xmlResponse); + final List pumpProperty1 = bridgehandler.evaluateXPath("//Body-of-water/Pump/Type/text()", xmlResponse); + final List pumpProperty2 = bridgehandler.evaluateXPath("//Body-of-water/Pump/Function/text()", + xmlResponse); + final List pumpProperty3 = bridgehandler.evaluateXPath("//Body-of-water/Pump/Priming-Enabled/text()", + xmlResponse); + final List pumpProperty4 = bridgehandler.evaluateXPath("//Body-of-water/Pump/Min-Pump-Speed/text()", + xmlResponse); + final List pumpProperty5 = bridgehandler.evaluateXPath("//Body-of-water/Pump/Max-Pump-Speed/text()", + xmlResponse); + final List pumpProperty6 = bridgehandler.evaluateXPath("//Body-of-water/Pump/Min-Pump-RPM/text()", + xmlResponse); + final List pumpProperty7 = bridgehandler.evaluateXPath("//Body-of-water/Pump/Max-Pump-RPM/text()", + xmlResponse); + final List pumpProperty8 = bridgehandler.evaluateXPath("//Body-of-water/Pump/Vsp-Low-Pump-Speed/text()", + xmlResponse); + final List pumpProperty9 = bridgehandler + .evaluateXPath("//Body-of-water/Pump/Vsp-Medium-Pump-Speed/text()", xmlResponse); + final List pumpProperty10 = bridgehandler + .evaluateXPath("//Body-of-water/Pump/Vsp-High-Pump-Speed/text()", xmlResponse); + final List 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 relayProperty1 = bridgehandler.evaluateXPath("//Backyard//Relay/Type/text()", xmlResponse); + final List 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 virtualHeaterProperty1 = bridgehandler + .evaluateXPath("//Body-of-water/Heater/Shared-Type/text()", xmlResponse); + final List virtualHeaterProperty2 = bridgehandler + .evaluateXPath("//Body-of-water/Heater/Min-Settable-Water-Temp/text()", xmlResponse); + final List virtualHeaterProperty3 = bridgehandler + .evaluateXPath("//Body-of-water/Heater/Max-Settable-Water-Temp/text()", xmlResponse); + final List 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, Integer> additionalPropertyConsumer) { - List systemIDs = bridgehandler.evaluateXPath("//" + xmlSearchTerm + "/System-Id/text()", xmlResponse); + List systemIDs = bridgehandler.evaluateXPath("//Backyard//" + xmlSearchTerm + "/System-Id/text()", + xmlResponse); List 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 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 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); } } diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardBridgeHandler.java b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardBridgeHandler.java index 13792f3e989..0558d4dc692 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardBridgeHandler.java +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardBridgeHandler.java @@ -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 = "GetAPIDef" + "" + account.token + "" + "" + account.mspSystemID + ";" @@ -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; diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardFilterHandler.java b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardFilterHandler.java index 4c0dc646381..d0b6babb487 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardFilterHandler.java +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardFilterHandler.java @@ -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 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 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); diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardPumpHandler.java b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardPumpHandler.java new file mode 100644 index 00000000000..5362a75d1e0 --- /dev/null +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardPumpHandler.java @@ -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 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 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 systemIDs = new ArrayList<>(); + List 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 + + "SetUIEquipmentCmd" + + "" + bridgehandler.account.token + + "" + "" + + bridgehandler.account.mspSystemID + "" + + "" + poolID + "" + + "" + systemID + "" + + "" + cmdString + "" + + HaywardBindingConstants.COMMAND_SCHEDULE + ""; + + // *****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); + } + } + } +} diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardSensorHandler.java b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardSensorHandler.java deleted file mode 100644 index a811e696079..00000000000 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardSensorHandler.java +++ /dev/null @@ -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 systemIDs = new ArrayList<>(); - List 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); - } - } - } -} diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardVirtualHeaterHandler.java b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardVirtualHeaterHandler.java index b06a7e96b29..c54c76b1917 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardVirtualHeaterHandler.java +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/java/org/openhab/binding/haywardomnilogic/internal/handler/HaywardVirtualHeaterHandler.java @@ -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 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 + "SetUIHeaterCmd" + "" + bridgehandler.account.token diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/backyard.xml b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/backyard.xml index 16983ad5157..8883111519d 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/backyard.xml +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/backyard.xml @@ -23,7 +23,7 @@ - Hayward + Hayward systemID diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/bow.xml b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/bow.xml index ca07c5cf92b..3363189dc8a 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/bow.xml +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/bow.xml @@ -17,7 +17,14 @@ - Hayward + Hayward + + + + + + + systemID diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/chlorinator.xml b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/chlorinator.xml index a0e6bd8849a..1173def5646 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/chlorinator.xml +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/chlorinator.xml @@ -24,7 +24,11 @@ - Hayward + Hayward + + + + systemID diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/colorlogic.xml b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/colorlogic.xml index 25d882eb244..14938105040 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/colorlogic.xml +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/colorlogic.xml @@ -18,7 +18,8 @@ - Hayward + Hayward + systemID diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/filter.xml b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/filter.xml index 886904432da..f1182f1957d 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/filter.xml +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/filter.xml @@ -14,17 +14,27 @@ - + + + - Hayward - - - - + Hayward + + + + + + + + + + + + systemID @@ -44,11 +54,33 @@ - + Number:Dimensionless - - Filter Speed in % - + + Filter Speed (%) + + + + + Number + + Filter Speed (RPM) + + + + + String + + Filter Speed States + + + + + + + + + @@ -76,7 +108,7 @@ Number:Dimensionless - Last Speed + Last Speed (%) diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/heater.xml b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/heater.xml index 960d9a9f720..be76ca46ded 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/heater.xml +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/heater.xml @@ -17,16 +17,25 @@ - Hayward + Hayward + + + systemID - Number + String Heater State - + + + + + + + diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/pump.xml b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/pump.xml index d9e43f45e44..13ce23f3124 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/pump.xml +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/pump.xml @@ -13,25 +13,87 @@ Pump - + + + + + - Hayward - - - - + Hayward + + + + + + + + + + + systemID - + Number:Dimensionless - - Pump Speed - + + Pump Speed (%) + + + + + Number:Dimensionless + + Pump Speed (RPM) + + + + + String + + Pump Speed States + + + + + + + + + + + + + String + + Pump State + + + + + + + + + + + + + + + + + + + + Number:Dimensionless + + Last Speed (%) + diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/relay.xml b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/relay.xml index 5c2b70e3b30..4427011b2da 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/relay.xml +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/relay.xml @@ -16,7 +16,9 @@ - Hayward + Hayward + + systemID diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/sensor.xml b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/sensor.xml deleted file mode 100644 index d33fc562a70..00000000000 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/sensor.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - Sensor - - - - - - Hayward - - systemID - - - - - Number - - The Body of Water ID - - - - - Number - - Sensor Data - - - - diff --git a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/virtualHeater.xml b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/virtualHeater.xml index 65c502e39d8..f7fbd6a6504 100644 --- a/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/virtualHeater.xml +++ b/bundles/org.openhab.binding.haywardomnilogic/src/main/resources/OH-INF/thing/virtualHeater.xml @@ -18,7 +18,11 @@ - Hayward + Hayward + + + + systemID