Як я зібрав smart-підставку для квітів і навіщо я це зробив
Всім привіт, мене звуть Олександр Вітер і я працюю Senior Software Engineer у компанії SoftServe. За майже 10 років в ІТ я встиг попрацювати у різних напрямках й доменах, але у цій статті мова піде про мій пет-проєкт. Чи, точніше, плант-проект 🙂
Думаю, не існує такої людини в Україні, для якої війна не була б надвеликим стресом. Різні люди справляються з цим стресом по-різному, в залежності від того, у кого до чого лежить душа: хтось із головою пірнає в роботу, хтось заїдає стрес смачненьким, а хтось навіть стає а̶л̶к̶о шопоголіком.
Я почав вирощувати квіти, щоб на якомусь абстрактно-психологічному рівні компенсувати оточуючі смерть і руйнування. Як казав пан Зеленський: «Життя переможе смерть».
Звісно, коли айтішник за щось береться, воно не може бути «як у всіх нормальних людей» — треба обов’язково додати якусь автоматизацію і перетворити всю ідею у цирк на дроті зі скрам-покером й тестувальницями. З чого все почалося та до чого дійшло і піде мова у цій статті.
Проблема
Коли я тільки почав саджати перші кісточки від авокадо та спостерігати за тим, як йде ріст, то помітив, що ця рослина не така жвава, як, наприклад, соняшник, що обертається за сонцем протягом дня.
В результаті, для мене подальших варіантів було декілька:
- Найпростіший, явно не наш шлях, — змиритися з тим, що рослинка не повністю використовує сонячну енергію і дозволити їй рости у повільному темпі.
- Шлях, що потребував додаткових витрат — купити додаткове обладнання, щоб покращити рослині умови життя.
- Як казав Мандалорець: «This is the way» — зібрати все необхідне самостійно, з того, «що є під рукою у кожної, поважаючої себе домогосподарки».
Рішення
Враховуючи обраний варіант дій та той набір речей, які вже давно валялися на поличках від минулих незавершених проєктів, я вирішив, що цілком можна зібрати «smart підставку для квітів», яка буде вдень обертати горщик з рослиною оптимальним чином.
Прикладом подібної поведінки можуть слугувати розумні сонячні панелі, які не закріплені стаціонарно, а можуть обертатися таким чином, щоб максимально ефективно поглинати сонячне світло (зазвичай, займаючи положення, перпендикулярне падінню сонячних променів).
Переді мною стояла дуже схожа задача, тільки замість сонячних панелей були листя рослин, які треба було підставляти сонячним променям під найкращим кутом.
Цю велику задачу можна було розділити на декілька підзадач, умовно поділених на 2 групи:
Hardware:
- власне, сама підставка, що може обертатися і при цьому витримувати вагу горщика з рослиною;
- двигун, щоб обертати підставку на потрібний кут;
- контролер, щоб керувати двигуном.
Software:
- логіка для передачі команд від контролера до двигуна;
- логіка для визначення потрібного часу для обертання (у різні дні сонце сходить та заходить у різний час, а вночі взагалі немає сенсу обертати рослинку);
- математична логіка для визначення оптимальних кутів повороту підставки, враховуючи такі фактори як: час сходу та заходу сонця; частина світу, на яку виходить вікно, на підвіконні якого стоїть підставка з рослиною; оточуюча архітектура, будинки, що блокують сонячне світло у той чи інший час.
Хардверна частина була закрита наступним чином: у якості підставки я використав старий кулер від стаціонарного комп’ютера у поєднанні з деякими елементами конструктора Lego. За рух відповідав сервопривід MG996R, а у якості контролера використовувався міні-комп’ютер Raspberry Pi 4, на якому я колись запускав власних Telegram-ботів.
Щодо першого пункту з розділу Software, все було досить нескладно, бо і Raspberry Pi, і обрана модель сервоприводу є досить популярними у DIY (do it yourself) ком’юніті, так що знайти інструкцію з налаштування не склало проблем.
Єдиним не досить очевидним моментом тут була не зовсім продумана конструкція кабелів сервоприводу, через що довелося використовувати додаткові джампери, щоб з’єднати сервопривід і міні-комп’ютер. Проте це ніяк не вплинуло на якість їхньої роботи, лише трошки зіпсувало естетику виробу.
З двома іншими софтверними пунктами довелося трохи згадати геометрію та астрономію, бо ці знання не використовувалися практично зі шкільних років.
Фінальна версія проєкту працює приблизно ось так:
Я кажу саме «приблизно», бо на відео показаний загальний механізм роботи з іншим (демонстраційним) скриптом, а не з тим, з яким воно фактично працює.
Це зроблено для того, щоб у короткому відео продемонструвати, як все рухається на практиці і при цьому глядачеві не довелося чекати (а мені — знімати і робити таймлапс) реальних
Код рішення
А ось власне і код, який всім цим керує:
import time import json import pytz import lgpio import requests from dateutil import tz from datetime import datetime, tzinfo PIN = 17 # RPi pin id where servo is connected FREQ = 50 # default for our purpose LAT, LNG = 46.4769954, 30.7302463 # where your device is located endpoint = f'https://api.sunrise-sunset.org/json?lat={lat}&lng={lng}&formatted=0' h = lgpio.gpiochip_open(0) while True: response = requests.get(endpoint) response = json.loads(response.text) sunrise = datetime.fromisoformat(response['results']['sunrise']) sunset = datetime.fromisoformat(response['results']['sunset']) sunrise = sunrise.astimezone(pytz.timezone("Europe/Kyiv")) sunset = sunset.astimezone(pytz.timezone("Europe/Kyiv")) now = datetime.now() if now.hour == sunrise.hour and now.minute == sunrise.minute: lgpio.tx_pwm(h, PIN, FREQ, 4.5) # go to initial position delta = sunset - sunrise light_day = delta.total_seconds() time.sleep(int(light_day / 4)) # wait until sun will be in the right place for i in range(100): lgpio.tx_pwm(h, PIN, FREQ, 4.5+((i+1)*0.05)) time.sleep(int(light_day / 200)) else: time.sleep(60)
Деякі коментарі щодо коду, якщо ви захочете адаптувати його під свої потреби:
- Ви можете використовувати й інший пін, не обов’язково 17, але тоді треба буде точно знати його id і змінити це значення у коді, інакше сервопривід не буде реагувати на команди вашого коду.
- Для максимально точного результату треба буде ввести географічні координати того місця, де буде знаходитися пристрій — від цього залежатиме точний час сходу та заходу сонця, який поверне сервіс api.sunrise-sunset.org, а на цьому базуються всі подальші розрахунки.
- Якщо ви знаходитеся в іншому часовому поясі, значення Europe/Kyiv також треба буде змінити, бо сервіс повертає час сходу й заходу сонця виключно в UTC, тому його треба конвертувати у місцевий час.
- У мене пристрій стоїть біля вікна, яке виходить на південь, при чому оточуючі будинки закривають частину неба зліва і справа, так що перші та останні 45 градусів руху сонця випадають. На цьому базуються розрахунки стартової позиції й того, скільки поворотів треба буде зробити і як часто. В залежності від того, куди виходять ваші вікна та яка частина неба є відкритою, ці параметри можуть змінюватися. У мене підставка обертається від 45° до 135°, що відповідає передачі значень від 4,5 до 9,5 сервоприводу. Там трохи нелінійна залежність, бо параметр 2 відповідає куту 0°, а 12 — 180°. Всі інші значення між ними — це кути, на які може обертатися сервопривід, і для них треба підбирати відповідні значення.
Щодо рядка time.sleep(int(light_day / 200)), то логіка там така: ми пропускаємо першу чверть сонячного півкола, бо немає сенсу щось робити, доки промені не падають на рослину. Далі у нас є 90 робочих градусів, це половина від 180°, які сонце проходить протягом світлового дня. Отже, нас цікавить лише час light_day / 2.
Але позаяк у нас 100 ітерацій, то кожну ітерацію ми маємо обертати підставку через light_day / 2 / 100 секунд, тобто раз на light_day / 200, що ми й робимо у коді.
Вирощуючи декілька рослин та маючи лише одну подібну smart-підставку, можу сказати, що в цілому у проєкту є як плюси, так і мінуси.
Два плюси рішення
До плюсів можна віднести те, що хоча й не сильно, але все ж таки на підставці рослина росте трохи краще, ніж аналогічна, яка просто стоїть стаціонарно.
Також я б додав у позитивне те, що мені було досить цікаво працювати над хардверно-софтверним проєктом — це додало різноманіття у життя звичайного розробника, коли все, чим ти займаєшся, — пишеш код і спілкуєшся на мітингах, не маючи жодного матеріалістичного підтвердження власної роботи.
Мінусів я б виділив 2+1
1. Не у кожного є «непотрібний» міні-комп’ютер, сервопривід та решта деталей, які потрібні для збірки цього диводевайсу. А купляти все спеціально для цього проєкту не дуже раціонально, особливо, враховуючи ціни на електроніку останніх пари років.
2. RaspberryPi хоча й споживає досить мало енергії, але все ж таки це енергозалежний прилад. Тобто кожен раз, коли у вас вдома немає світла, вся ця конструкція втрачає сенс і рослина продовжує рости у звичайному режимі. Це можна було б вирішити за допомогою павербанку, але тоді вся конструкція починає перетворюватися на якогось монстра, якого просто не хочеться використовувати для такої дрібної задачі, бо це як стріляти артилерією по горобцях.
3. (Опціональний мінус) У нас вдома живе киценька, яка дуже полюбляє гризти рослини та дроти. Так що така конструкція, як рослина в оточенні дротів, привертає її увагу з подвійною силю і вимагає додаткового захисту «від нападу хижаків». І якщо раптом одного дня цей захист не впорається — я залишусь і без проєкту, і без рослини.
UPD: вже під час роботи над статтею киценька таки дірвалася до рослин, тому вони, на жаль, мають не дуже презентабельний вигляд, але, наче, живі і продовжують рости.
Якщо цей проєкт надихнув вас на власні ідеї або ви раніше вже робили щось цікаве з Raspberry Pi — діліться у коментарях.
22 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів