Passed
Pull Request — main (#53)
by Guy
01:15
created

StationMeteorologicalReadings.__repr__()   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
"""Data Class for IMS Meteorological Readings."""
2
3
from __future__ import annotations
4
5
import datetime
6
import textwrap
7
import time
8
from dataclasses import dataclass, field
9
from datetime import datetime
10
11
from .const import (
12
    API_CHANNELS,
13
    API_DATA,
14
    API_DATETIME,
15
    API_NAME,
16
    API_RAIN,
17
    API_RH,
18
    API_STATION_ID,
19
    API_STATUS,
20
    API_STD_WD,
21
    API_TD,
22
    API_TD_MAX,
23
    API_TD_MIN,
24
    API_TG,
25
    API_TIME,
26
    API_VALID,
27
    API_VALUE,
28
    API_WD,
29
    API_WD_MAX,
30
    API_WS,
31
    API_WS_1MM,
32
    API_WS_10MM,
33
    API_WS_MAX,
34
    VARIABLES,
35
)
36
37
38
@dataclass
39
class MeteorologicalData:
40
    """Meteorological Data."""
41
42
    station_id: int
43
    """Station ID"""
44
    datetime: datetime
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable datetime does not seem to be defined.
Loading history...
45
    """Date and time of the data"""
46
    rain: float
47
    """Rainfall in mm"""
48
    ws: float
49
    """Wind speed in m/s"""
50
    ws_max: float
51
    """Gust wind speed in m/s"""
52
    wd: float
53
    """Wind direction in deg"""
54
    wd_max: float
55
    """Gust wind direction in deg"""
56
    std_wd: float
57
    """Standard deviation wind direction in deg"""
58
    td: float
59
    """Temperature in °C"""
60
    td_max: float
61
    """Maximum Temperature in °C"""
62
    td_min: float
63
    """Minimum Temperature in °C"""
64
    tg: float
65
    """Ground Temperature in °C"""
66
    tw: float
67
    """TW Temperature (?) in °C"""
68
    rh: float
69
    """Relative humidity in %"""
70
    ws_1mm: float
71
    """Maximum 1 minute wind speed in m/s"""
72
    ws_10mm: float
73
    """Maximum 10 minute wind speed in m/s"""
74
    time: datetime.time
75
    """Time"""
76
    bp: float
77
    """Maximum barometric pressure in mb"""
78
    diff_r: float
79
    """Distributed radiation in w/m^2"""
80
    grad: float
81
    """Global radiation in w/m^2"""
82
    nip: float
83
    """Direct radiation in w/m^2"""
84
85
    def _pretty_print(self) -> str:
86
        return textwrap.dedent(
87
            """Station: {}, Date: {}, Readings: [(TD: {}{}), (TDmax: {}{}), (TDmin: {}{}), (TG: {}{}), (RH: {}{}), (Rain: {}{}), (WS: {}{}), (WSmax: {}{}), (WD: {}{}), (WDmax: {}{}),  (STDwd: {}{}), (WS1mm: {}{}), (WS10mm: {}{}), (Time: {}{})]
88
            """
89
        ).format(
90
            self.station_id,
91
            self.datetime,
92
            self.td,
93
            VARIABLES[API_TD].unit,
94
            self.td_max,
95
            VARIABLES[API_TD_MAX].unit,
96
            self.td_min,
97
            VARIABLES[API_TD_MIN].unit,
98
            self.tg,
99
            VARIABLES[API_TG].unit,
100
            self.rh,
101
            VARIABLES[API_RH].unit,
102
            self.rain,
103
            VARIABLES[API_RAIN].unit,
104
            self.ws,
105
            VARIABLES[API_WS].unit,
106
            self.ws_max,
107
            VARIABLES[API_WS_MAX].unit,
108
            self.wd,
109
            VARIABLES[API_WD].unit,
110
            self.wd_max,
111
            VARIABLES[API_WD_MAX].unit,
112
            self.std_wd,
113
            VARIABLES[API_STD_WD].unit,
114
            self.ws_1mm,
115
            VARIABLES[API_WS_1MM].unit,
116
            self.ws_10mm,
117
            VARIABLES[API_WS_10MM].unit,
118
            self.time,
119
            VARIABLES[API_TIME].unit,
120
        )
121
122
    def __str__(self) -> str:
123
        return self._pretty_print()
124
125
    def __repr__(self) -> str:
126
        return self._pretty_print().replace("\n", " ")
127
128
129
@dataclass
130
class StationMeteorologicalReadings:
131
    """Station Meteorological Readings."""
132
133
    station_id: int
134
    """ Station Id"""
135
    data: list[MeteorologicalData] = field(default_factory=list)
136
    """ List of Meteorological Data """
137
138
    def __repr__(self) -> str:
139
        return textwrap.dedent("""Station ({}), Data: {}""").format(
140
            self.station_id, self.data
141
        )
142
143
144
def meteo_data_from_json(station_id: int, data: dict) -> MeteorologicalData:
145
    """Create a MeteorologicalData object from a JSON object."""
146
    dt = datetime.fromisoformat(data[API_DATETIME])
147
    channel_value_dict = {}
148
    for channel_value in data[API_CHANNELS]:
149
        if channel_value[API_VALID] is True and channel_value[API_STATUS] == 1:
150
            channel_value_dict[channel_value[API_NAME]] = float(
151
                channel_value[API_VALUE]
152
            )
153
154
    rain = channel_value_dict.get(API_RAIN)
155
    ws_max = channel_value_dict.get(API_WS_MAX)
156
    wd_max = channel_value_dict.get(API_WD_MAX)
157
    ws = channel_value_dict.get(API_WS)
158
    wd = channel_value_dict.get(API_WD)
159
    std_wd = channel_value_dict.get(API_STD_WD)
160
    td = channel_value_dict.get(API_TD)
161
    rh = channel_value_dict.get(API_RH)
162
    td_max = channel_value_dict.get(API_TD_MAX)
163
    td_min = channel_value_dict.get(API_TD_MIN)
164
    ws_1mm = channel_value_dict.get(API_WS_1MM)
165
    ws_10mm = channel_value_dict.get(API_WS_10MM)
166
    tg = channel_value_dict.get(API_TG)
167
    time_val = channel_value_dict.get(API_TIME)
168
    if time_val:
169
        time_val = time.strptime(str(int(time_val)), "%H%M")
170
171
    return MeteorologicalData(
172
        station_id,
173
        dt,
174
        rain,
175
        ws_max,
176
        wd_max,
177
        ws,
178
        wd,
179
        std_wd,
180
        td,
181
        rh,
182
        td_max,
183
        td_min,
184
        tg,
185
        ws_1mm,
186
        ws_10mm,
187
        time_val
188
    )
189
190
191
def station_meteo_data_from_json(json: dict) -> StationMeteorologicalReadings:
192
    station_id = int(json[API_STATION_ID])
193
    data = json.get(API_DATA)
194
    if not data:
195
        return None
196
    meteo_data = [meteo_data_from_json(station_id, single_meteo_data) for single_meteo_data in data]
197
    return StationMeteorologicalReadings(station_id, meteo_data)
198