nebulous / infinitude

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

Serial only works for a few seconds #187

Open MallocArray opened 1 month ago

MallocArray commented 1 month ago

I have a USB RS485 adapter connected to a Pi4 and I have Infinitude running in Docker. https://www.amazon.com/gp/product/B00NKAJGZM I'm on a higher firmware than is supported for the Proxy config, but I was hoping to be able to view the serial information to get some extra metrics.

  1. Is there an API that exposes the serial data, so I could consume just the serial data into HomeAssistant for tracking?

After updating my Docker Compose file and starting the container, I can view Serial data for a few seconds

image

But after a few seconds, maybe around 1 minute, the Stream section empties out entirely, and nothing else updates under State, it just gets older.

image

In the Docker logs, I see a message about Websocket Closed and then more lines about using the serial interface, but still nothing updates in the page.

The only way I've been able to get data to refresh is to restart the container entirely, which I don't think is expected. Any thoughts?

infinitude    | MODE is set to Production
infinitude    | Using /dev/ttyUSB0 serial interface
infinitude    | [2024-06-25 16:18:58.41914] [7] [info] Listening at "http://*:3000"
infinitude    | [2024-06-25 16:19:07.78226] [7] [info] Websocket Closed: 1001
infinitude    | Using /dev/ttyUSB0 serial interface
infinitude    | Using /dev/ttyUSB0 serial interface
infinitude    | Using /dev/ttyUSB0 serial interface
infinitude    | [2024-06-25 16:19:58.76175] [7] [info] Websocket Closed: 1006
infinitude    | Using /dev/ttyUSB0 serial interface
infinitude    | Using /dev/ttyUSB0 serial interface
infinitude    | Using /dev/ttyUSB0 serial interface
nebulous commented 1 month ago

It looks like you're doing everything right, but for some reason the connection to the serial stream is being lost. A Pi4 is definitely beefy enough to keep up unless there's a lot of other USB traffic. Those messages are attempts to reopen the interface.. Does the same thing happen independent of Infinitude? a test for that might be cat /dev/ttyUSB0 | strings or check the little C program cardump in contrib

nebulous commented 1 month ago

*setting mode to development will result in a bit more debug info which could help as well.

MallocArray commented 1 month ago
Attaching to infinitude
infinitude    | MODE is set to development
infinitude    | Using /dev/ttyUSB0 serial interface
infinitude    | [2024-06-25 23:52:25.36025] [7] [info] Listening at "http://*:3000"
infinitude    | Using /dev/ttyUSB0 serial interface
infinitude    | Using /dev/ttyUSB0 serial interface
infinitude    | Using /dev/ttyUSB0 serial interface
infinitude    | Using /dev/ttyUSB0 serial interface
infinitude    | Using /dev/ttyUSB0 serial interface
infinitude    | Using /dev/ttyUSB0 serial interface
infinitude    | Using /dev/ttyUSB0 serial interface

I moved the adapter from USB3 port to USB2 but same results. Development didn't seem to show much different.

I tried the cat command, and sometimes it shows nothing and just returns, and other times it shows a bit and then goes back to the terminal. Does that indicate an issue with the adapter more than Infinitude?

~/docker/infinitude $ cat /dev/ttyUSB0 | strings
~/docker/infinitude $ cat /dev/ttyUSB0 | strings
xre 
VARIABLE SPEED FURNAC
%K{K}[}[m}{o}
VARIABLE SPEED FURNAC
VARIABLE SPEED FURNAC
MallocArray commented 1 month ago

Lots more data with cardump

/tmp/infinitude/contrib/cardump $ cat frames.tsv 
Time    From    To      Type    Length  Hex Content
1719360101      20      56      0b      3       00 07 04 
1719360101      56      20      06      14      00 07 04 00 00 00 00 00 00 00 00 00 00 00 
1719360101      20      40      0b      3       00 01 04 
1719360101      40      20      06      123     00 01 04 56 41 52 49 41 42 4c 45 20 53 50 45 45 44 20 46 55 52 4e 41 43 45 20 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 43 45 53 52 31 33 31 36 37 31 2d 30 35 20 20 20 35 39 4d 4e 37 42 30 36 30 43 31 37 31 31 31 34 00 00 00 00 31 36 32 31 4d 31 35 34 38 39 38 20 32 34 32 31 41 34 36 36 30 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
1719360101      20      40      0b      3       00 03 06 
1719360101      40      20      06      13      00 03 06 01 02 5f 02 e9 00 c8 05 82 08 
1719360101      20      40      0b      3       00 03 0a 
1719360101      40      20      06      17      00 03 0a 01 71 71 03 00 51 00 3a 00 00 10 08 01 14 
1719360101      20      56      0b      3       00 06 0a 
1719360101      56      20      06      117     00 06 0a 48 52 34 36 56 50 30 30 31 00 00 00 00 00 00 00 41 30 32 39 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 19 9f 0b 3f 19 9f 0b 3f 0c b0 1e ff 0e ff 00 00 00 00 00 00 00 00 00 00 00 00 0b 7c 01 4a 00 00 00 00 00 00 00 00 00 06 59 00 00 02 0b 73 01 4a 00 03 00 00 00 00 07 7c ff 36 07 21 00 00 14 28 0e d1 05 2f 04 b0 07 29 00 00 05 41 07 62 
1719360101      20      56      0b      3       00 07 02 
1719360101      56      20      06      35      00 07 02 43 45 53 52 31 33 31 36 36 30 00 01 01 01 01 68 43 45 53 52 31 33 31 36 39 37 00 01 01 01 02 d0 
1719360101      20      56      0b      3       00 03 02 
1719360101      56      20      06      59      00 03 02 01 11 04 cc 01 12 04 ef 00 54 02 f0 00 4a 09 70 01 4a 2f 0d 01 45 08 90 00 00 00 00 00 00 00 00 04 55 02 f0 00 00 00 00 00 00 00 00 00 00 00 00 01 5b 02 59 01 5c 05 9f 
nebulous commented 1 month ago

I tried the cat command, and sometimes it shows nothing and just returns, and other times it shows a bit and then goes back to the terminal. Does that indicate an issue with the adapter more than Infinitude?

At first blush, I'd say yes that seems like an issue independent of Infinitude(provided Infinitude was not running when these tests were run), but for the below...

Lots more data with cardump

does cardump keep dumping in perpetuity or does it also stop after a bit?

shbatm commented 1 month ago

Looks like I'm having the same issue. Carrier Infinity Touch Thermostat running firmware version 4.56 connected to a fresh RPi4 with an FDTI USB to RS485 adapter.

cardump will run perpetually, but the Infinitude Web UI just keeps resetting like the logs above.

Curiously I was also having issues with the outdoor unit not wanting to turn on while this was connected, I wonder if it was generating some traffic the system didn't like.

MallocArray commented 1 month ago

That is pretty much my exact same scenario. cardump runs perpetually with no issue and continues to provide data. cat stops after a short amount of time.

I had left it connected and running and after a few hours I had an error on my thermostat OUTDOOR UNIT COMMUNICATION FAULT (Code: 179)

I ended up removing the USB adapter and power cycling the system to clear the error. May not be worth the risk of causing an error or the system to not be available.

shbatm commented 1 month ago

I had a Zone Control comms error from when I first connected the unit, I also had a resettable fault for the furnace for the 24VAC fuse, but I'm not sure when that was from. Same sentiment on the serial comms, I would love to be able to pull the extra information, but don't want to risk the system getting locked out due to a comms error when I'm not around to fix it.

Interestingly, I was able to get the serial stream to work briefly in the Web UI by just restarting the docker container a few times, but then it died again after a few minutes.

shbatm commented 1 month ago

@MallocArray - Are you connecting to the Pi over Wi-FI or Wired LAN? Out of ~desparation~ curiosity, I switched from Wireless to Wired and it appears to be much more stable.

dragonflight commented 1 month ago

couple of comments (I can't check out too much or experiment because I'm pretty much stuck laying down/sleeping on my couch - at least my monster TV is is a monitor for my computer!)

the fact that cardump works is good. cat probably fails because the tty is not in "raw" mode $ sudo stty -F /dev/ttyUSB0 38400 raw should fix that. as for infinitude it sounds like the same thing, but I don't remember who (what) was responsible for setting the tty mode.

It might also explain the comm errors as the interface may have responded to special chars like ^H.
$ stty -F /dev/ttyUSB0 will list what modes are set $ man stty for gory details. Try setting taw mode before running infinitude and see it makes a difference. Try checking after it stops.

shbatm - As for comm errors, they reset themselves as long as they are intermittent. if you really only want to just monitor, get one of the rs-232(ish)-rs-485 converters. (ish-because they're 0-5v) and you can be sure it will never transmit if you tie the TX pin high (or is it low?). Your using a PI so you have serial ports.

shbatm commented 1 month ago

@dragonflight thanks for the feedback -- I'm pretty sure the comms errors were a result of me hooking up the unit.

So I ran everything fine overnight with the Pi connected to ethernet and Infinitude running. Today when I tried to switch from my desktop to my laptop for monitoring, I accidentally used the WiFi IP for the Pi in the browser and it choked again (repeated "Using /dev/ttyUSB0 serial interface" lines in the log). Disabling Wi-Fi on the Pi entirely caused the stream to start working again.

nebulous commented 1 month ago

what @dragonflight said ⬆️ ... and I vaguely recall someone had trouble with one of the converters getting itself stuck in transmit mode(which sounds like what must have happened when you had to power cycle).

@shbatm - that's interesting re wifi - the serial traffic a miniscule amount of data for the usb bus width, but I believe the wifi adaptor on the Pi is a usb device, so I guess it's possible.

ultimately, I ended up getting one of the little WaveShare rs485 to ethernet boxes on @scyto's recommendation and, despite being overkill, is only like $25 and I haven't had to think about it since. It's nice to be able to test with any device on the network too.

MallocArray commented 1 month ago

@shbatm I was using Wifi to connect to my Pi, but don't have Ethernet nearby, so not easy to try switching over to that.

dragonflight commented 1 month ago

While I started to look at RP4s and look at their usb structures and didn't get very far, I realized that you both said (please correct if I'm mistaken) that cardump worked while you were connected by WiFi. cardump is excercising both the ttyUSB interface and the WiFi AND working.

@shbatm I'm a little curious what infinitude gets out of 4.56

I am wondering if there is a timeout or buffering difference between the WiFi and Ethernet connection between the thermostat and Infinitude that is causing the 485 interface to dropout or skip data. Running tcpdump may be instructive??

Otherwise if the only useful information is from the abcd interface creating a filter for cardump may be the best option and I can be of some use there.

shbatm commented 1 month ago

Re: WiFi/Wired, from what I can tell it's an issue with the actual webserver/websocket trying to stream over the Wi-Fi and resetting the server, rather than actual interference with the serial adapter itself.

The Infinitude front-end doesn't get much on 4.56, just shows the blower rpm (I didn't even try setting up the proxy yet), but I've been playing around to see if I could get more info out of the serial stream. So far in addition to most of the values already listed in the wiki for Zone Dampers and the Zone Thermostats, I've been able to extract the following additional info from my outdoor 24VNA9 unit--adding what I can back to the Wiki:

Device Address Data Byte Type
OutdoorUnit2 00 03 02 3 uint16 outdoor_air_temp*16
OutdoorUnit2 00 03 02 7 uint16 outdoor_coil_temp*16
OutdoorUnit2 00 03 02 11 uint16 suction_temp*16
OutdoorUnit2 00 03 02 15 uint16 superheat_temp*16
OutdoorUnit2 00 03 02 19 uint16 unknown_temp*16
OutdoorUnit2 00 03 02 23 uint16 discharge_temp*16
OutdoorUnit2 00 03 04 8 uint8 line_voltage;
OutdoorUnit2 00 06 04 1 uint16 target_compressor_rpm
OutdoorUnit2 00 06 0E 1 uint8 outdoor_unit_stage
OutdoorUnit2 00 03 03 3 uint16 suction_pressure*16
IndoorUnit 00 03 06 4 uint16 indoor_airflow_cfm

The only thing I haven't cracked yet is the static pressure, which doesn't look like it matches the update frequency or values showing in the Wiki.

I'm a Home Assistant user and I've pretty much conceded that I won't be able to control the system locally--only through the ha_carrier cloud integration for Carrier OpenAPI, but I'd like to be able to extract these values from serial to (most likely) MQTT for trending in HA.

dragonflight commented 1 month ago

@nebulous It seems it may be a timing/timeout with mojolicious, websocket and wifi vs tcp as shbatm does not even have the proxy set up it may or may not be unique to the PI.

@shbatm the temps are actually triplets (I believe) { byte status, byte ID, int value }. status is 1 for valid, 4 for absent or failed high. value is degrees*16 Fahrenheit. side note: all temperatures are stored/calculated/targeted in Fahrenheit even if they are displayed in Celsius except for the final display value { {1,4}, 0x11, "OAT %V" }, { {1,4}, 0x12, "OCT %V" }, { {1,4}, 0x13, "OST %V" }, { {1,4}, 0x14, "LAT %V" }, { {1,4}, 0x1C, "HPT %V" }, { {1,4}, 0x30, "OST %V" }, { {1,4}, 0x40, "DIS %V" }, // appears to be on units with actual thermistor on discharge tube { {1,4}, 0x4A, "SSH %V" }, { {1,4}, 0x4B, "DIS %V" }, // appears on some units displayed as discharge, but no discharge thermistor and not same range as 0x40

As for static pressure I was never happy with that. I have a scale factor of approx 3*65536 for the value from register 316 that is close and I have a lot of recorded data from this winter (>95% rs485 and 10 sec proxy updates). IF I get even a little better and can spend some time sitting up I can correlate the static pressures, and figure out what is what)

EDIT: corrected status byte (verified by looking at history of failed sensor last year)

shbatm commented 1 month ago

Thanks @dragonflight. I still get some frequent serial resets even using the wired connection to the Pi. It just seems finiky and haven't dug in much further.

Appreciate the pointers on the temperatures though. I just got my Carrier system so I'm playing 15 years of catchup learning about what's already been decoded over the years and what does and doesn't still work.

The tips here and links from the Wiki at least got me started. My C sucks, but I was able to hack together an initial code for dumping known values straight to local MQTT, with the eventual goal of using that as the intermediary to Home Assistant/VictoriaMetrics.

dragonflight commented 1 month ago

@shbatm sorry it took me a while to look it up, but https://github.com/dulitz/finitude/blob/master/finitude/registers.py is a source for register decoding and it seems he has your outside unit as well! (mine is a heat pump). As for temp 0x14B, in my system the UI displays that temp as discharge and I have no 0x140. I have never figured it out, as there is no temperature sensor unaccounted for except inside the compressor. I assumed it was some calculated temp (like SSH) but haven't found any reference to it.

If you are interested - capture just over 2 minute file (just so it gets a complete 1 minute sequence) by $stty -F /dev/ttyUSB0 raw ; cat /dev/ttyUSB0 |gzip >shbatm.z and kill it with cntrl-C after whatever. and email it to carrier at dragonflight (not com but ca)

I have a C program that decodes the messages (some) from my indoor and outdoor units. I will see if I just change the program to your device types if it produces some useful output and I will reply with the output and the C file that does the decoding and you can see if it helps you at all.

By the way I just got my machines 3 years ago, been sick the whole time (though not as bad as right now) and when I initially searched I didn't find anything so I started from scratch, and by scratch I mean scratch - I started with a 50 year old oscilloscope, mangled an old Microchip PIC project to look at the data, figured out it was rs485 or at least similar, build a rcvr. Eventually decoded packet details, cksum ... and then a good deal of the commands and then when I finally googled the software revision id of the outdoor unit and found a bunch of hits ... - anyway I had a pleasant distraction, but you're way, way ahead of where I was!

shbatm commented 1 month ago

Email sent and I'll stop sidetracking @MallocArray's issue.

nebulous commented 1 month ago

I've been pondering simplifying the serial code by limiting Infinitude to tcp and using socat to bridge serial to tcp. My hacked together serial code is bound to contain bugs, and removing code/simplifying is a good way to remove them.

You can test this by configuring your infinitude instance to use SERIAL_SOCKET (rather than SERIAL_TTY) and using socat to make the serial port accessible on a tcp port. The following should be thought of as untested psudocode but will hopefully get the idea across..

socat tcp-l:23,reuseaddr,fork file:/dev/ttyUSB0,nonblock,ispeed=38400,ospeed=38400,rawer

then SERIAL_SOCKET="youripaddress:23"

Also, @shbatm - that's an interesting idea re mqtt direct from cardump. It may make more sense in this case to use mosquitto's pub and sub cli commands rather than linking against libmosquitto to do the mqtt bits but it's cool either way. My time is extremely limited for hacking the thermostat these days, but I still think I should factor out a CarBus cli utility separate from the Infinitude process which allows for register getting and setting. We have that in the web interface now which is nice, but a quick cli command to pull a value in raw or parsed json form and the reverse would allow more people to poke at things/pipe to mqtt/etc and I already have the CarBus code to make it possible.

shbatm commented 2 weeks ago

Just wanted to check back in and say I was able to get a stable serial connection using ser2net (similar to socat) and using the SERIAL_SOCKET instead of giving Infinitude direct access to the serial port.

connection: &infinitude
    accepter: tcp,20108
    enable: on
    options:
      kickolduser: true
    connector: serialdev,
              /dev/serial/by-id/usb-FTDI_USB-RS485_Cable_FT6FWLV6-if00-port0,
              38400n81,local

Working my way through some data now to find the useful bits -- thanks to @dragonflight for the links and other registers on here. I haven't been able to play for very long except for breaks at work, but the one thing I cannot find is the Current Temp in my main zone where the thermostat is located (can find setpoints, WiFi connection/scan details, just about everything else, but not the current temp or humidity--the SAMINFO tables are all zeroes.