Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Radarr Integration loads without error but all sensors Unavailable #51390

Closed
DavidFW1960 opened this issue Jun 2, 2021 · 53 comments
Closed

Radarr Integration loads without error but all sensors Unavailable #51390

DavidFW1960 opened this issue Jun 2, 2021 · 53 comments

Comments

@DavidFW1960
Copy link

The problem

As per the title the Radarr Integration is not giving any errors and is loading but all sensors show as unavailable

What is version of Home Assistant Core has the issue?

2021.6.x

What was the last working version of Home Assistant Core?

one of the 2021.6 betas and certainly 2021.5.5

What type of installation are you running?

Home Assistant Supervised

Integration causing the issue

Radarr

Link to integration documentation on our website

https://www.home-assistant.io/integrations/radarr/

Example YAML snippet

sensor:
  - platform: radarr
    api_key: !secret my_radarr_api
    host: !secret my_radarr_host
    port: !secret my_radarr_port
    monitored_conditions:
      - movies
      - upcoming
      - commands
      - status
    days: 10


### Anything in the logs that might be useful for us?

```txt
nothing at all

Additional information

No response

@DavidFW1960
Copy link
Author

So I know what the problem is. They have removed the old API endpoint in version 4 nightlies and now /v3 is needed.
I tried making a custom_component and editing the endpoints:

ENDPOINTS = {
    "diskspace": "{0}://{1}:{2}/{3}api/v3/diskspace",
    "upcoming": "{0}://{1}:{2}/{3}api/v3/calendar?start={4}&end={5}",
    "movies": "{0}://{1}:{2}/{3}api/v3/movie",
    "commands": "{0}://{1}:{2}/{3}api/v3/command",
    "status": "{0}://{1}:{2}/{3}api/v3/system/status",

I then get errors so seems like there is something else in core?:

Logger: homeassistant.components.sensor
Source: custom_components/radarr/sensor.py:166
Integration: Sensor (documentation, issues)
First occurred: 3:51:29 PM (2 occurrences)
Last logged: 3:51:30 PM

Error adding entities for domain sensor with platform radarr
Error while setting up radarr platform for sensor
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 383, in async_add_entities
    await asyncio.gather(*tasks)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 588, in _async_add_entity
    await entity.add_to_platform_finish()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 615, in add_to_platform_finish
    self.async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 368, in async_write_ha_state
    self._async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 405, in _async_write_ha_state
    extra_state_attributes = self.extra_state_attributes
  File "/config/custom_components/radarr/sensor.py", line 166, in extra_state_attributes
    attributes[to_key(movie)] = movie["downloaded"]
KeyError: 'downloaded'

@DavidFW1960
Copy link
Author

Radarr support say the old API has been deprecated for some time and the new API will work with all current supported releases of Radarr - current v3 stable as well as the V4 nightlies.

@mcevansw
Copy link

mcevansw commented Jun 3, 2021

Same issue here, number 3 since last nights update, will follow up with any progress I may have

@DavidFW1960
Copy link
Author

ok well I fixed this but I fear no way a PR will be accepted because it's using yaml still.
I can't get the command condition working so if you have command in your monitored get rid of it.
My config:

  - platform: radarr
    api_key: !secret my_radarr_api
    host: !secret my_radarr_host
    port: !secret my_radarr_port
    monitored_conditions:
      - movies
      - upcoming
#      - commands
      - status
    days: 10

Need to copy contents of whole folder to config/custom_components and edit manifest.json to include a version number. Then replace sensor.py with this:

"""Support for Radarr."""
from datetime import datetime, timedelta
import logging
import time

import requests
import voluptuous as vol

from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
from homeassistant.const import (
    CONF_API_KEY,
    CONF_HOST,
    CONF_MONITORED_CONDITIONS,
    CONF_PORT,
    CONF_SSL,
    DATA_BYTES,
    DATA_EXABYTES,
    DATA_GIGABYTES,
    DATA_KILOBYTES,
    DATA_MEGABYTES,
    DATA_PETABYTES,
    DATA_TERABYTES,
    DATA_YOTTABYTES,
    DATA_ZETTABYTES,
    HTTP_OK,
)
import homeassistant.helpers.config_validation as cv
from homeassistant.util import dt as dt_util

_LOGGER = logging.getLogger(__name__)

CONF_DAYS = "days"
CONF_INCLUDED = "include_paths"
CONF_UNIT = "unit"
CONF_URLBASE = "urlbase"

DEFAULT_HOST = "localhost"
DEFAULT_PORT = 7878
DEFAULT_URLBASE = ""
DEFAULT_DAYS = "1"
DEFAULT_UNIT = DATA_GIGABYTES

SCAN_INTERVAL = timedelta(minutes=10)

SENSOR_TYPES = {
    "diskspace": ["Disk Space", DATA_GIGABYTES, "mdi:harddisk"],
    "upcoming": ["Upcoming", "Movies", "mdi:television"],
    "wanted": ["Wanted", "Movies", "mdi:television"],
    "movies": ["Movies", "Movies", "mdi:television"],
 #   "commands": ["Commands", "Commands", "mdi:code-braces"],
    "status": ["Status", "Status", "mdi:information"],
}

ENDPOINTS = {
    "diskspace": "{0}://{1}:{2}/{3}api/v3/diskspace",
    "upcoming": "{0}://{1}:{2}/{3}api/v3/calendar?unmonitored=false&start={4}&end={5}",
    "movies": "{0}://{1}:{2}/{3}api/v3/movie",
 #   "commands": "{0}://{1}:{2}/{3}api/v3/command",
    "status": "{0}://{1}:{2}/{3}api/v3/system/status",
}

# Support to Yottabytes for the future, why not
BYTE_SIZES = [
    DATA_BYTES,
    DATA_KILOBYTES,
    DATA_MEGABYTES,
    DATA_GIGABYTES,
    DATA_TERABYTES,
    DATA_PETABYTES,
    DATA_EXABYTES,
    DATA_ZETTABYTES,
    DATA_YOTTABYTES,
]
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {
        vol.Required(CONF_API_KEY): cv.string,
        vol.Optional(CONF_DAYS, default=DEFAULT_DAYS): cv.string,
        vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string,
        vol.Optional(CONF_INCLUDED, default=[]): cv.ensure_list,
        vol.Optional(CONF_MONITORED_CONDITIONS, default=["movies"]): vol.All(
            cv.ensure_list, [vol.In(list(SENSOR_TYPES))]
        ),
        vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
        vol.Optional(CONF_SSL, default=False): cv.boolean,
        vol.Optional(CONF_UNIT, default=DEFAULT_UNIT): vol.In(BYTE_SIZES),
        vol.Optional(CONF_URLBASE, default=DEFAULT_URLBASE): cv.string,
    }
)


def setup_platform(hass, config, add_entities, discovery_info=None):
    """Set up the Radarr platform."""
    conditions = config.get(CONF_MONITORED_CONDITIONS)
    add_entities([RadarrSensor(hass, config, sensor) for sensor in conditions], True)


class RadarrSensor(SensorEntity):
    """Implementation of the Radarr sensor."""

    def __init__(self, hass, conf, sensor_type):
        """Create Radarr entity."""

        self.conf = conf
        self.host = conf.get(CONF_HOST)
        self.port = conf.get(CONF_PORT)
        self.urlbase = conf.get(CONF_URLBASE)
        if self.urlbase:
            self.urlbase = f"{self.urlbase.strip('/')}/"
        self.apikey = conf.get(CONF_API_KEY)
        self.included = conf.get(CONF_INCLUDED)
        self.days = int(conf.get(CONF_DAYS))
        self.ssl = "https" if conf.get(CONF_SSL) else "http"
        self._state = None
        self.data = []
        self.type = sensor_type
        self._name = SENSOR_TYPES[self.type][0]
        if self.type == "diskspace":
            self._unit = conf.get(CONF_UNIT)
        else:
            self._unit = SENSOR_TYPES[self.type][1]
        self._icon = SENSOR_TYPES[self.type][2]
        self._available = False

    @property
    def name(self):
        """Return the name of the sensor."""
        return "{} {}".format("Radarr", self._name)

    @property
    def state(self):
        """Return sensor state."""
        return self._state

    @property
    def available(self):
        """Return sensor availability."""
        return self._available

    @property
    def unit_of_measurement(self):
        """Return the unit of the sensor."""
        return self._unit

    @property
    def extra_state_attributes(self):
        """Return the state attributes of the sensor."""
        attributes = {}
        if self.type == "upcoming":
            for movie in self.data:
                attributes[to_key(movie)] = get_release_date(movie)
 #       elif self.type == "commands":
 #           for command in self.data:
 #               attributes[command["name"]] = command["state"]
        elif self.type == "diskspace":
            for data in self.data:
                free_space = to_unit(data["freeSpace"], self._unit)
                total_space = to_unit(data["totalSpace"], self._unit)
                percentage_used = (
                    0 if total_space == 0 else free_space / total_space * 100
                )
                attributes[data["path"]] = "{:.2f}/{:.2f}{} ({:.2f}%)".format(
                    free_space, total_space, self._unit, percentage_used
                )
        elif self.type == "movies":
            for movie in self.data:
                attributes[to_key(movie)] = movie["hasFile"]
        elif self.type == "status":
            attributes = self.data

        return attributes

    @property
    def icon(self):
        """Return the icon of the sensor."""
        return self._icon

    def update(self):
        """Update the data for the sensor."""
        time_zone = dt_util.get_time_zone(self.hass.config.time_zone)
        start = get_date(time_zone)
        end = get_date(time_zone, self.days)
        try:
            res = requests.get(
                ENDPOINTS[self.type].format(
                    self.ssl, self.host, self.port, self.urlbase, start, end
                ),
                headers={"X-Api-Key": self.apikey},
                timeout=10,
            )
        except OSError:
            _LOGGER.warning("Host %s is not available", self.host)
            self._available = False
            self._state = None
            return

        if res.status_code == HTTP_OK:
            if self.type in ["upcoming", "movies"]:        #, "commands"]:
                self.data = res.json()
                self._state = len(self.data)
            elif self.type == "diskspace":
                # If included paths are not provided, use all data
                if self.included == []:
                    self.data = res.json()
                else:
                    # Filter to only show lists that are included
                    self.data = list(
                        filter(lambda x: x["path"] in self.included, res.json())
                    )
                self._state = "{:.2f}".format(
                    to_unit(sum([data["freeSpace"] for data in self.data]), self._unit)
                )
            elif self.type == "status":
                self.data = res.json()
                self._state = self.data["version"]
            self._available = True


def get_date(zone, offset=0):
    """Get date based on timezone and offset of days."""
    day = 60 * 60 * 24
    return datetime.date(datetime.fromtimestamp(time.time() + day * offset, tz=zone))


def get_release_date(data):
    """Get release date."""
    date = data.get("physicalRelease")
    if not date:
        date = data.get("inCinemas")
    return date


def to_key(data):
    """Get key."""
    return "{} ({})".format(data["title"], data["year"])


def to_unit(value, unit):
    """Convert bytes to give unit."""
    return value / 1024 ** BYTE_SIZES.index(unit)

OR you can copy my sensor.py and manifest.json from here:
https://github.com/DavidFW1960/home-assistant/tree/master/custom_components/radarr

I also patched Maykar's upcoming media component to add api v3 (one minor change) and made a PR for it

@DavidFW1960
Copy link
Author

@ronanmu Any chance you can take a look at and maybe fix this?

@towerhand
Copy link

Can anyone please fix this integration?

@DavidFW1960
Copy link
Author

Can anyone please fix this integration?

Did you try the above fix? It's working for me (except for the commands sensor)

@towerhand
Copy link

I haven’t had time to mess with it but I should be able to try it in a couple weeks.

@marine1988
Copy link

marine1988 commented Jul 26, 2021

I have the same bug on mine config

@tkdrob
Copy link
Contributor

tkdrob commented Oct 15, 2021

I wonder if people are still using radarr v2. If we can forget about v2, it will be easier to add config flow. Is anyone watching this issue working on that?

@DavidFW1960
Copy link
Author

no one so far seems to care about this..

@tkdrob
Copy link
Contributor

tkdrob commented Oct 16, 2021

no one so far seems to care about this..

Except possible me. I would have to either find a good existing library or make my own.

@DavidFW1960
Copy link
Author

DavidFW1960 commented Oct 16, 2021

Well the current integration works for old API.. It's only V3 that doesn't work and my custom hack of the core component works for v3.. just not the old commands function.

Except possible me. I would have to either find a good existing library or make my own.

Why when the hack works is a new library needed? Is that needed to use the config flow? I did look at the Sonarr component which was updated a while ago and uses the config flow but it's just beyond my skills.

I was also referring to the devs and code owner for this integration being uninterested in fixing it not people responding here...

@DeftNerd
Copy link

DeftNerd commented Nov 18, 2021

The Sonarr integration uses the sonarr 12 Python library, but there isn't an identical library for Radarr which would make code copy&paste possible.

Instead, I think that building a new Radarr integration based on pyarr 34 would be the best solution. The library has one pull request that'll cause breaking changes 5, but once that's done, I'm considering taking up the mantle and building a new plugin myself.

What's exciting is that the pyarr library currently supports Sonarr & Radarr, but Readarr6, Lidarr7 and Prowlarr8 are coming soon.

This means that a successful Home Assistant plugin for Radarr based on the pyarr library should be relatively easily modified to provide support for Sonarr, Lidarr, Readarr, and Prowlarr.

References:

Footnotes

  1. https://pypi.org/project/sonarr/

  2. https://github.com/ctalkington/python-sonarr

  3. https://pypi.org/project/pyarr/

  4. https://github.com/totaldebug/pyarr

  5. https://github.com/totaldebug/pyarr/tree/80-add_readarr_support

  6. https://github.com/totaldebug/pyarr/issues/80

  7. https://github.com/totaldebug/pyarr/issues/81

  8. https://github.com/totaldebug/pyarr/issues/82

@tkdrob
Copy link
Contributor

tkdrob commented Nov 18, 2021

I am also considering writing the radarr config flow.

@tkdrob
Copy link
Contributor

tkdrob commented Dec 4, 2021

The Sonarr integration uses the sonarr 12 Python library, but there isn't an identical library for Radarr which would make code copy&paste possible.

Instead, I think that building a new Radarr integration based on pyarr 34 would be the best solution. The library has one pull request that'll cause breaking changes 5, but once that's done, I'm considering taking up the mantle and building a new plugin myself.

What's exciting is that the pyarr library currently supports Sonarr & Radarr, but Readarr6, Lidarr7 and Prowlarr8 are coming soon.

This means that a successful Home Assistant plugin for Radarr based on the pyarr library should be relatively easily modified to provide support for Sonarr, Lidarr, Readarr, and Prowlarr.

References:

Footnotes

  1. https://pypi.org/project/sonarr/
  2. https://github.com/ctalkington/python-sonarr
  3. https://pypi.org/project/pyarr/
  4. https://github.com/totaldebug/pyarr
  5. https://github.com/totaldebug/pyarr/tree/80-add_readarr_support
  6. Add Readarr support totaldebug/pyarr#80
  7. Add Lidarr support totaldebug/pyarr#81
  8. Add Prowlarr support totaldebug/pyarr#82

The issue with pyarr is it does not throw exceptions for things like authentication and its not async. We like that here. You will now see that I have a PR open with a fresh new library. 🚀

@DavidFW1960
Copy link
Author

Well 2021.12.0b0 completely breaks the integration so good news if a new one is coming.

@tkdrob
Copy link
Contributor

tkdrob commented Dec 4, 2021

Its broken if you are running custom. Something was changed in the imports.

@DavidFW1960
Copy link
Author

Yeah I was running a modified version as per above as a custom component because it didn't support the latest API

@DavidFW1960
Copy link
Author

ok I loaded the 2 files you changed in latest 'tweak' and the integration loads with no errors when I restart HA.
When I go to integrations and add Radarr it says
image

@DavidFW1960
Copy link
Author

DavidFW1960 commented Dec 8, 2021

Can you confirm from this post that I made the correct modifications in the correct file?

#60847 (comment)

@tkdrob
Copy link
Contributor

tkdrob commented Dec 8, 2021

You would have to share with me the folder you made.

@DavidFW1960
Copy link
Author

image
It's just in config/custom_components?radarr

@tkdrob
Copy link
Contributor

tkdrob commented Dec 8, 2021

Check discord. I sent you my copy.

@DavidFW1960
Copy link
Author

Check discord. I sent you my copy.

Are you by any chance also using Sabnzbd? This is erroring in 2021.12.0.x as well. I raised an issue there #61306 but it seems an upstream library is the culprit for that.

@tkdrob
Copy link
Contributor

tkdrob commented Dec 10, 2021

Check discord. I sent you my copy.

Are you by any chance also using Sabnzbd? This is erroring in 2021.12.0.x as well. I raised an issue there #61306 but it seems an upstream library is the culprit for that.

No. But I may look into it. I'm currently working no some new integrations.

@DavidFW1960
Copy link
Author

Thanks. It's really weird because just using an API Call I think I can get the same data as the integration anyway by using a rest sensor so I dunno why HA is doing it the way that it currently is.

@tkdrob
Copy link
Contributor

tkdrob commented Dec 10, 2021

Thanks. It's really weird because just using an API Call I think I can get the same data as the integration anyway by using a rest sensor so I dunno why HA is doing it the way that it currently is.

A change has been made on how timeouts are handled. The timeout context is no longer used with aiohttp. That's why.

Actually, the loop argument is more the problem here and is deprecated.

@furrymayo
Copy link

Hey, I am having a similar issue. If you guys are anywhere near getting this resolved I wouldn't mind beta testing whatever you got.

@DavidFW1960
Copy link
Author

Hey, I am having a similar issue. If you guys are anywhere near getting this resolved I wouldn't mind beta testing whatever you got.

You can download a working version as a custom component from my repo

@tkdrob
Copy link
Contributor

tkdrob commented Feb 22, 2022

Hey, I am having a similar issue. If you guys are anywhere near getting this resolved I wouldn't mind beta testing whatever you got.

You can download a working version as a custom component from my repo

Keep in mind that if you use this custom component, to remove it and re-setup the integration when it is officially released. The config entries will be different.

@DavidFW1960
Copy link
Author

Hey, I am having a similar issue. If you guys are anywhere near getting this resolved I wouldn't mind beta testing whatever you got.

You can download a working version as a custom component from my repo

Keep in mind that if you use this custom component, to remove it and re-setup the integration when it is officially released. The config entries will be different.

Yes. Thanks for pointing that out. It serves a purpose for now though and I'll keep an eye on the release notes too.

@hellcry37

This comment was marked as abuse.

@DavidFW1960
Copy link
Author

Radarr v4.0.5.5981 server.

The reason is HA is only supporting v2 API still. This radarr is using API v3.

There has been a PR to fix this and add GUI confir since many months still not merged,

@hellcry37

This comment was marked as abuse.

@ghost
Copy link

ghost commented Apr 15, 2022

The PR seems to be failing black and pip check. Do these need to be fixed before they'll accept the PR?

@hellcry37

This comment was marked as abuse.

@tkdrob
Copy link
Contributor

tkdrob commented Apr 15, 2022

The PR seems to be failing black and pip check. Do these need to be fixed before they'll accept the PR?

The target branch for the PR is not dev, so that does not matter. It's whenever @balloob wants to review it.

no idea but clearly ppl don't seem to bother to much with this

It's quite the opposite, actually. Remember that this is volunteer work and the members have their own agendas of what needs to be done for each release. Each release is huge. Just look at the last release. It gets better and better. I prefer they stick to that plan.

Anyone is free to move anything that is being proposed into custom_components and run it that way.

@ghost
Copy link

ghost commented Apr 20, 2022

Is there some trick I'm missing to get it to work from custom components? I cloned your radarr folder and slide it into the custom_components but it's not an option.

@DavidFW1960
Copy link
Author

Where did you clone it from?

@github-actions
Copy link

There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates.
Please make sure to update to the latest Home Assistant version and check if that solves the issue. Let us know if that works for you by adding a comment 👍
This issue has now been marked as stale and will be closed if no further activity occurs. Thank you for your contributions.

@github-actions github-actions bot added the stale label Jul 20, 2022
@DavidFW1960
Copy link
Author

This still is not working

@github-actions github-actions bot removed the stale label Jul 20, 2022
@saschabrockel
Copy link

Like @DavidFW1960 says it is still not working.

@marine1988
Copy link

still not working on last version

@pseudomix
Copy link

Still not Working on last version

@tkdrob
Copy link
Contributor

tkdrob commented Sep 24, 2022

Not until next release, but be sure to read the posted issues. A lot of changes are being made to modernize things but still a WIP.

@julio8a
Copy link

julio8a commented Oct 5, 2022

Will look for this on next release

@pseudomix
Copy link

Oh! Great! Thanks a lot.
Very responsive.
Have a nice day

@tkdrob
Copy link
Contributor

tkdrob commented Oct 24, 2022

@home-assistant close

@github-actions github-actions bot locked and limited conversation to collaborators Nov 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests