Closed St4tikk closed 4 years ago
Hey there, I'm happy to help but I don't use any of those other things! As I've been figuring out what the fields mean and how to control more functions, I've been putting all of the info back on the CZII_to_MQTT wiki page. The owner of that project has given me access to update his wiki directly, and we decided to work together and try to maintain one complete protocol reference.
If you want more features and an MQTT interface, I can think of three options for you:
And you're right about making temperature changes stick. Read the note under Table 1, Row 16 on the wiki page.
So far I've got all the prerequisites installed properly (I think). I wasn't 100% sure how to install the FrameParser and Interface modules. Before attempting to install them I ran the cz2.pl script and received:
Can't locate Carrier/ComfortZoneII/Interface.pm in @INC (you may need to install the Carrier::ComfortZoneII::Interface module) (@INC contains: /home/pi/perl5/bin/lib /etc/perl /usr/local/lib/arm-linux-gnueabihf/perl/5.28.1 /usr/local/share/perl/5.28.1 /usr/lib/arm-linux-gnueabihf/perl5/5.28 /usr/share/perl5 /usr/lib/arm-linux-gnueabihf/perl/5.28 /usr/share/perl/5.28 /usr/local/lib/site_perl /usr/lib/arm-linux-gnueabihf/perl-base) at cz2.pl line 8. BEGIN failed--compilation aborted at cz2.pl line 8.
Then I copied things into: /home/pi/perl5/bin/cz2.pl /home/pi/perl5/lib/Carrier/ComfortZoneII/FrameParser.pm /home/pi/perl5/lib/Carrier/ComfortZoneII/Interface.pm
Now I get:
Excessively long <> operator at /home/pi/perl5/bin/lib/Carrier/ComfortZoneII/Interface.pm line 21. Compilation failed in require at cz2.pl line 8. BEGIN failed--compilation aborted at cz2.pl line 8.
Is this what you would expect if things are installed correctly but it's not hooked up to the unit yet? I wasn't planning to venture up into my attic to make the RS-485 connection until I was sure that things are installed properly on the Pi. I've edited the config section to use "/dev/ttyUSB0" since I'm using a USB adapter and set zones to 2.
I also tried replacing:
use IO::Socket::IP;
with use IO::Termios;
and
my $connect = "/dev/ttyUSB0"; # either host:port or /dev/ttyXXX
with
my $connect = IO::Termios->open( "/dev/ttyUSB0", "9600,8,n,1" ) or die "Cannot open ttyS0 - $!";
That didn't seem to make any difference for me either.
I really appreciate any assistance you can provide!
Well first things first: please make sure you pull the latest files from here on github. When you first submitted this a few days ago, I realized I had some local changes which hadn't yet been pushed so I did that. You'll want to grab those.
The directory layout you have is fine. The script will also work if you have a lib/ subdirectory underneath where the cz2 script is installed (same structure as in the repo). But it's fine to separate it out into existing bin and lib directories.
The "Excessively long <> operator" error doesn't make sense. I wonder if there's an issue with your copy of the file? If you get the latest, hopefully that will resolve itself.
And finally: you shouldn't have to edit anything other than the CHANGEME value, cz2 line 18. If you set it to "/dev/ttyUSB0" then it will do the IO::Termios stuff all by itself. The disclaimer here is that I don't have a serial connection, mine is TCP, so I haven't been able to test that myself.
I finally had a few free minutes to jump back into this tonight. I grabbed the latest, edited the config section, and uploaded everything straight to my home folder in the same structure as the repo. When I ran the script I ended up with a different error:
Can't locate JSON.pm in @INC
Which looks like I was just missing JSON so I ran:
sudo cpan JSON
Then I ran the script again and the usage info displayed!!! :D As a final test I tried:
cz2 set_system all=off
Which flashed the TX LED on my RS-485 adapter and left the script in a state that looks like it's waiting for a response!! I think this may be success, but I won't know for sure until I have a chance to get up into the attic (hopefully tomorrow) and get it hooked up.
Awesome, looks like you're on the right track!
Incidentally, I just pushed some more changes which you might want to pick up. The status reporting was only working correctly for heat and not for A/C, which figures since I wrote it this winter!
Also I externalized the config section (including a new ability to name your zones). You can now use a config file and/or environment variables, no need to edit the script. See the readme for more details. This will make it easier to pull new releases directly from github in the future.
I grabbed the new changes and had the idea to hook up to the thermostat wiring downstairs before venturing up into the crawl space where all the HVAC equipment lives. I didn't see any reason why that wouldn't work, but it didn't. I connected to AB using solid 18AWG wire I had laying around. Each wire was about 8 inches long.
I was using this RS-485 to USB adapter:
https://www.amazon.com/gp/product/B0195ZD3P4/ref=ppx_yo_dt_b_asin_title_o04_s00?ie=UTF8&psc=1
When I would run the script for status it would just hang with no result like it did before I hooked the adapter up. If I unplugged the adapter I would get an error about there being no /dev/ttyUSB0 which makes sense. At least it's seeing the interface.
Next I connected with screen at both 9600,8,n,1 and 38400,8,n,1 and have some screenshots of the garbage I saw which lead me to believe something is wrong with my connection method.
I started thinking (or probably overthinking) about the situation and decided that maybe I needed and RS-485 to RS-232 adapter and then a RS-232 to USB cable so I ordered both of these but had identical results:
https://www.amazon.com/gp/product/B0196AO1IG/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1
https://www.amazon.com/gp/product/B00H8HDS2K/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1
So at that point I tried different connection methods. I had been using T/R+ and T/R- with and without ground. So at this point I also tried RXD+ and RXD- with and without ground. I tried the same on the other adapter as well. After that didn't work I headed up into the crawlspace thinking that being directly connected to the board would make a difference but it did not. I left my pi up there connected to the first adapter I linked which is still connected to the board so that I can continue to experiment without having to go in and out of the crawl space more than necessary.
Here are some pics in case you can see anything obviously wrong here:
I have the exact same ECM board as jwarcd. It looks like he is just using the 12v and gnd to power the nodemcu there. https://github.com/jwarcd/CZII_to_MQTT/blob/master/docs/czii_esp8266_1.jpg
Actually the top output looks correct. 9600,8,n,1 are the correct parameters and when I connect directly to my serial interface, I get output that looks just like yours. It's a binary protocol so it won't look like much without decoding. But I'm willing to bet your wiring is correct.
The next step is to run cz2 monitor
. This will just listen passively on the serial line and print out any raw frames that go by. You should see a burst that looks like this, every 10 seconds, as the thermostat checks in with the panel:
01 -> 09 read 0.9.1
09 -> 01 reply 0.9.1.255.255.4.74.3.224.255.255
01 -> 09 read 0.9.2
09 -> 01 reply 0.9.2.255.255.255.255.255.255.255.255
01 -> 09 read 0.9.3
09 -> 01 reply 0.9.3.128.3.64.54.53.0.0
01 -> 09 write 0.9.4.0.15.0.0.0.0.0.0
09 -> 01 reply 0
01 -> 09 write 0.9.5.144
09 -> 01 reply 0
If you get that far but cz2 status
is still hanging, we can go from there. Otherwise the script might be having trouble making the serial connection.
Ok I just tried cz2 monitor
and the result is identical to when I run cz2 status
. I just get a blinking cursor until I CTRL-C to cancel the script.
Ok let's try something lower-level. First do your test above (at 9600 baud) and make sure you're getting the same output. Then run this for at least a minute and send over any output you get:
#!/usr/bin/perl
use strict;
use IO::Termios;
$| = 1;
my $fh = IO::Termios->open ("/dev/ttyUSB0", "9600,8,n,1") or die $!;
my $count = 0;
while (1) {
my $check = $fh->sysread (my $read, 16);
die $! unless defined $check;
for my $byte (split //, $read) {
printf "%02x ", ord $byte;
$count++;
if ($count == 16) {
print "\n";
$count = 0;
}
}
}
Ok here is what I got from about 3-4 minutes:
02 b4 08 28 68 10 55 ff 09 00 01 00 0b 00 00 0c 00 09 fe 09 00 01 00 0b 00 00 80 c9 fe 09 00 01 00 0b 00 00 0c 00 09 0f 00 00 00 00 ff 09 00 01 00 0b 00 00 cc 09 00 01 00 0b 00 00 0c 00 09 f8 08 28 68 10 55 ff 09 00 01 fe 09 00 01 00 00 00 54 79 09 00 01 00 42 41 82 08 08 10 10 20 20 40 72 c1 09 00 01 00 c0 09 00 01 f8 28 68 88 55 ff 09 00 01 00 0b 00 fc 08 50 ce f0 09 00 01 00 00 00 0b 00 e9 09 00 01 00 0b 00 00 00 00 00 c9 06 09 00 01 00 00 00 95 b9 09 00 01 00 ff 68 88 55 ff 09 00 01 00 0b f8 04 08 08 10 50 39 f0 09 00 01 00 00 00 0b c0 09 00 01 00 0b 00 00 0c 00 09 00 00 0b 80 09 00 01 00 0b 00 00 0c 00 09 0f 00 00 09 00 01 00 00 fe 09 00 01 00 0b 00 00 0c fe 09 00 01 00 00 00 0b 00 09 02 95 f9 09 00 01 00 0b 00 00 0c 00 09 00 01 00 09 00 01 00 0b e0 02 02 00 06 fb 09 00 01 00 0b 00 00 0c 00 09 f4 09 00 01 00 54 79 09 00 01 00 fb f4 08 08 08 10 10 a0 39 f0 09 00 01 00 00 80 42 20 55 ff 09 00 01 00 0b 00 80 09 00 01 00 0c 00 09 05 80 8e d9 02 f0 34 00 00 0b 00 ff 09 00 01 00 0b 00 00 ff 09 00 01 00 54 fd 09 00 01 00 0b 00 00 fc fc 09 00 01 00
Well this is fascinating. What you've got there is almost the CZII protocol but not quite. I wonder if your serial adapter is dropping bytes. RS485 can be a finicky protocol and I remember having to tune some of the timing parameters in my adapter to make it work. Because I'm using a network adapter rather than USB, it has web-based configuration:
Do you have any settings you can tweak in the driver for your adapter, specifically related to timing or framing?
To be honest I never installed a driver. I just plugged in the cable and it seemed to have driver support available. Where would you generally find driver settings to change from the Linux command line?
I looked up the adapter you mentioned. First try cat /sys/bus/usb-serial/devices/ttyUSB0/latency_timer
and it will probably be 16. Try either of these (they should be equivalent) and see if you get any different output to the test script above:
echo 1 > /sys/bus/usb-serial/devices/ttyUSB0/latency_timer
setserial /dev/ttyUSB0 low_latency
The result of cat /sys/bus/usb-serial/devices/ttyUSB0/latency_timer
was 16.
I tried echo 1 > /sys/bus/usb-serial/devices/ttyUSB0/latency_timer
and sudo echo 1 > /sys/bus/usb-serial/devices/ttyUSB0/latency_timer
Both resulted in:
-bash: /sys/bus/usb-serial/devices/ttyUSB0/latency_timer: Permission denied
I grabbed the file with WinSCP and verified that it was also 16.
When I tried setserial /dev/ttyUSB0 low_latency
it resulted in -bash: setserial: command not found
I went ahead and ran the test again anyways and this was the result:
80 09 00 01 00 00 00 0b 00 09 ff 09 00 01 00 00 00 0b f8 09 00 01 00 0b 00 00 00 00 00 ee f5 09 00 01 00 f0 04 94 24 a8 96 ff 09 00 01 f0 94 34 88 95 ff 09 00 01 00 0b 09 00 01 00 00 00 0b 00 09 83 09 00 01 00 00 00 fc 02 e0 1a 54 79 01 00 c9 19 02 96 34 08 a8 10 2a aa 00 00 49 bc 09 00 01 00 00 00 0b 09 00 01 00 0b 00 00 0c fc 09 00 01 00 00 00 eb 09 00 01 00 0b 00 00 0c 00 09 00 01 00 00 00 0b 00 09 02 95 b9 01 00 09 00 0b 00 00 06 00 09 02 ff 09 00 01 00 0b 00 00 0c fe 09 00 01 00 00 00 0b fc 09 00 01 00 00 00 0b 00 09 02 95 b9 01 00 09 00 0b 00 00 06 00 09 02 ff 09 00 01 00 0b 00 00 0c 09 00 01 00 00 00 aa de 09 00 01 00 0b 00 00 0c fc 09 00 01 00 00 ff 40 42 20 55 ff 09 00 01 00 0b 00 80 80 00 00 ee b5 09 00 01 00 00 00 0b 00 c9 09 00 01 00 00 05 52 53 ff 00 f0 09 00 01 80 09 00 00 0b 00 09 02 95 b9 01 00 09 00 0b 00 00 06 00 09 02 ff 09 00 01 00 fb 94 08 08 10 10 20 20 40 af ff 09 00 01 00 00 00 0b f0 09 00 01 00 00 00 0b c0 09 00 01 00 c0 09 00 01 00 ff 09 00 01 00
You might need to install setserial. Try: sudo apt install setserial
Sorry I should have figured that out! After I installed setserial and ran 'cat /sys/bus/usb-serial/devices/ttyUSB0/latency_timer' the value returned was now 1.
I ran the test again and so far have not seen any result at all.
Not getting any data back at all? That's unfortunate. I might be at the limits of what I can do to help, given that I don't have a USB serial adapter myself. I can say that what you got before has sequences of bytes here and there that look a lot like the CZII protocol (far too close to be coincidental) but there's a lot missing.
Since you mentioned having two serial adapters, did you go back and try the other with the low_latency setting? Unfortunately it looks like both of the devices you mentioned use the same chipset though, so if one chip doesn't like the RS485 timing used by the Carrier hardware, the other might be the same.
My other suggestion would be to connect the GND terminal to VG on the panel. A ground mismatch is probably unlikely but it's worth a shot.
I ordered the same wireless serial port adapter last night that you are using. Let’s see if that fixes it up. As a bonus I’ll get to move the pi out of the hot attic.
Hey look at this!
Ambient: Outside 75° / Indoor humidity 20%
Air Handler: 68°, Fan On, Cool On
Mode: Cool, Fan Auto
1. First Floor: Temperature 76°, Damper 40%, Cool setpoint 76° [HOLD]
2. Second Floor: Temperature 77°, Damper 100%, Cool setpoint 76° [HOLD]
Now I just need to figure out what some of these settings are on this wireless adapter and get my config dialed in. Then, it's time to start integrating status and control into HomeSeer! I've been looking around and I think the easiest method will be using plink to send commands and should hopefully be able to pipe the results back in to.
I really appreciate all of your help with this! I've been wanting to control this HVAC unit for like 7 years now.
Yay, I'm so glad you got it working! Sorry you had to go through so much hardware though, I really don't know why the serial adapter didn't work.
For status, take a look at the status_data command, which gives you everything above in an easily-parsed JSON format. And scripting the control commands on the command-line should be easy enough.
Good luck with the rest of your project!
Not a problem! I'm still within my return period on the other 2 adapters to back to Amazon they go! I was checking out the status_data command last night. That command is awesome! It should be the only one I need to figure out how to pull back into HomeSeer. It only took me like 2 minutes to get control commands working. I even think I'll be able to add virtual devices for heating/cooling of each zone and set them up as a dimmable light so that I can tell Alexa something like "set the air conditioner upstairs to 76".
Your script looks like the most complete and working project for controlling a CZII AC unit. I've been wanting to automate this thing for years and the last few times I looked around people were making progress but no one was quite there. I also ran across the CZII to MQTT project which is really what I'm trying to do but doesn't seems ideal for a few reasons.
1) it doesn't seem like he ever solved the temp changing issue. It looks like it was related to not adding the hold command. I think I read a post of yours that mentioned that somewhere. 2) I was hoping to run this on a Pi 3 I have laying around as opposed to an arduino.
I'm not amazing with linux by any means but I don't think I would have any trouble getting the listed perl components installed and getting your script running. What I'm not sure how to approach is getting input/output to/from your script from Homeseer. If I were able to somehow pipe it through MQTT I think that would do it, but I have no idea how to go about that. I already have MQTT up and running to integrate a few other things but they had support for MQTT built in already.
Is what I'm looking to do a difficult task? If not would you be willing to steer my efforts? Either way thank you so much for writing and publishing your script. I'm sure I'll figure something out eventually! :)