Hayward Omnilogic Pool Automation Binding

Quick update for you, I loaded your updated jar file, it looked good, properly created the things and channels and no errors from anything. However when I try to switch either of these two pumps on or off they do not do anything. The item changes as it usually does with the 3 usual logs:

Item received command ON
Item predicted to change from OFF to ON
Item changed from OFF to ON

(something like that, that’s from memory, I’m not at my computer). However, There is not an xml request logged to the Hayward server as with actuations for the other devices. So, I’m wondering if there may still be an error in the binding code for these types of pumps. I’ve triple checked the channel code on each item in the items file and they are correct. (I copied them straight from the UI things/channels pages)

Thank you! Let me know what I can send to help you.

Ok. We are getting close. I found one more omission that should solve the command issue. Let me know if you find anything else, or if this all works so I can publish the changes. Thanks!

https://drive.google.com/file/d/1-Z3SrIR-IArj4KQUTAsJe4Fg1d5YH8g1/view?usp=sharing

I just installed it and there is no change yet. I re-initialized the Omnilogic bridge after re-installing. Here are some more specifics: when I turn on the working pool Filter pump Switch item that I have it does this (as an example):

14:27:52.950 [INFO ] [openhab.event.ItemCommandEvent       ] - Item 'PoolFilterPower' received command OFF
14:27:52.965 [INFO ] [openhab.event.ItemStatePredictedEvent] - Item 'PoolFilterPower' predicted to become OFF
14:27:52.978 [INFO ] [openhab.event.ItemStateChangedEvent  ] - Item 'PoolFilterPower' changed from ON to OFF
14:27:53.070 [TRACE] [internal.handler.HaywardBridgeHandler] - Hayward Connection thing:  handleCommand Hayward http command: <?xml version="1.0" encoding="utf-8"?><Request><Name>SetUIEquipmentCmd</Name><Parameters><Parameter name="Token" dataType="String">1c75e9b5893f424d96cadf526cd0a939</Parameter><Parameter name="MspSystemID" dataType="int">116587</Parameter><Parameter name="PoolID" dataType="int">1</Parameter><Parameter name="EquipmentID" dataType="int">3</Parameter><Parameter name="IsOn" dataType="int">0</Parameter><Parameter name="IsCountDownTimer" dataType="bool">false</Parameter><Parameter name="StartTimeHours" dataType="int">0</Parameter><Parameter name="StartTimeMinutes" dataType="int">0</Parameter><Parameter name="EndTimeHours" dataType="int">0</Parameter><Parameter name="EndTimeMinutes" dataType="int">0</Parameter><Parameter name="DaysActive" dataType="int">0</Parameter><Parameter name="Recurring" dataType="bool">false</Parameter></Parameters></Request>
14:27:53.104 [TRACE] [internal.handler.HaywardBridgeHandler] - Hayward Connection thing:  handleCommand Hayward http response: Successfully <Response><Name>SetUIEquipmentCmd</Name><Parameters><Parameter dataType="int" name="Status">0</Parameter><Parameter dataType="int" name="StatusMessage">Successfully</Parameter></Parameters></Response>

However when I turn on or off one of the two pump things linked items it does nothing, other than this:

14:27:37.319 [INFO ] [openhab.event.ItemCommandEvent       ] - Item 'FountainPower' received command ON
14:27:37.430 [INFO ] [openhab.event.ItemStatePredictedEvent] - Item 'FountainPower' predicted to become ON
14:27:37.446 [INFO ] [openhab.event.ItemStateChangedEvent  ] - Item 'FountainPower' changed from OFF to ON

(the two pump devices we’ve been troubleshooting) Also, one more piece of info, none of the items linked to the channels of either of these pumps (spa jets and pool fountains) populate with any data, ie the pumpSpeed, pumpState, pumpLastSpeed and pumpEnable (they don’t seem to be getting any of the info from the getTelemetry call).

Edit: I also rebooted and restarted openhab and it still didn’t change (I just wanted to be sure that the new jar was installed)

Wow, I found yet another omission. Try this one. This is difficult developing code that I cannot test myself. I guess I need to install a water feature in my pool. :slight_smile:

https://drive.google.com/file/d/1-RI26aXOsieibhLBArHdxQcPPs77YN7m/view?usp=sharing

I loaded it up and there is progress! One of the pumps can be turned on and off (the single speed pump, pump 16) using the “pumpEnable” channel. The other pump can only be turned off using the “pumpEnable” channel (the variable speed pump, pump 9). Here is the command and response from the logs. I’m not sure why it isn’t working.


19:58:10.899 [TRACE] [internal.handler.HaywardBridgeHandler] - Hayward Connection thing:  handleCommand Hayward http command: <?xml version="1.0" encoding="utf-8"?><Request><Name>SetUIEquipmentCmd</Name><Parameters><Parameter name="Token" dataType="String">1c75e9b5893f424d96cadf526cd0a939</Parameter><Parameter name="MspSystemID" dataType="int">116587</Parameter><Parameter name="PoolID" dataType="int">1</Parameter><Parameter name="EquipmentID" dataType="int">9</Parameter><Parameter name="IsOn" dataType="int">100</Parameter><Parameter name="IsCountDownTimer" dataType="bool">false</Parameter><Parameter name="StartTimeHours" dataType="int">0</Parameter><Parameter name="StartTimeMinutes" dataType="int">0</Parameter><Parameter name="EndTimeHours" dataType="int">0</Parameter><Parameter name="EndTimeMinutes" dataType="int">0</Parameter><Parameter name="DaysActive" dataType="int">0</Parameter><Parameter name="Recurring" dataType="bool">false</Parameter></Parameters></Request>
19:58:10.937 [TRACE] [internal.handler.HaywardBridgeHandler] - Hayward Connection thing:  handleCommand Hayward http response: Successfully <Response><Name>SetUIEquipmentCmd</Name><Parameters><Parameter dataType="int" name="Status">0</Parameter><Parameter dataType="int" name="StatusMessage">Successfully</Parameter></Parameters></Response>

The other problem I see is that neither the “pumpState” nor “pumpLastSpeed” channels for either pump update their items. The getTelemetery call, while the pumps are on, have the correct data for those values, but for some reason it’s not parsing it into the channels and on to the items. Here is the getTelemetery return when the pumps are both on:

19:49:16.861 [TRACE] [internal.handler.HaywardBridgeHandler] - Hayward Connection thing:  getTelemetryData Hayward http response: OK <STATUS version="1.0"><Backyard systemId="116587" statusVersion="8" airTemp="83" status="1" state="1" configUpdatedTime="2021-08-21T23:27:11.696Z" datetime="2021-08-23T19:49:16.9505305" /><BodyOfWater systemId="1" flow="1" waterTemp="87" /><Filter systemId="3" valvePosition="1" filterSpeed="100" filterState="1" lastSpeed="100" /><VirtualHeater systemId="4" Current-Set-Point="81" enable="no" /><Heater systemId="5" heaterState="0" enable="yes" /><Chlorinator systemId="6" operatingMode="1" Timed-Percent="55" scMode="0" chlrError="0" chlrAlert="0" avgSaltLevel="3035" instantSaltLevel="2923" status="132" /><Pump systemId="9" pumpState="1" pumpSpeed="48" lastSpeed="48" /><ColorLogic-Light systemId="8" lightState="1" currentShow="3" /><CSAD systemId="0" ph="" orp="" status="0" mode="0" /><BodyOfWater systemId="2" flow="1" waterTemp="-1" /><Filter systemId="11" valvePosition="1" filterSpeed="0" filterState="0" lastSpeed="50" /><VirtualHeater systemId="12" Current-Set-Point="99" enable="no" /><Heater systemId="13" heaterState="0" enable="yes" /><Chlorinator systemId="14" operatingMode="1" Timed-Percent="6" scMode="0" chlrError="0" chlrAlert="0" avgSaltLevel="0" instantSaltLevel="0" status="0" /><Pump systemId="16" pumpState="1" pumpSpeed="100" lastSpeed="100" /><CSAD systemId="0" ph="" orp="" status="0" mode="0" /><Group systemId="29" groupState="0" /></STATUS>

“pumpSpeed” does get updated properly, though I have not checked yet if I can turn the pump on by setting a speed yet, instead of by using “pumpEnable”. The other functions I haven’t checked yet are seeing if I can control the heater.

@matchews, I have now verified that sending commands via “pumpSpeed” channels works great. I can control the speed of all of my pumps, and turn them off through this channel, with no issues. The only component I haven’t got incorporated on my sitemap yet is the heater, which I will test soon.

The issue from my previous message remains, I am unable to turn on my fountain (variable speed pump) using the “pumpEnable” channel. It turns on momentarily, sends the request, gets a successful response (also above) and then as soon as the next “getTelemetery” returns, it turns the linked item back off. The pump never actually turns on. Also, neither pump gets the “pumpState” or “pumpLastSpeed” channels updated, when the data is indeed in the “getTelemetery” return.

One suggestion I have, and I can write this up on github if you’d like… Would it make sense to request a “getTelemetry” a short time after any other command? I don’t really want to increase the normal polling speed of “getTelemetry” (currently 10 sec), but it would be nice to have items update close to immediately after you set them (somewhere between .5 and 2 sec would probably be good, you know better than I do how the system responds to commands though).

Thanks!

The “pump on” command was sending a 100% speed request, which exceeded the max speed on your Fountain Pump 09 and was therefore being ignored. I am now consuming the min and max speeds for each filter/pump as thing properties, and commanding the max speed when powering on the filter/pump. I still need to investigate how to dynamically set the pump/filter speed sliders to represent the min and max speeds of the filter/pump.

The state and speed channel updates should be fixed as well. As for the polling, the hayward API server has limits on the frequency of hits. Once the commands are fully functional, you shouldn’t notice any toggling.

This update will require you to remove and recreate all Hayward things. Copy the UID from your existing connection/bridge, delete all of the things first, then delete the connection/bridge last, then recreate the connection/bridge using the same UID, then scan/discover and add all items. If you use the same UID, all of your linked channels will survive.

https://drive.google.com/file/d/1ThW1Q_kZxlfVGT9i2rNv5fX4eaI684Bs/view?usp=sharing

Ok, I followed your instructions and reloaded, it’s working nicely. All of the fields populate with data now. I have a few questions:

  1. How does the binding do it’s “mapping”? When I look at the raw data in the logs a pump’s state might be 0, or 1 or 7, but in the sitemap default element it will actually say “Running” or “Off”, etc. How can I access these “maps” so that I can use them too in my own custom sitemap elements (like a selection element)

  2. I’m still having the issue where If I Turn a pump on just after a getTelemetery call, it could take 9 seconds for the other data fields to populate or update, I don’t see any immediate updating going on.

As far as the Fountain Pumps are concerned:
What I’ve found (though it’s really hard to be consistent with testing because there are so many variables) is that if I’ve got a value in a “Selection” item on the sitemap that is greater than the pump maximum (in my case I had 100 as “max” on my fountains), then it wouldn’t “enable” the pump. But this wasn’t consistent. I’ve gone through and changed my Sitemap to reflect the settings in the thing properties for each pump, but I wonder if it would be possible to just have the binding check for the maximum (or minimum non-off setting) and then just apply that instead. Ie if the user said “I want 100%” but the max is 75%, and the binding has collected this data, then just change the command to be 75%. It seems like one of my pumps actually did this when I set 48% as the min, but it changed to 50% automatically. Maybe that is your intention and there’s still something amiss with the pump thing specifically.

Again, thanks for all your work!

The mapped states are hard coded into the binding. OpenHab’s UI’s will utilize the textual states when the channel is displayed (rather than the raw integer). In other words, it’s handled for you. Speaking of UI’s, I recommend you use the new OH3 model which automatically builds your pages rather then the old OH3 sitemaps. Regarding the pump min/max, that will all be fixed once I implement the dynamic implementation of the min/max properties of each pump/filter. This will prevent the user from commanding anything outside of these limits.

image

image

Not sure how much you have to adjust your chlorinator, but this is the front end of an algorithm I wrote to automatically adjust the salt output based on water temperature and UV exposure. It really helps if you have a cover and can detect if its open/closed.

image

If you switch over to the OH3 pages, you can setup so nice graphs as well…

Chlorinator trend

Temperature/Heater trend

Oh wow, I haven’t even seen the OH3 models yet. Still using the same old OH2 site maps. I will have to read up on that.

Sounds great about your dynamic pump/filter values in work. I’ll be looking forward to that.

I’ve made a rule that fires on changes to BOW temp changes and filter pump states (and will eventually fire on heater on/off) so that I can update a String item with the overall state of the pool system ie: “Pool Heating in Spa Mode, 86° F”, I also use this rule to update additional spa and pool temp items so that I can always see the current (or last known) temp of the pool and spa, rather than -1 (if it is not in that BOW mode currently).

I just added the pool temp to my overall temp chart, so I’ll have a look at how OH3 models do charts as well.

Awesome work!

Yes, the -1 temperature is anoying. Here are some rules I made to handle that and a few other things to clean up the trends.

rule "Pool: Flow Delay"
when
    Item HaywardPool_FlowSensor changed
then
    if (HaywardPool_FlowSensor.state.toString=="ON"){
        FlowTimer = createTimer(now.plusSeconds(600)) [|
        PoolBOWFlowDelayed.sendCommand(ON)
        ]
    } else {
        PoolBOWFlowDelayed.sendCommand(OFF)
        if(FlowTimer!==null) {
            FlowTimer.cancel
            FlowTimer = null
        }
    }
end

rule "Pool: Autocover Status"
when
    Item AlarmPoolCover changed
then
    if (AlarmPoolCover.state == "CLOSED") {
        AutocoverStatus.sendCommand(OFF)
    }else{
        AutocoverStatus.sendCommand(ON)
    }
end

//Avoid null water temp value when pool isn't running and erratic when it first starts
//Memorize last know good water temp
//Ignore when pump first starts up
rule "Pool: Update Temp"
when
    Item HaywardPool_WaterTemp changed
    or
    Item HaywardPump_FilterState changed
    or
    Item PoolBOWFlowDelayed changed
then
    var filterState  = HaywardPump_FilterState.stateDescription.options.filter[stateOption | stateOption.value == HaywardPump_FilterState.state.toString].get(0).getLabel()

    //logInfo("Pool", "Filter state: " + filterState)
    //logInfo("Pool", "Flow Delay Switch: " + PoolBOWFlowDelayed.state)
    if ((PoolBOWFlowDelayed.state==ON) && (HaywardPool_WaterTemp.state > 0|°F) && (filterState != "Priming")) { 
        PoolLastBOWWaterTemp.sendCommand(HaywardPool_WaterTemp.state as QuantityType<Temperature>)
  }
end

//Running Average of Water Temp
rule "Pool: Average Water Temp"
when 
    Time cron "0 0/5 * ? * * *"  //Every 5 minutes
then
    if (PoolBOWFlowDelayed.state.toString=="ON"){
        PoolLastBOWWaterTempAvg.sendCommand(Math::round((PoolLastBOWWaterTemp.averageSince(now.minusMinutes(120), "rrd4j") * 10).floatValue) / 10)
    }
end

//Only chart heater setpoint when the heater is enabled
rule "Pool: Update Heater On Setpoint Temp"
when
    Item HaywardVirtualHeater_CurrentSetpoint changed
    or
    Item HaywardVirtualHeater_Power changed
    or 
    Item HaywardPump_FilterState changed
then
    if ((HaywardVirtualHeater_Power.state==ON) && (HaywardPump_FilterState.state != "0")) {
        HeaterOnSetpoint.sendCommand(HaywardVirtualHeater_CurrentSetpoint.state as Number)
    } else {
        HeaterOnSetpoint.postUpdate(40)
    }
end
 
//Only chart chlor setpoint when the chlor is enabled
rule "Pool: Update Chlor Setpoint"
when
    Item HaywardChlorinator_Power changed
    or
    Item HaywardChlorinator_scMode changed
    or 
    Item HaywardChlorinator_SaltOutput changed
    or
    Item HaywardPump_Power changed

then
    if ((HaywardChlorinator_Power.state.toString=="ON") && (HaywardPump_Power.state.toString=="ON") && (HaywardChlorinator_scMode.state.toString=="0")) {
        PoolChlorTimedPercentFiltered.sendCommand(HaywardChlorinator_SaltOutput.state as Number)
    } else if ((HaywardChlorinator_Power.state.toString=="ON") && (HaywardPump_Power.state.toString=="ON") && (HaywardChlorinator_scMode.state.toString=="1")) {
        PoolChlorTimedPercentFiltered.postUpdate(100)
    } else {
        PoolChlorTimedPercentFiltered.postUpdate(0)
    }
end

Hello, firstly I must say … awesome Binding!

I do have a question/small problem. I have an OpenHab3 running and I have put in the binding. It works very well, with the exception of not finding my relay on my Omnilogic. Sadly it is one relay that I would really like to control through my automation. I cannot figure out why. I was reading your documentation and it indicates that relays are part of the binding, and it seems to discover all else. I am wondering if you have any ideas. As I am a new user to this form, I cannot upload files. I would like to share my MSP configuration file, but without being able to upload files I am not sure how to share this. Any ideas on how to share it?

Glen,

Thanks for the feedback. You can paste the getMSP and getTelemetry responses right into your reply and I’ll check it out. I have a couple valve actuators that are working. Shouldn’t be a major issue.

I don’t know if I have done this right or not… as I am not fully familiar with OpenHab. I went into the terminal and entered log:set TRACE org.openhab.binding.haywardomnilogic. I then did a scan on the binding and here is what I got. (not sure how to format it correctly). Please let me know if I have done this right or I am missing something…

2021-09-03 19:08:49.734 [TRACE] [nternal.handler.HaywardBridgeHandler] - Hayward Connection thing: getMspConfig Hayward http response: OK RPM12 Hour FormatStandardSaltEnglishstandardYesYesYesYes
MSP Configuration
0Backyard09AirSensorSENSOR_AIR_TEMPUNITS_FAHRENHEIT11MisterRLY_HIGH_VOLTAGE_RELAYRLY_ACCESSORY
01
1PoolBOW_POOLBOW_NO_EQUIPMENT_SHAREDSHARED_EQUIPMENT_LOW_PRIORITY0no120002Filter PumpBOW_NO_EQUIPMENT_SHAREDFMT_VARIABLE_SPEED_PUMP100193250600yes19501001972003BOW_NO_EQUIPMENT_SHAREDno86871045598
PEO_HEATER_EQUIPMENT
4Heat PumpPET_HEATERHTR_HEAT_PUMPnoHTR_PRIORITY_1HTR_MAINTAINS_PRIORITY_FOR_NEVER-1
PEO_HEATER_EQUIPMENT
5Gas HeaterPET_HEATERHTR_GASnoHTR_PRIORITY_2HTR_MAINTAINS_PRIORITY_FOR_NEVER-16Water FtRLY_VALVE_ACTUATORRLY_WATER_FEATURE757LightCL_P_COLOR10WaterSensorSENSOR_WATER_TEMPUNITS_FAHRENHEIT1212164981060101271121316450111001612711614164111160191271171516426317110190221271171160268435455116Mist114TurnOnOffForGroup01110TurnOnOffForGroup1200SetHeaterScheduleCmd13550000000SetUITemporaryHeaterPriorityCmd145-1-1-1SetUITemporaryHeaterMaintainPriorityCmd1300255255255SetUITemporaryHeaterEnable130SetUITemporaryHeaterEnable140SetUITemporaryHeaterEnable150SetSolarScheduleCmd13550000000TurnOnOffForGroup1600TurnOnOffForGroup17263178018Swim Lights167200TurnOnOffForGroup01100TurnOnOffForGroup12190SetHeaterScheduleCmd13860000000SetUITemporaryHeaterPriorityCmd145-1-1-1SetUITemporaryHeaterMaintainPriorityCmd1300255255255SetUITemporaryHeaterEnable130SetUITemporaryHeaterEnable140SetUITemporaryHeaterEnable150SetSolarScheduleCmd13870000000TurnOnOffForGroup1600TurnOnOffForGroup172631711
2021-09-03 19:09:08.054 [TRACE] [nternal.handler.HaywardBridgeHandler] - Hayward Connection thing: getAlarmList Hayward http command: <?xml version="1.0" encoding="utf-8"?>GetAlarmListb17c7ea406e342e1a47afe20b64527b2126378en-us
2021-09-03 19:09:08.055 [TRACE] [nternal.handler.HaywardBridgeHandler] - Hayward Connection thing: getAlarmList Hayward http response: Successfully GetSiteList0Successfully

Hey @matchews I have a question about solar heating. I just added a solar setup to my controller and it uses an additional temperature sensor. I removed everything, installed the latest version of your binding and recreated all of my Things. It discovered two additional sensors, ID 13 (SENSOR_SOLAR_TEMP) and ID 4. But they’re both coming up NULL.

This is what I see in the UI. I’m not sure what that “virtual heater” is because it doesn’t exist. The only heater I have configured is the solar. But really I’m looking for the value of the rooftop temperature sensor (60 in the image).

I looked in the telemetry response and it doesn’t seem to be here:

<STATUS version="1.0">
  <Backyard systemId="99999" statusVersion="8" airTemp="75" status="1" state="1" configUpdatedTime="2021-09-05T15:47:36.634Z" datetime="2021-09-07T12:46:09.6749685"/>
  <BodyOfWater systemId="1" flow="255" waterTemp="71"/>
  <Filter systemId="2" valvePosition="1" filterSpeed="50" filterState="1" lastSpeed="32"/>
  <VirtualHeater systemId="11" Current-Set-Point="70" enable="no"/>
  <Heater systemId="12" heaterState="0" enable="yes"/>
  <Relay systemId="5" relayState="1"/>
  <CSAD systemId="0" ph="" orp="" status="0" mode="0"/>
</STATUS>

Obviously you can’t do anything with a value that Hayward isn’t giving you. So my question is: why isn’t it returning this value? Do you know if maybe a different query is needed? Here’s my full MSP for reference:

<Response>
  <MSPConfig>
    <System>
      <Msp-Vsp-Speed-Format>RPM</Msp-Vsp-Speed-Format>
      <Msp-Time-Format>12 Hour Format</Msp-Time-Format>
      <Units>Standard</Units>
      <Msp-Chlor-Display>Salt</Msp-Chlor-Display>
      <Msp-Language>English</Msp-Language>
      <UI-Display-Mode>standard</UI-Display-Mode>
      <UI-MoodColor-Enabled>Yes</UI-MoodColor-Enabled>
      <UI-Heater-SimpleMode>No</UI-Heater-SimpleMode>
      <UI-Filter-SimpleMode>No</UI-Filter-SimpleMode>
      <UI-Lights-SimpleMode>No</UI-Lights-SimpleMode>
    </System>
    <Backyard>
        MSP Configuration
        <System-Id>0</System-Id><Name>Backyard</Name><Service-Mode-Timeout>0</Service-Mode-Timeout><Sensor><System-Id>3</System-Id><Name>AirSensor</Name><Type>SENSOR_AIR_TEMP</Type><Units>UNITS_FAHRENHEIT</Units></Sensor><Body-of-water>
            01
            <System-Id>1</System-Id><Name>Pool</Name><Type>BOW_POOL</Type><Shared-Type>BOW_NO_EQUIPMENT_SHARED</Shared-Type><Shared-Priority>SHARED_EQUIPMENT_LOW_PRIORITY</Shared-Priority><Shared-Equipment-System-ID>0</Shared-Equipment-System-ID><Supports-Spillover>no</Supports-Spillover><Size-In-Gallons>0</Size-In-Gallons><Filter><System-Id>2</System-Id><Name>Filter Pump</Name><Shared-Type>BOW_NO_EQUIPMENT_SHARED</Shared-Type><Filter-Type>FMT_VARIABLE_SPEED_PUMP</Filter-Type><Max-Pump-Speed>80</Max-Pump-Speed><Min-Pump-Speed>32</Min-Pump-Speed><Max-Pump-RPM>3450</Max-Pump-RPM><Min-Pump-RPM>600</Min-Pump-RPM><Priming-Enabled>yes</Priming-Enabled><Vsp-Low-Pump-Speed>32</Vsp-Low-Pump-Speed><Vsp-Medium-Pump-Speed>50</Vsp-Medium-Pump-Speed><Vsp-High-Pump-Speed>70</Vsp-High-Pump-Speed><Vsp-Custom-Pump-Speed>70</Vsp-Custom-Pump-Speed><Freeze-Protect-Override-Interval>7200</Freeze-Protect-Override-Interval></Filter><Sensor><System-Id>4</System-Id><Name>WaterSensor</Name><Type>SENSOR_WATER_TEMP</Type><Units>UNITS_FAHRENHEIT</Units></Sensor><Relay><System-Id>5</System-Id><Name>SWG</Name><Type>RLY_HIGH_VOLTAGE_RELAY</Type><Function>RLY_ACCESSORY</Function><External-Interlock>
                    1
                    <External-Interlock-Enable>yes</External-Interlock-Enable><External-Interlock-Source>ILK_SOURCE_FILTER</External-Interlock-Source><External-Interlock-Source-System-Id>2</External-Interlock-Source-System-Id><External-Interlock-Compare-Type>ILK_COMPARE_EQUAL_TO</External-Interlock-Compare-Type><External-Interlock-ActiveLevel>0</External-Interlock-ActiveLevel><External-Interlock-ActionState>0</External-Interlock-ActionState></External-Interlock></Relay><Heater><System-Id>11</System-Id><Shared-Type>BOW_NO_EQUIPMENT_SHARED</Shared-Type><Enabled>no</Enabled><Current-Set-Point>70</Current-Set-Point><SolarSetPoint>90</SolarSetPoint><Max-Water-Temp>104</Max-Water-Temp><Min-Settable-Water-Temp>55</Min-Settable-Water-Temp><Max-Settable-Water-Temp>90</Max-Settable-Water-Temp><Operation>
                    PEO_HEATER_EQUIPMENT
                    <Heater-Equipment><System-Id>12</System-Id><Name>FPH</Name><Type>PET_HEATER</Type><Heater-Type>HTR_SOLAR</Heater-Type><Enabled>yes</Enabled><Priority>HTR_PRIORITY_1</Priority><Run-For-Priority>HTR_MAINTAINS_PRIORITY_FOR_AS_LONG_AS_VALID</Run-For-Priority><SupportsCooling>yes</SupportsCooling><Shared-Equipment-System-ID>-1</Shared-Equipment-System-ID></Heater-Equipment></Operation></Heater><Sensor><System-Id>13</System-Id><Name>SolarSensor</Name><Type>SENSOR_SOLAR_TEMP</Type><Units>UNITS_FAHRENHEIT</Units></Sensor></Body-of-water></Backyard>
    <Schedules>
      <sche>
        <bow-system-id>1</bow-system-id>
        <equipment-id>2</equipment-id>
        <schedule-system-id>7</schedule-system-id>
        <event>164</event>
        <data>32</data>
        <enabled>1</enabled>
        <start-minute>0</start-minute>
        <start-hour>14</start-hour>
        <end-minute>0</end-minute>
        <end-hour>8</end-hour>
        <days-active>127</days-active>
        <recurring>1</recurring>
      </sche>
      <sche>
        <bow-system-id>1</bow-system-id>
        <equipment-id>2</equipment-id>
        <schedule-system-id>8</schedule-system-id>
        <event>164</event>
        <data>50</data>
        <enabled>1</enabled>
        <start-minute>0</start-minute>
        <start-hour>8</start-hour>
        <end-minute>0</end-minute>
        <end-hour>14</end-hour>
        <days-active>127</days-active>
        <recurring>1</recurring>
      </sche>
      <sche>
        <bow-system-id>1</bow-system-id>
        <equipment-id>5</equipment-id>
        <schedule-system-id>9</schedule-system-id>
        <event>164</event>
        <data>1</data>
        <enabled>1</enabled>
        <start-minute>5</start-minute>
        <start-hour>8</start-hour>
        <end-minute>0</end-minute>
        <end-hour>14</end-hour>
        <days-active>127</days-active>
        <recurring>1</recurring>
      </sche>
    </Schedules>
  </MSPConfig>
  <MSPAPI version="0.4" latestversion="0.4">
    <Device-APIs>
      <API System-Id="2" OpType="ON_OFF" ref="SetUIEquipmentCmd" EquipmentID="2" IsOn="API::STATUS::Filter::filterSpeed"/>
      <API System-Id="11" OpType="ON_OFF" ref="SetHeaterEnable" HeaterID="11"/>
      <API System-Id="11" OpType="SETPOINT" ref="SetUIHeaterCmd" HeaterID="11" Temp="API::STATUS::VirtualHeater::Current-Set-Point"/>
      <API System-Id="5" OpType="ON_OFF" ref="SetUIEquipmentCmd" EquipmentID="5" IsOn="API::STATUS::Relay::relayState"/>
      <API System-Id="0" OpType="CSAD_MODE" ref="UISetCSADMode" CSADID="0" Mode="API::STATUS::CSAD::mode"/>
      <API System-Id="0" OpType="CSAD_CALIBRATION" ref="UISetCSADTargetValue" CSADID="0" Mode="API::STATUS::CSAD::ph"/>
    </Device-APIs>
    <Favorite-APIs>
      <API Favorite-Id="2" ref="SetUIEquipmentCmd" OpType="ON_OFF" EquipmentID="2" IsOn="API::STATUS::Filter::filterState"/>
      <API Favorite-Id="11" ref="API::GOTOFEATURE"/>
      <API Favorite-Id="1" ref="SetHeaterEnable" HeaterID="11"/>
      <API Favorite-Id="5" ref="SetUIEquipmentCmd" OpType="ON_OFF" EquipmentID="5"/>
      <API Favorite-Id="0" ref="API::GOTOFEATURE"/>
    </Favorite-APIs>
    <Schedule-APIs>
      <API System-Id="2" OpType="CREATE_SCHEDULE" ref="CreateUIScheduleCmd" EquipmentID="2" Data="API::STATUS::Filter::filterSpeed" ActionID="164"/>
      <API System-Id="2" OpType="EDIT_SCHEDULE" ref="EditUIScheduleCmd" EquipmentID="API::CONFIG::sche::schedule-system-id" Data="API::STATUS::Filter::filterSpeed" ActionID="164"/>
      <API System-Id="2" OpType="REMOVE_SCHEDULE" ref="DeleteUIScheduleCmd" ScheduleSystemID="API::CONFIG::sche::schedule-system-id"/>
      <API System-Id="11" OpType="CREATE_SCHEDULE" ref="CreateUIScheduleCmd" EquipmentID="11" Data="API::STATUS::VirtualHeater::Current-Set-Point" ActionID="315"/>
      <API System-Id="11" OpType="EDIT_SCHEDULE" ref="EditUIScheduleCmd" EquipmentID="API::CONFIG::sche::schedule-system-id" Data="API::STATUS::VirtualHeater::Current-Set-Point" ActionID="315"/>
      <API System-Id="11" OpType="REMOVE_SCHEDULE" ref="DeleteUIScheduleCmd" ScheduleSystemID="API::CONFIG::sche::schedule-system-id"/>
      <API System-Id="5" OpType="CREATE_SCHEDULE" ref="CreateUIScheduleCmd" EquipmentID="5" Data="1" ActionID="164"/>
      <API System-Id="5" OpType="EDIT_SCHEDULE" ref="EditUIScheduleCmd" EquipmentID="API::CONFIG::sche::schedule-system-id" Data="1" ActionID="164"/>
      <API System-Id="5" OpType="REMOVE_SCHEDULE" ref="DeleteUIScheduleCmd" ScheduleSystemID="API::CONFIG::sche::schedule-system-id"/>
    </Schedule-APIs>
  </MSPAPI>
</Response>

You are right. It doesn’t look like they expose the solar temp reading anywhere in the API. The info you are providing is helping me fill in the blanks on how they handle sensors. While they do assign a system ID, BOW, etc., each sensor is associated with a backyard air temp, BOW water temp or BOW flow sensor. In other words, this information comes back in the getTelemetry with the parent object (Backyard or BOW), and not on it’s own. Sorry, but I can’t help with the solar temps. I’m going to remove the sensor handler from the binding as I have yet to see a standalone sensor that reports back in the telemetry.

Ok thanks, that’s frustrating that they don’t give you a way to query it. I also have an actuator on the solar loop and was hoping the actuator state would be captured in the filterValvePosition channel on the pump, but that never seems to update either.

The heater state might reflect the state of the solar valve. The filter valve is for pool/spa mode.

@matchews I hope you’re doing well. After a while not looking at things I have started to get into linking items to my heater channels. It turns out that the binding only finds the virtual heaters when I do a scan, and does not generate any things for the actual heaters (which would give me a heaterState and enable channel I think). The heaterState would be useful for determining whether the Heater was actually on or if there was some discrepancy between heater status and the heater being turned on/off. Here is my getTelemetry response. You’ll see that systemId 4/12 are the virtual heaters (which do have things/channels) and systemId 5/13 are the heaters that do not get populated:

Hayward Connection thing:  getTelemetryData Hayward http response: OK <STATUS version="1.0"><Backyard systemId="116587" statusVersion="8" airTemp="66" status="1" state="1" configUpdatedTime="2021-12-08T17:02:52.54Z" datetime="2021-12-08T11:06:21.714" /><BodyOfWater systemId="1" flow="1" waterTemp="66" /><Filter systemId="3" valvePosition="1" filterSpeed="50" filterState="1" lastSpeed="50" />
<VirtualHeater systemId="4" Current-Set-Point="72" enable="no" />
<Heater systemId="5" heaterState="0" enable="yes" />
<Chlorinator systemId="6" operatingMode="1" Timed-Percent="55" scMode="0" chlrError="0" chlrAlert="0" avgSaltLevel="2772" instantSaltLevel="2655" status="128" /><Pump systemId="9" pumpState="0" pumpSpeed="0" lastSpeed="48" /><ColorLogic-Light systemId="8" lightState="0" currentShow="5" /><CSAD systemId="0" ph="" orp="" status="0" mode="0" /><BodyOfWater systemId="2" flow="1" waterTemp="-1" /><Filter systemId="11" valvePosition="1" filterSpeed="0" filterState="0" lastSpeed="100" />
<VirtualHeater systemId="12" Current-Set-Point="60" enable="no" />
<Heater systemId="13" heaterState="0" enable="yes" />
<Chlorinator systemId="14" operatingMode="1" Timed-Percent="6" scMode="0" chlrError="0" chlrAlert="0" avgSaltLevel="0" instantSaltLevel="0" status="0" /><Pump systemId="16" pumpState="0" pumpSpeed="0" lastSpeed="100" /><CSAD systemId="0" ph="" orp="" status="0" mode="0" /><Group systemId="34" groupState="0" /><Group systemId="36" groupState="0" /></STATUS>

Do you think this may be due to my system having 2 bodies of water, similar to some of the other issues I saw months ago?

Lastly, do you know what the “Enable” channel of the actual heaters (5/13) represents? You can see that both of those channels say “YES” currently while the heater is actually not heating, and neither BOW (pool/spa) have the heater turned on. (BTW, there is only 1 physical heater in my system)

The VirtualHeater that you control is capable of utilizing multiple physical heaters (i.e. solar and gas), with each heater given a priority. I suspect the enable allows you to disable one or the other. As for the heaters not being discovered, which version of the code are you running? Here is a link to the latest version:

https://drive.google.com/file/d/14ooOyNwiKFOrK3VQlmKQU2wOHdUPLXSj/view?usp=sharing

If this doesn’t solve the problem, please send me the getMSPConfig results and I’ll review.

Thanks