This is a docker container for https://github.com/ccutrer/balboa_worldwide_app that supports a remote serial to IP device or host running ser2net, socat or ESPEasy serial server.
There are 3 components to this solution:
Installation and configuration of MQTT are beyond the scope of this project as there are a plethora of good articles on setting up an MQTT broker.
Table of contents generated with markdown-toc
As an Amazon Associate I earn from qualifying purchases. I get commissions for purchases made through links in this post. Most hot tubs are fed 240v and are capable of delivering 50-amps of current = 12,000 W so... electricity is dangerous and can cause personal injury or DEATH as well as other property loss or damage if not used or constructed properly. If you have any doubts whatsoever about performing do-it-yourself electrical work, PLEASE do the smart thing and hire a QUALIFIED SPECIALIST to perform the work for you.
NEVER WORK WITH LIVE VOLTAGE. Always disconnect the power source before working with electrical circuits.
I've had great success with the Elfin-EW11A-0 from Hi-Flying Technology. It's a simple $24 RS-485 to WiFi device that takes an input voltage of 5-18VDC, has a web interface for remote admin and an external antenna.
EW11_D650
10.10.100.254
and login with username: admin
password: admin
Value | Setting |
---|---|
WiFi Mode | STA |
STA SSID | your wifi SSID |
STA KEY | your wifi password |
Optionally You can setup a static IP address using the LAN Settings section. Just remember to turn DHCP Server
to Off.
Submit
Restart
admin
password: admin
. This is a good time to change those and will only affect the web admin.Value | Setting |
---|---|
Baud Rate | 115200 |
Data Bit | 8 |
Stop Bit | 1 |
Parity | None |
Protocol | None |
Submit
Value | Setting |
---|---|
Name | netp |
Protocol | TCP Server |
Local Port | 8899 |
Buffer Size | 512 |
Keep Alive(s) | 60 |
Timeout(s) | 0 |
Max Accept | 3 |
Security | Disable |
Route | Uart |
Submit
Restart
You'll need an ATX Molex Micro Fit Connector to connect to the communications port of the Balboa equipment. I also recommend:
My hot tub had a small Y-Cable hanging outside of the control box that you can plug into for power and to get to the RS-485 communications of the tub. If you don't have this cable, you can likely plug into the main control board if it has the same outlet type. This should be the same type of connector that goes to your control panel.
Note that the tab is on the left of the connector
The connection is an ATX Molex Micro Fit Connector 4Pin (no, not the same as your old ATX power supply, I know, I tried too). Cut the one you ordered in half since you'll be making your own cable. Strip the ends of the ATX Molex Micro Fit connector. Be careful not to short anything and plug that into your tubs Y-cable or J33/J45 port. Confirm and tag the wires for +V, ground and RS-485 A/+ and B-, they should match the image.
Disconnect the cable and solder ~36-inches of Silicone coated wire onto each of the ends using the color that corresponds to the pin. Use some Heat Shrink Tubing or electrical tape to protect your soldered connections. I suggest crimping some 22AWG ferrules to the ends of those cables or you can just tin them and be careful.
Color | Pin/Wire |
---|---|
Red | DC + |
Black | Ground |
Yellow | RS-485 A/+ |
Blue | RS-485 B/- |
You can now connect the wires as show in the image below to the screw block at the end of the EW11 interface cable.
NOTE: You can disconnect the terminal block to make it easier to work with.
Plug everything in and confirm you can access the web interface of the EW11.
I drilled a small hole in the bottom of the hot tubs plastic media device enclosure, routed the cable in and stashed the EW11 in there. The media pocket has the added benefit of being unshielded, unlike the rest of the tub which has foil insulation.
Installation and configuration of Docker and docker-compose are beyond the scope of this project as there are a plethora of good articles on setting up Docker.
MQTT_URI
and BRIDGE_IP
to match your set updocker-compose up -d
and let Docker do its magic. NOTE: MQTT_URI must be properly escaped, e.g.
mqtt://useename:pa##word@10.1.10.2
would need to bemqtt://username:pa%23%23word@10.1.10.2
. See https://www.urlencoder.org/ for details.
Alternatively, you can execute docker run --rm ghcr.io/jshank/bwalink:latest -e MQTT_URI='your_mqtt_uri' -e BRIDGE_IP='your_ew11_ip'
If everything went well, you can subscribe to the homie/#
topic of your MQTT broker and should see something like this:
homie/bwa/$homie 4.0.0
homie/bwa/$name BWA Spa
homie/bwa/$state ready
homie/bwa/$nodes spa
homie/bwa/spa/$name BWA Spa
homie/bwa/spa/$type CL501X1
homie/bwa/spa/$properties priming,heatingmode,temperaturescale,24htime,heating,temperaturerange,currenttemperature,settemperature,filter1,filter2,pump1,pump2,pump3,light1,circpump
homie/bwa/spa/priming true
homie/bwa/spa/priming/$name Is the pump priming
homie/bwa/spa/priming/$datatype boolean
homie/bwa/spa/heatingmode ready
If you use Home Assistant, you don't need to run your own docker setup - you can run it as an addon.
/addons
, create a new directory called bwalink
. More info: Tutorial: Making your first add-onIf you have MQTT Discovery enabled, Home Assistant will get a new BWA device along with all of the discovered sensors and switches for the spa. Otherwise, you'll need to manually create them as follows.
- platform: mqtt
name: "Hot Tub 24hour Clock Mode"
state_topic: "homie/bwa/spa/24htime"
availability:
- topic: "homie/bwa/$state"
payload_available: "ready"
payload_not_available: "lost"
command_topic: "homie/bwa/spa/24htime/set"
payload_on: "true"
payload_off: "false"
icon: mdi:wrench-clock
- platform: mqtt
name: "Hot Tub Pump 1 (Lounge)"
state_topic: "homie/bwa/spa/pump1"
availability:
- topic: "homie/bwa/$state"
payload_available: "ready"
payload_not_available: "lost"
command_topic: "homie/bwa/spa/pump1/set"
payload_on: "toggle"
payload_off: "toggle"
state_on: 2
state_off: 0
icon: mdi:chart-bubble
- platform: mqtt
name: "Hot Tub Pump 2 (Seats)"
state_topic: "homie/bwa/spa/pump2"
availability:
- topic: "homie/bwa/$state"
payload_available: "ready"
payload_not_available: "lost"
command_topic: "homie/bwa/spa/pump2/set"
payload_on: "toggle"
payload_off: "toggle"
state_on: 2
state_off: 0
icon: mdi:chart-bubble
- platform: mqtt
name: "Hot Tub Pump 3 (Feet)"
state_topic: "homie/bwa/spa/pump3"
availability:
- topic: "homie/bwa/$state"
payload_available: "ready"
payload_not_available: "lost"
command_topic: "homie/bwa/spa/pump3/set"
payload_on: "toggle"
payload_off: "toggle"
state_on: 2
state_off: 0
icon: mdi:chart-bubble
- platform: mqtt
name: "Hot Tub Light"
state_topic: "homie/bwa/spa/light1"
availability:
- topic: "homie/bwa/$state"
payload_available: "ready"
payload_not_available: "lost"
command_topic: "homie/bwa/spa/light1/set"
payload_on: "true"
payload_off: "false"
state_on: "true"
state_off: "false"
icon: mdi:car-parking-lights
- platform: mqtt
name: "Hot Tub Circulation Pump"
state_topic: "homie/bwa/spa/circpump"
availability:
- topic: "homie/bwa/$state"
payload_available: "ready"
payload_not_available: "lost"
icon: mdi:sync
- platform: mqtt
name: "Hot Tub Priming"
state_topic: "homie/bwa/spa/priming"
availability:
- topic: "homie/bwa/$state"
payload_available: "ready"
payload_not_available: "lost"
- platform: mqtt
name: "Hot Tub Temperature Scale"
state_topic: "homie/bwa/spa/temperaturescale"
availability:
- topic: "homie/bwa/$state"
payload_available: "ready"
payload_not_available: "lost"
- platform: mqtt
name: "Hot Tub Heating"
state_topic: "homie/bwa/spa/heating"
availability:
- topic: "homie/bwa/$state"
payload_available: "ready"
payload_not_available: "lost"
icon: mdi:hot-tub
- platform: mqtt
name: "Hot Tub Temperature Range"
state_topic: "homie/bwa/spa/temperaturerange"
availability:
- topic: "homie/bwa/$state"
payload_available: "ready"
payload_not_available: "lost"
icon: mdi:thermometer-lines
- platform: mqtt
name: "Hot Tub Current Temperature"
state_topic: "homie/bwa/spa/currenttemperature"
unit_of_measurement: "°F"
availability:
- topic: "homie/bwa/$state"
payload_available: "ready"
payload_not_available: "lost"
- platform: mqtt
name: "Hot Tub Filter 1 Cycle Running"
state_topic: "homie/bwa/spa/filter1"
availability:
- topic: "homie/bwa/$state"
payload_available: "ready"
payload_not_available: "lost"
icon: mdi:air-filter
- platform: mqtt
name: "Hot Tub Filter 2 Cycle Running"
state_topic: "homie/bwa/spa/filter2"
availability:
- topic: "homie/bwa/$state"
payload_available: "ready"
payload_not_available: "lost"
icon: mdi:air-filter
- platform: mqtt
unique_id : hot_tub_set_temp
name: "Hot Tub Set Temperature"
state_topic: "homie/bwa/spa/settemperature"
command_topic: "homie/bwa/spa/settemperature/set"
min: 80
max: 104
availability:
- topic: "homie/bwa/$state"
payload_available: "ready"
payload_not_available: "lost"
icon: mdi:thermometer
input_select:
hottub_mode:
name: Hot Tub Mode
options:
- ready
- rest
- ready_in_rest
hottub_temperature_range:
name: Hot Tub Temperature Range
options:
- high
- low
- alias: "Update Spa Heating Mode Selector"
trigger:
platform: mqtt
topic: "homie/bwa/spa/heatingmode"
# entity_id: input_select.thermostat_mode
action:
service: input_select.select_option
target:
entity_id: input_select.hottub_mode
data:
option: "{{ trigger.payload }}"
- alias: "Set Hot Tub Heating Mode"
trigger:
platform: state
entity_id: input_select.hottub_mode
action:
service: mqtt.publish
data:
topic: "homie/bwa/spa/heatingmode/set"
payload: "{{ states('input_select.hottub_mode') }}"
- alias: "Update Hot Tub Temperature Range Selector"
trigger:
platform: mqtt
topic: "homie/bwa/spa/temperaturerange"
# entity_id: input_select.thermostat_mode
action:
service: input_select.select_option
target:
entity_id: input_select.hottub_temperature_range
data:
option: "{{ trigger.payload }}"
- alias: "Set Hot Tub Temperature Range"
trigger:
platform: state
entity_id: input_select.hottub_temperature_range
action:
service: mqtt.publish
data:
topic: "homie/bwa/spa/temperaturerange/set"
payload: "{{ states('input_select.hottub_temperature_range') }}"
- alias: "Set Hot Tub Temperature Ready"
trigger:
platform: time
at: "11:00:00"
condition:
condition: state
entity_id: group.family
state: "home"
action:
service: mqtt.publish
data:
topic: "homie/bwa/spa/settemperature/set"
payload: "99"
- alias: "Set Hot Tub Temperature Standby"
trigger:
platform: time
at: "17:00:00"
action:
service: mqtt.publish
data:
topic: "homie/bwa/spa/settemperature/set"
payload: "80"