1
1
"""KnmiApiClient"""
2
2
3
3
import asyncio
4
+ import json
5
+ import logging
4
6
import socket
5
7
6
8
import aiohttp
7
9
8
10
from .const import API_ENDPOINT , API_TIMEOUT
9
11
12
+ _LOGGER : logging .Logger = logging .getLogger (__package__ )
13
+
10
14
11
15
class KnmiApiClientError (Exception ):
12
16
"""Exception to indicate a general API error."""
@@ -27,6 +31,8 @@ class KnmiApiRateLimitError(KnmiApiClientError):
27
31
class KnmiApiClient :
28
32
"""KNMI API wrapper"""
29
33
34
+ response_text = None
35
+
30
36
def __init__ (
31
37
self ,
32
38
api_key : str ,
@@ -40,27 +46,39 @@ def __init__(
40
46
self .longitude = longitude
41
47
self ._session = session
42
48
49
+ async def get_response_text (self ) -> str :
50
+ """Get API response text"""
51
+ async with asyncio .timeout (API_TIMEOUT ):
52
+ response = await self ._session .get (
53
+ API_ENDPOINT .format (self .api_key , self .latitude , self .longitude )
54
+ )
55
+
56
+ return await response .text ()
57
+
43
58
async def async_get_data (self ) -> dict :
44
59
"""Get data from the API."""
45
60
try :
46
- async with asyncio .timeout (API_TIMEOUT ):
47
- response = await self ._session .get (
48
- API_ENDPOINT .format (self .api_key , self .latitude , self .longitude )
49
- )
61
+ self .response_text = await self .get_response_text ()
50
62
51
- response_text = await response .text ()
63
+ # The API has no proper error handling for a wrong API key or rate limit.
64
+ # Instead a 200 with a message is returned, try to detect that here.
65
+ if "Vraag eerst een API-key op" in self .response_text :
66
+ raise KnmiApiClientApiKeyError ("The given API key is invalid" )
52
67
53
- # The API has no proper error handling for a wrong API key or rate limit.
54
- # Instead a 200 with a message is returned, try to detect that here.
55
- if "Vraag eerst een API- key op" in response_text :
56
- raise KnmiApiClientApiKeyError ( "The given API key is invalid" )
68
+ if "Dagelijkse limiet" in self . response_text :
69
+ raise KnmiApiRateLimitError (
70
+ " API key daily limit exceeded, try again tomorrow"
71
+ )
57
72
58
- if "Dagelijkse limiet" in response_text :
59
- raise KnmiApiRateLimitError (
60
- "API key daily limit exceeded, try again tomorrow"
61
- )
73
+ # The API has an ongoing issue due to invalid JSON response.
74
+ # Where a null value of a number field is set to _ (without quotes).
75
+ # Here we fix the JSON by setting the value to null.
76
+ # More info: https://github.com/golles/ha-knmi/issues/130
77
+ if '": _,' in self .response_text :
78
+ _LOGGER .debug ("Detected invalid JSON, attempting to fix that..." )
79
+ return json .loads (self .response_text .replace ('": _,' , '": null,' ))
62
80
63
- return await response . json ( )
81
+ return json . loads ( self . response_text )
64
82
65
83
except asyncio .TimeoutError as exception :
66
84
raise KnmiApiClientCommunicationError (
0 commit comments