home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
73.45k stars 30.69k forks source link

Homekit thermostat mapping is wrong #33386

Closed fredrike closed 4 years ago

fredrike commented 4 years ago

The problem

Mapping from Homekit thermostat to HA is wrong..

https://github.com/home-assistant/core/blob/b731ddabde71b54fe295e76c26896b884b71ea9e/homeassistant/components/homekit/type_thermostats.py#L71-L79

I suggest that HVAC_MODE_AUTO: 3, is removed.

Environment

Problem-relevant configuration.yaml

Traceback/Error logs

2020-01-03 15:57:30 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection.139826232287184] 'auto'
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 133, in handle_call_service
    connection.context(msg),
  File "/usr/src/homeassistant/homeassistant/core.py", line 1235, in async_call
    await asyncio.shield(self._execute_service(handler, service_call))
  File "/usr/src/homeassistant/homeassistant/core.py", line 1260, in _execute_service
    await handler.func(service_call)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 205, in handle_service
    self._platforms.values(), func, call, service_name, required_features
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 336, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 358, in _handle_service_platform_call
    await getattr(entity, func)(**data)
  File "/usr/src/homeassistant/homeassistant/components/daikin/climate.py", line 199, in async_set_hvac_mode
    await self._set({ATTR_HVAC_MODE: hvac_mode})
  File "/usr/src/homeassistant/homeassistant/components/daikin/climate.py", line 131, in _set
    values[daikin_attr] = HA_STATE_TO_DAIKIN[value]
KeyError: 'auto'
2020-01-20 23:12:02 DEBUG (MainThread) [homeassistant.components.websocket_api.http.connection.548130921552] Received {'type': 'call_service', 'domain': 'climate', 'service': 'set_hvac_mode', 'service_data': {'entity_id': 'climate.daikinap27027', 'hvac_mode': 'heat_cool'}, 'id': 43}
2020-01-20 23:12:02 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=climate, service=set_hvac_mode, service_data=entity_id=climate.daikinap27027, hvac_mode=heat_cool>
2020-01-20 23:12:02 DEBUG (MainThread) [pydaikin.appliance] Sending query_c: aircon/set_control_info?pow=1&mode=auto&stemp=23&shum=--&f_rate=5&f_dir=0&lpw=&f_airside=0
2020-01-20 23:12:03 DEBUG (MainThread) [pydaikin.appliance] Represent: mode, mode, auto
2020-01-20 23:12:03 DEBUG (MainThread) [pydaikin.appliance] Represent: f_rate, fan rate, high
2020-01-20 23:12:03 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=climate.daikinap27027, old_state=<state climate.daikinap27027=cool; hvac_modes=['fan_only', 'dry', 'cool', 'heat', 'heat_cool', 'off'], min_temp=7, max_temp=35, target_temp_step=1, fan_modes=['Low', 'Mid', 'High'], current_temperature=23.0, temperature=23.0, fan_mode=High, friendly_name=DaikinAP27027, supported_features=9 @ 2020-01-20T23:08:10.008825+11:00>, new_state=<state climate.daikinap27027=heat_cool; hvac_modes=['fan_only', 'dry', 'cool', 'heat', 'heat_cool', 'off'], min_temp=7, max_temp=35, target_temp_step=1, fan_modes=['Low', 'Mid', 'High'], current_temperature=23.0, temperature=23.0, fan_mode=High, friendly_name=DaikinAP27027, supported_features=9 @ 2020-01-20T23:12:03.061673+11:00>>
2020-01-20 23:12:03 DEBUG (MainThread) [homeassistant.components.websocket_api.http.connection.548134659088] Sending {'id': 2, 'type': 'event', 'event': <Event state_changed[L]: entity_id=climate.daikinap27027, old_state=<state climate.daikinap27027=cool; hvac_modes=['fan_only', 'dry', 'cool', 'heat', 'heat_cool', 'off'], min_temp=7, max_temp=35, target_temp_step=1, fan_modes=['Low', 'Mid', 'High'], current_temperature=23.0, temperature=23.0, fan_mode=High, friendly_name=DaikinAP27027, supported_features=9 @ 2020-01-20T23:08:10.008825+11:00>, new_state=<state climate.daikinap27027=heat_cool; hvac_modes=['fan_only', 'dry', 'cool', 'heat', 'heat_cool', 'off'], min_temp=7, max_temp=35, target_temp_step=1, fan_modes=['Low', 'Mid', 'High'], current_temperature=23.0, temperature=23.0, fan_mode=High, friendly_name=DaikinAP27027, supported_features=9 @ 2020-01-20T23:12:03.061673+11:00>>}
2020-01-20 23:12:03 DEBUG (MainThread) [homeassistant.components.websocket_api.http.connection.548130921552] Sending {'id': 2, 'type': 'event', 'event': <Event state_changed[L]: entity_id=climate.daikinap27027, old_state=<state climate.daikinap27027=cool; hvac_modes=['fan_only', 'dry', 'cool', 'heat', 'heat_cool', 'off'], min_temp=7, max_temp=35, target_temp_step=1, fan_modes=['Low', 'Mid', 'High'], current_temperature=23.0, temperature=23.0, fan_mode=High, friendly_name=DaikinAP27027, supported_features=9 @ 2020-01-20T23:08:10.008825+11:00>, new_state=<state climate.daikinap27027=heat_cool; hvac_modes=['fan_only', 'dry', 'cool', 'heat', 'heat_cool', 'off'], min_temp=7, max_temp=35, target_temp_step=1, fan_modes=['Low', 'Mid', 'High'], current_temperature=23.0, temperature=23.0, fan_mode=High, friendly_name=DaikinAP27027, supported_features=9 @ 2020-01-20T23:12:03.061673+11:00>>}
2020-01-20 23:12:03 DEBUG (MainThread) [homeassistant.components.websocket_api.http.connection.548130921552] Sending {'id': 43, 'type': 'result', 'success': True, 'result': {'context': Context(user_id='ca2fd1eb2f134d579c6c2ba1f1af20a4', parent_id=None, id='ce5936da513a4e8caf8c6b66bab14327')}}

Additional information

There have been a discussion here: https://community.home-assistant.io/t/support-for-daikin-airbase-units/102622/104 which diggs down to that it is the Homekit integration that does wrong.

bdraco commented 4 years ago

We shouldn't remove it, as we are finding valid values in __init__


        # determine available modes for this entity, prefer AUTO over HEAT_COOL and COOL over FAN_ONLY
        self.hc_homekit_to_hass = {
            c: s
            for s, c in HC_HASS_TO_HOMEKIT.items()
            if (
                s in hc_modes
                and not (
                    (s == HVAC_MODE_HEAT_COOL and HVAC_MODE_AUTO in hc_modes)
                    or (s == HVAC_MODE_FAN_ONLY and HVAC_MODE_COOL in hc_modes)
                )
            )
        }
        hc_valid_values = {k: v for v, k in self.hc_homekit_to_hass.items()}

HC_HOMEKIT_TO_HASS is a bit suspect since its reversing the dict() and there are duplicate values

bdraco commented 4 years ago

HC_HOMEKIT_TO_HASS is only being used for water heaters so thats not the issue anyways

bdraco commented 4 years ago

Its building the list right without auto

2020-03-29 16:33:38 DEBUG (SyncWorker_3) [custom_components.homekit.type_thermostats] self.hc_homekit_to_hass: {0: 'off', 1: 'heat', 2: 'cool', 3: 'auto'}, hc_valid_values: {'off': 0, 'heat': 1, 'cool': 2, 'auto': 3}

Has auto

No auto

2020-03-29 16:33:38 DEBUG (SyncWorker_3) [custom_components.homekit.type_thermostats] self.hc_homekit_to_hass: {0: 'off', 1: 'heat', 2: 'cool', 3: 'heat_cool'}, hc_valid_values: {'off': 0, 'heat': 1, 'cool': 2, 'heat_cool': 3}
bdraco commented 4 years ago

Per #28586 you may need to disable auto start

bdraco commented 4 years ago

@fredrike

_LOGGER.debug("self.hc_homekit_to_hass: %s, hc_valid_values: %s", self.hc_homekit_to_hass, hc_valid_values)

Would you please add this to your type_thermostats.py

After this line

hc_valid_values = {k: v for v, k in self.hc_homekit_to_hass.items()}

And then restart with logger for homekit set to debug (https://www.home-assistant.io/integrations/logger/) and paste in the result here?

djxie2019 commented 4 years ago

Okay where is my type_thermostats file? I’ll give this a try.

fredrike commented 4 years ago

Okay where is my type_thermostats file? I’ll give this a try.

It depends on your installation but in hassio it exist under /usr/src/homeassistant/homeassistant/components/homekit/type_thermostats.py

Send me a message and I'll try to help you.

nukefrenzy commented 4 years ago

I'm getting something similar on 0.108.1 using an Ecobee with Homekit. I get the following repeatedly in my logs:

2020-04-09 15:10:57 ERROR (MainThread) [homeassistant.core] Error doing job: Future exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/homekit/type_thermostats.py", line 386, in update_state
    HC_HASS_TO_HOMEKIT_ACTION[hvac_action]
KeyError: 'fan'
bdraco commented 4 years ago

I'm getting something similar on 0.108.1 using an Ecobee with Homekit. I get the following repeatedly in my logs:

2020-04-09 15:10:57 ERROR (MainThread) [homeassistant.core] Error doing job: Future exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/homekit/type_thermostats.py", line 386, in update_state
    HC_HASS_TO_HOMEKIT_ACTION[hvac_action]
KeyError: 'fan'

Might have fixed that in #33682

bdraco commented 4 years ago

Not much can be done to investigate this until someone does the testing in https://github.com/home-assistant/core/issues/33386#issuecomment-605664790 who has a Daikin

djxie2019 commented 4 years ago

Testing in progress...

bdraco commented 4 years ago

https://github.com/home-assistant/core/pull/34073 should resolve most of these type of issues