Count substring occurences inside a string returned from sensor

Hi all,
I have to resort to your valuable time to ask for help in this situation:

what I have

a sensor from an integration https://github.com/zulufoxtrot/ha-zyxel that returns a string value


{{ states('sensor.zyxel_cellular_intf_current_band') }}

B7,B1,B3,B20,n78

Result type: string

what I wish for

a way to count how many times the different strings related to cell bands appears over time, I tought to build an automation that every time the state changes it increment a counter (one per band) but I cannot figure how to do it since the string returned from the sensor in different every time and not all the cells are present. (es. the next value/state could be ‘B3, B1, n78’)

So I think I need a way to iterate the possible values (which i know) comparing them to the values in the string and in the meantime update the related counter…but how??

Any ideas?

Thank you!

So something like this?

template:
  - sensor:
      - name: B7 Count
        state: >
          {% if this is defined %}
            {% if 'B7' in states('sensor.zyxel_cellular_intf_current_band') %}
              {{ this.state|int + 1 }}
            {% else %}
              {{ this.state }}
            {% endif %}
          {% else %}
            0
          {% endif %}

      - name: B1 Count
        state: >
          {% if this is defined %}
            {% if 'B1' in states('sensor.zyxel_cellular_intf_current_band') %}
              {{ this.state|int + 1 }}
            {% else %}
              {{ this.state }}
            {% endif %}
          {% else %}
            0
          {% endif %}

      - name:  etc...
1 Like

Would it not be possible to make this “dynamic” using the attributes?
Or is there something I’m missing?

Don’t use attributes for values that change.

Thank you @tom_l for the hint! It’s almost working, I say almost because when the main sensor state changes the count get incremented by 2:

after state changed like this

how could it be?!

Do you mean this literally? Are attributes supposed to be de facto immutable descriptors of an entity?

another case in which you could see that some template sensor get incremented by 2 and others never get incremented

Share your config.

Yes.

that’s in templates.yaml

  - name: "B7 Count"
    unique_id: "B7_count"
    state: >
      {% if this is defined %}
        {% if 'B7' in states('sensor.zyxel_cellular_intf_current_band') %}
          {{ this.state|int(0) + 1 }}
        {% else %}
          {{ this.state|int(0) }}
        {% endif %}
      {% else %}
        0
      {% endif %}
  - name: "B1 Count"
    unique_id: "B1_count"
    state: >
      {% if this is defined %}
        {% if 'B1' in states('sensor.zyxel_cellular_intf_current_band') %}
          {{ this.state|int(0) + 1 }}
        {% else %}
          {{ this.state|int(0) }}
        {% endif %}
      {% else %}
        0
      {% endif %}
  - name: "B3 Count"
    unique_id: "B3_count"
    state: >
      {% if this is defined %}
        {% if 'B3' in states('sensor.zyxel_cellular_intf_current_band') %}
          {{ this.state|int(0) + 1 }}
        {% else %}
          {{ this.state|int(0) }}
        {% endif %}
      {% else %}
        0
      {% endif %}
  - name: "B20 Count"
    unique_id: "B20_count"
    state: >
      {% if this is defined %}
        {% if 'B20' in states('sensor.zyxel_cellular_intf_current_band') %}
          {{ this.state|int(0) + 1 }}
        {% else %}
          {{ this.state|int(0) }}
        {% endif %}
      {% else %}
        0
      {% endif %}
  - name: "n78 Count"
    unique_id: "n78_count"
    state: >
      {% if this is defined %}
        {% if 'n78' in states('sensor.zyxel_cellular_intf_current_band') %}
          {{ this.state|int(0) + 1 }}
        {% else %}
          {{ this.state|int(0) }}
        {% endif %}
      {% else %}
        0
      {% endif %}

that’s my System Information

System Information

version core-2025.9.1
installation_type Home Assistant OS
dev false
hassio true
docker true
container_arch armv7
user root
virtualenv false
python_version 3.13.7
os_name Linux
os_version 6.12.34-haos-raspi
arch armv7l
timezone Europe/Rome
config_dir /config
Home Assistant Community Store
GitHub API ok
GitHub Content ok
GitHub Web ok
HACS Data ok
GitHub API Calls Remaining 5000
Installed Version 2.0.5
Stage running
Available Repositories 2189
Downloaded Repositories 14
Solcast Solar
can_reach_server ok
Home Assistant Cloud
logged_in false
can_reach_cert_server ok
can_reach_cloud_auth ok
can_reach_cloud ok
Home Assistant Supervisor
host_os Home Assistant OS 16.2
update_channel stable
supervisor_version supervisor-2025.09.0
agent_version 1.7.2
docker_version 28.3.3
disk_total 57.8 GB
disk_used 4.5 GB
nameservers 192.168.1.54
healthy true
supported true
host_connectivity true
supervisor_connectivity true
ntp_synchronized true
virtualization
board rpi3
supervisor_api ok
version_api ok
installed_addons File editor (5.8.0), Advanced SSH & Web Terminal (21.0.3), SQLite Web (4.4.0)
Dashboards
dashboards 5
resources 4
views 6
mode storage
Recorder
oldest_recorder_run August 27, 2025 at 06:17
current_recorder_run September 10, 2025 at 09:25
estimated_db_size 543.46 MiB
database_engine sqlite
database_version 3.48.0

what other parts of the configuration do you need ?

You don’t need the filter here:

But it would not cause the issue and I have no idea how it is possible to increment by 2 given your config.

:man_shrugging:

Let me “phone a friend” and I’ll get back to you (or they will).

1 Like

Actually, what is the state of your sensor here (hover your mouse to see):

I can confirm something is wrong.

I was so interested in how or why that would happen that I added it to my config with an input text and it does double count.

template:
  - sensor:
    - name: "B7 Count"
      unique_id: "B7_count"
      state: >
        {% if this is defined %}
          {% if 'B7' in states('input_text.zyxel') %}
            {{ this.state|int(0) + 1 }}
          {% else %}
            {{ this.state|int(0) }}
          {% endif %}
        {% else %}
          0
        {% endif %}
    - name: "B1 Count"
      unique_id: "B1_count"
      state: >
        {% if this is defined %}
          {% if 'B1' in states('input_text.zyxel') %}
            {{ this.state|int(0) + 1 }}
          {% else %}
            {{ this.state|int(0) }}
          {% endif %}
        {% else %}
          0
        {% endif %}                

color changed because I did a new query but the data it’s the same:

hope this’ll help

it’s also stranger (to me) that some sensors never get incremented…

I think I understand why that is.
As far as my limited testing has shown if the state changes from
B3,B20,n78,B7 to B3,B20,n78,B7,B1 then it will not count up any of the values in the first set, only B1.
It seems it has to not be there, then be there for it to count. Which kind of makes sense.
Not sure if that is what you want but I believe that is the case

Nope, any change of the sensor state will re-evaluate the templates.

that explains why some sensors didn’t get incremented at every state change.

Since I need to have a “statistical” representation of the most used bands over time, I don’t know how to consider the fact that some band will increment a lot just because they are swapped frequently (not because they are less used) and some will have lower numbers (because they are stable but also because they could be less used).

Still cannot grasp why the double increment at the same state change…

No, it really doesn’t.

yes, I read your reply to @Hellis81 just after I clicked Reply on his post :sweat_smile:

So this here should count B7 four times (or 8) right?

But in reality:

So it only counted it once (or 2 times) the other counts are from 32 minutes ago and is not the same session.

I agree that it should work the way you want it to, but it doesn’t