Force template sensor to retain value?

I’m making use of the SSOCR integration to use an esp32 cam to read digits from a water meter.

I’ve managed to get a test setup so that i can read a test seven-segment display which the SSOCR integration converts via the image processing and correctly displays the output.

The problem i have is that the reading of the meter will take place pretty much in total darkness, so the plan would be to periodically trigger the on-board LED so that i can grab a clear picture (Can’t leave the LED permanently lit as it gets very hot, will likely burn out, and is just a waste of energy) every 30-60 seconds or so.

With all that being said, the problem i’m facing is when the camera can’t read the display (when in darkness) the image processing just reports a “-”. I’ve created a template sensor to try and store this value but this also updates with “-” when image processing entity doesn’t have a value. What am i doing wrong? / Is it possible for this to only update when seeing a number?

Template sensor:

  - platform: template
    sensors:
      water_meter:
        value_template: "{{ states('image_processing.sevensegment_ocr_water_meter_camera') }}"
        friendly_name: "water_meter"

A picture might explain better.
With LED light on:

With LED light off:

I would like for “water_meter” to retain ‘1234’ as the previously stored value.

What might make things easier is that the value of this will only ever be a number or a “-” when it can’t see a number.

Something like this may work:

  - platform: template
    sensors:
      water_meter:
        value_template: "{{ states('image_processing.sevensegment_ocr_water_meter_camera') if not is_state('image_processing.sevensegment_ocr_water_meter_camera','-') else states('sensor.water_meter'}}"
        friendly_name: "water_meter"

That should make it use the last known value when it returns “-”

FYI the template is missing a closing parenthesis at the very end.

states('sensor.water_meter' }}"
                           ^
                           |

FWIW, here’s a way to reduce that template.

You can set a custom default for the int filter in the event it cannot convert a value to an integer. That’s handy for this application.

  • If the image-processed result is a number, not a hyphen, then int will successfully convert it to an integer value.
  • If it is a hyphen, int cannot convert it and will use whatever is defined to be the custom default value. In this case, the default is the water_meter sensor’s existing value.
  - platform: template
    sensors:
      water_meter:
        value_template: >
          {{ states('image_processing.sevensegment_ocr_water_meter_camera')
              | int(states('sensor.water_meter') }}
        friendly_name: Water Meter

@Dazman1
The technique Steven_Rollason has suggested is required because a Template Sensor cannot “retain a value” like you requested. It always computes a value by evaluating its template.

You should ensure that after you create the suggested Template Sensor the initial value of image_processing.sevensegment_ocr_water_meter_camera is not a hyphen. Otherwise the template will return unknown.

That’s looking promising! It’s retained the value when image processing can no longer get a picture. I’ll try with some new numbers and make sure it updates correctly.

Oh btw, there’s a missing close bracket right at the end, just in case anyone copies the example :slight_smile:

No, as explained, a Template Sensor cannot store/retain values. It always computes a value by evaluating its template.

The suggested technique supplies the sensor’s previous value in the event the image-processing sensor is reporting a non-integer value (a hyphen). That’s not the same as storing a value and, as explained there’s an opportunity for it to report unknown. For example, it can happen on startup if the image-processing sensor is unavailable or its value is a hyphen.

Thanks for your detailed explanation :slight_smile: i did see the “unknown” value when it was starting up so that’s good to know.

If you ever find that it reports unknown more often that you like (perhaps it will happen on every startup) another technique would be to create an automation with a State Trigger that monitors the image-processing sensor. When the value changes, the automation’s action would use it to update a counter entity (or an input_number or even an input_text) but only if the value is not a hyphen. If it is a hyphen, the counter’s value is left unchanged. A counter’s value is stored by Home Assistant (and input_number and input_text).

Another option, if you have MQTT configured, is:

  • Create an an automation which, if the sensor value is an integer, publishes it to an MQTT topic using the mqtt.publish service with the retain option set.
  • Create an MQTT sensor which subscribes to that topic

Since the message on the topic is retained by the broker, even when Home Assistant restarts it should get the latest value.