New Deluge Sensor Config

Hi all,

I’ve been struggling getting the deluge integration to work, so I wrote an appdaemon script which monitors the download and upload speeds as well as torrent status (# of active, seeding, paused, queued, etc torrents). Idk if anyone has gotten the integration to work, but since it offers only speed monitoring, this was not sufficient in my case. Anyhow below is the code I wrote and can be easily extended to monitor additional variables of choice or even to actively modify torrent conditions (set speed limits, pause them etc.).

import hassapi as hass
import requests
from datetime import datetime

class Deluge(hass.Hass):
    prefix = 'deluge_'
    url = 'http://host-ip:8112/json'    
    headers = {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
        }
    cookies = None
    handle = None
    
    def login(self):
        body = {
            "method": "auth.login", 
            "params": ["deluge"], 
            "id": 2
        }
        response = requests.post(
            self.url,
            json=body,
            headers=self.headers,
        )
        json_response = response.json()
        if(json_response['result']):
            return response.cookies
        else:
            self.log('Deluge: could not log in!')
            return json_response['result']

    def initialize(self):
        self.log("Starting Deluge")
        tm = datetime.now()
        if self.handle != None:
            self.handle = self.run_minutely(self.runMain, tm)
        else:
            self.cancel_timer(self.handle)
            self.handle = self.run_minutely(self.runMain, tm)
        

    def runMain(self, kwargs):
        if(self.isConnected()):
            res = self.updateWebUI()
            params = self.getParams(res)
            self.updateHAStates(params)
            self.log('Updated HA...')
        else:
            self.log('Connecting...')
            cookie = self.login()
            if(cookie):
                self.cookies = cookie

    def isConnected(self):
        body_con = {
            "method": "web.connected", 
            "params": [], 
            "id": 2
        }
        response = requests.post(
            self.url,
            cookies=self.cookies,
            json=body_con,
            headers=self.headers
        )
        json_response = response.json()
        return json_response['result']

    def updateWebUI(self):
        body_ui = {
            "method": "web.update_ui", 
            "params": [{},None], 
            "id": 2
        }
        response = requests.post(
            self.url,
            cookies=self.cookies,
            json=body_ui,
            headers=self.headers
        )
        json_response = response.json()
        return json_response['result']

    def getParams(self,res):
        dl = float(res['stats']['download_rate'])/1024
        ul = float(res['stats']['upload_rate'])/1024
        torrents_all = res['filters']['state'][0][1]
        torrents_active = res['filters']['state'][1][1]
        torrents_downloading = res['filters']['state'][4][1]
        torrents_seeding = res['filters']['state'][5][1]
        torrents_paused = res['filters']['state'][6][1]
        torrents_queued = res['filters']['state'][8][1]
        return {'dl': dl,
                'ul': ul,
                'torrents_all':torrents_all,
                'torrents_active':torrents_active,
                'torrents_downloading':torrents_downloading,
                'torrents_seeding':torrents_seeding,
                'torrents_paused':torrents_paused,
                'torrents_queued':torrents_queued
                }

    def updateHAStates(self,params):
        for ix,e in params.items():
            self.set_state("input_number."+self.prefix+ix, state=e)

The only things that you need to change in the script is the host-ip of the device running deluge and the password to the web-ui. Also you need to have the web-ui daemon running. The script runs minutely and upon completion will add a number of variables in the form of “input_number.deluge_variables” for download and upload speed and torrent statuses. Those can can be integrated within a visualization as such:
image

edit: as I was using the code, I noticed some inefficiencies and updated the code here with the latest revision.

Nice idea …I was thinking there would be something similar for qBittorrent with torrent names like for transmission add-on

Hi,

Great idea,

How do you achieve 2 lines in the sensor card?

I installed the standard deluge yesterday, works fine, but quite tricky to achieve through configuration, so I first checked if I could access deluge daemon from another computer, fixed all issues with firewall and public/private network, then works fine, for the limited options it provides…

Therefore looking to implement your script too!

Thanks

Hi, my script has changed a bit. Now I’m using the RPC API instead of the Web API as I found it to be more reliable. The Web API would often freeze and Appdaemon won’t be able to reconnect without restarting. Using the RPC API has been working without any hiccups for over a month now. Below is the updated and much cleaner looking script.

The code below returns the current upload/download speed from deluge as well as the number of torrents with the status of: ‘downloading’, ‘paused’, ‘seeding’, ‘queued’, ‘active’.

As to how to display two entities within the same chart, you can check here: History Graph Card - Home Assistant. Cheers.

import hassapi as hass
from deluge_client import DelugeRPCClient
import pytz
import datetime

class DelugeMonitor(hass.Hass):
    #Deluge params
    deluge_ip = '192.168.0.0' #host ip
    deluge_port = 58846 #deluge RPC port. needs to be exposed
    deluge_username = 'xxx' #username
    deluge_password = 'xxx' #password
    #HA params
    prefix = 'deluge_'
    #Timezone
    tz = pytz.timezone('Europe/Amsterdam')
    handle = None
	
    def initialize(self):
        self.log("Starting Deluge")
        if self.handle != None:
            self.handle = self.run_every(self.runMain, "now", 10)
        else:
            self.cancel_timer(self.handle)
            self.handle = self.run_every(self.runMain, "now", 10)

    def runMain(self, kwargs):
        speed,status = self.fetchData()
        self.updateSpeedState(speed)
        self.updateTorrentState(status)
        #last updated
        self.set_state("sensor."+self.prefix+"last_updated", state=datetime.datetime.now(self.tz))
        self.log(self.handle)

    def fetchData(self):
        status = {'downloading':0, 'paused':0, 'seeding':0, 'queued':0, 'active':0}
        speed = {'download':0,'upload':0}
        with DelugeRPCClient(self.deluge_ip, port=self.deluge_port, username=self.deluge_username, password=self.deluge_password) as client:
            torrents_list = client.call('core.get_torrents_status', {}, [])
            status['all'] = len(torrents_list)
            for torrent_id, torrent_data in torrents_list.items():
                status[torrent_data[b'state'].decode().lower()] += 1
                if torrent_data[b'peers']:
                    status['active'] += 1
                for peer in torrent_data[b'peers']:
                    speed['upload'] += peer[b'up_speed']
                    speed['download'] += peer[b'down_speed']
            speed['upload'] = speed['upload']/1024
            speed['download'] = speed['download']/1024
        return speed,status

    def updateSpeedState(self, speed):
        for ix,e in speed.items():
            self.set_state("sensor."+self.prefix+ix, state=e, attributes = {"unit_of_measurement": "KB"})
    def updateTorrentState(self, torrent):
        for ix,e in torrent.items():
            self.set_state("sensor."+self.prefix+ix, state=e, attributes = {"unit_of_measurement": "#"})

Hi, Do i just copy the contents into a new file called Appdaemon_Deluge.py, change the

  • deluge_ip

  • deluge_username

  • deluge_password

and save this file in /config/appdaemon/apps/appdaemon-deluge folder.

Restart home assistant.

Do i need to do anything else?

Sorry to bump this from the dead, but I can’t find reference to the deluge_client module anywhere online. Am I missing something to get this working? Right now, it’s spitting an error that it doesn’t recognize the module.

Figured it out. Needed to add deluge-client to the list of Python packages installed on container start.