Ultrasonic sensor pin is used twice error after upgrading to 2023.12.0

I have an ultrasonic sensor monitoring my watersoftener salt level hooked up to an ESP8266 with ESPHome. Has been working fine for a few years, but on updating to 2023.12.0 I am getting a compile error:

sensor.ultrasonic: [source <unicode string>:61]
  
  Pin 5 is used in multiple places.
  platform: ultrasonic
  trigger_pin: 
    number: 5
    mode: 
      output: True
      input: False
      open_drain: False
      pullup: False
      pulldown: False
      analog: False
    inverted: False
  echo_pin: 
    number: 4
    mode: 
      input: True
      output: False
      open_drain: False
      pullup: False
      pulldown: False
      analog: False
    inverted: False
  name: Salt level in percent
  update_interval: 5s
  filters: 
    - lambda: !lambda |-
        return (0.42-x)*(100/0.42);
  unit_of_measurement: %
  disabled_by_default: False
  force_update: False
  icon: mdi:arrow-expand-vertical
  accuracy_decimals: 2
  state_class: measurement
  timeout: 2.0
  pulse_time: 10us
sensor.ultrasonic: [source <unicode string>:73]
  
  Pin 5 is used in multiple places.
  platform: ultrasonic
  trigger_pin: 
    number: 5
    mode: 
      output: True
      input: False
      open_drain: False
      pullup: False
      pulldown: False
      analog: False
    inverted: False
  echo_pin: 
    number: 4
    mode: 
      input: True
      output: False
      open_drain: False
      pullup: False
      pulldown: False
      analog: False
    inverted: False
  name: Salt level in cm
  update_interval: 5s
  filters: 
    - lambda: !lambda |-
        return (0.42-x)*100;
  unit_of_measurement: cm
  disabled_by_default: False
  force_update: False
  icon: mdi:arrow-expand-vertical
  accuracy_decimals: 2
  state_class: measurement
  timeout: 2.0
  pulse_time: 10us
Pin 4 is used in multiple places

Pin 4 is used in multiple places

I am presuming that this is because I use the same pins to give me HA sensors reporting in both cm and %:

sensor:
  - platform: ultrasonic
    trigger_pin: D1
    echo_pin: D2
    name: "Salt level in percent"
    update_interval: 5s
    filters:
    # Calculates in %
    # Replace 0.42 by the height of your container. From the sensor to the bottom.
    # I used this website to know how I should multiply my values :https://www.skillsyouneed.com/num/percent-change.html 
    - lambda: return (0.42-x)*(100/0.42);
    unit_of_measurement: "%"
    
  - platform: ultrasonic
    trigger_pin: D1
    echo_pin: D2
    name: "Salt level in cm"
    update_interval: 5s
    filters:
    # Replace the 0.42 by the height of your container. From the sensor to the bottom.
    # I multiplied by 100 in order to get CM since the sensor works in meters
    - lambda: return (0.42-x)*100;
    unit_of_measurement: "cm"

Is there any way in the new version that I can keep the sensor logic on the device itself, or do I need to remove the translation to % and cm to my HA config?

I have the same code and error. Been looking at options all morning and nothing comes to mind with how I would return different values with the same pins for the sensor.

Create a template sensor for the cm sensor. See Template Sensor — ESPHome

I know I’m on the right lines here, but am struggling to figure out how to use the value from one sensor to calculate the correct value in the template sensor. I’m probably being stupid…

  - platform: ultrasonic
    trigger_pin: D1
    echo_pin: D2
    name: "Salt level"
    id: level
    update_interval: 5s

  - platform: template
    name: "Salt level in %"
    update_interval: 5s
    filters:
    - lambda: return (0.42-id(level).state)*(100/0.42);
    unit_of_measurement: "%"
    
  - platform: template
    name: "Salt level in cm"
    update_interval: 5s
    filters:
    - lambda: return (0.42-id(level).state)*100;
    unit_of_measurement: "cm"

sensor.salt_level returns correctly, but no values for the other two. I’ve tried id(level).value but throws an error on compiling. How do I call the value of the first sensor in the lambda of the other two?

remove the filters: statement and adjust the lambda.

2 Likes

Perfect - I knew it was something simple!

Many thanks.

You are correct…

This was a breaking change with 2023.12.0. See Pin Reuse Validation

I fixed my code by adding the ‘allow_other_uses: true’ statement. My code now reads in part;

  - platform: ultrasonic
    trigger_pin:
      number: GPIO5
      allow_other_uses: true
    echo_pin:
      number: GPIO4
      allow_other_uses: true
    name: "Saltlevel in percent"
    update_interval: 24h
    filters:

    ### Calculate level in percent ###
    # Sensor comes from factory with unit of measurement set in meters
    # Storage tank height (sensor to bottom of tank) = 84.7cm, 0.847m
    # Subtract measured value from the storage tank height => difference is the salt level = 84.7cm - 44.7cm = 40cm, .847m - .447m = .400
    # 100 % salt level is the container height minus 0.400 meters since nobody will drawn the sensor at full salt level
    # divide salt level through container height minus 0.4000, then multiply result with 100 to achieve percents
    - lambda: return (0.847-x) * (100/0.847);
    unit_of_measurement: "%"
    
  - platform: ultrasonic
    trigger_pin:
      number: GPIO5
      allow_other_uses: true
    echo_pin:
      number: GPIO4
      allow_other_uses: true
    name: "Saltlevel in cm"
    update_interval: 24h
    filters:
    # Container height 52.75cm. From the sensor to the top of the water that accumulates in the bin.
    # Multiply result by 100 - convert M to CM. Sensor works in meters
    - lambda: return (0.847-x)*100.0;
    unit_of_measurement: "cm"

That being said, I like the solution presented by @jsuanet better. Time for a change!

Thank you, it solved my problem also (water level ultrasonic).