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 HaywardFilterHandler extends HaywardThingHandler {
48 private final Logger logger = LoggerFactory.getLogger(HaywardFilterHandler.class);
49 private Map<String, State> channelStates = new HashMap<>();
51 public HaywardFilterHandler(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 set FilterHandler 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 Filter Speed % min and max speeds
76 Channel ch = thing.getChannel(HaywardBindingConstants.CHANNEL_FILTER_SPEEDPERCENT);
78 StateDescriptionFragment stateDescriptionFragment = StateDescriptionFragmentBuilder.create()
79 .withMinimum(new BigDecimal(
80 getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_MINSPEED)))
81 .withMaximum(new BigDecimal(
82 getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_MAXSPEED)))
84 bridgehandler.updateChannelStateDescriptionFragment(ch, stateDescriptionFragment);
87 // Set Filter Speed RPM min and max speeds
88 ch = thing.getChannel(HaywardBindingConstants.CHANNEL_FILTER_SPEEDRPM);
90 StateDescriptionFragment stateDescriptionFragment = StateDescriptionFragmentBuilder.create()
91 .withMinimum(new BigDecimal(
92 getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_MINRPM)))
93 .withMaximum(new BigDecimal(
94 getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_MAXRPM)))
96 bridgehandler.updateChannelStateDescriptionFragment(ch, stateDescriptionFragment);
99 // Set Filter Speed States
100 ch = thing.getChannel(HaywardBindingConstants.CHANNEL_FILTER_SPEEDSELECT);
102 options.add(new StateOption("0", "Off"));
103 option = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_LOWSPEED);
104 if (option != null) {
105 options.add(new StateOption(option, "Low"));
107 option = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_MEDSPEED);
108 if (option != null) {
109 options.add(new StateOption(option, "Medium"));
111 option = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_HIGHSPEED);
112 if (option != null) {
113 options.add(new StateOption(option, "High"));
115 option = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_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("//Filter/@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("//Filter/@valvePosition", xmlResponse);
143 updateData(HaywardBindingConstants.CHANNEL_FILTER_VALVEPOSITION, data.get(i));
146 data = bridgehandler.evaluateXPath("//Filter/@filterSpeed", xmlResponse);
147 updateData(HaywardBindingConstants.CHANNEL_FILTER_SPEEDPERCENT, data.get(i));
150 String filterMaxRpm = getThing().getProperties()
151 .get(HaywardBindingConstants.PROPERTY_FILTER_MAXRPM);
152 if (filterMaxRpm != null) {
153 Integer rpmSpeed = (Integer.parseInt(data.get(i))) * (Integer.parseInt(filterMaxRpm)) / 100;
154 updateData(HaywardBindingConstants.CHANNEL_FILTER_SPEEDRPM, rpmSpeed.toString());
157 if (data.get(i).equals("0")) {
158 updateData(HaywardBindingConstants.CHANNEL_FILTER_ENABLE, "0");
160 updateData(HaywardBindingConstants.CHANNEL_FILTER_ENABLE, "1");
164 data = bridgehandler.evaluateXPath("//Filter/@filterSpeed", xmlResponse);
165 updateData(HaywardBindingConstants.CHANNEL_FILTER_SPEEDSELECT, data.get(i));
168 data = bridgehandler.evaluateXPath("//Filter/@filterState", xmlResponse);
169 updateData(HaywardBindingConstants.CHANNEL_FILTER_STATE, data.get(i));
172 data = bridgehandler.evaluateXPath("//Filter/@lastSpeed", xmlResponse);
173 updateData(HaywardBindingConstants.CHANNEL_FILTER_LASTSPEED, data.get(i));
174 channelStates.putAll(updateData(HaywardBindingConstants.CHANNEL_FILTER_LASTSPEED, data.get(i)));
177 this.updateStatus(ThingStatus.ONLINE);
179 this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED);
185 public void handleCommand(ChannelUID channelUID, Command command) {
186 if ((command instanceof RefreshType)) {
190 String systemID = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_SYSTEM_ID);
191 String poolID = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_BOWID);
192 String filterMinSpeed = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_MINSPEED);
193 String filterMaxSpeed = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_MAXSPEED);
194 String filterMaxRpm = getThing().getProperties().get(HaywardBindingConstants.PROPERTY_FILTER_MAXRPM);
196 Bridge bridge = getBridge();
197 if (bridge != null) {
198 HaywardBridgeHandler bridgehandler = (HaywardBridgeHandler) bridge.getHandler();
199 if (bridgehandler != null) {
200 String cmdString = this.cmdToString(command);
202 switch (channelUID.getId()) {
203 case HaywardBindingConstants.CHANNEL_FILTER_ENABLE:
204 if (command == OnOffType.ON) {
205 cmdString = channelStates.get(HaywardBindingConstants.CHANNEL_FILTER_LASTSPEED)
211 case HaywardBindingConstants.CHANNEL_FILTER_SPEEDPERCENT:
212 if (filterMinSpeed != null && filterMaxSpeed != null) {
213 if (Integer.parseInt(cmdString) > 0
214 && Integer.parseInt(cmdString) < Integer.parseInt(filterMinSpeed)) {
215 cmdString = filterMinSpeed;
216 } else if (Integer.parseInt(cmdString) > Integer.parseInt(filterMaxSpeed)) {
217 cmdString = filterMaxSpeed;
221 case HaywardBindingConstants.CHANNEL_FILTER_SPEEDRPM:
222 // Convert cmdString from RPM to Percent
223 if (filterMaxRpm != null && filterMaxSpeed != null && filterMinSpeed != null) {
225 .toString((Integer.parseInt(cmdString) * 100 / Integer.parseInt(filterMaxRpm)));
226 if (Integer.parseInt(cmdString) > 0
227 && Integer.parseInt(cmdString) < Integer.parseInt(filterMinSpeed)) {
228 cmdString = filterMinSpeed;
229 } else if (Integer.parseInt(cmdString) > Integer.parseInt(filterMaxSpeed)) {
230 cmdString = filterMaxSpeed;
234 case HaywardBindingConstants.CHANNEL_FILTER_SPEEDSELECT:
237 logger.warn("haywardCommand Unsupported type {}", channelUID);
241 String cmdURL = HaywardBindingConstants.COMMAND_PARAMETERS
242 + "<Name>SetUIEquipmentCmd</Name><Parameters>"
243 + "<Parameter name=\"Token\" dataType=\"String\">" + bridgehandler.account.token
244 + "</Parameter>" + "<Parameter name=\"MspSystemID\" dataType=\"int\">"
245 + bridgehandler.account.mspSystemID + "</Parameter>"
246 + "<Parameter name=\"PoolID\" dataType=\"int\">" + poolID + "</Parameter>"
247 + "<Parameter name=\"EquipmentID\" dataType=\"int\">" + systemID + "</Parameter>"
248 + "<Parameter name=\"IsOn\" dataType=\"int\">" + cmdString + "</Parameter>"
249 + HaywardBindingConstants.COMMAND_SCHEDULE + "</Parameters></Request>";
251 // *****Send Command to Hayward server
252 String xmlResponse = bridgehandler.httpXmlResponse(cmdURL);
253 String status = bridgehandler.evaluateXPath("//Parameter[@name='Status']/text()", xmlResponse)
256 if (!("0".equals(status))) {
257 logger.debug("haywardCommand XML response: {}", xmlResponse);
260 } catch (HaywardException e) {
261 logger.debug("Unable to send command to Hayward's server {}:{}:{}",
262 bridgehandler.config.endpointUrl, bridgehandler.config.username, e.getMessage());
263 } catch (InterruptedException e) {
266 this.updateStatus(ThingStatus.ONLINE);
268 this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED);