Pull to refresh

Продолжаем оптимизировать затраты с Yota

Reading time 6 min
Views 36K
В данной статье речь пойдет об автоматизации управления тарифами YOTA с помощью curl, OpenWRT и MR-3020. Предложенные скрипты можно использовать и в иной *nix среде с установленной curl.


Пролог


Так получилось, что около месяца назад я стал счастливым (или не очень) обладателем LTE-модема YOTA. В связи с отсутствием других альтернатив приходится использовать оный в качестве основного домашнего источника доступа к глобальной паутине.

Для раздачи интернета по квартире (в связи с дороговизной Йотовских устройств) было решено использовать связку модем YOTA + TP-LINK MR-3020 с OpenWRT на борту. Выбор пал именно на MR-3020 как на компактный и самый дешевый роутер с наличием USB-порта и поддержкой OpenWRT.

На стоковый MR-3020 curl не станет, не хватит места. Если точнее, то нехватает места для libopenssll, там библиотека libcrypto весит больше 1 МБ. В данной ситуации самый простой выход — подгружать libopenssll в RAM после загрузки роутера, инструкция по установке внизу. Я использую дополнительно usb-хаб + usb-hdd, который примонтирован к rootfs, на hdd так же установлены minidlna, samba и transmission, соответствнно для закачки торрентов и просмотра их на ТВ и с проблемой нехватки места на сталкиваюсь.

Следует отметить, что настройка OpenWRT для работы с модемом YOTA весьма проста — необходимо лишь установить дополнительные пакеты для работы с USB и сетью, а так же добавить дополнительный сетевой интерфейс в настройках.

Автоматизация и OpenWRT


В тех случаях, когда есть возможность «безнаказанно» прыгать с тарифа на тариф вопросы автоматизации-оптимизации возникают сами собой. К тому же после прочтения статьи linx56 «автоматизационный зуд» (спасибо автору за термин) не давал покоя.

Задача заключалась в следующем — вместо установки предложенного linx56 скрипта на каждый домашний ПК необходимо «заставить» маршрутизатор самостоятельно переключать тарифы в зависимости от времени суток и дней недели, благо гарфик потребления интеренета представлялся достаточно опредленным. Вышеупомянтый кросс-платформенный Yota-скрипт не удовлетворял требованиям по причине того, что использует phantom.js, установка которого на стоковый MR-3020 c OpenWRT не представляется возможным.

Такм образом, созрела необходимость в написании скрипта без использования тяжеловестных headless-браузеров. Выход был найден практически сразу (по комментариям к вышеупомянутой статье) — было решено использовать утилиту curl для отправки запросов на сервер YOTA.

Первоначально curl был устанавлен на маршрутизатор:

opkg install curl

После этого необходимо было выяснить каким образом происходит общение браузера с сайтом Yota, а именно — какие запросы с какими параметрами.

C помощью FireBug первым был отловлен запрос на авторизацию в личном кабинете. Полученные результаты были отправлены curl'ом на сервер и… неудача — ошибка авторизации!!! Проверил параметры и значения — опять ошибка, и опять, и опять…

В результате выяснилось, что для авторизации и для установки параметров в личном кабинете сайт YOTA активно использует cookies. Благо curl отлично справляется с обработкой cookies — вопрос авторизации был решен:

curl -c cook.txt  -s -k -L -d "IDToken1=$1&IDToken2=$2&IDToken3=$2&goto=https%3A%2F%2Fmy.yota.ru%3A443%2Fselfcare%2FloginSuccess&gotoOnFail=https%3A%2F%2Fmy.yota.ru%3A443%2Fselfcare%2FloginError&old-token=&org=customer" https://login.yota.ru/UI/Login

Вот мы и в личном кабинете. Опять же используем FireBug для перехвата запроса на изменение тарифа. Полученные параметры и cookies отправляем на сервер и… опять неудача!!!

После анализа нескольких запросов заинтересовало значение одного из параметров передаваемых на сервер, а именно — «ProductID», каждый раз это значение было новым после изменения тарифа. Как удалось выяснить — значение ProductID возвращается сервером в коде страницы и изменяется каждый раз при смене тарифа. Сам же тариф — это параметр offerCode, принимающий значения от POS-MA14-0002 до POS-MA14-0022.

curl -b cook.txt  -s -k -L -d "product=$pr&offerCode=$OCODE&homeOfferCode=&areOffersAvailable=false&period=&status=custom&autoprolong=0&isSlot=false&resourceId=&currentDevice=1&username=&isDisablingAutoprolong=false" https://my.yota.ru/selfcare/devices/changeOffer

В итоге алгоритм выглядит следующим образом:

  1. Авторизируемся в личном кабинете;
  2. Переходим на страницу с «регулятором» скорости;
  3. Выделяем ProductID из полученной страницы;
  4. Устанавливаем новый тариф.

В результате изысканий родился небольшой скрипт, который можно получить тут.

Применение простое:
yota.sh <логин> <пароль> <скорость> 

Результат выполнения — установленный тариф (скорость) и количество оставшихся дней (часов) на тарифе.

С помощью crontab был настроен предполагаемый режим потребления интернета, а именно:
для рабочих дней:
  • включение скорости по утрам — во время сборов на работу;
  • выключение утром — когда уходишь на работу;
  • включение вечером — когда возвращаешься с работы;
  • выключение ночью — когда идешь спать;

для выходных дней — свой отдельный график с поздним временем утреннего включения :).

Прошло семь дней


Спустя неделю стало ясно, что предложенная методика смены тарифов по расписанию не совсем эффективна, если время ночного и утреннего выключения скорости почти всегда совпадает с установленным, то время включения — зачастую существенно отличается от заданного, иногда инет нужен раньше, иногда — гораздо позже (а если проспал то и не нужен вовсе :)).

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

Следущая мысль — изменять параметры включения и выключения скорости в зависимости от наличия «потребителей интернета» в домашней сети, а именно:

  1. Включать скорость, когда стационарный PC или ноутбук (или любое другое заданное устройство) появляются в сети.
  2. Выключать — когда оба исчезают.
  3. Выключать — в заданное время (ночью), т.к. можно забыть выключить комп на ночь :).

В связи с этим так же был рожден небольшой скрипт pingsh.sh, который, посредствам команды ping, определяет наличие в сети «нужных» устройств, ip-адреса этих устройств перечисляются в файле pings, а dhcp маршрутизатора, соответственно, настраивается на выдачу «нужным» домашним устройствам фиксированных ip-адресов. В случае присутствия в сети хотя бы одного адреса из файла — скорость включается, в случае отсутствия всех — через 3 минуты происходит повторная проверка наличия устройств в сети (на случай если wi-fi отвалился), и если устройств не обнаружено — скорость выключается. Дабы не раздражать Йоту лишними запросами, каждый раз при изменении тарифа устанавливем флаг включения/выключения скорости.

Применение скрипта pingsh.sh простое — в файл pings заносим необходимые ip-адреса домашних устройств, в самом скрипте редактируем значения login, psw, speedon и speedoff.

Теперь у меня в crontab всего 2 строки: первая — запуск pingsh.sh каждые 6 минут, и вторая — принудительное выключение скорости в час ночи на случай, если заснул и не выключил комп :)

Вышеупомянутые скрипты можно взять тут.

P.S.


Немного оффтоп. По просьбам трудящихся параллельно была написана простая программа на Delphi под винду для быстрого изменения тарифов. В отличие от предложенного ratswolf варианта браузер не используется, с сервером Yota работаем напрямую посредствам запросов GET и POST с вышеупомянутыми параметрами.
Вариант выбора скорости и отображение текущей скорости/баланса:
image

И все настройки:



Взять можно тут.

Самое главное


И самый главный вопрос — реальная экономия составила около 50%, на базовом тарифе 900 руб/месяц (5.5 мбит/с) удалось проработать почти полтора месяца.

Инструкция по установке curl


Если на rootfs мало места делаем следующим образом.
Соединяемся с роутером через ssh и выполняем следующие команды:
opkg update
opkg install curl --nodeps
opkg install zlib --nodeps
opkg install libcurl --nodeps
opkg install libopenssl -d ram
ln -s /tmp/usr/lib/libcrypto.so.1.0.0 /lib/libcrypto.so.1.0.0
ln -s /tmp/usr/lib/libssl.so.1.0.0  /lib/libssl.so.1.0.0

Теперь добавляем в rc.local строки (можно через web-интерфейс System — Startup):

sleep 180
opkg update
opkg install libopenssl -d ram

Таким образом, даже после перезагрузки роутер сам подгрузит недостающий пакет в RAM.

UPD


Как выяснилось — провайдер Yota использует различные тарифы и параметры для разных регионов.
Представленный yota.sh для Хабаровска. Для того, чтобы получить скрипт для Вашего региона
необходимо воспользоваться скриптом gen.sh (находится там же):
gen.sh login password

По окончании работы скрипта будет создан n_yota.sh с необходимыми параметрами и тарифами.

Спасибо за внимание.
Tags:
Hubs:
+9
Comments 12
Comments Comments 12

Articles