- PVSM.RU - https://www.pvsm.ru -
Привет!
Наступило лето и очень многие уезжают из города. Кто-то на время отпуска, а кто-то и на все лето (если работа позволяет). Но одна из главных проблем за городом (для всех людей так или иначе связанных с IT) — отсутствие нормального проводного быстрого интернета. Но это частично решается благодаря такой прекрасной технологии как LTE.
В моем регионе крупных провайдеров LTE всего два: Мегафон и Yota. Мегафон существенно дешевле, но у него есть одна крайне неприятная особенность: ограничение в 20гб трафика в месяц даже на максимальном тарифе.
Поэтому, выбор оператора, на мой взгляд, очевиден. Но все же платить за 20 мегабит в два раза больше чем за 100 дома — сомнительное удовольствие. Но при этом, в отличии от других операторов, Yota позволяет в в любой момент бесплатно изменять текущий тариф в личном кабинете. Нужна скорость — выкручиваем ползунок на максимум. Нет? Тогда можно снизить скорость и платить меньше. Притом тарификация, судя по всему, посекундная. Ну как тут можно удержаться и не автоматизировать этот процесс?
На хабре уже были статьи (раз [1], два [2]), описывающие попытки йотоводов-автоматизаторов. Однако, по определенным причинам, их творения мне не подошли и пришлось написать свой, довольно кардинально отличающийся, велосипед.
Всех йотоводов и автоматизаторов прошу под кат.
А начнем мы, пожалуй, с разбора причин, по которым мне не подошли чужие велосипеды. Особо нетерпеливые / материально заинтересованные могут сразу перейти к разделу, описывающему реализацию.
Вариант [1]linx56 [3] мне не подошел ну совсем никак, потому как он работает phantomjs, для работы которого нужно довольно нехилое железо (которым Raspberry PI не является). Да и даже если я поставлю это на свой основной компьютер и оставлю его работать круглосуточно, забив в cron расписание по которому нужно отключать интернет, то я получу счет за электричество больше, чем сэкономлю все равно не получу нормального результата, потому как интернет используется крайне ненормировано (при том не только мной, но и членами семьи, для которых главное чтобы «Просто работало»).
Второй вариант [2] от bambrman [4] уже лучше хотя бы тем, что использует curl вместо phantomjs. Но по функциональности остается на том же уровне.
По итогам рассмотрения вышеперечисленных вариантов было решено сделать свой велосипед, в основе которого лежало бы не расписание (или руки человека), а текущая скорость, потребляемая всеми устройствами в локальной сети.
В основе всего лежит Raspberry Pi, на котором крутится демон, написанный на Python. Он каждые n секунд (задается в конфиге, котрый будет приведен в следующем разделе) подключается по SSH к главному домашнему роутеру (TP-LINK WDR4300 перепрошитому на OpenWrt) и при помощи команды ifconfig стягивает статистику нужного интерфейса.
После этого он считает среднюю скорость за промежуток между последним и предыдущим замером и отправляет ее в модуль, который отвечает за переключение тарифов в соответствии с текущей скоростью и настройками конфига. Чтобы было понятнее, приведу здесь его часть:
modes: {
0: 320,
290: 512,
495: 768,
700: 1.0,
900: 2.1,
1900: 3.1,
2900: 4.1,
3900: 6.5,
6500: 8.0,
8000: 10.0,
10000: 15.0,
14800: 20.0
}
Как вы видите, в качестве индекса словаря выступает скорость в килобитах. Я называю это режимом. В качестве значения — тариф йоты, который нужно установить для данного режима. Попробую объяснить на примере:
По результатам замера текущей скорости у нас получилось, скажем, 1530 килобит. Округляем в меньшую сторону до ближайшего режима. Получается, что эта скорость соответствует режиму 900, то есть тарифу 2.1 мегабит.
После того, как режим вычислен он сравнивается с установленным в данный момент режимом. Тут есть 3 варианта развития событий:
В этом случае цикл просто продолжится
В этом случае запускается процесс апгрейда. По сути, текущий тариф просто меняется на указанный в режиме.
Но и тут есть одна особенность. Дело в том, что в конфиге есть такой параметр как:
speed_increase_step: 1
Он указывает на размер шага апгрейда между тарифами. То есть обычно скорость с предыдущего тарифа может переключиться только на следующий (потому как например при тарифе в 10 мегабит невозможно достигнуть скорости в 14800 для переключения сразу на 20. То есть между 10 и 20 все равно должен быть 15). Иногда это не очень удобно. Попробую объяснить на примере:
Вы не пользовались интернетом некоторое время, а потом пришли и сразу включили поток с YouTube в 720-1080p. Соответственно, скорости в 320 килобит, которая была установлена в ваше отсутствие для этого явно не хватает. И тут 2 варианта: либо демон будет постепено повышать тариф (320 — 512 — 768 — 1.0 и т.д.) или же он увеличит его с запасом скажем, до 1 мегабита, а затем уменьшит до нужной скорости (см. механизм даунгрейда).
Но в этом случае есть и определенные минусы. Например, если вы/ваше устройство грузить будете что-то маленькое и легкое (вроде RSS ленты например). На это у него уйдет всего пара секунд. Да и 320 килобит будет достаточно. Но тариф то все равно подскочит до мегабита и будет висеть на этом уровне до тех пор пока его не выполнится даунгрейд.
Особенности:
В этом случае запускается механизм даунгрейда. Он сохраняет текущую статистику трафика (не скорости) роутера (вместе с таймстемпом создания), а затем создает задачу на исполнение даунгрейда через определенное время. Это время задается в минутах в параметре:
hold_high_speed_time: 3
Если за этот промежуток времени скорость поднимется до текущего режима (или превысит его), то даунгрейд будет отменен. В дальнейшем, если скорость опять упадет, он снова будет запущен.
Если же скорость за отведенный промежуток времени так и не восстановится, то даунгрейд будет выполнен. А если быть точнее произойдет следующее:
Как и при запуске даунгрейда, будет запрошена текущая статистика трафика, а затем с помощью статистики сохраненной при запуске даунгрейда будет высчитана средняя скорость. Дальше, на основе этой скорости, высчитывается соответствующий режим и тариф меняется на соответствующий.
Для чего вообще нужен весь этот механизм и почему по умолчанию именно 3 минуты? Объясню, опять же, на примере:
Вы смотрите ролик на YouTube. Он небольшой. Всего пара минут. И пока он скачивался скорость подскочила до 8 мегабит. И вот вы досмотрели ролик и переходите к следующему. Если бы не было этой задержки в механизме, то демон бы уже понизил скорость и при загрузке второго ролика ему пришлось бы снова поднимать скорость.То есть вам придется дожидаться пока скорость вновь будет повышена. В то же время это еще и нагружает и так не шибко стабильный ЛК Yota. Да и согласитесь, за 1 минуту (ну пусть за 2) вы много не сэкономите.
С другой стороны перегибать палку с увеличением задержки тоже не надо. Чем больше значение — тем меньше экономия.
По сути, основной функционал на этом завершается. Правда, есть еще кое-что, что, возможно, кого-нибудь да заинтересует:
Писалось, как и все остальное, в первую очередь для себя. Но, честно честно говоря, так и не пригодилось, потому как генерирует слишком много спама. Но может кому понравится ;)
Включается это дело все там же, в конфиге:
pb_enabled: true
pb_api: v13WA7HYfwj99gUz8rwvK2m7eLN1uheVxZujAgP8gn2su
pb_devices: [
ujAgP8gn2sasFDsgsWhxs,
ujAgP8gn2mkasnuH2Gtga
]
Как видите, здесь все довольно просто. pb_enabled принимает значения true/false. Назначение очевидно.
pb_api — ваш ключ со страницы www.pushbullet.com/account [5]
pb_devices — список идентификаторов устройств, на которые рассылаются уведомления. Взять можно тут: api.pushbullet.com/v2/devices [6]. При входе вас попросят авторизоваться: просто введите ключ api в поле логина. Полное описание метода тут: docs.pushbullet.com/v2/devices/ [7]
Ну что же. Дело сделано — сообщение описание доставлено. Теперь можно и код показать рассказать, как все это дело готовить.
2014-07-06 14:16:01,805 [INFO] yota | Initializing
2014-07-06 14:16:11,497 [INFO] yota.web | CURRENT TARIFF: 512
2014-07-06 14:16:11,712 [INFO] yota | Initialised
2014-07-06 14:16:11,718 [INFO] yota | Starting
2014-07-06 14:16:16,016 [DEBUG] yota.current_speed_provider | Current speed: RX: 5 TX: 9. Summary: 14, Time: 3
2014-07-06 14:16:17,262 [INFO] yota.speed_control | Downgrade started: 2014-07-06 14:19:16.022307
2014-07-06 14:16:18,315 [DEBUG] yota.current_speed_provider | Current speed: RX: 7 TX: 19. Summary: 26, Time: 2
2014-07-06 14:16:20,575 [DEBUG] yota.current_speed_provider | Current speed: RX: 12 TX: 20. Summary: 32, Time: 2
Вот, собственно, и все. Надеюсь, у Yota есть совесть и они не будут «вставлять палки в колеса», как это обычно любят делать в России. В конце концов, людей, способных развернуть у себя такое — не так много. А если учесть, что мало кто из них пользуется Yota, то так и вообще мелочь в масштабах компании.
Традиционно, как и все выходцы песочницы, прошу не очень сильно кидаться помидорами. Ну или посвежее выбрать что-ли :)
Автор: rdvlip
Источник [9]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/raspberry-pi/64294
Ссылки в тексте:
[1] раз: http://habrahabr.ru/post/166721/
[2] два: http://habrahabr.ru/post/176817/
[3] linx56: http://habrahabr.ru/users/linx56/
[4] bambrman: http://habrahabr.ru/users/bambrman/
[5] www.pushbullet.com/account: https://www.pushbullet.com/account
[6] api.pushbullet.com/v2/devices: https://api.pushbullet.com/v2/devices
[7] docs.pushbullet.com/v2/devices/: http://docs.pushbullet.com/v2/devices/
[8] отсюда: https://bitbucket.org/Rdvlip/yota-speed-controller/get/master.zip
[9] Источник: http://habrahabr.ru/post/228959/
Нажмите здесь для печати.