Ultrasonic Sensor (HC-SR04) change update interval via Home Assistant?

I have the following setup:

ESP32 (C3) with an HC-SR04 Ultrasonic Sensor attached to PIN 10 (Trigger) and PIN 1 (Echo) as well as VCC and GND connected.

The code in ESPHome:

sensor:
  - platform: ultrasonic
    trigger_pin: 10
    echo_pin: 1
    name: "Ultrasonic Sensor"
    update_interval: 0.1s

Now my problem is that the ESP is constantly calculating the distance and sending signals even though it is not necessary every 0.1s to Home Assistant.

What I would like is that the Ultrasonic Sensor is not updating (or has an extreme long interval > 60min) and I am able to change the interval numerically (ideally) or alternate between a long and short interval via Home Assistant.

I have problems putting the right syntax together based on my code snippets. I managed to create a template sensor in ESP Home that shows up in Home Assistant:

button:
  - platform: template
    name: Switch Interval
    id: interval_switch
    on_press:
      - logger.log: "Button pressed"

Ideally I could now set the interval numerically in Home Assistant or at least define two intervals that I can switch when the button is pressed in HA:

update_interval_fast: 0.1s
update_interval_slow: 60s # or longer / off if possible?

How would that look like? I think it should be somehow solvable with lambda but I am no expert in the syntax. I also looked into working with “delta” but it does not really achieve what I am looking for.

Ok one variant that works is to create an input_boolean toggle in Home assistant:

And link it to a binary sensor in the ESP Home yaml:

sensor:
  - platform: ultrasonic
    trigger_pin: 10
    echo_pin: 1
    name: "Ultrasonic Sensor"
    id: ultrasonic_sensor
    update_interval: 60s

binary_sensor: 
  - platform: homeassistant
    id: high_speed_update
    entity_id: input_boolean.high_speed_update
    on_state:
      - lambda: !lambda |-
          // revert back to the default update interval
          static uint32_t default_update_interval = id(ultrasonic_sensor).get_update_interval();
          // 100 = 100 ms = New "high speed" interval
          int update_interval = x ? 100 : default_update_interval;
          id(ultrasonic_sensor).set_update_interval(update_interval);
          id(ultrasonic_sensor).call_setup();

When the HA toggle is on the ultrasonic sensor updates every 100ms and when it is off only every 60s.

If there is an even more elegant way I would be happy about further suggestions. I try to work with this for now and see if there are any unintended consequences (maybe because of the call_setup()).

1 Like

in the update_interval you can set the time you want for it to update but you can only set it on seconds or milliseconds. example 300s = 5 minutes. use google to calculate the seconds in minutes.

Where are you coming up with this bad information? You arent limited to milliseconds and seconds. You can absolutely do minutes.

The setting vary from different platform and as i can see you are not using the ultrasonic platform. I have tried minutes in this platform and doesnt work.

oh, you have? lol. Why do you have to lie man? That’s complete BS and I know and you know it. Now since you can’t test something yourself and you’re going to sit here and lie then i’m gonna test it just for you sweet cheeks!

Here you go sweet pea! Next time don’t be lazy and do your own testing if you don’t want to embarrass yourself. All you had to do was put a sensor in a config and check it but, that was too difficult so you rather lie about it… shame shame


here’s another one cupcake. I did hours for you this time.


applaud your ridiculous attitude. Nobody asked you for opinion/test/check/fix anything. it works for you, amen. if it doesn’t work for me its none of your business, I didn’t asked you. Take your ridiculous attitude somewhere else crybaby.

Well, don’t make crap up or outright lie about stuff. Have a little integrity.

How about using a long update interval, and defining a button to update the sensor on demand?

Then, you could create an Automation in Home Assistant to call the esphome button press at any frequency you want. No lambda required…

sensor:
# Define HC-SR04 Ultrasonic sensor
  - platform: ultrasonic
    trigger_pin: GPIO32
    echo_pin: GPIO35
    name: "Distance"
    id: distance
    update_interval: 600s
    filters:
      - filter_out: nan
 
button:
  # Initiate a distance sensor read
  - platform: template
    name: Measure Distance
    on_press:
      - component.update: distance

In my case (desk hight control) I need a mechanism I can active which updates the sensor every 100ms until a condition is met (desk hight reached).

This way I solved it now and it is running successfully in production:

# Control Desk UP/DOWN movement
# ...
api:
  #...
  services:
    # home assistant service call to change desk height
    - service: change_desk_hight
      variables:
        set_desk_hight: int
      then:
        if:
          condition:
            - script.is_running: script_change_desk_height
          then:
            - logger.log: Script is still running!
          else:
            - logger.log: Service called!
            - lambda: |-
                id(gvar_set_desk_hight) = set_desk_hight;
            - script.execute: script_change_desk_height
    # home assistant service call to interrupt desk movement
    - service: killswitch
      then:
        - if:
            condition:
              - script.is_running: script_change_desk_height
            then:
              # stop script: "script_change_desk_height"
              - script.stop: script_change_desk_height
              - switch.turn_off: switch_up
              - switch.turn_off: switch_down
              # reset ultrasonic sensor update interval to: 60s
              - lambda: |-
                  id(ultrasonic_sensor).set_update_interval(60000);
                  id(ultrasonic_sensor).call_setup();
              - logger.log: "KILLSWITCH EXEC"

globals:
  # to use specifically in lambdas
  - id: gvar_update_interval_high
    type: int
    restore_value: no
    initial_value: '100' # 100ms
  - id: gvar_update_interval_low
    type: int
    restore_value: no
    initial_value: '60000' # 60s
  - id: gvar_set_desk_hight
    type: int
    restore_value: no
    initial_value: '80' 

script:
  # change the desk height to given input number from home assistant
  # desk limits: 63 - 111 cm
  - id: script_change_desk_height
    then:
      # set ultrasonic sensor update interval to: 100ms
      - lambda: |-
          id(ultrasonic_sensor).set_update_interval(100);
          id(ultrasonic_sensor).call_setup();
      - if:
          condition:
            # if current hight > set hight
            lambda: 'return (id(ultrasonic_sensor).state*100) > id(gvar_set_desk_hight);'
          then:
            - logger.log: "Current desk height is bigger than target!"
            # -> Lower Desk:
            - while:
                condition:
                  and:
                    lambda: 'return ((id(ultrasonic_sensor).state*100)-3) > id(gvar_set_desk_hight);'
                then:
                - logger.log: "Executing: LOWERING"
                - switch.turn_on: switch_down
                - delay: 100ms
          else:
            # if current hight < set hight
            # -> Raise Desk:
            - logger.log: "Current desk height is lower than target!"
            - while:
                condition:
                  and:
                    - lambda: 'return ((id(ultrasonic_sensor).state*100)+2) < id(gvar_set_desk_hight);'
                    # stop for values > max desk hight
                    - lambda: 'return (id(ultrasonic_sensor).state*100) < 117;'
                then:
                - logger.log: "Executing: RAISE"
                - switch.turn_on: switch_up
                - delay: 100ms
      - switch.turn_off: switch_up
      - switch.turn_off: switch_down
      # set ultrasonic sensor update interval to: 60s
      - lambda: |-
          id(ultrasonic_sensor).set_update_interval(60000);
          id(ultrasonic_sensor).call_setup();
      - logger.log: "DONE EXEC"

sensor:
  - platform: ultrasonic
    trigger_pin: 10
    echo_pin: 1
    name: "Ultrasonic Sensor"
    id: ultrasonic_sensor
    update_interval: 60s
    filters:
      # account for added desk top thickness and sensor module
      - offset: 0.07    

switch:
  - platform: gpio
    pin:
      number: 5
    id: switch_down
    name: "Desk - DOWN"
    icon: "mdi:arrow-expand-down"
  - platform: gpio
    pin:
      number: 6
    id: switch_up
    name: "Desk - UP"
    icon: "mdi:arrow-expand-up"
1 Like

I think you could alternatively do it without lambdas using the component resume action if you like.

That may avoid call setup (although I don’t know what’s happening under the hood).

You could also just have it at 0.1ms all the time and add a delta filter so you don’t spam HA when the value isn’t changing. But Maybe that is excessive and avoidable ongoing load on the sensor (not sure).

Adding a distance delta filter probably isn’t a bad idea either way (only send changes of more than say 1cm to HA, while internally you can use the raw data for your calcs).

1 Like

This answer is the bomb! I did not know about suspend and resume components and this saved me a buttload of trouble.

1 Like