briis / smartweather

WeatherFlow Smart Weather Component for Home Assistant
MIT License
108 stars 11 forks source link

Sensor causing uncaught exception when API does not return lightning_strike_last_epoch #42

Closed mstovenour closed 4 years ago

mstovenour commented 4 years ago

This line of code creates an exception when lightning_strike_last_epoch is not returned by the API. https://github.com/briis/smartweather/blob/1fa3d00a8445daff60710e3362f3306566cc7dd4/custom_components/smartweather/sensor.py#L197

2020-10-10 13:32:28 DEBUG (MainThread) [custom_components.smartweather] Finished fetching smartweather data in 0.180 seconds
2020-10-10 13:32:28 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/homeassistant/lib/python3.7/site-packages/homeassistant/helpers/update_coordinator.py", line 118, in _handle_refresh_interval
    await self.async_refresh()
  File "/usr/local/homeassistant/lib/python3.7/site-packages/homeassistant/helpers/update_coordinator.py", line 192, in async_refresh
    update_callback()
  File "/usr/local/homeassistant/lib/python3.7/site-packages/homeassistant/helpers/entity.py", line 281, in async_write_ha_state
    self._async_write_ha_state()
  File "/usr/local/homeassistant/lib/python3.7/site-packages/homeassistant/helpers/entity.py", line 305, in _async_write_ha_state
    sstate = self.state
  File "/var/local/homeassistant/hass/custom_components/smartweather/sensor.py", line 197, in state
    return round(value, 1)
TypeError: type NoneType doesn't define __round__ method

I added a check to see what was going on:

195a196
>
197c198,202
<             return round(value, 1)
---
>             if value is not None:
>                 return round(value, 1)
>             else:
>                 _LOGGER.debug(f"sensor value is NoneType: {self._sensor}")
>                 return value

And found the culprit:

[custom_components.smartweather.sensor] sensor value is NoneType: lightning_strike_last_time

I pulled the API with:

curl https://swd.weatherflow.com/swd/rest/observations/station/28192?api_key=20c70eae-e62f-4d3b-b3a4-8586e90f3ac8  | python -mjson.tool

I took a peak at the library code and client.py intentionally returns None if lightning_strike_last_epoch is not present: briis/pysmartweatherio: /pysmartweatherio/client.py#L209 image

I recommend that this line: https://github.com/briis/smartweather/blob/1fa3d00a8445daff60710e3362f3306566cc7dd4/custom_components/smartweather/sensor.py#L196

Be changed to:

196c196
<         if not isinstance(value, str):
---
>         if not isinstance(value, str) and value is not None:
briis commented 4 years ago

Thanks for catching this Michael. I will ook at the code tomorrow, and send out a fix. Agree with your fix, but I just want to check the IO module, and see if we can't avoid the error before it hits HA.

mstovenour commented 4 years ago

You could do something in the python library, but it doesn't seem unreasonable to have an "undefined" value for some of the parameters. It also doesn't seem unreasonable for the HA integration to defensively handle undefined values. The smart weather API is going to constantly evolve and the code could use a lot of belt-and-suspenders defensive measures.

briis commented 4 years ago

Good point. I will fix it tomorrow.

briis commented 4 years ago

Your fix has been implemented. 2.0.4 is out, containing this. Thanks.

mstovenour commented 4 years ago

Thanks. HACS updated to the new release. It seems to work well.