Like others, it definitely acted weird with the KJR-120X “wired controller” and so as a last-ditch effort (I almost got the company to rip it out…), we switched it to 24V control. This mostly worked, but was not good when really cold as the Honeywell had terrible settings, and does not support dual fuel to run the heat pump and electric backup at the same time.
I’d basically like to use this thread to find out the current status of RS-485 support, detail what hardware is needed. I’ve got the UART stick, and it works for everything except Follow Me support, I just can’t get the IR stuff to work.
Edit: Even tried to connect together the GND plane of the UART dongle with the wired controller’s IR TSOP. That didn’t work either.
But ideally if I could take an ESP32 and just hook it to RS-485 and be done with it, aside from times the wired controller might be needed for some maintenance settings…then that would be the cleanest, as I have the “Wifi smart module” there right now to hold the UART thing ( SMARTLIGHT SLWF-01pro (v.2.1))
“ALMOCN 2 Pack TTL to RS485 Adapter Module 3.3V 5V 485 to TTL Signal Single Chip Serial Port Level Converter Borad with RXD, TXD Indicator” off Amazon.
I used the github repo named esphome-mideaXYE-rs485 and tried that…
I used some probes to connect to the TX/RX on the wifi smart port where the Wired Controller pluigged in via RS-485.
All I get in the logs are:
[23:47:10][I][custom:130]: there are 240 bytes of data waiting
[23:47:10][I][custom:155]: dumped some data: 240
[23:47:10][I][custom:201]: First 6 bytes of incoming data were bad, not using values
[23:47:10][D][sensor:094]: 'updater': Sending state 0.00000 with 1 decimals of accuracy
[23:47:10][D][sensor:094]: 'Inlet Air Temperature': Sending state 0.00000 °F with 1 decimals of accuracy
[23:47:10][D][sensor:094]: 'Outside Air Temperature': Sending state 0.00000 °F with 1 decimals of accuracy
[23:47:11][D][number:012]: 'Set Point': Sending state 70.000000
[23:47:11][D][select:015]: 'Fan Mode': Sending state auto (index 3)
[23:47:11][D][sensor:094]: 'Coil A Temperature': Sending state 0.00000 °F with 1 decimals of accuracy
[23:47:11][D][sensor:094]: 'Coil B Temperature': Sending state 0.00000 °F with 1 decimals of accuracy
[23:47:11][D][text_sensor:064]: 'Error Codes': Sending state 'E1: 0 E2: 0'
[23:47:11][D][select:015]: 'Operating Mode': Sending state off (index 0)
[23:47:11][I][custom:130]: there are 240 bytes of data waiting
[23:47:11][I][custom:162]: got small response, wait for more. size was 240
Over and over.
Ideally, I’d like to just dump what it’s seeing, to see if I’ve even got the physical layer right.
Any help / thoughts would be appreciated!
-Matt
PS I also have a scope and a logic analyzer, and am OK with C…so I’ll hopefully have something that will make the old wired controller useless after this is done…
Changed the error line to actually just dump data - I’m getting values of some sort.
I also note that the LED on the board is always RX. I guess that means the board does not have automatic flow control. Re-reading the description on Amazon, it does…Interesting…
[04:41:43][E][midea_xye:164]: Received incorrect message length from AC
[04:41:43][W][component:237]: Component midea_xye.climate took a long time for an operation (2094 ms).
[04:41:43][W][component:238]: Components should block for at most 30 ms.
[04:41:43][D][uart_debug:114]: <<< 55:AA:C4:00:00:00:00:00:00:00:00:00:00:00:3B:01:55:AA:C4:00:00:00:00:00:00:00:30:98:00:00:00:01:20:84:80:CE:BC:D6:2C:00:00:FF:00:80:80:80:80:C4:55:AA:C0:00:00:00:00:00:00:00:00:00:00:00:3F:01:55:AA:C0:00:00:00:00:30:14:84:80:15:52:54:00:2E:FF:00:00:00:00:00:00:00:00:00:00:00:14:E0:01:1B:55:AA:C4:00:00:00:00:00:00:00:00:00:00:00:3B:01:55:AA:C4:00:00:00:00:00:00:00:30:98:00:00:00:01:20:84:80:CE:BC:D6:2C:00:00:FF:00:80:80:80:80:C4:55
[04:41:45][D][uart_debug:114]: >>> AA:C0:00:00:80:00:00:00:00:00:00:00:00:3F:81:55
[04:41:45][D][uart_debug:114]: <<< AA:C0:00:00:00:00:00:00:00:00:00:00:00:3F:01:55:AA:C0:00:00:00:00:30:14:84:80:15:52:54:00:2E:FF:00:00:00:00:00:00:00:00:00:00:00:14:E0:01:1B:55:AA:C4:00:00:00:00:00:00:00:00:00:00:00:3B:01:55:AA:C4:00:00:C0:E5:FC:FF:FF:FF:FF:FF:FF:FF:FF:F3:F7:2C:00:00:FF:00:80:80:80:80:C4:55:AA:C0:00:00:00:00:00:00:00:00:00:00:00:3F:01:55:AA:C0:00:00:00:00:30:14:84:80:15:52:54:00:2E:FF:00:00:00:00:00:00:00:00:00:00:00:14:E0:01:1B:55:AA:C4:00:00:00:00:00:00:00:00
Using this config:
substitutions:
name: esp32-bluetooth-proxy-48bbf4
friendly_name: RS485 Sniffer 48bbf4
esphome:
name: ${name}
name_add_mac_suffix: false
friendly_name: ${friendly_name}
api:
encryption:
key: ...
esp32:
board: esp32dev
framework:
type: arduino
wifi:
use_address: ...
ssid: !secret wifi_ssid
password: !secret wifi_password
ota:
- platform: esphome
# Enable logging (but not via UART)
logger:
baud_rate: 0
external_components:
- source:
type: git
url: https://github.com/exciton/esphome
ref: dev
components: [midea_xye]
# UART settings for RS485 converter dongle (required)
uart:
tx_pin: GPIO17
rx_pin: GPIO16
baud_rate: 4800
debug: #If you want to help reverse engineer
direction: BOTH
# Main settings
climate:
- platform: midea_xye
name: Heatpump
period: 1s # Optional. Defaults to 1s
timeout: 2s # Optional. Defaults to 100ms
beeper: true # Optional. Beep on commands.
visual: # Optional. Example of visual settings override.
min_temperature: 17 °C # min: 17
max_temperature: 30 °C # max: 30
temperature_step: 1.0 °C # min: 0.5
supported_modes: # Optional.
- FAN_ONLY
- HEAT_COOL
- COOL
- HEAT
- DRY
supported_swing_modes: # Optional
- VERTICAL
outdoor_temperature: # Optional. Outdoor temperature sensor
name: Outside Temp
temperature_2a: # Optional. Inside coil temperature
name: Inside Coil Temp
temperature_2b: # Optional. Outside coil temperature
name: Outside Coil Temp
current: # Optional. Current measurement
name: Current
timer_start: # Optional. On timer duration
name: Timer Start
timer_stop: # Optional. Off timer duration
name: Timer Stop
error_flags: # Optional.
name: Error Flags
protect_flags: # Optional.
name: Protect Flags
Please note I had a wired controller connected dfuring this exchange…
I guess I should fork the code and then add in debugging to just dump the contents witrhout it trying to send something out…
Edit: Forked code.
Commented out the send commands…
Had the UART debugging on, did some text manipulation and…
Disconnected the wired controlller…and some success.
Some values still seem very wrong, but I was able to turn the unit to heat mode and back off using the XYE interface in Home Assistant.
Now to figure out what the Wired Controller is sending for the foillow-me temperature so I can finaly make that part work.
At least on my unit, it looks like the temperatures were off a bit.
I validated using the wired controller (using the t1,t2,t2b,t3,t4 items), and it looks like the offset is 0x28, not 0x30. The values via XYE now match that of the UART interface.
Interestingly, when you send a 0xC6 command for follow me - it looks like the AC responds with a 0xC4 in addition to the 0xC6 response.
That branch has client_id change, follow_me change, and temperature offset change.
Trying to find T3 (T3 = Outdoor = already found and correct) and T4 temperature values (as reported on my wired controller) now.
Response byte 0x15 (21) on 0xC4 query seems to be T4 temperature.
Edit: According to the service manual, T3 is outdoor coil temp, T4 is outdoor “room” temperature.
From the Midea circuit diagram:
T2 COIL TEMP> SENSOR
T2A INDOOR COIL INLET TEMP.SENSOR
T2B INDOOR COIL OUTLET TEMP.SENSOR
Error EC52 “Condenser coil temperature sensor T3 is in open circuit or has short circuited”
Error EC53 “Outdoor room temperature sensor T4 is in open circuit or has short circuited”
This gaph seems to suggest that indeed, XYE reports the coil temp.
The ESPHome Style Guide mentions following Google standards for the most part, so I ran the code through clang-format --style=Google. So the diff vs the main branch looks bigger, but git log -p -w is probably the easiest way to see what happens on each commit.
Past that, the changes are now:
Client ID is set to 0 to match the wired controller
Temperature offset has ben corrected
Follow-me code is available and seems to mostly work
Corrected naming of Temperature Sensors (Add in T3 for Outside Coil Temp, Outdoor Temp is actually T4 and comes from 0xC4 query)
Restructure ParseResponse to handle 0xC0 and 0xC4 queries
Please note that as of right now I’m listening-only to what the wired controller does, so I may have broke sending stuff, but I don’t think I did. I did reduce the sned delay in my config from 1s to 100ms.
Probably a pretty stable 20 Degrees C in the basement. Hence the C6 Query.
Note for all counts below - unique counts…there were 86000+ values send / received during the timeframe in question.
Looks like there is common structure between the C6 and C4 Query responses:
$ ../../an c6-response
15 (Array 14)
--
6 00
7 01
--
17 (Array 16) [ Edit: Theory is this is the current running mode ]
--
2 81
11 84
--
19 (Array 18)
--
7 CD
5 CF
1 D0
--
22 (Array 21)
--
1 38
3 3A
2 3C
3 3E
2 40
1 50
1 52
C4 Responses:
15 (Array 14)
--
6 00
22 01
--
17 (Array 16) [ Edit: Theory is this is the current running mode ]
--
12 81
16 84
--
19 (Array 18)
--
10 CD
7 CF
11 D0
--
22 (Array 21)
--
2 38
3 3A
4 3C
5 3E
3 40
1 42
1 44
1 46
1 48
1 4A
1 4C
1 4E
2 50
2 52
22 (Array 21) is now known to be the outside temperature. So that one makes total sense.
15/17/19 though…
Edited up there - 17 I think is the current running mode.
In other news, I was able to get my remote control into “Inquiry Mode” - which interestingly put my controlle rback into F Temperature units (that’s how the remote was set). Unfortunately I got no response out of the wired controller after messing with a few queries…
0x95-9F (5-15 for Static Pressure), 0x80 - Emergency Heat
10
?
0x00
11
Follow-Me Command
0x6 Start, 0x2 Update, 0x4 Stop
12
Follow-Me Temp
in C
13
?
0x00
14
Command Check
0xFF - Field 2
15
CRC
255 - sum(data) % 256 + 1
16
prologue
0x55
That’s where I am so far in terms of analysis. Mind you I’m onlyu using the heating mode right now…Haven’t even tried turning on the Heat + Aux Heat mode.
Also, when I tried to put the unit in Inquiry / Service mode with the remote, it switched it back into Farenheight.on the wired controller display. The only data this affects is the setpoint. Everything else stilli is in C.
This is awesome work! Did you figure out how to set/read auto mode? I had a similar observation where the actual mode is returned, so it’s not possible to know if you’re in auto. Any luck?
This is awesome work! Did you figure out how to set/read auto mode? I had a similar observation where the actual mode is returned, so it’s not possible to know if you’re in auto. Any luck?
Nothing on that yet.
I did, however, figure out a little aobut the F vs C on the wired display.
It literally just sends it in F instead of C, on the AA:C3 command:
So if in range A → Celsius, if in range B, Farenheit. Also C moves in 0.5C increments, F moves in 1F increments.
Yep. So, interestingly, AA:C3 → Setpoint in C or F… But Follow Me value on 0xC6 is always in C. Also, looks like all of the other temp sensors are always in C.
That said, it may change the overall behavior leaving it in F as to the way “Auto” mode will work with regards to deadbands, etc.
So…it turns out when I put it into “High” mode the other day - it did not go back into auto when I thought it did.
I looked at the wired controller and was confused when I didn’t see the word “Auto” and just saw Full speed…
So, Yes I can say, with certainty…
if (RXData[9] & 0xF0) == 0x80 —> Auto fan speed enabled.
In other words…
0x84 = Auto + Low Speed
0x82 = Auto + Medium Speed
0x81 = Auto + High Speed
0x04 = Low Speed
0x02 = Medium Speed
0x01 = High Speed
NOW - Here’s the fun part - Just because it was set into Hi -The system will ramp it lower as it gets closer to the target temperature, at least in heating mode.
I got a few captures of things I tested on the wired controller. Will compare the captures vs what the code does tomorrow. Bed time now.
Looking through the log they don’t count up in order, they move around a bit. But for sure it’s something related to readiness of the hardware. In no other logs do I see values other than E0:01in Fields 29 and 30.
f718aed05b8d1941dc3fb9e79d59a5cd548cce70 Run clang-format --style=Google -i air_conditioner.*
aa5b6d51589b8f906c7ede6e4f8b011f953a1798 Fix representation of beginning and ending bytes.
7bc3ab714554c24a1235dae0d152c97acaf6effc Change FROM_CLIENT byte to match Wired Control KJR-120X.
0a782d56f177bd42bfdf063d6e096b55789e3c0c Change TO_CLIENT byte to match Wired Control KJR-120X.
d96fe8584200a89353856cba9a057eeb57559e62 Remove setup code for Celsius, as it doesn't do what it is thought to do.
b21f1c9f7d52b08f742c5e4288541ce77ac7c428 Correct temperature calculation. 0x28, not 0x30 offset.
835bcee7a118158a4e3cc45fa6f5c0ea4944fb8e Correct naming of T2/3 sensors.
5e0967ef357764b6163a04d20dcfa3f91f9b97fb Send out query types of both 0xC0 and 0xC4. Restructure ParseResponse to handle multiple message types.
4727a429d9b374c649ef003c4fb13b247f7dd7c5 Rename setClientCommand function to prepareTXData.
3476287549be1f8be0969ac408aa0fb6750282ee Handle Automatic Fan Speed Correctly.
337d13cb037f2c8553507469c068ed1e48bc2c5b Fix location of Mode Flag - Array location 11, not 12.
30b74c18bd14a967395ff6b9fc10fc0940a1a774 Add action trait to show heating/cooling vs heat/cool.
cc07a95444f3a50474fcf5d6a91d6c3353825134 Add in follow_me code.
08c34738da4a744c1e51cfd71af1e812fd52649f Add Debug for 0xC4 packet type.
Follow-Me is working as expected, it defintiely reports back teh same value as what I’m seinding it (within a 1 Degree C accuracy). I do wish there was a way to accurately identify when the compressor was running.
I’m just starting to analyse my system to see if I can set static pressure from Home Assistant via XYE.
Wall controller commands when setting static pressure to SP0-SP4:
aac6000000000000100004170039d655
aac6000000000000110004170039d555
aac6000000000000120004170039d455
aac6000000000000130004170039d355
aac6000000000000140004170039d255
Responses from indoor unit:
aac600000000000000301c0000000000108054bed65200002000000000000455
aac600000000000000301c0000000000108054bed65200002100000000000355
aac600000000000000301c0000000000108054bed65200002200000000000255
aac600000000000000301c0000000000108054bed65200002300000000000155
aac600000000000000301c0000000000108054bed65200002400000000000055
C6 command
Field 9: lower nibble is static pressure?
C6 response
Field 24: lower nibble is static pressure?
This seems to line up with your more rigorous analysis. I’m watching with interest for now, waiting for some parts to arrive before I hook up an ESP32.