For me one of always missing integrations was Synology Download Station. So I decided to fill in the gap… and here it is… sort of.
Since I’m not familiar with python, I did not took challenge to build proper integration, but I figured out how I can link with SDS using standard tools available for everyone within HA. It ended with creation of yaml package containing everything that is needed to integrate SDS into HA. Before you begin, however, a few words of warning:
- it is
entirely based on sensor created in configuration.yamlcreated using mix of REST sensors, shell commands, some scripts and automations, so it probably not as efficient as it would be while using proper integration. -
since I use rest sensors to obtain information from SDS and use other set of sensors to process this data, propagation of information takes time. I believe rest sensors are updated every 15 seconds and it takes up to 3 cycles to update ‘child’ sensors. Not ideal, but given the fact that sometimes file downloads are very long process I believe this speed of update is acceptable. I no more use REST sensors, being replaced by shell commands that are invoked every 10 seconds. Responce from these commands is instantly processed by file sensors, so overal whole ‘integration’ is way more responsive and (almost) always provides consistent download tasks informtion. - WARNING: since I found no way to template secrets, configuration of this ‘integration’ is hardcoded in sensors. Especially it concerns user ID and password used to access Synology NAS via API and also exposes session token (required to access API after logging in) as one of sensors ! ! !
- since using this method I can’t create dynamically sensors, these are somehow reusable. You should consider each sensor as representing download slot rather that actual individual task. It means that these sensors are ‘reusable’ and if one download is completed and removed from SDS, this slot might be used for other pending download task, effectively changing history of task from old to new one… especially inconvenient for charts (like download speed).
Also when task is removed or added to SDS it might cause some inconsistency of displayed data, before sensors values changes in up to 3 iterations I mentioned in point #1.
So, to the actual implementation:
You need to copy all the code from gist below into download.yaml file inside your config directory (or obviously modify setup to your liking! )
- Since everything is packaged into single download.yaml package file, your configuration just need to be updated. Since now I’m using temporary files to store data from shell commands, it is required to create /sds folder under your config directory and whitelist it, so it can be accessed by scripts and file sensors. Required changes to configuration.yaml file are listed below:
homeassistant:
packages:
download: !include download.yaml
whitelist_external_dirs:
- /config/sds
- Additional step for system preparation is to create set of files (should be emty) in config/sds folder. These files will be used by shell commands to store temporary data. I found commands failing if files are not created prior to running them for the first time, so this is mandatory step. Files to be created:
sid.json
sds_tasks_list.json
sds_task_0.json
sds_task_1.json
sds_task_2.json
sds_task_3.json
sds_task_4.json
sds_task_5.json
sds_task_6.json
sds_task_7.json
sds_task_8.json
sds_task_9.json
- within download.yaml, you need to update
2 first sensors (sds_login and sds_tasks_list)all 12 shell_commands replacing following statements with actual data:
_SDS_IP_ - IP address of your NAS
_SDS_PORT_ - port to connect on. in standard setup it is:
5000 for Synology Diskstation Manager or
8000 for Synology Download Station
either of these 2 can be used
_SDS_USER_ - DSM user with permission to use SDS
_SDS_PASS_ - password for above user
- if you have proper ssl access configgured on your NAS, you can change protocol to hppts and update port accordingly (5001 or 8001).
- you also need to update
_SDS_IP_
and_SDS_PORT_
within all sds_task_# sensors. - I created sensor templates for 10 download slots. All corresponding to specific download slot sensors have name ending with _#, where # represent number of slot, starting with 0 and ending with 9. If you do not expect such number of slots to be used you can safely delete some and decrease number of created sensors. If you download more, you can also add new sensors with # starting from 10…
Following sensors are created:
- sensor.sds_login - it is used to initially log on to SDS and obtain the API token. Not used elsewhere.
- sensor.sds_tasks_list - contain list of basic data for all download tasks. This list will be empty if no downloads or might contain information about more than 10 tasks, but the tasks 10+ will be disregarded (until you create additional sensors). Otherwise this sensor has no use.
- sensor.sds_task_# - contains detailed information about download task as reported via SDS API. Based on information from this sensor all other sensors are created. If you feel confident with templating, you can uses these sensors directly!
- sensor.sds_sid - this is the sensor that holds API token used by rest sensors to retrieve data via API. No for direct use.
- sensor.sds_sid_2 - temporary sensor, not to be used
- sensor.sds_task_id_# - set of sensors used by SDS API to identify unique tasks. Used as reference by other sensors only.
- sensor.sds_task_name_# - name of downloaded file
- sensor,sds_task_size_# - size of downloaded file in MB
- sensor.sds_task_size_downloaded_# - size of already downloaded part of file in MB
- sensor.sds_task_completed_# - download progress in %
- sensor.sds_task_speed_down_# - task download speed in kbps
- sensor.sds_task_speed_up_# - task upload speed in kbps
- sensor.sds_task_status_# - status of task (downloading, error, finished, unknown for just started, unavailable for empty slot)
- sensor.sds_task_state_# - True if download task is active
Set of statistical sensors, useful for example to dynamically scale some charts, or dynamic color representation:
- sensor.sds_max_download - sensor reporting download speed of fastest task
- sensor.sds_avg_download - sensor reporting average download speed of all tasks
- sensor.sds_min_download - sensor reporting download speed of slowest task (frequently 0)
- sensor.sds_max_upload - sensor reporting upload speed of fastest task
- sensor.sds_avg_upload - sensor reporting average upload speed of all tasks
- sensor.sds_min_upload - sensor reporting upload speed of slowest task (frequently 0)
- sensor.sds_max_transfer - representing fastest one of upload and download, useful if you want to use one graph to display both and have uniform scale.
As you can see package I prepared contains lots of sensors, in your particular implementation perhaps some might be useless, so can be safely deleted, decluttering configuration.
As a bonus I’m attaching template of lovelace card I created to use with this ‘integration’. It requires following components to be installed:
- button-card
- custom:mini-graph-card
- custom:config-template-card
- custom:button-card
Following code is for download slot 0. To create similar cards for subsequent slots you need to replace in the names of sensors use ‘_0’ with proper number. Card is autohiding, if slot not in use, to keep UI declustered.
card:
aspect_ratio: 1.3/1
custom_fields:
bar:
card:
direction: right
entities:
- entity: sensor.sds_task_completed_0
height: 25px
max: 100
min: 0
positions:
icon: 'off'
indicator: 'off'
minmax: 'off'
name: 'off'
target: 'off'
value: inside
severity:
- color: '#7b55d5'
from: 0
to: 25
- color: '#fc70f3'
from: 25
to: 50
- color: '#00b8fe'
from: 50
to: 75
- color: '#7cff73'
from: 75
to: 100
type: 'custom:bar-card'
width: 10%
graph:
card:
card:
entities:
- entity: sensor.sds_task_speed_down_0
color: var(--greenish)
state_adaptive_color: true
name: Download
- entity: sensor.sds_task_speed_up_0
color: var(--light-magenta)
state_adaptive_color: true
name: Upload
y_axis: secondary
show_state: true
height: 100
hours_to_show: 1
line_width: 2
points_per_hour: 600
show:
points: false
fill: fade
icon: false
name: false
labels: false
labels_secondary: false
type: 'custom:mini-graph-card'
entities:
- sensor.sds_max_download
- sensor.sds_avg_download
- sensor.sds_task_speed_down_0
- sensor.sds_task_speed_up_0
type: 'custom:config-template-card'
variables:
- 'states[''sensor.sds_max_download''].state'
- 'states[''sensor.sds_avg_download''].state'
entity: sensor.sds_task_name_0
hold_action:
action: none
show_name: false
show_state: true
styles:
card:
- padding-left: 10px
- padding-right: 10px
custom_fields:
bar:
- filter: opacity(100%)
- overflow: unset
- margin-left: '-51%'
- width: 105%
graph:
- filter: opacity(100%)
- overflow: unset
state:
- color: var(--cyanish)
grid:
- grid-template-areas: '"s" "graph" "bar'
- grid-template-columns: 1fr
- grid-template-rows: 1fr 1fr
type: 'custom:button-card'
conditions:
- entity: sensor.sds_task_id_0
state_not: '0'
type: conditional
I also created entire view, showing at a glance status of all download slots (more like in traditional clients), one per row:
This view uses following elements:
- multiple-entity-row
- config-template-card
- bar-card
- mini-graph-card
- layout-card
Here is the complete code for this view (should be used in panel mode):
cards:
- card:
entities:
- entities:
- entity: sensor.sds_task_speed_down_0
name: Speed
- entity: sensor.sds_task_status_0
name: Status
- entity: sensor.sds_task_size_0
name: Size
- entity: sensor.sds_task_completed_0
name: '%'
- entity: sensor.sds_task_size_downloaded_0
name: Downloaded
entity: sensor.sds_task_size_downloaded_0
icon: 'mdi:numeric-0-box'
name: '${vars[0]}'
show_state: false
state_color: true
type: 'custom:multiple-entity-row'
gridcol: 1 / 2
gridrow: 1 / 2
type: entities
entities:
- sensor.sds_tasks_list
type: 'custom:config-template-card'
variables:
- 'states[''sensor.sds_task_name_0''].state'
- direction: right
entities:
- entity: sensor.sds_task_completed_0
gridcol: 2 / 3
gridrow: 1 / 2
height: 35px
max: 100
min: 0
positions:
icon: 'off'
indicator: 'off'
minmax: 'off'
name: 'off'
target: 'off'
value: inside
severity:
- color: '#7b55d5'
from: 0
to: 25
- color: '#fc70f3'
from: 25
to: 50
- color: '#00b8fe'
from: 50
to: 75
- color: '#7cff73'
from: 75
to: 100
type: 'custom:bar-card'
- entities:
- color: var(--greenish)
entity: sensor.sds_task_speed_down_0
name: Download
state_adaptive_color: true
- color: var(--light-magenta)
entity: sensor.sds_task_speed_up_0
name: Upload
show_state: true
state_adaptive_color: true
y_axis: secondary
gridcol: 3 / 4
gridrow: 1 / 2
height: 150
hours_to_show: 1
line_width: 2
points_per_hour: 360
show:
fill: fade
icon: false
labels: false
labels_secondary: false
legend: false
name: false
points: false
state: false
type: 'custom:mini-graph-card'
- card:
entities:
- entities:
- entity: sensor.sds_task_speed_down_1
name: Speed
- entity: sensor.sds_task_status_1
name: Status
- entity: sensor.sds_task_size_1
name: Size
- entity: sensor.sds_task_completed_1
name: '%'
- entity: sensor.sds_task_size_downloaded_1
name: Downloaded
entity: sensor.sds_task_size_downloaded_1
icon: 'mdi:numeric-1-box'
name: '${vars[0]}'
show_state: false
state_color: true
type: 'custom:multiple-entity-row'
gridcol: 1 / 2
gridrow: 2 / 3
type: entities
entities:
- sensor.sds_tasks_list
type: 'custom:config-template-card'
variables:
- 'states[''sensor.sds_task_name_1''].state'
- direction: right
entities:
- entity: sensor.sds_task_completed_1
gridcol: 2 / 3
gridrow: 2 / 3
height: 35px
max: 100
min: 0
positions:
icon: 'off'
indicator: 'off'
minmax: 'off'
name: 'off'
target: 'off'
value: inside
severity:
- color: '#7b55d5'
from: 0
to: 25
- color: '#fc70f3'
from: 25
to: 50
- color: '#00b8fe'
from: 50
to: 75
- color: '#7cff73'
from: 75
to: 100
type: 'custom:bar-card'
- entities:
- color: var(--greenish)
entity: sensor.sds_task_speed_down_1
name: Download
state_adaptive_color: true
- color: var(--light-magenta)
entity: sensor.sds_task_speed_up_1
name: Upload
show_state: true
state_adaptive_color: true
y_axis: secondary
gridcol: 3 / 4
gridrow: 2 / 3
height: 150
hours_to_show: 1
line_width: 2
points_per_hour: 360
show:
fill: fade
icon: false
labels: false
labels_secondary: false
legend: false
name: false
points: false
state: false
type: 'custom:mini-graph-card'
- card:
entities:
- entities:
- entity: sensor.sds_task_speed_down_2
name: Speed
- entity: sensor.sds_task_status_2
name: Status
- entity: sensor.sds_task_size_2
name: Size
- entity: sensor.sds_task_completed_2
name: '%'
- entity: sensor.sds_task_size_downloaded_2
name: Downloaded
entity: sensor.sds_task_size_downloaded_2
icon: 'mdi:numeric-2-box'
name: '${vars[0]}'
show_state: false
state_color: true
type: 'custom:multiple-entity-row'
gridcol: 1 / 2
gridrow: 3 / 4
type: entities
entities:
- sensor.sds_tasks_list
type: 'custom:config-template-card'
variables:
- 'states[''sensor.sds_task_name_2''].state'
- direction: right
entities:
- entity: sensor.sds_task_completed_2
gridcol: 2 / 3
gridrow: 3 / 4
height: 35px
max: 100
min: 0
positions:
icon: 'off'
indicator: 'off'
minmax: 'off'
name: 'off'
target: 'off'
value: inside
severity:
- color: '#7b55d5'
from: 0
to: 25
- color: '#fc70f3'
from: 25
to: 50
- color: '#00b8fe'
from: 50
to: 75
- color: '#7cff73'
from: 75
to: 100
type: 'custom:bar-card'
- entities:
- color: var(--greenish)
entity: sensor.sds_task_speed_down_2
name: Download
state_adaptive_color: true
- color: var(--light-magenta)
entity: sensor.sds_task_speed_up_2
name: Upload
show_state: true
state_adaptive_color: true
y_axis: secondary
gridcol: 3 / 4
gridrow: 3 / 4
height: 150
hours_to_show: 1
line_width: 2
points_per_hour: 360
show:
fill: fade
icon: false
labels: false
labels_secondary: false
legend: false
name: false
points: false
state: false
type: 'custom:mini-graph-card'
- card:
entities:
- entities:
- entity: sensor.sds_task_speed_down_3
name: Speed
- entity: sensor.sds_task_status_3
name: Status
- entity: sensor.sds_task_size_3
name: Size
- entity: sensor.sds_task_completed_3
name: '%'
- entity: sensor.sds_task_size_downloaded_3
name: Downloaded
entity: sensor.sds_task_size_downloaded_3
icon: 'mdi:numeric-3-box'
name: '${vars[0]}'
show_state: false
state_color: true
type: 'custom:multiple-entity-row'
gridcol: 1 / 2
gridrow: 4 / 5
type: entities
entities:
- sensor.sds_tasks_list
type: 'custom:config-template-card'
variables:
- 'states[''sensor.sds_task_name_3''].state'
- direction: right
entities:
- entity: sensor.sds_task_completed_3
gridcol: 2 / 3
gridrow: 4 / 5
height: 35px
max: 100
min: 0
positions:
icon: 'off'
indicator: 'off'
minmax: 'off'
name: 'off'
target: 'off'
value: inside
severity:
- color: '#7b55d5'
from: 0
to: 25
- color: '#fc70f3'
from: 25
to: 50
- color: '#00b8fe'
from: 50
to: 75
- color: '#7cff73'
from: 75
to: 100
type: 'custom:bar-card'
- entities:
- color: var(--greenish)
entity: sensor.sds_task_speed_down_3
name: Download
state_adaptive_color: true
- color: var(--light-magenta)
entity: sensor.sds_task_speed_up_3
name: Upload
show_state: true
state_adaptive_color: true
y_axis: secondary
gridcol: 3 / 4
gridrow: 4 / 5
height: 150
hours_to_show: 1
line_width: 2
points_per_hour: 360
show:
fill: fade
icon: false
labels: false
labels_secondary: false
legend: false
name: false
points: false
state: false
type: 'custom:mini-graph-card'
- card:
entities:
- entities:
- entity: sensor.sds_task_speed_down_4
name: Speed
- entity: sensor.sds_task_status_4
name: Status
- entity: sensor.sds_task_size_4
name: Size
- entity: sensor.sds_task_completed_4
name: '%'
- entity: sensor.sds_task_size_downloaded_4
name: Downloaded
entity: sensor.sds_task_size_downloaded_4
icon: 'mdi:numeric-4-box'
name: '${vars[0]}'
show_state: false
state_color: true
type: 'custom:multiple-entity-row'
gridcol: 1 / 2
gridrow: 5 / 6
type: entities
entities:
- sensor.sds_tasks_list
type: 'custom:config-template-card'
variables:
- 'states[''sensor.sds_task_name_4''].state'
- direction: right
entities:
- entity: sensor.sds_task_completed_4
gridcol: 2 / 3
gridrow: 5 / 6
height: 35px
max: 100
min: 0
positions:
icon: 'off'
indicator: 'off'
minmax: 'off'
name: 'off'
target: 'off'
value: inside
severity:
- color: '#7b55d5'
from: 0
to: 25
- color: '#fc70f3'
from: 25
to: 50
- color: '#00b8fe'
from: 50
to: 75
- color: '#7cff73'
from: 75
to: 100
type: 'custom:bar-card'
- entities:
- color: var(--greenish)
entity: sensor.sds_task_speed_down_4
name: Download
state_adaptive_color: true
- color: var(--light-magenta)
entity: sensor.sds_task_speed_up_4
name: Upload
show_state: true
state_adaptive_color: true
y_axis: secondary
gridcol: 3 / 4
gridrow: 5 / 6
height: 150
hours_to_show: 1
line_width: 2
points_per_hour: 360
show:
fill: fade
icon: false
labels: false
labels_secondary: false
legend: false
name: false
points: false
state: false
type: 'custom:mini-graph-card'
- card:
entities:
- entities:
- entity: sensor.sds_task_speed_down_5
name: Speed
- entity: sensor.sds_task_status_5
name: Status
- entity: sensor.sds_task_size_5
name: Size
- entity: sensor.sds_task_completed_5
name: '%'
- entity: sensor.sds_task_size_downloaded_5
name: Downloaded
entity: sensor.sds_task_size_downloaded_5
icon: 'mdi:numeric-5-box'
name: '${vars[0]}'
show_state: false
state_color: true
type: 'custom:multiple-entity-row'
gridcol: 1 / 2
gridrow: 6 / 7
type: entities
entities:
- sensor.sds_tasks_list
type: 'custom:config-template-card'
variables:
- 'states[''sensor.sds_task_name_5''].state'
- direction: right
entities:
- entity: sensor.sds_task_completed_5
gridcol: 2 / 3
gridrow: 6 / 7
height: 35px
max: 100
min: 0
positions:
icon: 'off'
indicator: 'off'
minmax: 'off'
name: 'off'
target: 'off'
value: inside
severity:
- color: '#7b55d5'
from: 0
to: 25
- color: '#fc70f3'
from: 25
to: 50
- color: '#00b8fe'
from: 50
to: 75
- color: '#7cff73'
from: 75
to: 100
type: 'custom:bar-card'
- entities:
- color: var(--greenish)
entity: sensor.sds_task_speed_down_5
name: Download
state_adaptive_color: true
- color: var(--light-magenta)
entity: sensor.sds_task_speed_up_5
name: Upload
show_state: true
state_adaptive_color: true
y_axis: secondary
gridcol: 3 / 4
gridrow: 6 / 7
height: 150
hours_to_show: 1
line_width: 2
points_per_hour: 360
show:
fill: fade
icon: false
labels: false
labels_secondary: false
legend: false
name: false
points: false
state: false
type: 'custom:mini-graph-card'
- card:
entities:
- entities:
- entity: sensor.sds_task_speed_down_6
name: Speed
- entity: sensor.sds_task_status_6
name: Status
- entity: sensor.sds_task_size_6
name: Size
- entity: sensor.sds_task_completed_6
name: '%'
- entity: sensor.sds_task_size_downloaded_6
name: Downloaded
entity: sensor.sds_task_size_downloaded_6
icon: 'mdi:numeric-6-box'
name: '${vars[0]}'
show_state: false
state_color: true
type: 'custom:multiple-entity-row'
gridcol: 1 / 2
gridrow: 7 / 8
type: entities
entities:
- sensor.sds_tasks_list
type: 'custom:config-template-card'
variables:
- 'states[''sensor.sds_task_name_6''].state'
- direction: right
entities:
- entity: sensor.sds_task_completed_6
gridcol: 2 / 3
gridrow: 7 / 8
height: 35px
max: 100
min: 0
positions:
icon: 'off'
indicator: 'off'
minmax: 'off'
name: 'off'
target: 'off'
value: inside
severity:
- color: '#7b55d5'
from: 0
to: 25
- color: '#fc70f3'
from: 25
to: 50
- color: '#00b8fe'
from: 50
to: 75
- color: '#7cff73'
from: 75
to: 100
type: 'custom:bar-card'
- entities:
- color: var(--greenish)
entity: sensor.sds_task_speed_down_6
name: Download
state_adaptive_color: true
- color: var(--light-magenta)
entity: sensor.sds_task_speed_up_6
name: Upload
show_state: true
state_adaptive_color: true
y_axis: secondary
gridcol: 3 / 4
gridrow: 7 / 8
height: 150
hours_to_show: 1
line_width: 2
points_per_hour: 360
show:
fill: fade
icon: false
labels: false
labels_secondary: false
legend: false
name: false
points: false
state: false
type: 'custom:mini-graph-card'
- card:
entities:
- entities:
- entity: sensor.sds_task_speed_down_7
name: Speed
- entity: sensor.sds_task_status_7
name: Status
- entity: sensor.sds_task_size_7
name: Size
- entity: sensor.sds_task_completed_7
name: '%'
- entity: sensor.sds_task_size_downloaded_7
name: Downloaded
entity: sensor.sds_task_size_downloaded_7
icon: 'mdi:numeric-7-box'
name: '${vars[0]}'
show_state: false
state_color: true
type: 'custom:multiple-entity-row'
gridcol: 1 / 2
gridrow: 8 / 9
type: entities
entities:
- sensor.sds_tasks_list
type: 'custom:config-template-card'
variables:
- 'states[''sensor.sds_task_name_7''].state'
- direction: right
entities:
- entity: sensor.sds_task_completed_7
gridcol: 2 / 3
gridrow: 8 / 9
height: 35px
max: 100
min: 0
positions:
icon: 'off'
indicator: 'off'
minmax: 'off'
name: 'off'
target: 'off'
value: inside
severity:
- color: '#7b55d5'
from: 0
to: 25
- color: '#fc70f3'
from: 25
to: 50
- color: '#00b8fe'
from: 50
to: 75
- color: '#7cff73'
from: 75
to: 100
type: 'custom:bar-card'
- entities:
- color: var(--greenish)
entity: sensor.sds_task_speed_down_7
name: Download
state_adaptive_color: true
- color: var(--light-magenta)
entity: sensor.sds_task_speed_up_7
name: Upload
show_state: true
state_adaptive_color: true
y_axis: secondary
gridcol: 3 / 4
gridrow: 8 / 9
height: 150
hours_to_show: 1
line_width: 2
points_per_hour: 360
show:
fill: fade
icon: false
labels: false
labels_secondary: false
legend: false
name: false
points: false
state: false
type: 'custom:mini-graph-card'
- card:
entities:
- entities:
- entity: sensor.sds_task_speed_down_8
name: Speed
- entity: sensor.sds_task_status_8
name: Status
- entity: sensor.sds_task_size_8
name: Size
- entity: sensor.sds_task_completed_8
name: '%'
- entity: sensor.sds_task_size_downloaded_8
name: Downloaded
entity: sensor.sds_task_size_downloaded_8
icon: 'mdi:numeric-8-box'
name: '${vars[0]}'
show_state: false
state_color: true
type: 'custom:multiple-entity-row'
gridcol: 1 / 2
gridrow: 9 / 10
type: entities
entities:
- sensor.sds_tasks_list
type: 'custom:config-template-card'
variables:
- 'states[''sensor.sds_task_name_8''].state'
- direction: right
entities:
- entity: sensor.sds_task_completed_8
gridcol: 2 / 3
gridrow: 9 / 10
height: 35px
max: 100
min: 0
positions:
icon: 'off'
indicator: 'off'
minmax: 'off'
name: 'off'
target: 'off'
value: inside
severity:
- color: '#7b55d5'
from: 0
to: 25
- color: '#fc70f3'
from: 25
to: 50
- color: '#00b8fe'
from: 50
to: 75
- color: '#7cff73'
from: 75
to: 100
type: 'custom:bar-card'
- entities:
- color: var(--greenish)
entity: sensor.sds_task_speed_down_8
name: Download
state_adaptive_color: true
- color: var(--light-magenta)
entity: sensor.sds_task_speed_up_8
name: Upload
show_state: true
state_adaptive_color: true
y_axis: secondary
gridcol: 3 / 4
gridrow: 9 / 10
height: 150
hours_to_show: 1
line_width: 2
points_per_hour: 360
show:
fill: fade
icon: false
labels: false
labels_secondary: false
legend: false
name: false
points: false
state: false
type: 'custom:mini-graph-card'
- card:
entities:
- entities:
- entity: sensor.sds_task_speed_down_9
name: Speed
- entity: sensor.sds_task_status_9
name: Status
- entity: sensor.sds_task_size_9
name: Size
- entity: sensor.sds_task_completed_9
name: '%'
- entity: sensor.sds_task_size_downloaded_9
name: Downloaded
entity: sensor.sds_task_size_downloaded_9
icon: 'mdi:numeric-9-box'
name: '${vars[0]}'
show_state: false
state_color: true
type: 'custom:multiple-entity-row'
gridcol: 1 / 2
gridrow: 10 / 11
type: entities
entities:
- sensor.sds_tasks_list
type: 'custom:config-template-card'
variables:
- 'states[''sensor.sds_task_name_9''].state'
- direction: right
entities:
- entity: sensor.sds_task_completed_9
gridcol: 2 / 3
gridrow: 10 / 11
height: 35px
max: 100
min: 0
positions:
icon: 'off'
indicator: 'off'
minmax: 'off'
name: 'off'
target: 'off'
value: inside
severity:
- color: '#7b55d5'
from: 0
to: 25
- color: '#fc70f3'
from: 25
to: 50
- color: '#00b8fe'
from: 50
to: 75
- color: '#7cff73'
from: 75
to: 100
type: 'custom:bar-card'
- entities:
- color: var(--greenish)
entity: sensor.sds_task_speed_down_9
name: Download
state_adaptive_color: true
- color: var(--light-magenta)
entity: sensor.sds_task_speed_up_9
name: Upload
show_state: true
state_adaptive_color: true
y_axis: secondary
gridcol: 3 / 4
gridrow: 10 / 11
height: 150
hours_to_show: 1
line_width: 2
points_per_hour: 360
show:
fill: fade
icon: false
labels: false
labels_secondary: false
legend: false
name: false
points: false
state: false
type: 'custom:mini-graph-card'
gridcols: 75% auto 170px
gridrows: 80px 80px 80px 80px 80px 80px 80px 80px 80px 80px 80px
layout: grid
type: 'custom:layout-card'
And the final word… I tested this only with torrent downloads, but given the nature of SDS API I’d expect that it should work equally fine with any supported by SDS transfer protocol (BT, FTP/HTTP, NZB, RSS).
Happy downloading!