пятница, 3 марта 2017 г.

Сводка погоды в консоли linux на python.

В последнее время все погодные агрегаторы ужесточили процесс выдачи прогнозов погоды для общественности, оставляя поле для коммерческого доступа к информации. Ресурт http://openweathermap.org/ позволяет бесплатно получать сводку о погоде до 60 запросов в минуту, платные аккаутны имеют более расширеныный интервал запросов. Для некоммерческого использования этого вполне хватит.

Первоначально регистрируемся на http://openweathermap.org/, ознакамливаемся с описанием API и находим ID интересующего региона или города. В моем случае выбор пал на получение информации по городу Ставрополю, в формате json:

http://openweathermap.org/find?q=stavropol

город найден переходим по ссылке, в адресе ссылки виден ID города:

http://openweathermap.org/city/487846

После регистрации нам выделили user API-key, он нам понадобится для авторизации при запросе данных.



import datetime
import json
import urllib.request


def time_converter(time):
    converted_time = datetime.datetime.fromtimestamp(
        int(time)
    ).strftime('%H:%m')
    return converted_time


def url_builder(city_id):
    user_api = ''  # API-key полученый после регистрации
    unit = 'metric'  # Метрическая система значений
    api = 'http://api.openweathermap.org/data/2.5/weather?id=487846'     # Здесь надо указать ID города

    full_api_url = api + '&mode=json&units=' + unit + '&APPID=' + user_api
    #print (full_api_url) #если необходимо посмотреть полный url запроса
    return full_api_url


def data_fetch(full_api_url):
    url = urllib.request.urlopen(full_api_url)
    output = url.read().decode('utf-8')
    raw_api_dict = json.loads(output)
    url.close()
    return raw_api_dict


def data_organizer(raw_api_dict):
    data = dict(
        city=raw_api_dict.get('name'),
        country=raw_api_dict.get('sys').get('country'),
        temp=raw_api_dict.get('main').get('temp'),
        temp_max=raw_api_dict.get('main').get('temp_max'),
        temp_min=raw_api_dict.get('main').get('temp_min'),
        humidity=raw_api_dict.get('main').get('humidity'),
        pressure=raw_api_dict.get('main').get('pressure'),
        sky=raw_api_dict['weather'][0]['main'],
        sunrise=time_converter(raw_api_dict.get('sys').get('sunrise')),
        sunset=time_converter(raw_api_dict.get('sys').get('sunset')),
        wind=raw_api_dict.get('wind').get('speed'),
        #wind_deg=raw_api_dict.get('deg'),
 wind_deg=raw_api_dict.get('wind').get('deg'),
        dt=time_converter(raw_api_dict.get('dt')),
        cloudiness=raw_api_dict.get('clouds').get('all')
    )
    return data


def data_output(data):
    m_symbol = '\xb0' + 'C'


    print('_____________________________________________')
    print('')
    print('Погода сейчас в: {}, {}:'.format(data['city'], data['country']))
    if data['sky']=="Clouds":
        sky="Облачно"
    if data['sky']=="Mist":
        sky="Туман"
    if data['sky']=="Rain":
        sky="Дождь"
    if data['sky']=="Drizzle":
        sky="Изморось"
    if data['sky']=="Clear":
        sky="Ясно"
    if data['sky']=="Snow":
        sky="Снег"
    print("Температура: {} {}. {}.".format(data['temp'], m_symbol, sky))
    print('')
    print('Изменение температуры \nв ближайшее время: от {} до {} °C'.format(data['temp_min'], data['temp_max']))
    print('')
    print('Скорость ветра: {} м/c'.format(data['wind']))
    
    if 348.75 <= data['wind_deg'] <= 360 or 0 < data['wind_deg'] < 11.25:
        print("Направление ветра: С")

    if 11.25 <= data['wind_deg'] <= 33.75:
        print("Направление ветра: С-С-В")

    if 33.75 <= data['wind_deg'] <= 56.25:
        print("Направление ветра: С-В")

    if 56.25 <= data['wind_deg'] <= 78.75:
        print("Направление ветра: В-С-В")

    if 78.75 <= data['wind_deg'] <= 101.25:
        print("Направление ветра: В")

    if 101.25 <= data['wind_deg'] <= 123.75:
        print("Направление ветра: В-Ю-В")

    if 123.75 <= data['wind_deg'] <= 146.25:
        print("Направление ветра: Ю-В")

    if 146.25 <= data['wind_deg'] <= 168.75:
        print("Направление ветра: Ю-Ю-В")

    if 168.75 <= data['wind_deg'] <= 191.25:
        print("Направление ветра: Ю")

    if 191.25 <= data['wind_deg'] <= 213.75:
        print("Направление ветра: Ю-Ю-З")

    if 213.75 <= data['wind_deg'] <= 236.25:
        print("Направление ветра: Ю-З")

    if 236.25 <= data['wind_deg'] <= 258.75:
        print("Направление ветра: З-Ю-З")

    if 258.75 <= data['wind_deg'] <= 281.25:
        print("Направление ветра: З")

    if 281.25 <= data['wind_deg'] <= 303.75:
        print("Направление ветра: З-С-З")

    if 303.75 <= data['wind_deg'] <= 326.25:
        print("Направление ветра: С-З")

    if 326.25 <= data['wind_deg'] <= 348.75:
        print("Направление ветра: С-С-З")

    print('Относительная влажность: {} %'.format(data['humidity']))
    print('Плотность облаков: {} %'.format(data['cloudiness']))
    a=data['pressure']/1.3332239
    b=round(a)
    print ('Давление: ' + str(b) + ' мм рт.ст.')
    print('Восход: {}'.format(data['sunrise']))
    print('Закат: {}'.format(data['sunset']))
    print('')
    print('Последнее обновление: {}'.format(data['dt']))
    print('_____________________________________________')
    
if __name__ == '__main__':
    try:
        data_output(data_organizer(data_fetch(url_builder(2172797))))
    except IOError:
        print('no internet')

Сложные операции над направлением ветра связаны с метеорологическими стандартами указания направления ветра:



upd: от спагетти кода отвечающего за направление ветра можно избавиться следующей конструкцией:
nap = ['С','ССВ','СВ','ВСВ','В','ВЮВ','ЮВ','ЮЮВ','Ю','ЮЮЗ','ЮЗ','ЗЮЗ','З','ЗСЗ','СЗ','ССЗ']

delta_phi = 22.5

degs = [delta_phi*d for d in range(0, len(nap))]

def get_dir(d):
    d += delta_phi/2
    if d > 360:
        d -= 360
    index = int(d/delta_phi)
    return nap[index]

Комментариев нет:

Отправить комментарий