Open source Gree wifi module replacement

So for Midea branded wifi modules there’s an awesome open source alternative for the wifi module: Midea branded AC’s with ESPhome (no cloud)

However Gree wifi seems to be at least as big as Midea, lots of air conditioners use the protocol like Gree, Daikin, Daizuki, Sinclair and several others. Yet it seems there’s not a true open source alternative available. I found this project though that has come closest:

Which seems to work for a few air conditioners, but not sure if it works for most.

There’s also this collection of downloaded Gree firmwares: GitHub - maxim-smirnov/gree-wifimodule-firmware: Gree AC WiFi Modules Firmwares which could help.

It would be interesting to work towards a true open source alternative for all Gree supported air conditioners, so support for more air conditioners types. I’m very low on free time myself these days but if there are some people willing to help out working on this, I think we could get this going and I’m willing to help out with some reverse engineering

2 Likes

I did open up my wifi module (GRJWB04-J) and it has both a UART as a JTAG port. It seems to based on a Realtek rtl8720cf module.

Haven’t connected either just yet, problem is that the airco hangs 2m high on a wall, but I guess I can connect the UART to a small PC, attach it to the airco and then use it via a remote desktop to manage the connection. So will be trying that soon.

The firmwares for this particular module can be found here: gree-wifimodule-firmware/362001065279 at main · maxim-smirnov/gree-wifimodule-firmware · GitHub
You can load them up in Ghidra using Cortex little Endian. However I havent figured out the firmware layout just yet, most of the FW disassembles but there seem to be at least 3 different partitions in the FW. (bootloader, main code and data it seems. It seems at 0x200 the first partition start with the first 4 bytes being the partition length, so you can work from there to find the other partitions). Also haven’t figured out the loading addresses just yet. Not sure if it’s all even needed, probably better to first connect the UART and start sniffing packets, hopefully that already would be enough to get a good idea of the protocol used in this particular module, together with the existing code that Piotr already developed that might already be enough.

1 Like

Actually somebody already hooked up the uart and described the whole protocol GitHub - bekmansurov/gree-hvac-protocol: Description of data exchange protocol for GREE air conditioners via UART based on reverse engineering

So it seems all that remains is combine all of the above

1 Like

Also the chip is rtl8720cf https://manuals.plus/gree/grjwb04-j-wifi-module-manual

1 Like

Ok I managed to parse the OTA firmwares. I found this great tool that works very well:

The sections I already had identified (as mentioned above) but this tool also shows the loading address:
section 1: Bootloader @0x10000480
section 2:FW code @0x9b000140
section 3: data @0x9b800140

(all for that v1.26 FW dump I mentioned earlier)

So I now loaded the section 2 and 3 to the correct address in Ghidra and now everything decompiles correctly. So the reverse engineering of the firmware can now really start :slight_smile:

Not sure if this is even necessary but as the guy(s) who analyzed the sniffed frames had still some doubts as to what is what, it can now be analyzed via the firmware code.

2 Likes

So as noted by “bekmansurov” on his github page, packages always start with:
0x7E, 0x7E
And then the following byte is the package length. However he identifies that byte as ‘command byte’ too, he writes “Usually packets have different length byte so it’s convenient to use this byte as a packet identifier.” However it seems that actually the following byte is the command byte (so the identifier) !! (at least for the out going packets, haven’t checked the incoming ones yet)

So for example, a package that he identifies as a ‘0x10’ packet:
10 02 00 00 00 00 00 00 01 00 28 1e 19 23 23 00 b8
This should actually be identified as a ‘02’ packet, which is the ‘command’ (or identifier) of the packet! So the command 0x2 packet has length 0x10.

Or in other words, the first 4 bytes of each packet are:
0x7E, 0x7E, [length], [CMD]

So that’s of course super important to realize. In fact I see different packet lengths in the firmware code than bekmansurov noted, but for the same commands.

1 Like

So far I have identified 5 different outgoing packet types (so from WIFI module to the AC) :

CMD 0x01. Length 0x2F in my firmware.
CMD 0x02. Length 0x10 in my firmware.
CMD 0x03. Length 0x1A in my firmware.
CMD 0x04. Length 0xD in my firmware.
CMD 0x0D. Length 0x7 in my firmware.

At this point I’m pretty sure that’s all there is, but if I find more I will update here. I still need to identify what these exactly do. “bekmansurov” had identified 0x2 as the first command to the AC after the wifi module powers up. And Command 0x1 as the packets conveying the commands to the AC. And he couldn’t find out what the others were. Will look into all that …

Anyway it’s interesting to see that the commands actually have different lengths than “bekmansurov” found.

1 Like

Actually I just realized that that piotvra already did all that too in his esphome replacement, his command findings are here: esphome_gree_ac/components/sinclair_ac/esppac_cnt.h at 60444cb0bf13fc56c57d9b29a04694dc77912458 · piotrva/esphome_gree_ac · GitHub

Actually I think his code works on most gree models. I thought it wouldn’t because some guy commented on his github that it didn’t work but I now think that guy did something wrong.

Going to order the parts myself and try it!

I do see he didn’t find command 0xD though. I think this might be a secret debug code that puts the air conditioner in a special factory mode, I saw several references to such mode in the firmware. Will investigate all that

The other commands he noted are commands from ac to the module, haven’t really looked into that yet but I saw similar commands indeed. Will also look into that. But it actually seems his code should be working universally for gree branded acs

1 Like

BTW, if anyone wonders, there are of course 2 UART’s on board:

  1. The connection to the AC is an UART. The params are 4800, 8 databits, 1 stop bit, Even parity
  2. The debugging UART: Params here are 115200, 8 databits, 1 stop bit, no parity.

If you connect to the first, you’ll of course get the data packets. And connecting to the 2nd the debug messages.

1 Like

Once connected to the debug UART you can issue these GREE specific commands:
[GATF]: Enter Factory Test Mode
[GATR]: Gree Reset
[ATST]: Gree Reboot
[GATO]: Gree Enter OTA Upgrade

[GATL]:
GATL=1 Recv Printf
GATL=2 Send Printf
GATL=3 Debug Printf
GATL=4 MQTT Printf
GATL=5 Config printf
GATL=0 Close Printf

[GATD]:
GATD=1 Open Tx Printf
GATD=2 Open Rx Printf
GATD=3 Open Uart Printf
GATD=0 Close Printf

[GKEY]:Printf Wifi Info
[GREE]: Open GRAT Order (this enables/disables all printf screen output)
[GHEX]: Open Upload Data Printf

So this is a nice way to receive the data frames without even connecting to the AC UART

2 Likes

Actually there are tons of other commands available, to debug and also network related
Actually it seems to be this code here:

So some of the commands:

#define AT_WLAN_SET_SSID “ATW0”
#define AT_WLAN_SET_PASSPHRASE “ATW1”
#define AT_WLAN_SET_KEY_ID “ATW2”
#define AT_WLAN_AP_SET_SSID “ATW3”
#define AT_WLAN_AP_SET_SEC_KEY “ATW4”
#define AT_WLAN_AP_SET_CHANNEL “ATW5”
#define AT_WLAN_SET_BSSID “ATW6”
#define AT_WLAN_AP_ACTIVATE “ATWA”
#define AT_WLAN_AP_STA_ACTIVATE “ATWB”
#define AT_WLAN_JOIN_NET “ATWC”
#define AT_WLAN_DISC_NET “ATWD”
#define AT_WLAN_WEB_SERVER “ATWE”
#define AT_WLAN_P2P_FIND “ATWF”
#define AT_WLAN_P2P_START “ATWG”
#define AT_WLAN_P2P_STOP “ATWH”
#define AT_WLAN_PING_TEST “ATWI”
#define AT_WLAN_P2P_CONNECT “ATWJ”
#define AT_WLAN_P2P_DISCONNECT “ATWK”
#define AT_WLAN_SSL_CLIENT “ATWL”
#define AT_WLAN_PROMISC “ATWM”
#define AT_WLAN_P2P_INFO “ATWN”
#define AT_WLAN_OTA_UPDATE “ATWO”
#define AT_WLAN_POWER “ATWP”
#define AT_WLAN_SIMPLE_CONFIG “ATWQ”
#define AT_WLAN_GET_RSSI “ATWR”
#define AT_WLAN_SCAN “ATWS”
#define AT_WLAN_SCAN_WITH_SSID “ATWs”
#define AT_WLAN_TCP_TEST “ATWT”
#define AT_WLAN_UDP_TEST “ATWU”
#define AT_WLAN_WPS “ATWW”
#define AT_WLAN_AP_WPS “ATWw”
#define AT_WLAN_AIRKISS “ATWX”
#define AT_WLAN_IWPRIV “ATWZ”
#define AT_WLAN_INFO “ATW?”

Not sure if there are any bad intentions behind this, but this is practically a complete hack tool, lol, including WIFI promiscious mode.

Even more commands and the documentation can be found here:

Although it SEEMS this can only be accessed through the UART and not via the internet, which would of course be a tremendous security breach.

1 Like

Anyway, I used up pretty much all of my free time for the coming few weeks, LOL, so going to work on some other stuff now. I’ve ordered the components to build the ESP32 unit like described in “Piotrva”'s github post from my first post. His code should definitely work for most GREE branded models as the protocol he uses matched the one I’ve been reverse engineering, the GRJWB04-J, which seems to work in a lot of GREE branded models.

So in a few weeks I’ll try that. I read on his github page that the AC doesn’t seem to always process the commands, sometimes it ‘misses’ one, if that indeed happens I’ll look into that and see if there’s a way to fix that. It could be for example that we’ll need to better mimic the original communication since it seems he only sends the 0x1 command. Could be that we’ll need to implement the others too …

2 Likes

BTW if anyone is interested in playing with the above commands, be careful! I managed to brick my module, not even sure how I did it, LOL, but it didn’t boot correctly anymore, it wouldn’t start the bluetooth access point anymore (and I hadnt configured wifi yet on this module). Also it wouldnt even issue packets to the AC anymore … Maybe it was because I tried the ‘factory mode’ command, not sure… Anyway, luckily I could still issue commands via the debug UART. With the “ATWC” command I could have the module join my home wifi. With the ‘downloadserver’ tool (ambd_sdk/tools/DownloadServer at dev · ambiot/ambd_sdk · GitHub) I could create a local server with the new firmware. Then with the ATW0 command I could flash the FW. I took the opportunity to upgrade to the latest v1.53 FW (downloaded from that github page in my first post) and everything works again :sweat_smile:

3 Likes

Hoi Gekke Henkie, nice to read this progress. would appreciate it if you can also share the results when you finish your ESP32 unit.
Thanks!

2 Likes

Same for me, very interested in this project!