6
6
7
7
from asyncio import Task
8
8
from typing import Any
9
-
9
+ import json
10
10
import aiohttp
11
11
from aiohttp import CookieJar , ClientSession , ClientTimeout
12
12
13
13
from .exceptions import CloudError
14
14
from .model import (
15
- IntelliFireFireplaceCloud ,
16
15
IntelliFireUserData ,
17
16
)
18
17
from .model import IntelliFirePollData
19
18
20
- from .const import IntelliFireCommand , IntelliFireApiMode
19
+ from .const import IntelliFireCommand , IntelliFireApiMode , IntelliFireCloudPollType
21
20
22
21
from .control import IntelliFireController
23
22
from .read import IntelliFireDataProvider
@@ -30,6 +29,7 @@ class IntelliFireAPICloud(IntelliFireController, IntelliFireDataProvider):
30
29
"""Api for cloud access."""
31
30
32
31
_control_mode = IntelliFireApiMode .CLOUD
32
+ _poll_mode = IntelliFireCloudPollType .LONG
33
33
34
34
def __init__ (
35
35
self ,
@@ -87,8 +87,6 @@ def __init__(
87
87
# Full data set on the user
88
88
self ._user_data : IntelliFireUserData = IntelliFireUserData ()
89
89
90
- self .last_send = None
91
-
92
90
def _get_session (self , timeout_seconds : float = 10.0 ) -> ClientSession :
93
91
"""Ensure that the aiohttp ClientSession is created and open."""
94
92
timeout = ClientTimeout (timeout_seconds )
@@ -150,7 +148,7 @@ async def _send_cloud_command(
150
148
422 Invalid Parameter (invalid command id or command value)
151
149
"""
152
150
if response .status == 204 :
153
- self .last_send = datetime .now ()
151
+ self ._last_send = datetime .now ()
154
152
return
155
153
# elif (
156
154
# response.status == 403
@@ -165,7 +163,7 @@ async def _send_cloud_command(
165
163
else :
166
164
raise Exception (f"Unexpected return code { response .status } " )
167
165
168
- async def long_poll (self , fireplace : IntelliFireFireplaceCloud ) -> bool :
166
+ async def long_poll (self ) -> bool :
169
167
"""Perform a LongPoll to wait for a Status update.
170
168
171
169
Only returns a status update when the fireplace’s status actually changes (excluding normal periodic
@@ -192,30 +190,43 @@ async def long_poll(self, fireplace: IntelliFireFireplaceCloud) -> bool:
192
190
bool: `True` if status changed, `False` if it did not
193
191
"""
194
192
195
- self ._log .debug ("Long Poll: Start" )
196
-
197
- async with self ._get_session ().get (
198
- f"{ self .prefix } ://iftapi.net/a/{ self ._serial } /applongpoll" , timeout = 61
199
- ) as response :
200
- self ._log .debug ("Long Poll Status Code %d" , response .status )
201
- if response .status == 200 :
202
- self ._log .debug ("Long poll: 200 - Received data" )
203
- self .last_long_poll = datetime .now ()
204
- return True
205
- elif response .status == 408 :
206
- self ._log .debug ("Long poll: 408 - No Data changed" )
207
- self .last_long_poll = datetime .now ()
208
- return False
209
- elif response .status == 403 :
210
- raise CloudError ("Not authorized" )
211
- elif response .status == 404 :
212
- raise CloudError ("Fireplace not found (bad serial number)" )
213
- else :
214
- response_text = await response .text ()
215
- self ._log .error (
216
- f"Unexpected status code: { response .status } , Response: { response_text } "
217
- )
218
- raise CloudError (f"Unexpected status code: { response .status } " )
193
+ long_poll_url = f"{ self .prefix } ://iftapi.net/a/{ self ._serial } /applongpoll"
194
+ self ._log .debug (f"long_poll() { long_poll_url } " )
195
+
196
+ async with self ._get_session () as session :
197
+ try :
198
+ response = await session .get (long_poll_url , timeout = 61 )
199
+
200
+ self ._log .debug ("Long Poll Status Code %d" , response .status )
201
+ if response .status == 200 :
202
+ self ._log .debug ("Long poll: 200 - Received data" )
203
+
204
+ # Data has text/html header type so we need to manually convert it to json
205
+ json_data = json .loads (await response .text ())
206
+
207
+ self ._data = IntelliFirePollData (** json_data )
208
+ self ._log .debug (f"poll() complete: { self ._data } " )
209
+
210
+ self ._last_poll = datetime .now ()
211
+ return True
212
+ elif response .status == 408 :
213
+ self ._log .debug ("Long poll: 408 - No Data changed" )
214
+ self ._last_poll = datetime .now ()
215
+ return False
216
+ except aiohttp .ClientResponseError as e :
217
+ if e .status == 403 :
218
+ raise CloudError ("Not authorized" ) from e
219
+ if e .status == 404 :
220
+ raise CloudError ("Fireplace not found (bad serial number)" ) from e
221
+ else :
222
+ response_text = await response .text ()
223
+ self ._log .error (
224
+ f"Unexpected status code: { response .status } , Response: { response_text } "
225
+ )
226
+ raise CloudError (
227
+ f"Unexpected status code: { response .status } "
228
+ ) from e
229
+ return False
219
230
220
231
async def poll (self , timeout_seconds : float = 10.0 ) -> None :
221
232
"""Return a fireplace’s status in JSON.
@@ -266,8 +277,7 @@ async def poll(self, timeout_seconds: float = 10.0) -> None:
266
277
267
278
"""
268
279
269
- serial = self ._serial
270
- poll_url = f"{ self .prefix } ://iftapi.net/a/{ serial } //apppoll"
280
+ poll_url = f"{ self .prefix } ://iftapi.net/a/{ self ._serial } //apppoll"
271
281
272
282
self ._log .debug (f"poll() { poll_url } " )
273
283
async with self ._get_session () as session :
@@ -278,7 +288,7 @@ async def poll(self, timeout_seconds: float = 10.0) -> None:
278
288
self ._data = IntelliFirePollData (** json_data )
279
289
self ._log .debug (f"poll() complete: { self ._data } " )
280
290
281
- self .last_poll = datetime .now ()
291
+ self ._last_poll = datetime .now ()
282
292
283
293
except aiohttp .ClientResponseError as e :
284
294
if e .status == 403 :
@@ -324,14 +334,20 @@ async def __background_poll(self, minimum_wait_in_seconds: int = 15) -> None:
324
334
self ._log .debug ("__background_poll:: Loop start time %f" , start )
325
335
326
336
try :
327
- # new_data = await self.long_poll()
337
+ if self ._poll_mode == IntelliFireCloudPollType .LONG :
338
+ await self .long_poll ()
339
+ else :
340
+ await self .poll ()
341
+
328
342
#
329
- # if new_data:
330
- # self._log.debug(self.data)
343
+ # # has_new_data = await self.long_poll()
344
+ # #
345
+ # # if new_data:
346
+ # # self._log.debug(self.data)
347
+ # #
348
+ # # Long poll didn't seem to be working so switched to normal polling again
331
349
#
332
- # Long poll didn't seem to be working so switched to normal polling again
333
-
334
- await self .poll ()
350
+ # await self.poll()
335
351
336
352
end = time .time ()
337
353
duration : float = end - start
@@ -361,3 +377,7 @@ def data(self) -> IntelliFirePollData:
361
377
): # pragma: no cover - the tests SHOULD be hitting this but dont appear to be
362
378
self ._log .warning ("Returning uninitialized poll data" ) # pragma: no cover
363
379
return self ._data
380
+
381
+ def set_poll_mode (self , mode : IntelliFireCloudPollType ):
382
+ """Set the poll mode."""
383
+ self ._poll_mode = mode
0 commit comments