RobertD502 / home-assistant-iocare

Home Assistant custom component for monitoring and controlling Coway Airmega Purifiers
MIT License
52 stars 8 forks source link

Convert empty string to float error #5

Closed romedtino closed 2 years ago

romedtino commented 2 years ago

Hi Robert,

First thanks for maintaining this integration! I just installed it and I seem to be running into an issue where it is trying to convert an empty string to a float specifically in this line: https://github.com/RobertD502/home-assistant-iocare/blob/f90d1037e4a79ea6471fd6295cedf8c98bd09cbf/custom_components/coway/sensor.py#L241

I can reproduce the error seen in the log if I just switch the Preset Mode to auto or even toggle the light on/off which the commands end up not executing because of the error. Seems to be related to AQI and I do notice for some reason my sensor.airmega_aqi is showing unavailable.

Is this a bug or is there something perhaps I'm missing regarding the setup? Thanks!

RobertD502 commented 2 years ago

Please post any related logs here. The preset mode and light switch are separate from the AQI sensor, so this line shouldn't be having any impact on those functions. Regarding the sensor being unavailable - this isn't a bug. If the coway servers are reporting your purifier as not connected to their servers then the entities related to the purifier become unavailable. They become available again once Coway's servers report the purifier as being connected to their servers again.

To further narrow down your issue, as said before, please post any related logs (including anything regarding changing the preset mode, turning light on/off).

Also, just to make sure - are you using either a 300S or 400s purifier? If you are using their new purifier (I believe it is the 250S?), I can't confirm that this integration will work as I don't have access to one/wrote the code for the 300S and 400s.

romedtino commented 2 years ago

I have the AirMega 400S White. Software Version : MCU: V1.0.0.2( 2022.03.23 16:31)

I don't believe I saw anything in the logs regarding being disconnected but I can't rule it out.

Here' a complete log after startup and trying to toggle the light entity

``` 2022-03-24 00:13:04 ERROR (MainThread) [homeassistant.components.sensor] Error adding entities for domain sensor with platform coway Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 382, in async_add_entities await asyncio.gather(*tasks) File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 614, in _async_add_entity await entity.add_to_platform_finish() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 801, in add_to_platform_finish self.async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 553, in async_write_ha_state self._async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 590, in _async_write_ha_state state = self._stringify_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 559, in _stringify_state if (state := self.state) is None: File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 372, in state value = self.native_value File "/config/custom_components/coway/sensor.py", line 241, in native_value return round(float(self.coordinator.data[self._device].quality["air_quality_index"]), 1) ValueError: could not convert string to float: '' 2022-03-24 00:13:04 ERROR (MainThread) [homeassistant.components.sensor] Error while setting up coway platform for sensor Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 257, in _async_setup_platform await asyncio.gather(*pending) File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 382, in async_add_entities await asyncio.gather(*tasks) File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 614, in _async_add_entity await entity.add_to_platform_finish() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 801, in add_to_platform_finish self.async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 553, in async_write_ha_state self._async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 590, in _async_write_ha_state state = self._stringify_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 559, in _stringify_state if (state := self.state) is None: File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 372, in state value = self.native_value File "/config/custom_components/coway/sensor.py", line 241, in native_value return round(float(self.coordinator.data[self._device].quality["air_quality_index"]), 1) ValueError: could not convert string to float: '' 2022-03-24 00:13:36 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 134, in _handle_refresh_interval await self._async_refresh(log_failures=True, scheduled=True) File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 265, in _async_refresh update_callback() File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 325, in _handle_coordinator_update self.async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 553, in async_write_ha_state self._async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 590, in _async_write_ha_state state = self._stringify_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 559, in _stringify_state if (state := self.state) is None: File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 372, in state value = self.native_value File "/config/custom_components/coway/sensor.py", line 241, in native_value return round(float(self.coordinator.data[self._device].quality["air_quality_index"]), 1) ValueError: could not convert string to float: '' 2022-03-24 00:13:40 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [139928036300496] could not convert string to float: '' Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 192, in handle_call_service await hass.services.async_call( File "/usr/src/homeassistant/homeassistant/core.py", line 1636, in async_call task.result() File "/usr/src/homeassistant/homeassistant/core.py", line 1673, in _execute_service await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)( File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 204, in handle_service await self.hass.helpers.service.entity_service_call( File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 671, in entity_service_call future.result() # pop exception if have File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 949, in async_request_call await coro File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 708, in _handle_entity_call await result File "/config/custom_components/coway/switch.py", line 76, in async_turn_off await self.coordinator.async_request_refresh() File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 141, in async_request_refresh await self._debounced_refresh.async_call() File "/usr/src/homeassistant/homeassistant/helpers/debounce.py", line 78, in async_call await task File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 165, in async_refresh await self._async_refresh(log_failures=True) File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 265, in _async_refresh update_callback() File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 325, in _handle_coordinator_update self.async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 553, in async_write_ha_state self._async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 590, in _async_write_ha_state state = self._stringify_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 559, in _stringify_state if (state := self.state) is None: File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 372, in state value = self.native_value File "/config/custom_components/coway/sensor.py", line 241, in native_value return round(float(self.coordinator.data[self._device].quality["air_quality_index"]), 1) ValueError: could not convert string to float: '' ```
RobertD502 commented 2 years ago

Ok, so based on the logs it is unavailable because the coway server is returning an empty AQI - this is odd behavior as it should never be empty.

Can you press and hold the WiFi button on your Airmega 400S to turn off WiFi, press the button again to turn WiFi on and wait for it to reconnect to your network. After it reconnects, restart Home Assistant and let me know if the problem persists. Forcing the purifier to reconnect to Coway's servers may help getting the AQI to update properly.

romedtino commented 2 years ago

Still no luck :( It's getting late here but let me keep playing with it. I even tried commenting out adding the AQI entity in sensor.py which prevents the error but toggling fan/light don't seem to work. I'll keep poking at it and I'll let you know what I find. Thanks!

RobertD502 commented 2 years ago

It was around 3 AM when I saw your initial post and I misread thinking all of the entities related to a purifier appeared as unavailable. Just to clarify, if the coway servers are reporting your purifier(s) as not connected then all entities related to the purifier(s) will be unavailable - this isn't a bug. However, in your case, just the AQI sensor entity is appearing as unavailable, which isn't normal behavior.

Where did you obtain your Software Version from? I checked all the server endpoints but wasn't able to find a key related to software version for either of my two purifiers. I think for starters we need to determine if your purifier is using a different version and, if so, if it uses different endpoints.

Edit:

I myself own two 300S purifiers. Just to double check it isn't a 300S vs 400S issue, I tested with a coway account that has a 400S purifier associated with it - had no problems with any of the entities or controlling the 400S. Now I don't know the software version on this 400S (it was purchased a few months ago), so, this 400S could be running a different version than yours.

romedtino commented 2 years ago

I just grabbed the version info from the ioCare app (using Android app) there was a tab called Device Management and under Product Software Version it listed that MCU information. On the back of the device it reads 400S (AP-2015E)

I was hoping it was some connection problem or it just needed more data before it started displaying the AQI information. I hoped I would wake up today seeing it magically work after a restart of HA but no dice :(.

I tried toggling WiFi, rejoining my WiFi to see if it would change behavior but it didn't seem to do much. The controls seem to work alright through the app so it could perhaps be a version change as you suspect?

RobertD502 commented 2 years ago

Ahhhhh this info isn't listed in the iOS app. I'll have to dig out an android tablet I have laying around and check the version there. In the meantime, would you feel comfortable sharing your account with me via email (changing the password before I use it and then changing it back to your original password when I am done)? I'll need it to sniff out what endpoints the app is using for your purifier to determine if there is a difference.

RobertD502 commented 2 years ago

Went to the Device Management tab (on the Android app) which shows the Max2 and Prefilter life. On that page I clicked on product settings. No Product Software Version listed on either the main Device Management tab or the product settings page.

theglus commented 2 years ago

My Airmega 400S is generating a similar error:

Logger: homeassistant.components.websocket_api.http.connection
Source: custom_components/coway/sensor.py:241
Integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 3:45:20 PM (1 occurrences)
Last logged: 3:45:20 PM

[547932243472] could not convert string to float: ''
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 192, in handle_call_service
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 1636, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1673, in _execute_service
    await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 204, in handle_service
    await self.hass.helpers.service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 668, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 949, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 705, in _handle_entity_call
    await result
  File "/config/custom_components/coway/fan.py", line 151, in async_turn_off
    await self.coordinator.async_request_refresh()
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 141, in async_request_refresh
    await self._debounced_refresh.async_call()
  File "/usr/src/homeassistant/homeassistant/helpers/debounce.py", line 78, in async_call
    await task
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 165, in async_refresh
    await self._async_refresh(log_failures=True)
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 265, in _async_refresh
    update_callback()
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 325, in _handle_coordinator_update
    self.async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 553, in async_write_ha_state
    self._async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 590, in _async_write_ha_state
    state = self._stringify_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 559, in _stringify_state
    if (state := self.state) is None:
  File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 372, in state
    value = self.native_value
  File "/config/custom_components/coway/sensor.py", line 241, in native_value
    return round(float(self.coordinator.data[self._device].quality["air_quality_index"]), 1)
ValueError: could not convert string to float: ''
RobertD502 commented 2 years ago

Unfortunately, I won't be able to track down what is causing the issue without access to an affected account. I have tested it with a 400S that I have access to, but it isn't experiencing the reported issue. This leads me to believe that some 400s purifiers may be running a different software version and I will need to investigate the communication between purifier and coway servers in order resolve the problem.

romedtino commented 2 years ago

Hi @RobertD502,

Sorry for the late reply. I am unsure if I am able to share my account but I was able to sniff some of the information which I think could prove useful.

I think there's a new endpoint CWIG0009. Here's the JSON dump with some PI removed

```json { "body": { "supportAreaFlag": true, "weatherKR": [], "airnowUS": [ { "list": [ { "ParameterName": "CO", "Latitude": "34", "Longitude": "-118", "AQI": "99", "CategoryNumber": "1", "CategoryName": "Excellent", "CategoryTotCnt": "5", "NationCd": "US", "ReportingArea": "", "StateCode": "", "LocalTimeZone": "", "HourObserved": "03", "DateObserved": "2022-03-29" }, { "ParameterName": "NO2", "Latitude": "34", "Longitude": "-118", "AQI": "86", "CategoryNumber": "1", "CategoryName": "Excellent", "CategoryTotCnt": "5", "NationCd": "US", "ReportingArea": "", "StateCode": "", "LocalTimeZone": "", "HourObserved": "03", "DateObserved": "2022-03-29" }, { "ParameterName": "O3", "Latitude": "34", "Longitude": "-118", "AQI": "68", "CategoryNumber": "2", "CategoryName": "Good", "CategoryTotCnt": "5", "NationCd": "US", "ReportingArea": "", "StateCode": "", "LocalTimeZone": "", "HourObserved": "03", "DateObserved": "2022-03-29" }, { "ParameterName": "PM10", "Latitude": "34", "Longitude": "-118", "AQI": "65", "CategoryNumber": "2", "CategoryName": "Good", "CategoryTotCnt": "5", "NationCd": "US", "ReportingArea": "", "StateCode": "", "LocalTimeZone": "", "HourObserved": "03", "DateObserved": "2022-03-29" }, { "ParameterName": "PM2.5", "Latitude": "34", "Longitude": "-118", "AQI": "86", "CategoryNumber": "1", "CategoryName": "Excellent", "CategoryTotCnt": "5", "NationCd": "US", "ReportingArea": "", "StateCode": "", "LocalTimeZone": "", "HourObserved": "03", "DateObserved": "2022-03-29" }, { "ParameterName": "SO2", "Latitude": "34", "Longitude": "-118", "AQI": "100", "CategoryNumber": "1", "CategoryName": "Excellent", "CategoryTotCnt": "5", "NationCd": "US", "ReportingArea": "", "StateCode": "", "LocalTimeZone": "", "HourObserved": "03", "DateObserved": "2022-03-29" } ], "laqiList": [ { "ParameterName": "o3", "Latitude": "34", "Longitude": "-118", "AQI": "38", "CategoryNumber": "1", "CategoryName": "Good", "CategoryTotCnt": "6", "NationCd": "US", "ReportingArea": "", "StateCode": "", "LocalTimeZone": "", "HourObserved": "03", "DateObserved": "2022-03-29" } ] } ], "stationCd": "", "admdongCd": "", "stationAdress": "" }, "header": { "accessToken": "REMOVED", "error_code": "", "error_text": "", "info_text": "", "login_session_id": "", "message_version": "", "refreshToken": "REMOVED", "result": true, "trcode": "CWIG0009" } } ```

I think I also see that MCU version I had mentioned in endpoint CWIG0615. Here's a sample JSON

```json { "body": { "updateState": "NONE", "newestMcuVer": null, "newestWifiVer": null, "isShowResveUpdateMessage": false, "curUpdateDate": 1648078318868, "curMcuVer": "V1.0.0.2", "curWifiVer": "4889", "resveUpdateDate": 0 }, "header": { "accessToken": "REMOVED" "error_code": "", "error_text": "", "info_text": "", "login_session_id": "", "message_version": "", "refreshToken": "REMOVED", "result": true, "trcode": "CWIG0615" } } ```

Hope this helps! I'm guessing there will need to be a way to figure out if the 400S version is the newer ones with different endpoints? Hopefully that second JSON or there's some way to figure that out. Let me know if I can help more!

RobertD502 commented 2 years ago

I have the CWIG0009 endpoint, but that isn't where AQI for the unit is obtained from. That endpoint serves outdoor air quality measurements and not those obtained by the purifier itself.

I can confirm that I do not have the CWIG0615 endpoint.

romedtino commented 2 years ago

Oh, I see. odd then, perhaps these new 400S units need some update because all of the IAQ section definitely just comes in blank :(

RobertD502 commented 2 years ago

What does your CWIA0120 endpoint json look like? In particular, the IAQ section:

image

romedtino commented 2 years ago

The keys are there but the values except for dustpm10 are blank

"IAQ": [
      {
        "co2": "",
        "inairquality": "",
        "humidity": "",
        "dustpm25": "",
        "temperature": "",
        "dustpm10": "25",
        "dustpm1": "",
        "vocs": ""
      }
    ],
    "OAQ": []

just invoking iocareapi.py on its own, I also noticed the control commands don't work unless I add mqttRequest: True in the request body.

def control(self, device, command, value):
        response = self._request(CONTROL, {
            'barcode': device.device_id,
            'dvcBrandCd': device.device_brand,
            'prodName': device.product_name,
            'dvcTypeCd': device.device_type,
            'funcList': [{
              'comdVal': value,
              'funcId': command
            }],
            'mqttDevice': True
        })
romedtino commented 2 years ago

So with the info above, I kind of got it partially working on Home Assistant with some kludging:

The functionality seems to work sans the AQI information.

RobertD502 commented 2 years ago

It should work without just the AQI sensor. Home Assistant tries to update info for all sensors when any control functions are called which is why yours hangs up when it fails to update the AQI in the process.

The MQTT portion shouldn't be necessary - it is also sent for my purifiers, but still works without it (the library was created with a lower iOS version app before they started using that option).

Edit:

I didn't see your reply before this latest one. Looks like I'll need to add the MQTT portion since the new purifiers require it - odd because my purifiers also use it, but don't require it.

RobertD502 commented 2 years ago

Does your report section look like this?:

image

If so, that means the purifier has to be reporting AQI to the Coway servers...the issue is where.

romedtino commented 2 years ago

Yea, I have those too

But the only thing populated in the CWIA0120 section which has some semblance of AQI is that pm10Graph section, here's a snippet.

```json "pm10Graph":[ { "graphhighvalue":"0", "place":"in", "msrdt":"202203290320", "graphvalue":"0" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290330", "graphvalue":"0" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290340", "graphvalue":"0" }, { "graphhighvalue":"None", "place":"in", "msrdt":"202203290350", "graphvalue":"None" }, { "graphhighvalue":"10", "place":"in", "msrdt":"202203290400", "graphvalue":"1" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290410", "graphvalue":"0" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290420", "graphvalue":"0" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290430", "graphvalue":"0" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290440", "graphvalue":"0" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290450", "graphvalue":"0" }, { "graphhighvalue":"10", "place":"in", "msrdt":"202203290500", "graphvalue":"1" }, { "graphhighvalue":"9", "place":"in", "msrdt":"202203290510", "graphvalue":"1" }, { "graphhighvalue":"17", "place":"in", "msrdt":"202203290520", "graphvalue":"2" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290530", "graphvalue":"0" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290540", "graphvalue":"0" }, { "graphhighvalue":"13", "place":"in", "msrdt":"202203290550", "graphvalue":"1" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290600", "graphvalue":"0" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290610", "graphvalue":"0" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290620", "graphvalue":"0" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290630", "graphvalue":"0" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290640", "graphvalue":"0" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290650", "graphvalue":"0" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290700", "graphvalue":"0" }, { "graphhighvalue":"7", "place":"in", "msrdt":"202203290710", "graphvalue":"1" }, { "graphhighvalue":"12", "place":"in", "msrdt":"202203290720", "graphvalue":"2" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290730", "graphvalue":"0" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290740", "graphvalue":"0" }, { "graphhighvalue":"None", "place":"in", "msrdt":"202203290750", "graphvalue":"None" }, { "graphhighvalue":"7", "place":"in", "msrdt":"202203290800", "graphvalue":"1" }, { "graphhighvalue":"4", "place":"in", "msrdt":"202203290810", "graphvalue":"0" }, { "graphhighvalue":"15", "place":"in", "msrdt":"202203290820", "graphvalue":"2" }, { "graphhighvalue":"6", "place":"in", "msrdt":"202203290830", "graphvalue":"1" }, { "graphhighvalue":"18", "place":"in", "msrdt":"202203290840", "graphvalue":"3" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290850", "graphvalue":"0" }, { "graphhighvalue":"46", "place":"in", "msrdt":"202203290900", "graphvalue":"8" }, { "graphhighvalue":"0", "place":"in", "msrdt":"202203290910", "graphvalue":"0" }, { "graphhighvalue":"25", "place":"in", "msrdt":"202203290920", "graphvalue":"4" } ], ```

If I'm understanding it right, is "place":"in" here meaning the indoor AQI value? This might be the only thing provided now for these newer models perhaps? The values I have here seem to match this graph in the Home tab. At least comparing that fairly high value between 8 and 9 which looks to have that graphhighvalue of 46?

RobertD502 commented 2 years ago

Maybe they'll update it down the line. For now it seems the newer models won't have AQI sensors - It is a bit puzzling why they chose to report PM10, but not anything else.

RobertD502 commented 2 years ago

Just an update:

Even though my purifiers don't call the CWIG0615 endpoint, I made a manual call using the backend library and it returns:

{'updateState': '', 'newestMcuVer': None, 'newestWifiVer': None, 'isShowResveUpdateMessage': False, 'curUpdateDate': 0, 'curMcuVer': None, 'curWifiVer': None, 'resveUpdateDate': 0}

So, I can use this endpoint to determine if a user has an older model or the updated model.

RobertD502 commented 2 years ago

@romedtino @theglus

I just released a 0.0.3.2 pre-release and need to have it tested with your new units before I release it in the wild.

First of all, I need to test if everything works out from onboarding, so, I will need for you all to please delete the integration (from the Home Assistant integration page) if you currently have it set up.

After doing so, go to HACS, select Integrations and find the Coway integration card. On the coway card, select the overflow menu (three vertical dots) and click on redownload. After doing so be sure Show beta versions is selected. You should then be able to select version 0.0.3.2. Install it, restart Home Assistant, and set the integration up through the Home Assistant integrations page.

Things I need tested:

I appreciate the help!

theglus commented 2 years ago

@RobertD502 Awesome, thanks for the quick turn-around time. I'm out of the house now, but I'll put together a testing report with my results when I get home.

RobertD502 commented 2 years ago

@theglus @romedtino

Out of curiosity, what do you all have your sensitivity set to (located on the product settings page)?

I'm curious to know if perhaps settings aside from sensitive for newer models don't report AQI values to Coway's servers.

image

romedtino commented 2 years ago

I verified the list you mentioned

--EDIT BEGIN-- * [x] Confirm that an AQI sensor is not created for your purifier

When I loaded up the devices page initially the sensor wasn't there but now it's there again and unavailable

--EDIT END--

While the control of it worked, I would get this as an error in the HA logs for every command

Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 134, in _handle_refresh_interval
await self._async_refresh(log_failures=True, scheduled=True)
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 265, in _async_refresh
update_callback()
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 325, in _handle_coordinator_update
self.async_write_ha_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 553, in async_write_ha_state
self._async_write_ha_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 590, in _async_write_ha_state
state = self._stringify_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 559, in _stringify_state
if (state := self.state) is None:
File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 372, in state
value = self.native_value
File "/config/custom_components/coway/sensor.py", line 225, in native_value
return round(float(self.coordinator.data[self._device].quality["air_quality_index"]), 1)
ValueError: could not convert string to float: ''

I had my smart mode sensitivity to Normal, are you thinking that affects the info we get back?

RobertD502 commented 2 years ago

Just to confirm, you deleted the integration from the Home Assistant integrations page (not from your custom_components folder) prior to updating to 0.0.3.2 and restarting Home Assistant?

Regarding the smart mode sensitivity, can you set it to sensitive and then sniff the traffic to see if AQI is reported?

RobertD502 commented 2 years ago

@romedtino

Make these changes to the sensor.py file starting at line 26, restart Home Assistant, and let me know what is logged:

    for idx, ent in enumerate(coordinator.data):
        _LOGGER.error(f'{coordinator.data[idx].name} is new model: {coordinator.data[idx].new_model}')
        if not coordinator.data[idx].new_model:
            _LOGGER.error(f'AQI sensor added for {coordinator.data[idx].name}')
            sensors.append(AirQualityIndex(coordinator, idx))
        sensors.append(PreFilter(coordinator, idx))
        sensors.append(MAX2Filter(coordinator, idx))
        sensors.append(TimerRemaining(coordinator, idx))
        sensors.append(ParticulateMatter25(coordinator, idx))
        sensors.append(ParticulateMatter10(coordinator, idx))
        sensors.append(CarbonDioxide(coordinator, idx))
        sensors.append(VolatileOrganicCompounds(coordinator, idx))
romedtino commented 2 years ago

Yeah, I see the new changes in my copies of custom_components/coway/* and iocareapi.py

Pulling the newer copy of iocareapi.py, trying out the new mcu_version it seems that the body key/value 'barcode': device.device_id is now 'deviceId': device.device_id. I think that might be why it's thinking the AQI sensor needs to be added because otherwise, the curMcuVer returns None.

Actually, if the body only contains 'deviceId': device.device_id that seems to be enough for a query to CWIG0615 to return a value 🤔

RobertD502 commented 2 years ago

What all does the request body include for the 0615 endpoint based on your sniffing?

If you can provide me the full request body, I can test to see if it still works for older models.

Are you saying that the current iocareapi backend returns None for curMcuVer, but a value is returned when using 'deviceId': device_id?

romedtino commented 2 years ago

Sure the body request for 0615

```json { "header":{ "result":false, "error_code":"", "error_text":"", "info_text":"", "message_version":"", "login_session_id":"", "trcode":"CWIG0615", "accessToken": "REMOVED", "refreshToken": "REMOVED", }, "body":{ "deviceId":"15102DNO2191000274", "timezone":"America/Los_Angeles" } } ```

and yes precisely. I guess they changed it for the newer models

OLD 'barcode': device.device_id,

NEW 'deviceId': device.device_id,

otherwise, curMcuVer returns None

Also, I tried changing to Sensitive but AQI information is still missing :(

theglus commented 2 years ago

@theglus @romedtino

Out of curiosity, what do you all have your sensitivity set to (located on the product settings page)?

I'm curious to know if perhaps settings aside from sensitive for newer models don't report AQI values to Coway's servers.

I have mine set to sensitive.

RobertD502 commented 2 years ago

Alright, I can confirm that curMcuVer returns None for me when using deviceId. I also tested to see if the quality endpoint works when using deviceId, but not luck.

I'll go ahead and push the deviceId change to pypi and then create a new release

RobertD502 commented 2 years ago

@theglus @romedtino

Just released 0.0.3.3. Let me know if that prevents the AQI sensor from being added.

romedtino commented 2 years ago

Can confirm no AQI sensor and no more errors for all the commands 🎉 thanks for the quick turnaround!

theglus commented 2 years ago

Testing report for 0.0.33 pre-release

Sensor List

@RobertD502 Everything seems to be working perfectly now 🎉

RobertD502 commented 2 years ago

Perfect!

Thanks to both of you for helping out!

@romedtino If you don't mind, can you check the quality endpoint from time to time and report back here if an AQI ever gets populated?

romedtino commented 2 years ago

No problem, can do 🥳