Очередная ненужная никому история о Linux и i3. В этот раз я реализовал для себя блок с погодой. Не то, чтобы я не выхожу на улицу - что на самом деле является долей правды - просто мне так удобней и мне так понятней, когда можно выбежать за хлебушком. Зимой, конечно, вообще не хочется никуда выходить. Особенно, если температура ниже -10 градусов. Жуть! Вернемся к нашему блоку. Визуально он выглядит следующим образом:
Здесь можно заметить самое простое визуальное оформление и иконки FontAwesome. Данные о погоде извлекаются благодаря API OpenWeather, которые предоставляют free план на 60 запросов в минуту или 1 млн в месяц. Для меня этого вполне достаточно, потому что я дергаю погоду только 1 раз в 15 минут. Это всего 2880 запросов в месяц.
Что ж, сам код блока i3blocks написан на Bash. Ниже представлен файл u-i3blocks-weather.sh
:
#!/usr/bin/env bash
set -euo pipefail
WEATHER_SITE_URL="https://www.gismeteo.ru/weather-armavir-5220/10-days/"
nm-online -q -t 15 || exit 1
btn_code="${BLOCK_BUTTON:-"0"}"
if [ "${btn_code}" -eq "1" ]; then
xdg-open $WEATHER_SITE_URL 1> /dev/null &
fi
/path/to/u-weather.py
exit 0
Здесь можно заметить константу WEATHER_SITE_URL
, которая содержит ссылку на сайт с погодой. По этой ссылке открывается браузер, когда происходит левый клик по блоку в i3bar. Также в этом файлике у нас есть путь до Bash файла /path/to/u-weather.py
, который как раз и содержит весь важный код для предоставления данных о погоде. Данный файл представляет собой код на языке Python:
#!/usr/bin/env python3
from pycurl import Curl, FOLLOWLOCATION, HTTPGET, WRITEDATA, error as CurlError
import sys
import os
from io import BytesIO
import json
from json import JSONDecodeError
from typing import List
from urllib.parse import urlencode
from subprocess import CalledProcessError
# https://openweathermap.org/current
# https://openweathermap.org/weather-conditions
OPENWEATHERMAP_API_KEY = ''
LOCATION_NAME = 'Armavir'
SYMBOL_DEGREE = '\u00B0'
ICON_WIND = '\uf72e'
ICON_CLEAR = '\uf185'
ICON_CLOUDS = '\uf0c2'
ICON_RAIN = '\uf73d'
ICON_THUNDERSTORM = '\uf76c'
ICON_SNOW = '\uf2dc'
ICON_SMOG = '\uf75f'
request = Curl()
request.setopt(
request.URL,
'https://api.openweathermap.org/data/2.5/weather?' + urlencode({
'q': LOCATION_NAME,
'appid': OPENWEATHERMAP_API_KEY,
'units': 'metric',
'lang': 'en'
})
)
request.setopt(FOLLOWLOCATION, True)
request.setopt(HTTPGET, True)
buffer = BytesIO()
request.setopt(WRITEDATA, buffer)
try:
request.perform()
except (CurlError) as e:
print(e, file=sys.stderr)
sys.exit(os.EX_DATAERR)
request.close()
try:
weather_data = json.loads(buffer.getvalue())
except (JSONDecodeError, CalledProcessError) as e:
print(e, file=sys.stderr)
sys.exit(os.EX_DATAERR)
output: List[str] = []
if (
'weather' in weather_data
and len(weather_data['weather']) > 0
and 'id' in weather_data['weather'][0]
):
weather_id = weather_data['weather'][0]['id']
if (200 <= weather_id <= 232):
output.append(ICON_THUNDERSTORM)
elif (300 <= weather_id <= 321 or 500 <= weather_id <= 531):
output.append(ICON_RAIN)
elif (600 <= weather_id <= 622):
output.append(ICON_SNOW)
elif (701 <= weather_id <= 781):
output.append(ICON_SMOG)
elif (weather_id == 800):
output.append(ICON_CLEAR)
elif (801 <= weather_id <= 804):
output.append(ICON_CLOUDS)
if ('name' in weather_data):
output.append(weather_data['name'])
if ('main' in weather_data and 'temp' in weather_data['main']):
output.append(
str(round(weather_data['main']['temp'])) + SYMBOL_DEGREE + 'C'
)
if ('wind' in weather_data and 'speed' in weather_data['wind']):
output.append(ICON_WIND)
# m/s
# --------- = m/s * 3.6
# 1000/3600
output.append(str(round(weather_data['wind']['speed'] * 3.6)))
output.append('km/h')
print(' '.join(output))
sys.exit(os.EX_OK)
В этом файле можно заметить две важные константы. Первая OPENWEATHERMAP_API_KEY
, а вторая - LOCATION_NAME
. В OPENWEATHERMAP_API_KEY
указывается ключ API для OpenWeather, который вы сможете скопировать после регистрации на сайте OpenWeather в личном профиле пользователя. А в LOCATION_NAME
указывается ваше текущее местоположение. Данный блок разрабатывался исключительно под использование на стационарном компьютере, поэтому если у вас ноутбук и вы часто куда-то путешествуете, то данный код потребует некоторых доработок.
Теперь осталось все добавить в i3blocks:
[weather]
command=/path/to/u-i3blocks-weather.sh
interval=900
Перезапускаем i3 - i3-msg restart
- и радуемся. =)