simple-dwd-weatherforecast 2.0.31__py3-none-any.whl → 2.0.32__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.
@@ -546,6 +546,15 @@ class Weather:
546
546
  )
547
547
  return None
548
548
 
549
+ def get_daily_avg(
550
+ self, weatherDataType: WeatherDataType, timestamp: datetime, shouldUpdate=True
551
+ ):
552
+ if shouldUpdate:
553
+ self.update()
554
+ if self.is_in_timerange(timestamp):
555
+ return self.get_avg(self.get_day_values(timestamp), weatherDataType)
556
+ return None
557
+
549
558
  def get_avg(_, weather_data, weatherDataType):
550
559
  value_sum = 0.0
551
560
  count = len(weather_data)
@@ -586,20 +595,16 @@ class Weather:
586
595
  time_step += timedelta(hours=1)
587
596
  else:
588
597
  time_step = first_entry_date
589
- endtime = (
590
- datetime(
591
- time_step.year,
592
- time_step.month,
593
- time_step.day,
594
- 0,
595
- 0,
596
- 0,
597
- 0,
598
- timezone.utc,
599
- )
600
- + timedelta(days=1)
601
- + timedelta(hours=-1)
602
- )
598
+ endtime = datetime(
599
+ time_step.year,
600
+ time_step.month,
601
+ time_step.day,
602
+ 0,
603
+ 0,
604
+ 0,
605
+ 0,
606
+ timezone.utc,
607
+ ) + timedelta(days=1)
603
608
  timediff = endtime - time_step
604
609
  for _ in range(round(timediff.total_seconds() / 3600)):
605
610
  result.append(self.forecast_data[self.strip_to_hour_str(time_step)])
@@ -15,6 +15,7 @@ class WeatherMapType(Enum):
15
15
  WARNUNGEN_GEMEINDEN = "dwd:Warnungen_Gemeinden"
16
16
  WARNUNGEN_KREISE = "dwd:Warnungen_Landkreise"
17
17
 
18
+
18
19
  class WeatherBackgroundMapType(Enum):
19
20
  LAENDER = "dwd:Laender"
20
21
  BUNDESLAENDER = "dwd:Warngebiete_Bundeslaender"
@@ -23,7 +24,16 @@ class WeatherBackgroundMapType(Enum):
23
24
  SATELLIT = "dwd:bluemarble"
24
25
  GEWAESSER = "dwd:Gewaesser"
25
26
 
26
- def get_from_location(longitude, latitude, radius_km, map_type: WeatherMapType, background_type: WeatherBackgroundMapType = WeatherBackgroundMapType.BUNDESLAENDER, image_width=520, image_height=580):
27
+
28
+ def get_from_location(
29
+ longitude,
30
+ latitude,
31
+ radius_km,
32
+ map_type: WeatherMapType,
33
+ background_type: WeatherBackgroundMapType = WeatherBackgroundMapType.BUNDESLAENDER,
34
+ image_width=520,
35
+ image_height=580,
36
+ ):
27
37
  if radius_km <= 0:
28
38
  raise ValueError("Radius must be greater than 0")
29
39
  if latitude < -90 or latitude > 90:
@@ -31,17 +41,46 @@ def get_from_location(longitude, latitude, radius_km, map_type: WeatherMapType,
31
41
  if longitude < -180 or longitude > 180:
32
42
  raise ValueError("Longitude must be between -180 and 180")
33
43
  radius = math.fabs(radius_km / (111.3 * math.cos(latitude)))
34
- return get_map(latitude-radius, longitude-radius, latitude+radius, longitude+radius, map_type, background_type, image_width, image_height)
44
+ return get_map(
45
+ latitude - radius,
46
+ longitude - radius,
47
+ latitude + radius,
48
+ longitude + radius,
49
+ map_type,
50
+ background_type,
51
+ image_width,
52
+ image_height,
53
+ )
54
+
55
+
56
+ def get_germany(
57
+ map_type: WeatherMapType,
58
+ background_type: WeatherBackgroundMapType = WeatherBackgroundMapType.BUNDESLAENDER,
59
+ image_width=520,
60
+ image_height=580,
61
+ ):
62
+ return get_map(
63
+ 4.4, 46.4, 16.1, 55.6, map_type, background_type, image_width, image_height
64
+ )
35
65
 
36
- def get_germany(map_type: WeatherMapType, background_type: WeatherBackgroundMapType = WeatherBackgroundMapType.BUNDESLAENDER, image_width=520, image_height=580):
37
- return get_map(4.4, 46.4, 16.1, 55.6, map_type, background_type, image_width, image_height)
38
66
 
39
- def get_map(minx,miny,maxx,maxy, map_type: WeatherMapType, background_type: WeatherBackgroundMapType, image_width=520, image_height=580):
67
+ def get_map(
68
+ minx,
69
+ miny,
70
+ maxx,
71
+ maxy,
72
+ map_type: WeatherMapType,
73
+ background_type: WeatherBackgroundMapType,
74
+ image_width=520,
75
+ image_height=580,
76
+ ):
40
77
  if image_width > 1200 or image_height > 1400:
41
- raise ValueError("Width and height must not exceed 1200 and 1400 respectively. Please be kind to the DWD servers.")
78
+ raise ValueError(
79
+ "Width and height must not exceed 1200 and 1400 respectively. Please be kind to the DWD servers."
80
+ )
42
81
 
43
- url = f"https://maps.dwd.de/geoserver/dwd/wms?service=WMS&version=1.1.0&request=GetMap&layers={background_type.value},{map_type.value}&bbox={minx},{miny},{maxx},{maxy}&width={image_width}&height={image_height}&srs=EPSG:4326&styles=&format=image/png"
82
+ url = f"https://maps.dwd.de/geoserver/dwd/wms?service=WMS&version=1.1.0&request=GetMap&layers={map_type.value},{background_type.value}&bbox={minx},{miny},{maxx},{maxy}&width={image_width}&height={image_height}&srs=EPSG:4326&styles=&format=image/png"
44
83
  request = requests.get(url, stream=True)
45
84
  if request.status_code == 200:
46
85
  image = Image.open(BytesIO(request.content))
47
- return image
86
+ return image
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: simple_dwd_weatherforecast
3
- Version: 2.0.31
3
+ Version: 2.0.32
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
@@ -127,6 +127,8 @@ class Weather:
127
127
 
128
128
  get_timeframe_sum(weatherDataType: see WeatherDataType, datetime, timeframe: hours after datetime as int, optional bool shouldUpdate) # Returns the sum of that value within the time frame
129
129
 
130
+ get_daily_avg(weatherDataType: see WeatherDataType, datetime, optional bool shouldUpdate) # Returns the daily average of that value
131
+
130
132
  get_timeframe_avg(weatherDataType: see WeatherDataType, datetime, timeframe: hours after datetime as int, optional bool shouldUpdate) # Returns the average of that value within the time frame
131
133
 
132
134
  get_forecast_condition(datetime, optional bool shouldUpdate) # Result is condition as text
@@ -1,17 +1,18 @@
1
1
  simple_dwd_weatherforecast/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- simple_dwd_weatherforecast/dwdforecast.py,sha256=ZTKS32lRedjzNucZHZ0w9bBuzJd3--EibU9wG6Au_M4,35282
3
- simple_dwd_weatherforecast/dwdmap.py,sha256=bFAZfYjUryZkErJ3aDNRm9ZhNwKGMcy4pEl8TnWJKzA,2476
2
+ simple_dwd_weatherforecast/dwdforecast.py,sha256=45-nCx_amQE0lQH31aSZGYc51Va5AabKGN4OhfAkuPQ,35474
3
+ simple_dwd_weatherforecast/dwdmap.py,sha256=k6TTTMO6Db-qhaZhZwGssmYM5R9GUFcNxg4J8a3_J78,2684
4
4
  simple_dwd_weatherforecast/stations.json,sha256=1u8qc2CT_rVy49SAlOicGixzHln6Y0FXevuFAz2maBw,838948
5
5
  simple_dwd_weatherforecast/uv_stations.json,sha256=ADenYo-aR6qbf0UFkfYr72kkFzL9HyUKe4VQ23POGF8,2292
6
6
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  tests/dummy_data.py,sha256=sF8pXxq8innSpRc4lW0XxGcr34dESSAoBdAf2F2D4AI,63395
8
8
  tests/dummy_data_full.py,sha256=IwYoeqVX8cpfn_gE-7arXaWV9btRm_HHqka_LfKqW-E,64053
9
9
  tests/dummy_uv.py,sha256=TM1TwvNq_ea4WgIJyYsNAEXZJTx1dXH1ZVrW_LfLBLg,4548
10
+ tests/test_get_daily_avg.py,sha256=ZD4mT7HLjzsFnb0DOLbi4U3sGMOCBSj49WYVbNGN7GQ,1997
10
11
  tests/test_get_daily_condition.py,sha256=J_0gg9fejPqESP7Np5wl5kr7wwcm04a-G1Txx4JH02g,2043
11
12
  tests/test_get_daily_max.py,sha256=vC873a1Uuw01a61fkvV0XKwTnkxJWkrOycTOSLrOp9Q,1940
12
13
  tests/test_get_daily_min.py,sha256=jYgPK-dK7P_QRBe1oNlSSZlnd-BrTDXGt5AfS-sEThw,1944
13
- tests/test_get_daily_sum.py,sha256=WeOVXl905X-n5gnPuNM6ut-q9VeBM2j2f6heBDol3Ok,1942
14
- tests/test_get_day_values.py,sha256=zn9GaLnsLA_rvk6pNApmR9ZHD_OsElU01T6oFJiqL7I,28680
14
+ tests/test_get_daily_sum.py,sha256=sViAjOq7IHs057Zr9zz36brZyFbckdasmHk1YluRNBc,1941
15
+ tests/test_get_day_values.py,sha256=iNVGP7roy5R5jGTvJNUHAIefSlXI4NBFnYVsr-WLECs,29348
15
16
  tests/test_get_forecast_condition.py,sha256=mawVIJ7xQgH9Xbz_nLnAHNS5Ib-mp-A3zLbkEllw2hw,2904
16
17
  tests/test_get_forecast_data.py,sha256=dsKtfGTlQbhB7tteBuB6d_RHEOtM7ikfVWh_Fk-CtyU,3432
17
18
  tests/test_get_station_name.py,sha256=58fBETHAgDaTAsAFP9xOcYfipNO-AqUf_n_bMj5FwWc,439
@@ -34,8 +35,8 @@ tests/test_update.py,sha256=JMdlN_lc9Zb58yU4GNrO_sOaKN9pZEx8nt4E2UeKBi0,7254
34
35
  tests/test_update_hourly.py,sha256=Zx0e_E2n2Wi1yGMDN6TURzIbk_xVYaMc-7IDK1sC5UY,1668
35
36
  tests/test_uv_index.py,sha256=tr6wnOyHlXT1S3yp1oeHc4-Brmc-EMEdM4mtyrdpcHg,579
36
37
  tests/test_weather.py,sha256=U4FkTtqLcLs8k-xy6YKNM_4HVscITymURCEIUShk6iE,802
37
- simple_dwd_weatherforecast-2.0.31.dist-info/LICENCE,sha256=27UG7gteqvSWuZlsbIq2_OAbh7VyifGGl-1zpuUoBcw,1072
38
- simple_dwd_weatherforecast-2.0.31.dist-info/METADATA,sha256=qVASoG2VqxxpKIKQ7-6m1yYBVL1nQYu7CqBO_7SgdO4,10800
39
- simple_dwd_weatherforecast-2.0.31.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
40
- simple_dwd_weatherforecast-2.0.31.dist-info/top_level.txt,sha256=iyEobUh14Tzitx39Oi8qm0NhBrnZovl_dNKtvLUkLEM,33
41
- simple_dwd_weatherforecast-2.0.31.dist-info/RECORD,,
38
+ simple_dwd_weatherforecast-2.0.32.dist-info/LICENCE,sha256=27UG7gteqvSWuZlsbIq2_OAbh7VyifGGl-1zpuUoBcw,1072
39
+ simple_dwd_weatherforecast-2.0.32.dist-info/METADATA,sha256=o3F9zUnLganqA2_Sue4bhUjktjMePFwFw9YAjDD5lFU,10937
40
+ simple_dwd_weatherforecast-2.0.32.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
41
+ simple_dwd_weatherforecast-2.0.32.dist-info/top_level.txt,sha256=iyEobUh14Tzitx39Oi8qm0NhBrnZovl_dNKtvLUkLEM,33
42
+ simple_dwd_weatherforecast-2.0.32.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (71.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,48 @@
1
+ from simple_dwd_weatherforecast.dwdforecast import WeatherDataType
2
+ import unittest
3
+ from unittest.mock import patch
4
+ from datetime import datetime
5
+ from simple_dwd_weatherforecast import dwdforecast
6
+ from dummy_data import parsed_data
7
+
8
+
9
+ class Weather_get_daily_avg(unittest.TestCase):
10
+ def setUp(self):
11
+ self.dwd_weather = dwdforecast.Weather("H889")
12
+ self.dwd_weather.forecast_data = parsed_data
13
+ self.dwd_weather.station_name = "BAD HOMBURG"
14
+
15
+ @patch("simple_dwd_weatherforecast.dwdforecast.Weather.update", return_value=None)
16
+ def test_shouldupdate(self, mock_update):
17
+ test_time = datetime(2020, 11, 7, 3, 30)
18
+ self.dwd_weather.get_daily_avg(WeatherDataType.PRECIPITATION, test_time, True)
19
+ mock_update.assert_called()
20
+
21
+ @patch("simple_dwd_weatherforecast.dwdforecast.Weather.update", return_value=None)
22
+ def test_shouldupdate_not(self, mock_update):
23
+ test_time = datetime(2020, 11, 7, 3, 30)
24
+ self.dwd_weather.get_daily_avg(WeatherDataType.PRECIPITATION, test_time, False)
25
+ mock_update.assert_not_called()
26
+
27
+ def test_not_in_timerange(self):
28
+ test_time = datetime(2000, 11, 7, 3, 30)
29
+ self.assertIsNone(
30
+ self.dwd_weather.get_daily_avg(WeatherDataType.PRECIPITATION, test_time)
31
+ )
32
+
33
+ @patch("simple_dwd_weatherforecast.dwdforecast.Weather.update", return_value=None)
34
+ def test_precipitation(self, mock_update):
35
+ test_time = datetime(2020, 11, 6, 12, 0)
36
+ print(self.dwd_weather.get_day_values(test_time))
37
+ self.assertEqual(
38
+ self.dwd_weather.get_daily_avg(WeatherDataType.PRECIPITATION, test_time),
39
+ 1.8,
40
+ )
41
+
42
+ @patch("simple_dwd_weatherforecast.dwdforecast.Weather.update", return_value=None)
43
+ def test_temperature(self, mock_update):
44
+ test_time = datetime(2020, 11, 6, 23, 0)
45
+ self.assertEqual(
46
+ self.dwd_weather.get_daily_avg(WeatherDataType.TEMPERATURE, test_time),
47
+ 278.09,
48
+ )
@@ -35,7 +35,7 @@ class Weather_get_daily_sum(unittest.TestCase):
35
35
  test_time = datetime(2020, 11, 6, 10, 0)
36
36
  self.assertEqual(
37
37
  self.dwd_weather.get_daily_sum(WeatherDataType.PRECIPITATION, test_time),
38
- 27.25,
38
+ 36.01,
39
39
  )
40
40
 
41
41
  @patch("simple_dwd_weatherforecast.dwdforecast.Weather.update", return_value=None)
@@ -43,5 +43,5 @@ class Weather_get_daily_sum(unittest.TestCase):
43
43
  test_time = datetime(2020, 11, 6, 10, 0)
44
44
  self.assertEqual(
45
45
  self.dwd_weather.get_daily_sum(WeatherDataType.TEMPERATURE, test_time),
46
- 5286.25,
46
+ 5561.8,
47
47
  )
@@ -451,6 +451,7 @@ class Weather_get_day_values(unittest.TestCase):
451
451
  self.dwd_weather.get_day_values(test_time),
452
452
  test_data,
453
453
  )
454
+ self.assertEqual(len(self.dwd_weather.get_day_values(test_time)), 24)
454
455
 
455
456
  def test_day_not_last_day(self):
456
457
  test_time = datetime(2020, 11, 16, 1, 0)
@@ -1004,8 +1005,27 @@ class Weather_get_day_values(unittest.TestCase):
1004
1005
  "wwM": 3.0,
1005
1006
  "humidity": 81.3,
1006
1007
  },
1008
+ {
1009
+ "TTT": 275.55,
1010
+ "Td": 273.45,
1011
+ "condition": "51",
1012
+ "PPPP": 103060.0,
1013
+ "DD": 52.0,
1014
+ "FF": 1.54,
1015
+ "FX1": 3.09,
1016
+ "RR1c": 8.76,
1017
+ "wwP": 2.0,
1018
+ "DRR1": 0.0,
1019
+ "N": 22.0,
1020
+ "VV": 15500.0,
1021
+ "SunD1": 0.0,
1022
+ "Rad1h": None,
1023
+ "wwM": 2.0,
1024
+ "humidity": 86.0,
1025
+ },
1007
1026
  ]
1008
1027
  self.assertEqual(
1009
1028
  self.dwd_weather.get_day_values(test_time),
1010
1029
  test_data,
1011
1030
  )
1031
+ self.assertEqual(len(self.dwd_weather.get_day_values(test_time)), 20)