ZHA Thermostat

For those that are interested, I am working on ZHA Thermostats here:

https://github.com/presslab-us/home-assistant/tree/zha-thermostat

It is fully functional, but I realize that the Climate component is undergoing some changes at the moment so I expect it will change to accommodate that.

2 Likes

I have a ZigBee thermostat that pairs just fine with ZHA, but no thermostat/climate component is detected in HA. I can see all the clusters in the ZigBee management UI in HA. And I can set heat set point etc.
But, without a dashboard component to view the data or control the thermostat it is a bit cumbersome to only use the new ZigBee management console.
What you’ve done here looks promising. Can you suggest how I can implement your ZHA Thermostat support in my Hasbian install? Is there a way for me to pull your climate component?
My thermostat is the Bitron AV2010/32, which is basically just a mains switch controlled via a heat set point and the current room temperature. I would like to display both the heat set point and the current temperature in my HA dashboard as well as be able to set the heat set point. Ideally something like this:
15

But instead of setting a range for the heat set point, just a single temperature as this device doesn’t support a range.

Yeah, if you get it to work it should look like you want it to.

You can download that branch from my repo, and then copy the homeassistant/components/zha folder into a folder named custom_components/zha off your config directory. Restart hass and see what’s in your logs.

OK, thanks. I will give it a try. I downloaded the repo. Unfortunately I clicked the “Send pull request” option and it looks like it sent something to you for review. I think you can ignore that since I just downloaded an archive of the repo.

I added the zha as a custom component and the log says I am using a non-tested aha component. So, it is picking it up.
When I join my device it still joins as before, but no climate or thermostat devices are detected or created. Which log would you need to figure out what is going wrong?

This is all I see in the homeassistant.log:

pi@hassbian:/home/homeassistant/.homeassistant $ tail -f home-assistant.log
2019-06-15 13:04:32 WARNING (MainThread) [homeassistant.loader] You are using a custom integration for zha which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you do experience issues with Home Assistant.
2019-06-15 13:05:34 WARNING (MainThread) [zigpy.zdo] [0x0000:zdo] Unsupported ZDO request:ZDOCmd.Node_Desc_req
2019-06-15 13:05:34 WARNING (MainThread) [zigpy.zdo] [0x0000:zdo] Unsupported ZDO request:ZDOCmd.Active_EP_req
2019-06-15 13:05:34 WARNING (MainThread) [zigpy.zdo] [0x0000:zdo] Unsupported ZDO request:ZDOCmd.Simple_Desc_req
2019-06-15 13:07:52 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection.1739393712] Error handling message: required key not provided @ data[‘device_id’]. Got None
Traceback (most recent call last):
File “/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/websocket_api/connection.py”, line 76, in async_handle
handler(self.hass, self, schema(msg))
File “/srv/homeassistant/lib/python3.5/site-packages/voluptuous/schema_builder.py”, line 267, in call
return self._compiled([], data)
File “/srv/homeassistant/lib/python3.5/site-packages/voluptuous/schema_builder.py”, line 589, in validate_dict
return base_validate(path, iteritems(data), out)
File “/srv/homeassistant/lib/python3.5/site-packages/voluptuous/schema_builder.py”, line 427, in validate_mapping
raise er.MultipleInvalid(errors)
voluptuous.error.MultipleInvalid: required key not provided @ data[‘device_id’]

The log to look at is the one you see on the web page while you pair the thermostat. Cut and paste that.

I think I did something wrong when downloading the repository above. I see in the web browser a climate.py under zha, but what I downloaded doesn’t have a climate.py in there. So, that would explain why no thermostat can be detected.

You need to make sure you select the proper branch when downloading.

I re-downloaded and now the climate.py is included in the zha directory. Not sure why it was missing the first time. I am currently traveling, so I will retry later this week to see if it now works. I suppose it should work since the HA Zigbee Management detects all the clusters. So, it looks to be pretty much standard and doesn’t use vendor specific clusters.

I just tried again with a version that included climate.py. But now my zha fails completely since it can’t initialize the zigbee device (/dev/ttyUSB0).

2019-06-20 14:52:51 ERROR (MainThread) [homeassistant.config_entries] Error setting up entry /dev/ttyUSB0 for zha
Traceback (most recent call last):
File “/srv/homeassistant/lib/python3.5/site-packages/homeassistant/config_entries.py”, line 310, in async_setup
hass, self)
File “/home/homeassistant/.homeassistant/custom_components/zha/init.py”, line 94, in async_setup_entry
await zha_gateway.async_initialize(config_entry)
File “/home/homeassistant/.homeassistant/custom_components/zha/core/gateway.py”, line 69, in async_initialize
self.zha_storage = await async_get_registry(self._hass)
File “/home/homeassistant/.homeassistant/custom_components/zha/core/store.py”, line 160, in async_get_registry
return cast(ZhaDeviceStorage, await task)
File “/usr/lib/python3.5/asyncio/futures.py”, line 380, in iter
yield self # This tells Task to wait for completion.
File “/usr/lib/python3.5/asyncio/tasks.py”, line 304, in _wakeup
future.result()
File “/usr/lib/python3.5/asyncio/futures.py”, line 293, in result
raise self._exception
File “/usr/lib/python3.5/asyncio/tasks.py”, line 239, in _step
result = coro.send(None)
File “/home/homeassistant/.homeassistant/custom_components/zha/core/store.py”, line 155, in _load_reg
await registry.async_load()
File “/home/homeassistant/.homeassistant/custom_components/zha/core/store.py”, line 112, in async_load
power_source=device[‘power_source’],
KeyError: ‘power_source’

looks like this error is unrelated to the ZHA thermostat implementation. If I remove the custom_components directory I still get this error.
Crap, my ZHA worked before and now it has broken. It must have been the last (or the one before last) update that broke it, because I haven’t changed anything except testing this custom ZHA thermostat deployment.

EDIT:
I found the error with my ZHA in general. 0.90 broke it when the store.py was introduced. When I go back to 0.89.2 my ZHA works again.

Now the bad news for me and your thermostat custom component - your component is apparently also based off the 0.9x release since you have a store.py and I get the same error I was getting before downgrading to 0.89.2. You think there is any way of getting your climate component working in the 0.89.2 HA release?

I guess you could apply the branch diff to 0.89.2 and see what happens? Although your should probably figure out why your ZHA doesn’t work on 0.90. Maybe you need to edit your ZHA database.

Yeah, from looking at the store.py file and the errors I get it looks like it us looking for keys in the DB (power_source) that don‘t exist. The question is what should I fix in the DB? I know how to modify SQLite DBs. But I did delete the DB I had and let it be recreated after reinstalling the ZHA integration while in 0.9x. So, I suspect the issue is not in the general DB structure. Maybe certain data is not added to the DB for my Zigbee USB device when ZHA is reinstalled and associated with the device using ezsp. Do you have any idea what the power_source (the one in the line after it in store.py) data would be that needs to be associated with a zigbee USB stick?
I would like to fix 0.9x instead of remaining on 0.86.2.

OK, I got it fixed. There was a messed up file (zha.storage) in the homeassistant users directory structure.
Now my ZHA works in 0.9x and your custom component works as well. Although the standard thermostat card in Lovelace doesn’t seen to work properly. If I change the temperature in that “dial” it doesn’t change the heat set point on my thermostat. The only thing that seems to work in that card is the “Off” button. Unfortunately, hitting it a second time doesn’t turn the thermostat back on.
So, I need to look for a better thermostat card for this thermostat. Maybe this custom simple thermostat card will do the trick: Lovelace: Simple thermostat card

I am using the Lovelace cards and it works ok for me.

What is the ctrl_seqe_of_oper attribute set to in the Thermostat cluster?

The ctrl_seq_of_oper value is 2.
The card can display the current temperature and it shows an off button (because the operations_list only has off in it). The off button apparently controls the system_mode cluster and sets it to 0. I can manually set it back into an operational state by using the ZHA management and setting the value to 4. Then the thermostat goes back into its normal operating state.
This thermostat has clusters for heat and cool set points (occupied and unoccupied), although the only one that needs to be set is the occupied_heating_setpoint cluster as all this thermostat does is switch a mains connection on or off (using it to turn a infrared heater on and off when the heat set point is reached). If I could only get the heat setpoint control to work, I think I would be set to go.
Currently the heat setpoint control of the standard card just shows me whatever I set it to. It never shows the current value or even changes the value on the thermostat.
I tried a custom thermostat card (Simple Thermostat - https://github.com/nervetattoo/simple-thermostat). But it has a similar behavior. It will show the current temperature and the current state (Heat or Off). But the setpoint always displays “N/A”. Even if I do set a value there, it will eventually return to N/A.

EDIT: just noticed that the ctrl_seqe_of_oper value 2 (or 0x02) means “Heating Only”. Makes sense, since it is only controlling a heater by turning it on and off when the heat setpoint is reached.
Question is, how can I get the card to understand that it only needs to set the occupied heat setpoint?

It uses a cached value on boot for ctrl_seqe_of_oper, maybe this didn’t get stored properly. You can look in the zigbee.db and see if that attribute is there. The climate component configures itself based on that value when it starts up.

It would look like INSERT INTO attributes VALUES('addr',ep,513,27,2), the “513,27,2” being the key values, and addr and ep being specific to your device.

If might actually be in there now that you read it manually. Perhaps a restart of HA is all that’s needed.

Yeah those values already exist in the DB. And I have restarted HA multiple times. So, I don’t think this is the reason for not being able to set heat set points from the card.

EDIT: interesting. Now the card is reading the existing heat set point and displaying it. So, now I see the current heat set point, temperature and status.
But, when I try to set a new heat setpoint I now get a traceback error in my HA log:

2019-06-27 13:42:43 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection.1747786992] name ‘ATTR_TEMPERATURE’ is not defined
Traceback (most recent call last):
File “/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/websocket_api/commands.py”, line 121, in handle_call_service
connection.context(msg))
File “/srv/homeassistant/lib/python3.5/site-packages/homeassistant/core.py”, line 1150, in async_call
self._execute_service(handler, service_call))
File “/usr/lib/python3.5/asyncio/futures.py”, line 380, in iter
yield self # This tells Task to wait for completion.
File “/usr/lib/python3.5/asyncio/tasks.py”, line 304, in _wakeup
future.result()
File “/usr/lib/python3.5/asyncio/futures.py”, line 293, in result
raise self._exception
File “/usr/lib/python3.5/asyncio/tasks.py”, line 239, in _step
result = coro.send(None)
File “/srv/homeassistant/lib/python3.5/site-packages/homeassistant/core.py”, line 1172, in _execute_service
await handler.func(service_call)
File “/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity_component.py”, line 194, in handle_service
required_features
File “/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/service.py”, line 316, in entity_service_call
future.result() # pop exception if have
File “/usr/lib/python3.5/asyncio/futures.py”, line 293, in result
raise self._exception
File “/usr/lib/python3.5/asyncio/tasks.py”, line 239, in _step
result = coro.send(None)
File “/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/service.py”, line 339, in _handle_service_platform_call
await func(entity, data)
File “/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/climate/init.py”, line 559, in async_service_temperature_set
await entity.async_set_temperature(**kwargs)
File “/home/homeassistant/.homeassistant/custom_components/zha/climate.py”, line 389, in async_set_temperature
temperature = kwargs.get(ATTR_TEMPERATURE)
NameError: name ‘ATTR_TEMPERATURE’ is not defined

Ah yes there was a slight bug there. I do not have a heating only thermostat to test. Get the latest climate.py from my Github and try it again.