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

New Transmission component #19230

Merged
merged 21 commits into from Jan 29, 2019
Merged
114 changes: 34 additions & 80 deletions homeassistant/components/sensor/transmission.py
Expand Up @@ -4,89 +4,59 @@
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.transmission/
"""
from datetime import timedelta
import logging

import voluptuous as vol

from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import (
CONF_HOST, CONF_MONITORED_VARIABLES, CONF_NAME, CONF_PASSWORD, CONF_PORT,
CONF_USERNAME, STATE_IDLE)
import homeassistant.helpers.config_validation as cv
from homeassistant.components.transmission import (
DATA_TRANSMISSION, SENSOR_TYPES, SCAN_INTERVAL)
from homeassistant.const import STATE_IDLE
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle
from homeassistant.exceptions import PlatformNotReady

REQUIREMENTS = ['transmissionrpc==0.11']
DEPENDENCIES = ['transmission']

_LOGGER = logging.getLogger(__name__)

DEFAULT_NAME = 'Transmission'
DEFAULT_PORT = 9091

SENSOR_TYPES = {
'active_torrents': ['Active Torrents', None],
'current_status': ['Status', None],
'download_speed': ['Down Speed', 'MB/s'],
'paused_torrents': ['Paused Torrents', None],
'total_torrents': ['Total Torrents', None],
'upload_speed': ['Up Speed', 'MB/s'],
}

SCAN_INTERVAL = timedelta(minutes=2)

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_MONITORED_VARIABLES, default=['torrents']):
vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PASSWORD): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_USERNAME): cv.string,
})


def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Transmission sensors."""
import transmissionrpc
from transmissionrpc.error import TransmissionError

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)

try:
transmission = transmissionrpc.Client(
host, port=port, user=username, password=password)
transmission_api = TransmissionData(transmission)
except TransmissionError as error:
if str(error).find("401: Unauthorized"):
_LOGGER.error("Credentials for Transmission client are not valid")
return

_LOGGER.warning(
"Unable to connect to Transmission client: %s:%s", host, port)
raise PlatformNotReady
if discovery_info is None:
return

MatteGary marked this conversation as resolved.
Show resolved Hide resolved
component_name = DATA_TRANSMISSION
MatteGary marked this conversation as resolved.
Show resolved Hide resolved
transmission_api = hass.data[component_name]
monitored_variables = discovery_info['sensors']
name = discovery_info['client_name']
sensor_types = SENSOR_TYPES
MatteGary marked this conversation as resolved.
Show resolved Hide resolved

dev = []
for variable in config[CONF_MONITORED_VARIABLES]:
dev.append(TransmissionSensor(variable, transmission_api, name))
for variable in monitored_variables:
MatteGary marked this conversation as resolved.
Show resolved Hide resolved
dev.append(TransmissionSensor(
variable,
transmission_api,
name,
sensor_types[variable][0],
sensor_types[variable][1]))

add_entities(dev, True)


class TransmissionSensor(Entity):
"""Representation of a Transmission sensor."""

def __init__(self, sensor_type, transmission_api, client_name):
def __init__(
self,
sensor_type,
transmission_api,
client_name,
sensor_name,
unit_of_measurement):
"""Initialize the sensor."""
self._name = SENSOR_TYPES[sensor_type][0]
self._name = sensor_name
self._state = None
self._transmission_api = transmission_api
self._unit_of_measurement = SENSOR_TYPES[sensor_type][1]
self._unit_of_measurement = unit_of_measurement
self._data = None
self.client_name = client_name
self.type = sensor_type
Expand All @@ -111,11 +81,17 @@ def available(self):
"""Could the device be accessed during the last update call."""
return self._transmission_api.available

@Throttle(SCAN_INTERVAL)
MatteGary marked this conversation as resolved.
Show resolved Hide resolved
def update(self):
"""Get the latest data from Transmission and updates the state."""
self._transmission_api.update()
self._data = self._transmission_api.data

if self.type == 'completed_torrents':
self._state = self._transmission_api.get_completed_torrent_count()
elif self.type == 'started_torrents':
self._state = self._transmission_api.get_started_torrent_count()

if self.type == 'current_status':
if self._data:
upload = self._data.uploadSpeed
Expand Down Expand Up @@ -146,25 +122,3 @@ def update(self):
self._state = self._data.pausedTorrentCount
elif self.type == 'total_torrents':
self._state = self._data.torrentCount


class TransmissionData:
"""Get the latest data and update the states."""

def __init__(self, api):
"""Initialize the Transmission data object."""
self.data = None
self.available = True
self._api = api

@Throttle(SCAN_INTERVAL)
def update(self):
"""Get the latest data from Transmission instance."""
from transmissionrpc.error import TransmissionError

try:
self.data = self._api.session_stats()
self.available = True
except TransmissionError:
self.available = False
_LOGGER.error("Unable to connect to Transmission client")
53 changes: 15 additions & 38 deletions homeassistant/components/switch/transmission.py
Expand Up @@ -6,54 +6,30 @@
"""
import logging

import voluptuous as vol

from homeassistant.components.switch import PLATFORM_SCHEMA
from homeassistant.components.transmission import (
MatteGary marked this conversation as resolved.
Show resolved Hide resolved
DATA_TRANSMISSION, SCAN_INTERVAL)
from homeassistant.const import (
CONF_HOST, CONF_NAME, CONF_PORT, CONF_PASSWORD, CONF_USERNAME, STATE_OFF,
STATE_ON)
STATE_OFF, STATE_ON)
from homeassistant.util import Throttle
from homeassistant.helpers.entity import ToggleEntity
import homeassistant.helpers.config_validation as cv

REQUIREMENTS = ['transmissionrpc==0.11']
DEPENDENCIES = ['transmission']

_LOGGING = logging.getLogger(__name__)

DEFAULT_NAME = 'Transmission Turtle Mode'
DEFAULT_PORT = 9091

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PASSWORD): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_USERNAME): cv.string,
})


def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Transmission switch."""
import transmissionrpc
from transmissionrpc.error import TransmissionError

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)
if discovery_info is None:
return

try:
transmission_api = transmissionrpc.Client(
host, port=port, user=username, password=password)
transmission_api.session_stats()
except TransmissionError as error:
_LOGGING.error(
"Connection to Transmission API failed on %s:%s with message %s",
host, port, error.original
)
return False
component_name = DATA_TRANSMISSION
transmission_api = hass.data[component_name]
name = discovery_info['client_name']

add_entities([TransmissionSwitch(transmission_api, name)])
add_entities([TransmissionSwitch(transmission_api, name)], True)


class TransmissionSwitch(ToggleEntity):
Expand Down Expand Up @@ -88,14 +64,15 @@ def is_on(self):
def turn_on(self, **kwargs):
"""Turn the device on."""
_LOGGING.debug("Turning Turtle Mode of Transmission on")
self.transmission_client.set_session(alt_speed_enabled=True)
self.transmission_client.set_alt_speed_enabled(True)

def turn_off(self, **kwargs):
"""Turn the device off."""
_LOGGING.debug("Turning Turtle Mode of Transmission off")
self.transmission_client.set_session(alt_speed_enabled=False)
self.transmission_client.set_alt_speed_enabled(False)

@Throttle(SCAN_INTERVAL)
MatteGary marked this conversation as resolved.
Show resolved Hide resolved
def update(self):
"""Get the latest data from Transmission and updates the state."""
active = self.transmission_client.get_session().alt_speed_enabled
active = self.transmission_client.get_alt_speed_enabled()
self._state = STATE_ON if active else STATE_OFF