This must be a simple misunderstanding on my part. So much is a mystery although I have made great progress in a variety of ESPHome projects using the ESP32+OLED display, etc.
I defined a refrigerator controller using a LILIGO S3 OLED widget. I am using the two buttons on the unit for a simple menu system to enable/disable, adjust display timeout, select F/C and various setpoints. To interface with HA I defined two templated controls: a switch (power) and a number (display timeout). This all works, and all controls are visible in HA and seem to work; power tracks the widget and the widget tracks changing the switch in HA. Ditto for the display timeout number.
The issue is the embedded web page doesn’t seem to link the templated switch or number state with the action. I can click on the action to affect the state but the action always return to the initial state. If I change the state from the controller, the “action” doesn’t change, just the state. If I refresh the web page, then the “action” matches the state.
Because the front end works as expected, I suppose this isn’t a big deal except I like having access to the refrigerator control panel w/o going through HA.
Here is a minimal test case where the templated switch doesn’t track the action yet the HA dashboard works properly (i.e. it changes state and represents it properly but I have to refresh the embedded web page to have the action set properly).
switch:
- platform: template
name: foo
id: bar
optimistic: yes
My code below:
The global to store state after power cycle.
- id: bEnable
type: bool
restore_value: yes
initial_value: 'false'
Boot code to set the switch state on power cycle and set immediate commits for state changes.
esphome:
name: refrigerator
on_boot:
priority: 600.0
then:
- output.turn_on: lcd_power
- script.execute: lcd_backlight_script
- lambda: id(power).publish_state(id(bEnable));
preferences:
flash_write_interval: 0s
The switch definition
switch:
- platform: template
name: Enable
id: power
turn_on_action:
- lambda: id(bEnable) = true;
- script.execute: refer_control
turn_off_action:
- lambda: id(bEnable) = false;
- script.execute: refer_control
lambda: return id(bEnable);
And the snippet in the menu handler which turns the power on/off. NB. toggle seems to be sufficient, but I was struggling trying various mechanisms to get the embedded page to track properly.
case 4:
// id(power).toggle();
id(bEnable) = !id(bEnable);
id(power).publish_state(id(bEnable));
break;