Як я створив віджет з інформацією, чи є електроенергія та інтернет вдома
Ще до початку війни відкрив для себе Scriptable — iOS-додаток для створення віджетів на JavaScript. А оскільки нам Тім Кук ще й дозволив створювати віджети для домашнього екрана, то треба цим користуватись!
Колись було досить багато ідей (і я створював віджети з кількістю відвідувачів карти тривог, але коли їх стало дуже багато, то перестав гратись і продався Google Analytics), але в новій реальності у нас в країні війна, і поки агресор не розпався на багато інших, то одна з проблем їх існування — періодична відсутність світла вдома. Через те, що графік не сходиться з реальним вимкненням світла, не завжди зрозуміло, чи пора повертатись додому.
В результаті у мене вийшов ось такий віджет:
Далі йдуть технічні моменти, а внизу інструкція, як додати його собі — якщо хтось працює на
Як правильно зазначили в твітерах [1, 2], віджет фактично перевіряє, чи доступний ваш роутер в інтернеті. Можуть бути випадки, що електроенергія є, хоча самого інтернету немає — в такому випадку, віджет все ще буде червоним. В мене в таких випадках інтернет зʼявлявся протягом
No-Сode?
Спочатку я думав виводити віджет на заблокованому екрані, і знайшов Any Text, який підтримує інтеграцію з Shortcuts. Їх навіть можна запускати по розкладу, але мінімальна періодичність — день. Якщо я хочу оновлювати кожні 15 хвилин, то потрібно створити 96 автоматизацій, і кожну з них вручну. Інших варіантів я так і не знайшов, тому ідея з ноукодом швидко провалилась.
Шо по пінгу роутера?
Найпростіший спосіб перевірити, чи є інтернет вдома — зробити пінг на IP адресу роутера, а Scriptable (читай ES6) не вміє робити запити по icmp-протоколу. З доступних ресурсів я знайшов API, яке робить пінг, але там досить довго потрібно чекати на результати — мені достатньо хоча б одного результату, а не перевіряти, чи відповідає мій роутер з усіх материків. Тому треба було створити свій мікросервіс!
Підіймати сервер для одного запиту — така собі ідея, і я спочатку подумав про DigitalOcean Functions (а-ля AWS Lambda), але є проблема, що складно обмежувати кількість запитів в разі необхідності, раптом росіяни почнуть навантажувати сервіс своїми запитами, як і зробили з карти тривог.
А потім я згадав пост Антона (і ось зараз помітив, що там якраз і за Scriptable мова була), що в nginx можна писати на lua, і це виглядало ідеальним рішенням! Тому з гівна та палок за пару хвилин я зібрав швиденько ендпоінт, який робить ping заданої IP-адреси та повертає інформацію, чи доступний він.
server { # ... location /ping/ { default_type 'application/json'; content_by_lua ' local cjson = require "cjson" if ngx.var.arg_ip == nil then ngx.say(cjson.encode({status="error", error="Передайте IP через ?ip= параметр. Наприклад, ?ip=127.0.0.1"})); return end local ip = ngx.var.arg_ip; local chunks = {ip:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)$")} if #chunks == 4 then for _,v in pairs(chunks) do if tonumber(v) > 255 then ngx.say(cjson.encode({status="error", error="Додайте коректний IP в налаштуваннях"})) return end end else ngx.say(cjson.encode({status="error", error="Додайте коректний IP в налаштуваннях"})); return end local handle = io.popen("ping -c 1 " .. ngx.var.arg_ip .. " -W 0.5", "r") local out = handle:read("*all") handle:close() if string.find(out, "1 received") then ngx.say(cjson.encode({status="ok"})) else ngx.say(cjson.encode({status="error"})) end '; } }
І все запрацювало!
Віджет
Віджет виявився найпростішою частиною, і на основі інших прикладів я швиденько зробив віджет, який показує стан та дату оновлення. Сам код віджета в файлі нижче — там один запит, відображення його та часу генерації, і ніякого рокет саєнс!
Що треба ще знати
Вдома повинен бути завжди статичний IP, оскільки з динамічним складно працювати.
Також iOS сама вирішує, коли їй оновити віджет, і робить це по документації в інтервалі 15..60 хвилин, але фактично в мене виходило
Як?
- Повинен бути статичний IP. Якщо роутер вимкнути-увімкнути, і IP зміниться — потрібно буде у провайдера замовляти додатково послугу статичного IP. Віджет постійно перевіряє лише одну і ту ж адресу.
- Роутер повинен відповідати на ping запити. Якщо повертається помилка при натисканні на кнопку «Надіслати пінг на мій IP», то треба гуглити щось «%router name% Respond to Pings from WAN» та вмикати на роутері.
- Потрібно встановити Scriptable, завантажити файл нижче, поділитись ним в Scriptable та замінити IP в першому рядку на потрібний. Раптом що, ось відео, як це робиться.
- Створити віджет та додати його на домашній екран.
- Всьо!
Що далі?
Взагалі в мене ще була ідея пройтись по закладах та зробити невелику краудсорсинг-карту з закладами та станом вайфаю в реальному часі. Можна також зробити якогось телеграм-бота або надсилати сповіщення при зміні стану світла.
Або можна зробити якусь zapier-інтеграцію для слака, щоб всі бачили, що у вас немає світла, і що можлива якась затримка в для відповідей. Я якось робив таке для сирен, тому повинно бути максимально просто і зробити для світла також.
Найкращі коментарі пропустити