From 4ef8db35d1d8c1dc13b207a197b8016004b1d8d8 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 16 Sep 2025 07:35:18 -0400 Subject: [PATCH] Support parsing and discovery of sensors with operations --- .../internal/config/BackyardConfig.java | 7 +++ .../internal/config/SensorConfig.java | 63 +++++++++++++++++++ .../discovery/HaywardDiscoveryService.java | 14 +++++ .../internal/config/ConfigParserTest.java | 28 +++++++++ .../HaywardDiscoveryServiceTest.java | 23 ++++++- 5 files changed, 132 insertions(+), 3 deletions(-) diff --git a/bundles/org.openhab.binding.haywardomnilogiclocal/src/main/java/org/openhab/binding/haywardomnilogiclocal/internal/config/BackyardConfig.java b/bundles/org.openhab.binding.haywardomnilogiclocal/src/main/java/org/openhab/binding/haywardomnilogiclocal/internal/config/BackyardConfig.java index 7030c7e8c7587..ba1ca8e607a8b 100644 --- a/bundles/org.openhab.binding.haywardomnilogiclocal/src/main/java/org/openhab/binding/haywardomnilogiclocal/internal/config/BackyardConfig.java +++ b/bundles/org.openhab.binding.haywardomnilogiclocal/src/main/java/org/openhab/binding/haywardomnilogiclocal/internal/config/BackyardConfig.java @@ -36,6 +36,9 @@ public class BackyardConfig { @XStreamAlias("Service-Mode-Timeout") private @Nullable String serviceModeTimeoutElement; + @XStreamImplicit(itemFieldName = "Sensor") + private final List sensors = new ArrayList<>(); + @XStreamImplicit(itemFieldName = "BodyOfWater") private final List bodiesOfWater = new ArrayList<>(); @@ -57,6 +60,10 @@ public class BackyardConfig { return serviceModeTimeout != null ? serviceModeTimeout : serviceModeTimeoutElement; } + public List getSensors() { + return sensors; + } + public List getBodiesOfWater() { return bodiesOfWater; } diff --git a/bundles/org.openhab.binding.haywardomnilogiclocal/src/main/java/org/openhab/binding/haywardomnilogiclocal/internal/config/SensorConfig.java b/bundles/org.openhab.binding.haywardomnilogiclocal/src/main/java/org/openhab/binding/haywardomnilogiclocal/internal/config/SensorConfig.java index 587f607ec5b99..fdda6c8e42567 100644 --- a/bundles/org.openhab.binding.haywardomnilogiclocal/src/main/java/org/openhab/binding/haywardomnilogiclocal/internal/config/SensorConfig.java +++ b/bundles/org.openhab.binding.haywardomnilogiclocal/src/main/java/org/openhab/binding/haywardomnilogiclocal/internal/config/SensorConfig.java @@ -1,10 +1,16 @@ package org.openhab.binding.haywardomnilogiclocal.internal.config; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import com.thoughtworks.xstream.annotations.XStreamImplicit; +import com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter; /** * Representation of a Sensor element. @@ -37,6 +43,9 @@ public class SensorConfig { @XStreamAlias("Units") private @Nullable String unitsElement; + @XStreamImplicit(itemFieldName = "Operation") + private final List operations = new ArrayList<>(); + public @Nullable String getSystemId() { return systemId != null ? systemId : systemIdElement; } @@ -52,5 +61,59 @@ public class SensorConfig { public @Nullable String getUnits() { return units != null ? units : unitsElement; } + + public List getOperations() { + return operations; + } + + @NonNullByDefault + @XStreamAlias("Operation") + @XStreamConverter(value = ToAttributedValueConverter.class, strings = "type") + public static class OperationConfig { + private @Nullable String type; + + @XStreamImplicit(itemFieldName = "Action") + private final List actions = new ArrayList<>(); + + @XStreamImplicit(itemFieldName = "Parameter") + private final List parameters = new ArrayList<>(); + + public @Nullable String getType() { + return type; + } + + public List getActions() { + return actions; + } + + public List getParameters() { + return parameters; + } + } + + @NonNullByDefault + @XStreamAlias("Action") + @XStreamConverter(value = ToAttributedValueConverter.class, strings = "type") + public static class ActionConfig { + private @Nullable String type; + + @XStreamImplicit(itemFieldName = "Device") + private final List devices = new ArrayList<>(); + + @XStreamImplicit(itemFieldName = "Parameter") + private final List parameters = new ArrayList<>(); + + public @Nullable String getType() { + return type; + } + + public List getDevices() { + return devices; + } + + public List getParameters() { + return parameters; + } + } } diff --git a/bundles/org.openhab.binding.haywardomnilogiclocal/src/main/java/org/openhab/binding/haywardomnilogiclocal/internal/discovery/HaywardDiscoveryService.java b/bundles/org.openhab.binding.haywardomnilogiclocal/src/main/java/org/openhab/binding/haywardomnilogiclocal/internal/discovery/HaywardDiscoveryService.java index 87da0ab0e257a..45aa970e57628 100644 --- a/bundles/org.openhab.binding.haywardomnilogiclocal/src/main/java/org/openhab/binding/haywardomnilogiclocal/internal/discovery/HaywardDiscoveryService.java +++ b/bundles/org.openhab.binding.haywardomnilogiclocal/src/main/java/org/openhab/binding/haywardomnilogiclocal/internal/discovery/HaywardDiscoveryService.java @@ -81,6 +81,20 @@ public synchronized void mspConfigDiscovery(String xmlResponse) { putIfNotNull(backyardProps, HaywardBindingConstants.PROPERTY_SYSTEM_ID, systemId); onDeviceDiscovered(HaywardBindingConstants.THING_TYPE_BACKYARD, "Backyard", backyardProps); + for (SensorConfig sensor : backyard.getSensors()) { + Map sensorProps = new HashMap<>(); + sensorProps.put(HaywardBindingConstants.PROPERTY_TYPE, HaywardTypeToRequest.SENSOR); + String sensorId = sensor.getSystemId(); + putIfNotNull(sensorProps, HaywardBindingConstants.PROPERTY_SYSTEM_ID, sensorId); + putIfNotNull(sensorProps, HaywardBindingConstants.PROPERTY_SENSOR_TYPE, sensor.getType()); + putIfNotNull(sensorProps, HaywardBindingConstants.PROPERTY_SENSOR_UNITS, sensor.getUnits()); + String name = sensor.getName(); + if (name == null) { + name = sensorId != null ? sensorId : "Sensor"; + } + onDeviceDiscovered(HaywardBindingConstants.THING_TYPE_SENSOR, name, sensorProps); + } + for (BodyOfWaterConfig bow : backyard.getBodiesOfWater()) { Map bowProps = new HashMap<>(); bowProps.put(HaywardBindingConstants.PROPERTY_TYPE, HaywardTypeToRequest.BOW); diff --git a/bundles/org.openhab.binding.haywardomnilogiclocal/src/test/java/org/openhab/binding/haywardomnilogiclocal/internal/config/ConfigParserTest.java b/bundles/org.openhab.binding.haywardomnilogiclocal/src/test/java/org/openhab/binding/haywardomnilogiclocal/internal/config/ConfigParserTest.java index becefc99e964c..8f96877dee2c6 100644 --- a/bundles/org.openhab.binding.haywardomnilogiclocal/src/test/java/org/openhab/binding/haywardomnilogiclocal/internal/config/ConfigParserTest.java +++ b/bundles/org.openhab.binding.haywardomnilogiclocal/src/test/java/org/openhab/binding/haywardomnilogiclocal/internal/config/ConfigParserTest.java @@ -33,6 +33,12 @@ public void testParsePopulatesAllListsAndAttributes() { " BY" + " Main Backyard" + " 15" + + " " + + " SENBY1" + + " Air Sensor" + + " SENSOR_AIR_TEMP" + + " UNITS_FAHRENHEIT" + + " " + " " + @@ -113,6 +119,11 @@ public void testParsePopulatesAllListsAndAttributes() { " Water Sensor" + " SENSOR_WATER_TEMP" + " UNITS_FAHRENHEIT" + + " PEO_SENSOR_SAMPLE" + + " PEA_SENSOR_REPORT" + + " 15" + + " " + + " " + " " + " " + " " + @@ -181,6 +192,13 @@ public void testParsePopulatesAllListsAndAttributes() { assertEquals("BY", backyard.getSystemId()); assertEquals("Main Backyard", backyard.getName()); assertEquals("15", backyard.getServiceModeTimeout()); + assertEquals(1, backyard.getSensors().size()); + SensorConfig backyardSensor = backyard.getSensors().get(0); + assertEquals("SENBY1", backyardSensor.getSystemId()); + assertEquals("Air Sensor", backyardSensor.getName()); + assertEquals("SENSOR_AIR_TEMP", backyardSensor.getType()); + assertEquals("UNITS_FAHRENHEIT", backyardSensor.getUnits()); + assertEquals(0, backyardSensor.getOperations().size()); assertEquals(1, backyard.getBodiesOfWater().size()); BodyOfWaterConfig bow = backyard.getBodiesOfWater().get(0); assertEquals("BOW", bow.getSystemId()); @@ -298,6 +316,16 @@ public void testParsePopulatesAllListsAndAttributes() { assertEquals("Water Sensor", sensor.getName()); assertEquals("SENSOR_WATER_TEMP", sensor.getType()); assertEquals("UNITS_FAHRENHEIT", sensor.getUnits()); + assertEquals(1, sensor.getOperations().size()); + SensorConfig.OperationConfig sensorOperation = sensor.getOperations().get(0); + assertEquals("PEO_SENSOR_SAMPLE", sensorOperation.getType()); + assertEquals(1, sensorOperation.getActions().size()); + SensorConfig.ActionConfig sensorAction = sensorOperation.getActions().get(0); + assertEquals("PEA_SENSOR_REPORT", sensorAction.getType()); + assertEquals(0, sensorAction.getDevices().size()); + assertEquals(1, sensorAction.getParameters().size()); + assertEquals("Interval", sensorAction.getParameters().get(0).getName()); + assertEquals("15", sensorAction.getParameters().get(0).getValue()); assertEquals(1, backyard.getPumps().size()); PumpConfig pump = backyard.getPumps().get(0); diff --git a/bundles/org.openhab.binding.haywardomnilogiclocal/src/test/java/org/openhab/binding/haywardomnilogiclocal/internal/discovery/HaywardDiscoveryServiceTest.java b/bundles/org.openhab.binding.haywardomnilogiclocal/src/test/java/org/openhab/binding/haywardomnilogiclocal/internal/discovery/HaywardDiscoveryServiceTest.java index 7f75a68c54172..58343260f9c72 100644 --- a/bundles/org.openhab.binding.haywardomnilogiclocal/src/test/java/org/openhab/binding/haywardomnilogiclocal/internal/discovery/HaywardDiscoveryServiceTest.java +++ b/bundles/org.openhab.binding.haywardomnilogiclocal/src/test/java/org/openhab/binding/haywardomnilogiclocal/internal/discovery/HaywardDiscoveryServiceTest.java @@ -1,6 +1,7 @@ package org.openhab.binding.haywardomnilogiclocal.internal.discovery; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import java.util.ArrayList; @@ -37,6 +38,7 @@ public void mspConfigDiscoveryCreatesResultsForAllDevices() { "" + " " + " " + + " " + " " + @@ -61,19 +63,28 @@ public void mspConfigDiscoveryCreatesResultsForAllDevices() { TestDiscoveryService service = new TestDiscoveryService(); service.mspConfigDiscovery(xml); - assertEquals(13, service.types.size()); + assertEquals(14, service.types.size()); assertEquals(2, service.types.stream().filter(t -> t.equals(HaywardBindingConstants.THING_TYPE_PUMP)).count()); assertEquals(2, service.types.stream().filter(t -> t.equals(HaywardBindingConstants.THING_TYPE_FILTER)).count()); assertEquals(2, service.types.stream().filter(t -> t.equals(HaywardBindingConstants.THING_TYPE_BOW)).count()); - assertEquals(1, service.types.stream().filter(t -> t.equals(HaywardBindingConstants.THING_TYPE_SENSOR)).count()); + assertEquals(2, service.types.stream().filter(t -> t.equals(HaywardBindingConstants.THING_TYPE_SENSOR)).count()); Map bowProps = null; + Map backyardSensorProps = null; for (int i = 0; i < service.types.size(); i++) { + if (bowProps != null && backyardSensorProps != null) { + break; + } if (service.types.get(i).equals(HaywardBindingConstants.THING_TYPE_BOW)) { Map properties = service.propertyMaps.get(i); if ("BOW1".equals(properties.get(HaywardBindingConstants.PROPERTY_SYSTEM_ID))) { bowProps = properties; - break; + } + } + if (service.types.get(i).equals(HaywardBindingConstants.THING_TYPE_SENSOR)) { + Map properties = service.propertyMaps.get(i); + if ("S2".equals(properties.get(HaywardBindingConstants.PROPERTY_SYSTEM_ID))) { + backyardSensorProps = properties; } } } @@ -87,6 +98,12 @@ public void mspConfigDiscoveryCreatesResultsForAllDevices() { assertEquals("BOW2", bowProps.get(HaywardBindingConstants.PROPERTY_BOW_SHAREDEQUIPID)); assertEquals("yes", bowProps.get(HaywardBindingConstants.PROPERTY_BOW_SUPPORTSSPILLOVER)); assertEquals("15000", bowProps.get(HaywardBindingConstants.PROPERTY_BOW_SIZEINGALLONS)); + + assertNotNull(backyardSensorProps); + assertEquals(HaywardTypeToRequest.SENSOR, backyardSensorProps.get(HaywardBindingConstants.PROPERTY_TYPE)); + assertEquals("SENSOR_AIR_TEMP", backyardSensorProps.get(HaywardBindingConstants.PROPERTY_SENSOR_TYPE)); + assertEquals("UNITS_FAHRENHEIT", backyardSensorProps.get(HaywardBindingConstants.PROPERTY_SENSOR_UNITS)); + assertFalse(backyardSensorProps.containsKey(HaywardBindingConstants.PROPERTY_BOWID)); } @Test