Un-Expected LVGL Interaction

Currently Working on a Project to Automate the Air Flow on My Wood Heater.
I have an EspHome Device controlling a Servo to Move the Air Damper.

I also have Several WaveShare Displays that Display Temperature Gauges
& a Slider that allows me to Manually move the Damper.

The Issue I'm Seeing is that if one of these Displays is Rebooted, or possibly also loses the API Connection, the Panel will cause the Servo to trigger & move thru it's Sequence.

Servo Control is like this, always moving to zero before establishing a new setting.
(The Servo & Heater Temp Probes are on it's Own Esp32).

##### Servo Control #####
servo:
  - id: wh_servo1
    output: whs_output
    min_level: 5%
    max_level: 10%
    transition_length: 1s
#
output:
  - platform: ledc
    id: whs_output
    pin: 23
    frequency: 50 Hz
#
number:
  - platform: template
    id: whservoslider
    name: Heater Servo
    optimistic: true
    min_value: 0
    max_value: 100
    initial_value: 0
    step: 10
    on_value:
      then:
        - servo.write:
            id: wh_servo1
            level: -100%
        - delay: 1s
        - servo.write:
            id: wh_servo1
            level: !lambda |-
              return x/100;
        - delay: 1s
        - servo.write:
            id: wh_servo1
            level: 0%
        - delay: 2s
        - servo.detach: wh_servo1

The WaveShare Panels have a Slider that Ranges from 0 to 10, which I then Scale up by x10 to match the Servo Value.
Slider Portion of My LVGL is this:-

- slider:
    id: servo_slider
    align: BOTTOM_MID
    x: 0
    y: -50
    width: 400
    height: 50
    pad_all: 0
    radius: 5
    min_value: 0
    max_value: 10
    #step: 10
    value: 5  # Default slider value (50% brightness)
    indicator:
      radius: 5
    knob:
      bg_opa: "0%"  # Hides the knob entirely
      radius: 0
    on_value:
      then:
        - lvgl.label.update:
            id: wh_servo_slide
            text: !lambda |-
              char buf[32];
              sprintf(buf, "Servo: %.0f%%", x * 10 );
              return std::string(buf);
        - homeassistant.action:
            action: number.set_value
            data:
              entity_id: number.woodheat_1_heater_servo
              value: !lambda return x * 10;

- label:
    text: "Servo: 50%"
    id: wh_servo_slide
    y: 0
    width: 400
    align: BOTTOM_MID
    text_align: CENTER
    text_color: WHITE
    text_font: robo_25 # override font size

This is the Sensor Code that the WaveShare's uses to pull the Heaters Servo Value from Home Assistant:-

sensor:
  - platform: homeassistant
    name: "Servo Value"
    id: fire_servo
    entity_id: number.woodheat_1_heater_servo
    internal: True
    on_value:
      then:
        - lvgl.slider.update:
            id: servo_slider
            value: !lambda 'return x /10;'

Can Anyone Point to Why the Servo Does this Dance back to its present value every time one of the WaveShare Panels is rebooted.

While It's only a Minor anomaly to Me, My Wife is going Crazy about the Heater Having a Mind of it's Own every time I'm Updating the Code on the Panel in other Rooms.

Thanks.

Use on_change or on_release instead of on_value - those trigger only on user input.

You might also want to change the template number to an LVGL number which connects the slider automatically. Set trigger: on_release. Move the label update to the number on_value trigger.

You can dispense with the sensor - in HA just update the number to control it remotely. And you should be able to eliminate the other number in HA since it appears this device is the source of truth for the servo position.

Thanks Clyde,

The First Change is Pretty Straight Forward.

Not Quite Clear in the Others. Will Read Up thouogh.

Just to Clarify What I Have.

  1. 1st Esp Device is at the Heater; Drives the Servo & Reads Thermistors.
  2. Three WaveShare ESP32 Displays to control the heater & other devices
  3. Two Elecrow Displays to do similar to the above.
  4. All Displays have same LVGL & control all devices on Different Pages

Servo Position is mostly set by an automation to control the Burn Rate.
but can be overridden in the HA Dashboard; Remotely on My Phone over a VPN,
Or from any of the LCDs.

As the Slider also displays the Current Position of the Damper,
I have assumed that the Sensor was required to make sure that all devices displayed the current position of the damper.

The "Source of Truth" could be HA (but not sure I'm correct) as it is generally what is moving the damper via the Automation.

HA also has another Input Number, which contains the Minimum allowed position of the damper,
so as to allow the fire to burn hotter when required.

Also My Servo has no feedback, so if it Don't Move HA is oblivious.

Well, you need to choose one source of truth, and I'd suggest that would be the ESP that is actually controlling the servo. If you have no position feedback, then obviously it has to just assume that it reacted to the last command, but if the network goes down for example the controlling device is the most likely one to know where it was last positioned.

Now the problem is that HA doesn't know about servos so you will need a number synced to the servo that is visible in HA (as you have done.) That number then essentially becomes the source of truth because all commands to change the servo position would go through that.

That could be a template number or an LVGL number - the latter just eliminates a bit of manual coupling, the end result is the same. Either way use on_release as the trigger to update the number.

HA can directly change the number, other nodes can read it via a sensor and use service calls to change it. Those would use an LVGL slider that is updated by the sensor, and sends service calls using on_release.

That's the broad outline of what I would do, anyway. There are many ways to skin this particular cat, but the key is making sure that changes don't cascade, and the fewer components used the easier it will be to understand and maintain.