Авторегулирование скорости Transmission

в 14:34, , рубрики: bash, diy или сделай сам, Raspberry Pi, transmission, Гаджеты. Устройства для гиков, метки: , ,

После приобретения RPi, установки кучи всяких вкусностей, понял, что надо что-то делать со скоростью работы торрент-трекера. Когда он качает на полной скорости — быстро качаются треки, но невозможно нормально пользоваться интернетом. Приходится постоянно лезть в веб интерфейс и резать скорость. Если качает медленно — это напрягает длиииительностью процесса. Все это порядком поднадоело, поэтому было решено автоматизировать этот процесс
image

Как известно, transmission имеет функцию «альтернативная скорость» и запуск ее по расписанию. По началу меня это устраивало, но все-таки можно же качать не только ночью по полной, но и все то время, когда никто не пользуется интернетом.

Изменяем скорость через файл конфигурации

По-началу все мои мысли пали на файл конфигурации transmission

/etc/transmission-daemon/settings.json

Необходимо учитывать, что все изменения в этом файле вступят в силу только, если сначала остановить работу треккера
/etc/init.d/transmission-daemon stop
внести изменения и запустить
/etc/init.d/transmission-daemon stop
Параметры, которые меня интересовали были:

speed-limit-down
speed-limit-up

Ограничение скорости закачки и отдачи соответственно.
Значения этих параметров необходимо изменить в зависимости есть ли кто-нибудь сейчас в сети.

Есть кто в сети?

Для определения наличия кого-либо в сети я воспользовался обычным пингом. Так как все устройства (ПК, ноутбук, моб. телефон) подключаются к роутеру с DHCP, то IP адреса устройствам присваиваются последовательно, а значит перебирать будем с помощью цикла.

Так родился скрипт версии 1.0

#!/bin/bash 

#v1.0
#локальный адрес
ip=192.168.1.
#количество возможных машин в сети
n=3
#с какого адреса начинать пинговать машины
i0=2
i=$i0
#ограничение скорости. 0 - никого нет в сети, скорость на максимум; 1- есть кто-то в сети, скорость ограничена
speedlimit=0
#скорость на отдачу и прием, если никого нет
upspeed=50
downspeed=500
#скорость на отдачу и прием, если кто-то есть в сети
upspeedlim=10
downspeedlim=10

let end=n+i
result=0

#бесконечный цикл
while [ 1 = 1 ]; do
	#цикл пинга локальных машин от i до последней машины end
	until [ "$i" -eq "$end" ];do
		result=$(ping -c 1 $ip$i | tail -2 | head -1 | awk '{print $4}')
		#если в результате пинга кто-то был обнаружен, то цикл останавливается и .. см. if
		if [ "$result" = 1 ]; then
			break
		fi
		let i++
	done
	#если результат пинга=1 (кто-то в сети) и в то же время ограничение на скорость не стоит, то включаем его
	#иначе, если результат пинга=0 (нет никого) и в то же время ограничение на скорость стоит, то выключаем его
	if [ "$result" = 1 ]; then
		if [ $speedlimit = 0 ]; then
			sudo /etc/init.d/transmission-daemon stop
			#изменяем скорость закачки
			sudo perl -pi~ -e 's/"speed-limit-down":(.+)/"speed-limit-down": '$downspeedlim',/' /etc/transmission-daemon/settings.json
			#изменяем скорость отдачи
                        		sudo perl -pi~ -e 's/"speed-limit-up":(.+)/"speed-limit-up": '$upspeedlim',/' /etc/transmission-daemon/settings.json
			sudo /etc/init.d/transmission-daemon start
			speedlimit=1
		fi
	fi
	if [ "$result" = 0 ]; then
		if [ $speedlimit = 1 ]; then
			sudo /etc/init.d/transmission-daemon stop
                        		#изменяем скорость закачки
                        		sudo perl -pi~ -e 's/"speed-limit-down":(.+)/"speed-limit-down": '$downspeed',/' /etc/transmission-daemon/settings.json
                      		#изменяем скорость отдачи
                        		sudo perl -pi~ -e 's/"speed-limit-up":(.+)/"speed-limit-up": '$upspeed',/' /etc/transmission-daemon/settings.json
			sudo /etc/init.d/transmission-daemon start
			speedlimit=0
		fi
	fi
#задержка 30 секунд
sleep 30
i=$i0

done

Он конечно не супер, но работает.

Совершенствуемся дальше

Дальше я начал рассуждать о том, что перезагружать треккер как-то уныло, веб интерфейс ведь все это делает без перезагрузок, а чем я, собственно, хуже.
Благодаря товарищу andbas было выбрано направление в сторону утилиты transmission-remote. Расписывать и хвалить ее не буду, вкратце скажу, что с ее помощью подключаясь к веб-интерфейсу можно управлять треккером. Единственным минусом я бы назвал то, что в скрипте приходится в явном виде указывать логин и пароль, хотя это, возможно, можно изменить.
Для некоторого упрощения я решил использовать функцию «альтернативная скорость» или далее по тексту «черепашка», потому что в веб-интерфейсе иконка изображена как раз в виде черепашки и интуитивно намекает что с ее помощью мы будем «тормозить».
Значит так, если кто-то есть в сети, то включаем черепашку, нет — выключаем. Если мы в сети и хотим принудительно включить закачку на полную, то делается достаточно просто — клик по черепашке, вместо входа в настройки и изменения скорости.

Перерождение, скрипт версии 1.1
#!/bin/bash 
#ver.1.1

#transmission ip:port
tip=192.168.1.100:9091
#login
login=*
#password
password=*

#локальный адрес
ip=192.168.1.
#количество возможных машин в сети
n=3
#с какого адреса начинать пинговать машины
i0=2
i=$i0
let end=n+i

result=0
#флаг однократного выполнения при старте
start=1
#флаг ограничения скорости
speedlimit=0

#бесконечный цикл
while [ 1 = 1 ]; do
	#цикл пинга локальных машин от i до последней машины end
	until [ "$i" -eq "$end" ];do
		result=$(ping -c 1 $ip$i | tail -2 | head -1 | awk '{print $4}')
		#если в результате пинга кто-то был обнаружен, то цикл останавливается и .. см. if
		if [ "$result" = 1 ]; then
			break
		fi
		let i=$i+1
	done
	#если результат пинга=1 (кто-то в сети) и в то же время ограничение на скорость не стоит, то включаем его
	#иначе, если результат пинга=0 (нет никого) и в то же время ограничение на скорость стоит, то выключаем его
	if [ "$result" = 1 ]; then
		if [ $start = 1 ]; then
			#однократно при старте
			#устанавливаем черепашку, устанавливаем флаг ограничения скорости
			transmission-remote $tip -n $login:$password -as
			speedlimit=1
			start=0
		else
			if [ $speedlimit = 0 ]; then
				#устанавливаем черепашку, устанавливаем флаг ограничения 
				transmission-remote $tip -n $login:$password -as
 				speedlimit=1
			fi
		fi
	fi
	if [ "$result" = 0 ]; then
		if [ $start = 1 ]; then
			#однократно при старте
			#сбрасываем черепашку, сбрасываем флаг ограничения скорости
			transmission-remote $tip -n $login:$password -AS
			speedlimit=0
			start=0			
		else
			if [ $speedlimit = 1 ]; then
				#сбрасываем черепашку, сбрасываем флаг ограничения
 				transmission-remote $tip -n $login:$password -AS
				speedlimit=0
			fi
		fi
	fi
#задержка 30 секунд
sleep 30
i=$i0
done

Опять двадцать пять. Когда кто-то в сети — качаем медленно, канал не забиваем, никому не мешаем, но винчестер то работает: греется, потребляет энергию. С моими настройками (10кб/с закачка на черепашке) это выглядит не совсем экономично, уж лучше пусть ничего не качается вовсе и винчестер не гудит.

Ставлю точку (возможно временно), скрипт версии 1.2
#!/bin/bash 

#v1.2 

#transmission ip:port
tip=192.168.1.100:9091
#login
login=login
#password
password=pass

#локальный адрес
ip=192.168.1.
#количество возможных машин в сети
n=3
#с какого адреса начинать пинговать машины
i0=2
i=$i0
let end=n+i
result=0
#флаг однократного выполнения при старте
start=1
#флаг ограничения скорости
speedlimit=0

#бесконечный цикл
while [ 1 = 1 ]; do
	#цикл пинга локальных машин от i до последней машины end
	until [ "$i" -eq "$end" ];do
		result=$(ping -c 1 $ip$i | tail -2 | head -1 | awk '{print $4}')
		#если в результате пинга кто-то был обнаружен, то цикл останавливается и см далее
		if [ "$result" = 1 ]; then
			break
		fi
		let i++
	done
	#если результат пинга=1 (кто-то в сети) и в то же время ограничение на скорость не стоит, то включаем его
	#иначе, если результат пинга=0 (нет никого) и в то же время ограничение на скорость стоит, то выключаем его
	if [ "$result" = 1 ]; then
		if [ $start = 1 ]; then
			#однократно при старте
			#останавливаем все треки, устанавливаем флаг ограничения скорости
			transmission-remote $tip -n $login:$password -t all -S
			speedlimit=1
			#сбрасываем флаг однократного выполнения
			start=0
		else
			if [ $speedlimit = 0 ]; then
				#останавливаем все треки, устанавливаем флаг ограничения скорости
 				transmission-remote $tip -n $login:$password  -t all -S
				speedlimit=1
			fi
		fi
	fi
	if [ "$result" = 0 ]; then
		if [ $start = 1 ]; then
			#однократно при старте
			#запускаем все треки, сбрасываем флаг ограничения скорости
			transmission-remote $tip -n $login:$password -t all -s
			speedlimit=0
			#сбрасываем флаг однократного выполнения
			start=0			
		else
			if [ $speedlimit = 1 ]; then
				#запускаем все треки, сбрасываем флаг ограничения скорости
				transmission-remote $tip -n $login:$password -t all -s
				speedlimit=0
			fi
		fi
	fi
#задержка 30 секунд
sleep 30
i=$i0
done

Теперь вроде бы все устраивает…

Напоследок автозагрузка скрипта

Совсем забыл, ведь скрипт должен стартовать вместе с системой. Поэтому было решено сделать демон.

#! /bin/sh
### BEGIN INIT INFO
# Provides:          tsl
# Required-Start:    $remote_fs $syslog $all
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Example initscript
# Description:       This file should be used to construct scripts to be
#                    placed in /etc/init.d.
### END INIT INFO


case "$1" in

  start)
	start-stop-daemon -Sbvx /usr/bin/tsl
  ;;
  stop)
	sudo pkill tsl
  ;;
  *)
     echo "Usage: /etc/init.d/tsl-deamon {start|stop}"
     ;;
esac
:

Для начинающих линуксоидов: скрипт необходимо сделать запускающимся
sudo chmod +x <bash_script_name>
и положить в папку usr/bin
Демон положить в etc/ini.d и для автозапуска прописать
update-rc.d <daemon_name> defaults
для удаления из автозагрузки
update-rc.d -f <daemon_name> remove

*в моем случае имя скрипта tsl (transmission speed limiter), если собираетесь его менять, то и в демоне также необходимо поменять

Эпилог

Все описано не детально, это и так понятно. Также должны быть ошибки, недочеты и прочее. Сам я начинающий линуксоид (спасибо малине за это), поэтому в некоторых местах возможны глупости…
А в общем, думаю, идея ясна. На базе данного шаблона можно сделать двух, трех… позиционное регулирование скорости закачки/откачки, в зависимости от количества пользователей в сети например (если 1 юзер — одна скорость, 2 — другая и т.д.). Также если у нас айпи идет не по порядку, то можно использовать массив из адресов и в цикле перебирать элементы массива.

Автор: outofspace

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js