Notes on Gree Amber Nordic / Prestige GWH09YD-S6DBA2A Heat Pump

Gree GWH09YD-S6DBA1 indoor PCB with IR and WiFi modules
Gree GWH09YD-S6DBA1A indoor heat exchanger power connectors, PCB with IR and WiFi modules.

As part of an experiment to add domestic water heating capabilities to conventional mini-split ACs, I purchased an air-source heat pump Gree GWH09YD-S6DBA2A which has an inverter controlled compressor and an electronic expansion valve that allows it to work efficiently even down to -30℃ (-22℉).

  • Model: GWH09YD-S6DBA2A (outdoor), S6DBA1A (indoor)
  • Product code: CB466000100/CB466000102
  • Cooling capacity: 2.7kW
  • Heating capacity: 3.5kW
  • Refrigerant: R32
  • Remote model: YAG1FB3

Service Manual

Most of the technical information in this post has been retrieved from the official service manual:

Firmware

Initially the unit was reporting firmware version v1.00 and only in April 2023 it offered an update to v3.76 via the official Gree+ app which completed successfully.

Gree firmware update from v1.00 to v3.76
Firmware update to v3.76.

In July 2023 it started showing an available update to v3.77 but I haven’t been able to apply it due to a network timeout after requesting the update.

Gree firmware update to v3.77
Firmware update to v3.77.

IR Remote Protocol

I used an infrared photodiode attached directly to pins GND and D3 (which is pulled high) of Wemos D1 mini and the IRrecvDumpV3.ino sketch bundled with v2.8.1 of the IRremoteESP8266 library to decoded the messages.

Here are the infrared bit sequences captured by the Saleae logic analyser:

Gree YAG1FB3 remote signal capture
Capture of the IR signal from the YAG1FB3 remote when turning on the device.

We can clearly see two sets of messages that are repeated twice. Each message has two parts and the first one starts with a longer sync header.

Initially it complained about the packets being too large to fit in the allocated buffer:

WARNING: IR code is too big for buffer (>= 1024). This result shouldn't be trusted until this is resolved. Edit & increase `kCaptureBufferSize`.

That is because of the kTimeout constant which is set to 50 by default and is 10ms above the actual period of 40ms between the groups of messages that we see in the logic analyser output above. By setting the value to 30:

const uint8_t kTimeout = 30;

it started decoding the packets as expected:

Protocol  : GREE
Code      : 0x0C084070000000E0 (64 Bits)
Mesg Desc.: Model: 1 (YAW1F), Power: On, Mode: 4 (Heat), Temp: 24C, Fan: 0 (Auto), Turbo: Off, Econo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: Off, Sleep: Off, Swing(V) Mode: Manual, Swing(V): 0 (Last), Swing(H): 0 (Off), Timer: Off, Display Temp: 0 (Off)
uint16_t rawData[139] = {9004, 4474,  664, 540,  664, 540,  666, 1642,  664, 1644,  664, 542,  664, 540,  664, 542,  664, 542,  664, 542,  664, 542,  664, 542,  664, 1642,  664, 542,  664, 540,  666, 540,  664, 540,  664, 542,  664, 542,  664, 542,  664, 540,  664, 540,  664, 542,  664, 1642,  664, 542,  664, 540,  666, 540,  666, 540,  664, 540,  666, 1642,  664, 1642,  664, 1642,  664, 540,  664, 542,  664, 1642,  664, 540,  664, 19974,  664, 542,  664, 542,  664, 542,  664, 542,  664, 542,  664, 542,  662, 542,  662, 542,  664, 542,  664, 542,  664, 542,  664, 542,  662, 544,  662, 544,  662, 544,  662, 542,  662, 544,  662, 542,  662, 542,  662, 544,  662, 544,  662, 542,  664, 544,  662, 542,  662, 544,  662, 542,  662, 542,  664, 542,  662, 544,  662, 1644,  662, 1644,  662, 1644,  662};  // GREE
uint8_t state[8] = {0x0C, 0x08, 0x40, 0x70, 0x00, 0x00, 0x00, 0xE0};

In the decoded bit timing sequence above we see a 9004us header mark followed by a 4474us space and then the actual message bits where the bit mark is 664us, logical 0 space is 542us, logical 1 space is 1642us and with 19974us between the two packets of the message.

Enabling the I-feel mode (where the remote sends the indoor temperature to the indoor unit) does append another packet to the end which isn’t parsed correctly, though:

Protocol  : UNKNOWN
Code      : 0x5EF985F1 (18 Bits)
uint16_t rawData[35] = {6008, 2986,  658, 546,  658, 548,  658, 548,  658, 1648,  658, 1648,  658, 546,  658, 548,  658, 548,  658, 1650,  658, 546,  658, 1648,  658, 546,  658, 548,  658, 1648,  658, 548,  658, 1648,  658};

It appears that this packet is supported by the arduino-heatpumpir library. According to the GreeYACHeatpumpIR::send() method we’re expecting a header followed by two data bytes (using the following logic) and one closing GREE_YAC_BIT_MARK:

  • 6008, 2986 are the two header marks,
  • 658,546 | 658,548 | 658,548 | 658,1648 | 658,1648 | 658,546 | 658,548 | 658,548 maps to 0x00011000 in binary which is 24 in decimal (the temperature measured by the remote).
  • 658,1650 | 658,546 | 658,1648 | 658,546 | 658,548 | 658,1648 | 658,548 | 658,1648 maps to 0b10100101 or 0xA5 in hex as expected.
  • 658 is the closing GREE_YAC_BIT_MARK.

IR Receiver Module

Attached to the back of the inner block cover is a display module combined with an IR receiver. I was wondering if the IR receiver logic could be handled there and forwarded to the main PCB via something like UART. Turns out the LCD elements and the IR receiver diode run down to the main PCB so there is nothing to hijack.

Gree GWH09YD-S6DBA1 front cover LCD module with IR receiver
Back of the PCB for Gree GWH09YD-S6DBA2A front cover LCD module with IR receiver.

Wi-Fi Module

There is a built-in Wi-Fi module which uses a protocol that has been reverse-engineered and enables full control over the local network once the unit has been added to the Wi-Fi network using the GREE+ app for iOS and Android. There is even a fully functional HomeAssistant integration.

Gree GWH09YD-S6DBA1 built-in WiFi module top
Gree GWH09YD-S6DBA2A built-in WiFi module top.
Gree GWH09YD-S6DBA1 built-in WiFi module back
Gree GWH09YD-S6DBA2A built-in WiFi module back.

The COM-MANUAL label and the four wires going to the module from the PCB indicate that this is possibly an UART-to-WIFI bridge. However, attaching the digital logic analyser probes to the dark-brown, light-brown and GND pins produced a lot of noise without clear indication of the data being transfered.

BMS and COM Manual Connections

There are two additional wire connections that are coming out of the PCB that are left not connected:

  • BMS which is potentially a Modbus or CAN connections for Building Management Systems.
  • COM-MANUAL which is designated as “Wired Controller (optional)” in the service manual.

There is a lot of potential for gaining full read-write access to the device through these ports but I haven’t gotten to that yet.

Gree GWH09YD-S6DBA1AO indoor PCB diagram
Gree GWH09YD-S6DBA1A indoor PCB diagram.
Gree GWH09YD-S6DBA1A indoor PCB
Gree GWH09YD-S6DBA1A indoor PCB.

Wired Controller XK76

Some of the Gree models support wired controllers or thermostats in addition to the RF remotes. This indoor unit has two unpopulated connectors labeled BMS and (forgot the other one) in addition to the WIFI cable that is connected to the WIFI module.

The BMS connector is attached to the wired controller and it appears to be using some kind of serial protocol (potentially Modbus over RS485 similar to their commercial units) to communicate with the remote controller.

Unfortunately, it isn’t very clear which wired controllers support which indoor units especially because the model numbers don’t appear to be shared between units sold in EU and US, for example. Your best option is to review the service manual for the heat pump and determine the controller model by the picture. I decided to get what appeared to be the most recent version of the wired controllers XK76 and just hoped it would work with my device. And luckily it does!

Important: Make sure to turn off the heat pump completely before connecting the controller or it will return an error code E6 and fail to communicate with the device. I almost thought it just doesn’t work and put it on sale…

XK76 comes in a box with two back panels, a four wire cable and a patch cable.

And here is the photo of the PCB which appears to have just a single microcontroller and three physical connection ports with matching drivers and a bunch of passives to drive the screen:

The PCB of the Gree Gree XK76 wired controller thermostat
The CN4 connector on the top-right is used to attach the communications cable. With markings GRJ4K-B on the PCB.

And here is a photo of the main controller which appears to be NXP LPC3100 series ARM9:

Gree XK76 wired controller with NXP LPC3100 ARM9 microcontroller
Gree XK76 with NXP LPC3100 ARM9 microcontroller.

Outdoor and Indoor Unit Communication

There is no official documentation for the communication protocol used between the indoor and outdoor units. Below are my findings based on reverse-engineering and the insight shared by other enthusiasts after publishing this post.

System Design

All of the heat pump control logic is handled by the outdoor unit while the indoor unit only requests heating or cooling and sends the temperature readings of the indoor heat exchanger as input for the outdoor control board.

The communication between the outdoor and indoor units happens via a DC signal referenced to the AC power ground.

Gree Heat Pump Outdoor Unit Wiring
Wire labeled “BK” (2) used for communication signal between the indoor and outdoor units.

Communication Protocol

I was able to attach an oscilloscope and record the following communication between the outdoor and indoor units. See this thread on Reddit for what others think.

Gree heatpump indoor and outdoor unit communication
Indoor and outdoor unit communication.

It is using a 0-60V serial signal centered around 30V — the outdoor control board keeps the signal at 30V and the indoor unit pulls it low to 0V to send the data. For replies the outdoor unit pulls the signal high to 60V.

The logic analyser was able to decode the serial signal when set to LSB byte order, 1200 baud rate, 8 data bits, 1 stop bit and even parity.

Gree heat pump heat exchanger and compressor communication
Serial communication with 20 bytes of data sent between the indoor and outdoor units.

Based on the functionality of the multifunctional inverter testers mentioned below, it should contain the following data:

  • Operation mode (heating, cooling)
  • Internal fan speed
  • Set temperature
  • Bus voltage (AC supply)
  • Bus current
  • Compressor frequency
  • Expansion valve opening
  • Module temperature (?)
  • Inner ring temperature (?)
  • Inner tube temperature (?)
  • Outer ring temperature (?)
  • Outer tube temperature (?)
  • Exhaust temperature
  • Cold inlet temperature (?)

The first byte indicates the type of the message (0x31 and 0x32 in the examples above) followed by the actual data bytes closed out by an 8-bit modulo 256 checksum byte. Here are the messages I’ve been able to decode:

Message 0x31 Source

ByteHexDecimalValueDescription
00x3149Destination or source address?
10x2032Destination or source address?
200
30x1420HeatingMode, 20=heat, 17=cool, 19=ventilation, ?=auto, ?=dry, fan-only=?, off=?
40x88AutoFan speed, 1=low, 2=medium, 3=high, 4=turbo, 128=off, 8=auto? (low, medium low, medium, medium high, high)
500
60x385616Set temperature (value – 40)
70x3C6020Room temperature (value – 40)
800
90x3A5818Refrigerant temperature inside (value – 40)
100x77
1100
1200
1300
1400
1500
1600
1700
1800
190x223434CheckSum8 Modulo 256

Message 0x31 Reply

ByteHexDecimalValueDescription
00x3149Destination or source address?
10x1016Destination or source address?
200
30x1420HeatingMode, 20=heat, 17=cool, 19=ventilation, ?=auto, ?=dry, fan-only=?, off=?
40x203232Compressor frequency?
50x5A9090Outdoor fan frequency?
600
700
80x11Unknown
90x2335Unknown
100x6197Unknown
1100
120x335111Outside temperature (value – 40)
130x30488Suction line temperature (value – 40)
140x5C9252Discharge line temperature (value – 40)
1500
1600
170x44Unknown
1800
190x1723CheckSum8 Modulo 256

Message 0x32 Source

ByteHexDecimalValueDescription
00x3250Destination or source address?
10x2032Destination or source address?
200
300
400
500
600
700
80x1117Unknown
900
1000
1100
1200
1300
1400
1500
1600
1700
1800
190x6399CheckSum8 Modulo 256

Message 0x32 Reply

ByteHexDecimalValueDescription
00x3250Destination or source address?
10x1016Destination or source address?
200
300
400
500
600
700
800
900
1000
1100
120x3957Unknown
1300
1400
1500
1600
170xA10Unknown
180x3654Unknown
190xBB187CheckSum8 Modulo 256

There are several other message types that I haven’t yet captured.

Portable and Multifunctional Tester for Inverter A/C

There appear to be several inverter tester tools which support the single wire communication used by multiple brands. The GT2D3AAa model is often referenced as the “new” version of the older model GZJ10D009 but I haven’t been able to confirm that. Importantly, GZJ10D009 is specifically branded by Gree:

Gree GZJ10D009 tester
Gree GZJ10D009 tester.

And here is the “new” version:

GT2D3AAa inverter multifunction tester
GT2D3AAa inverter multifunction tester (source: AliExpress).

Drain Pan Heater in Cold Climates

The outside unit contains a resistive heater for the drain pan which is turned on and draws constant 100W when the outside temperature falls below 0C (32F) even when the unit is not running or defrosting anything (there might be a setting that controls this but I haven’t been able to find it).

Gree drain pan heater drawing 0.4A during freezing temperatures
Drain pan heater drawing 0.4A at 240V during freezing temperatures.

This leads to 2.4kWh of additional energy consumption per day which is unfortunate. Note that the heater is only for the drain pan and not the compressor so there is no reason it should be on for more than the defrost cycle and some time after it.

Gree drain pan heater power consumption during cold climate
Gree drain pan heater drawing 100W during cold weather.

The compressor compartment and piping are really well insulated:

Gree GWH09YD-S6DBA2A outdoor unit
Gree GWH09YD-S6DBA2A outdoor unit.
Gree GWH09YD-S6DBA2A outdoor unit element connections
Gree GWH09YD-S6DBA2A outdoor controller connections.

Notice how the 4WAY valve 220V switch is almost right next to the HEAT connection for the resistive heater so it should be possible to connect a timer relay which keeps the heater running only for 10 or 30 minutes after the defrost cycle.

Forums and Links

29 Comments

  1. Marcin says:

    Hello. Have you tried to see the communication between the indoor unit and the controller with the program Gree Text Parser ?
    I would also like to communicate with Gree using rs485.
    Do you have any progress yet?

    Regards

    • Kaspars says:

      Yes, I did try to do that and posted my findings on Reddit. There seems to be valid UART data but I didn’t get to parse out any bits that would match the sensor data or the unit settings.

      Thanks for the “Gree Text Parser” suggestion — I wasn’t aware it existing. I assume there must be tools for parsing the raw communication between the indoor and outdoor units for all Gree hardware but I just don’t have access to it.

  2. Marcin says:

    If you have xk76 you could try to connect the converter usb/rs485 to line between indoor (terminal com-manual – middle wires)unit and xk76 and run the Gree Text Parser program. Maybe it will work for data preview.
    If you want, I can share this program.

  3. JL says:

    Very interesting! Have you done something with the drain pan heater?

    Would be interested to hear how did you solve it?

    • Kaspars says:

      I unplugged the PCB connector for the heater completely for now. Turns out that it takes more than a week of freezing temperatures for the defrost water to block all of the drain holes and for ice to start building up the heat exchanger fins. It would probably happen faster if it was set to more than 8C of target temperature.

      The long term plan is to add this ETI SMR-T timer relay (or any similar timer relay) between the PCB connector and the heating element to turn on the heater only at regular intervals. Hiding the relay under the top cover of the outside unit would allow to adjust the timer intervals easily.

      • JL says:

        That sounds like a good plan! Do you know which type is the connector, or are there any other connectors that fit? From warranty POV it would be nice to find a matching connector pair.

  4. steve says:

    In your earlier post from Oct 21, you talked about design questions like 1) whether a bypass valve would be needed or if toggling recirc on the water loop would be sufficient 2) determining optimal water flow rates through the plate exchanger

    Did you get this working and arrive at any conclusions?

  5. trp says:

    Hi, I have split AC Panasonic. Indoor and outdoor set. I tried to sniff data as well. It seems so the communication is the same or very similar. I had connected TTL to RS232 directly on MCU. Sniffed frames were 14 bytes as well. Last byte is maybe CRC. Voltage level between indoor and outdoor unit (1 wire) seems to be the same as at GREE. Pls, do you have somebody basic electrical wiring, how to connect to this wire and sniff both communication via TTL (indoor and outdoor)? First step. Second step – wiring for the sending data to outdoor unit via TTL. Thanks in advance.

    • Kaspars says:

      Thanks for sharing this! This is great news. It would be really convenient if the signalling was similar between several brands.

      I haven’t continued building the PCB for the communications so I don’t have an update there.

  6. trp says:

    I´m sorry, I looked to my remarks. Frame is 20 bytes (I wrote 14).
    1200 baud
    For example:
    10 00 00 00 00 E6 16 B0 B0 00 05 00 00 00 00 00 00 00 00 71
    last byte (20) CRC CheckSum8 Modulo 256

    but I can’t verify if my thoughts are correct :-(

  7. Grzegorz Krawczyk says:

    Witam,
    Jeśli mogę pomóc to dołączę do dyskusji.
    Trochę skanowałem komunikację w GREE.

    if (buffer_gree[0] == 49 && buffer_gree[1] == 32)
    {
        temp_zadana_Gree = buffer_gree[6] - 40;
        temp_pomieszczenia_Gree = buffer_gree[7] - 40;
        temp_freonu_Gree = buffer_gree[9] - 40;
    
        label1.Text = temp_zadana_Gree.ToString();
        label2.Text = temp_pomieszczenia_Gree.ToString();
        label3.Text = temp_freonu_Gree.ToString();
    
        if (buffer_gree[3] == 20) label12.Text = "Grzanie";
        if (buffer_gree[3] == 17) label12.Text = "Chłodzenie";
        if (buffer_gree[3] == 19) label12.Text = "Wentylacja";
        // if (buffer_gree[3] == 17) label12.Text = "Osuszanie";
    
        if (buffer_gree[4] == 1) label11.Text = "FAN 1 bieg";
        if (buffer_gree[4] == 2) label11.Text = "FAN 2 bieg";
        if (buffer_gree[4] == 3) label11.Text = "FAN 3 bieg";
        if (buffer_gree[4] == 4) label11.Text = "Tryb Turbo";
        if (buffer_gree[4] == 128) label11.Text = "FAN OFF ";
    }

    mam program w C# który odczytuje wartości z ramek transmisji.

  8. Grzegorz Krawczyk says:
    if (buffer_gree[0] == 49 && buffer_gree[1] == 32)
    {
        Temp_SET = buffer_gree[6] - 40;
        Temp_ROOM = buffer_gree[7] - 40;
        Temp_Freon_internal = buffer_gree[9] - 40;
        if (buffer_gree[3] == 20) label12.Text = "HEAT";
        if (buffer_gree[3] == 17) label12.Text = "COOL";
        if (buffer_gree[3] == 19) label12.Text = "VENTILATION";
            if (buffer_gree[4] == 1) label11.Text = "FAN 1";
        if (buffer_gree[4] == 2) label11.Text = "FAN 2";
        if (buffer_gree[4] == 3) label11.Text = "FAN 3";
        if (buffer_gree[4] == 4) label11.Text = "TURBO";
        if (buffer_gree[4] == 128) label11.Text = "FAN OFF ";
    }
  9. Mateusz says:

    Hi, did you manage to solve the drip heater problem? I also have this Gree unit and it annoys me that the heater is constantly working when the temperature drops. Regards.

    • Kaspars says:

      I got this ETI SMR-T timer relay to connect between the PCB control and the heater line, and set it to run for a limited amount of time whenever it is enabled.

      • Mateusz says:

        Thank you my friend for sharing this valuable information. Could I ask you to e-mail me photos of how it was connected in your case and instructions on how to make this connection? I will be very grateful for your help and congratulations on your wonderful idea. My email is [redacted] Best regards 😉

      • Piotr says:

        Hello and thanks for your detailed description of this AC unit. Did you use some other line for the signaling? My idea is that the timer would be turning on the heated pan when fan is spinning + 15 minutes (and ofc also only when temp is below 0). What do you think?

        • Kaspars says:

          I decided to simply throttle the original pan AC power wire by adding the timer so it makes it run 20% or 50% of the original time it is supposed to be on.

  10. Mateusz says:

    It’s a bypity that we weren’t able to take photos as souvenirs for other users. I have another question, do you know how to turn off the sound signal in the indoor unit?

  11. Mateusz says:

    I have one more question, have you tested the modulation of your unit on heating and cooling? I have the same unit as you and in cooling mode it goes down beautifully with power up to 150-200W and runs smoothly without interruption, in heating mode the unit does not go below 550-600W which causes frequent switching on and off. I wonder if there is a way to improve the heating performance because according to the data sheets, the heating output should also be up to 140W.

    • Kaspars says:

      I have the same observation — it is very bad at low-power heating and never drops below 600W. It appears to quickly heat up the air and modulate rapidly as it reaches the low and high threshold temperatures.

      I was hoping that connecting the XK76 controller would make it use its sensor for the room temperature but it doesn’t appear to be happening, and I can’t really move the built-in temperature sensor to a different location.

      I could try using the remote with the “I-feel” mode as it would then send the temperature readings from the remote. Will report back if I see an improved behaviour.

      • Mateusz says:

        I’m waiting for your conclusions with Ifell because I also conducted a lot of tests and only by using an external IR remote control for Tuya and creating scenes in which the temperature of the unit with Ifell turned on is changed with a specific delay, I was able to achieve modulation. The pump has dropped to 250W and runs for 20 minutes, then it accelerates, reaches the set value and turns off. I haven’t managed to get it to work continuously, it always turns off after some time…

  12. Daniel says:

    I decided to simply throttle the original pan AC power wire by adding the timer so it makes it run 20% or 50% of the original time it is supposed to be on.

    I’ve just disabled the pan by disconnecting the plug – no problems so far – (it was working like that whole prev season)

    I’m running amber prestige 7kw modified as air into the water heat pomp

  13. Mateusz says:

    I bought an IR remote control on Aliexpress and made a diy remote control there. I taught all the functions of the remote control there, then I created scenes in Tuya and thanks to ifell being enabled, information about the temperature is sent in the remote control and in the Tuya application the scenes activate the appropriate functions with an appropriate delay, which causes modulation of the unit. It looks like this, when the temperature on the external thermometer connected to the tuya reaches x degrees, the scene starts: turn on heating 23 degrees, delay 10 seconds, turn on heating 19 degrees, delay 4 minutes, heating 21 degrees. After this start, the unit reduces to 250W and then slowly increases the power.

Leave a Reply