Giter Club home page Giter Club logo

gree-remote's Introduction

gree-remote

This project aims to provide an open-source library for controlling Gree Smart Air Conditioners. The implementation is based on the reverse-engineered proprietary, JSON-based protocol used by these units. Also there are remote control app implementations for multiple platforms:

  • Qt/C++ for Windows/macOS
  • ObjectiveC/Cocoa for macOS
  • Java for Android
  • C# for DotNet Core
  • Python 3 (PythonCLI/gree.py)

You can find more implementations for other languages and frameworks:

Getting started

The first step is to clone this repository: git clone https://github.com/tomikaa87/gree-remote.git. Don't forget to checkout all the submodules using git submodule update --init --recursive.

Qt application:

  • Compile the CryptoPP using the provided build script in 3rdparty. This is only necessary for the native C++/Qt library, Android uses Java's crypto library.
  • Open GreeRemote.pro from the root of the checkout directory
  • Compile the project

Android application:

  • Open the project from GreeRemoteAndroid in Android Studio
  • Run the application on the selected device. Keep in mind that the Gree library must access the local network using WiFi, which is not available in the emulator. You must use a physical device.

Prerequisites

For the Qt library and application:

  • Qt 5.9.1
  • XCode 9 for macOS, Visual Studio (2017 is preferred) for Windows

For the Android application:

  • Android Sutdio 3

For the macOS application:

  • XCode 9

Remarks

This project is in a very early development stage. Currently only a basic device discovery and binding is implemented.

There is so much to do:

  • Implement device control with all the air conditioning unit features (mode, temperature etc.)
  • Implement querying device status
  • Create a basic view for a device model
  • Implement initial device setup (direct WiFi connection to a unit to set SSID and password of the home WiFi AP)
  • At a later phase, firmware update capability could be added
  • Command line options could be added to be able to use the app from a terminal

License

This project is licensed under the GPL License - see the LICENSE file for details

Acknowledgments

I would like to thank the additional work to:

Protocol details

This information is based on the implementation of the official Gree Smart Android App and the network packets obtained via Wireshark. The current implementation is incomplete, for example it doesn't have the ability to update the firmware on the AC unit.

The communication protocol uses unicast and broadcast UDP messages sent to port 7000.

Message encryption and encoding

The protocol uses pack-type messages to deliver data from and to the device in a (somewhat) secure way. This message contains a field named pack, which encapsulates an another JSON object.

Packs created in the following way:

  • Encrypt the JSON with AES128/ECB with PKCS-7 padding using either the generic or the device-specific AES key
  • Encode the encrypted binary data using Base64

Decoding a pack is the same process, but in reverse order. The generic AES key is used for reading scan results and binding devices, the device-specific key is used for direct communication (requesting status, changing parameters etc.).

Device discovery (scanning)

In order to find all the devices on the network, a scan packet must be broadcasted. This package is a very simple JSON object:

{
  "t": "scan"
}

All connected devices will send a response JSON like this one:

{
  "t": "pack",
  "i": 1,
  "uid": 0,
  "cid": "<device's MAC address, e.g. 00123456789a>",
  "tcid": "",
  "pack": "<base64 encoded, encrypted data>"
}

This is a generic pack-type response which has a pack field that contains an embedded JSON object. The pack is encrypted with AES128/ECB and encoded in Base64. This response is encrypted using the "Generic AES key" which is the same for all devices.

Contents of pack should look like this:

{
  "t": "dev",
  "cid": "<MAC address>",
  "bc": "gree",
  "brand": "gree",
  "catalog": "gree",
  "mac": "<MAC address>",
  "mid": "10001",
  "model": "gree",
  "name": "<friendly name of the unit>",
  "series": "gree",
  "vender": "1",
  "ver": "V1.1.13",
  "lock": 0
}

You can obtain some basic information (e.g. device's friendly name, software version etc.) from this object.

Binding to a specific device

In order to communicate with a specific device and obtain the device's unique encryption key, you must bind to it using the following request JSON:

{
  "cid": "app",
  "i": 1,
  "pack": "<encrypted, encoded pack>",
  "t": "pack",
  "tcid": "<MAC address>",
  "uid": 0
}

pack must have the following content:

{
  "mac": "<MAC address>",
  "t": "bind",
  "uid": 0
}

If the binding request succeeds, you should have the following response:

{
  "t": "pack",
  "i": 1,
  "uid": 0,
  "cid": "<MAC address>",
  "tcid": "app",
  "pack": "<encrypted, encoded pack>"
}

The pack of this response should look like this:

{
  "t": "bindok",
  "mac": "<MAC address>",
  "key": "<unique AES key>",
  "r": 200
}

The AES key in the key field is used to send control packets to a specific device.

Reading status of a device

To get the status of the device, a generic pack type request must be sent to it:

{
  "cid": "app",
  "i": 0,
  "pack": "<encrypted, encoded pack>",
  "t": "pack",
  "tcid": "<MAC address>",
  "uid": 0
}

The pack of this request must contain a status request object:

{
  "cols": [
    "Pow", 
    "Mod", 
    "SetTem", 
    "WdSpd", 
    "Air", 
    "Blo", 
    "Health", 
    "SwhSlp", 
    "Lig", 
    "SwingLfRig", 
    "SwUpDn", 
    "Quiet", 
    "Tur", 
    "StHt", 
    "TemUn", 
    "HeatCoolType", 
    "TemRec", 
    "SvSt"
  ],
  "mac": "<MAC address>",
  "t": "status"
}

In this object you must define which parameters you are interested in. All of them has a numerical value. The official Gree Smart app uses these fields:

  • Pow: power state of the device

    • 0: off
    • 1: on
  • Mod: mode of operation

    • 0: auto
    • 1: cool
    • 2: dry
    • 3: fan
    • 4: heat
  • "SetTem" and "TemUn": set temperature and temperature unit

    • if TemUn = 0, SetTem is the set temperature in Celsius
    • if TemUn = 1, SetTem is the set temperature is Fahrenheit
  • WdSpd: fan speed

    • 0: auto
    • 1: low
    • 2: medium-low (not available on 3-speed units)
    • 3: medium
    • 4: medium-high (not available on 3-speed units)
    • 5: high
  • Air: controls the state of the fresh air valve (not available on all units)

    • 0: off
    • 1: on
  • Blo: "Blow" or "X-Fan", this function keeps the fan running for a while after shutting down. Only usable in Dry and Cool mode

  • Health: controls Health ("Cold plasma") mode, only for devices equipped with "anion generator", which absorbs dust and kills bacteria

    • 0: off
    • 1: on
  • SwhSlp: sleep mode, which gradually changes the temperature in Cool, Heat and Dry mode

    • 0: off
    • 1: on
  • Lig: turns all indicators and the display on the unit on or off

    • 0: off
    • 1: on
  • SwingLfRig: controls the swing mode of the horizontal air blades (available on limited number of devices, e.g. some Cooper & Hunter units - thanks to mvmn)

    • 0: default
    • 1: full swing
    • 2-6: fixed position from leftmost to rightmost
    • Full swing, like for SwUpDn is not supported
  • SwUpDn: controls the swing mode of the vertical air blades

    • 0: default
    • 1: swing in full range
    • 2: fixed in the upmost position (1/5)
    • 3: fixed in the middle-up position (2/5)
    • 4: fixed in the middle position (3/5)
    • 5: fixed in the middle-low position (4/5)
    • 6: fixed in the lowest position (5/5)
    • 7: swing in the downmost region (5/5)
    • 8: swing in the middle-low region (4/5)
    • 9: swing in the middle region (3/5)
    • 10: swing in the middle-up region (2/5)
    • 11: swing in the upmost region (1/5)
  • Quiet: controls the Quiet mode which slows down the fan to its most quiet speed. Not available in Dry and Fan mode.

    • 0: off
    • 1: on
  • Tur: sets fan speed to the maximum. Fan speed cannot be changed while active and only available in Dry and Cool mode.

    • 0: off
    • 1: on
  • StHt: maintain the room temperature steadily at 8°C and prevent the room from freezing by heating operation when nobody is at home for long in severe winter (from http://www.gree.ca/en/features)

  • HeatCoolType: unknown

  • TemRec: this bit is used to distinguish between two Fahrenheit values (see Setting the temperature using Fahrenheit section below)

  • SvSt: energy saving mode

    • 0: off
    • 1: on

If the status request succeeds, you should have the following object in the response pack:

{
  "t": "dat",
  "mac": "<MAC address>",
  "r": 200,
  "cols": [
    "Pow", 
    "Mod", 
    "SetTem", 
    "WdSpd", 
    "Air", 
    "Blo",
    "Health", 
    "SwhSlp", 
    "Lig", 
    "SwingLfRig", 
    "SwUpDn", 
    "Quiet", 
    "Tur", 
    "StHt", 
    "TemUn", 
    "HeatCoolType", 
    "TemRec", 
    "SvSt"
  ],
  "dat": [1, 1, 25, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0]
}

In this object, cols defines the parameter names and dat defines the values for them.

Since the device won't send you a status update packet when you change a setting using the remote control or the app, you should poll the it periodically.

Controlling the device

In order to set a parameter of a device, you must send a command packet to it. It's a simple pack-type object with the following JSON encoded into it:

{
  "cid": "app",
  "i": 0,
  "pack": "<encrypted, encoded pack>",
  "t": "pack",
  "tcid": "<MAC address>",
  "uid": 0
}

pack:

{
  "opt": ["TemUn", "SetTem"],
  "p": [0, 27],
  "t": "cmd"
}

In this object, opt contains the names of the parameters you want to set and p contains the values for them. The type of the pack is cmd. If the request succeeds, you should have the following response pack:

{
  "t": "pack",
  "i": 0,
  "uid": 0,
  "cid": "<MAC address>",
  "tcid": "",
  "pack": "<encrypted, encoded pack>"
}

pack:

{
  "t": "res",
  "mac": "<MAC address>",
  "r": 200,
  "opt": ["TemUn", "SetTem"],
  "p": [0, 27],
  "val": [0, 27]
}

In this object, r is the response code (not sure if there are other values than 200 because the device won't send you anythin if the request fails]), opt contains the name of the parameters you set, p and val contains the values for them.

Some firmwares may return only one field p instead of both p and val. It is better to handle such cases.

Update: it seems that there are different variants of these Gree devices that properly respond to an invalid packet, probably the newer ones with updated firmware.

Setting the temperature using Fahrenheit

Two things I found were despite TemUn being set, the set temp is still in Celsius. Use the TemRec bit to distinguish between the two Fahrenheit temps

pack:

{
  "opt": ["TemUn", "SetTem","TemRec"],
  "p": [1, 27,0],
  "t": "cmd"
}

Getting the current temperature reading from the internal sensor

If the device is equipped with a temperature sensor, you can read it via the TemSen key. The value is in celsius and has an offset of +40 to avoid using negative values. For example if you get 65 from the device it means the current temperature is 65 - 40 = 25.

If you use the gree.py script, you can read the sensor like this:

python3 gree.py -c <device ip> -i <device id> -k <device key> get TemSen

TempRec TemSet Mapping for setting Fahrenheit

Units 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Fahrenheit 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86.
Celsius 20.0 20.5 21.1 21.6 22.2 22.7 23.3 23.8 24.4 25.0 25.5 26.1 26.6 27.2 27.7 28.3 28.8 29.4 30.0
TemSet 20 21 21 22 22 23 23 24 24 25 26 26 27 27 28 28 29 29 30
TemRec 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0

Equations
TemSet = round((desired_temp_f - 32.0) * 5.0 / 9.0)
TemRec = (int) ((((desired_temp_f - 32.0) * 5.0 / 9.0) - TemSet) > 0)

Scheduling

There is a simple scheduler implementation which can turn on or off your device automatically. New scheduling item can be added via the following packet (thanks to oroce for the details):

{
  "cmd": [
    {
      "mac": [
        "<MAC address>"
      ],
      "opt": [
        "Pow"
      ],
      "p": [
        0
      ]
    }
  ],
  "enable": 0,
  "hr": 20,
  "id": 0,
  "min": 40,
  "name": "5363686564756c65",
  "sec": 0,
  "t": "setT",
  "tz": 1,
  "week": [
    0,
    0,
    1,
    0,
    0,
    1,
    0
  ]
}

In this object, cmd defines which device you want to address (mac), which parameters you want to set (opt) and which are the values for them (p). enable controls the state of this scheduling item, hr and min is the time, name is the name of the item encoded into ASCII bytes in hexadecimal format, tz is the time zone (probably an offset value) and week defines on which weekdays the device will execute the command, begining with Sunday.

Synchronizing the time on the device

In order to get the current time of the device's clock, you must send the following encrypted pack to it:

pack:

{
  "cols": ["time"],
  "mac": "<MAC address>",
  "t": "status"
}

And the device will send a response like that:

pack:

{
  "t": "dat",
  "mac": "<MAC address>",
  "r": 200,
  "cols": ["time"],
  "dat": ["2018-05-11 19:42:01"]
}

To set the time on the device, send the following pack:

pack:

{
  "opt": ["time"],
  "p": ["2018-05-11 19:29:38"],
  "sub": "<MAC address>",
  "t": "cmd"
}

And the device will send a response like that:

pack:

{
  "t": "res",
  "mac": "<MAC address>",
  "r": 200,
  "opt": ["time"],
  "p": ["2018-05-11 19:29:38"],
  "val": ["2018-05-11 19:29:38"]
}

Remarks

For the sake of simplicity, you can send device control messages to the broadcast address instead of the IP of the device, because the tcid field addresses the device properly. With this little trick you can omit storing IP addresses for specific devices.

Different units have different firmware versions. Some of them have weird limitations. One of these can be a WiFi password length limitation. WPA supports 63-character long passwords, but some units limit this to 31 characters. Please be aware of this issue when your units can't connect to your network.

The units talk home to China, what can I do?

The WiFi controller in these devices has the ability to be controlled through the cloud. To be able to do that, they periodically send "heartbeat" packets to Gree servers which are located in China. If you are concerned about your privacy and want to block this communication, you have a few ways to do that:

  • Block traffic in your firewall from your unit that is going outside from the local network. My units try to connect to 138.91.51.53 to port 5000 TCP. This method can cause some units to lock up and stop responding to local requests.
  • Use the dummy server made by emtek-at:

gree-remote's People

Contributors

aivus avatar alexiade avatar alexmuntean avatar eschava avatar makemeafirewall avatar sm4rk0 avatar tomikaa87 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gree-remote's Issues

.NET Rest API

I don't know if you are interested in this but I've created a basic rest API in .NET using your code. If you want to I can share that for others.

Ac unit not responding to "status cmd"

Hello all,
many thanks for this great info ! i followed the instructions & open source and developed everything from scratch- AES128 encrypt & Decrypt, BASE64 encrypt, (the BASE64 decrypt was part of exiting lib) on a TwinCAT3.1 PLC.
i was able to "search" and "bind' and even got response from the AC unit with it's special key,
now, I'm trying to read AC unit statuses, but got zero response,
i think the status cmd i'm sending is wrong,
i used an online tool to double check the "Pack", from some reason i'm not sure why (yet) it's different than what my TwinCAT code is generating, but i send "status cmd" with both Packs ,and AC not responding to any of them.

the only thing cross my mind: is there any meaning for spacing? which i might used differently
here is how my Json looks like:
{"cols":["Pow","Mod","SetTem","WdSpd","Air","Blo","Health","SwhSlp","Lig","SwingLfRig","SwUpDn","Quiet","Tur","StHt","TemUn","HeatCoolType","TemRec","SvSt"],"mac":"f4911e312b48","t": "status"}

2nd thing that cross my mind : does status cmd is encrypted with the generic key or the unique key ?
tnx! Moti

Update wiki/code with clock status & update.

Hi @tomikaa87 , @alexiade ,

Below is the JSON procedure for Get & Set the clock on device. Would be nice if you update the documentation on README.md .

Procedure works for me (i am using a simple python script to control the air-cooler, will publish it later)

##
## get time
##

  * send
  {"cid":"app","i":0,"pack":"<encrypted_pack>","t":"pack","tcid":"f4911e343545","uid":0}

  pack = {"cols":["time"],"mac":"f4911e343545","t":"status"}

  * receive
  {"t":"pack","i":0,"uid":0,"cid":"f4911e343545","tcid":"","pack":"<encrypted_pack>"}

  pack = {"t":"dat","mac":"f4911e343545","r":200,"cols":["time"],"dat":["2018-05-11 19:42:01"]}


##
## set time
##

  * send
  {"cid":"app","i":0,"pack":"<encrypted_pack>","t":"pack","tcid":"f4911e343545","uid":0}

  pack = {"opt":["time"],"p":["2018-05-11 19:29:38"],"sub":"f4911e343545","t":"cmd"}

  * receive
  {"t":"pack","i":0,"uid":0,"cid":"f4911e343545","tcid":"","pack":"<encrypted_pack>"}

  pack = {"t":"res","mac":"f4911e343545","r":200,"opt":["time"],"p":["2018-05-11 19:29:38"],"val":["2018-05-11 19:29:38"]}

Documentation: List of params?

Where can I find the list of params that my AC provides, and an explanation what each parameter does?

A thousand thanks for this, I love this CLI utility. I will buy You a beer if I ever meet You.

emitter.setMaxListeners()

Hi there!

I'm using this MQTT Bridge to control my AC (through nodered btw, but that has nothing to do with the error)

https://github.com/stas-demydiuk/ewpe-smart-mqtt

Since this morning, I cannot use the mqtt bridge, due to this error that it gives in the terminal when I run "npm start" in the ewpe-smart-mqtt::

(node:3635) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 message listeners added to [Socket]. Use emitter.setMaxListeners() to increase limit

What should I do?

I tried to search for how and where should I set it to infinty (emitter.setMaxListeners(0)), but I have no idea which file should I edit.
Also I read that this message is not strictly generated because it runs out of places for listeners, it could also indicate some sort of code error.
I've read somewhere that the code might not release listeners, when connection lost, so when it reconnects the mqtt, it just adds another listener...so it might be a "not-perfect-wifi" connection between the AC and the router, therefore the mqtt, so it always creates a new listener, and that fills up quickly...

Can you help me here?

Reset wifi configuration, switch back to setup mode

Is there any way I can issue a command that resets the wifi configuration?

When setting up, I didn't realize some devices in the wifi list are not mine, so I have some devices connecting to my WiFi AP. I can control some unknown AC's that are not in my house. They accept commands, and I can confirm that they to turn on/off, etc.

I've tried to send them

{"psw": "00000000","ssid": "00000000","t": "wlan"}

but of course they won't accept it since they're not in setup mode anymore.

I rather not change my SSID and password, as there are too many IoT devices connected to it, some have the pass cooked into the firmware, etc, so I really hope I can just reset them remotely. I could also probably blacklist their MAC address, but again, they'd keep trying to connect indefinitely I think.

There's also the go around my neighbourhood asking about their ACs, or look for GREE external units, then explain them how to reset, etc option but hopefully it doesn't have to come to that.

"Tur" value

Just to mention:
"Tur" value sets Turbo mode of the AC. It IS available in HEAT mode(not as specified in readme.md), and the device is controlling automatically the fan speed. Probably the same in in other modes.

And you can set the friendly name of the device, with "name" tag of a cmd request.

My devices answering on a "cmd" request with invalid values. Not as stated in readme.md: the device is not answering. The device will not answer only if the request is malformed or not correctly encrypted.

Do you have the ways to get the GenericKey? (old: "a3K8Bx%2r8Y7#xDh")

I bought a new Gree AC, it can controlled by gree's APP, and I used the udp try to controll myself. it can be discovered but cannot bind. my old gree AC can be discovered and bind success. so the problem is the new one changed the GenericKey.
Do you have way to get or hack the new generic key? please, I really want to get it. My 5 gree ACs, only the last one cannot controll myself.

Reading TemSen in the Android app

It looks like some ACs report current room temperature with the TemSen property. The reported value has +40°C offset. Would this be possible to integrate into your programs?

I should also add that my Sinclair AC with firmware 3.7 didn't report the temperature until I "updated" to 2.5. Before that it just reported 0.

Question about documentation

Hi! Thank you for the your documentation that is very useful and well explained. I'm trying to interface the gree system via Python but have some issue probably in the requests.
The discover works perfectly and I receive the answers from all splitter but I'm not able to bind any of the five devices.
So, the question is, reading the documentation you wrote about MAC Address that I should use in the tcid and mac fields but when I try the discover I receive different values for these fields.
So, which one I've to use?

The answer on discover in my case is:
Received from ('192.168.0.81', 7000): {"t":"pack","i":1,"uid":0,"cid":"f4911e6fcbdf","tcid":"dc26211e39c8","pack":"LP24Ek0OaYogxs3iQLjL4FxcFMarR4aGOyo8RK7I2p6Ma9lM2RqI/KytvJ32IsGSZXrOr+MakVzzXHbghPeyijnWMzaLQaaw1aFXlE9k71L0cMm8bsr/y4FkxumpRg1tKs/34xhBuMSxXfNfvEgS5yy17SnLfjPrNMTsp5oXbJ1zMQoS41XpnORSG7+GfavhnKYbt0iIDsdp8/ftXlA9HjiRRKlroAV17fdfFvf6AtK80gq9HxK8Loa8WXVjgZcP4Vf5MjKxa60Xt5J1oI+lsxUuXTHkgunLg76WWGy+euo="}

Decoding the pack I have:
{"t":"dev","cid":"f4911e6fcbdf","bc":"000000000000000000000000000000","brand":"gree","catalog":"gree","mac":"f4911e6fcbdf","mid":"10001","model":"gree","name":"1e6fcbdf","series":"gree","vender":"1","ver":"V1.2.1","lock":0}

So we have these values:
cid: f4911e6fcbdf
mac: f4911e6fcbdf
tcid: dc26211e39c8

The question is, which one and in which field I've to use to do a right request?

In any combination I try I didn't get an answer...

Thank you!

Sinclair ACs?

Hi, recently we've had some Sinclair AC units installed at our house.
They also support some form of control over WiFi. I'd like to integrate them into OpenHab, but I'm not nearly experienced enough to make my own binding. So I'd like to ask, would it be possible to add support for this Sinclair unit?

I can provide any info you may need (as long as it doesn't require disassembling the AC).
I already tried the python script you made but it doesn't find it (I ran python gree.py scan -b 255.255.255.0).

Before you dismiss this... I have a few reasons to believe your code might need very little modification to work with this brand.

User's perspective

When enabled using the AC remote, it makes a WiFi hotspot with a random name and the password 12345678. Connecting to it allows to use their app called WiFi Smart. This works only as long as the user is connected to the AC's WiFi. The app has an option to make an online account and I assume that would allow the AC to connect to your home WiFi network and be controlled even over the internet (I haven't tried that because I would prefer not to create such an account.)

How it works under the hood

I connected to the AC's WiFi using one laptop, bridged it to its Ethernet, connected another laptop and made a WiFi hotspot. I then connected my phone and could control the AC while capturing the packets exchanged between the phone and the AC on the second laptop.

voila
The phone constantly sends UDP packets to port 7000, address 255.255.255.0.

Other similarities

The features are almost identical.

  • 5 modes in order Auto, Cool, Dry, Fan, Heat
  • 3 fan speed levels (low, medium, high and auto), the manual hints at more speeds in different models
  • X-Fan (also only available in Cool and Dry modes)
  • "Health"
  • "Sleep" function that works in exactly the same way as the Gree ACs
  • The display on the AC unit can be turned off
  • Left-right and up-down swing
  • "Quiet" mode
  • "Turbo" mode (only in Heat and Cool) - from your docs on the Gree units this works in Dry and Cool
  • 8°C Heating mode
  • Energy-saving function

Ac unit sometimes not responding to status request

Hi,
So, as mentioned here already, I used this great GitHub with it's info to build from scratch my PLC code,
my code does :
--> connecting to WIFI
--> get's the unique key
--> send operation commands,
--> ask for current status
and I'm polling status from the AC units every ~5 sec, i have in my home 4 AC units.

I've seen that sometimes, at the moment not sure exactly why , the AC unit not respond to status request, but it does do any command I'll ask ,so it's not general communication problem.

My units are having version V1.1.13, they are 5 years old. and I'm wonder if it worth trying upgrade their FW.

Any one has any experience with such behavior?

cheers!

Add SwingLfRig values to readme

The values for SwingLfRig are

  • 0 - default (no swing)
  • 1 - full swing
  • 2 to 6 - fixed leftmost to rightmost

Partial swing doesn't seem to be supported

Figured out on Cooper&Hunter AC by setting swing via "Wifi smart" iOS app and then reading AC status via Gree protocol.

Maximum length for AP password?

Hello,

I can successfully register my AC with the "guest wifi" of a FritzBox, for example:
ssid: "Guest", pw: "1234ABCD"
But I am not able to register my AC with either the main wifi or the guest wifi with a significant longer password (30-40 characters). The response is always
resp={'t': 'ret', 'r': 200, 'mac': 'mac1234'}
The wifi AP of the AC shuts down and comes back up after a few moments.
Are there any restrictions? Or any ideas? I do not want to change my wifi password to a shorter one (this could weaken security and also I am too lazy).

Kind regards,
Daniel

change wifi network for existing AC device- end with problem with binding

Hi,
i have existing AC device which i want to use on another WIFI network,
the new WIFI has different IP range
i was able to reset the WIFI settings in the device using the remote control, and was able to command it to connect with the new network(using simple hyper terminal), that's works fine, i can ping it on the new network, it answer to {"t": "scan"} , so far all good.

i tried to send commands using the know unique password I have used so far, he's not answering ,
it not responding to binding command with the default AES password key either.

seem that he kind of stuck with the previous binding, any one seen something like that before?
tnx
Moti.

Incorrect response from gree U-crown after {"t": "scan"}

I have a Gree U-crown installed: https://www.gree.nl/nl/12-producten/split/33-u-crown

After the {"t": "scan"} I get a incorrect formatted response like:
Received packet of size 347
From 192.168.0.12, port 7000

Packet contents:
0-->t 74
1-->� 0
2-->p 70
3-->a 61
4-->c 63
5-->k 6B
6-->� 0
7-->i 69
8-->� 0
9-->1 31
10-->� 0
11-->u 75
12-->i 69
13-->d 64
Position, char value en hex number.

I am using the software on an arduino mega.
My computer can not run QT (Ubuntu 14.04).
Can you please give me a hint?

With kind regards
Ron Groen
The Netherlands.

Add support of statuses

I've found few extra statuses which can be requested (changed?):
SlpMod: 0,
AllErr: 0,
host: 'eu.dis.gree.com',
name: 'Livingroom conditioner '

Those statuses were found in SQLite DB of EWPE Smart iOS APP.
Data form "deviceTable" table:

  • "fullJson1" column: ["Pow","HeatCoolType","Mod","TemUn","SetTem","TemRec","StHt","SvSt","host","name","AllErr","ModelType"]
  • "fullJson2" column: ["Pow","Mod","TemUn","SetTem","TemRec","HeatCoolType","WdSpd","Tur","Quiet","SwUpDn","SwingLfRig","Air","Blo","Health","SvSt","Lig","StHt","SwhSlp","SlpMod","AllErr","ModelType"]

gree.py - "The length of the provided data is not a multiple of the block length" exception on initial search

Hi,
First, thanks for your great initiative!

When using gree.py to discover my Gree devices (the search command) it first successfully decrypt my Cooper & Hunder's returned pack JSON field. Still, then it returns The length of the provided data is not a multiple of the block length exception while attempting to decrypt the pack field returned by the second Gree Soyal device (might be a newer model!!). I've tried to apply padding, using Python's PKCS7(128).padder(), it doesn't crash anymore but the decrypted data seems garbage and not a valid JSON.

Are the new Gree models make use of other generic keys? Can you, please provide some guidance, on how to investigate further?

Thanks!

Esp8266 (Arduino) support

Hello All,

I am having a bunch of esp8266 room thermostats in my flat.
I wuld also like to make them controlling my airconditionig system.

I did a quick try on this already, but to be honest, I am not experienced enough on encrypting.

Are you able to help me doing this?

Thank you very much in advance!

All the best,
Gábor

I want to write a server for Gree in the cloud

Hello brothers!

I want to write a server that can replace the current server. I saw that the server address can be changed, so I was wondering if I can replace the server completely. My goal is to write my own Android app+server and control my AC from everywhere in the world. Does someone know how the AC communicate with the remote Gree server? thanks!

Toyotomi dehumidifier

I found that my Toyotomi dehumidifier uses the Gree protocol. I used gree.py to get the device key, then decrypted info from "Ewpe Smart" application that Toyotomi suggests to use.
Those are the fields:
{"cols":["Pow","Dmod","Dwet","WdSpd","DwatFul","Lig","SwUpDn","Health","Quiet","PM2P5","airQlt","DwatSen","ChildLock","AppTimer","AllErr","ModelType","Dfltr"],"mac":"502cc626d560","t":"status"}

and a response:
{"t":"dat","mac":"502cc626d560","r":200,"cols":["Pow","Dmod","Dwet","WdSpd","DwatFul","Lig","SwUpDn","Health","Quiet","PM2P5","airQlt","DwatSen","ChildLock","AppTimer","AllErr","ModelType","Dfltr"],"dat":[1,2,5,0,0,1,1,1,2,1,1,51,0,0,0,0,0]}

DwatSen is the humidity sensor (51 meaning 51% humidity). The target value set is in increments of 5% from 30 to 80, I will figure out all the values in the next days.

What else is needed to support my device?

No devices on Android

Hey,
I have recently setup a gree air conditioning system and wanted to combine it with some android skills of my own.
I've checked out your code and and ran it only to have no devices and no response on the discover method.
Could you please provide me with a few simple steps on how to setup the connection between the app and the device?
I believe there is something silly and simple escaping my reasoning :)

Remarkable job gathering all this information under this repository!
Kind regards,

Command to disable beeping

It would be very useful, as I am controling my airconditioner automatically.
Quit anoying.

Anyone have tried to do this already?

Regards,
Gábor

Indoor/Outdoor temperature sensors

A unit branded as "Inventor" reports Indoor and Outdoor temperature in the Android application (Invmate II). How would it be possible to determine the name of the outdoor sensor? Using the python cli the unit was detected and the value of the TemSen sensor is 41. The Android app reports the indoor temperature as 19 degrees Celsius.

TemSen value

Hello, I need help reading value of TemSen

I have a Gree Device (branded NordCel) with firmware revision 3.1.
TemUn returns 0 (should mean Celsius), but TemSen returns 118.
What could that possibly mean? Even after subtracting -40, it is not a reasonable value.

Support for air-to-water heatpump

Hey!
I've got myself a few months back a heat pump from Sinclair (model: smh-100irb and smh-60irb) and it didn't work out of the box with the gree-remote or any other gree-variant (HomeAssistant plugin or ewpe-smart-mqtt) so I've started digging. Here is the complete flow I was able to dig out from the EWPE Smart app with Wireshark (the heat pump is there as "ATW HP").
All the pack data is decrypted for easier reading.

the initial discovery of the device via UDP broadcast

send:
{
  "t": "scan"
}

received data: (decoded with key "a3K8Bx%2r8Y7#xDh")

{
    "t":"pack",
    "i":1,
    "uid":0,
    "cid":"<MAC>",
    "tcid":"app",
    "pack":"{
        "t":"dev",
        "cid":"<MAC>",
        "bc":"gree",
        "brand":"gree",
        "catalog":"gree",
        "mac":"<MAC>",
        "mid":"9300",
        "model":"gree",
        "name":"",
        "series":"gree",
        "vender":"1",
        "ver":"V5.0.0.0",
        "lock":0
    }"
}

send: (encoded with key "a3K8Bx%2r8Y7#xDh")

{
    "cid": "app",
    "i": 1,
    "pack": "{
        "mac": "<MAC>",
        "t": "bind",
        "uid": 0
    }",
    "t": "pack",
    "tcid": "<MAC>",
    "uid": 0
}

received data: (decoded with key "a3K8Bx%2r8Y7#xDh")

{
    "t":"pack",
    "i":1,
    "uid":0,
    "cid":"<MAC>",
    "tcid":"app",
    "pack":"{
        "t":"bindok",
        "mac":"<MAC>",
        "key":"<KEY>",
        "r":200
    }"
}

got key "KEY"
Now I was able to read the status and temperature of the heat pump.
This part took me the longest as I had to figure out the new object names.

send: (encoded with key "KEY")

{
    "pack":"{
        "t":"status",
        "mac":"<MAC>",
        "cols":[
            "AllInWatTemHi",
            "AllInWatTemLo",
            "AllOutWatTemHi",
            "AllOutWatTemLo",
            "HepOutWatTemHi",
            "HepOutWatTemLo",
            "WatBoxTemHi",
            "WatBoxTemLo",
            "RmoHomTemHi",
            "RmoHomTemLo",
            "WatBoxElcHeRunSta",
            "SyAnFroRunSta",
            "ElcHe1RunSta",
            "ElcHe2RunSta",
            "AnFrzzRunSta",
            "TemUn",
            "AllErr"
        ]
    }",
    "i":0,
    "cid":"app",
    "uid":0,
    "tcid":"<MAC>",
    "t":"pack"
}

received data: (decoded with key "KEY")

{
    "t":"pack",
    "i":0,
    "uid":0,
    "cid":"<MAC>",
    "tcid":"app",
    "pack":"{
        "t":"dat",
        "r":200,
        "mac":"<MAC>",
        "cols":[
            "AllInWatTemHi",
            "AllInWatTemLo",
            "AllOutWatTemHi",
            "AllOutWatTemLo",
            "HepOutWatTemHi",
            "HepOutWatTemLo",
            "WatBoxTemHi",
            "WatBoxTemLo",
            "RmoHomTemHi",
            "RmoHomTemLo",
            "WatBoxElcHeRunSta",
            "SyAnFroRunSta",
            "ElcHe1RunSta",
            "ElcHe2RunSta",
            "AnFrzzRunSta",
            "TemUn",
            "AllErr"
        ],
        "dat":[
            132,
            4,
            132,
            2,
            70,
            0,
            100,
            0,
            70,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0
        ]
    }"
}

input water temp: (dat[0]-100)+dat[1]*0.1 = 32.4
output water temp: (dat[2]-100)+dat[3]*0.1 = 32.2
same goes for other variables that have two parts wih Hi-Lo ending
(HepOutWatTem shows -30 because i dont have it configured)

send: (encoded with key "KEY")

{
    "pack":"{
        "t":"status",
        "mac":"<MAC>",
        "cols":[
            "Pow",
            "Mod",
            "CoWatOutTemSet",
            "HeWatOutTemSet",
            "WatBoxTemSet",
            "TemUn",
            "TemRec",
            "AllErr",
            "host",
            "name",
            "ColHtWter",
            "HetHtWter",
            "LefHom",
            "TemRecB",
            "RomHomTemExt",
            "CoHomTemSet",
            "HeHomTemSet"
            ]
    }"
    "i":0,
    "cid":"app",
    "uid":2179292,
    "tcid":"<MAC>",
    "t":"pack"
}

received data: (decoded with key "KEY")

{
    "t":"pack",
    "i":0,
    "uid":2179292,
    "cid":"<MAC>",
    "tcid":"app",
    "pack":"{
        "t":"dat",
        "r":200,
        "mac":"<MAC>",
        "cols":[
            "Pow",
            "Mod",
            "CoWatOutTemSet",
            "HeWatOutTemSet",
            "WatBoxTemSet",
            "TemUn",
            "TemRec",
            "AllErr",
            "host",
            "name",
            "ColHtWter",
            "HetHtWter",
            "LefHom",
            "TemRecB",
            "RomHomTemExt",
            "CoHomTemSet",
            "HeHomTemSet"],
        "dat":[
            1,
            1,
            18,
            35,
            50,
            0,
            0,
            0,
            "eu.dis.gree.com",
            "",
            0,
            0,
            0,
            0,
            0,
            24,
            20
            ]
    }"
}

it would be nice if you could integrate this into the gree-remote. In the end, I would love it to work with Home assistant.

Multiple commands with Python script

Hi,

How can one send multiple commands in one request? Like the gree apps scenes-feature. One press can turn on the device, set a specific mode and temp.

no support for firmware v2

It's only support my KFR-35GW ,which firmware version is V3.31,doesn't work for KFR-26GW,which firmware version is V2

Registering AC on the network

Hi,
Do you have information about how the registration of the AC happens on the network?
I mean, when I set the WiFi access for the device on EWPE application.

Regards,
Grunci

Re-connecting to network

Hi all!

I have this Gree AC (actually Nordcel in my country) in a country house for keeping 8 degrees in the house during the winter time.
I did set up Pi3 with temperature sensors (DHT22) to see if the device is actually working (and it seems from the temperature, that it does) and I also have access over the internet to my Wifi router.

The problem is that after some period Gree AC disconnects itself from Wifi network.

Does anyone of you have an idea how could I reconnect Gree back to the network? Daily automatic restarts somehow? Some sort of timer function? How does the remote control work?

Of course EWPE Smart nor Wifi Smart can see the device.

Hopefully I can jump in and help develop some sort of managing software (web based?) for Gree devices in summer, when I have physical access to the device.

Thank you everybody for your work and help!

Mind sharing some details about how does Gree device work?

Hey, I have a Gree Smart AC as well and if I can guess you are mimicking the Gree Smart app. Can you share some details how does it work? I was trying to reverse engineer it, but I had no luck.

I tried:

  • listening on the wifi for bonjour devices
  • using proxy on android
  • nmapping the AC

I emailed them for docs, no reply.

Do you have a documentation or did I miss something?

Thanks

Innova Racker model time out

Hi,
I'm trying to get this to work with a Gree+ model (Innova Racker), but I get timeouts when trying to get the unit key:

pi@pi4:~/projects/gree-remote/PythonCLI $ python3 gree.py search -b 192.168.1.255
Searching for devices using broadcast address: 192.168.1.255
Search finished, found 1 device(s)
Binding device: 192.168.1.23 (Sypialnia, ID: f4911ec262a3)
Traceback (most recent call last):
File "gree.py", line 189, in
search_devices()
File "gree.py", line 103, in search_devices
bind_device(r)
File "gree.py", line 113, in bind_device
result = send_data(search_result.ip, 7000, bytes(request, encoding='utf-8'))
File "gree.py", line 29, in send_data
return s.recv(1024)
socket.timeout: timed out

What could cause this? Newer master key or unsupported protocol version?
Would appreciate any help.
Thanks

Gree Fairy - update firmware to V4

Hi, I read on github the possibility to update the unit to firmware V4 (currently I have firmware 3.72). How can I do? I have the Gree+ app on Android and my account is set to Europe. Thank you so much for your valuable contribution.

AC not found

Hi

I’m trying to use a Python version on linux. I try to discover my AC in the network but it returns nothing.

python3 gree.py -b 192.168.2.255 search
Searching for devices using broadcast address: 192.168.2.255
Search finished, found 0 device(s)

I used tcpdump in my network. It seem that it produces correct request as described in documentation but my AC does not answer.

I captured also communication between my AC and some server (I guess in China) which happens when I’m controlling my AC from Android app. The messages looks also as you describe in the documentation. However, it uses TCP (not UDP) and uses port 64065 at AC side.

I tried also port scanning in my network and played with ARPs. AC replies to ARP. But seems not to have open ports at all.

Tried also to modify a bit gree.py to use actual MAC and IP of my device (instead of broadcast). Also nothing.

My AC communicates with Android app without any problem.

Do you have any idea of what I’m doing wrong?

New repo

Hi guys,

I used your repo to read how to do the binding and stuff.. I created a rest API. I'm using this to create applets on IFTTT mostly for google assistant :)
I'll document it later and add your repository as source of inspiration if that's fine for you.
repo: https://github.com/alexmuntean/gree-airconditioner-rest
It's a spring boot project. if you wanna see it just mvn clean install and java -jar target/....jar" and you'll see the REST API in localhost:8080/powerOn localhost:8080/powerOff localhost:8080/temperature?temperature=16`

Thanks for your contribution and research and patience :)

Thanks,
Alex

Implementing ad-hoc AP authentication

As far as I can see, the initial AP authentication phase which requires ad-hoc WiFi connection between the smart phone app and the AC hasn't been implemented yet.

I know packet sniffing on switched networks with already connected ACs is not so difficult but what about this kind of ad-hoc connection? Have you any ideas? ...maybe any progress?

Lock flag in scan response

Hello.

Thank you for reverse engineering Gree protocol.
I'm using it in app for smart home controller Homey.

But I have a question.

Do you have any information about "lock" flag in the scan response package?
Any ideas what does it mean when lock=1?

{
  "t": "dev",
  "cid": "<MAC address>",
  "bc": "gree",
  "brand": "gree",
  "catalog": "gree",
  "mac": "<MAC address>",
  "mid": "10001",
  "model": "gree",
  "name": "<friendly name of the unit>",
  "series": "gree",
  "vender": "1",
  "ver": "V1.1.13",
  "lock": 0   // <----- THIS
}

Thanks

Python CLI script on Windows - ConnectionResetError [WinError 10054]

I'm trying to run gree.py on Windows 11 using python 3.10 but no luck, I'm getting ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host all the time, no matter what I do.
Anyone succeeded on windows?

$ .\python.exe C:\workspace\home-assistant\gree.py -b 192.168.55.255 search
Searching for devices using broadcast address: 192.168.55.255
Search finished, found 1 device(s)
Binding device: 192.168.55.18 (c6a4XXXX, ID: 502cc6aXXXXX)
Bind to 502cc6aXXXXX succeeded, key = Pq9St2Vw5YzXXXXX

$ .\python.exe C:\workspace\home-assistant\gree.py --verbose -c 192.168.55.32 -i 502cc6aXXXXX -k Pq9St2Vw5YzXXXXX get Pow
Getting parameters: Pow
send_data: ip=192.168.55.32, port=7000, data=b'{"cid":"app","i":0,"pack":"3LbLoQxLG6Ulufx/18NHB9khXFXA2SxQBCKZI3tL2+9iihDQaZQfQ3o42gZa95Z8MOIuRn73jYAffH44aaJ+dQ==","t":"pack","tcid":"502cc6aXXXXX","uid":0}'
Traceback (most recent call last):
  File "C:\workspace\home-assistant\gree.py", line 251, in <module>
    get_param()
  File "C:\workspace\home-assistant\gree.py", line 164, in get_param
    result = send_data(args.client, 7000, bytes(request, encoding='utf-8'))
  File "C:\workspace\home-assistant\gree.py", line 37, in send_data
    return s.recv(1024)
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
$ .\python.exe -V
Python 3.10.7

$ .\Scripts\pip.exe install pyopenssl
Requirement already satisfied: pyopenssl in c:\uses\python310\lib\site-packages (23.1.1)
Requirement already satisfied: cryptography<41,>=38.0.0 in c:\uses\python310\lib\site-packages (from pyopenssl) (38.0.1)
Requirement already satisfied: cffi>=1.12 in c:\uses\python310\lib\site-packages (from cryptography<41,>=38.0.0->pyopenssl) (1.15.1)
Requirement already satisfied: pycparser in c:\uses\python310\lib\site-packages (from cffi>=1.12->cryptography<41,>=38.0.0->pyopenssl) (2.21)

gree ac

Hi! Please if someone can help me. Maybe I'm I'm on wrong address but I don't know anymore who can answer my.
I have gree ac GEH18AA-K6DNA1F/O
GEH18AA-K6DNA1F/I and I didn't never get update. It's terrible how work's. I have still V1.00 and If I try to make update I get information that no Server firmware version... Does someone same problem?
Screenshot_2023-01-13-18-25-39-126_com google android apps photos

Simple way for remote control from linux server?

Hi,
I want to use your code for remote control my gree ac, I need to auto set temperature on ac at some time using cron on my linux server...is it easy possible with "gree-remote" code?
Also I must note that my server is not on same network as AC!

If it possible with gree-remote code on linux server please somebody write how I can easy do that, please step by step...

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.