3
3
import logging
4
4
from datetime import datetime , timedelta
5
5
from io import BytesIO
6
- from typing import List
6
+ from typing import List , Tuple
7
7
8
8
import async_timeout
9
9
import pytz
10
10
from homeassistant .components .weather import Forecast
11
+ from homeassistant .components .zone import Zone
11
12
from homeassistant .const import ATTR_LATITUDE , ATTR_LONGITUDE
13
+ from homeassistant .core import HomeAssistant
12
14
from homeassistant .helpers .aiohttp_client import async_get_clientsession
13
15
from homeassistant .helpers .update_coordinator import (DataUpdateCoordinator ,
14
16
UpdateFailed )
26
28
class IrmKmiCoordinator (DataUpdateCoordinator ):
27
29
"""Coordinator to update data from IRM KMI"""
28
30
29
- def __init__ (self , hass , zone ):
31
+ def __init__ (self , hass : HomeAssistant , zone : Zone ):
30
32
"""Initialize my coordinator."""
31
33
super ().__init__ (
32
34
hass ,
@@ -89,6 +91,15 @@ async def _async_animation_data(self, api_data: dict) -> RadarAnimationData:
89
91
radar_animation ['hint' ] = api_data .get ('animation' , {}).get ('sequenceHint' , {}).get ('en' )
90
92
return radar_animation
91
93
94
+ async def process_api_data (self , api_data : dict ) -> ProcessedCoordinatorData :
95
+
96
+ return ProcessedCoordinatorData (
97
+ current_weather = IrmKmiCoordinator .current_weather_from_data (api_data ),
98
+ daily_forecast = IrmKmiCoordinator .daily_list_to_forecast (api_data .get ('for' , {}).get ('daily' )),
99
+ hourly_forecast = IrmKmiCoordinator .hourly_list_to_forecast (api_data .get ('for' , {}).get ('hourly' )),
100
+ animation = await self ._async_animation_data (api_data = api_data )
101
+ )
102
+
92
103
async def download_images_from_api (self , animation_data , country , localisation_layer_url ):
93
104
coroutines = list ()
94
105
coroutines .append (self ._api_client .get_image (f"{ localisation_layer_url } &th={ 'd' if country == 'NL' else 'n' } " ))
@@ -101,18 +112,28 @@ async def download_images_from_api(self, animation_data, country, localisation_l
101
112
_LOGGER .debug (f"Just downloaded { len (images_from_api )} images" )
102
113
return images_from_api
103
114
104
- async def merge_frames_from_api (self , animation_data , country , images_from_api ,
105
- localisation_layer ) -> RadarAnimationData :
115
+ async def merge_frames_from_api (self ,
116
+ animation_data : List [dict ],
117
+ country : str ,
118
+ images_from_api : Tuple [bytes ],
119
+ localisation_layer : Image
120
+ ) -> RadarAnimationData :
121
+
122
+ background : Image
123
+ fill_color : tuple
106
124
107
125
if country == 'NL' :
108
126
background = Image .open ("custom_components/irm_kmi/resources/nl.png" ).convert ('RGBA' )
127
+ fill_color = (0 , 0 , 0 )
109
128
else :
110
129
background = Image .open ("custom_components/irm_kmi/resources/be_bw.png" ).convert ('RGBA' )
130
+ fill_color = (255 , 255 , 255 )
111
131
112
132
most_recent_frame = None
113
133
tz = pytz .timezone (self .hass .config .time_zone )
114
134
current_time = datetime .now (tz = tz )
115
135
sequence : List [AnimationFrameData ] = list ()
136
+
116
137
for (idx , sequence_element ) in enumerate (animation_data ):
117
138
frame = images_from_api [idx ]
118
139
layer = Image .open (BytesIO (frame )).convert ('RGBA' )
@@ -126,10 +147,7 @@ async def merge_frames_from_api(self, animation_data, country, images_from_api,
126
147
127
148
time_str = time_image .isoformat (sep = ' ' , timespec = 'minutes' )
128
149
129
- if country == 'NL' :
130
- draw .text ((4 , 4 ), time_str , (0 , 0 , 0 ), font = font )
131
- else :
132
- draw .text ((4 , 4 ), time_str , (255 , 255 , 255 ), font = font )
150
+ draw .text ((4 , 4 ), time_str , fill_color , font = font )
133
151
134
152
bytes_img = BytesIO ()
135
153
temp .save (bytes_img , 'png' , compress_level = 8 )
@@ -154,15 +172,6 @@ async def merge_frames_from_api(self, animation_data, country, images_from_api,
154
172
most_recent_image = most_recent_frame
155
173
)
156
174
157
- async def process_api_data (self , api_data : dict ) -> ProcessedCoordinatorData :
158
-
159
- return ProcessedCoordinatorData (
160
- current_weather = IrmKmiCoordinator .current_weather_from_data (api_data ),
161
- daily_forecast = IrmKmiCoordinator .daily_list_to_forecast (api_data .get ('for' , {}).get ('daily' )),
162
- hourly_forecast = IrmKmiCoordinator .hourly_list_to_forecast (api_data .get ('for' , {}).get ('hourly' )),
163
- animation = await self ._async_animation_data (api_data = api_data )
164
- )
165
-
166
175
@staticmethod
167
176
def current_weather_from_data (api_data : dict ) -> CurrentWeatherData :
168
177
# Process data to get current hour forecast
@@ -183,7 +192,6 @@ def current_weather_from_data(api_data: dict) -> CurrentWeatherData:
183
192
if module .get ('type' , None ) == 'uv' :
184
193
uv_index = module .get ('data' , {}).get ('levelValue' )
185
194
186
- # TODO NL cities have a better 'obs' section, use that for current weather
187
195
current_weather = CurrentWeatherData (
188
196
condition = CDT_MAP .get ((api_data .get ('obs' , {}).get ('ww' ), api_data .get ('obs' , {}).get ('dayNight' )), None ),
189
197
temperature = api_data .get ('obs' , {}).get ('temp' ),
@@ -193,6 +201,11 @@ def current_weather_from_data(api_data: dict) -> CurrentWeatherData:
193
201
pressure = now_hourly .get ('pressure' , None ) if now_hourly is not None else None ,
194
202
uv_index = uv_index
195
203
)
204
+
205
+ if api_data .get ('country' , '' ) == 'NL' :
206
+ current_weather ['wind_speed' ] = api_data .get ('obs' , {}).get ('windSpeedKm' )
207
+ current_weather ['wind_bearing' ] = api_data .get ('obs' , {}).get ('windDirectionText' , {}).get ('en' )
208
+
196
209
return current_weather
197
210
198
211
@staticmethod
0 commit comments