I’m creating an automation to process license plate recognition via MQTT.
My template works: {{trigger.payload_json.plate | upper() | replace(" ", "")=="plate_number_here"}}
The LPR isn’t perfect, so I remove any spaces and set to upper case. However, the LPR often get’s 1 character wrong on the plate. I would like a template to return true if 6 of the 7 characters match. In python I could just do the following: sum(1 for char1 in trigger.payload_json.plate.replace(" ", "").upper() if char1 in "plate_number_here") >= 6
But, my first thought is you are removing spaces from the lpr plate. Am I missing something? Doesn’t that shift the lpr plate letters/numbers? Meaning that if the early characters come in as a space, you won’t be able to match six positions?
For example:
target plate = 1234567
lpr plate = 1b34567 (b is a space).
So, you are now comparing 1234567 to 134567. Only the first position matches.
I’m not great with python but doesn’t your python code ignore the order of the letters entirely? Additionally, what would happen in your python code if the LPR plate is AAA1111 and you are trying to match it to ABC1234? Isn’t it going to result in a match?
If you are ok with those flaws, you can use this code:
{% set ns = namespace(total=0) %}
{% for char in 'AAA1111' %}
{% set ns.total = ns.total + ( 1 if char in 'ABC1234') %}
{% endfor %}
{{ ns.total >=6 }}
If you’re looking for some other logic (or your python code already does something better) then if you could explain what it’s doing I’m sure we could come up with something.
@mekaneck You’re right about the bug. It should be: sum(1 for char1, char2 in zip(plate.replace(" ", "").upper(), TARGET) if char1 == char2) >= 6
Here are the results to match 7ABC123:
The order does matter. Here’s the Jinga2 code I came up with although I have not tested it yet in HA:
{% set target_cleaned = TARGET_PLATE_HERE.upper() %}
{% set plate_cleaned = trigger.payload_json.plate.replace(" ", "").upper() %}
{% set matched_chars = [] %}
{% for i in range(plate_cleaned|length) %}
{% if plate_cleaned[i] == target_cleaned[i] %}
{% set _ = matched_chars.append(1) %}
{% endif %}
{% endfor %}
{{ matched_chars|length >= 6 }}
@jeffcrum The plates I’m matching should not have any spaces. Sometimes CPAI adds non-existent spaces. I have seen CPAI return 7ABC 123 instead of 7ABC123. If CPAI replaced a letter with a space then you are correct that it would cause a problem as shown above. I’ll cross that bridge if I see it. I suppose I could only remove the spaces if the length is greater than 7.