From 632466bb5659545e0870407e9491ffed143f3225 Mon Sep 17 00:00:00 2001 From: Hydreliox Date: Wed, 25 Oct 2017 15:13:11 +0200 Subject: [PATCH] Add Deluge Sensor (#10117) Add a sensor to provide upload and download speed of the Deluge Bittorrent Client --- .coveragerc | 1 + homeassistant/components/sensor/deluge.py | 129 ++++++++++++++++++++++ requirements_all.txt | 1 + 3 files changed, 131 insertions(+) create mode 100644 homeassistant/components/sensor/deluge.py diff --git a/.coveragerc b/.coveragerc index 11f3e837ef8..522ba69f08c 100644 --- a/.coveragerc +++ b/.coveragerc @@ -473,6 +473,7 @@ omit = homeassistant/components/sensor/cups.py homeassistant/components/sensor/currencylayer.py homeassistant/components/sensor/darksky.py + homeassistant/components/sensor/deluge.py homeassistant/components/sensor/deutsche_bahn.py homeassistant/components/sensor/dht.py homeassistant/components/sensor/dnsip.py diff --git a/homeassistant/components/sensor/deluge.py b/homeassistant/components/sensor/deluge.py new file mode 100644 index 00000000000..f4793867d4c --- /dev/null +++ b/homeassistant/components/sensor/deluge.py @@ -0,0 +1,129 @@ +""" +Support for monitoring the Deluge BitTorrent client API. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/sensor.deluge/ +""" +import logging + +import voluptuous as vol + +import homeassistant.helpers.config_validation as cv +from homeassistant.components.sensor import PLATFORM_SCHEMA +from homeassistant.const import ( + CONF_HOST, CONF_PASSWORD, CONF_USERNAME, CONF_NAME, CONF_PORT, + CONF_MONITORED_VARIABLES, STATE_IDLE) +from homeassistant.helpers.entity import Entity + +REQUIREMENTS = ['deluge-client==1.0.5'] + +_LOGGER = logging.getLogger(__name__) +_THROTTLED_REFRESH = None + +DEFAULT_NAME = 'Deluge' +DEFAULT_PORT = 58846 +DHT_UPLOAD = 1000 +DHT_DOWNLOAD = 1000 + +SENSOR_TYPES = { + 'current_status': ['Status', None], + 'download_speed': ['Down Speed', 'kB/s'], + 'upload_speed': ['Up Speed', 'kB/s'], +} + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_HOST): cv.string, + vol.Required(CONF_PASSWORD): cv.string, + vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, + vol.Required(CONF_USERNAME): cv.string, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_MONITORED_VARIABLES, default=[]): vol.All( + cv.ensure_list, [vol.In(SENSOR_TYPES)]), +}) + + +# pylint: disable=unused-argument +def setup_platform(hass, config, add_devices, discovery_info=None): + """Set up the Deluge sensors.""" + from deluge_client import DelugeRPCClient + + name = config.get(CONF_NAME) + host = config.get(CONF_HOST) + username = config.get(CONF_USERNAME) + password = config.get(CONF_PASSWORD) + port = config.get(CONF_PORT) + + deluge_api = DelugeRPCClient(host, port, username, password) + try: + deluge_api.connect() + except ConnectionRefusedError: + _LOGGER.error("Connection to Deluge Daemon failed") + return + + dev = [] + for variable in config[CONF_MONITORED_VARIABLES]: + dev.append(DelugeSensor(variable, deluge_api, name)) + + add_devices(dev) + + +class DelugeSensor(Entity): + """Representation of a Deluge sensor.""" + + def __init__(self, sensor_type, deluge_client, client_name): + """Initialize the sensor.""" + self._name = SENSOR_TYPES[sensor_type][0] + self.client = deluge_client + self.type = sensor_type + self.client_name = client_name + self._state = None + self._unit_of_measurement = SENSOR_TYPES[sensor_type][1] + self.data = None + + @property + def name(self): + """Return the name of the sensor.""" + return '{} {}'.format(self.client_name, self._name) + + @property + def state(self): + """Return the state of the sensor.""" + return self._state + + @property + def unit_of_measurement(self): + """Return the unit of measurement of this entity, if any.""" + return self._unit_of_measurement + + def update(self): + """Get the latest data from Deluge and updates the state.""" + self.data = self.client.call('core.get_session_status', + ['upload_rate', 'download_rate', + 'dht_upload_rate', 'dht_download_rate']) + + upload = self.data[b'upload_rate'] - self.data[b'dht_upload_rate'] + download = self.data[b'download_rate'] - self.data[ + b'dht_download_rate'] + + if self.type == 'current_status': + if self.data: + if upload > 0 and download > 0: + self._state = 'Up/Down' + elif upload > 0 and download == 0: + self._state = 'Seeding' + elif upload == 0 and download > 0: + self._state = 'Downloading' + else: + self._state = STATE_IDLE + else: + self._state = None + + if self.data: + if self.type == 'download_speed': + kb_spd = float(download) + kb_spd = kb_spd / 1024 + self._state = round(kb_spd, 2 if kb_spd < 0.1 else 1) + elif self.type == 'upload_speed': + kb_spd = float(upload) + kb_spd = kb_spd / 1024 + self._state = round(kb_spd, 2 if kb_spd < 0.1 else 1) diff --git a/requirements_all.txt b/requirements_all.txt index 344374b51f6..720cadcdc52 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -184,6 +184,7 @@ datapoint==0.4.3 # homeassistant.components.device_tracker.upc_connect defusedxml==0.5.0 +# homeassistant.components.sensor.deluge # homeassistant.components.switch.deluge deluge-client==1.0.5