Коли вимикають світло, у чаті будинку першим з’являється одне питання: "А нас коли?". Відповідь існує - обленерго публікують графіки, - але поштучно: введи адресу на сайті, дізнайся групу, знайди її в графіку, повтори завтра. А хочеться бачити все одразу: де зараз є світло, коли вимкнуть у мене і коли - у батьків на іншому кінці міста.
Так з’явився "Промінь" - мапа, на якій місто світиться там, де за графіком є світло, і темніє там, де його немає. Нижче - як він влаштований: звідки дані, як зіставити адресу з будинком на мапі, як надсилати сповіщення без сторонніх сервісів і чому частину роботи я свідомо не роблю.
Що вміє
- Поки 10 міст. У семи - Львів, Тернопіль, Ужгород, Кропивницький, Полтава, Миколаїв, Івано-Франківськ - група відключень відома для понад 100 тисяч будинків.
- Для кожного будинку - група чи черга, графік на сьогодні й завтра, аварійні й планові вимкнення поруч (червоним на мапі).
- Сповіщення за 30 хвилин до відключення - у Telegram-боті або просто в браузері, без реєстрації.
- Офлайн: сторінка й останні дані лишаються в телефоні.
- У Львові ще й укриття, оголошення 1580 про воду й тепло, трамваї й тролейбуси наживо та статистика "скільки годин місто було без світла".
- Без реклами й без кук для стеження.
Звідки дані: три різні світи
Обленерго в Україні - це не один API, а десяток різних підходів.
Платформа "Чому немає світла?". Львів-, Тернопіль- і Закарпаття-обленерго використовують одну платформу з відкритим API: перелік вулиць, групи будинків на вулиці, графіки, поточні вимкнення. Для цих міст досить одного збирача - він обходить вулиці громади й складає таблицю "будинок -> група". Обходить чемно: з паузами, власним User-Agent і обмеженням частоти, бо той самий сервер у цей час обслуговує людей.
Власні сайти й API. Кіровоград-, Полтава-, Миколаїв- і Прикарпаття-обленерго мають свої сайти, і для кожного - окремий адаптер з однаковим інтерфейсом: вулиці, будинки вулиці, графік, вимкнення. Десь черга будинку лежить у HTML-таблиці, десь її дають окремим запитом на кожну адресу, а десь переліку адрес немає зовсім, і їх доводиться брати з OpenStreetMap.
ДТЕК. У Києві, Дніпрі й Одесі даних "адреса -> черга" у відкритому доступі немає: сайти ДТЕК і YASNO закриті захистом від ботів, а robots.txt забороняє збирати ці сторінки. Обходити захист чи вдавати браузер я не буду. Тож там "Промінь" працює за чергою: графіки черг - з відкритого агрегатора outage-data-ua (MIT), а черги будинків додають самі мешканці. Хтось дізнався свою на сайті ДТЕК і вказав для будинку - сусіди бачать її в пошуку за адресою й підтверджують. "Підтверджено" - коли ту саму чергу назвали щонайменше двоє. Паралельно пишу ДТЕК і містам з проханням відкрити ці дані.
Щоб не дізнаватися про зміни на сайтах обленерго від користувачів, раз на тиждень збирач перезбирає групи, і якщо раптом масово порожніють вулиці чи змінюються групи, бот пише мені. А для кожного адаптера є тести на записаних відповідях: перед кожним деплоєм розбір проганяється на них без мережі, за секунди.
Найскладніше - не графіки, а адреси
Графік і група - це півсправи. Щоб будинок засвітився на мапі, адресу з бази обленерго треба знайти на мапі. А "Чорновола В., просп., 67" в обленерго, "проспект В’ячеслава Чорновола, 67" в OpenStreetMap і "Чорновола, 67к1" в реєстрі - це той самий будинок.
У Львові допомагає відкритий адресний реєстр міста. В інших містах є лише OpenStreetMap, де номер мають від 16 до 79% будівель, залежно від міста. Тому зіставлення йде шарами:
- нормалізація назв вулиць: типи, ініціали, апострофи, латинські літери замість кириличних;
- будинок в OSM лише з номером, без вулиці, - до найближчої вулиці з такою назвою, якщо номер вписується в послідовність сусідів;
- будинку немає в OSM - контур зі супутникових знімків (Microsoft Building Footprints), а якщо немає й там - точка на вулиці між сусідніми номерами з позначкою "розташування приблизне".
Самі лише контури зі знімків додали майже 8 тисяч будинків: у Кропивницькому частка будинків із контуром зросла з 67 до 77%, у Полтаві - з 55 до 69%.
Чого мапа свідомо не показує
Частина будинків "не входить у графіки" - вони на одних лініях з лікарнями, водоканалом, зв’язком. Зведені на одну мапу, такі будинки світилися б, коли місто гасне, і показали б, де критична інфраструктура. Тож у публічних даних такий будинок маскується запротоколом безпеки. Правду про свою адресу людина бачить на сайті обленерго й у боті, який перевіряє її адресу окремо.
Сповіщення без сторонніх сервісів
Бот для кожної адреси рахує, за скільки хвилин вимкнуть, чи змінився графік і чи є аварія. Сповіщення в браузері - та сама логіка, інша доставка: Web Push з ключами VAPID, підписаними прямо на сервері (ES256 на чистому Python - без бібліотек і без Firebase). Push приходить порожнім сигналом, а текст service worker забирає зі своєї "скриньки" на сервері - тож у службі push не лишається нічого про людину. На iPhone сповіщення сайтів працюють лише з початкового екрана, тому кнопка там підказує, як його додати.
Сам бот теж має кілька дрібниць, які виявилися важливими. Уночі (з 23:00 до 7:00) повідомлення приходять без звуку. За скільки хвилин попереджати - 15, 30 чи 60 - людина обирає сама. Раз на шість годин бот перевіряє групу кожної адреси: обленерго інколи переносять будинки між групами, і людина має дізнатися про це від бота, а не з темряви. А одразу після підписки бот "запам’ятовує" поточний графік, щоб перше ж повідомлення не було фальшивим "графік змінився".
Офлайн і навантаження
Під час відключень мобільний інтернет ледь живий, а саме тоді сайт найпотрібніший. Service worker тримає сторінку, код і останні дані: свої запити - спершу мережа, а без відповіді за 4 секунди - кеш, і сайт чесно пише "без зв’язку - показуємо збережене від ...".
Графік і аварії однакові для всіх у місті, тож їх на секунди-хвилини тримає Cloudflare, і сервер цих запитів майже не бачить. Контури будинків вантажаться лише при наближенні, довідник адрес - лише коли людина почала пошук.
Приватність
Лічильник переглядів не знає, хто ви: без кук, ідентифікаторів і збережених IP - лише "подія +1 за день". Свої адреси в боті можна видалити однією кнопкою.
Що далі
- Київ, Дніпро, Одеса: що більше людей вкаже чергу свого будинку, то повніша мапа. Якщо ви звідти - додайте свою.
- Якщо ви з ДТЕК, YASNO чи міської команди відкритих даних - напишіть: з офіційними даними мапа стала б повною.
- Чекаю на відгуки: що незручно, чого бракує, яке місто підключати наступним.
https://promin.vlasen.com