Спочатку я просто хотів підключити GPS-модуль NEO-6M до моєї Raspberry Pi 4, але отримання координат без їх подальшого використання виглядало нецікавим. Тому нижче описано процес підключення модуля, а також python скрипти, для запиту до API погодного сервісу openweathermap, отримання від нього прогнозу погоди і надсилання його через бот у телеграм.
Підключаємо GPS-модуль
Для цього маємо схему:
Встановлюємо необхідні пакети:
sudo pip install pynmea2
sudo apt-get install gpsd gpsd-clients gpsd-tools minicom
Тоді змінюємо конфігурацію попередньо зберігши поточну:
sudo cp /boot/cmdline.txt /boot/cmdline.txt.bak
sudo nano /boot/cmdline.txt
Замінюємо налаштування на такі:
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles
Також редагуємо файл config.txt
sudo nano /boot/config.txt
Додаємо в кінець файлу:
dtparam=spi=on
dtoverlay=pi3-disable-bt
core_freq=250
enable_uart=1
force_turbo=1
init_uart_baud=9600
Перезавантажуємо міні-комп’ютер:
sudo reboot now
Налаштовуємо GPS-модуль на швидкість 9600:
stty -F /dev/ttyAMA0 9600
Вбиваємо всі процеси gpsd і додаємо пристрій в конфігурацію:
sudo killall gpsd
sudo nano /etc/default/gpsd
Нас цікавить параметр DEVICES
DEVICES="/dev/ttyAMA0"
Перезавантажуємо софт:
sudo systemctl enable gpsd.socket
sudo systemctl start gpsd.socket
sudo cgps -s
Ми повинні отримати щось на зразок:
Зауважте, що для першого разу GPS-модулю може знадобитися до 20 хвилин часу доки він отримає координати від супутників, надалі буде швидше.
Скрипт для отримання координат із GPS-модуля
Тепер нам необхвдно написати Python-скрипт, який буде зчитувати широту і довготу з GPS-модуля. Далі ми його доповнимо. Спочатку це буде щось таке:
#! /usr/bin/python
from gps import *
import time
import subprocess
import sys
gpsd = gps(mode=WATCH_ENABLE|WATCH_NEWSTYLE)
while True:
report = gpsd.next()
if report['class'] == 'TPV':
print(str(getattr(report,'lat',0.0)))
print(str(getattr(report,'lon',0.0)))
time.sleep(3)
Результат:
Скрипт для отримання прогнозу погоди через API openweathermap.org
Для початку реєструємося на openweathermap.org, заходимо в розділ API keys свого облікового запису та генеруємо новий ключ. Ну або беремо дефолтний.
Спочатку навчимося просто отримувати дані про погоду від АПІ з нашим ключем:
import requests
api_url = 'https://api.openweathermap.org/data/2.5/onecall?'
params = dict(
lat=ВАША_ШИРОТА,
lon=ВАША_ДОВГОТА,
appid='ВАШ_АПІ_КЛЮЧ',
units='metric',
exclude='minutely,daily',
lang='ua'
)
resp = requests.get(url=api_url, params=params)
print(resp.json())
Створення чат-бота в Telegram
Оскільки я детально розписував цей крок у попередньому проекті Raspberry Pi + OpenCV: розпізнавання об’єктів та сповіщення через Telegram-бот, то тут повторюватись не буду, просто можна проглянути відповідний розділ Налаштовування телеграм бота для Raspberry Pi. Головне на цьому кроці створити чат-бот та отримати токен та ідентифікатор чату.
Все до купи
Що ж, ми маємо деякі спрощені варіанти скриптів, що опитують GPS-модуль для отримання координат, окремо маємо отримання інформації про погоду за координатами від АПІ погодного сервіси та маємо чат-бот. Настав час розширити функціональність цих скриптів та об’єднати це все в єдине ціле.
Алгоритм роботи буде таким:
1. Запускаємо основний скрипт;
1.1 Він отримує координати з GPS-модуля;
1.2 Та запускає наступний скрипт і передає координати у цей скрипт.
2. Наступний скрипт отримує координати від попереднього і:
2.1 Робить із нимим запит до АПІ погодного сервісу;
2.2 Парсить отриману відповідь;
2.3 Надсилає розпаршену відповідь у телеграм.
З урахуванням описаного вище алгоритму, основний скрипт буде мати вигляд:
from gps import *
import time
import sys
gpsd = gps(mode=WATCH_ENABLE|WATCH_NEWSTYLE)
while True:
report = gpsd.next()
if report['class'] == 'TPV':
latitude = str(getattr(report,'lat',0.0))
longitude = str(getattr(report,'lon',0.0))
os.system("python api_forecast.py " + latitude + " " + longitude)
sys.exit()
time.sleep(3)
Як видно з коду, скрипт зберігає координати у змінні та передає їх при запуску наступного скрипта як аргументи. Для запуску наступного скрипта використав модуль sys. Після успішного виконання наступного скрипта, основний скрипт завершує свою роботу за допомогою методу sys.exit().
Тепер розглянемо наступний скрипт:
import requests
import datetime
import sys
TOKEN = "ТОКЕН_ТЕЛЕГРАМ_БОТА"
chat_id = "ІДЕНТИФІКАТОР_ЧАТУ"
api_url = 'https://api.openweathermap.org/data/2.5/onecall?'
params = dict(
lat=sys.argv[1],
lon=sys.argv[2],
appid='ВАШ_АПІ_КЛЮЧ',
units='metric',
exclude='minutely,daily',
lang='uk'
)
resp = requests.get(url=api_url, params=params)
data = resp.json()
forecast = ''
limit = 12
index = 0
for dt in data["hourly"]:
forecast += "Час: " + datetime.datetime.fromtimestamp(dt["dt"]).strftime('%d-%m %H:%M') + "\nТемпература: " + str(dt["temp"]) + "\N{DEGREE SIGN}C." + " Опис: " + dt["weather"][0]["description"] + "\n\n"
if index == limit:
break
index+=1
message = "Поточна погода:\n" + "Час: " + datetime.datetime.fromtimestamp(data["current"]["dt"]).strftime('%d-%m %H:%M') + "\nТемпература: " + str(data["current"]["temp"]) + "\N{DEGREE SIGN}C." + " Опис: " + data["current"]["weather"][0]["description"] + "\n\n" + "Прогноз погоди на сьогодні:\n" + forecast
url = f"https://api.telegram.org/bot{TOKEN}/sendMessage?chat_id={chat_id}&text={message}"
requests.get(url).json()
Описаний скрипт отримує поточну погоду від сервісу погоди, а також погодинний прогноз на 12 годин. Формує це все у повідомлення, яке надсилає у телеграм. Для зчитування аргументів від основного скрипта використав метод sys.argv. В телеграм повідомлення виглядає так:
Ще можна доробити, щоб цей скрипт запускався регулярно скажімо о 9 годині ранку – так ми будемо щодня отримувати поточну погоду та прогноз на день прямо у свій телеграм 🙂
Мені були корисними матеріали:
1. https://github.com/FranzTscharf/Python-NEO-6M-GPS-Raspberry-Pi
2. https://openweathermap.org/api/one-call-api
3. https://ozzmaker.com/using-python-with-a-gps-receiver-on-a-raspberry-pi/