Split data from attributes

I’m trying to split data from an attributes
from Template editor:
{{ states.sensor.engineering_feed.attributes["RouterOS 6.43.2 [Stable]"]}}

this is the output:
{'title': 'RouterOS 6.43.2 [Stable]', 'link': 'https://www.mikrotik.com/download/changelogs/stable'}

when i add the split im getting error:

{ states.sensor.engineering_feed.attributes["RouterOS 6.43.2 [Stable]"].split ('link') [0] }}

Error rendering template: UndefinedError: 'dict object' has no attribute 'split'  

why is that?

I don’t understand your “split[‘link’])” and what you expect from it ?
But the split method is on string object, if the output is as you cite, this is a structure by itself, so you’ll have to extract the attribute first to get a string.
Or you can try to cast to a string and see if you can manage from this :
> {{ (states.sensor.engineering_feed.attributes["RouterOS 6.43.2 [Stable]"] | string).split ('<separator>') [0] }}

Well, you’re pulling the information out incorrectly. If the attributes are:

{'title': 'RouterOS 6.43.2 [Stable]', 'link': 'https://www.mikrotik.com/download/changelogs/stable'}

Then all you need to do is grab the attribute via the name, title or link:


to get 'RouterOS 6.43.2 [Stable]' out of your attributes:

{{ states.sensor.engineering_feed.attributes['title'] }}

or

{{ states.sensor.engineering_feed.attributes.title }}

or

{{ state_attr('sensor.engineering_feed','title') }}

to get 'https://www.mikrotik.com/download/changelogs/stable' out:

{{ states.sensor.engineering_feed.attributes['link'] }}

or

{{ states.sensor.engineering_feed.attributes.link }}

or

{{ state_attr('sensor.engineering_feed','link') }}

That error is because you are trying to access the dictionary object and use split on it. Split is a string operation, not dictionary operation. You shouldn’t even need this based on what I wrote above.

@petro @Mister_Slowhand
Thanks for that.
But all the above you’ve suggested , return no value.

Im using this sensor, to pull out the info.

- platform: feedparser
  name: Engineering Feed
  feed_url: 'https://mikrotik.com/download.rss'
  date_format: '%a, %b %d %I:%M %p'
  inclusions:
    - description
  exclusions:
    - language 

in the template editor

what does {{ states.sensor.engineering_feed.state }} return?
what does {{ states.sensor.engineering_feed.attributes }} return?

 {{ states.sensor.engineering_feed.state }} return: 20
 {{ states.sensor.engineering_feed.state }} return:  {'RouterOS 6.43.2 [Stable]': {}, 'RouterOS 6.43.1 [Stable]': {}, 'RouterOS 6.44beta9 [Testing]': {}, 'RouterOS 6.44beta6 [Testing]': {}, 'RouterOS 6.43 [Stable]': {}, 'RouterOS 6.43rc66 [Testing]': {}, 'RouterOS 6.43rc64 [Testing]': {}, 'RouterOS 6.40.9 [Long-term]': {}, 'RouterOS 6.42.7 [Stable]': {}, 'RouterOS 6.43rc56 [Testing]': {}, 'RouterOS 6.43rc51 [Testing]': {}, 'RouterOS 6.43rc45 [Testing]': {}, 'RouterOS 6.43rc44 [Testing]': {}, 'RouterOS 6.42.6 [Stable]': {}, 'RouterOS 6.43rc42 [Testing]': {}, 'RouterOS 6.43rc40 [Testing]': {}, 'RouterOS 6.42.5 [Stable]': {}, 'RouterOS 6.43rc34 [Testing]': {}, 'RouterOS 6.43rc32 [Testing]': {}, 'RouterOS 6.42.4 [Stable]': {}, 'friendly_name': 'Engineering Feed', 'icon': 'mdi:rss'}

All those attributes are empty… what are you trying to get?

do you mean the attr’ name is RouterOS 6.43.2 and so on?

so i do i get the attr’ name to be display in the sensor instead of the state?

I’m asking you:

What information are you trying to get?

The goal is To make notification when new releases available.
Screenshot_2018-09-24-17-40-59

When there’s a new update, the state changed.(20,21,22…)
From that i can make a notification that show the new releases from that attribute…

Edited the above :point_up_2:

This is painful but this should get you the first [Stable] result:

{% set sorted_releases = states.sensor.engineering_feed.attributes.keys() | sort | reverse %}
{%- for release in sorted_releases if release | regex_match('.*\[Stable\].*') %}
  {%- if loop.first %}
    {{- release | replace('[Stable]','') }}
  {%- endif %}
{%- endfor %}

so inside a template sensor:

sensor:
  - platform: template
    sensors:
      next_router_os_release:
        value_template: >
          {% set sorted_releases = states.sensor.engineering_feed.attributes | sort | reverse %}
          {%- for release in sorted_releases if release | regex_match('.*\[Stable\].*') %}
            {%- if loop.first %}
              {{- release | replace('[Stable]','') }}
            {%- endif %}
          {%- endfor %}

Your output should be:

RouterOS 6.43.2
1 Like

Wow, it works just like I wanted.
Thank you very much .
routeros

1 Like

That’s strange that you get an empty string when you cast the answer as a string. I tried to put the output you provided as my source and I can make it work.
If the list you have is always ordered, then this would work :
states.sensor.engineering_feed.attributes| string).split('[Stable]')[0].split("'")[-1]

If it needs sorting, this should work for latest stable :

states.sensor.engineering_feed.attributes | sort(reverse=True) | string ).split('[Stable]')[0].split("'")[-1] }}

`

  1. states.sensor.engineering_feed.attributes is a dictionary. It’s not sorted.
  2. Splitting on ‘[Stable]’ may not work because what happens when the site removes everything but 1 ‘[Stable]’?

1 - The structure itself ain’t but I supposed the source ordered the items. See that the latest in each category comes first (Stable, Testing, long term…). Anyway, the sorted version should work though I don’t use sort in my configuration.

2 - What do you mean ?
This :
{'RouterOS 6.43.2 [Stable]': {} }
It will work as [Stable] gets removed, the [0] item is still what’s on the left side and there’s still the ’ to get the string.

Of course, if there is no “[Stable]” item in the list, it will fail, displaying a ] ! But I found this quite unlikely in that case.

What happens in this case:

{'RouterOS 6.44.11 [Testing]': {} ,'RouterOS 6.43.2 [Stable]': {} }

That’s my point. Your solution doesn’t cover all cases, which is why you need to search for [Stable] in the name, filter the list, and choose the highest revision. Doing a simple split in this case with your method would result in:

RouterOS 6.44.11 [Testing] RouterOS 6.43.2

I think this dict shows my case better:

{‘RouterOS 6.44.11 [Testing]’: {} ,‘RouterOS 6.43.2 [Stable]’: {} ,‘RouterOS 6.40.9 [Long-term]’: {}}

Sorted looks like:

‘RouterOS 6.40.9 [Long-term]’, ‘RouterOS 6.43.2 [Stable]’, ‘RouterOS 6.44.11 [Testing]’

resulting in this:

‘RouterOS 6.40.9 [Long-term]’, 'RouterOS 6.43.2

As long as you have at least 1 Stable version, it works. In your example I have this result. I splitted in several actions so that you see how it cuts and selects the parts.

And see why it fails when there is no “stable” entry :