Stil hier
Inmiddels hebben we geen zwembad meer. We hebben een nieuw huis laten bouwen en hierbij bewust gekozen om geen zwembad meer te nemen (de buren wel, dus ik kan daar nog af en toe het orakel uithangen

).
Wel hebben we besloten om een nieuwe hottub te nemen. Omdat bouwen al duur zat was hebben we er eentje uit de Fonteyn stal genomen. Prima tub want er zit gewoon een Balboa pack in.
Dus toen het bouwstof enigzins neergedaald was werd het tijd om eens te kijken hoe we die tub kunnen aansturen, ik weiger natuurlijk om 250 euro te betalen voor een wifi oplossing waar voor nog geen 10 dollar aan onderdelen in zit.
Na wat zoekwerk ben ik uitgekomen bij
https://github.com/brianfeucht/esphome-balboa-spa deze is toch wel het meest actief.
Hardware
Omdat ik niet meer zoveel zin heb om te klooien met jumperwires, weerstandjes en soldererbout ben ik in het M5Stack ecosysteem. Simpel een
AtomS3 Lite ESP32S3 en een
RS485 Base in elkaar klikken en je bent er.
Vervolgens heb je een
ATX 4-pins molex microfit connector nodig. Maak niet dezelfde fout als ik door direct bij de woorden ATX en 4-pins naar een oude PC voeding graven in de doos met oude hardware, die zijn namelik net een fractie te groot.
Mooi, alle spullen waren toen in huis.
Aansluiten
Mijn tub heeft een Balboa B21 pack. Het moederbord wat daarin zit is van het type BP6013G2 (mijn vader heeft tegelijk met mij zijn tub ook gedaan, hij heeft ook een BP21 maar met board JZ6013X1, voor dit project was daar geen verschil in).
Haal de stroom van de tub, je wil niet per ongeluk met je dikke worstenvingertjes aan die 3 fase kabeltjes komen.
Maak het pack open.
Rechtsbovenin vind je 2 connectors: J34 en J35. Beide zijn voor wifi/bedieningspaneel. Hoewel Balboa aangeeft dat je met een Y-kabel 2 devices tegelijkertijd kunt aansluiten op 1 connecter gaf dit bij mij storing op het bedieningspaneel.
J35 was bij mij in gebruik voor het bedieningspaneel dus ik heb J34 gebruikt voor de ESP32.
De connector op het board heeft het clipje aan de bovenkant zitten. Als je de molex er dan in klikt zijn dit de kleuren van de draden (van links naar rechts, van boven naar beneden):
ROOD - ZWART
ZWART - GEEL
Omdat er 2 keer zwart is, heb ik bij mij een stukje paarse tape eromheen gedaan zodat ik ZWART en ZWART-PAARS heb
De pin nummering van J34/J35 is (van links naar rechts, van boven naar beneden):
4 - 3
2 - 1
De pin layout van board naar RS485 is als volgt:
B = 4 (zwart)
A = 2 (zwart-paars)
DC = 1 (geel)
G = 3 (rood)
Software
Zoals gezegd heb ik gekozen voor een bestaand project wat is gebaseerd op ESPHome. Het project voorzien in simpele on/off switches voor de jets. Deze gaven bij ons op beide BP21 boards problemen. De jets gingen aan/uit/aan/uit , zelfs na tweaken met de waardes voor max_toggle_attempts en discard_updates
De oplossing was om niet het switch component te gebruiken maar de fan component. Deze is bedoeld voor pompen met 2 snelheden (heb ik niet) maar werkt voor mijn board perfect.
Inmiddels is mijn yaml behoorlijk uitgebreid naar mijn situatie, maar hier moet je echt een heel eind mee komen:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
| # https://github.com/dhWasabi/M5Tough-BalboaSpa-esphome
# https://github.com/brianfeucht/esphome-balboa-spa
esphome:
name: hottub-dev
friendly_name: hottub-dev
# PlatformIO / USB behaviour
platformio_options:
board_build.extra_flags:
- "-DARDUINO_USB_CDC_ON_BOOT=0"
# Startup actions
on_boot:
priority: -100
then:
- delay: 10s
# Trigger a time sync so the spa clock matches Home Assistant
- button.press: spa_sync_time_button
esp32:
board: esp32-s3-devkitc-1
framework:
type: arduino
# External Balboa spa component
external_components:
- source:
type: git
url: https://github.com/brianfeucht/esphome-balboa-spa
ref: main
components: [balboa_spa]
# Network connectivity
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_pwd
# Fallback access point
ap:
ssid: !secret wifi_fallback_ssid
password: !secret wifi_fallback_pwd
# Home Assistant API
api:
# OTA update methods
ota:
- platform: web_server
- platform: esphome
# Embedded web interface
web_server:
port: 80
# Time source for spa clock sync
time:
- platform: homeassistant
timezone: "Europe/Amsterdam"
# Logging configuration
logger:
level: INFO
baud_rate: 115200
# Reduce UART-related noise
logs:
uart.arduino_esp32: WARN
sensor: WARN
template.sensor: WARN
# UART bus to spa controller
uart:
id: spa_uart_bus
tx_pin: GPIO6
rx_pin: GPIO5
baud_rate: 115200
data_bits: 8
parity: NONE
stop_bits: 1
rx_buffer_size: 1024
# Core Balboa spa integration
balboa_spa:
id: spa
spa_temp_scale: C
esphome_temp_scale: C
uart_id: spa_uart_bus
# Numeric sensors
sensor:
- platform: balboa_spa
balboa_spa_id: spa
# Fault log data
fault_code:
name: Fault Code
fault_total_entries:
name: Fault Total Entries
fault_current_entry:
name: Fault Current Entry
fault_days_ago:
name: Fault Days Ago
# WiFi diagnostics
- platform: wifi_signal
name: "WiFi Signal"
update_interval: 120s
entity_category: diagnostic
# Device uptime
- platform: uptime
name: "Uptime"
update_interval: 120s
entity_category: diagnostic
# Binary state sensors
binary_sensor:
- platform: balboa_spa
balboa_spa_id: spa
# Operating modes
highrange:
name: High Range
circulation:
name: Circulation Pump
restmode:
name: Rest Mode
heatstate:
name: Heat State
connected:
name: Connected
# Text sensors (read-only)
text_sensor:
- platform: balboa_spa
balboa_spa_id: spa
# Time and filter configuration
spa_time:
name: "Spa Time"
filter1_config:
name: "Filter 1 Config"
filter2_config:
name: "Filter 2 Config"
# Fault log text
fault_message:
name: "Fault Message"
fault_log_time:
name: "Fault Log Time"
# ESPHome version info
- platform: version
name: "ESPHome Version"
hide_timestamp: true
# Text inputs (writeable)
text:
- platform: balboa_spa
balboa_spa_id: spa
# Time and filter programming
spa_time:
name: "Set Spa Time"
mode: TEXT
filter1_start_time:
name: "Set Filter 1 Start Time"
mode: TEXT
filter1_duration:
name: "Set Filter 1 Duration"
mode: TEXT
filter2_start_time:
name: "Set Filter 2 Start Time"
mode: TEXT
filter2_duration:
name: "Set Filter 2 Duration"
mode: TEXT
# Simple on/off controls
# Jet switches are disabled because they showed unstable behaviour in this setup;
# use the fan-based jet controls below instead
switch:
- platform: balboa_spa
balboa_spa_id: spa
# Jets (disabled – using fan platform)
# jet1:
# name: Jet1
# max_toggle_attempts: 1
# discard_updates: 10
# jet2:
# name: Jet2
# max_toggle_attempts: 1
# discard_updates: 10
# jet3:
# name: Jet3
# max_toggle_attempts: 1
# discard_updates: 10
# Lighting
light:
name: Lights
# Multi-speed jet control
# Fan entities are used instead of switches because they provide more stable
# state handling and better behaviour in this setup than balboa_spa switches
fan:
- platform: balboa_spa
balboa_spa_id: spa
jet_1:
name: "Jet 1"
id: jet1_fan
discard_updates: 20
jet_2:
name: "Jet 2"
id: jet2_fan
jet_3:
name: "Jet 3"
id: jet3_fan
# Action buttons
button:
- platform: balboa_spa
balboa_spa_id: spa
# Spa commands
sync_time:
id: spa_sync_time_button
name: "Sync Spa Time"
disable_filter2:
name: "Disable Filter 2"
request_fault_log:
name: "Request Fault Log"
# Device restart
- platform: restart
name: "Restart"
# Temperature control
climate:
- platform: balboa_spa
balboa_spa_id: spa
name: "Spa Thermostat"
id: spa_thermostat
# UI constraints
visual:
min_temperature: 5 C
max_temperature: 45 C
temperature_step: 0.5 C |
Zoals je ziet doe ik een sync_time bij iederen boot van de ESP. De reden: als ik straks klaar ben met tweaken aan de tub word het een sit and forget setup. De ESP zal dan eigenlijk alleen nog opnieuw opstarten wanneer de tub stroomloos is geweest.
Het Balboa board heeft geen batterij voor de klok, wat betekend dat hij na stroomloos te zijn geweest altijd opstart met als tijd 12 uur 's middags (alle andere waardes zijn wel onthouden).
De ESP haalt bij opstarten de tijd op, en stuurt deze vervolgens naar de Balboa.
Home Assistant
Nu alles werkt is het natuurlijk tijd om het in HA te zetten en mooie dashboards te maken. In ons nieuwe huis heb ik een
tablet hangen welke de centrale spil is voor bediening en informatievoorziening rondom ons huis.
Daar is dus nu ook een tabje bijgekomen voor de tub

Zoals je ziet heb ik een Boost functie toegevoeg. Mijn ritueeltje als ik de tub in ga: eerst even douchen dan wat lekkere biertjes uitkiezen en dan richting de tuin lopen.
Voordat ik ga douchen druk ik even op Boost en de rest regelt HA:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
| alias: Hottub boost
description: ""
triggers:
- entity_id: input_boolean.hottub_boost
from: "off"
to: "on"
id: boost_on
trigger: state
- entity_id: input_boolean.hottub_boost
from: "on"
to: "off"
id: boost_off
trigger: state
conditions: []
actions:
- choose:
- conditions:
- condition: trigger
id: boost_on
sequence:
- action: input_number.set_value
target:
entity_id: input_number.hottub_temp_before_boost
data:
value: >-
{{ state_attr('climate.hottub_spa_thermostat', 'temperature') |
float }}
- parallel:
- alias: Turn off after 1 hour
sequence:
- delay:
hours: 1
minutes: 0
seconds: 0
milliseconds: 0
- action: input_boolean.turn_off
metadata: {}
target:
entity_id: input_boolean.hottub_boost
data: {}
- alias: Boost temperature
sequence:
- action: climate.set_temperature
target:
entity_id: climate.hottub_spa_thermostat
data:
temperature: >
{{ states('input_number.hottub_temp_before_boost') |
float + 1 }}
- alias: Turn jets on
sequence:
- delay:
seconds: 10
- action: fan.turn_on
target:
entity_id: fan.hottub_jet_1
- delay:
minutes: 1
- action: fan.turn_on
target:
entity_id: fan.hottub_jet_2
- delay:
minutes: 1
- action: fan.turn_on
target:
entity_id: fan.hottub_jet_3
- conditions:
- condition: trigger
id: boost_off
sequence:
- action: climate.set_temperature
target:
entity_id: climate.hottub_spa_thermostat
data:
temperature: |
{{ states('input_number.hottub_temp_before_boost') | float }}
- delay:
seconds: 10
- action: fan.turn_off
target:
entity_id: fan.hottub_jet_1
- delay:
seconds: 10
- action: fan.turn_off
target:
entity_id: fan.hottub_jet_2
- delay:
seconds: 10
- action: fan.turn_off
target:
entity_id: fan.hottub_jet_3
mode: restart |
Waarom?
Omdat het kan

Maar serieus: belangrijkste reden voor mij is zodat ik op afstand de temperatuur kan zien en aanpassen. Bijkomend voordeel is dat ik nu na stroomloos maken ook niet meer hoef te pielen op het bedieningspaneel om de tijd weer goed te zetten. Ook niet bij verandering van wintertijd naar zomertijd en weer terug.
Al het andere eromheen is gewoon bonus
En verder?
Ik ben nog met 2 sideprojects bezig die hieruit zijn voortgevloeid:
- Mijn oude NSPanel flashen van Tasmota naar ESPHome. Deze komt dan in de tubruimte te hangen
- Detecteren welke kleur de LED's van de tub zijn
Plaatjes zijn altijd leuk
Tijd voor een nieuwe sig..