Official Honeywell evohome/Round Thermostat integration (EU-only)

This is the code:

    def current_temperature(self) -> Optional[float]:
        """Return the current temperature of a Zone."""
        if not self._evo_device.temperatureStatus["isAvailable"]:
            return None

        if self._evo_broker.temps:
            return self._evo_broker.temps[self._evo_device.zoneId]

        return self._evo_device.temperatureStatus["temperature"]

If
self._evo_device.temperatureStatus["isAvailable"] is True, then
self._evo_device.temperatureStatus["temperature"] would be a valid temperature.

The issue is that I had assumed that
self._evo_broker.temps[self._evo_device.zoneId] would also be valid if
self._evo_device.temperatureStatus["isAvailable"] was True, and above is the evidence this isn’t the case.

A solution (but not best practice code):

    def current_temperature(self) -> Optional[float]:
        """Return the current temperature of a Zone."""
        if self._evo_broker.temps:
            if self._evo_broker.temps[self._evo_device.zoneId] != 128:
                return self._evo_broker.temps[self._evo_device.zoneId]

        if not self._evo_device.temperatureStatus["isAvailable"]:
            return None

        return self._evo_device.temperatureStatus["temperature"]

I am very familiar with the evohome2 client - I wrote parts of it. My original advice stands.

Log into: https://international.mytotalconnectcomfort.com/ with the new accounts - that will confirm you can authenticate with the username, password.

For each account, check that only one location appears under “Shared Locations”.

Go to python:

python -m pip install evohomeclient
python

>>> username = "...
>>> password = "...
>>>
>>> from evohomeclient2 import EvohomeClient as EvohomeClient2
>>>
>>> c2 = EvohomeClient2(username, password)
>>> c2 = EvohomeClient2(username, "bad_password")

You can/should also check the v1 API:

>>> from evohomeclient import EvohomeClient as EvohomeClient1
>>>
>>> c1 = EvohomeClient1(username, password)
>>> c1._populate_full_data(force_refresh=True)
>>>
>>> c1 = EvohomeClient1(username, "bad_password")
>>> c1._populate_full_data(force_refresh=True)

It’s not super critical, so I will just await a general release with a fix rather than to patch in place.

Could you raise an issue over at https://github.com/home-assistant/core/issues

And maybe replace your batteries?

Not trying to be a smartass, but most of the things you’ve asked me to do, I already mentioned I did in my original post. (The only thing I hadn’t done was check the v1 evohome client)

But I did manage to figure it out. The v1 client was giving me an invalid password error instead of the invalid grant. Now I knew for 100% that the password was correct (as I had logged in with it already multiple times the past few days).

So i figured something must be going wrong with the special characters in the password. As it had all 3 of these in it: &@!

After changing the password on both accounts, they did work with the pythone evohome client (both v1 and v2).

Maybe honeywell changed the password rules to allow special characters somewhere along the way, but the client wasn’t updated for that?

That’s great you’re online.

I suspect there’s an issue with the & character - maybe you could submit an issue at

or

and one of us will sort it out.

Dug a bit more, but I get the feeling its a honeywell issue. For some reason their API just throws invalid password errors around when you have a & in a password. I tried creating a session manually on the v1 api while knowing the password is correct, and it still gives me an invalid password error.

Do they not use the same v1 or v2 API for their own website? As those passwords seem to work fine there.

Here you go

Yeah, I’m working on the batteries. About 6 TRV’s decided to go low at the same time.

To be clear - did you:
a) use the evohomeclient library via Python, or
b) use the Honeywell RESTful API via (say) CURL?

I suspect that if using a), the & has to be escaped.

I don’t know!

I did B, using Postman. Because after looking at the evohomeclient code I was not convinced the problem was there. There didn’t seem to be much string mangling going on.

I think you’ve got it right.

If you’re keen -could you work out how to escape the & char in the headers/post-data & I can update the python libraries, otherwise (no bother) I’ll come up with a workaround, to throw a more useful warning, either in the client library, or the HA component.

I think you’ll have to do the more useful warning anyway, because the password is in the json in the body, so as far as I know it does not need to be escaped?

OK, I’ll do that - thanks for your help.

Hi @zxdavb, quick question, if you were to implement turning down the heat based on open windows, how would you do it? I’ve tried a number of different ways, from turning off the heat, to storing the temperature in a variable, but I can’t really get something that will get me back 100% of the time to the state that the heating was in before… I will lose the time on my previous temporary override, for example, if I add another temporary override for the window being open. What are the cases that can be used that will put the heating back in the state where it was before?

Also, I know there is some functionality in the TRV to hook up an external window sensor, do you think we could somehow trigger that from the component?

The HR92s have an (optional) open window function, as an alternative to the (optional) open window sensor you allude to - if enabled, it is triggered on the basis of a significant drop in ambient temperature.

AFAIK, open window mode has no place in the Public/RESTful API - so no options there.

I think it would be a bad idea to implement an openwindow mode via HA - but I was thinking of a variable ecomode offset, rather than the fixed 3C from the controller - but there is some recent activity from the (new) vendor about this - the vendor is no longer Honeywell, but Resideo - see:

I guess you could do something with HA integrating a window sensor with evohome outpoints via automatons - you could record the current state, and restore it later, etc. - I’ll leave that up to others to explore.

You can track (and even trigger) open window mode via evohome_RF, using a nanoCUL with (something like) evofw3 on it.

The problem with the TRV’s open window function is that it waits for a certain drop in temperature and then sets it for 30 minutes as a fixed time, which is kind of dumb. In my rooms that have round thermostats, it rarely detects it because they are on the other side of the room. And 30 minutes is never really the right amount of time. If we could emulate the window sensor that feeds into it, I would hope we could do it for the duration that the window is open. Maybe I will try to write an appdaemon to do this.

Hey I got this in the log today if it’s interesting to you:



Logger: evohome.logger
Source: /usr/local/lib/python3.7/site-packages/evohome/message.py:1026
First occurred: July 6, 2020, 3:58:32 AM (21 occurrences)
Last logged: July 6, 2020, 3:59:34 AM

    EXCEPTION, raw_packet = >>> 045 RP --- 01:158182 04:136489 --:------ 313F 009 00FCB10004060707E4 <<<
    EXCEPTION, raw_packet = >>> 045 RP --- 01:158182 04:136505 --:------ 313F 009 00FCB10004060707E4 <<<
    EXCEPTION, raw_packet = >>> 045 RP --- 01:158182 04:136495 --:------ 313F 009 00FCB50004060707E4 <<<
    EXCEPTION, raw_packet = >>> 045 RP --- 01:158182 04:136481 --:------ 313F 009 00FCB90004060707E4 <<<
    EXCEPTION, raw_packet = >>> 045 RP --- 01:158182 04:136485 --:------ 313F 009 00FC870104060707E4 <<<

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/evohome/message.py", line 1019, in payload
    self._payload = payload_parser(self.raw_payload) if payload_parser else None
  File "/usr/local/lib/python3.7/site-packages/evohome/message.py", line 708, in sync_datetime
    return {"datetime": _dt(payload[4:18])}
  File "/usr/local/lib/python3.7/site-packages/evohome/message.py", line 311, in _dt
    second=int(seqx[:2], 16),
ValueError: second must be in 0..59

Thanks for reporting this.

This is a known issue & has already been fixed in the newest library. It is because the unused 8th bit is used to indicate DST (summer time).

It is not clear to me whether this issue was caused by the very latest evohome firmware, or only became apparent after DST started - I think the former, but it could have been the later.

Anyway, this error shouldn’t cause any issue with your system, as this payload is not used by HA.

hey all,
did something change in the attributes at all?
i had a load of templates for reporting the status based on “hvac_action” however i dont see this as an attirbute any more?

      radiator_status_bathroom:
        friendly_name: "Radiator Status: Bathroom"
        value_template: "{{ state_attr('climate.bathroom', 'hvac_action') }}"