nebulous / infinitude

Open control of Carrier/Bryant thermostats
MIT License
224 stars 50 forks source link

Clarification on Carrier server access #177

Closed lukeCpp closed 10 months ago

lukeCpp commented 10 months ago

Apologies in advance if this info is already available somewhere, but I was having a hard time finding a definitive answer. I have a new Carrier Infinity system and am running the published docker container to enable control from HA. I had some struggles during the initial setup, and wanted to get some server access clarification. From info I found in one of the other issues, it seems like the Carrier servers are only involved if you're controlling the system from both infinitude and the carrier app? Does Infinitude (or does the tstat) need to be able to reach Carriers servers at all, even if I don't plan to use the Carrier app for control?

For some background, in my home I have 2 LANs - one is dedicated to my IoT devices and has no internet access. I have one machine acting as the bridge to the IoT LAN, and infinitude is running there. I followed the readme and everything came up fine using the docker-compose steps. I then put my tstat on the IoT LAN WiFi and configured the proxy address, but nothing would populate to the infinitude server. The tstat showed the WiFi icon with an exclamation because it couldn't reach the MyInfinity server (www.api.ing.carrier.com). I then tried swapping the tstat over to my other LAN's WiFi, and swapped the tstat proxy settings over to the new subnet and everything started working perfectly. For now I have pass_reqs=0 so it's at least reaching out as little as possible, but ideally I'd like the setup to be on the other LAN and never touch Carrier at all. Last thing I want is some upstream server change (or outage) to break everything. Also, in case it matters at all the thermostat is an STSTXCCWIC01-B with v4.05 firmware.

nebulous commented 10 months ago

Infinitude sits between your thermostat and Carrier's servers. If you don't need to use Carrier's cloud apps then I wouldn't think that internet access would be required for long-term use, though I haven't tested that theory in daily use myself. It would be best to have internet access for initial setup so that the thermostat can contact Carrier and be convinced that everything is working - which it sounds like you've done. The trouble with having pass_reqs=0 is that infinitude can't cache any responses from Carrier, since it can't contact Carrier in the first place. The thermostat won't upgrade its firmware without your intervention, so for the least headaches, I would recommend setting pass_reqs to a rather high value and allowing internet access.

lukeCpp commented 10 months ago

Thank you for the quick reply! I appreciate you taking the time to answer my questions and for all the work that has gone into this project. It's been so great to use over the past week-ish.

I think I'll plan to keep pass_reqs=0 for the time being, if anything as a bit of an experiment since carriers cloud apps shouldn't be required for long-term use. It's an easy enough thing to change if something breaks. I definitely am observing an interruption in thermostat/infinitude communications when the thermostat "isn't connected" and shows an exclamation. I was able to force that on my main LAN by blocking the MyInfinity API address in my pihole settings, which makes me think it's doing something (hopefully simple) related to DNS to determine connectivity...? Ideally I'd like to figure out what that is, and replicate it locally to stub out the MyInfinity server on my IoT subnet to allow everything to run totally isolated.

So when you say, "It would be best to have internet access for initial setup so that the thermostat can contact Carrier and be convinced that everything is working" Is there any kind of authentication token-y type thing the carrier servers normally use to authenticate messages to/from the thermostat that infinitude also is using?

dragonflight commented 10 months ago

For more clarification, in very simplistic terms (and not 100% true) infinitude acts as a proxy forwarding messages (requests) from the the tstat to the cloud and relaying the responses back to the tstat.

In the process it maintains a copy of the latest requests and responses in the directory "state". Based on the value of pass_reqs it decides to either forward the request or reply immediately with its copy of the latest response (if it has one), to reduce the traffic going to the cloud, as it increases the frequency of traffic from the tstat.

Of course its main purpose is to exposes the contents of these messages through it API(s). It also manipulates the cloud's responses to the extent that it can effect changes to the tsat.

This should explain why infinitude must be connected initially to the cloud at least overnight to receive the bulk of the responses.

I am not sure which of the messages must be responded to for the tstat to consider itself connected, but it must at least receive a response to the ALIVE message that it sends periodically, but it does not fret if it does not get a response to the sequence of commands required to download a new software version (this I discovered by accident in both nebulous's version and my own copycat) which is fortuitous.

One final comment, if you leave the tstat in the unconnected state (yellow "!") it will periodically reset in an attempt to re-establish the connection. This will abruptly stop the system (HP,strip heating, not sure about the fan if the strip heating was on) and delaying any restart of the HP for 5+ minutes). I assume it does it safely, but it is probably not a good idea to leave it in that condition for long.

nebulous commented 10 months ago

You're answering all of your own questions! 😄 Yep, the above is a good summary of how Infinitude works. Its primary goal is to allow local control of the thermostat and a secondary goal is to not break use of Carrier's apps. Though in practice, very few people care to use Carrier's apps - I certainly don't.

The thermostat sends a bunch of different xml docs to Carrier's servers to maintain and update its state. Some of them we synthesize so that a call to Carrier isn't ever required(ie Alive, set time, system status) but others we just want to monitor and/or not interfere with(gas usage/system alerts/any random new feature)

I think you may be on to something re DNS. If the thermostat can't resolve the IP of the Carrier service it may not even bother sending an Alive message (which would be generated/returned directly from Infinitude if requested).

to test that theory you could - as I take it you may have already done in your pihole config - disallow all internet-bound traffic from the thermostat except DNS and see if that resolves the alert/rebooting issue.

or (and obviously this would definitely break access to any of Carrier's services) change the hostname for the API to something locally-resolvable, which still matches this regex (bryant|carrier|ioncomfort|127.0.0.1). eg a pihole host entry for carrier-infinitude.local

nebulous commented 10 months ago

Added a commit to also match any domain which includes infinitude here: d97f310235dea

lukeCpp commented 10 months ago

@nebulous You are correct, it doesn't even try to send an alive message if it can't resolve the carrier server address(es). Making sure those locally resolve was the solution. In my case I set up an empty DNS server on my IoT subnet with rewrite entries for www.api.ing.carrier.com, carrier.no-ip.info, and www.ota.ing.carrier.com (found the other two by doing some wireshark sniffing). I redirected them to the infinitude server IP, but I think any address should be fine...I'm pretty sure it only cares about getting a success DNS response back.

Thanks again for the support! :beers: