šŸ“° Lovelace: RSS Feed Parser Plugin/List Card

Hi I got this setup and working well, Iā€™m using it for a news feed, which updates every few minsā€¦ How can I get the rss feed (and card on the frontend) to update every 5 mins? is that at all possible?
Thanks

Any ideas why the card doesnā€™t pick up the entries from the sensor?

sensors.yaml

  • platform: feedparser
    name: rss Feed
    feed_url: ā€˜http://expressen.se/rss/nyheterā€™
    date_format: ā€˜%a, %b %d %I:%M %pā€™
    inclusions:
    exclusions:

Example of sensor content:
entries:

card:
type: ā€˜custom:list-cardā€™
entity: sensor.rss_feed
title: Engineering Feed
feed_attribute: entries
columns:

  • title: ā€˜ā€™
    type: image
    add_link: link
    field: image
  • title: Title
    field: title
    style: null
  • white-space: nowrap
  • title: Description
    field: description

Result:

I have an issue with this solution out of a sudden after upgrading to 2021.6.3 now.

Have not changed anything to the configuration or ui-lovelace files, also the sensor for the RSS feed is working and showing all the fields within the attributes (names unchanged as well). The list card is displayed (so also installed), title displayed but no feeds. Also tried with other sensors, but same result.

Any clue or anybody with the same issue?

@gunny I am having the same issue. I tried upgrading to 2021.6.5 and still see the same issue

I reviewed the developer tools - engineering feed entity and could see that I was no longer getting any ā€˜descriptionsā€™. I since removed the following lines from the ā€˜custom:list-cardā€™ and now I get the images and titles successfully.

Remove
style: null
white-space: nowrap
title: Description
field: description

1 Like

Thanks for your reply. I looked thru the list-card.js but have not found the lines you are mentioning. Can you give me a hint how to perform your fix?

Thx again!

What I am doing is a workaround to just get the images and titles as the descriptions seem to be missing from the attributes for the engineering feed. What I simply did was edit the card in my lovelace view to remove the descriptions.

Previous Card - No longer working
- type: custom:list-card
entity: sensor.engineering_feed
title: Engineering Feed
feed_attribute: entries
columns:
- title: ā€˜ā€™
type: image
add_link: link
field: image
- title: Title
field: title
style:
- white-space: nowrap
- title: Description
field: description

Changed To
- type: custom:list-card
entity: sensor.engineering_feed
title: Engineering Feed
feed_attribute: entries
columns:
- title: ā€˜ā€™
type: image
add_link: link
field: image
- title: Title
field: title

I hope the above helps to at least give you some information. But I guess this still needs to be fixed so we can get the description information back.

Thanks again. I have removed all style attributes and reduced the confi to itā€˜s bare minimum but still no result. I hope this gets fixed soon.

Thx for the support anyway.

Hello, Iā€™m new to HA, but have installed a few cards from HACS. list-card dosenā€™t pull up for me, so I tried the lovelace guide of installing it manually and still no dice. Does anyone have a tip on how to get list-card installed?

btw Feedparser is installed and working according to developer tools.

Thank you!

1 Like

Would like to know that as well!

Click the 3 dots menu in the top right corner of HACS, select custom repositories, add the github address for the list card and select ā€˜frontendā€™ as the category.

1 Like

Hi,

I canā€™t get the images to show anymore. Any ideas what is wrong:

Here is my config.yaml part:

- platform: feedparser
  name: Engineering Feed
  feed_url: 'https://www.is.fi/rss/tuoreimmat.xml'
  inclusions:

Here is my lovelace.ui part that i want to get to work:

type: custom:list-card
entity: sensor.engineering_feed
title: ''
feed_attribute: entries
row_limit: 6
columns:
  - field: image
    title: ' '
    type: image
    add_link: link
  - title: ' '
    field: title
    add_link: link

And this is how i can get it to work without images:

type: custom:list-card
entity: sensor.engineering_feed
title: ''
feed_attribute: entries
row_limit: 6
columns:
  - title: 'Uutisotsikko '
    field: title
    add_link: link
    

Any ideas how to get the pics vissible again? it used to work earlier this yearā€¦

Iā€™m getting an error (again) and no sensors are created/filled:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/dateutil/parser/_parser.py", line 655, in parse
    ret = self._build_naive(res, default)
  File "/usr/local/lib/python3.9/site-packages/dateutil/parser/_parser.py", line 1241, in _build_naive
    naive = default.replace(**repl)
ValueError: second must be in 0..59

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 431, in _async_add_entity
    await entity.async_device_update(warning=False)
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 633, in async_device_update
    await task
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/feedparser/sensor.py", line 110, in update
    value = parser.parse(value)
  File "/usr/local/lib/python3.9/site-packages/dateutil/parser/_parser.py", line 1374, in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/dateutil/parser/_parser.py", line 657, in parse
    six.raise_from(ParserError(e.args[0] + ": %s", timestr), e)
  File "<string>", line 3, in raise_from
dateutil.parser._parser.ParserError: second must be in 0..59: 2021-09-08T12:15:1631099700Z

Iā€™ve got the same error some days ago, then an update of feedparser arrived and it was working again for a few days. All of a sudden it stopped working :frowning:
Iā€™m on HA 2021.9.4 and feedparser 0.1.7. Any ideas?

Canā€™t get the image out of this RSS feed. What should i use to get the image (tried already with the image parameter but no luck). Titles only works perfect.

The following is the response after the feedparser.

entries:
  - title: >-
      Afgelopen week bijna 40 procent meer positieve coronatests, ook fors meer
      opnames
    title_detail:
      type: text/plain
      language: null
      base: https://www.nu.nl/rss/Algemeen
      value: >-
        Afgelopen week bijna 40 procent meer positieve coronatests, ook fors
        meer opnames
    links:
      - rel: alternate
        type: text/html
        href: >-
          https://www.nu.nl/coronavirus/6169374/afgelopen-week-bijna-40-procent-meer-positieve-coronatests-ook-fors-meer-opnames.html
      - length: '0'
        type: image/jpeg
        href: >-
          https://media.nu.nl/m/qlbxndiazeci_sqr256.jpg/afgelopen-week-bijna-40-procent-meer-positieve-coronatests-ook-fors-meer-opnames.jpg
        rel: enclosure
      - href: >-
          https://nu.nl/coronavirus/6169375/grootste-aantal-coronapatienten-opgenomen-op-verpleegafdelingen-sinds-december.html
        rel: related
        title: >-
          Grootste aantal coronapatiƫnten opgenomen op verpleegafdelingen sinds
          december
        type: text/html
      - href: >-
          https://nu.nl/coronavirus/6169359/ziekenhuizen-bieden-weer-minder-zorg-aan-door-aanhoudende-coronadrukte.html
        rel: related
        title: Ziekenhuizen bieden weer minder zorg aan door aanhoudende coronadrukte
        type: text/html
      - href: >-
          https://nu.nl/coronavirus/6169338/voor-het-eerst-in-deze-coronagolf-wordt-coronapatient-naar-duitsland-verplaatst.html
        rel: related
        title: >-
          Voor het eerst in deze coronagolf wordt coronapatiƫnt naar Duitsland
          verplaatst
        type: text/html
    link: >-
      https://www.nu.nl/coronavirus/6169374/afgelopen-week-bijna-40-procent-meer-positieve-coronatests-ook-fors-meer-opnames.html
    summary: >-
      De afgelopen week testten opnieuw een recordaantal mensen positief op het
      coronavirus. In de weekupdate meldt het RIVM 153.957 positieve tests, een
      stijging van bijna 40 procent ten opzichte van een week eerder. Ook het
      aantal ziekenhuisopnames blijkt fors te zijn gestegen.
    summary_detail:
      type: text/html
      language: null
      base: https://www.nu.nl/rss/Algemeen
      value: >-
        De afgelopen week testten opnieuw een recordaantal mensen positief op
        het coronavirus. In de weekupdate meldt het RIVM 153.957 positieve
        tests, een stijging van bijna 40 procent ten opzichte van een week
        eerder. Ook het aantal ziekenhuisopnames blijkt fors te zijn gestegen.
    published: Tue, Nov 23 03:07 PM
    id: https://www.nu.nl/-/6169374/
    guidislink: false
    tags:
      - term: Algemeen
        scheme: null
        label: null
      - term: Coronavirus
        scheme: null
        label: null
    authors:
      - name: NU.nl
    author: NU.nl
    author_detail:
      name: NU.nl
    rights: 'copyright photo: ANP'
    rights_detail:
      type: text/plain
      language: null
      base: https://www.nu.nl/rss/Algemeen
      value: 'copyright photo: ANP'
----

friendly_name: Engineering Feed
icon: mdi:rss
1 Like

I made a separate custom component to handle enclosure tagsā€¦

"""Feedparser custom sensor"""
from __future__ import annotations

import asyncio
import re
from datetime import timedelta

import homeassistant.helpers.config_validation as cv
import voluptuous as vol
from dateutil import parser
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
from homeassistant.const import CONF_NAME
import homeassistant.util.dt as dt

import feedparser
import requests

__version__ = "0.0.1"

REQUIREMENTS = ["feedparser"]

CONF_FEED_URL = "feed_url"
CONF_DATE_FORMAT = "date_format"
CONF_INCLUSIONS = "inclusions"
CONF_EXCLUSIONS = "exclusions"
CONF_SHOW_TOPN = "show_topn"
CONF_LOCAL_TIME  = 'local_time'

DEFAULT_SCAN_INTERVAL = timedelta(hours=1)

COMPONENT_REPO = "https://github.com/custom-components/sensor.feedparser/"
SCAN_INTERVAL = timedelta(hours=1)

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {
        vol.Required(CONF_NAME): cv.string,
        vol.Required(CONF_FEED_URL): cv.string,
        vol.Required(CONF_DATE_FORMAT, default="%a, %b %d %I:%M %p"): cv.string,
        vol.Optional(CONF_SHOW_TOPN, default=9999): cv.positive_int,
        vol.Optional(CONF_INCLUSIONS, default=[]): vol.All(cv.ensure_list, [cv.string]),
        vol.Optional(CONF_EXCLUSIONS, default=[]): vol.All(cv.ensure_list, [cv.string]),
        vol.Optional(CONF_LOCAL_TIME, default=False): cv.boolean,
    }
)


@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
    async_add_devices(
        [
            FeedParserCustomSensor(
                feed=config[CONF_FEED_URL],
                name=config[CONF_NAME],
                date_format=config[CONF_DATE_FORMAT],
                local_time=config[CONF_LOCAL_TIME],
                show_topn=config[CONF_SHOW_TOPN],
                inclusions=config[CONF_INCLUSIONS],
                exclusions=config[CONF_EXCLUSIONS],
            )
        ],
        True,
    )


class FeedParserCustomSensor(SensorEntity):
    def __init__(
        self,
        feed: str,
        name: str,
        date_format: str,
        show_topn: str,
        local_time: bool,
        exclusions: str,
        inclusions: str,
    ) -> None:
        self._feed = feed
        self._attr_name = name
        self._attr_icon = "mdi:rss"
        self._date_format = date_format
        self._local_time = local_time
        self._show_topn = show_topn
        self._inclusions = inclusions
        self._exclusions = exclusions
        self._attr_state = None
        self._entries = []

    def update(self):
        r = requests.get(self._feed).content
        parsed_feed = feedparser.parse(r)

        if not parsed_feed:
            return False
        else:
            self._attr_state = (
                self._show_topn
                if len(parsed_feed.entries) > self._show_topn
                else len(parsed_feed.entries)
            )
            self._entries = []

            for entry in parsed_feed.entries[: self._attr_state]:
                entry_value = {}

                for key, value in entry.items():
                    if (
                        (self._inclusions and key not in self._inclusions)
                        or ("parsed" in key)
                        or (key in self._exclusions)
                    ):
                        continue
                    if key in ["published", "updated", "created", "expired"]:
                        value = parser.parse(value)
                        if self._local_time:
                            value = dt.as_local(value)
                        value = value.strftime(self._date_format)


                    entry_value[key] = value
                    
                images = []
                if "image" in self._inclusions and "image" not in entry_value.keys():
                    if "summary" in entry.keys():
                        images = re.findall(
                            r"<img.+?src=\"(.+?)\".+?>", entry["summary"]
                        )
                    if images:
                        entry_value["image"] = images[0]
                if "enclosure" in self._inclusions and "enclosure" not in entry_value.keys():
                    if entry.enclosures:
                        images.append(str(entry.enclosures[0].href))
                    if images:
                        entry_value["image"] = images[0]
                    else:
                        entry_value[
                            "image"
                        ] = "https://image.shutterstock.com/image-vector/no-image-vector-isolated-on-600w-1481369594.jpg"

                self._entries.append(entry_value)

    @property
    def device_state_attributes(self):
        return {"entries": self._entries}

1 Like

Nice!!

How do i integrate this in home assistant?

The easiest options would be to edit sensor.py in feedparser or copy/paste the feedparser folder then rename to create a separate component. In that case you will need to also edit manifest.json.

{
  "domain": "feedparser_custom",
  "name": "Feedparser custom",
  "version": "0.0.1",
  "documentation": "",
  "dependencies": [],
  "codeowners": ["@wetzel402"],
  "requirements": ["feedparser==6.0.8", "requests==2.26.0"]
}

Thanks for the help.

I tried your code and suggestions , but still no image in the feed parser sensor.

You should load up the URL in your web browser and make sure their is an image in the enclosure tag.

It is an JPG image (see example). The URL is in the links part of the feed parser sensor.

entries:
  - title: >-
      Quarantaineplicht voor Nederlanders in Oostenrijk, behalve na booster en
      PCR-test
    title_detail:
      type: text/plain
      language: null
      base: https://www.nu.nl/rss/Algemeen
      value: >-
        Quarantaineplicht voor Nederlanders in Oostenrijk, behalve na booster en
        PCR-test
    links:
      - rel: alternate
        type: text/html
        href: >-
          https://www.nu.nl/buitenland/6174480/quarantaineplicht-voor-nederlanders-in-oostenrijk-behalve-na-booster-en-pcr-test.html
      - length: '0'
        type: image/jpeg
        href: >-
          https://media.nu.nl/m/m1mxxp9aqakn_sqr256.jpg/quarantaineplicht-voor-nederlanders-in-oostenrijk-behalve-na-booster-en-pcr-test.jpg
        rel: enclosure
    link: >-
      https://www.nu.nl/buitenland/6174480/quarantaineplicht-voor-nederlanders-in-oostenrijk-behalve-na-booster-en-pcr-test.html
    summary: >-
      Oostenrijk heeft Nederland, Groot-Brittanniƫ, Noorwegen en Denemarken
      aangemerkt als gebieden waar de omikronvariant van het coronavirus heerst.
      Dat betekent dat reizigers vanuit deze landen vanaf zaterdag verplicht in
      quarantaine moeten na aankomst, tenzij ze een boosterprik hebben gehad en
      een negatieve PCR-test kunnen tonen. Dat meldde de Oostenrijkse overheid
      woensdag op een persconferentie.