ccutrer / balboa_worldwide_app

Ruby library for communication with Balboa Water Group's WiFi module or RS-485
98 stars 27 forks source link

Balboa Worldwide App gem

This gem is a Ruby library for interacting with Wifi spa controllers from Balboa Water Group. There is no documentation on the protocol, and it has been reverse engineered by various individuals from both packet captures and tapping directly into the controller's communication bus. Not all messages have been deciphered. Configuration is automatic for those accessories that the protocol has been deciphered (number of pumps and speeds, lighting, etc.).

MQTT/Homie Bridge

An MQTT Bridge is provided to allow easy integration with other systems. You will need a separate MQTT server running (Mosquitto is a relatively easy and robust one). The MQTT topics follow the Homie convention, making them self-describing. If you're using a systemd Linux distribution, an example unit file is provided in contrib/bwa_mqtt_bridge.service. So a full example would be (once you have Ruby installed):

gem install balboa_worldwide_app
sudo curl https://github.com/ccutrer/balboa_worldwide_app/raw/main/contrib/bwa_mqtt_bridge.service -L -o /etc/systemd/system/bwa_mqtt_bridge.service
<modify the file to pass the correct URI to your MQTT server, and path to RS-485 device or hostname/IP for WiFi>
sudo systemctl enable bwa_mqtt_bridge
sudo systemctl start bwa_mqtt_bridge

Several properties also accept the non-Homie conforming value of toggle to indicate to cycle through available values, instead of going to a specifc value. These properties are:

OpenHAB

If you're going to integrate with OpenHAB, you'll need to install the MQTT Binding in Add-ons. Then go to Inbox, click +, select MQTT Binding and click ADD MANUALLY near the bottom. First create a Thing for the MQTT Broker and configure it to point to your MQTT server. Then go to manually add again, and choose a Homie MQTT Device. Select your bridge, and for Device ID put in bwa. Example Thing configuration:

OpenHAB MQTT Homie Thing Configuration

Example Items file (including configuration for exposing to HomeKit):

Number HotTubPump1_Speed "Pump 1" <pump> { channel="mqtt:homie300:hottub:spa#pump1", autoupdate="false" }
Number HotTubPump2_Speed "Pump 2" <pump> { channel="mqtt:homie300:hottub:spa#pump2", autoupdate="false" }
Switch HotTubLights_Switch "Hot Tub Lights" <light> (gAllOff, gLights) [ "Lighting" ] { channel="mqtt:homie300:hottub:spa#light1", autoupdate="false" }

String HotTub_HeatingMode "Heating Mode" { channel="mqtt:homie300:hottub:spa#heatingmode", autoupdate="false" }
String HotTub_TemperatureRange "Temperature Range" { channel="mqtt:homie300:hottub:spa#temperaturerange", autoupdate="false" }

Switch HotTubCircPump_Switch "Circ Pump" <pump> { channel="mqtt:homie300:hottub:spa#circpump" }
Switch HotTubHeaterActive_Switch "Heater Active" <fire> { channel="mqtt:homie300:hottub:spa#heating" }

Group gHotTubThermostat "Hot Tub Heater" [ "Thermostat" ]

String HotTub_HomeKitTargetMode (gHotTubThermostat) [ "homekit:TargetHeatingCoolingMode" ]
String HotTub_HomeKitCurrentMode (gHotTubThermostat) [ "homekit:CurrentHeatingCoolingMode" ]

Number:Temperature HotTub_CurrentTemp <temperature> (gHotTubThermostat) [ "CurrentTemperature" ] { channel="mqtt:homie300:hottub:spa#currenttemperature" }
Number:Temperature HotTub_SetTemp <temperature> (gHotTubThermostat) [ "TargetTemperature" ] { channel="mqtt:homie300:hottub:spa#settemperature", autoupdate="false" }

Example Rules file for maintaining HomeKit state:

rule "HomeKit Control"
when
  Item HotTubHeaterActive_Switch changed
then
  if (triggeringItem.state == OFF) {
    HotTub_HomeKitCurrentMode.postUpdate("OFF")
  } else {
    HotTub_HomeKitCurrentMode.postUpdate("HEAT")
  }
end

Example sitemap snippet:

Frame label="Hot Tub" {
    Switch item=HotTubLights_Switch label="Lights"
    Setpoint item=HotTubPump1_Speed minValue=0 maxValue=2 step=1
    Setpoint item=HotTubPump2_Speed minValue=0 maxValue=2 step=1
    Setpoint item=HotTub_SetTemp label="Set Point" minValue=80 maxValue=104 step=1
    Text item=HotTub_CurrentTemp label="Temperature"
    Text item=HotTub_HeatingMode
    Text item=HotTub_TemperatureRange
    Text item=HotTubCircPump_Switch
    Text item=HotTubHeaterActive_Switch
}

Home Assistant Integration

This gem will publish all of the BWA sensors and controls to Home Assistant and create a BWA Link device.

BWA Link Device in Home Assistant

Using RS-485 for a direct connection

This gem supports using an RS-485 direct connection to the hot tub if you don't have the Wifi module, or would simply like something more reliable. It is possible to connect to the GPIOs on a Raspberry Pi using a something like a MAX13487 transceiver, or to use a USB RS-485 dongle such as this one from Amazon. Any adapter based on the MAX485 chip is not supported. Setting up a serial device in Linux with GPIOs is beyond the scope of this documentation.

The key to proper communication is identifying the correct wires as RS-485+ and RS-485-. There should be a small connector coming out of your control box. It's compatible with an ATX micro-fit connector. You can also purchase a Y-cable such as this one if you already have something connected to the port, and want to keep it connected (or spy on its communication). Note that the colors may not be the same on any adapter or pigtail you find. Here's a photo of mine connected to the dongle:

RS-485 Dongle

As you can see in my case, the two black wires ended up being RS-485. The surefire way to test is to break out a multimeter and compare pairs of wires. One set of opposite pins should show 12-14V. Once you've found that keep one probe on the negative end, and try the other two wires. They should both read 2-3V. The slightly higher one will be RS-485+, and the slightly lower one will be RS-485-. You don't have to fret too much on getting them right (as long as you don't hook up the +12V line!) - you'll just get garbage if you swap + and -. Swap them back and you should be good. Here's a closer view of the header where you can see that the black wires (RS-485) are top-left and bottom-right when viewed looking into the connector, with the latch on the left.

Pinout

RFC2217 serial ports are also supported, if you want to run thie bridge on a different server than is directly connected to the spa. You can use ser2net to create such a serial port like ser2net -C "2217:telnet:0:/dev/ttyHotTub:remctl" -d, and then just specify the address as rfc2217://hostname:2217/. socat cannot be used, because we need to properly configure the serial port, and know that it is a serial port and not the BWA WiFi bridge, since the protocol is slightly different.

Related Projects

These projects are all in various states, and may be more or less developed than this one in varying aspects.

If you have the older GL/EL range such as the GL2000.

Thanks