core/homeassistant/components/nzbget/__init__.py

199 lines
5.8 KiB
Python
Raw Normal View History

"""The nzbget component."""
from datetime import timedelta
import logging
import pynzbgetapi
import voluptuous as vol
from homeassistant.const import (
CONF_HOST,
CONF_NAME,
CONF_PASSWORD,
CONF_PORT,
CONF_SCAN_INTERVAL,
CONF_SSL,
CONF_USERNAME,
)
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.dispatcher import dispatcher_send
from homeassistant.helpers.event import track_time_interval
_LOGGER = logging.getLogger(__name__)
ATTR_SPEED = "speed"
DOMAIN = "nzbget"
DATA_NZBGET = "data_nzbget"
DATA_UPDATED = "nzbget_data_updated"
DEFAULT_NAME = "NZBGet"
DEFAULT_PORT = 6789
DEFAULT_SPEED_LIMIT = 1000 # 1 Megabyte/Sec
DEFAULT_SCAN_INTERVAL = timedelta(seconds=5)
SERVICE_PAUSE = "pause"
SERVICE_RESUME = "resume"
SERVICE_SET_SPEED = "set_speed"
SPEED_LIMIT_SCHEMA = vol.Schema(
{vol.Optional(ATTR_SPEED, default=DEFAULT_SPEED_LIMIT): cv.positive_int}
)
CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: vol.Schema(
{
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_PASSWORD): cv.string,
vol.Optional(CONF_USERNAME): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(
CONF_SCAN_INTERVAL, default=DEFAULT_SCAN_INTERVAL
): cv.time_period,
vol.Optional(CONF_SSL, default=False): cv.boolean,
}
)
},
extra=vol.ALLOW_EXTRA,
)
def setup(hass, config):
"""Set up the NZBGet sensors."""
host = config[DOMAIN][CONF_HOST]
port = config[DOMAIN][CONF_PORT]
ssl = "s" if config[DOMAIN][CONF_SSL] else ""
name = config[DOMAIN][CONF_NAME]
username = config[DOMAIN].get(CONF_USERNAME)
password = config[DOMAIN].get(CONF_PASSWORD)
scan_interval = config[DOMAIN][CONF_SCAN_INTERVAL]
try:
nzbget_api = pynzbgetapi.NZBGetAPI(host, username, password, ssl, ssl, port)
nzbget_api.version()
except pynzbgetapi.NZBGetAPIException as conn_err:
_LOGGER.error("Error setting up NZBGet API: %s", conn_err)
return False
_LOGGER.debug("Successfully validated NZBGet API connection")
nzbget_data = hass.data[DATA_NZBGET] = NZBGetData(hass, nzbget_api)
nzbget_data.init_download_list()
nzbget_data.update()
def service_handler(service):
"""Handle service calls."""
if service.service == SERVICE_PAUSE:
nzbget_data.pause_download()
elif service.service == SERVICE_RESUME:
nzbget_data.resume_download()
elif service.service == SERVICE_SET_SPEED:
limit = service.data[ATTR_SPEED]
nzbget_data.rate(limit)
hass.services.register(
DOMAIN, SERVICE_PAUSE, service_handler, schema=vol.Schema({})
)
hass.services.register(
DOMAIN, SERVICE_RESUME, service_handler, schema=vol.Schema({})
)
hass.services.register(
DOMAIN, SERVICE_SET_SPEED, service_handler, schema=SPEED_LIMIT_SCHEMA
)
def refresh(event_time):
"""Get the latest data from NZBGet."""
nzbget_data.update()
track_time_interval(hass, refresh, scan_interval)
sensorconfig = {"client_name": name}
hass.helpers.discovery.load_platform("sensor", DOMAIN, sensorconfig, config)
return True
class NZBGetData:
"""Get the latest data and update the states."""
def __init__(self, hass, api):
"""Initialize the NZBGet RPC API."""
self.hass = hass
self.status = None
self.available = True
self._api = api
self.downloads = None
self.completed_downloads = set()
def update(self):
"""Get the latest data from NZBGet instance."""
try:
self.status = self._api.status()
self.downloads = self._api.history()
self.check_completed_downloads()
self.available = True
dispatcher_send(self.hass, DATA_UPDATED)
except pynzbgetapi.NZBGetAPIException as err:
self.available = False
_LOGGER.error("Unable to refresh NZBGet data: %s", err)
def init_download_list(self):
"""Initialize download list."""
self.downloads = self._api.history()
self.completed_downloads = {
(x["Name"], x["Category"], x["Status"]) for x in self.downloads
}
def check_completed_downloads(self):
"""Check history for newly completed downloads."""
actual_completed_downloads = {
(x["Name"], x["Category"], x["Status"]) for x in self.downloads
}
tmp_completed_downloads = list(
actual_completed_downloads.difference(self.completed_downloads)
)
for download in tmp_completed_downloads:
self.hass.bus.fire(
"nzbget_download_complete",
{"name": download[0], "category": download[1], "status": download[2]},
)
self.completed_downloads = actual_completed_downloads
def pause_download(self):
"""Pause download queue."""
try:
self._api.pausedownload()
except pynzbgetapi.NZBGetAPIException as err:
_LOGGER.error("Unable to pause queue: %s", err)
def resume_download(self):
"""Resume download queue."""
try:
self._api.resumedownload()
except pynzbgetapi.NZBGetAPIException as err:
_LOGGER.error("Unable to resume download queue: %s", err)
def rate(self, limit):
"""Set download speed."""
try:
if not self._api.rate(limit):
_LOGGER.error("Limit was out of range")
except pynzbgetapi.NZBGetAPIException as err:
_LOGGER.error("Unable to set download speed: %s", err)