tomikaa87 / gree-remote

Simple remote control utility for Gree Smart air conditioners
GNU General Public License v3.0
265 stars 62 forks source link

Simple way for remote control from linux server? #23

Open xman123 opened 4 years ago

xman123 commented 4 years ago

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.

tomikaa87 commented 4 years ago

Hi,

There is no command line utility at the moment, but there are implementations in multiple languages that can be adapted. I have a python test script somewhere which can send commands to the AC. I get back to you when I found it.

xman123 commented 4 years ago

Will be nice if you can do that with all info step by step how I can use it...your script using gree api? I need to control my AC from remote location, not from local network...

Thanks.

tomikaa87 commented 4 years ago

The script can only communicate directly with the units. If you can setup your firewall to allow trafic to your AC units, the script will reach them, but it uses the local communication protocol. I don't have implementation for the cloud API unfortunately.

xman123 commented 4 years ago

Ok, I can work with it, I can open firewall ports to AC... If you know how directly to communicate with gree ac, do you know for some option to schedule temp changes from windows os?

Thanks.

tomikaa87 commented 4 years ago

Just a quick update, I'm working on the script. It's not finished, yet. You can track the progress on this branch: https://github.com/tomikaa87/gree-remote/tree/feature/python-cli-script/PythonCLI

xman123 commented 4 years ago

Can I use it to set temperature on my gree ac, how? In this moment I just need that function...

tomikaa87 commented 4 years ago

I've finished with the initial implementation of the device control function of the script. You can use it in the following way:

  1. You need to scan your network with the script in search mode: python3 gree.py search -b <LAN broadcast address> If this succeeds, you should get a list of the devices found on your network. Each device has an ID, an IP address and a unique password. Make a note of these.

  2. You can read a parameter's value from a specific device like this: python3 gree.py get <parameter name> -c <device IP address> -k <device password> -i <device ID> If the command succeeds, you should see the value of the parameter.

  3. You can also set a value of a parameter: python3 gree.py set <parameter name> <value> -c <device IP address> -k <device password> -i <device ID> If the command succeeds, you should hear a beep from the unit.

The script can be found here: https://github.com/tomikaa87/gree-remote/blob/feature/python-cli-script/PythonCLI/gree.py It requires Python 3 to run.

xman123 commented 4 years ago

Great, I`ll test it, thanks.

dulemis commented 4 years ago

Hi!

Could you please adapt this script so it doesnt use pycrypto? For one, i'm having issues installing it, and second everywhere I read it states that pycrypto is compromised and not developing anymore.

tomikaa87 commented 4 years ago

@dulemis hi, i've updated the script, it now uses cryptography instead of pycrypto. You should be able to install it with python3 -m pip install cryptography. I've tested it, works fine in my environment.

dulemis commented 4 years ago

Super, thank you very much!

Do you have any idea why I get following error?

pip install cryptography

Collecting cryptography Using cached cryptography-2.9.tar.gz (517 kB) Installing build dependencies ... \^[[B^[[B^[[error ERROR: Command errored out with exit status 1: command: /opt/bin/python3 /opt/lib/python3.7/site-packages/pip install --ignore-installed --no-user --prefix /opt/tmp/pip-build-env-t5jylq31/overlay --no-warn-script-location --no-binary :none: --only-binary :none: -i https://pypi.org/simple -- 'setuptools>=40.6.0' wheel 'cffi>=1.8,!=1.11.3; platform_python_implementation != '"'"'PyPy'"'"'' cwd: None Complete output (67 lines): Collecting setuptools>=40.6.0 Using cached setuptools-46.1.3-py3-none-any.whl (582 kB) Collecting wheel Using cached wheel-0.34.2-py2.py3-none-any.whl (26 kB) Collecting cffi!=1.11.3,>=1.8 Using cached cffi-1.14.0.tar.gz (463 kB) Collecting pycparser Using cached pycparser-2.20-py2.py3-none-any.whl (112 kB) Installing collected packages: setuptools, wheel, pycparser, cffi Running setup.py install for cffi: started Running setup.py install for cffi: finished with status 'error' ERROR: Command errored out with exit status 1: command: /opt/bin/python3 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/opt/tmp/pip-install-ow212_5a/cffi/setup.py'"'"'; file='"'"'/opt/tmp/pip-install-ow212_5a/cffi/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record /opt/tmp/pip-record-wa88xk/install-record.txt --single-version-externally-managed --prefix /opt/tmp/pip-build-env-t5jylq31/overlay --compile --install-headers /opt/tmp/pip-build-env-t5jylq31/overlay/include/python3.7/cffi cwd: /opt/tmp/pip-install-ow212_5a/cffi/ Complete output (50 lines): unable to execute 'arm-openwrt-linux-gnueabi-gcc': No such file or directory unable to execute 'arm-openwrt-linux-gnueabi-gcc': No such file or directory

      No working compiler found, or bogus compiler options passed to
      the compiler from Python's standard "distutils" module.  See
      the error messages above.  Likely, the problem is not related
      to CFFI but generic to the setup.py of any Python package that
      tries to compile C code.  (Hints: on OS/X 10.8, for errors about
      -mno-fused-madd see http://stackoverflow.com/questions/22313407/
      Otherwise, see https://wiki.python.org/moin/CompLangPython or
      the IRC channel #python on irc.freenode.net.)

      Trying to continue anyway.  If you are trying to install CFFI from
      a build done in a different context, you can ignore this warning.

  running install
  running build
  running build_py
  creating build
  creating build/lib.linux-armv7l-3.7
  creating build/lib.linux-armv7l-3.7/cffi
  copying cffi/cffi_opcode.py -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/error.py -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/pkgconfig.py -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/model.py -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/verifier.py -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/vengine_cpy.py -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/vengine_gen.py -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/__init__.py -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/recompiler.py -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/setuptools_ext.py -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/commontypes.py -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/cparser.py -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/lock.py -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/api.py -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/backend_ctypes.py -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/ffiplatform.py -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/_cffi_include.h -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/parse_c_type.h -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/_embedding.h -> build/lib.linux-armv7l-3.7/cffi
  copying cffi/_cffi_errors.h -> build/lib.linux-armv7l-3.7/cffi
  warning: build_py: byte-compiling is disabled, skipping.

  running build_ext
  building '_cffi_backend' extension
  creating build/temp.linux-armv7l-3.7
  creating build/temp.linux-armv7l-3.7/c
  arm-openwrt-linux-gnueabi-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -O2 -pipe -march=armv7-a -mtune=cortex-a9 -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -mfloat-abi=soft -O2 -pipe -march=armv7-a -mtune=cortex-a9 -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -mfloat-abi=soft -DNDEBUG -fno-inline -O2 -pipe -march=armv7-a -mtune=cortex-a9 -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -mfloat-abi=soft -DNDEBUG -fno-inline -I/media/ware/Entware.2019.10/staging_dir/target-arm_cortex-a9_glibc-2.23_eabi/opt/include -I/media/ware/Entware.2019.10/staging_dir/toolchain-arm_cortex-a9_gcc-7.4.0_glibc-2.23_eabi/include -fPIC -I/usr/include/ffi -I/usr/include/libffi -I/opt/include/python3.7 -c c/_cffi_backend.c -o build/temp.linux-armv7l-3.7/c/_cffi_backend.o
  unable to execute 'arm-openwrt-linux-gnueabi-gcc': No such file or directory
  error: command 'arm-openwrt-linux-gnueabi-gcc' failed with exit status 1
  ----------------------------------------

ERROR: Command errored out with exit status 1: /opt/bin/python3 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/opt/tmp/pip-install-ow212_5a/cffi/setup.py'"'"'; file='"'"'/opt/tmp/pip-install-ow212_5a/cffi/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record /opt/tmp/pip-record-wa88xk/install-record.txt --single-version-externally-managed --prefix /opt/tmp/pip-build-env-t5jylq31/overlay --compile --install-headers /opt/tmp/pip-build-env-t5jylq31/overlay/include/python3.7/cffi Check the logs for full command output.

ERROR: Command errored out with exit status 1: /opt/bin/python3 /opt/lib/python3.7/site-packages/pip install --ignore-installed --no-user --prefix /opt/tmp/pip-build-env-t5jylq31/overlay --no-warn-script-location --no-binary :none: --only-binary :none: -i https://pypi.org/simple -- 'setuptools>=40.6.0' wheel 'cffi>=1.8,!=1.11.3; platform_python_implementation != '"'"'PyPy'"'"'' Check the logs for full command output.

tomikaa87 commented 4 years ago

@dulemis according to this line: unable to execute 'arm-openwrt-linux-gnueabi-gcc': No such file or directory you don't have gcc on your openwrt device and the installer tries to compile the necessary components. You can try installing with static wheels: https://cryptography.io/en/latest/installation/

Edit: after a quick search I've found this: https://openwrt.org/packages/pkgdata/python-cryptography

dulemis commented 4 years ago

opkg install python3-cryptography

Installing python3-cryptography (2.8-1) to root... Downloading http://bin.entware.net/armv7sf-k2.6/python3-cryptography_2.8-1_armv7-2.6.ipk Configuring python3-cryptography.

python3 /jffs/gree.py search -b 10.1.1.63

Traceback (most recent call last): File "/jffs/gree.py", line 3, in from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes ModuleNotFoundError: No module named 'cryptography'

tomikaa87 commented 4 years ago

Maybe you can try to modify the script and load the module manually using a full path: https://stackoverflow.com/questions/67631/how-to-import-a-module-given-the-full-path

dulemis commented 4 years ago

Thank you! I seem to have continued issues with my environment. See below.

/jffs/gree.py

Traceback (most recent call last): File "/jffs/gree.py", line 5, in from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes ImportError: bad magic number in 'cryptography': b'U\r\r\n'

I noticed that cryptographt module is getting installed in a folder named pythhn3.8/site-packages, but my Python version is actually 3.7 and all my current files and packages are located in python3.7/site-packages. So I tried moving the cryptography folder to python3.7-folder, and then i started getting above magic number error...

dulemis commented 4 years ago

Please ignore my last post, i've upgraded to Python 3.8 now and then it works. However, ihere is the next issue:

/jffs/gree.py search -b 10.1.1.63

Searching for devices using broadcast address: 10.1.1.63 Traceback (most recent call last): File "/jffs/gree.py", line 188, in search_devices() File "/jffs/gree.py", line 82, in search_devices s.sendto(b'{"t":"scan"}', (args.broadcast, 7000)) PermissionError: [Errno 13] Permission denied

dulemis commented 4 years ago

I got to work by replacing the broadcast address with the actual IP of the Gree unit. Then I got the ID and key, so everything seems to work!

dulemis commented 4 years ago

Two more questions!

1 do you have the original version with pycrypto? Could you publish it I would like to test something.

  1. Is it possible to somehow send several cimmsnds/settings in one request?
sm4rk0 commented 4 years ago

Thank you @tomikaa87, I've managed to make this work, but had to set the broadcast param to the actual AC's IP. When I tried with 192.168.1.255 it gave me the same permission error as for @dulemis. This answer gives a hint, but I couldn't make it work because of lack of Python knowledge.

@dulemis You can easily tweak the Python code so it sends an array of more than one element of cols list for get_param or more than one element for both opt and p list in set_param. I'll make a pull request that enables printing more than one element (and avoid IndexError: list index out of range if there's no elements) in get_param. After that you can do a quick and dirty trick to get more than one param with get 'host", "name' even without changing the code.

sm4rk0 commented 4 years ago

BTW, @tomikaa87, you should update the script's URL with master branch instead of feature/... in this comment.

dulemis commented 4 years ago

Hi Marko,

Great find, I added s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) before s.settimeout(3) and now the broadcast search seem to work :)

However, I tried your changed code and it doesnt work to get/set multiple values in one request.

gree.py get Pow, SetTem -c 10.1.1.16 -k xxxxxxxxxx -i xxxxxxxxx Getting parameter: Pow,

sm4rk0 commented 4 years ago

You should use single and double quotes exactly as in example in order for that hack to work.

dulemis commented 4 years ago

Hello again @sm4rk0,

Okey, sorry I misunderstood, it does work now. However, the following doesnt:

gree.py set 'Pow 1", "SetTem 22'

dulemis commented 4 years ago

@tomikaa87 do you know if is it possible to retrieve the inside/outside temperature from the Gree unit somehow?

tomikaa87 commented 4 years ago

@dulemis unfortunately my device doesn't have that feature and I didn't manage to capture the related communication. If your device can do that and the mobile app show this temperature, you should try capturing the data. On android, you can use Packet Capture, or if you have a laptop and a pendrive, you can use Kali Linux live to capture WiFi communication. You can decrypt the data in the packets with the device-specific password.

grav commented 2 years ago

@tomikaa87 Script works great! Didn't notice your guide in this issue before now. Maybe you could add it to a README.md in the PythonCLI directory?

I also created my own guide fwiw: https://gist.github.com/grav/6004ded69263f54dc391c86adf20f89c

DeadF commented 2 years ago

Hello all got a Gree aircon and try to set gree.py script from @tomikaa87 under Jeedom Debian 10 aircon is already set in wifi network using EWPE smart control

root@jeedom:/var/www/html/plugins/script/data# ./gree.py search -b 192.168.170.109 Searching for devices using broadcast address: 192.168.170.109 Search finished, found 1 device(s) Binding device: 192.168.170.109 (c6xxxx60, ID: ) Traceback (most recent call last): File "./gree.py", line 213, in search_devices() File "./gree.py", line 113, in search_devices bind_device(r) File "./gree.py", line 123, in bind_device result = send_data(search_result.ip, 7000, bytes(request, encoding='utf-8')) File "./gree.py", line 37, in send_data return s.recv(1024) socket.timeout: timed out

seems does not return any unique ID .

Thanks for your great job.

tomikaa87 commented 2 years ago

@DeadF

Hi, I've updated the script to have a new --verbose switch to enable debug logging. Please try to run that and share the output here to find out why it can't detect the device ID of your unit.

DeadF commented 2 years ago

Hi tomikaa87 thanks for update. i use jeedom in proxmox VM. also try to create another ubuntu VM but still same result.

root@jeedom:/var/www/html/plugins/script/data# ./gree.py search -b 192.168.170.255 --verbose Searching for devices using broadcast address: 192.168.170.255 Search finished, found 0 device(s)

root@jeedom:/var/www/html/plugins/script/data# ./gree.py search -b 192.168.170.255 --verbose Searching for devices using broadcast address: 192.168.170.255 search_devices: resp={'t': 'pack', 'i': 1, 'uid': 0, 'cid': '502ccxxxxx60', 'tcid': '', 'pack': 'LP24Ek0OaYogxs3iQLjL4N9zkK6Z9KWVTRCvhRWqV8Q6Hcv+Un2MiFEJz3NDMsHEI/Pa9syFI0kYFCUeBNxq44+UmYq4E5g5QzzU+6/Qd+QbBAoXfR9+9YbpzBBkmy3uZtdFMALbzIQfSicO3KpLeXLpvz93fYRRHLTlg2Zgioxbb7w7uMPP71vKyFENZweODvEJeWbjZ/VwJNq+lUDDeRlndWQaq6aF/gj7M7NaYGZz2sTOyF/t3EXhqAlo/Ivz'}, pack={'t': 'dev', 'cid': '', 'bc': 'gree', 'catalog': 'gree', 'mid': '10001', 'model': 'gree', 'name': 'cxxxxx60', 'series': 'gree', 'vender': '1', 'ver': 'V1.2.1', 'brand': 'gree', 'mac': '502ccxxxxx60', 'lock': 0} Search finished, found 1 device(s) Binding device: 192.168.170.109 (cxxxxx60, ID: ) send_data: ip=192.168.170.109, port=7000, data=b'{"cid":"app","i":1,"t":"pack","uid":0,"tcid":"","pack":"6/DYYuNvtRtMP9mIBJNNhzSDZ337NlMJxh04RiPPNys="}' Traceback (most recent call last): File "./gree.py", line 238, in search_devices() File "./gree.py", line 118, in search_devices bind_device(r) File "./gree.py", line 128, in bind_device result = send_data(search_result.ip, 7000, bytes(request, encoding='utf-8')) File "./gree.py", line 39, in send_data return s.recv(1024) socket.timeout: timed out root@jeedom:/var/www/html/plugins/script/data#

tomikaa87 commented 2 years ago

I see the problem, the script looks for cid in pack, which is empty. I'll improve the logic by taking cid from resp in this case.

Edit: I've just updated the script, please try it again.

DeadF commented 2 years ago

now is ok ! thanks a lot!!!

Search finished, found 1 device(s) Binding device: 192.168.170.109 (cxxxxx60, ID: 502ccxxxxx60) Bind to 502ccxxxxx60 succeeded, key = xxxFt2H8mIy5wl4E

DeadF commented 2 years ago

Hi all

try to set time using gree.py script

doc said 👍

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

pack:

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

//getting time

./gree.py get "time" -c 192.168.170.109 -k Xupg56t27QP0da96 -i 502cc6744860 Getting parameters: time time = 2022-01-10 00:16:46<

//set time

root@jeedom:/var/www/html/plugins/script/data# ./gree.py set time="2022-01-10 20:53:00" -c 192.168.170.50 -k Xupg56t27QP0da96 -i 502cc6744860 --verbose Setting parameters: time=2022-01-10 20:53:00 {"opt":["time"],"p":[2022-01-10 20:53:00],"t":"cmd"} send_data: ip=192.168.170.50, port=7000, data=b'{"cid":"app","i":0,"pack":"0Nx4/wKaZRXlNXgwbplFhDfCpzpgcybXCdKBIytsB/ZFcbCSPfok0QyRHLM8GqEAfX2VPmAxdAx15I0NBbNlig==","t":"pack","tcid":"502ccxxxxx60","uid":0}' Traceback (most recent call last): File "./gree.py", line 253, in set_param() File "./gree.py", line 200, in set_param result = send_data(args.client, 7000, bytes(request, encoding='utf-8')) File "./gree.py", line 38, in send_data return s.recv(1024) socket.timeout: timed out

seems missing the sub:"Mac adress" option in pack data.

i also need to use the scheduling script which seems not implement into the py script. Was using on old wespoint aircon before and it was easy to set timer off . Just need to power on aircon ,then each time i click on timer off, it add 30 mn to the timer. on GREE it is just impossible. Would be great if can add scheduling option on the py script. will try to set a button on smart home system that will read the time,add 1 or 2 hour and send the scheduling to the aircon. so i can still keep my eyes closed and enjoy a fresh night .

thanks for all.

edit for setting time ,maybe can use something like this . duno anything about python, please apologize if weird coding as duno how handle if user send multi parameter too. but this work for me in set_param()

if {opts}=='time': pack = f'{{"opt":[{opts}],"p":[{ps}],"sub":"{args.id}","t":"cmd"}}' else : pack = f'{{"opt":[{opts}],"p":[{ps}],"t":"cmd"}}'

dulemis commented 2 months ago

EDIT: Never mind, seems as the script works even when leaving the ID empty.

My friend got two Gree units installed, but this script doesnt expose the IDs anymore? Maybe something have been changed in newer firmwares.

gree.py search -b 192.168.1.254 Searching for devices using broadcast address: 192.168.1.254 Search finished, found 2 device(s) Binding device: 192.168.1.60 (, ID: ) Bind to succeeded, key = FzL89lj12N5tJtrE Binding device: 192.168.1.15 (, ID: ) Bind to succeeded, key = 34hm552niW16O13o

tomikaa87 commented 2 months ago

My friend got two Gree units installed, but this script doesnt expose the IDs anymore?

Hi @dulemis,

I see that you've made the script work without the ID, but to verify the root cause of the issues, can you please run it with --verbose to show the detailed communication flow with the devices?

dulemis commented 2 months ago

My friend got two Gree units installed, but this script doesnt expose the IDs anymore?

Hi @dulemis,

I see that you've made the script work without the ID, but to verify the root cause of the issues, can you please run it with --verbose to show the detailed communication flow with the devices?

Yes, of course!

gree.py search -b 192.168.1.254 --verbose Searching for devices using broadcast address: 192.168.1.254 search_devices: resp={'t': 'pack', 'i': 1, 'uid': 0, 'cid': '', 'tcid': '', 'pack': 'LP24Ek0OaYogxs3iQLjL4PbSM9V07U8GBMw5utmV5qRles6v4xqRXPNcduCE97KK8mkVsn0iN/2xV4f3+2PwiM9tn1GbVG5G5VGBeQc5Sg1fcXkMzJbGj+ESgba57A6zRxAouqpFGUJHWejlldDxhiPz2vbMhSNJGBQlHgTcauOPlJmKuBOYOUM81Puv0HfkxBEW3Y1RAHG4Us5KEDstpA1AXR9IsVDWBspeCCbdOsqBHV3JTN/hW6UWDYaKUON0bAG+gcGI6kaWjSglact/LqYY7RZGKWNg79QeOCikWKAMzYH0YpoM9VagPCFsSYv8rB+mzRjHgZHIAgtr7yKleg=='}, pack={'t': 'dev', 'cid': '', 'bc': '00000000000000000000000000000000', 'brand': 'gree', 'catalog': 'gree', 'mac': '9424b868b54d', 'mid': '10001', 'model': 'gree', 'name': '', 'lock': 0, 'series': 'gree', 'vender': '1', 'ver': 'V3.0.0', 'hid': '362001065279+U-WB05RT13V1.16.bin'} search_devices: resp={'t': 'pack', 'i': 1, 'uid': 0, 'cid': '', 'tcid': '', 'pack': 'LP24Ek0OaYogxs3iQLjL4N9zkK6Z9KWVTRCvhRWqV8RSMznvK0I6J5Vht4wnw/X1SNF+v537AbMbcHUZ7w7/MJ59gW3AnMHS4VPzno9Y8tL2WDl06zFRWc9ET8T63MtKIUb9YF3pMA8Yz+Bm7o/lnwLVaKPB+vd4jEbOZqKgM7cprDLF6so1X0TWv6LubXKA4fHVl/jhRVQDoU3ZhMIE2stDah3Cb5uRy7W07SOEcNLpyhNX6ZNWv5dfVP60FBpD'}, pack={'t': 'dev', 'cid': '', 'bc': 'gree', 'brand': 'gree', 'catalog': 'gree', 'mac': '502cc6bcd1a0', 'mid': '10001', 'model': 'gree', 'name': '', 'lock': 0, 'series': 'gree', 'vender': '1', 'ver': 'V3.0.0'} Search finished, found 2 device(s) Binding device: 192.168.1.60 (, ID: ) send_data: ip=192.168.1.60, port=7000, data=b'{"cid":"app","i":1,"t":"pack","uid":0,"tcid":"","pack":"6/DYYuNvtRtMP9mIBJNNhzSDZ337NlMJxh04RiPPNys="}' bind_device: resp={'r': 200, 't': 'bindok', 'mac': '', 'key': 'FzL89lj12N5tJtrE'} Bind to succeeded, key = FzL89lj12N5tJtrE Binding device: 192.168.1.15 (, ID: ) send_data: ip=192.168.1.15, port=7000, data=b'{"cid":"app","i":1,"t":"pack","uid":0,"tcid":"","pack":"6/DYYuNvtRtMP9mIBJNNhzSDZ337NlMJxh04RiPPNys="}' bind_device: resp={'r': 200, 't': 'bindok', 'mac': '', 'key': '34hm552niW16O13o'} Bind to succeeded, key = 34hm552niW16O13o