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.
@@ -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 time
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
- "DW": "dwsg",
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.station_name
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 = datetime(
484
- *(
485
- time.strptime(next(iter(self.forecast_data)), "%Y-%m-%dT%H:%M:%S.%fZ")[
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 = datetime(
639
- *(
640
- time.strptime(
641
- tree.xpath("//dwd:IssueTime", namespaces=self.namespaces)[0].text,
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]: float(
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,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: simple-dwd-weatherforecast
3
- Version: 2.0.21
3
+ Version: 2.0.23
4
4
  Summary: A simple tool to retrieve a weather forecast from DWD OpenData
5
5
  Home-page: https://github.com/FL550/simple_dwd_weatherforecast.git
6
6
  Author: Max Fermor
@@ -1,5 +1,5 @@
1
1
  simple_dwd_weatherforecast/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- simple_dwd_weatherforecast/dwdforecast.py,sha256=9dvEzIZ1_gGombKDONK2C3sGn9QnrJRWMZNhYBob_Vc,29642
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=FZE1GHuEJfGfKDZlyhkBytsqEFl6HhYrPhS7MjVsSHo,917
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=sVJVoj1M0sz754t9CDzXpx1yaNe_CIRjV9SmIBxS3LE,6805
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.21.dist-info/LICENCE,sha256=27UG7gteqvSWuZlsbIq2_OAbh7VyifGGl-1zpuUoBcw,1072
35
- simple_dwd_weatherforecast-2.0.21.dist-info/METADATA,sha256=0fbsmn_i5NoRbDxRVNARSnA_px56TpruNJpxhT9bFe8,10490
36
- simple_dwd_weatherforecast-2.0.21.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
37
- simple_dwd_weatherforecast-2.0.21.dist-info/top_level.txt,sha256=iyEobUh14Tzitx39Oi8qm0NhBrnZovl_dNKtvLUkLEM,33
38
- simple_dwd_weatherforecast-2.0.21.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.2)
2
+ Generator: bdist_wheel (0.41.3)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
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", return_value=None
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", return_value=None,
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", return_value=None
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", return_value=None,
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", return_value=None
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", return_value=None
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", return_value=None,
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", return_value=None
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", return_value=None
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", return_value=None,
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", return_value=None
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
- "simple_dwd_weatherforecast.dwdforecast.Weather.parse_kml", return_value=None
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
- "simple_dwd_weatherforecast.dwdforecast.Weather.parse_kml", return_value=None
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["https://opendata.dwd.de/weather/local_forecasts/mos/MOSMIX_L/single_stations/{stationid}/kml/MOSMIX_L_LATEST_{stationid}.kmz"] = "invalid_etag"
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
- "simple_dwd_weatherforecast.dwdforecast.Weather.parse_kml", return_value=None
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", return_value=None
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", return_value=None,
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", return_value=None
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", return_value=None
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", return_value=None,
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", return_value=None
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", return_value=None
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", return_value=None,
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", return_value=None
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", return_value=None
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", return_value=None,
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", return_value=None
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)