berniedp
(Bernard)
August 17, 2025, 8:35pm
1
Hi all,
I have the following select with an action when the value changes:
- platform: template
name: Schedule 2 Program
id: pump_schedule_2_program
options:
- "Standard - 2300 RPM"
- "Solar Heating - 40 GPM"
- "Cleaner - 2650 RPM"
- "Freeze Protect - 1250 RPM"
initial_option: "Standard - 2300 RPM"
optimistic: true
on_value:
then:
- lambda: |-
auto program = i + 1;
id(pentairpump).commandLocalProgram(program);
Now, this by itself works as defined.
However, I want to use the value (index) of this select elsewhere to run the same action and created the following lambda in a script (note: took out some parts
- id: egg_timer_check
then:
lambda: |-
if (id(egg_timer_enabled).state)
{
auto index = id(egg_timer_program).active_index();
auto program = index + 1;
id(pentairpump).run();
id(pentairpump).commandLocalProgram(program);
}
That however gives me the following compiler error:
/config/esphome-pool-heater.yaml: In lambda function:
/config/esphome-pool-heater.yaml:810:32: error: no match for 'operator+' (operand types are 'esphome::optional<unsigned int>' and 'int')
auto program = index + 1;
~~~~~~^~~
In file included from src/esphome/core/entity_base.h:5,
from src/esphome/components/binary_sensor/binary_sensor.h:4,
from src/esphome/core/controller.h:5,
from src/esphome/components/api/api_server.h:11,
from src/esphome/components/api/api_connection.h:8,
from src/esphome.h:3,
from src/main.cpp:3:
src/esphome/core/string_ref.h:118:20: note: candidate: 'std::__cxx11::string esphome::operator+(const char*, const esphome::StringRef&)'
inline std::string operator+(const char *lhs, const StringRef &rhs) {
^~~~~~~~
src/esphome/core/string_ref.h:118:20: note: no known conversion for argument 1 from 'esphome::optional<unsigned int>' to 'const char*'
src/esphome/core/string_ref.h:124:20: note: candidate: 'std::__cxx11::string esphome::operator+(const esphome::StringRef&, const char*)'
inline std::string operator+(const StringRef &lhs, const char *rhs) {
^~~~~~~~
src/esphome/core/string_ref.h:124:20: note: no known conversion for argument 1 from 'esphome::optional<unsigned int>' to 'const esphome::StringRef&'
*** [.pioenvs/esphome-pool-heater/src/main.cpp.o] Error 1
========================== [FAILED] Took 4.56 seconds ==========================
Anybody who can help me out here?
Thanks,
B.
zoogara
(Daryl)
August 18, 2025, 10:33am
2
Maybe if you post all the yaml instead of just the bits you think are relevant…
1 Like
berniedp
(Bernard)
August 18, 2025, 12:49pm
3
Hi Daryl,
as it’s a meaty piece of code, I thought of only adding the code that’s giving me problems… But here’s the entire bunch:
esphome:
name: "esphome-pool-heater"
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
level: DEBUG
logs:
text_sensor: ERROR
# Enable Home Assistant API
api:
ota:
platform: esphome
time:
- platform: sntp
id: sntp_time
timezone: America/New_York
servers:
- pfsense.deprez.biz
- 0.pool.ntp.org
- 1.pool.ntp.org
on_time_sync:
- globals.set:
id: time_synced
value: "true"
on_time:
- seconds: /15
then:
- script.execute: ichlor_on_off_script
- script.execute: pump_schedule_check
wifi:
ssid: "REDACTED"
password: "REDACTED"
manual_ip:
static_ip: 172.16.10.138
gateway: 172.16.10.1
subnet: 255.255.255.0
dns1: 172.16.10.15
domain: .REDACTED
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "REDACTED"
password: "REDACTED"
captive_portal:
external_components:
- source: github://bdeprez/Pool_Automation@main
# https://github.com/bdeprez/Pool_Automation/tree/main
components: [pentair_intelliflo]
refresh: 0s
uart:
tx_pin: GPIO17
rx_pin: GPIO18
baud_rate: 9600
pentair_intelliflo:
id: pentairpump
web_server:
port: 80
version: 3
auth:
username: "REDACTED"
password: "REDACTED"
sorting_groups:
- id: sorting_group_temperatures
name: "Temperatures"
sorting_weight: -10
- id: sorting_group_heating
name: "Heating"
sorting_weight: -9
- id: sorting_group_pump_status
name: "Pump Status"
sorting_weight: -20
- id: sorting_group_pump_schedules
name: "Pump Schedules"
sorting_weight: -19
- id: sorting_group_pump_eggtimer
name: "Pump Egg Timer"
sorting_weight: -18
- id: sorting_group_pump_freezeprotect
name: "Pump Freeze Protect"
sorting_weight: -17
- id: sorting_group_ichlor
name: "iChlor"
sorting_weight: -15
- id: sorting_group_waterfall
name: "Waterfall"
sorting_weight: -5
- id: sorting_group_light
name: "Light"
sorting_weight: -4
globals:
- id: time_synced
type: bool
restore_value: no
initial_value: "false"
# pump mode: 0: inactive, 1: sched 1, 2: sched 2, 3: eggtimer, 4: freezeprotect, (9:always_on)
- id: pump_mode
type: int
restore_value: yes
initial_value: "0"
# to count timestamp when the pump was started
- id: pump_running_timestamp
type: long int
restore_value: no
initial_value: "0"
# to count timestamp when the pump has been stopped
- id: pump_stopped_timestamp
type: long int
restore_value: no
initial_value: "0"
- id: egg_timer_start_timestamp
type: long int
restore_value: no
initial_value: "0"
- id: pump_running_for
type: long int
restore_value: no
initial_value: "0"
- id: pump_stopped_for
type: long int
restore_value: no
initial_value: "0"
- id: egg_timer_check_script_result
type: bool
restore_value: no
- id: freeze_protect_check_script_result
type: bool
restore_value: no
- id: schedule_1_check_script_result
type: bool
restore_value: no
- id: schedule_2_check_script_result
type: bool
restore_value: no
- id: schedule_1_current_program
type: int
restore_value: yes
initial_value: "1"
- id: schedule_1_new_program
type: int
restore_value: yes
initial_value: "1"
- id: schedule_2_current_program
type: int
restore_value: yes
initial_value: "1"
- id: schedule_2_new_program
type: int
restore_value: yes
initial_value: "1"
- id: egg_timer_current_program
type: int
restore_value: yes
initial_value: "3"
- id: egg_timer_new_program
type: int
restore_value: yes
initial_value: "3"
- id: freeze_protect_current_program
type: int
restore_value: yes
initial_value: "4"
- id: freeze_protect_new_program
type: int
restore_value: yes
initial_value: "4"
sensor:
- platform: wifi_signal
name: "WiFi Signal"
id: wifi_signal_db
update_interval: 60s
entity_category: diagnostic
# Reports the WiFi signal strength in %
- platform: copy
source_id: wifi_signal_db
name: "WiFi Strength"
filters:
- lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
unit_of_measurement: "%"
entity_category: diagnostic
# - platform: pentair_intelliflo
# power:
# id: pump_power
# name: "Power"
# web_server:
# sorting_group_id: sorting_group_pump_status
# sorting_weight: 4
# rpm:
# id: pump_rpm
# name: "RPM"
# unit_of_measurement: 'RPM'
# web_server:
# sorting_group_id: sorting_group_pump_status
# sorting_weight: 5
# flow:
# id: pump_gpm
# name: "GPM"
# unit_of_measurement: gal/min
# web_server:
# sorting_group_id: sorting_group_pump_status
# sorting_weight: 6
# !!! TEMP !!! POOL & ROOF TEMP - removed for testing purposes
#Pool sensor voltages
# - platform: ads1115
# multiplexer: 'A0_GND'
# gain: 4.096
# update_interval: 30s
# id: pool_voltage
# name: "Pool Sensor Voltage"
# - platform: ads1115
# multiplexer: 'A1_GND'
# gain: 4.096
# update_interval: 30s
# id: roof_voltage
# name: "Roof Sensor Voltage"
#Pool sensor resistance
# - platform: resistance
# id: pool_resistance
# sensor: pool_voltage
# configuration: DOWNSTREAM
# resistor: 9.6kOhm
# name: Pool Resistance
# - platform: resistance
# id: roof_resistance
# sensor: roof_voltage
# configuration: DOWNSTREAM
# resistor: 9.6kOhm
# name: Roof Resistance
#Pool sensor temperatures
# https://esphome.io/components/sensor/ntc.html#ntc-sensor
# !!! TEMP !!! POOL & ROOF TEMP - removed for testing purposes
# - platform: ntc
# id: pool_temp_c
# name: Pool Temperature C
# sensor: pool_resistance
# calibration:
# - 10.0kOhm -> 25°C
# - 32.648kOhm -> 0°C
# - 15.711kOhm -> 15°C
# web_server:
# sorting_group_id: sorting_group_temperatures
# sorting_weight: 10
# - platform: copy
# source_id: pool_temp_c
# id: pool_temp_f
# name: Pool Temperature F
# filters:
# - lambda: return (x * 9/5) + 32;
# unit_of_measurement: °F
# web_server:
# sorting_group_id: sorting_group_temperatures
# sorting_weight: 12
# - platform: ntc
# id: roof_temp_c
# name: Roof Temperature C
# sensor: roof_resistance
# calibration:
# - 10.0kOhm -> 25°C
# - 32.648kOhm -> 0°C
# - 15.711kOhm -> 15°C
# web_server:
# sorting_group_id: sorting_group_temperatures
# sorting_weight: 11
# - platform: copy
# source_id: roof_temp_c
# id: roof_temp_f
# name: Roof Temperature F
# filters:
# - lambda: return (x * 9/5) + 32;
# web_server:
# sorting_group_id: sorting_group_temperatures
# sorting_weight: 13
number:
# Pool Heating - target temperature
- platform: template
name: Target Temperature
optimistic: True
restore_value: True
initial_value: 30
id: target_temperature
update_interval: never
min_value: 25
max_value: 35
step: 1
device_class: temperature
unit_of_measurement: °C
icon: mdi:coolant-temperature
mode: SLIDER
web_server:
sorting_group_id: sorting_group_heating
sorting_weight: 6
# Home Assistant - Outdoor Temperature
- platform: homeassistant
id: ha_outdoor_temp_feels_like
entity_id: sensor.tempest_ws_feels_like
- platform: homeassistant
id: ha_outdoor_temp
entity_id: sensor.tempest_ws_temperature
# Freeze Protect - Start temperature
- platform: template
name: Freeze Protect Temp
optimistic: True
restore_value: True
initial_value: 30
id: freeze_protect_temperature
update_interval: never
min_value: 0
max_value: 5
step: 0.1
device_class: temperature
unit_of_measurement: °C
icon: mdi:coolant-temperature
mode: SLIDER
web_server:
sorting_group_id: sorting_group_pump_freezeprotect
sorting_weight: 2
# EGG TIMER duration
- platform: template
name: Egg Timer Duration
id: egg_timer_duration
min_value: 15
max_value: 300
step: 30
initial_value: 60
optimistic: True
unit_of_measurement: min
mode: SLIDER
web_server:
sorting_group_id: sorting_group_pump_eggtimer
sorting_weight: 2
# !!! TEMP !!! POOL & ROOF TEMP - added for testing purposes
- platform: template
name: Pool Temperature C
id: pool_temp_C
min_value: 25
max_value: 35
step: 1
initial_value: 25
optimistic: True
unit_of_measurement: °C
mode: SLIDER
web_server:
sorting_group_id: sorting_group_heating
sorting_weight: 1
# !!! TEMP !!! POOL & ROOF TEMP
- platform: template
name: Roof Temperature C
id: roof_temp_C
min_value: 25
max_value: 35
step: 1
initial_value: 25
optimistic: True
unit_of_measurement: °C
mode: SLIDER
web_server:
sorting_group_id: sorting_group_heating
sorting_weight: 2
###DATETIME TIMES###
datetime:
- platform: template
id: pump_sched_1_start
type: time
name: Schedule 1 Start Time
optimistic: yes
initial_value: "08:00:00"
restore_value: true
web_server:
sorting_group_id: sorting_group_pump_schedules
sorting_weight: 2
- platform: template
id: pump_sched_1_end
type: time
name: Schedule 1 End Time
optimistic: yes
initial_value: "18:00:00"
restore_value: true
web_server:
sorting_group_id: sorting_group_pump_schedules
sorting_weight: 3
- platform: template
id: pump_sched_2_start
type: time
name: Schedule 2 Start Time
optimistic: yes
initial_value: "08:00:00"
restore_value: true
web_server:
sorting_group_id: sorting_group_pump_schedules
sorting_weight: 6
- platform: template
id: pump_sched_2_end
type: time
name: Schedule 2 End Time
optimistic: yes
initial_value: "18:00:00"
restore_value: true
web_server:
sorting_group_id: sorting_group_pump_schedules
sorting_weight: 7
- platform: template
id: waterfall_sched_start
type: time
name: Waterfall Start Time
optimistic: yes
initial_value: "08:00:00"
restore_value: true
web_server:
sorting_group_id: sorting_group_waterfall
sorting_weight: 4
- platform: template
id: waterfall_sched_end
type: time
name: Waterfall End Time
optimistic: yes
initial_value: "08:05:00"
restore_value: true
web_server:
sorting_group_id: sorting_group_waterfall
sorting_weight: 5
button:
# !!! TEMP !!! added only for testing purposes
- platform: template
id: pump_run_button
name: "Pump Run Button"
on_press:
then:
if:
condition:
- binary_sensor.is_on: pump_running_status
then:
lambda: |-
id(pump_running_status).publish_state(false);
else:
lambda: |-
id(pump_running_status).publish_state(true);
- platform: restart
name: "Restart"
id: restart_button
entity_category: config
binary_sensor:
# - platform: pentair_intelliflo
# running:
# name: "Pump Running"
# id: pump_running_status
# web_server:
# sorting_group_id: sorting_group_pump_status
# sorting_weight: 2
- platform: template ## replace with above on PRD ##
id: pump_running_status
name: "Pump Running"
device_class: running
on_state:
then:
- if:
condition:
- binary_sensor.is_on: pump_running_status
then:
lambda: |-
id(pump_running_timestamp) = id(sntp_time).now().timestamp;
ESP_LOGD("TEST", "Pump running timestamp set to: ", id(pump_running_timestamp));
else:
lambda: |-
id(pump_stopped_timestamp) = id(sntp_time).now().timestamp;
ESP_LOGD("TEST", "Pump stopped timestamp set to: ", id(pump_stopped_timestamp));
web_server:
sorting_group_id: sorting_group_pump_status
sorting_weight: 2
- platform: copy
id: pump_running_status_copy
source_id: pump_running_status
switch:
# Pump enabled/disabled
- platform: template
id: pump_enabled
name: "Pump Enabled"
restore_mode: RESTORE_DEFAULT_ON
optimistic: True
web_server:
sorting_group_id: sorting_group_pump_status
sorting_weight: 1
on_turn_on:
then:
- lambda: |-
id(pentairpump).run();
# - text_sensor.template.publish:
# id: last_action
# state: "Pump ON"
on_turn_off:
then:
- lambda: |-
id(pentairpump).stop();
# - text_sensor.template.publish:
# id: last_action
# state: "Pump OFF"
# Schedule 1 enabled
- platform: template
id: schedule_1_enabled
name: "Schedule 1 Enabled"
restore_mode: RESTORE_DEFAULT_ON
optimistic: True
web_server:
sorting_group_id: sorting_group_pump_schedules
sorting_weight: 1
# Schedule 2 enabled
- platform: template
id: schedule_2_enabled
name: "Schedule 2 Enabled"
restore_mode: RESTORE_DEFAULT_OFF
optimistic: True
web_server:
sorting_group_id: sorting_group_pump_schedules
sorting_weight: 5
# Egg Timer enabled
- platform: template
id: egg_timer_enabled
name: "Egg Timer Enabled"
restore_mode: RESTORE_DEFAULT_OFF
optimistic: True
web_server:
sorting_group_id: sorting_group_pump_eggtimer
sorting_weight: 1
# Freeze Protect enabled
- platform: template
id: freeze_protect_enabled
name: "Freeze Protect Enabled"
restore_mode: RESTORE_DEFAULT_ON
optimistic: True
web_server:
sorting_group_id: sorting_group_pump_freezeprotect
sorting_weight: 11
# iChlor switches
# !!! TEMP !!! added for testing purposes
- platform: template
id: iChlor_enabled
name: "iChlor enabled"
# on_turn_on:
# - text_sensor.template.publish:
# id: last_action
# state: "iChlor ON"
# on_turn_off:
# - text_sensor.template.publish:
# id: last_action
# state: "iChlor OFF"
restore_mode: RESTORE_DEFAULT_OFF
optimistic: True
web_server:
sorting_group_id: sorting_group_ichlor
sorting_weight: 9
# !!! TEMP !!! commented for testing purposes
# - platform: gpio
# pin:
# number: GPIO45
# ignore_strapping_warning: true
# id: relay5
# name: iChlor L2
# internal: True
# - platform: gpio
# pin:
# number: GPIO46
# ignore_strapping_warning: true
# id: relay6
# name: iChlor L1
# internal: True
- platform: template
id: iChlor_relay
name: "iChlor"
# on_turn_on:
# - text_sensor.template.publish:
# id: last_action
# state: "iChlor ON"
# on_turn_off:
# - text_sensor.template.publish:
# id: last_action
# state: "iChlor OFF"
restore_mode: RESTORE_DEFAULT_OFF
optimistic: True
web_server:
sorting_group_id: sorting_group_ichlor
sorting_weight: 10
# Switch to enable / disable heating
- platform: template
id: heating_enabled
name: "Heating Enabled"
optimistic: True
restore_mode: RESTORE_DEFAULT_ON
web_server:
sorting_group_id: sorting_group_heating
sorting_weight: 5
# Heater Relay Switch
- platform: gpio
pin: GPIO2
id: heater_relay
name: Heater Valve
restore_mode: RESTORE_DEFAULT_OFF
# on_turn_on:
# then:
# - text_sensor.template.publish:
# id: last_action
# state: "Heater Valve OPENED"
# on_turn_off:
# then:
# - text_sensor.template.publish:
# id: last_action
# state: "Heater Valve CLOSED"
web_server:
sorting_group_id: sorting_group_heating
sorting_weight: 7
# Waterfall Relay Switch
# !!! TEMP !!! removed for testing purposes
# - platform: gpio
# pin: GPIO41
# !!! TEMP !!! added for testing purposes
- platform: template
id: waterfall_relay
name: Waterfall valve
restore_mode: RESTORE_DEFAULT_OFF
# on_turn_on:
# then:
# - text_sensor.template.publish:
# id: last_action
# state: "Waterfall Valve OPENED"
# on_turn_off:
# then:
# - text_sensor.template.publish:
# id: last_action
# state: "Waterfall Valve CLOSED"
optimistic: True ### REMOVE ON PROD ###
web_server:
sorting_group_id: sorting_group_waterfall
sorting_weight: 2
# Switch to enable / disable waterfall
- platform: template
id: waterfall_enabled
name: "Waterfall Enabled"
optimistic: True
restore_mode: RESTORE_DEFAULT_OFF
web_server:
sorting_group_id: sorting_group_waterfall
sorting_weight: 1
# Waterfall Schedule enabled
- platform: template
id: waterfall_schedule_enabled
name: "Watefall Schedule Enabled"
restore_mode: RESTORE_DEFAULT_OFF
optimistic: True
web_server:
sorting_group_id: sorting_group_waterfall
sorting_weight: 3
# Waterfall Schedule enabled
- platform: template
id: waterfall_always_on
name: "Watefall Always On"
restore_mode: RESTORE_DEFAULT_OFF
optimistic: True
web_server:
sorting_group_id: sorting_group_waterfall
sorting_weight: 6
# Light Relay Switch
# - platform: gpio
# pin: GPIO42
- platform: template
id: light_relay
name: Light
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- text_sensor.template.publish:
id: last_action
state: "Light ON"
on_turn_off:
then:
- text_sensor.template.publish:
id: last_action
state: "Light OFF"
optimistic: True ### REMOVE ON PROD ###
web_server:
sorting_group_id: sorting_group_light
sorting_weight: 10
select:
# To select Pump program
- platform: template
name: Schedule 1 Program
id: pump_schedule_1_program
options:
- "Standard - 2300 RPM"
- "Solar Heating - 40 GPM"
- "Cleaner - 2650 RPM"
- "Freeze Protect - 1000 RPM"
initial_option: "Standard - 2300 RPM"
restore_value: True
optimistic: true
on_value:
then:
- lambda: |-
auto program = i + 1;
id(pentairpump).commandLocalProgram(program);
web_server:
sorting_group_id: sorting_group_pump_schedules
sorting_weight: 4
- platform: template
name: Schedule 2 Program
id: pump_schedule_2_program
options:
- "Standard - 2300 RPM"
- "Solar Heating - 40 GPM"
- "Cleaner - 2650 RPM"
- "Freeze Protect - 1000 RPM"
initial_option: "Standard - 2300 RPM"
restore_value: True
optimistic: true
# on_value:
# then:
# - lambda: |-
# auto program = i + 1;
# id(pentairpump).commandLocalProgram(program);
web_server:
sorting_group_id: sorting_group_pump_schedules
sorting_weight: 8
# To select Timer program
- platform: template
name: Egg Timer Program
id: egg_timer_program
options:
- "Standard - 2300 RPM"
- "Solar Heating - 40 GPM"
- "Cleaner - 2650 RPM"
- "Freeze Protect - 1250 RPM"
initial_option: "Cleaner - 2650 RPM"
restore_value: True
optimistic: true
web_server:
sorting_group_id: sorting_group_pump_eggtimer
sorting_weight: 3
# To select Freeze protect program
- platform: template
name: Freeze Protect Program
id: freeze_protect_program
options:
- "Standard - 2300 RPM"
- "Solar Heating - 40 GPM"
- "Cleaner - 2650 RPM"
- "Freeze Protect - 1250 RPM"
initial_option: "Freeze Protect - 1250 RPM"
restore_value: True
optimistic: true
web_server:
sorting_group_id: sorting_group_pump_eggtimer
sorting_weight: 3
text_sensor:
- platform: version
name: "ESPHome Version"
- platform: wifi_info
ip_address:
name: "IP Address"
entity_category: diagnostic
ssid:
name: "Connected SSID"
entity_category: diagnostic
mac_address:
name: "Mac Address"
entity_category: diagnostic
# https://esphome.io/components/text_sensor/template.html
- platform: template
id: last_action
name: Last Action
icon: mdi:message
lambda: return {"System Started"};
update_interval: never
- platform: template
id: pump_mode_text
name: Pump Mode
icon: mdi:message
lambda: |-
switch(id(pump_mode)) {
case 0: return std::string("Inactive");
case 1: return std::string("Schedule 1");
case 2: return std::string("Schedule 2");
case 3: return std::string("Egg Timer");
case 4: return std::string("Freeze Protect");
//case 9: return std::string("Always On");
default: return std::string("No Known Mode");
}
update_interval: 1s
web_server:
sorting_group_id: sorting_group_pump_status
sorting_weight: 3
script:
- id: pump_schedule_check
then:
lambda: |-
if (id(time_synced))
{
switch (id(pump_mode))
{
// (inactive)
case 0:
if (id(pump_enabled).state)
{
id(egg_timer_check).execute();
}
else
{
}
//run egg_timer_check
//if schedule_1_enabled
// then run schedule_1_check
}
}
- id: egg_timer_check
then:
lambda: |-
if (id(egg_timer_enabled).state)
{
auto index = id(egg_timer_program).active_index();
auto program = index + 1;
id(pentairpump).run();
id(pentairpump).commandLocalProgram(program);
}
- id: schedule_1_check
then:
lambda: |-
if (id(schedule_1_enabled).state)
{
auto current_time = (id(sntp_time).now().hour * 3600) + (id(sntp_time).now().minute * 00) + (id(sntp_time).now().second);
auto schedule_start_time_seconds = (id(pump_sched_1_start).hour * 3600) + (id(pump_sched_1_start).minute * 60) + id(pump_sched_1_start).second;
auto schedule_end_time_seconds = (id(pump_sched_1_end).hour * 3600) + (id(pump_sched_1_end).minute * 60) + id(pump_sched_1_end).second;
if (current_time >= schedule_start_time_seconds < schedule_end_time_seconds)
{
id(pump_mode) = 1;
}
}
- id: schedule_2_check
then:
lambda: |-
if (id(schedule_2_enabled).state)
{
auto current_time = id(sntp_time).now().timestamp;
auto schedule_start_time_seconds = (id(pump_sched_2_start).hour * 3600) + (id(pump_sched_2_start).minute * 60) + id(pump_sched_2_start).second;
auto schedule_end_time_seconds = (id(pump_sched_2_end).hour * 3600) + (id(pump_sched_2_end).minute * 60) + id(pump_sched_2_end).second;
if (current_time >= schedule_start_time_seconds < schedule_end_time_seconds)
{
id(pump_mode) = 2;
}
}
# - id: freeze_protect_script
# then:
# lambda: |-
- id: ichlor_on_off_script # Triggered every minute from Time
then:
lambda: |-
//if (id(homeassistant_time).now().timestamp.is_valid())
if (id(sntp_time).now().is_valid())
{
// get current time
auto current_time = id(sntp_time).now().timestamp;
// check if pump is running
if (id(pump_running_status).state == true)
// pump is running
{
if (id(iChlor_relay).state == false)
// iChlor is off
{
id(pump_running_for) = difftime((current_time), id(pump_running_timestamp));
ESP_LOGD("TEST", "Pump running for: %d", id(pump_running_for));
if (id(pump_running_for) >= 60)
{
id(iChlor_relay).turn_on();
ESP_LOGD("TEST", "iChlor turned on");
}
}
}
// pump is not running
else
{
if (id(iChlor_relay).state == true)
// iChlor is on
{
id(pump_stopped_for) = difftime((current_time), id(pump_stopped_timestamp));
ESP_LOGD("TEST", "Pump stopped for: %d", id(pump_stopped_for));
if (id(pump_stopped_for) >= 60)
{
id(iChlor_relay).turn_off();
ESP_LOGD("TEST", "iChlor turned off");
}
}
}
}
Note: this version of the code is for testing purposes as I cannot use the target device without taking the current systems out without rewiring. So I’m simulating a number of sensors with manual workarounds for testing.
Thanks!
B.
Karosm
(Karosm)
August 18, 2025, 3:08pm
4
because you need .active_index().value() + 1
Look at the documentation example:
auto index = id(my_select).active_index();
if (index.has_value()) {
ESP_LOGI("main", "Option at index %d is active", index.value());
} else {
ESP_LOGI("main", "No option is active");
}
berniedp
(Bernard)
September 1, 2025, 8:53pm
5
Brilliant, I totally overlooked that - thank you @Karosm
Sorry for my delayed response - have been busy work-wise so hadn’t gotten around to work on this till now.
B.
1 Like
Karosm
(Karosm)
September 1, 2025, 9:00pm
6
No problem. I’m pleased to get any response, sooner or later. Not always the case…
Sorry isnt going to cut it around here for me, sir!! Next time your going to be late, we expect you to show up with some breakfast sandwiches or some donuts because we can’t eat “sorry’s” “traffic was bad”, etc excuses!!! Dang rookies!! ; )
Jk dude… Did you happen to mention what it is your making? Im just curious.
berniedp
(Bernard)
September 11, 2025, 2:44pm
8
As my recent pool controller (the Pentair Intelliconnect) which I installed in May of 2020 died, the pool guys’ only suggestion was to upgrade to the more expensive ones and I was not going to shell out 2.3K dollars for something that’s pretty simple, really.
So, with the experience of my previous adventure (see: How I added a Hayward solar pool control to HA via ESPhome ) I decided to build one myself.
I’ve so far been able to create a setup that controls the pump, pool solar heating, waterfall and the light. Currently the chlorinator is only partially integrated in where I can power it on/off and it’s still relying on the RS485 connection to the pump to know if there’s flow. I am struggling massively to create the code to fully integrate so I can update the output percentage.
I’m working on a write-up of what I accomplished so far, hoping somebody may be interested in helping out with the chlorinator. Write-up now published New Pentair pool automation setup – full write-up
Well that’s no surprise! I bet he was kind enough to let you pay him to so it for you too lol.
FYI back when i worked in landscaping and construction in general, things like pools or luxury cars were signs to us that the price was gonna get jacked up when it didnt look like people would miss an extra 500$ or so. Thats capitalism for ya though…
In the future you shouod borrow someone’s hooptie Ford Taurus and park it in the driveway and pretend your just house sitting and need to fix something you messed up or some similar story if you dont want contractors to tack on an extra 25% just because they think you wont want to negotiate the difference, or do what what you want, its just a tip.
Im busy for a couple more hours but, ill check it out and see if i can help ya out! You’re still at the same address, right? Just want to verify where i need to send my bill for tech support!
; )
1 Like