JSN-SR04T-2.0 timed out -> reading 21474836.00000 cm!?

With this part of the ESPHome .yaml code loaded into an ESP32-WROOM-32 for a JSN-SR04T-2.0 sensor (default settings / no resistor soldered into R27):

sensor:
  - platform: ultrasonic
    trigger_pin: GPIO5  # D5
    echo_pin: GPIO18    # D18
    name: "JSN-SR04T Distance"
    update_interval: 5s
    unit_of_measurement: "cm"
    accuracy_decimals: 1
    timeout: 2.0m
    filters:
      - lambda: |-
          if (x < 0.1 || x > 4.5) {
            return NAN;                           // Return NAN for out-of-range values
          }
          float value_in_cm = x * 100;   // Convert meters to cm  height above floor 
          return int(value_in_cm * 100 + 0.5) / 100.0;  // Round to 2 decimal places

I’m wondering why I periodically see readings like this:

[21:40:45.775][D][ultrasonic.sensor:035]: 'JSN-SR04T Distance' - Distance measurement timed out!
[21:40:45.831][D][sensor:135]: 'JSN-SR04T Distance': Sending state 21474836.00000 cm with 1 decimals of accuracy

… and how to prevent them. I’m just getting started with ESPHome, but what is a return value of NAN actually supposed to accomplish when the reading is out of range?

It looks like the timeout products invalid value (either nan or infinite) that doesn’t get filtered out with your lambda.
Try something like this:
(not tested, if it doesn’t compile, comment out both filter_out: nan lines)

sensor:
  - platform: ultrasonic
    trigger_pin: GPIO5  # D5
    echo_pin: GPIO18    # D18
    name: "JSN-SR04T Distance"
    update_interval: 5s
    unit_of_measurement: "cm"
    accuracy_decimals: 1
    timeout: 2.0m
    filters:
      - filter_out: nan
      - lambda: |-
          if (!isfinite(x)) return NAN;
          if (x < 0.22 || x > 4.5) return NAN;
          return x * 100.0;

      - filter_out: nan # to filter out nans fron lamda

But why you have such a small timeout value? 4.5m would be better to prevent timeouts in the first place.
Also, consider adding median filter (as last filter) to get rid of any outliers or spikes.

- median:
    window_size: 5
    send_every: 1
    send_first_at: 1

Karosm, thank you for your suggestions! I did find that I had to revise the first line of the lambda filter to:
if (!infinity) return NAN;

To answer your question - no good reason for the listed syntax, other than it was based on the first coding I found that would validate, compile and install! Everything else I’d tried beforehand had failed.

This sensor is watching the level in the basement sump hole, and when it rains, the level can rise rather quickly. Not sure if a long or short timeout is better in this particular application.

Code validated, compiled, downloaded! Currently watching the trend …

Next step - configuring SMS messaging to alert me of a high level.

Unit of timeout is meters. So if your intention is to measure distance up to 4.5m, at least that you should put there…

Having a ‘timeout’ parameter specified in meters seems odd to me. Especially when info about the timeout parameter on this webpage:

suggests that it’s a measure of time. The examples show units as ‘s’ and ‘min’.

But trying ‘min’ units as per the webpage fails. That supports of your comment - especially given the error message:

  Expected distance with unit, got 2min.
  timeout: 2min

How do we get the Sensors webpage fixed?

Sensors have timeout filter.
Yours is not under filters, but parameter for ultrasonic sensor.
" timeout (Optional, float): The number of meters for the timeout. Most sensors can only sense up to 2 meters. Defaults to 2 meters."

Thanks for the clarification. Searching the esphome website on a smartphone, I never would have found this webpage:

After seeing fairly good readings from the JSN SR04T v2.0 sensor in the sump hole for about a week:

The last couple days have been really wonky:

Just wondering if anyone else has experience with these kinds of readings and how they resolved the erratic issue. The sensor is mounted in a 2" cap on the end of a 2" ABS pipe drilled with holes to allow for water in/out flow and air movement. Checked the sensor head - no condensation / deposits. Wondering if the cold temperatures or humidity in the cold cellar may be affecting the sensor or DuPont connections …

ESPHome code:

esphome:
  name: esphome-01
  friendly_name: ESPHome-01
  min_version: 2025.11.0
  name_add_mac_suffix: false

esp32:
  board: esp32dev
  framework:
    type: esp-idf

# Example configuration entry

sensor:
  - platform: ultrasonic
    trigger_pin: GPIO5  # D5
    echo_pin: GPIO18    # D18
    name: "JSN-SR04T Distance"
    update_interval: 5s
    unit_of_measurement: "cm"
    accuracy_decimals: 1
    timeout: 1.0m
    filters:
      - filter_out: nan
      - round: 3
      - lambda: |-
          if (!infinity) return NAN;
          if (x < 0.25 || x > 4.5) return NAN; // Return NAN for out-of-range values
          return x * -100 +33;                     // Convert meters to -cm and compensate

      - filter_out: nan  # to filter out nan from lambda
      - median:          # to get rid of outliers and spikes (see Forum)
          window_size: 5
          send_every: 1
          send_first_at: 1

# Enable logging
logger:

# Enable Home Assistant API
api:
  port: 6053
  batch_delay: 50ms  # Reduce latency for real-time applications
  listen_backlog: 2  # Allow 2 pending connections in queue
  max_connections: 6  # Allow up to 6 simultaneous connections
  max_send_queue: 10  # Maximum queued messages per connection before disconnect
  encryption:
    key: "+++"
  reboot_timeout: 30min

# Allow Over-The-Air updates
ota:
- platform: esphome

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

It’s weird that the median filter didn’t filter out those spikes, maybe you should “zoom in” to see why. Also, those smaller spikes all arrive to your normal max line at around -25cm. Doesn’t look like random outliers…

Drilled into the 10-11am timeframe, downloaded the data and homed in on this part of the trend:

It appears the system stores the data with a GMT timestamp.

So they are so consistent that they take over median filter. Interestingly the raw measured distance for your spikes is pretty close to half of the normal one. 0.3m vs 0.6m.