openmotics / home-assistant

OpenMotics Home Assistant integration Beta
GNU Affero General Public License v3.0
15 stars 9 forks source link

Sensor validation errors #11

Closed wash34000 closed 1 year ago

wash34000 commented 2 years ago

Hello,

I setup it for cloud connexion and after enable the integration i have this error in logs :

2022-05-13 13:15:58 ERROR (MainThread) [custom_components.openmotics.coordinator] Unexpected error fetching openmotics-clouddev-159 data: 6 validation errors for ParsingModel[list[pyhaopenmotics.cloud.models.sensor.Sensor]] __root__ -> 1 -> status none is not an allowed value (type=type_error.none.not_allowed) __root__ -> 2 -> status none is not an allowed value (type=type_error.none.not_allowed) __root__ -> 4 -> status none is not an allowed value (type=type_error.none.not_allowed) __root__ -> 5 -> status none is not an allowed value (type=type_error.none.not_allowed) __root__ -> 13 -> status none is not an allowed value (type=type_error.none.not_allowed) __root__ -> 14 -> status none is not an allowed value (type=type_error.none.not_allowed) Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 191, in _async_refresh self.data = await self._async_update_data() File "/config/custom_components/openmotics/coordinator.py", line 57, in _async_update_data my_sensors = await self._omclient.sensors.get_all() File "/usr/local/lib/python3.9/site-packages/pyhaopenmotics/cloud/sensors.py", line 52, in get_all return parse_obj_as(list[Sensor], body["data"]) File "/usr/local/lib/python3.9/site-packages/pydantic/tools.py", line 38, in parse_obj_as return model_type(__root__=obj).__root__ File "/usr/local/lib/python3.9/site-packages/pydantic/main.py", line 331, in __init__ raise validation_error pydantic.error_wrappers.ValidationError: 6 validation errors for ParsingModel[list[pyhaopenmotics.cloud.models.sensor.Sensor]] __root__ -> 1 -> status none is not an allowed value (type=type_error.none.not_allowed) __root__ -> 2 -> status none is not an allowed value (type=type_error.none.not_allowed) __root__ -> 4 -> status none is not an allowed value (type=type_error.none.not_allowed) __root__ -> 5 -> status none is not an allowed value (type=type_error.none.not_allowed) __root__ -> 13 -> status none is not an allowed value (type=type_error.none.not_allowed) __root__ -> 14 -> status none is not an allowed value (type=type_error.none.not_allowed)

wash34000 commented 2 years ago

pyhaopenmotics/openmoticsgw/sensors.py

sensors_status = await self._omcloud.exec_action("get_sensor_status")
status = sensors_status["status"]

https://api.openmotics.com/api/get_sensor_status?gateway_id=XX return [{"id": 1, "value": 25.0}, {"id": 2, "value": 25.0}, ...]

woutercoppens commented 2 years ago

A friend had a similar error, but it was related to a bug in his gateway, although he was using the cloud. He opened a ticket with openmotics and they will fix it in the next release of the gateway firmware (2.25 of something).

I see that you're using the local gateway code. This code is very limited tested because my gateway has an old ssl version and I cannot connect to it locally.

wash34000 commented 2 years ago

Tonight I will try from a local connection to see if I have the same problems.

Why don't you have the problem?

For the code of "https://api.openmotics.com/api/get_sensor_status?gateway_id=XX" I use the inspector of my chrome browser for convenience. Where can I test cloud queries?

woutercoppens commented 2 years ago

The HA integration uses pyhaopenmotics in the background: https://github.com/openmotics/pyhaopenmotics

Have a look at the examples. I always use these to test the cloud output.

I cannot connect to my local gateway because I'm hitting this issue: https://github.com/openmotics/gateway/issues/62 Plus I don't have sensors :-(

woutercoppens commented 2 years ago

Plus the cloud is leading and the api is documented here: https://postman.openmotics.com/

I wrote the code of the local gateway to reproduce something that is similar to the outcome of the cloud. The cloud should be working for everybody. People with older gateways has issues to connect locally.

wash34000 commented 2 years ago

Ok thanks for informations. I'll wait for the next gateway update to try this hass integration.

wash34000 commented 2 years ago

Do you want to leave the issue open until the gateway update is released? Do you have any information about this update online?

woutercoppens commented 2 years ago

Otherwise:

Modify "/config/custom_components/openmotics/coordinator.py"

        try:
            my_outputs = await self._omclient.outputs.get_all()
            my_lights = await self._omclient.lights.get_all()
            my_groupactions = await self._omclient.groupactions.get_all()
            my_shutters = await self._omclient.shutters.get_all()
            # my_sensors = await self._omclient.sensors.get_all()

        except OpenMoticsError as err:
            _LOGGER.error("Could not retrieve the data from the OpenMotics API")
            _LOGGER.error("Too many errors: %s", err)
            return {
                "lights": [],
                "outputs": [],
                "groupactions": [],
                "shutters": [],
                "sensors": [],
            }
        # Store data in a way Home Assistant can easily consume it
        return {
            "outputs": my_outputs,
            "lights": my_lights,
            "groupactions": my_groupactions,
            "shutters": my_shutters,
            "sensors": [],
        }
tmds commented 2 years ago

Do you want to leave the issue open until the gateway update is released? Do you have any information about this update online?

I also had this issue, and I can confirm upgrading the gateway to the latest version (2.25.4) fixed it.

evilB commented 2 years ago

Otherwise:

Modify "/config/custom_components/openmotics/coordinator.py"

        try:
            my_outputs = await self._omclient.outputs.get_all()
            my_lights = await self._omclient.lights.get_all()
            my_groupactions = await self._omclient.groupactions.get_all()
            my_shutters = await self._omclient.shutters.get_all()
            # my_sensors = await self._omclient.sensors.get_all()

        except OpenMoticsError as err:
            _LOGGER.error("Could not retrieve the data from the OpenMotics API")
            _LOGGER.error("Too many errors: %s", err)
            return {
                "lights": [],
                "outputs": [],
                "groupactions": [],
                "shutters": [],
                "sensors": [],
            }
        # Store data in a way Home Assistant can easily consume it
        return {
            "outputs": my_outputs,
            "lights": my_lights,
            "groupactions": my_groupactions,
            "shutters": my_shutters,
            "sensors": [],
        }

I had to bypass the sensors for my installation (most recent homeassistant version and openmotics cloud). Bypassing the sensors does work, I do have sensors though so I'll look into what exactly it is that Homeassistant doesn't like.

evilB commented 2 years ago

So I did some further digging: According to the api documentation the api should return something along these lines:

{
    "_version": <version>,
    "id": <id>,
    "name": "<name>",
    "location": {
        "room_id": null | <room_id>,
        "installation_id": <installation id>
    },
    "status": {
        "humidity": null | <hunidity 0 - 100>,
        "temperature": null | <temperature -32 - 95>,
        "brightness": null | <brightness 0 - 100>
    }
}

Instead I get this:

{
    "data": [
        {
            "name": "Droogkelder",
            "status": null,
            "location": {
                "gateway_id": xxxx,
                "installation_id": xxx,
                "room_id": xxxxxxx
            },
            "id": xxxxxx,
            "local_id": 7,
            "physical_quantity": "temperature",
            "unit": "celcius",
            "_version": 1.1
        },
        {
            "name": "Droogkelder",
            "status": {
                "humidity": 52.0
            },
            "location": {
                "gateway_id": x,xxx
                "installation_id": xxxx,
                "room_id": xxxxx
            },
            "id": xxxxx,
            "local_id": 38,
            "physical_quantity": "humidity",
            "unit": "percent",
            "_version": 1.1
        },

This looks like a bug in the api. I have 16 temperature sensors and only 3 of them return a value form the api. The cloud web platform does give me correct values though. All the sensors equipped with humidity and temperature are reported separately, which probably isn't an issue, but the temperature sensors have a null status which doens't help. Querying the individual sensor also returns null status.

@woutercoppens: the documentation didn't mention where to file a bug report. Any idea? Otherwise i'll email support@openmotics.com

woutercoppens commented 2 years ago

Sorry for the late reply.

Do you have the latest version on the gateway installed? A friend had a similar problem and it was a bug in the firmware. If an update doesn’t solve it, you should file a bug report. I always send an email;-)

Op zo 30 okt. 2022 om 22:09 schreef evilB @.***>

So I did some further digging: According to the api documentation https://postman.openmotics.com/#efb626db-47c1-4b35-b06f-f6b890f6f3ac the api should return something along these lines:

{ "_version": , "id": , "name": "", "location": { "room_id": null | , "installation_id": }, "status": { "humidity": null | <hunidity 0 - 100>, "temperature": null | <temperature -32 - 95>, "brightness": null | <brightness 0 - 100> } }

Instead I get this:

{ "data": [ { "name": "Droogkelder", "status": null, "location": { "gateway_id": xxxx, "installation_id": xxx, "room_id": xxxxxxx }, "id": xxxxxx, "local_id": 7, "physical_quantity": "temperature", "unit": "celcius", "_version": 1.1 }, { "name": "Droogkelder", "status": { "humidity": 52.0 }, "location": { "gateway_id": x,xxx "installation_id": xxxx, "room_id": xxxxx }, "id": xxxxx, "local_id": 38, "physical_quantity": "humidity", "unit": "percent", "_version": 1.1 },

This looks like a bug in the api. I have 16 temperature sensors and only 3 of them return a value form the api. The platform does give me correct values though.

@woutercoppens https://github.com/woutercoppens: the documentation didn't mention where to file a bug report. Any idea? Otherwise i'll email @.***

— Reply to this email directly, view it on GitHub https://github.com/openmotics/home-assistant/issues/11#issuecomment-1296351556, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABZEVZ5EANRMG4XU26BADUDWF3IXXANCNFSM5V3LO5JA . You are receiving this because you were mentioned.Message ID: @.***>

evilB commented 2 years ago

Sorry for the late reply.

No appology needed

Do you have the latest version on the gateway installed? A friend had a similar problem and it was a bug in the firmware. If an update doesn’t solve it, you should file a bug report. I always send an email;-)

I was sure I checked it, but it turns out i didn't check correctly. The update is now done and the api behaves correctly. I'll check the homeassistant integration when I'm back home.

evilB commented 1 year ago

Edit:

I was misinformed:

I have a single sensor breaking (a temperature sensor no longer reports a value (it is currently outside with subzero temperatures. Either that is it or the moisture killed the sensor).

According to what i can see in postman:

// the offending sensor returns null
{            
"name": "buiten",           
"status": null,           
"location": {               
 "gateway_id": xxx,                
"installation_id": xxx,               
 "room_id": null            },           
 "id": xxx,            
"local_id": 2,            
"physical_quantity": "temperature",            
"unit": "celcius",            
"_version": 1.1        },

plugin source code

  @property
    def native_value(self):
        """Return % chance the aurora is visible."""
        try:
            self._device = self.coordinator.data["sensors"][self.index]
            return self._device.status.temperature
        except (AttributeError, KeyError):
            return None

then you get the error status None is not allowed error with the plugin not loading.

I'm guessing there should be a way to indicate to homeassistant this sensor is currently not available. The alternative would be to filter the sensor at plugin loading, but that would seem weird because all of a sudden you lose the sensor in homeassistant?

// below is wrong Fyi, i think the update 2.27.1 a few days ago for the heating broke the fix they had in place. This update was automatic, so more people might be affected. I've updated to the latest version and it still seems to be in the regressed state. I'm sending the team an e-mail.

    "data": [
        {
            "name": "Droogkelder",
            "status": {
                "temperature": 16.5
            },
            "location": {
                "gateway_id": xxxx,
                "installation_id": xxx,
                "room_id": xxxx
            },
            "id": xxxxx,
            "local_id": 7,
            "physical_quantity": "temperature",
            "unit": "celcius",
            "_version": 1.1
        },
        {
            "name": "Droogkelder",
            "status": {
                "humidity": 53.5
            },
            "location": {
                "gateway_id": xxxx,
                "installation_id": xxx,
                "room_id": xxxxxx
            },
            "id": 145206,
            "local_id": 38,
            "physical_quantity": "humidity",
            "unit": "percent",
            "_version": 1.1
        },
        {
            "name": "Fietsenstalling",
            "status": {
                "temperature": 11.5`</del>
evilB commented 1 year ago

I've raised an issue in pyhaopenmotics