2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.haywardomnilogic.internal.handler;
15 import java.math.BigDecimal;
16 import java.util.ArrayList;
17 import java.util.HashMap;
18 import java.util.List;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.openhab.binding.haywardomnilogic.internal.HaywardBindingConstants;
23 import org.openhab.binding.haywardomnilogic.internal.HaywardException;
24 import org.openhab.binding.haywardomnilogic.internal.HaywardThingHandler;
25 import org.openhab.core.library.types.OnOffType;
26 import org.openhab.core.thing.Bridge;
27 import org.openhab.core.thing.Channel;
28 import org.openhab.core.thing.ChannelUID;
29 import org.openhab.core.thing.Thing;
30 import org.openhab.core.thing.ThingStatus;
31 import org.openhab.core.thing.ThingStatusDetail;
32 import org.openhab.core.types.Command;
33 import org.openhab.core.types.RefreshType;
34 import org.openhab.core.types.State;
35 import org.openhab.core.types.StateDescriptionFragment;
36 import org.openhab.core.types.StateDescriptionFragmentBuilder;
37 import org.openhab.core.types.StateOption;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
44 * @author Matt Myers - Initial contribution
47 public class HaywardPumpHandler extends HaywardThingHandler {
48 private final Logger logger = LoggerFactory.getLogger(HaywardPumpHandler.class);
49 private Map<String, State> channelStates = new HashMap<>();
51 public HaywardPumpHandler(Thing thing) {
56 public void initialize() {
58 setStateDescriptions();
59 updateStatus(ThingStatus.ONLINE);
60 } catch (HaywardException e) {
61 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
62 "Unable to setPumpHandler StateDescriptions");
67 public void setStateDescriptions() throws HaywardException {
68 List<StateOption> options = new ArrayList<>();
71 Bridge bridge = getBridge();
73 HaywardBridgeHandler bridgehandler = (HaywardBridgeHandler) bridge.getHandler();
74 if (bridgehandler != null) {
75 // Set Pump % min and max speeds
76 Channel ch = thing.getChannel(HaywardBindingConstants.CHANNEL_PUMP_SPEEDPERCENT);
78 StateDescriptionFragment stateDescriptionFragment = StateDescriptionFragmentBuilder.create()
79 .withMinimum(new BigDecimal(
80 getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_MINSPEED)))
81 .withMaximum(new BigDecimal(
82 getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_MAXSPEED)))
84 bridgehandler.updateChannelStateDescriptionFragment(ch, stateDescriptionFragment);
87 // Set Pump Speed RPM min and max speeds
88 ch = thing.getChannel(HaywardBindingConstants.CHANNEL_PUMP_SPEEDRPM);
90 StateDescriptionFragment stateDescriptionFragment = StateDescriptionFragmentBuilder.create()
91 .withMinimum(new BigDecimal(
92 getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_MINRPM)))
93 .withMaximum(new BigDecimal(
94 getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_MAXRPM)))
96 bridgehandler.updateChannelStateDescriptionFragment(ch, stateDescriptionFragment);
99 // Set Pump Speed States
100 ch = thing.getChannel(HaywardBindingConstants.CHANNEL_PUMP_SPEEDSELECT);
102 options.add(new StateOption("0", "Off"));
103 option = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_LOWSPEED);
104 if (option != null) {
105 options.add(new StateOption(option, "Low"));
107 option = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_MEDSPEED);
108 if (option != null) {
109 options.add(new StateOption(option, "Medium"));
111 option = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_HIGHSPEED);
112 if (option != null) {
113 options.add(new StateOption(option, "High"));
115 option = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_CUSTOMSPEED);
116 if (option != null) {
117 options.add(new StateOption(option, "Custom"));
120 StateDescriptionFragment stateDescriptionFragment = StateDescriptionFragmentBuilder.create()
121 .withOptions(options).build();
122 bridgehandler.updateChannelStateDescriptionFragment(ch, stateDescriptionFragment);
129 public void getTelemetry(String xmlResponse) throws HaywardException {
130 List<String> systemIDs = new ArrayList<>();
131 List<String> data = new ArrayList<>();
133 Bridge bridge = getBridge();
134 if (bridge != null) {
135 HaywardBridgeHandler bridgehandler = (HaywardBridgeHandler) bridge.getHandler();
136 if (bridgehandler != null) {
137 systemIDs = bridgehandler.evaluateXPath("//Pump/@systemId", xmlResponse);
138 String thingSystemID = getThing().getUID().getId();
139 for (int i = 0; i < systemIDs.size(); i++) {
140 if (systemIDs.get(i).equals(thingSystemID)) {
142 data = bridgehandler.evaluateXPath("//Pump/@pumpSpeed", xmlResponse);
143 updateData(HaywardBindingConstants.CHANNEL_PUMP_SPEEDPERCENT, data.get(i));
146 String pumpMaxRpm = getThing().getProperties()
147 .get(HaywardBindingConstants.PROPERTY_PUMP_MAXRPM);
148 if (pumpMaxRpm != null) {
149 Integer rpmSpeed = (Integer.parseInt(data.get(i))) * (Integer.parseInt(pumpMaxRpm)) / 100;
150 updateData(HaywardBindingConstants.CHANNEL_PUMP_SPEEDRPM, rpmSpeed.toString());
153 if ("0".equals(data.get(i))) {
154 updateData(HaywardBindingConstants.CHANNEL_PUMP_ENABLE, "0");
156 updateData(HaywardBindingConstants.CHANNEL_PUMP_ENABLE, "1");
160 data = bridgehandler.evaluateXPath("//Pump/@pumpSpeed", xmlResponse);
161 updateData(HaywardBindingConstants.CHANNEL_PUMP_SPEEDSELECT, data.get(i));
164 data = bridgehandler.evaluateXPath("//Pump/@pumpState", xmlResponse);
165 updateData(HaywardBindingConstants.CHANNEL_PUMP_STATE, data.get(i));
168 data = bridgehandler.evaluateXPath("//Pump/@lastSpeed", xmlResponse);
169 updateData(HaywardBindingConstants.CHANNEL_PUMP_LASTSPEED, data.get(i));
170 channelStates.putAll(updateData(HaywardBindingConstants.CHANNEL_PUMP_LASTSPEED, data.get(i)));
173 this.updateStatus(ThingStatus.ONLINE);
175 this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED);
181 public void handleCommand(ChannelUID channelUID, Command command) {
182 if ((command instanceof RefreshType)) {
186 String systemID = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_SYSTEM_ID);
187 String poolID = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_BOWID);
188 String pumpMinSpeed = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_MINSPEED);
189 String pumpMaxSpeed = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_MAXSPEED);
190 String pumpMaxRpm = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_PUMP_MAXRPM);
192 Bridge bridge = getBridge();
193 if (bridge != null) {
194 HaywardBridgeHandler bridgehandler = (HaywardBridgeHandler) bridge.getHandler();
195 if (bridgehandler != null) {
196 String cmdString = this.cmdToString(command);
198 switch (channelUID.getId()) {
199 case HaywardBindingConstants.CHANNEL_PUMP_ENABLE:
200 if (command == OnOffType.ON) {
201 cmdString = channelStates.get(HaywardBindingConstants.CHANNEL_PUMP_LASTSPEED)
207 case HaywardBindingConstants.CHANNEL_PUMP_SPEEDPERCENT:
208 if (pumpMinSpeed != null && pumpMaxSpeed != null) {
209 if (Integer.parseInt(cmdString) > 0
210 && Integer.parseInt(cmdString) < Integer.parseInt(pumpMinSpeed)) {
211 cmdString = pumpMinSpeed;
212 } else if (Integer.parseInt(cmdString) > Integer.parseInt(pumpMaxSpeed)) {
213 cmdString = pumpMaxSpeed;
217 case HaywardBindingConstants.CHANNEL_PUMP_SPEEDRPM:
218 // Convert cmdString from RPM to Percent
219 if (pumpMaxRpm != null && pumpMaxSpeed != null && pumpMinSpeed != null) {
221 .toString((Integer.parseInt(cmdString) * 100 / Integer.parseInt(pumpMaxSpeed)));
222 if (Integer.parseInt(cmdString) > 0
223 && Integer.parseInt(cmdString) < Integer.parseInt(pumpMinSpeed)) {
224 cmdString = pumpMinSpeed;
225 } else if (Integer.parseInt(cmdString) > Integer.parseInt(pumpMaxSpeed)) {
226 cmdString = pumpMaxSpeed;
230 case HaywardBindingConstants.CHANNEL_PUMP_SPEEDSELECT:
233 logger.warn("haywardCommand Unsupported type {}", channelUID);
237 String cmdURL = HaywardBindingConstants.COMMAND_PARAMETERS
238 + "<Name>SetUIEquipmentCmd</Name><Parameters>"
239 + "<Parameter name=\"Token\" dataType=\"String\">" + bridgehandler.account.token
240 + "</Parameter>" + "<Parameter name=\"MspSystemID\" dataType=\"int\">"
241 + bridgehandler.account.mspSystemID + "</Parameter>"
242 + "<Parameter name=\"PoolID\" dataType=\"int\">" + poolID + "</Parameter>"
243 + "<Parameter name=\"EquipmentID\" dataType=\"int\">" + systemID + "</Parameter>"
244 + "<Parameter name=\"IsOn\" dataType=\"int\">" + cmdString + "</Parameter>"
245 + HaywardBindingConstants.COMMAND_SCHEDULE + "</Parameters></Request>";
247 // *****Send Command to Hayward server
248 String xmlResponse = bridgehandler.httpXmlResponse(cmdURL);
249 String status = bridgehandler.evaluateXPath("//Parameter[@name='Status']/text()", xmlResponse)
252 if (!("0".equals(status))) {
253 logger.debug("haywardCommand XML response: {}", xmlResponse);
256 } catch (HaywardException e) {
257 logger.debug("Unable to send command to Hayward's server {}:{}:{}",
258 bridgehandler.config.endpointUrl, bridgehandler.config.username, e.getMessage());
259 } catch (InterruptedException e) {
262 this.updateStatus(ThingStatus.ONLINE);
264 this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED);