|
| 1 | +#!/usr/bin/env python |
| 2 | +# -*- coding: utf-8 -*- |
| 3 | + |
| 4 | +from pyowm.commons import exceptions |
| 5 | +from pyowm.utils import formatting, timestamps |
| 6 | +from pyowm.weatherapi25 import location |
| 7 | + |
| 8 | + |
| 9 | +class AirStatus: |
| 10 | + """ |
| 11 | + A class representing a dataset about air quality |
| 12 | +
|
| 13 | + :param reference_time: GMT UNIXtime telling when the data has been measured |
| 14 | + :type reference_time: int |
| 15 | + :param location: the *Location* relative to this measurement |
| 16 | + :type location: *Location* |
| 17 | + :param interval: the time granularity of the CO observation |
| 18 | + :type interval: str |
| 19 | + :param air_quality_data: the dataset |
| 20 | + :type air_quality_data: dict |
| 21 | + :param reception_time: GMT UNIXtime telling when the CO observation has |
| 22 | + been received from the OWM Weather API |
| 23 | + :type reception_time: int |
| 24 | + :returns: an *COIndex* instance |
| 25 | + :raises: *ValueError* when negative values are provided as reception time, |
| 26 | + CO samples are not provided in a list |
| 27 | +
|
| 28 | + """ |
| 29 | + |
| 30 | + def __init__(self, reference_time, location, air_quality_data, reception_time): |
| 31 | + if reference_time < 0: |
| 32 | + raise ValueError("'reference_time' must be greater than 0") |
| 33 | + self.ref_time = reference_time |
| 34 | + self.location = location |
| 35 | + if not isinstance(air_quality_data, dict): |
| 36 | + raise ValueError("'air_quality_data' must be a list") |
| 37 | + self.air_quality_data = air_quality_data |
| 38 | + for key, val in air_quality_data.items(): |
| 39 | + setattr(self, key, val) |
| 40 | + if reception_time < 0: |
| 41 | + raise ValueError("'reception_time' must be greater than 0") |
| 42 | + self.rec_time = reception_time |
| 43 | + |
| 44 | + def reference_time(self, timeformat='unix'): |
| 45 | + """ |
| 46 | + Returns the GMT time telling when the air quality data have been measured |
| 47 | +
|
| 48 | + :param timeformat: the format for the time value. May be: |
| 49 | + '*unix*' (default) for UNIX time |
| 50 | + '*iso*' for ISO8601-formatted string in the format ``YYYY-MM-DD HH:MM:SS+00:00`` |
| 51 | + '*date* for ``datetime.datetime`` object instance |
| 52 | + :type timeformat: str |
| 53 | + :returns: an int or a str |
| 54 | + :raises: ValueError when negative values are provided |
| 55 | +
|
| 56 | + """ |
| 57 | + return formatting.timeformat(self.ref_time, timeformat) |
| 58 | + |
| 59 | + def reception_time(self, timeformat='unix'): |
| 60 | + """ |
| 61 | + Returns the GMT time telling when the air quality data has been received |
| 62 | + from the OWM Weather API |
| 63 | +
|
| 64 | + :param timeformat: the format for the time value. May be: |
| 65 | + '*unix*' (default) for UNIX time |
| 66 | + '*iso*' for ISO8601-formatted string in the format ``YYYY-MM-DD HH:MM:SS+00:00`` |
| 67 | + '*date* for ``datetime.datetime`` object instance |
| 68 | + :type timeformat: str |
| 69 | + :returns: an int or a str |
| 70 | + :raises: ValueError when negative values are provided |
| 71 | +
|
| 72 | + """ |
| 73 | + return formatting.timeformat(self.rec_time, timeformat) |
| 74 | + |
| 75 | + |
| 76 | + @classmethod |
| 77 | + def from_dict(cls, the_dict): |
| 78 | + """ |
| 79 | + Parses a *AirStatus* instance out of a data dictionary. |
| 80 | +
|
| 81 | + :param the_dict: the input dictionary |
| 82 | + :type the_dict: `dict` |
| 83 | + :returns: a *AirStatus* instance or ``None`` if no data is available |
| 84 | + :raises: *ParseAPIResponseError* if it is impossible to find or parse the data needed to build the result |
| 85 | +
|
| 86 | + """ |
| 87 | + if the_dict is None: |
| 88 | + raise exceptions.ParseAPIResponseError('Data is None') |
| 89 | + try: |
| 90 | + |
| 91 | + item = the_dict['list'][0] |
| 92 | + |
| 93 | + # -- reference time (strip away Z and T on ISO8601 format) |
| 94 | + reference_time = item['dt'] |
| 95 | + |
| 96 | + # -- reception time (now) |
| 97 | + reception_time = timestamps.now('unix') |
| 98 | + |
| 99 | + # -- location |
| 100 | + lon = float(the_dict['coord']['lat']) |
| 101 | + lat = float(the_dict['coord']['lon']) |
| 102 | + place = location.Location(None, lon, lat, None) |
| 103 | + |
| 104 | + # -- air quality data |
| 105 | + data = item['components'] |
| 106 | + data['aqi'] = item['main']['aqi'] |
| 107 | + |
| 108 | + except KeyError: |
| 109 | + raise exceptions.ParseAPIResponseError( |
| 110 | + ''.join([__name__, ': impossible to parse AirStatus'])) |
| 111 | + |
| 112 | + return AirStatus(reference_time, place, data, reception_time) |
| 113 | + |
| 114 | + def to_dict(self): |
| 115 | + """Dumps object to a dictionary |
| 116 | +
|
| 117 | + :returns: a `dict` |
| 118 | +
|
| 119 | + """ |
| 120 | + return {"reference_time": self.ref_time, |
| 121 | + "location": self.location.to_dict(), |
| 122 | + "air_quality_data": self.air_quality_data, |
| 123 | + "reception_time": self.rec_time} |
| 124 | + |
| 125 | + def __repr__(self): |
| 126 | + return "<%s.%s - reference time=%s, reception time=%s, location=%s" % ( |
| 127 | + __name__, |
| 128 | + self.__class__.__name__, |
| 129 | + self.reference_time('iso'), |
| 130 | + self.reception_time('iso'), |
| 131 | + str(self.location)) |
0 commit comments