@@ -218,7 +218,24 @@ async def request(
218218 ):
219219 _LOGGER .debug ("ISY not ready or closed connection." )
220220 except aiohttp .ClientResponseError as err :
221- # Malformed framing/protocol error — retrying won't recover; bail.
221+ # Malformed framing/protocol error — retrying won't recover.
222+ # When the caller already opted into ``ok404=True`` we treat it
223+ # as another flavor of "feature not present": ISY-994 firmware
224+ # on a factory-reset / un-configured controller responds to
225+ # missing optional resources (``/CONF/STATE.VAR``,
226+ # ``/CONF/NET/RES.CFG``) with a real 404 whose framing trips
227+ # aiohttp's parser when the connection is reused — the next
228+ # request on the kept-alive socket reads the prior 404's HTML
229+ # body where an HTTP status line should be. Demote that to a
230+ # debug log and return ``""`` so the optional manager's
231+ # "no resource configured" path handles it cleanly.
232+ if ok404 :
233+ _LOGGER .debug (
234+ "ISY response framing error on optional endpoint %s: %s" ,
235+ url ,
236+ err .message ,
237+ )
238+ return ""
222239 _LOGGER .error (
223240 "Client Response Error from ISY: %s %s." ,
224241 err .status ,
@@ -289,13 +306,25 @@ async def get_status(self) -> str | None:
289306 return await self .request (req_url )
290307
291308 async def get_variable_defs (self ) -> list [str | BaseException ] | None :
292- """Fetch the list of variables from the ISY."""
309+ """Fetch the list of variables from the ISY.
310+
311+ ``ok404=True`` because both endpoints legitimately 404 on a
312+ factory-reset / un-configured ISY-994 (``/CONF/INTEGER.VAR not
313+ found`` / ``/CONF/STATE.VAR not found``); the ``Variables``
314+ parser already handles those bodies and ``None`` as
315+ "no variables defined" (see ``EMPTY_VARIABLE_RESPONSES``).
316+ Without ``ok404`` the request path emits ERROR-level log spam
317+ for what is really an empty-config success.
318+ """
293319 req_list = [
294320 [URL_VARIABLES , URL_DEFINITIONS , VAR_INTEGER ],
295321 [URL_VARIABLES , URL_DEFINITIONS , VAR_STATE ],
296322 ]
297323 req_urls = [self .compile_url (req ) for req in req_list ]
298- return await asyncio .gather (* [self .request (req_url ) for req_url in req_urls ], return_exceptions = True )
324+ return await asyncio .gather (
325+ * [self .request (req_url , ok404 = True ) for req_url in req_urls ],
326+ return_exceptions = True ,
327+ )
299328
300329 async def get_variables (self ) -> str | None :
301330 """Fetch the variable details from the ISY to update local copy."""
0 commit comments