Noltari / aioairzone

Python library to control Airzone via Local API
Apache License 2.0
2 stars 0 forks source link

Error fetching airzone data: error: request malformed #8

Closed millerdev closed 1 month ago

millerdev commented 3 months ago

I'm seeing a lot of these errors in my Home Assistant logs. The Airzone climate controls in HA are sometimes responsive, and sometimes not. They often become "unavailble" for a few minutes, and then revert to normal function.

Sample HA logs at default warning level:

2024-08-08 04:59:13.596 ERROR (MainThread) [homeassistant.components.airzone.coordinator] Error fetching airzone data: error: request malformed
2024-08-08 06:43:19.149 ERROR (MainThread) [homeassistant.components.airzone.coordinator] Error fetching airzone data: error: request malformed
2024-08-08 06:59:17.192 ERROR (MainThread) [homeassistant.components.airzone.coordinator] Error fetching airzone data: error: request malformed

With debug logging enabled it's clear there are many requests that are successful (newlines added to highlight the error).

2024-08-08 12:32:08.032 DEBUG (MainThread) [aioairzone.localapi] aiohttp request: /api/v1/hvac (params={'systemID': 0, 'zoneID': 0})
2024-08-08 12:32:08.107 DEBUG (MainThread) [aioairzone.localapi] aiohttp response: {'systems': [{'data': [{'systemID': 1, 'zoneID': 1, 'name': 'Ian bedroom', 'on': 0, 'coolsetpoint': 80, 'coolmaxtemp': 90, 'coolmintemp': 60, 'heatsetpoint': 66, 'heatmaxtemp': 90, 'heatmintemp': 60, 'maxTemp': 90, 'minTemp': 60, 'setpoint': 80, 'roomTemp': 80, 'modes': [4, 2, 3, 5, 7], 'mode': 2, 'speeds': 3, 'speed': 0, 'coldStages': 0, 'coldStage': 0, 'heatStages': 0, 'heatStage': 0, 'humidity': 0, 'units': 1, 'errors': [], 'air_demand': 0, 'floor_demand': 0}]}]}
2024-08-08 12:32:08.107 DEBUG (MainThread) [homeassistant.components.airzone.coordinator] Finished fetching airzone data in 0.075 seconds (success: True)
2024-08-08 12:32:12.962 DEBUG (MainThread) [aioairzone.localapi] aiohttp request: /api/v1/hvac (params={'systemID': 0, 'zoneID': 0})
2024-08-08 12:32:13.099 DEBUG (MainThread) [aioairzone.localapi] aiohttp request: /api/v1/hvac (params={'systemID': 0, 'zoneID': 0})

2024-08-08 12:32:13.166 DEBUG (MainThread) [aioairzone.localapi] aiohttp response: {'errors': [{'error': 'request malformed'}]}
2024-08-08 12:32:13.166 ERROR (MainThread) [homeassistant.components.airzone.coordinator] Error fetching airzone data: error: request malformed
2024-08-08 12:32:13.166 DEBUG (MainThread) [homeassistant.components.airzone.coordinator] Finished fetching airzone data in 0.068 seconds (success: False)

2024-08-08 12:32:14.217 DEBUG (MainThread) [aioairzone.localapi] aiohttp response: {'systems': [{'data': [{'systemID': 1, 'zoneID': 1, 'name': 'DN bedroom', 'on': 0, 'coolsetpoint': 79, 'coolmaxtemp': 90, 'coolmintemp': 60, 'heatsetpoint': 65, 'heatmaxtemp': 90, 'heatmintemp': 60, 'maxTemp': 90, 'minTemp': 60, 'setpoint': 79, 'roomTemp': 80, 'modes': [4, 2, 3, 5, 7], 'mode': 2, 'speeds': 3, 'speed': 0, 'coldStages': 0, 'coldStage': 0, 'heatStages': 0, 'heatStage': 0, 'humidity': 0, 'units': 1, 'errors': [], 'air_demand': 0, 'floor_demand': 0}]}]}
2024-08-08 12:32:14.217 DEBUG (MainThread) [homeassistant.components.airzone.coordinator] Finished fetching airzone data in 1.255 seconds (success: True)
2024-08-08 12:33:08.032 DEBUG (MainThread) [aioairzone.localapi] aiohttp request: /api/v1/hvac (params={'systemID': 0, 'zoneID': 0})
2024-08-08 12:33:08.127 DEBUG (MainThread) [aioairzone.localapi] aiohttp response: {'systems': [{'data': [{'systemID': 1, 'zoneID': 1, 'name': 'Ian bedroom', 'on': 0, 'coolsetpoint': 80, 'coolmaxtemp': 90, 'coolmintemp': 60, 'heatsetpoint': 66, 'heatmaxtemp': 90, 'heatmintemp': 60, 'maxTemp': 90, 'minTemp': 60, 'setpoint': 80, 'roomTemp': 80, 'modes': [4, 2, 3, 5, 7], 'mode': 2, 'speeds': 3, 'speed': 0, 'coldStages': 0, 'coldStage': 0, 'heatStages': 0, 'heatStage': 0, 'humidity': 0, 'units': 1, 'errors': [], 'air_demand': 0, 'floor_demand': 0}]}]}
2024-08-08 12:33:08.128 DEBUG (MainThread) [homeassistant.components.airzone.coordinator] Finished fetching airzone data in 0.096 seconds (success: True)

There are three Airzone (AZAI6WSPDKC) controllers on my network.

Is something configured incorrectly that is causing these errors?

Noltari commented 3 months ago

Since the "Request Malformed" errors are given by the Airzone device it's probably an issue on Airzone side (FW bug)... If this is the case maybe you can update the device with the Airzone Cloud app instead of Daikin's app. Airzone people might be able to update it too.

Is this happening on all three devices? Can you attach Home Assistant diagnostics for all 3 Airzone devices?

Did you notice any improvement with latest Home Assistant version? (2024.8) I've introduced a semaphore limiting the concurrent API requests to 1 because I've realized that performing parallel requests to the Local API results in higher response times to each request, and sometimes even incorrect or no response at all.

Best regards, Álvaro.

millerdev commented 3 months ago

maybe you can update the device with the Airzone Cloud app

I am unable to connect to my devices with the Airzone Cloud app. It gives a generic error "Device not found. This device isn't registered." possibly because these devices are made for Daikin? It's disappointing because the Airzone Cloud app does seem nicer than the Daikin app.

I just checked in the Daikin app and it said there was an update (v4.04), so I installed it. However, after installing it it still says there is an update with the same version number.

Is this happening on all three devices?

I'm not sure if I have enough information to know this. They all randomly become unavailable many times per day, but maybe that's unrelated?

Can you attach Home Assistant diagnostics for all 3 Airzone devices?

config_entry-airzone-7f2e9cccf52b854cfe6959a866cf780c.json config_entry-airzone-22d1f0a8fe112d97ab850fba86b637d5.json config_entry-airzone-e029c97465217cc5382cc085ffed2150.json

Did you notice any improvement with latest Home Assistant version? (2024.8)

Haven't tried it yet. I'll upgrade and report back.

Noltari commented 3 months ago

I am unable to connect to my devices with the Airzone Cloud app. It gives a generic error "Device not found. This device isn't registered." possibly because these devices are made for Daikin? It's disappointing because the Airzone Cloud app does seem nicer than the Daikin app.

Well, that's disappointing... I thought that you would be able to use the Airzone Cloud app, but it seems to be locked under a special Daikin branding... And I suppose that you can't use the Airzone Cloud integration in Home Assistant since that uses the same API as the Airzone Cloud app...

I just checked in the Daikin app and it said there was an update (v4.04), so I installed it. However, after installing it it still says there is an update with the same version number.

Yes, this seems to be an issue on Airzone's side. I'm currently on v4.06 myself, but it says that a new version is available (v4.04). This has happened to me shortly after v4.05 and v4.06 updates were released... I will try to contact Airzone and see what's going on...

I'm not sure if I have enough information to know this. They all randomly become unavailable many times per day, but maybe that's unrelated?

You can check any of the entities provided by each Airzone device, and see the number of times that they become unavailable troughout the day: image

Haven't tried it yet. I'll upgrade and report back.

Once you have upgraded all 3 Airzone devices to v4.04 and Home Assistant to 2024.8 it would be great if you could attach new diagnostics, since there should be some changes after the FW upgrade.

millerdev commented 3 months ago

Is there a way to see what firmware version is running on each device? I think I have upgraded them all to 4.04, but I can't tell for sure. Here's the diagnostics since upgrading to HA 2024.8:

config_entry-airzone-22d1f0a8fe112d97ab850fba86b637d5.json config_entry-airzone-7f2e9cccf52b854cfe6959a866cf780c.json config_entry-airzone-e029c97465217cc5382cc085ffed2150.json

Still getting plenty of Error fetching airzone data: error: request malformed in the logs. Don't know if those are coming from all devices or just from one or two.

I suppose that you can't use the Airzone Cloud integration in Home Assistant since that uses the same API as the Airzone Cloud app...

Correct. When I try to install that integration I have nothing to choose at the step where it prompts to choose an installation.

Is this happening on all three devices?

Here's a screenshot of a 4-hour period from today where you can see small slices of time when they have all been unavailable. That type of behavior is constant.

image

Noltari commented 3 months ago

@millerdev I've contacted Airzone about this issue, but it will take some time for them to respond since everyone is currently on holidays ^^

vtamayo-az commented 3 months ago

Hi @millerdev,

I'm with Airzone. Could you please send an email to devapps@altracorporacion.es so we can assist you? When you do, please include the issue URL and your device's MAC address.

Kind regards, Víctor

millerdev commented 3 months ago

@vtamayo-az, apologies for the delayed response. I sent the email as requested.

millerdev commented 2 months ago

@vtamayo-az, has my email been received? I haven't seen a response.

Noltari commented 2 months ago

@millerdev according to Airzone this is caused because some Airzone devices expect the HTTP header and body in the same TCP segment. However, this doesn't comply with the HTTP specification, since the header and body can be split into 2 TCP segments. I've tested with multiple HTTP Python libraries and all of them except pycurl send 2 TCP segments, but pycurl can't be used in Home Assistant since it relies on libcurl and other dependencies being installed on the system, which I believe will be a NACK from the official Home Assistant developers. Therefore, I've implemented a custom and very basic HTTP handler which should fix the issue. However, since this quirk is needed on some older Airzone devices, it won't be enabled by default and you will need to toggle the option on Home Assistant once it's available.

Noltari commented 2 months ago

@millerdev I've attached the updated airzone integration in case you want to test it before it's merged into Home Assistant and a new version is released, which will take some time (at least a month). Just copy the following airzone folder in your custom_components folder: airzone-v0.9.0-http-sockets.zip

Noltari commented 2 months ago

New version which enables the HTTP quirks for all devices (no user configuration needed): airzone-v0.9.2-http-quirks.zip

millerdev commented 2 months ago

Thank you! I'll give it a try.

millerdev commented 2 months ago

@Noltari, installing this manually by dropping it in custom_components will permanently lock me at that version, correct? How will I know when a newer version has been released?

millerdev commented 2 months ago

I may have answered my own question. I think I need to watch for a new version of Home Assistant to be released with the aioairzone at v0.9.2 or later. In the latest release the version would be observed here. Is that correct?

millerdev commented 2 months ago

After restarting I can see that the new version is installed, but with issues.

image

Logs:

2024-09-14 11:18:04.537 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration airzone which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2024-09-14 11:18:09.916 ERROR (MainThread) [homeassistant] Error doing job: Fatal error: protocol.eof_received() call failed. (None)
Traceback (most recent call last):
File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 1029, in _read_ready__on_eof
keep_open = self._protocol.eof_received()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/aioairzone/http.py", line 222, in eof_received
self.response.parse_data()
File "/usr/local/lib/python3.12/site-packages/aioairzone/http.py", line 179, in parse_data
self.parse_header_bytes(header_bytes)
File "/usr/local/lib/python3.12/site-packages/aioairzone/http.py", line 158, in parse_header_bytes
raise InvalidHost(f"Invalid HTTP Content-Type: {self.content_type}")
aioairzone.exceptions.InvalidHost: Invalid HTTP Content-Type: text/html
2024-09-14 11:18:09.918 ERROR (MainThread) [aioairzone.http] Invalid HTTP Content-Type: text/html
2024-09-14 11:18:09.918 ERROR (MainThread) [homeassistant] Error doing job: Fatal error: protocol.eof_received() call failed. (None)
Traceback (most recent call last):
File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 1029, in _read_ready__on_eof
keep_open = self._protocol.eof_received()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/aioairzone/http.py", line 222, in eof_received
self.response.parse_data()
File "/usr/local/lib/python3.12/site-packages/aioairzone/http.py", line 179, in parse_data
self.parse_header_bytes(header_bytes)
File "/usr/local/lib/python3.12/site-packages/aioairzone/http.py", line 158, in parse_header_bytes
raise InvalidHost(f"Invalid HTTP Content-Type: {self.content_type}")
aioairzone.exceptions.InvalidHost: Invalid HTTP Content-Type: text/html
2024-09-14 11:18:09.919 ERROR (MainThread) [aioairzone.http] Invalid HTTP Content-Type: text/html
2024-09-14 11:18:09.929 ERROR (MainThread) [homeassistant] Error doing job: Fatal error: protocol.eof_received() call failed. (None)
Traceback (most recent call last):
File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 1029, in _read_ready__on_eof
keep_open = self._protocol.eof_received()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/aioairzone/http.py", line 222, in eof_received
self.response.parse_data()
File "/usr/local/lib/python3.12/site-packages/aioairzone/http.py", line 179, in parse_data
self.parse_header_bytes(header_bytes)
File "/usr/local/lib/python3.12/site-packages/aioairzone/http.py", line 158, in parse_header_bytes
raise InvalidHost(f"Invalid HTTP Content-Type: {self.content_type}")
aioairzone.exceptions.InvalidHost: Invalid HTTP Content-Type: text/html
2024-09-14 11:18:09.930 ERROR (MainThread) [aioairzone.http] Invalid HTTP Content-Type: text/html
Noltari commented 2 months ago

@Noltari, installing this manually by dropping it in custom_components will permanently lock me at that version, correct? How will I know when a newer version has been released?

Once the next major Home Assistant major version (2024.10.X) is released you'll have to delete the airzone folder from custom_components.

After restarting I can see that the new version is installed, but with issues.

Logs:

2024-09-14 11:18:09.930 ERROR (MainThread) [aioairzone.http] Invalid HTTP Content-Type: text/html

It seems that your Airzone local API is incorrectly providing the Content-Type as "text/html" instead of "text/json". I've fixed this in the next release (https://github.com/Noltari/aioairzone/releases/tag/0.9.3). Could you try and see if it works now? airzone-v0.9.3-http-quirks.zip

Noltari commented 1 month ago

@millerdev the custom integration files that I provided should no longer be needed since the fix is now present on the latest releases of Home Assistant. Can you confirm that the issue has been resolved so that I can close this?

millerdev commented 1 month ago

@Noltari I installed the update (0.9.3) and then went away on a work trip and didn't get much time to monitor until now. The Invalid HTTP Content-Type error appears to have gone away, but I am seeing a new error that I did not see before. There are over a thousand of these in my logs over the past month.

2024-09-15 21:40:15.283 ERROR (MainThread) [custom_components.airzone.coordinator] Unexpected error fetching airzone data
Traceback (most recent call last):
File "/usr/local/lib/python3.12/site-packages/aioairzone/http.py", line 258, in request
transport, protocol = await self.loop.create_connection(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1104, in create_connection
sock = await self._connect_sock(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1007, in _connect_sock
await self.sock_connect(sock, address)
File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 641, in sock_connect
return await fut
^^^^^^^^^
asyncio.exceptions.CancelledError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 354, in _async_refresh
self.data = await self._async_update_data()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/airzone/coordinator.py", line 41, in _async_update_data
await self.airzone.update()
File "/usr/local/lib/python3.12/site-packages/aioairzone/localapi.py", line 449, in update
hvac = await self.get_hvac()
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/aioairzone/localapi.py", line 591, in get_hvac
res = await self.http_request(
^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/aioairzone/localapi.py", line 275, in http_request
return await self.http_quirks_request(method, path, data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/aioairzone/localapi.py", line 237, in http_quirks_request
resp = await self.http.request(
^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/aioairzone/http.py", line 268, in request
transport.close()
^^^^^^^^^
UnboundLocalError: cannot access local variable 'transport' where it is not associated with a value

I removed /config/custom_components/airzone today and upgraded to HA 2024.10.2. So far I see no airzone errors, but I will post an update if they reappear. In the mean time, feel free to close this out if the most recent error seems unrelated.

Thank you for your responsiveness and follow-through.

Noltari commented 1 month ago

@Noltari I installed the update (0.9.3) and then went away on a work trip and didn't get much time to monitor until now. The Invalid HTTP Content-Type error appears to have gone away

Awesome :)

but I am seeing a new error that I did not see before. There are over a thousand of these in my logs over the past month.

2024-09-15 21:40:15.283 ERROR (MainThread) [custom_components.airzone.coordinator] Unexpected error fetching airzone data
Traceback (most recent call last):
File "/usr/local/lib/python3.12/site-packages/aioairzone/http.py", line 258, in request
transport, protocol = await self.loop.create_connection(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1104, in create_connection
sock = await self._connect_sock(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1007, in _connect_sock
await self.sock_connect(sock, address)
File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 641, in sock_connect
return await fut
^^^^^^^^^
asyncio.exceptions.CancelledError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 354, in _async_refresh
self.data = await self._async_update_data()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/airzone/coordinator.py", line 41, in _async_update_data
await self.airzone.update()
File "/usr/local/lib/python3.12/site-packages/aioairzone/localapi.py", line 449, in update
hvac = await self.get_hvac()
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/aioairzone/localapi.py", line 591, in get_hvac
res = await self.http_request(
^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/aioairzone/localapi.py", line 275, in http_request
return await self.http_quirks_request(method, path, data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/aioairzone/localapi.py", line 237, in http_quirks_request
resp = await self.http.request(
^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/aioairzone/http.py", line 268, in request
transport.close()
^^^^^^^^^
UnboundLocalError: cannot access local variable 'transport' where it is not associated with a value

This is a side-effect of the changes I had to introduce in order to fix your errors. It was already reported here by another user and it's already fixed, but the fix isn't present on any Home Assistant release yet: https://github.com/home-assistant/core/issues/127917 https://github.com/home-assistant/core/pull/128265 This happens because there's at least one device on your network with a MAC address starting with "E8:4F:25", which the Home Assistant identifies as an Airzone device autodiscovered by DHCP and then it fails because it isn't really an Airzone device. This MAC address prefix is used by other devices and not only for Airzone devices.

I removed /config/custom_components/airzone today and upgraded to HA 2024.10.2. So far I see no airzone errors, but I will post an update if they reappear. In the mean time, feel free to close this out if the most recent error seems unrelated.

Sure, just repoen this issue if the errors reappear.

Thank you for your responsiveness and follow-through.

Thanks!