1 """Support for monitoring the rtorrent BitTorrent client API."""
3 from __future__
import annotations
8 import voluptuous
as vol
11 PLATFORM_SCHEMA
as SENSOR_PLATFORM_SCHEMA,
14 SensorEntityDescription,
17 CONF_MONITORED_VARIABLES,
29 _LOGGER = logging.getLogger(__name__)
31 SENSOR_TYPE_CURRENT_STATUS =
"current_status"
32 SENSOR_TYPE_DOWNLOAD_SPEED =
"download_speed"
33 SENSOR_TYPE_UPLOAD_SPEED =
"upload_speed"
34 SENSOR_TYPE_ALL_TORRENTS =
"all_torrents"
35 SENSOR_TYPE_STOPPED_TORRENTS =
"stopped_torrents"
36 SENSOR_TYPE_COMPLETE_TORRENTS =
"complete_torrents"
37 SENSOR_TYPE_UPLOADING_TORRENTS =
"uploading_torrents"
38 SENSOR_TYPE_DOWNLOADING_TORRENTS =
"downloading_torrents"
39 SENSOR_TYPE_ACTIVE_TORRENTS =
"active_torrents"
41 DEFAULT_NAME =
"rtorrent"
42 SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
44 key=SENSOR_TYPE_CURRENT_STATUS,
48 key=SENSOR_TYPE_DOWNLOAD_SPEED,
50 device_class=SensorDeviceClass.DATA_RATE,
51 native_unit_of_measurement=UnitOfDataRate.KILOBYTES_PER_SECOND,
54 key=SENSOR_TYPE_UPLOAD_SPEED,
56 device_class=SensorDeviceClass.DATA_RATE,
57 native_unit_of_measurement=UnitOfDataRate.KILOBYTES_PER_SECOND,
60 key=SENSOR_TYPE_ALL_TORRENTS,
64 key=SENSOR_TYPE_STOPPED_TORRENTS,
65 name=
"Stopped Torrents",
68 key=SENSOR_TYPE_COMPLETE_TORRENTS,
69 name=
"Complete Torrents",
72 key=SENSOR_TYPE_UPLOADING_TORRENTS,
73 name=
"Uploading Torrents",
76 key=SENSOR_TYPE_DOWNLOADING_TORRENTS,
77 name=
"Downloading Torrents",
80 key=SENSOR_TYPE_ACTIVE_TORRENTS,
81 name=
"Active Torrents",
85 SENSOR_KEYS: list[str] = [desc.key
for desc
in SENSOR_TYPES]
87 PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
89 vol.Required(CONF_URL): cv.url,
90 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
91 vol.Optional(CONF_MONITORED_VARIABLES, default=SENSOR_KEYS): vol.All(
92 cv.ensure_list, [vol.In(SENSOR_KEYS)]
101 add_entities: AddEntitiesCallback,
102 discovery_info: DiscoveryInfoType |
None =
None,
104 """Set up the rtorrent sensors."""
105 url = config[CONF_URL]
106 name = config[CONF_NAME]
109 rtorrent = xmlrpc.client.ServerProxy(url)
110 except (xmlrpc.client.ProtocolError, ConnectionRefusedError)
as ex:
111 _LOGGER.error(
"Connection to rtorrent daemon failed")
112 raise PlatformNotReady
from ex
113 monitored_variables = config[CONF_MONITORED_VARIABLES]
116 for description
in SENSOR_TYPES
117 if description.key
in monitored_variables
124 """Return a bytes/s measurement as a human readable string."""
125 kb_spd =
float(speed) / 1024
126 return round(kb_spd, 2
if kb_spd < 0.1
else 1)
130 """Representation of an rtorrent sensor."""
133 self, rtorrent_client, client_name, description: SensorEntityDescription
135 """Initialize the sensor."""
140 self.
_attr_name_attr_name = f
"{client_name} {description.name}"
144 """Get the latest data from rtorrent and updates the state."""
145 multicall = xmlrpc.client.MultiCall(self.
clientclient)
146 multicall.throttle.global_up.rate()
147 multicall.throttle.global_down.rate()
148 multicall.d.multicall2(
"",
"main")
149 multicall.d.multicall2(
"",
"stopped")
150 multicall.d.multicall2(
"",
"complete")
151 multicall.d.multicall2(
"",
"seeding",
"d.up.rate=")
152 multicall.d.multicall2(
"",
"leeching",
"d.down.rate=")
155 self.
datadata = multicall()
157 except (xmlrpc.client.ProtocolError, OSError)
as ex:
158 _LOGGER.error(
"Connection to rtorrent failed (%s)", ex)
162 upload = self.
datadata[0]
163 download = self.
datadata[1]
164 all_torrents = self.
datadata[2]
165 stopped_torrents = self.
datadata[3]
166 complete_torrents = self.
datadata[4]
168 uploading_torrents = 0
169 for up_torrent
in self.
datadata[5]:
171 uploading_torrents += 1
173 downloading_torrents = 0
174 for down_torrent
in self.
datadata[6]:
176 downloading_torrents += 1
178 active_torrents = uploading_torrents + downloading_torrents
181 if sensor_type == SENSOR_TYPE_CURRENT_STATUS:
183 if upload > 0
and download > 0:
185 elif upload > 0
and download == 0:
187 elif upload == 0
and download > 0:
195 if sensor_type == SENSOR_TYPE_DOWNLOAD_SPEED:
197 elif sensor_type == SENSOR_TYPE_UPLOAD_SPEED:
199 elif sensor_type == SENSOR_TYPE_ALL_TORRENTS:
201 elif sensor_type == SENSOR_TYPE_STOPPED_TORRENTS:
203 elif sensor_type == SENSOR_TYPE_COMPLETE_TORRENTS:
205 elif sensor_type == SENSOR_TYPE_UPLOADING_TORRENTS:
207 elif sensor_type == SENSOR_TYPE_DOWNLOADING_TORRENTS:
209 elif sensor_type == SENSOR_TYPE_ACTIVE_TORRENTS:
None __init__(self, rtorrent_client, client_name, SensorEntityDescription description)
def add_entities(account, async_add_entities, tracked)
None setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback add_entities, DiscoveryInfoType|None discovery_info=None)