weather_api.py 4.64 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
#!/usr/bin/env python3


"""
Implements API calls related to weather use case

NOTES:
- id and type of message sent should follow convention defined for URN in spreadsheet
https://telecombretagneeu-my.sharepoint.com/:x:/g/personal/federico_sismondi_telecom-bretagne_eu/Ebw_b9iHempGoSPEz__sYCcB_qPu0pwxDAgAeKXFoMu6cA?e=6uuUGD


"""

import os
import json
import requests
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()

# config environment
URL_weather_service = 'https://www.prevision-meteo.ch/services/json/carouge'
POST_DATA_PERIOD = int(os.getenv('POST_DATA_PERIOD', default='300'))  # in seconds
URL_BASE = 'http://{}:1026'.format(os.getenv('ORION_HOST', default='localhost'))
dump_keys = ['city_info', 'current_condition']

# see note above about id and type
fiware_data = {
30 31
    'id': 'urn:ngsi-ld:WeatherObservedRaw:carouge_weather_observed_raw',
    'type': 'WeatherObservedRaw'
32 33 34 35 36
}

# build header for POST
http_header_post = {
    'Fiware-Service': 'carouge',
37
    'Fiware-ServicePath': '/Weather/Raw',
38 39 40 41 42 43 44 45
    'Content-Type': 'application/json',
    'Accept': 'application/json',
}

# build header for GET
http_header_get = http_header_post.copy()
http_header_get.pop('Content-Type')

46
logger.info('Config: \n\tPOST_DATA_PERIOD: {} seconds \n\tURL: {}'.format(POST_DATA_PERIOD, URL_BASE))
47 48 49


def get_data_from_weather_service():
50 51 52
    """
    :return: Raw data (json as string)
    """
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
    logger.info('Querying weather service..')
    try:
        r = requests.get(
            url=URL_weather_service,
            timeout=90,
        )
    except (requests.exceptions.ConnectTimeout, requests.exceptions.ConnectionError):
        logger.info('Could not weather reach service')
        return None

    weather_data = {k: v for k, v in r.json().items() if k in dump_keys}

    return weather_data


def create_weather_entity_in_platform():
    weather_data = get_data_from_weather_service()
    assert weather_data, 'Weather data not defined'

    logger.info('Creating entity')
    response = None

    try:
        entity = {**weather_data, **fiware_data}

        response = requests.post(
            url=URL_BASE + '/v2/entities?options=keyValues',
            headers=http_header_post,
            json=entity
        )
        logger.info('Got {}'.format(response.status_code))

    except (requests.exceptions.ConnectTimeout, requests.exceptions.ConnectionError):
        logger.error('IoT Platform at {} seems unreachable'.format(URL_BASE))

    if response and response.ok:
        return True
    else:
91 92 93 94 95
        if response:
            logger.error('Operation failed, got message: {}'.format(response.json()))
        else:
            logger.error('Operation failed, no response received')

96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
        return False


def post_weather_data_to_platform():
    weather_data = get_data_from_weather_service()
    assert weather_data, 'Weather data not defined'
    logger.info('Posting weather data to platform')

    response = None

    try:
        entity = {**weather_data}

        with open('weather_raw_last_data.json', encoding='utf-8', mode='w') as f:
            json.dump(
                obj=entity,
                fp=f
            )

        response = requests.put(
            url=URL_BASE + '/v2/entities/{}/attrs?options=keyValues'.format(fiware_data['id']),
            headers=http_header_post,
            json=entity
        )
        logger.info('Got {}'.format(response.status_code))

    except (requests.exceptions.ConnectTimeout, requests.exceptions.ConnectionError):
        logger.error('IoT Platform at {} seems unreachable'.format(URL_BASE))

    if response and response.ok:
        return True
    else:
        logger.error('Operation failed, got message: {}'.format(response.json()))
        return False


def get_all_raw_weather_data_from_platform():
    logger.info('Getting all RAW weather data from platform')

    response = None

    try:

        response = requests.get(
            url=URL_BASE + '/v2/entities/?options=keyValues&type={}'.format(fiware_data['type']),
            headers=http_header_get,
        )
        logger.info('Got {}'.format(response.status_code))

    except (requests.exceptions.ConnectTimeout, requests.exceptions.ConnectionError):
        logger.error('IoT Platform at {} seems unreachable'.format(URL_BASE))

    if response and response.ok:
        return response.json()
    else:
        logger.error('Operation failed, got message: {}'.format(response.json()))
        return False


__all__ = [
    'URL_weather_service',
    'POST_DATA_PERIOD',
    'URL_BASE',
    'post_weather_data_to_platform',
    'get_data_from_weather_service',
    'create_weather_entity_in_platform',
    'get_all_raw_weather_data_from_platform'
]