simple-dwd-weatherforecast 2.0.21__py3-none-any.whl → 2.0.23__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- simple_dwd_weatherforecast/dwdforecast.py +31 -44
- {simple_dwd_weatherforecast-2.0.21.dist-info → simple_dwd_weatherforecast-2.0.23.dist-info}/METADATA +1 -1
- {simple_dwd_weatherforecast-2.0.21.dist-info → simple_dwd_weatherforecast-2.0.23.dist-info}/RECORD +8 -8
- {simple_dwd_weatherforecast-2.0.21.dist-info → simple_dwd_weatherforecast-2.0.23.dist-info}/WHEEL +1 -1
- tests/test_parsekml.py +2 -0
- tests/test_update.py +59 -28
- {simple_dwd_weatherforecast-2.0.21.dist-info → simple_dwd_weatherforecast-2.0.23.dist-info}/LICENCE +0 -0
- {simple_dwd_weatherforecast-2.0.21.dist-info → simple_dwd_weatherforecast-2.0.23.dist-info}/top_level.txt +0 -0
@@ -5,7 +5,7 @@ from zipfile import ZipFile
|
|
5
5
|
from enum import Enum
|
6
6
|
from lxml import etree
|
7
7
|
from datetime import datetime, timedelta, timezone
|
8
|
-
import
|
8
|
+
import arrow
|
9
9
|
import math
|
10
10
|
import json
|
11
11
|
import csv
|
@@ -97,7 +97,6 @@ class Weather:
|
|
97
97
|
NOT_AVAILABLE = "---"
|
98
98
|
|
99
99
|
station_id = ""
|
100
|
-
station_name = ""
|
101
100
|
issue_time = None
|
102
101
|
forecast_data = None
|
103
102
|
report_data = None
|
@@ -176,36 +175,35 @@ class Weather:
|
|
176
175
|
}
|
177
176
|
|
178
177
|
region_codes = {
|
179
|
-
"NW": "dweh",
|
180
|
-
"NI": "dwhg",
|
181
|
-
"HB": "dwhg",
|
182
|
-
"SH": "dwhh",
|
183
|
-
"HH": "dwhh",
|
184
|
-
"SN": "dwlg",
|
185
|
-
"ST": "dwlh",
|
186
|
-
"TH": "dwli",
|
187
|
-
"BY": "dwmg",
|
188
|
-
"
|
189
|
-
"HE": "dwoh",
|
190
|
-
"RP": "dwoi",
|
191
|
-
"SL": "dwoi",
|
192
|
-
"BB": "dwpg",
|
193
|
-
"BE": "dwpg",
|
194
|
-
"MV": "dwph",
|
178
|
+
"NW": "dweh", # Nordrhein-Westfalen
|
179
|
+
"NI": "dwhg", # Niedersachsen
|
180
|
+
"HB": "dwhg", # Bremen
|
181
|
+
"SH": "dwhh", # Schleswig-Holstein
|
182
|
+
"HH": "dwhh", # Hamburg
|
183
|
+
"SN": "dwlg", # Sachsen
|
184
|
+
"ST": "dwlh", # Sachsen-Anhalt
|
185
|
+
"TH": "dwli", # Thueringen
|
186
|
+
"BY": "dwmg", # Bayern
|
187
|
+
"BW": "dwsg", # Baden-Württemberg
|
188
|
+
"HE": "dwoh", # Hessen
|
189
|
+
"RP": "dwoi", # Rheinland-Pfalz
|
190
|
+
"SL": "dwoi", # Saarland
|
191
|
+
"BB": "dwpg", # Brandenburg
|
192
|
+
"BE": "dwpg", # Berlin
|
193
|
+
"MV": "dwph", # Mecklenburg-Vorpommern
|
195
194
|
}
|
196
195
|
|
197
196
|
def __init__(self, station_id):
|
198
197
|
self.etags = {}
|
199
|
-
station = load_station_id(station_id)
|
200
|
-
if station:
|
198
|
+
self.station = load_station_id(station_id)
|
199
|
+
if self.station:
|
201
200
|
self.station_id = station_id
|
202
|
-
self.station_name = station["name"]
|
203
201
|
self.region = get_region(station_id)
|
204
202
|
else:
|
205
203
|
raise ValueError("Not a valid station_id")
|
206
204
|
|
207
205
|
def get_station_name(self):
|
208
|
-
return self.
|
206
|
+
return self.station["name"]
|
209
207
|
|
210
208
|
def is_in_timerange(self, timestamp: datetime):
|
211
209
|
return (
|
@@ -480,15 +478,9 @@ class Weather:
|
|
480
478
|
def get_day_values(self, timestamp: datetime):
|
481
479
|
"timestamp has to be checked prior to be in timerange"
|
482
480
|
result = []
|
483
|
-
first_entry_date =
|
484
|
-
|
485
|
-
|
486
|
-
0:6
|
487
|
-
]
|
488
|
-
),
|
489
|
-
0,
|
490
|
-
timezone.utc,
|
491
|
-
)
|
481
|
+
first_entry_date = arrow.get(
|
482
|
+
next(iter(self.forecast_data)), "YYYY-MM-DDTHH:mm:ss.SSSZ"
|
483
|
+
).datetime
|
492
484
|
if timestamp.day != first_entry_date.day:
|
493
485
|
time_step = self.strip_to_day(timestamp)
|
494
486
|
for _ in range(24):
|
@@ -635,17 +627,10 @@ class Weather:
|
|
635
627
|
placemark.clear()
|
636
628
|
|
637
629
|
def parse_issue_time(self, tree):
|
638
|
-
issue_time_new =
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
"%Y-%m-%dT%H:%M:%S.%fZ",
|
643
|
-
)[0:6]
|
644
|
-
),
|
645
|
-
0,
|
646
|
-
timezone.utc,
|
647
|
-
)
|
648
|
-
|
630
|
+
issue_time_new = arrow.get(
|
631
|
+
tree.xpath("//dwd:IssueTime", namespaces=self.namespaces)[0].text,
|
632
|
+
"YYYY-MM-DDTHH:mm:ss.SSSZ",
|
633
|
+
).datetime
|
649
634
|
return issue_time_new
|
650
635
|
|
651
636
|
def parse_station_name(self, tree):
|
@@ -748,8 +733,10 @@ class Weather:
|
|
748
733
|
* 1e3
|
749
734
|
if row[WeatherDataType.VISIBILITY.value[1]] != self.NOT_AVAILABLE
|
750
735
|
else None,
|
751
|
-
WeatherDataType.SUN_IRRADIANCE.value[0]:
|
752
|
-
row[WeatherDataType.SUN_IRRADIANCE.value[1]].replace(",", ".")
|
736
|
+
WeatherDataType.SUN_IRRADIANCE.value[0]: round(
|
737
|
+
float(row[WeatherDataType.SUN_IRRADIANCE.value[1]].replace(",", "."))
|
738
|
+
* 3.6,
|
739
|
+
1,
|
753
740
|
)
|
754
741
|
if row[WeatherDataType.SUN_IRRADIANCE.value[1]] != self.NOT_AVAILABLE
|
755
742
|
else None,
|
{simple_dwd_weatherforecast-2.0.21.dist-info → simple_dwd_weatherforecast-2.0.23.dist-info}/RECORD
RENAMED
@@ -1,5 +1,5 @@
|
|
1
1
|
simple_dwd_weatherforecast/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
simple_dwd_weatherforecast/dwdforecast.py,sha256=
|
2
|
+
simple_dwd_weatherforecast/dwdforecast.py,sha256=wWXUDgG_QCsBXsQevJCUgAiiUNap465jl1jH3XXNR04,29636
|
3
3
|
simple_dwd_weatherforecast/dwdmap.py,sha256=lf9TtO9Hs70tVnAUrAEDc42GdAkCSfMK5B0HQn1inJk,2457
|
4
4
|
simple_dwd_weatherforecast/stations.json,sha256=HJVtV-06ToIeJ0mzjlxqM8GAjIEdai5cVazhfaYiU1c,838460
|
5
5
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -23,16 +23,16 @@ tests/test_is_in_timerange.py,sha256=Zy8YwO_O272IwjdrGKfqARw5EPnIdhZM5e648bBXaWQ
|
|
23
23
|
tests/test_is_valid_timeframe.py,sha256=lmQTapM6BztqFEgei-JTuuETq5ZhscPzxqT2Y2_u3Ak,928
|
24
24
|
tests/test_location_tools.py,sha256=wto_XzVnARJQ-Qc83YAn0ahfMBSaOHpfzqAeKRDsNm8,1208
|
25
25
|
tests/test_map.py,sha256=Bnf7XSap7xAfozE5U9aB0GjjMiHmXrpyJPE79VmEvFg,830
|
26
|
-
tests/test_parsekml.py,sha256=
|
26
|
+
tests/test_parsekml.py,sha256=Y0EHJi5e8lqFUS8N9yfA5ByQkKV4-iyrwUaIipQpM7w,1065
|
27
27
|
tests/test_region.py,sha256=KJeRkQ5bcaJOjj7MvGuTPhSp2luXxE1aVx3AMN9OOLM,615
|
28
28
|
tests/test_reported_weather.py,sha256=ULg4ogZRxus01p2rdxiSFL75AisqtcvnLDOc7uJMBH0,767
|
29
29
|
tests/test_station.py,sha256=LhiiBov0vL0dWDGCJlspWKREmjBtek3XTnX5j3rGURY,887
|
30
30
|
tests/test_stationsfile.py,sha256=slRH5N4Gznr6tkN2oMFWJbVCw3Xrma7Hvzn1lG5E-Qg,1401
|
31
|
-
tests/test_update.py,sha256=
|
31
|
+
tests/test_update.py,sha256=JMdlN_lc9Zb58yU4GNrO_sOaKN9pZEx8nt4E2UeKBi0,7254
|
32
32
|
tests/test_update_hourly.py,sha256=Zx0e_E2n2Wi1yGMDN6TURzIbk_xVYaMc-7IDK1sC5UY,1668
|
33
33
|
tests/test_weather.py,sha256=X0YABiIvKJzysLhiPv3bLiuhGRf_O3e92OQW8qSU7es,695
|
34
|
-
simple_dwd_weatherforecast-2.0.
|
35
|
-
simple_dwd_weatherforecast-2.0.
|
36
|
-
simple_dwd_weatherforecast-2.0.
|
37
|
-
simple_dwd_weatherforecast-2.0.
|
38
|
-
simple_dwd_weatherforecast-2.0.
|
34
|
+
simple_dwd_weatherforecast-2.0.23.dist-info/LICENCE,sha256=27UG7gteqvSWuZlsbIq2_OAbh7VyifGGl-1zpuUoBcw,1072
|
35
|
+
simple_dwd_weatherforecast-2.0.23.dist-info/METADATA,sha256=LmrduyelA2jzS5Zjc5r7xeEwG6A0kw8SbJDSwKidUO8,10490
|
36
|
+
simple_dwd_weatherforecast-2.0.23.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92
|
37
|
+
simple_dwd_weatherforecast-2.0.23.dist-info/top_level.txt,sha256=iyEobUh14Tzitx39Oi8qm0NhBrnZovl_dNKtvLUkLEM,33
|
38
|
+
simple_dwd_weatherforecast-2.0.23.dist-info/RECORD,,
|
tests/test_parsekml.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
from datetime import datetime, timezone
|
1
2
|
import unittest
|
2
3
|
|
3
4
|
from simple_dwd_weatherforecast import dwdforecast
|
@@ -15,6 +16,7 @@ class KMLParseTestCase(unittest.TestCase):
|
|
15
16
|
with open(self.FILE_NAME, "rb") as kml:
|
16
17
|
self.dwd_weather.parse_kml(kml)
|
17
18
|
self.assertEqual(self.dwd_weather.forecast_data, dummy_data.parsed_data)
|
19
|
+
self.assertEqual(self.dwd_weather.issue_time, datetime(2020, 11, 6, 3, 0, tzinfo=timezone.utc))
|
18
20
|
|
19
21
|
|
20
22
|
class KMLParseFullTestCase(unittest.TestCase):
|
tests/test_update.py
CHANGED
@@ -13,35 +13,44 @@ class WeatherUpdate(unittest.TestCase):
|
|
13
13
|
self.dwd_weather.station_name = "BAD HOMBURG"
|
14
14
|
|
15
15
|
@patch(
|
16
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_report",
|
16
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_report",
|
17
|
+
return_value=None,
|
17
18
|
)
|
18
19
|
@patch(
|
19
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_weather_report",
|
20
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_weather_report",
|
21
|
+
return_value=None,
|
20
22
|
)
|
21
23
|
def test_download(self, _1, _2):
|
22
24
|
self.dwd_weather.update()
|
23
25
|
self.assertIsNotNone(self.dwd_weather.forecast_data)
|
24
26
|
|
25
27
|
@patch(
|
26
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_report",
|
28
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_report",
|
29
|
+
return_value=None,
|
27
30
|
)
|
28
31
|
@patch(
|
29
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_weather_report",
|
32
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_weather_report",
|
33
|
+
return_value=None,
|
30
34
|
)
|
31
35
|
@patch(
|
32
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_kml",
|
36
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_kml",
|
37
|
+
return_value=None,
|
33
38
|
)
|
34
39
|
def test_issue_time_none(self, mock_function, _1, _2):
|
35
40
|
self.dwd_weather.update()
|
36
41
|
mock_function.assert_called()
|
42
|
+
|
37
43
|
@patch(
|
38
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_report",
|
44
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_report",
|
45
|
+
return_value=None,
|
39
46
|
)
|
40
47
|
@patch(
|
41
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_weather_report",
|
48
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_weather_report",
|
49
|
+
return_value=None,
|
42
50
|
)
|
43
51
|
@patch(
|
44
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_kml",
|
52
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_kml",
|
53
|
+
return_value=None,
|
45
54
|
)
|
46
55
|
def test_issue_time_old(self, mock_function, _1, _2):
|
47
56
|
self.dwd_weather.issue_time = datetime(
|
@@ -53,13 +62,16 @@ class WeatherUpdate(unittest.TestCase):
|
|
53
62
|
mock_function.assert_called()
|
54
63
|
|
55
64
|
@patch(
|
56
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_report",
|
65
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_report",
|
66
|
+
return_value=None,
|
57
67
|
)
|
58
68
|
@patch(
|
59
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_weather_report",
|
69
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_weather_report",
|
70
|
+
return_value=None,
|
60
71
|
)
|
61
72
|
@patch(
|
62
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_kml",
|
73
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_kml",
|
74
|
+
return_value=None,
|
63
75
|
)
|
64
76
|
@patch(
|
65
77
|
"simple_dwd_weatherforecast.dwdforecast.Weather.parse_kml", return_value=None
|
@@ -72,7 +84,7 @@ class WeatherUpdate(unittest.TestCase):
|
|
72
84
|
|
73
85
|
class WeatherDownload(unittest.TestCase):
|
74
86
|
@patch(
|
75
|
-
|
87
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.parse_kml", return_value=None
|
76
88
|
)
|
77
89
|
def test_etag_valid(self, mock_function):
|
78
90
|
stationid = "H889"
|
@@ -83,18 +95,20 @@ class WeatherDownload(unittest.TestCase):
|
|
83
95
|
mock_function.assert_called_once()
|
84
96
|
|
85
97
|
@patch(
|
86
|
-
|
98
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.parse_kml", return_value=None
|
87
99
|
)
|
88
100
|
def test_etag_invalid(self, mock_function):
|
89
101
|
stationid = "H889"
|
90
102
|
self.dwd_weather = dwdforecast.Weather(stationid)
|
91
103
|
self.dwd_weather.etags = {}
|
92
|
-
self.dwd_weather.etags[
|
104
|
+
self.dwd_weather.etags[
|
105
|
+
"https://opendata.dwd.de/weather/local_forecasts/mos/MOSMIX_L/single_stations/{stationid}/kml/MOSMIX_L_LATEST_{stationid}.kmz"
|
106
|
+
] = "invalid_etag"
|
93
107
|
self.dwd_weather.download_latest_kml(stationid)
|
94
108
|
mock_function.assert_called()
|
95
109
|
|
96
110
|
@patch(
|
97
|
-
|
111
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.parse_kml", return_value=None
|
98
112
|
)
|
99
113
|
def test_etag_missing(self, mock_function):
|
100
114
|
stationid = "H889"
|
@@ -104,13 +118,16 @@ class WeatherDownload(unittest.TestCase):
|
|
104
118
|
mock_function.assert_called()
|
105
119
|
|
106
120
|
@patch(
|
107
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_report",
|
121
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_report",
|
122
|
+
return_value=None,
|
108
123
|
)
|
109
124
|
@patch(
|
110
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_weather_report",
|
125
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_weather_report",
|
126
|
+
return_value=None,
|
111
127
|
)
|
112
128
|
@patch(
|
113
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_kml",
|
129
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_kml",
|
130
|
+
return_value=None,
|
114
131
|
)
|
115
132
|
@patch(
|
116
133
|
"simple_dwd_weatherforecast.dwdforecast.Weather.parse_kml", return_value=None
|
@@ -121,13 +138,16 @@ class WeatherDownload(unittest.TestCase):
|
|
121
138
|
mock_download_latest_report.assert_not_called()
|
122
139
|
|
123
140
|
@patch(
|
124
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_report",
|
141
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_report",
|
142
|
+
return_value=None,
|
125
143
|
)
|
126
144
|
@patch(
|
127
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_weather_report",
|
145
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_weather_report",
|
146
|
+
return_value=None,
|
128
147
|
)
|
129
148
|
@patch(
|
130
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_kml",
|
149
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_kml",
|
150
|
+
return_value=None,
|
131
151
|
)
|
132
152
|
@patch(
|
133
153
|
"simple_dwd_weatherforecast.dwdforecast.Weather.parse_kml", return_value=None
|
@@ -138,13 +158,16 @@ class WeatherDownload(unittest.TestCase):
|
|
138
158
|
mock_download_latest_report.assert_called()
|
139
159
|
|
140
160
|
@patch(
|
141
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_report",
|
161
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_report",
|
162
|
+
return_value=None,
|
142
163
|
)
|
143
164
|
@patch(
|
144
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_weather_report",
|
165
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_weather_report",
|
166
|
+
return_value=None,
|
145
167
|
)
|
146
168
|
@patch(
|
147
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_kml",
|
169
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_kml",
|
170
|
+
return_value=None,
|
148
171
|
)
|
149
172
|
@patch(
|
150
173
|
"simple_dwd_weatherforecast.dwdforecast.Weather.parse_kml", return_value=None
|
@@ -156,13 +179,16 @@ class WeatherDownload(unittest.TestCase):
|
|
156
179
|
mock_download_weather_report.assert_called()
|
157
180
|
|
158
181
|
@patch(
|
159
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_report",
|
182
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_report",
|
183
|
+
return_value=None,
|
160
184
|
)
|
161
185
|
@patch(
|
162
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_weather_report",
|
186
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_weather_report",
|
187
|
+
return_value=None,
|
163
188
|
)
|
164
189
|
@patch(
|
165
|
-
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_kml",
|
190
|
+
"simple_dwd_weatherforecast.dwdforecast.Weather.download_latest_kml",
|
191
|
+
return_value=None,
|
166
192
|
)
|
167
193
|
@patch(
|
168
194
|
"simple_dwd_weatherforecast.dwdforecast.Weather.parse_kml", return_value=None
|
@@ -171,4 +197,9 @@ class WeatherDownload(unittest.TestCase):
|
|
171
197
|
self.dwd_weather = dwdforecast.Weather("01008")
|
172
198
|
self.dwd_weather.region = None
|
173
199
|
self.dwd_weather.update()
|
174
|
-
mock_download_weather_report.assert_not_called()
|
200
|
+
mock_download_weather_report.assert_not_called()
|
201
|
+
|
202
|
+
def test_weather_report_available(self):
|
203
|
+
self.dwd_weather = dwdforecast.Weather("10739")
|
204
|
+
self.dwd_weather.update(with_report=True)
|
205
|
+
self.assertIsNotNone(self.dwd_weather.weather_report)
|
{simple_dwd_weatherforecast-2.0.21.dist-info → simple_dwd_weatherforecast-2.0.23.dist-info}/LICENCE
RENAMED
File without changes
|
File without changes
|