Skip to content

[DNM] Gree Integration rewrite#373

Open
p-monteiro wants to merge 1 commit into
RobHofmann:4.0-pre-releasefrom
p-monteiro:gree-rewrite
Open

[DNM] Gree Integration rewrite#373
p-monteiro wants to merge 1 commit into
RobHofmann:4.0-pre-releasefrom
p-monteiro:gree-rewrite

Conversation

@p-monteiro
Copy link
Copy Markdown
Contributor

@p-monteiro p-monteiro commented Sep 23, 2025

Caution

This PR changes the domain of the integration, so current users will lose their device configs!
The config schema also changed, so verify your YAML if you use it to configure the devices.
This no longer overwrites the official integration.

This PR introduces a rewrite of this integration. The main goal of this was to better align the integration with the Home Assistant (HA) development workflow with two main changes:

  • Completely separate device API code from HA code
  • Align with code style guidelines (mainly Ruff code formatting and full typing)

Breaking changes

  • Major version bump
  • New domain for the integration
  • Configs have a different schema, devices need to be re-added
  • Translations need to be redone (can use the old ones, but need to be migrated to the new template)

Features

  • Device features are now user-configurable (automatic detection removed due to unreliable Gree API)
  • Async device communication via DataUpdateCoordinator
  • GreeDevice abstraction for device logic
  • Auto Encryption support
  • Expose all device sensors as entities
  • Add device fault detection support
  • Add diagnostics download for config entries and devices
  • Add option to set device temperature units (device display)
  • Add RestoreEntity support in ClimateEntity
  • Auto recovery of device IP

Improvements

  • Improve config flow with better validation and error handling
  • Allow reconfiguration of config entries (e.g., device IP changes)
  • Allow individual device removal
  • Make entity restore behavior configurable
  • Refactor Gree API to be fully declarative (remove string guessing)
  • Improve API structure and reuse of logic
  • Improve entity creation and organization

Fixes

  • Improve error handling across config flow and entity setup

Known problems:

  • Broken VRF Device Status (needs debugging, could be fixed later)

As you can see, there are a lot of changes, and I understand if this does not go through as is.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

@RobHofmann I was adding the temperature step back, but I'm not sure of its utility.
Is there any device that accepts non-integer ºC/ºF?

@domialex
Copy link
Copy Markdown
Contributor

@p-monteiro
The temperature step should not be in the configuration entities anyways, it should be in the climate options. That was a mistake on my part.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

Hi @domialex, that's fine. I'm more interested in the real use case for it. Should it be locked to integers? I don't think any device supports half degrees or even 0.1 steps, as is the lower limit for the current slider...

@meirlo
Copy link
Copy Markdown
Contributor

meirlo commented Oct 3, 2025

@p-monteiro I'm getting an error when trying to auto discovery (vrf).

This error originated from a custom integration.

Logger: custom_components.gree.gree_api
Source: custom_components/gree/gree_api.py:869
integration: Gree A/C (documentation)
First occurred: 1:44:19 PM (3 occurrences)
Last logged: 3:04:12 PM

Failed to fetch sub-devices
Traceback (most recent call last):
  File "/config/custom_components/gree/gree_api.py", line 931, in get_sub_devices_list
    result = await get_result_pack(
             ^^^^^^^^^^^^^^^^^^^^^^
    ...<7 lines>...
    )
    ^
  File "/config/custom_components/gree/gree_api.py", line 426, in get_result_pack
    data = await fetch_result(
           ^^^^^^^^^^^^^^^^^^^
    ...<7 lines>...
    )
    ^
  File "/config/custom_components/gree/gree_api.py", line 382, in fetch_result
    data = get_gree_response_data(received_json, cipher, encryption_version)
  File "/config/custom_components/gree/gree_api.py", line 401, in get_gree_response_data
    pack = decryptedPack.decode("utf-8")
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbb in position 3: invalid start byte

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree/gree_api.py", line 869, in discover_gree_devices
    discovered_sub_devices = await get_sub_devices_list(
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<5 lines>...
    )
    ^
  File "/config/custom_components/gree/gree_api.py", line 944, in get_sub_devices_list
    raise ValueError(f"Error fetching sub-device list for '{mac_addr}'") from err
ValueError: Error fetching sub-device list for '580d0d30225f'

@p-monteiro
Copy link
Copy Markdown
Contributor Author

@meirlo Thanks for the heads-up. Interestingly, I believe that bit is the same as the current version.
I've added a debug log before the faulty line to check the pack content. If you can, rerun again and provide the log output.

@meirlo
Copy link
Copy Markdown
Contributor

meirlo commented Oct 4, 2025

here is the same operation with the pack dump:

2025-10-04 22:34:32.911 DEBUG (MainThread) [custom_components.gree.gree_api] Fetching data from 192.168.69.10
2025-10-04 22:34:32.929 DEBUG (MainThread) [custom_components.gree.gree_api] Decoding pack: b'\x05wv\xbb\x04\x01\xeaur\xfa\xd1\xc8\xdew\x99\x82\\\x85#*\xef\xcc\x95\xdf^\xa4\xc5Ne\xeae\xaeI\x8e\xbfna\x13\xff\xbe|R\xac=\xf2{z\x97\x95\x95\xb3\xf5\xd1\xbe\xbe\xf0tn\x96\x1c\xca\xcf\xa5\x97\xc3\x18)\xdb\x0e3I\xbb,\xab\xcc\xdd\xe5\xa2o\xe6v#\x9f\x9b,\xb8\x10\x06\xd2\tk\xa3\xee5D4\xb1\xc9\xcf\x82L\xd44\xf3\xd8\xb6L\xc0\xdaB\xd4!\xeeB\x19\x1c\xbf\xc1\x1f\n>\xbf\x01\xd8\xc6\x9a\xde\xa6,\xfa\x81\xd0\xa1\x1a\xc0\x97\xbd\xa4\x9c/\xad\x88\xa9\xbaA\n\x17l\xa0\xd7\xdd\xc6"Z#\xdcY\x97=A'
2025-10-04 22:34:32.929 ERROR (MainThread) [custom_components.gree.gree_api] Failed to fetch sub-devices
Traceback (most recent call last):
  File "/config/custom_components/gree/gree_api.py", line 932, in get_sub_devices_list
    result = await get_result_pack(
             ^^^^^^^^^^^^^^^^^^^^^^
    ...<7 lines>...
    )
    ^
  File "/config/custom_components/gree/gree_api.py", line 427, in get_result_pack
    data = await fetch_result(
           ^^^^^^^^^^^^^^^^^^^
    ...<7 lines>...
    )
    ^
  File "/config/custom_components/gree/gree_api.py", line 382, in fetch_result
    data = get_gree_response_data(received_json, cipher, encryption_version)
  File "/config/custom_components/gree/gree_api.py", line 402, in get_gree_response_data
    pack = decryptedPack.decode("utf-8")
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbb in position 3: invalid start byte
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "/config/custom_components/gree/gree_api.py", line 870, in discover_gree_devices
    discovered_sub_devices = await get_sub_devices_list(
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<5 lines>...
    )
    ^
  File "/config/custom_components/gree/gree_api.py", line 945, in get_sub_devices_list
    raise ValueError(f"Error fetching sub-device list for '{mac_addr}'") from err
ValueError: Error fetching sub-device list for '580d0d30225f'

@p-monteiro
Copy link
Copy Markdown
Contributor Author

@meirlo Seems like it is obtaining a device key, and that key is not decrypting the pack correctly. I'll have to check in more detail. If you can debug further since I don't have a VRF, it'll be helpful.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

p-monteiro commented Oct 6, 2025

@RobHofmann @meirlo @domialex I'd like your input on some decisions that are blocking this.

  1. Since this is a big rewrite, I wonder if we should use it to bump the major version (4?) and possibly change the domain to not replace the official integration (as I saw in the bug reports that it might impose some problems). What do you think? This is blocking the config migration feature, as if we change the domain, there's no need to migrate. Users will need to re-add the devices.

  2. I was adding the temperature step back, but I'm not sure of its utility. Is there any device that accepts non-integer ºC/ºF? What's the practical use case here?

@meirlo
Copy link
Copy Markdown
Contributor

meirlo commented Oct 6, 2025

@meirlo Seems like it is obtaining a device key, and that key is not decrypting the pack correctly. I'll have to check in more detail. If you can debug further since I don't have a VRF, it'll be helpful.

the encryption key should the same for all the sub unit as it calculated only with the mac address (without the sub_mac_addr).
I'll try to find some time debug it further

update:
I think the get_sub_list command builds to command incorrectly,
in the master branch, the json to send is

        jsonPayloadToSend = (
            f'{{"cid": "app","i": 1,"pack": "{pack}","t":"**subList**","tcid":"{str(mac_addr)}","uid": 0}}'
        )
 where in this PR it resolves to `"t":"bind"`

I'm not sure if that's the only issue. as I don't have much time to test that currently.

@domialex
Copy link
Copy Markdown
Contributor

domialex commented Oct 6, 2025

@p-monteiro
Don't wait for my input, I'm a bit out of free time for GitHub at the moment.
Follow your instinct, it's easier to refactor with a major. Bump to 4, change the domain, remove the step. All of this can be adjusted eventually.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

@meirlo Good catch, I also noticed the subList request uses the default key and not the specific device key, so I also changed to that. Now I'm not sure if this works because the device key is actually the generic one, or the sublist requires the generic one.
I've updated the code. Please try whenever you can.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

I pushed the domain change, beware!

@RobHofmann
Copy link
Copy Markdown
Owner

@RobHofmann @meirlo @domialex I'd like your input on some decisions that are blocking this.

  1. Since this is a big rewrite, I wonder if we should use it to bump the major version (4?) and possibly change the domain to not replace the official integration (as I saw in the bug reports that it might impose some problems). What do you think? This is blocking the config migration feature, as if we change the domain, there's no need to migrate. Users will need to re-add the devices.
  2. I was adding the temperature step back, but I'm not sure of its utility. Is there any device that accepts non-integer ºC/ºF? What's the practical use case here?
  1. I think its good to take this into account if we are doing a big rewrite anyway, but you've already done it; so good.
  2. My device is able to step in 0,5 degrees (celcius).

@p-monteiro
Copy link
Copy Markdown
Contributor Author

2. My device is able to step in 0,5 degrees (celcius).

@RobHofmann Ah ok, I'll add it back. Would a bool for "Supports half increments" be better?

@RobHofmann
Copy link
Copy Markdown
Owner

2. My device is able to step in 0,5 degrees (celcius).

@RobHofmann Ah ok, I'll add it back. Would a bool for "Supports half increments" be better?

I would leave the steps option. people can then choose how to do this (even 0.1's are theoretically possible).

@p-monteiro
Copy link
Copy Markdown
Contributor Author

@RobHofmann I re-added the temperature step, but I limited it to 0.5 increments as the API only supports half ºC and integer ºF. A warning is logged if a non-integer ºF is set, since it is rounded to the nearest integer.

@meirlo
Copy link
Copy Markdown
Contributor

meirlo commented Oct 8, 2025

@meirlo Good catch, I also noticed the subList request uses the default key and not the specific device key, so I also changed to that. Now I'm not sure if this works because the device key is actually the generic one, or the sublist requires the generic one. I've updated the code. Please try whenever you can.

Sorry it took me a while, quite busy lately.
the subList now works, but I'm getting an error message when selecting the device:
image

here is the log:

2025-10-08 23:09:08.334 DEBUG (MainThread) [custom_components.gree.config_flow] Found broadcast addresses from HA: ['255.255.255.255']
2025-10-08 23:09:08.334 DEBUG (MainThread) [custom_components.gree.gree_api] Sending broadcast to 255.255.255.255
2025-10-08 23:09:08.334 DEBUG (MainThread) [custom_components.gree.gree_api] Sending broadcast to 192.168.255.255
2025-10-08 23:09:08.334 DEBUG (MainThread) [custom_components.gree.gree_api] Sending broadcast to 10.255.255.255
2025-10-08 23:09:08.335 DEBUG (MainThread) [custom_components.gree.gree_api] Sending broadcast to 172.31.255.255
2025-10-08 23:09:08.335 DEBUG (MainThread) [custom_components.gree.gree_api] Sent broadcast packets, waiting for replies... 
2025-10-08 23:09:13.404 DEBUG (MainThread) [custom_components.gree.gree_api] Got 2 responses in 5 seconds: {'192.168.69.11': '{"t":"pack","i":1,"uid":0,"cid":"","tcid":"","pack":"LP24Ek0OaYogxs3iQLjL4GxVgUZU3rtYupe1YWCCZzmMa9lM2RqI/KytvJ32IsGSZXrOr+MakVzzXHbghPeyiui/giRwi/22P1NeJSbhyoDt21IYC5nmTB0FSNCtGSQCCP/IZpjNt09zcc1aLtS4znlSqBQy8N/2MMZVqZoAQkkJPRFZzjLrUDkhvMjz32yVMkOVsFsTAafzePY7qSehbZIhsbG6Ck8X1+GBAEqEtdxSARmdHzsfl0hV7CQKMyULqf7+wHqDf2mz9uzNFv2ejQPpn0gG1yCMDrcqGdH2dZ87NZwcceL02wWBXsdkOjw4Ulrqi8VIr2r3Cmrm4wCp4K/UPK7Wvj+xDUBarOvvfc+86x4l/dRoudCtrydSECrA"}', '192.168.69.10': '{"t":"pack","cid":"580d0d30225f","tcid":"app","uid":0,"i":1,"pack":"bkVMP61MVBCj+bKj6Nc/0xEr+tLgPK36TXqIj6rcC74JTQTQIGpNxI8D1U8tSJB1pEr7RuJkLnXf1f/7trvXW5M3btthpc8M0pRZm6+g5N2LTf/WV/dAWpRvIRJkq16rT+A+pJrQeGdAWwN6kxXhvK/YNUtrUMnpV863TeyoLi2o90+ZgYyLoH1N26RgWIimQIoYkO/+w8rSr1nvVeJEc9vgCMb5UKzgzUy/KfaBXZXZgQaJ54sp4j+tIDgPXwVO"}\n'}
2025-10-08 23:09:13.404 DEBUG (MainThread) [custom_components.gree.gree_api] Decoding pack: b'{"t":"dev","cid":"c03937873cb5","bc":"00000000000000000000000000000000","brand":"gree","catalog":"gree","mac":"c03937873cb5","mid":"10001","model":"gree","name":"","lock":0,"series":"gree","vender":"1","ver":"V2.0.0","ModelType":"21200896","hid":"362001065279+U-WB05RT13V1.23.bin"}\x07\x07\x07\x07\x07\x07\x07'
2025-10-08 23:09:13.405 DEBUG (MainThread) [custom_components.gree.gree_api] Discovered device: GreeDiscoveredDevice(name='Gree 3cb5', host='192.168.69.11', mac='c03937873cb5', port=7000, brand='gree', model='gree', uid=0)
2025-10-08 23:09:13.405 DEBUG (MainThread) [custom_components.gree.gree_api] Decoding pack: b'{"t":"dev","bc":"","catalog":"gree","series":"gree","model":"gree","lock":0,"vender":"1","mid":"60","name":"GR-Gcloud_60_0a_225f_EC","ver":"V3.2.M","mac":"580d0d30225f","subCnt":4}\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c'
2025-10-08 23:09:13.405 DEBUG (MainThread) [custom_components.gree.gree_api] Trying to fetching sub-devices for '580d0d30225f' (subCount=4)
2025-10-08 23:09:13.405 INFO (MainThread) [custom_components.gree.gree_api] Trying to retrieve device encryption key v1
2025-10-08 23:09:13.405 DEBUG (MainThread) [custom_components.gree.gree_api] Bind Pack: {"mac": "580d0d30225f", "t": "bind", "uid": 0}
2025-10-08 23:09:13.405 DEBUG (MainThread) [custom_components.gree.gree_api] Fetching data from 192.168.69.10
2025-10-08 23:09:13.453 DEBUG (MainThread) [custom_components.gree.gree_api] Decoding pack: b'{"t":"bindOk","r":200,"mac":"580d0d30225f","key":"3de498fe6382a411"}\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c'
2025-10-08 23:09:13.453 DEBUG (MainThread) [custom_components.gree.gree_api] Got data from 192.168.69.10: {'t': 'pack', 'cid': '580d0d30225f', 'tcid': 'app', 'uid': 0, 'i': 1, 'pack': {'t': 'bindOk', 'r': 200, 'mac': '580d0d30225f', 'key': '3de498fe6382a411'}}
2025-10-08 23:09:13.453 INFO (MainThread) [custom_components.gree.gree_api] Fetched device encryption key with version 1 with success
2025-10-08 23:09:13.453 DEBUG (MainThread) [custom_components.gree.gree_api] Fetched encryption key: 3de498fe6382a411
2025-10-08 23:09:13.454 DEBUG (MainThread) [custom_components.gree.gree_api] Sub Bind Pack: {"mac": "580d0d30225f", "i": 1}
2025-10-08 23:09:13.456 DEBUG (MainThread) [custom_components.gree.gree_api] Fetching data from 192.168.69.10
2025-10-08 23:09:13.477 DEBUG (MainThread) [custom_components.gree.gree_api] Decoding pack: b'{"t":"subList","i":1,"c":4,"r":200,"list":[{"mac":"293b824d550000","mid":"608f"},{"mac":"69630f1e000000","mid":"605c"},{"mac":"57be8c4dce0000","mid":"608f"}]}\x02\x02'
2025-10-08 23:09:13.478 DEBUG (MainThread) [custom_components.gree.gree_api] Got data from 192.168.69.10: {'t': 'pack', 'cid': '580d0d30225f', 'tcid': 'app', 'uid': 0, 'i': 1, 'pack': {'t': 'subList', 'i': 1, 'c': 4, 'r': 200, 'list': [{'mac': '293b824d550000', 'mid': '608f'}, {'mac': '69630f1e000000', 'mid': '605c'}, {'mac': '57be8c4dce0000', 'mid': '608f'}]}}
2025-10-08 23:09:13.478 DEBUG (MainThread) [custom_components.gree.gree_api] Discovered sub-device: GreeDiscoveredDevice(name='GR-Gcloud_60_0a_225f_EC', host='192.168.69.10', mac='580d0d30225f', port=7000, brand='gree', model='gree', uid=0)
2025-10-08 23:09:13.478 DEBUG (MainThread) [custom_components.gree.gree_api] Discovered sub-device: GreeDiscoveredDevice(name='GR-Gcloud_60_0a_225f_EC', host='192.168.69.10', mac='580d0d30225f', port=7000, brand='gree', model='gree', uid=0)
2025-10-08 23:09:13.478 DEBUG (MainThread) [custom_components.gree.gree_api] Discovered sub-device: GreeDiscoveredDevice(name='GR-Gcloud_60_0a_225f_EC', host='192.168.69.10', mac='580d0d30225f', port=7000, brand='gree', model='gree', uid=0)
2025-10-08 23:09:19.483 INFO (MainThread) [custom_components.gree.gree_device] Initialize the GREE Device API for: 293b824d550000@580d0d30225f (192.168.69.10:7000)
2025-10-08 23:09:19.483 DEBUG (MainThread) [custom_components.gree.gree_device] Version: None, Key: 
2025-10-08 23:09:19.483 DEBUG (MainThread) [custom_components.gree.gree_device] Trying to get device status
2025-10-08 23:09:19.483 DEBUG (MainThread) [custom_components.gree.gree_api] Fetching data from 192.168.69.10
2025-10-08 23:09:19.492 DEBUG (MainThread) [custom_components.gree.gree_api] Decoding pack: b'{"t":"dev","bc":"","catalog":"gree","series":"gree","model":"gree","lock":0,"vender":"1","mid":"60","name":"GR-Gcloud_60_0a_225f_EC","ver":"V3.2.M","mac":"580d0d30225f","subCnt":4}\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c'
2025-10-08 23:09:19.492 DEBUG (MainThread) [custom_components.gree.gree_api] Got data from 192.168.69.10: {'t': 'pack', 'cid': '580d0d30225f', 'tcid': 'app', 'uid': 0, 'i': 1, 'pack': {'t': 'dev', 'bc': '', 'catalog': 'gree', 'series': 'gree', 'model': 'gree', 'lock': 0, 'vender': '1', 'mid': '60', 'name': 'GR-Gcloud_60_0a_225f_EC', 'ver': 'V3.2.M', 'mac': '580d0d30225f', 'subCnt': 4}}
2025-10-08 23:09:19.492 DEBUG (MainThread) [custom_components.gree.gree_api] {'t': 'dev', 'bc': '', 'catalog': 'gree', 'series': 'gree', 'model': 'gree', 'lock': 0, 'vender': '1', 'mid': '60', 'name': 'GR-Gcloud_60_0a_225f_EC', 'ver': 'V3.2.M', 'mac': '580d0d30225f', 'subCnt': 4}
2025-10-08 23:09:19.493 INFO (MainThread) [custom_components.gree.gree_device] No encryption key provided
2025-10-08 23:09:19.493 INFO (MainThread) [custom_components.gree.gree_api] Trying to retrieve device encryption key v1
2025-10-08 23:09:19.493 DEBUG (MainThread) [custom_components.gree.gree_api] Bind Pack: {"mac": "580d0d30225f", "t": "bind", "uid": 0}
2025-10-08 23:09:19.493 DEBUG (MainThread) [custom_components.gree.gree_api] Fetching data from 192.168.69.10
2025-10-08 23:09:19.504 DEBUG (MainThread) [custom_components.gree.gree_api] Decoding pack: b'{"t":"bindOk","r":200,"mac":"580d0d30225f","key":"3de498fe6382a411"}\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c'
2025-10-08 23:09:19.505 DEBUG (MainThread) [custom_components.gree.gree_api] Got data from 192.168.69.10: {'t': 'pack', 'cid': '580d0d30225f', 'tcid': 'app', 'uid': 0, 'i': 1, 'pack': {'t': 'bindOk', 'r': 200, 'mac': '580d0d30225f', 'key': '3de498fe6382a411'}}
2025-10-08 23:09:19.505 INFO (MainThread) [custom_components.gree.gree_api] Fetched device encryption key with version 1 with success
2025-10-08 23:09:19.505 DEBUG (MainThread) [custom_components.gree.gree_api] Fetched encryption key: 3de498fe6382a411
2025-10-08 23:09:19.505 DEBUG (MainThread) [custom_components.gree.gree_api] Trying to get device status
2025-10-08 23:09:19.505 DEBUG (MainThread) [custom_components.gree.gree_api] Status Pack: {"cols": ["Pow", "Mod", "WdSpd", "SetTem", "TemRec", "TemUn", "SwingLfRig", "SwUpDn", "Quiet", "Tur", "Air", "Blo", "Health", "SwhSlp", "SlpMod", "Lig", "StHt", "SvSt", "AntiDirectBlow", "LigSen", "TemSen", "OutEnvTem", "DwatSen", "HeatCoolType"], "mac": "293b824d550000", "t": "status"}
2025-10-08 23:09:19.505 DEBUG (MainThread) [custom_components.gree.gree_api] Fetching data from 192.168.69.10
2025-10-08 23:09:19.534 DEBUG (MainThread) [custom_components.gree.gree_api] Decoding pack: b'{"t":"dat","mac":"293b824d550000","cols":["Pow","Mod","WdSpd","SetTem","TemRec","TemUn","SwingLfRig","SwUpDn","Quiet","Tur","Air","Blo","Health","SwhSlp","SlpMod","Lig","StHt","SvSt","AntiDirectBlow","LigSen","TemSen","OutEnvTem","DwatSen","HeatCoolType"],"dat":[0,1,0,24,"","",0,0,0,0,0,0,"",0,"","","",0,"","","","","",""],"r":200}\x03\x03\x03'
2025-10-08 23:09:19.534 DEBUG (MainThread) [custom_components.gree.gree_api] Got data from 192.168.69.10: {'t': 'pack', 'cid': '580d0d30225f', 'tcid': 'app', 'uid': 0, 'i': 0, 'pack': {'t': 'dat', 'mac': '293b824d550000', 'cols': ['Pow', 'Mod', 'WdSpd', 'SetTem', 'TemRec', 'TemUn', 'SwingLfRig', 'SwUpDn', 'Quiet', 'Tur', 'Air', 'Blo', 'Health', 'SwhSlp', 'SlpMod', 'Lig', 'StHt', 'SvSt', 'AntiDirectBlow', 'LigSen', 'TemSen', 'OutEnvTem', 'DwatSen', 'HeatCoolType'], 'dat': [0, 1, 0, 24, '', '', 0, 0, 0, 0, 0, 0, '', 0, '', '', '', 0, '', '', '', '', '', ''], 'r': 200}}
2025-10-08 23:09:21.064 INFO (MainThread) [custom_components.gree.gree_device] Initialize the GREE Device API for: 293b824d550000@580d0d30225f (192.168.69.10:7000)
2025-10-08 23:09:21.064 DEBUG (MainThread) [custom_components.gree.gree_device] Version: None, Key: 
2025-10-08 23:09:21.064 DEBUG (MainThread) [custom_components.gree.gree_device] Trying to get device status
2025-10-08 23:09:21.064 DEBUG (MainThread) [custom_components.gree.gree_api] Fetching data from 192.168.69.10
2025-10-08 23:09:21.080 DEBUG (MainThread) [custom_components.gree.gree_api] Decoding pack: b'{"t":"dev","bc":"","catalog":"gree","series":"gree","model":"gree","lock":0,"vender":"1","mid":"60","name":"GR-Gcloud_60_0a_225f_EC","ver":"V3.2.M","mac":"580d0d30225f","subCnt":4}\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c'
2025-10-08 23:09:21.080 DEBUG (MainThread) [custom_components.gree.gree_api] Got data from 192.168.69.10: {'t': 'pack', 'cid': '580d0d30225f', 'tcid': 'app', 'uid': 0, 'i': 1, 'pack': {'t': 'dev', 'bc': '', 'catalog': 'gree', 'series': 'gree', 'model': 'gree', 'lock': 0, 'vender': '1', 'mid': '60', 'name': 'GR-Gcloud_60_0a_225f_EC', 'ver': 'V3.2.M', 'mac': '580d0d30225f', 'subCnt': 4}}
2025-10-08 23:09:21.080 DEBUG (MainThread) [custom_components.gree.gree_api] {'t': 'dev', 'bc': '', 'catalog': 'gree', 'series': 'gree', 'model': 'gree', 'lock': 0, 'vender': '1', 'mid': '60', 'name': 'GR-Gcloud_60_0a_225f_EC', 'ver': 'V3.2.M', 'mac': '580d0d30225f', 'subCnt': 4}
2025-10-08 23:09:21.080 INFO (MainThread) [custom_components.gree.gree_device] No encryption key provided
2025-10-08 23:09:21.080 INFO (MainThread) [custom_components.gree.gree_api] Trying to retrieve device encryption key v1
2025-10-08 23:09:21.080 DEBUG (MainThread) [custom_components.gree.gree_api] Bind Pack: {"mac": "580d0d30225f", "t": "bind", "uid": 0}
2025-10-08 23:09:21.081 DEBUG (MainThread) [custom_components.gree.gree_api] Fetching data from 192.168.69.10
2025-10-08 23:09:21.094 DEBUG (MainThread) [custom_components.gree.gree_api] Decoding pack: b'{"t":"bindOk","r":200,"mac":"580d0d30225f","key":"3de498fe6382a411"}\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c'
2025-10-08 23:09:21.094 DEBUG (MainThread) [custom_components.gree.gree_api] Got data from 192.168.69.10: {'t': 'pack', 'cid': '580d0d30225f', 'tcid': 'app', 'uid': 0, 'i': 1, 'pack': {'t': 'bindOk', 'r': 200, 'mac': '580d0d30225f', 'key': '3de498fe6382a411'}}
2025-10-08 23:09:21.094 INFO (MainThread) [custom_components.gree.gree_api] Fetched device encryption key with version 1 with success
2025-10-08 23:09:21.094 DEBUG (MainThread) [custom_components.gree.gree_api] Fetched encryption key: 3de498fe6382a411
2025-10-08 23:09:21.095 DEBUG (MainThread) [custom_components.gree.gree_api] Trying to get device status
2025-10-08 23:09:21.095 DEBUG (MainThread) [custom_components.gree.gree_api] Status Pack: {"cols": ["Pow", "Mod", "WdSpd", "SetTem", "TemRec", "TemUn", "SwingLfRig", "SwUpDn", "Quiet", "Tur", "Air", "Blo", "Health", "SwhSlp", "SlpMod", "Lig", "StHt", "SvSt", "AntiDirectBlow", "LigSen", "TemSen", "OutEnvTem", "DwatSen", "HeatCoolType"], "mac": "293b824d550000", "t": "status"}
2025-10-08 23:09:21.095 DEBUG (MainThread) [custom_components.gree.gree_api] Fetching data from 192.168.69.10
2025-10-08 23:09:21.122 DEBUG (MainThread) [custom_components.gree.gree_api] Decoding pack: b'{"t":"dat","mac":"293b824d550000","cols":["Pow","Mod","WdSpd","SetTem","TemRec","TemUn","SwingLfRig","SwUpDn","Quiet","Tur","Air","Blo","Health","SwhSlp","SlpMod","Lig","StHt","SvSt","AntiDirectBlow","LigSen","TemSen","OutEnvTem","DwatSen","HeatCoolType"],"dat":[0,1,0,24,"","",0,0,0,0,0,0,"",0,"","","",0,"","","","","",""],"r":200}\x03\x03\x03'
2025-10-08 23:09:21.122 DEBUG (MainThread) [custom_components.gree.gree_api] Got data from 192.168.69.10: {'t': 'pack', 'cid': '580d0d30225f', 'tcid': 'app', 'uid': 0, 'i': 0, 'pack': {'t': 'dat', 'mac': '293b824d550000', 'cols': ['Pow', 'Mod', 'WdSpd', 'SetTem', 'TemRec', 'TemUn', 'SwingLfRig', 'SwUpDn', 'Quiet', 'Tur', 'Air', 'Blo', 'Health', 'SwhSlp', 'SlpMod', 'Lig', 'StHt', 'SvSt', 'AntiDirectBlow', 'LigSen', 'TemSen', 'OutEnvTem', 'DwatSen', 'HeatCoolType'], 'dat': [0, 1, 0, 24, '', '', 0, 0, 0, 0, 0, 0, '', 0, '', '', '', 0, '', '', '', '', '', ''], 'r': 200}}

Please let me know if you have an idea where the issue is, or need me to debug further.
Thanks for investing time on that, really appreciate your's (and everyone else) efforts to support VRF

@p-monteiro
Copy link
Copy Markdown
Contributor Author

@meirlo Thanks for your patience with us.
I've improved the debug and some typos to actually surface the error in the logs.
I suspect now you will be able to add the device, but will have errors while using it.
Either way, please post the logs whenever you can.

@meirlo
Copy link
Copy Markdown
Contributor

meirlo commented Oct 9, 2025

here is the next error :)
image

2025-10-09 10:49:07.378 DEBUG (MainThread) [custom_components.gree] Setting up entry: <ConfigEntry entry_id=01K73Z08C98C2VCNE7CG496V3X version=2 domain=gree_custom title=GR-Gcloud_60_0a_225f_EC@293b state=ConfigEntryState.SETUP_IN_PROGRESS unique_id=293b824d550000>
{'name': 'GR-Gcloud_60_0a_225f_EC@293b', 'host': '192.168.69.10', 'mac': '293b824d550000@580d0d30225f', 'advanced': {'port': 7000, 'encryption_version': <EncryptionVersion.V1: 1>, 'encryption_key': '3de498fe6382a411', 'uid': 0, 'disable_available_check': False, 'max_online_attempts': 5, 'timeout': 10}, 'hvac_modes': ['auto', 'cool', 'dry', 'fan_only', 'heat', 'off'], 'fan_modes': ['Auto', 'Low', 'MediumLow', 'Medium', 'MediumHigh', 'High', 'turbo', 'quiet'], 'swing_modes': ['Default', 'FullSwing', 'FixedUpper', 'FixedUpperMiddle', 'FixedMiddle', 'FixedLowerMiddle', 'FixedLower', 'SwingLower', 'SwingLowerMiddle', 'SwingMiddle', 'SwingUpperMiddle', 'SwingUpper'], 'swing_horizontal_modes': ['Default', 'FullSwing', 'Left', 'LeftCenter', 'Center', 'RightCenter', 'Right'], 'features': ['beeper', 'air', 'xfan', 'sleep', 'eightdegheat', 'lights', 'health', 'anti_direct_blow', 'powersave', 'light_sensor'], 'target_temp_step': 1.0, 'external_temperature_sensor': 'None', 'external_humidity_sensor': 'None', 'restore_states': True}
2025-10-09 10:49:07.378 INFO (MainThread) [custom_components.gree.gree_device] Initialize the GREE Device API for: 293b824d550000@580d0d30225f (192.168.69.10:7000)
2025-10-09 10:49:07.378 DEBUG (MainThread) [custom_components.gree.gree_device] Version: 1, Key: 3de49
2025-10-09 10:49:07.378 DEBUG (MainThread) [custom_components.gree.gree_api] Fetching data from 192.168.69.10
2025-10-09 10:49:07.391 DEBUG (MainThread) [custom_components.gree.gree_api] Decoding pack: b'{"t":"dev","bc":"","catalog":"gree","series":"gree","model":"gree","lock":0,"vender":"1","mid":"60","name":"GR-Gcloud_60_0a_225f_EC","ver":"V3.2.M","mac":"580d0d30225f","subCnt":4}\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c'
2025-10-09 10:49:07.391 DEBUG (MainThread) [custom_components.gree.gree_api] Got data from 192.168.69.10: {'t': 'pack', 'cid': '580d0d30225f', 'tcid': 'app', 'uid': 0, 'i': 1, 'pack': {'t': 'dev', 'bc': '', 'catalog': 'gree', 'series': 'gree', 'model': 'gree', 'lock': 0, 'vender': '1', 'mid': '60', 'name': 'GR-Gcloud_60_0a_225f_EC', 'ver': 'V3.2.M', 'mac': '580d0d30225f', 'subCnt': 4}}
2025-10-09 10:49:07.391 DEBUG (MainThread) [custom_components.gree.gree_api] {'t': 'dev', 'bc': '', 'catalog': 'gree', 'series': 'gree', 'model': 'gree', 'lock': 0, 'vender': '1', 'mid': '60', 'name': 'GR-Gcloud_60_0a_225f_EC', 'ver': 'V3.2.M', 'mac': '580d0d30225f', 'subCnt': 4}
2025-10-09 10:49:07.391 INFO (MainThread) [custom_components.gree.gree_device] Using the provided encryption key with version 1
2025-10-09 10:49:07.391 DEBUG (MainThread) [custom_components.gree] Bound to device 192.168.69.10
2025-10-09 10:49:07.392 DEBUG (MainThread) [custom_components.gree.gree_device] Trying to get device status
2025-10-09 10:49:07.392 DEBUG (MainThread) [custom_components.gree.gree_api] Trying to get device status
2025-10-09 10:49:07.392 DEBUG (MainThread) [custom_components.gree.gree_api] Status Pack: {"cols": ["Pow", "Mod", "WdSpd", "SetTem", "TemRec", "TemUn", "SwingLfRig", "SwUpDn", "Quiet", "Tur", "Air", "Blo", "Health", "SwhSlp", "SlpMod", "Lig", "StHt", "SvSt", "AntiDirectBlow", "LigSen", "TemSen", "OutEnvTem", "DwatSen", "HeatCoolType"], "mac": "293b824d550000", "t": "status"}
2025-10-09 10:49:07.392 DEBUG (MainThread) [custom_components.gree.gree_api] Payload: {'cid': 'app', 'i': 0, 'pack': 'rZ8nuCEJpoBu9vx086El1RSlbVikgZfPvjPf25P1+DHJPwAdkGW83HJT5abT6TQegRcAvA+oPIL9kXRTSYzjpb6nQJhHxz+YnRx94uW0AMu08lLB3tsGKBLEmuXb5+227wRXS/txAIUehIfUyxBACriWqq+oEYiIcFjj/JyuNhTet4NWL+fArjVUEDRohEV7R+O6ri6vzyp/b/6tz9M1zd6usC/J/Dv/WO2RPJkoDucFnTnNMd8GFpKi4r/IpjVTREiM+QSzNYplEq+nN/xE3QfEK8F9NuvUmZNuVs8gtHhgeJYpxoevfG1lwclfW5lM+LYlxEgOqV09fJzfRkE1eoXCT/rAP8tT2X1faBzfQv7ay1B/8b6/9TXbJ/tGwkaY', 't': 'pack', 'tcid': '580d0d30225f', 'uid': 0}
2025-10-09 10:49:07.392 DEBUG (MainThread) [custom_components.gree.gree_api] Fetching data from 192.168.69.10
2025-10-09 10:49:07.420 DEBUG (MainThread) [custom_components.gree.gree_api] Decoding pack: b'{"t":"dat","mac":"293b824d550000","cols":["Pow","Mod","WdSpd","SetTem","TemRec","TemUn","SwingLfRig","SwUpDn","Quiet","Tur","Air","Blo","Health","SwhSlp","SlpMod","Lig","StHt","SvSt","AntiDirectBlow","LigSen","TemSen","OutEnvTem","DwatSen","HeatCoolType"],"dat":[0,1,0,24,"","",0,0,0,0,0,0,"",0,"","","",0,"","","","","",""],"r":200}\x03\x03\x03'
2025-10-09 10:49:07.421 DEBUG (MainThread) [custom_components.gree.gree_api] Got data from 192.168.69.10: {'t': 'pack', 'cid': '580d0d30225f', 'tcid': 'app', 'uid': 0, 'i': 0, 'pack': {'t': 'dat', 'mac': '293b824d550000', 'cols': ['Pow', 'Mod', 'WdSpd', 'SetTem', 'TemRec', 'TemUn', 'SwingLfRig', 'SwUpDn', 'Quiet', 'Tur', 'Air', 'Blo', 'Health', 'SwhSlp', 'SlpMod', 'Lig', 'StHt', 'SvSt', 'AntiDirectBlow', 'LigSen', 'TemSen', 'OutEnvTem', 'DwatSen', 'HeatCoolType'], 'dat': [0, 1, 0, 24, '', '', 0, 0, 0, 0, 0, 0, '', 0, '', '', '', 0, '', '', '', '', '', ''], 'r': 200}}
2025-10-09 10:49:07.421 DEBUG (MainThread) [custom_components.gree.coordinator] Finished fetching Gree Coordinator 293b824d550000 data in 0.029 seconds (success: False)
2025-10-09 10:49:27.723 DEBUG (MainThread) [custom_components.gree] Setting up entry: <ConfigEntry entry_id=01K73Z08C98C2VCNE7CG496V3X version=2 domain=gree_custom title=GR-Gcloud_60_0a_225f_EC@293b state=ConfigEntryState.SETUP_IN_PROGRESS unique_id=293b824d550000>
{'name': 'GR-Gcloud_60_0a_225f_EC@293b', 'host': '192.168.69.10', 'mac': '293b824d550000@580d0d30225f', 'advanced': {'port': 7000, 'encryption_version': <EncryptionVersion.V1: 1>, 'encryption_key': '3de498fe6382a411', 'uid': 0, 'disable_available_check': False, 'max_online_attempts': 5, 'timeout': 10}, 'hvac_modes': ['auto', 'cool', 'dry', 'fan_only', 'heat', 'off'], 'fan_modes': ['Auto', 'Low', 'MediumLow', 'Medium', 'MediumHigh', 'High', 'turbo', 'quiet'], 'swing_modes': ['Default', 'FullSwing', 'FixedUpper', 'FixedUpperMiddle', 'FixedMiddle', 'FixedLowerMiddle', 'FixedLower', 'SwingLower', 'SwingLowerMiddle', 'SwingMiddle', 'SwingUpperMiddle', 'SwingUpper'], 'swing_horizontal_modes': ['Default', 'FullSwing', 'Left', 'LeftCenter', 'Center', 'RightCenter', 'Right'], 'features': ['beeper', 'air', 'xfan', 'sleep', 'eightdegheat', 'lights', 'health', 'anti_direct_blow', 'powersave', 'light_sensor'], 'target_temp_step': 1.0, 'external_temperature_sensor': 'None', 'external_humidity_sensor': 'None', 'restore_states': True}
2025-10-09 10:49:27.723 INFO (MainThread) [custom_components.gree.gree_device] Initialize the GREE Device API for: 293b824d550000@580d0d30225f (192.168.69.10:7000)
2025-10-09 10:49:27.723 DEBUG (MainThread) [custom_components.gree.gree_device] Version: 1, Key: 3de49
2025-10-09 10:49:27.723 DEBUG (MainThread) [custom_components.gree.gree_api] Fetching data from 192.168.69.10
2025-10-09 10:49:27.741 DEBUG (MainThread) [custom_components.gree.gree_api] Decoding pack: b'{"t":"dev","bc":"","catalog":"gree","series":"gree","model":"gree","lock":0,"vender":"1","mid":"60","name":"GR-Gcloud_60_0a_225f_EC","ver":"V3.2.M","mac":"580d0d30225f","subCnt":4}\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c'
2025-10-09 10:49:27.741 DEBUG (MainThread) [custom_components.gree.gree_api] Got data from 192.168.69.10: {'t': 'pack', 'cid': '580d0d30225f', 'tcid': 'app', 'uid': 0, 'i': 1, 'pack': {'t': 'dev', 'bc': '', 'catalog': 'gree', 'series': 'gree', 'model': 'gree', 'lock': 0, 'vender': '1', 'mid': '60', 'name': 'GR-Gcloud_60_0a_225f_EC', 'ver': 'V3.2.M', 'mac': '580d0d30225f', 'subCnt': 4}}
2025-10-09 10:49:27.741 DEBUG (MainThread) [custom_components.gree.gree_api] {'t': 'dev', 'bc': '', 'catalog': 'gree', 'series': 'gree', 'model': 'gree', 'lock': 0, 'vender': '1', 'mid': '60', 'name': 'GR-Gcloud_60_0a_225f_EC', 'ver': 'V3.2.M', 'mac': '580d0d30225f', 'subCnt': 4}
2025-10-09 10:49:27.741 INFO (MainThread) [custom_components.gree.gree_device] Using the provided encryption key with version 1
2025-10-09 10:49:27.741 DEBUG (MainThread) [custom_components.gree] Bound to device 192.168.69.10
2025-10-09 10:49:27.741 DEBUG (MainThread) [custom_components.gree.gree_device] Trying to get device status
2025-10-09 10:49:27.741 DEBUG (MainThread) [custom_components.gree.gree_api] Trying to get device status
2025-10-09 10:49:27.741 DEBUG (MainThread) [custom_components.gree.gree_api] Status Pack: {"cols": ["Pow", "Mod", "WdSpd", "SetTem", "TemRec", "TemUn", "SwingLfRig", "SwUpDn", "Quiet", "Tur", "Air", "Blo", "Health", "SwhSlp", "SlpMod", "Lig", "StHt", "SvSt", "AntiDirectBlow", "LigSen", "TemSen", "OutEnvTem", "DwatSen", "HeatCoolType"], "mac": "293b824d550000", "t": "status"}
2025-10-09 10:49:27.742 DEBUG (MainThread) [custom_components.gree.gree_api] Payload: {'cid': 'app', 'i': 0, 'pack': 'rZ8nuCEJpoBu9vx086El1RSlbVikgZfPvjPf25P1+DHJPwAdkGW83HJT5abT6TQegRcAvA+oPIL9kXRTSYzjpb6nQJhHxz+YnRx94uW0AMu08lLB3tsGKBLEmuXb5+227wRXS/txAIUehIfUyxBACriWqq+oEYiIcFjj/JyuNhTet4NWL+fArjVUEDRohEV7R+O6ri6vzyp/b/6tz9M1zd6usC/J/Dv/WO2RPJkoDucFnTnNMd8GFpKi4r/IpjVTREiM+QSzNYplEq+nN/xE3QfEK8F9NuvUmZNuVs8gtHhgeJYpxoevfG1lwclfW5lM+LYlxEgOqV09fJzfRkE1eoXCT/rAP8tT2X1faBzfQv7ay1B/8b6/9TXbJ/tGwkaY', 't': 'pack', 'tcid': '580d0d30225f', 'uid': 0}
2025-10-09 10:49:27.742 DEBUG (MainThread) [custom_components.gree.gree_api] Fetching data from 192.168.69.10
2025-10-09 10:49:27.784 DEBUG (MainThread) [custom_components.gree.gree_api] Decoding pack: b'{"t":"dat","mac":"293b824d550000","cols":["Pow","Mod","WdSpd","SetTem","TemRec","TemUn","SwingLfRig","SwUpDn","Quiet","Tur","Air","Blo","Health","SwhSlp","SlpMod","Lig","StHt","SvSt","AntiDirectBlow","LigSen","TemSen","OutEnvTem","DwatSen","HeatCoolType"],"dat":[0,1,0,24,"","",0,0,0,0,0,0,"",0,"","","",0,"","","","","",""],"r":200}\x03\x03\x03'
2025-10-09 10:49:27.784 DEBUG (MainThread) [custom_components.gree.gree_api] Got data from 192.168.69.10: {'t': 'pack', 'cid': '580d0d30225f', 'tcid': 'app', 'uid': 0, 'i': 0, 'pack': {'t': 'dat', 'mac': '293b824d550000', 'cols': ['Pow', 'Mod', 'WdSpd', 'SetTem', 'TemRec', 'TemUn', 'SwingLfRig', 'SwUpDn', 'Quiet', 'Tur', 'Air', 'Blo', 'Health', 'SwhSlp', 'SlpMod', 'Lig', 'StHt', 'SvSt', 'AntiDirectBlow', 'LigSen', 'TemSen', 'OutEnvTem', 'DwatSen', 'HeatCoolType'], 'dat': [0, 1, 0, 24, '', '', 0, 0, 0, 0, 0, 0, '', 0, '', '', '', 0, '', '', '', '', '', ''], 'r': 200}}
2025-10-09 10:49:27.784 DEBUG (MainThread) [custom_components.gree.coordinator] Finished fetching Gree Coordinator 293b824d550000 data in 0.043 seconds (success: False)

BTW, I see that this integration does not override the official integration anymore and also the Gree logo is missing.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

p-monteiro commented Oct 9, 2025

BTW, I see that this integration does not override the official integration anymore and also the Gree logo is missing.

@meirlo

That is intended. Once we go through with this PR, we can PR the logo on the official custom integration brands.

About the error, as predicted, the device was added, but now it is failing to get the status, which is weird since the log shows that it receives the status correctly, and there is no exception logged. I'll check later.

Update: Actually, I see that some important fields are blank. Do you happen to know if some of the properties are given by the main device while others are given by the subdevices? That can explain the problem. Also, can you provide screenshots of how the official app organizes the settings for the VRF?

Comment thread custom_components/gree_custom/gree_api.py Outdated
@meirlo
Copy link
Copy Markdown
Contributor

meirlo commented Oct 12, 2025

Screenshot_20251012_142342_GREE+

The office AC is the only standalone one and is not part of the vrf system.

The living room is the main one, meaning it controls the cool/heat setting for all the vrf ac (since there only a single outdoor unit, it's impossible to set some indoor units to cool and some to heating), it is possible to change this setting for other ac units, but it will revert to Fan mode if that's conflict with the main ac.

Here are some screenshots from the bedroom ac:

Screenshot_20251012_142423_GREE+ Screenshot_20251012_142410_GREE+ Screenshot_20251012_142359_GREE+

Please let me know if you want a screenshot from a specific ac/page

@p-monteiro
Copy link
Copy Markdown
Contributor Author

p-monteiro commented Oct 12, 2025

@meirlo Thanks for the screenshots, I'm having a bit of a hard time understanding the options, not gonna lie.

More importantly, how would you expect the controls to work in Home Assistant in terms of devices and the controls they provide?
For example, would you prefer for all controls to be in all devices and when changing it goes to the fan (as you said), or the subdevices override the main device, or the controls not show for the subdevices, or another thing?

@meirlo
Copy link
Copy Markdown
Contributor

meirlo commented Oct 12, 2025

@p-monteiro does it looks different on your ac?
Because the standalone ac and the vrf looks very similar.
If some setting is not clear please let me know.

In home assistant, I believe each unit needs to be a separate device, with its own settings. similar to how it shows in the gree+ app.

The limitation of the mode that must be set on the main unit first, can be ignored.
It is possible to set a mode that conflicts with the main with the gree app or even the ac.

if one want to sync between the mode in all ac it can be done via automation, no need to over complicate the integration.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

@meirlo The thing is, at first glance, the subdevices API does not provide some of the parameters that you want (they came empty in the status pack, but it needs to be further investigated), so maybe the official app sends commands to both the subunit and the main unit when you change the mode on the subunit. If that's the case, it can actually be easier to make the subunits override the main one, or just omit the properties altogether.

I just pushed a commit, please try it, and check if the main device can be discovered, added and it works. Ignore the subunits for a moment hehe

@p-monteiro
Copy link
Copy Markdown
Contributor Author

This might need some architectural changes in the way we communicate with the device (possibly to communicate with the main and sub devices for getting and setting the status)

@p-monteiro
Copy link
Copy Markdown
Contributor Author

@meirlo Another thing, in a VRF system all units are the same as the main one right? So the capabilities of them all are the same.

@meirlo
Copy link
Copy Markdown
Contributor

meirlo commented Oct 15, 2025

I'm getting an error when trying to add the entity without the sub unit

Logger: custom_components.gree.climate
Source: custom_components/gree/climate.py:846
integration: gree (documentation, issues)
First occurred: 5:37:20 PM (1 occurrence)
Last logged: 5:37:20 PM

Error in 'async_set_temperature'
Traceback (most recent call last):
  File "/config/custom_components/gree/gree_api.py", line 372, in fetch_result
    received_json = await udp_request_async(
                    ^^^^^^^^^^^^^^^^^^^^^^^^
        ip_addr, port, json_data, max_connection_attempts, timeout
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/config/custom_components/gree/gree_api.py", line 302, in udp_request_async
    raise ValueError(
        f"Failed to communicate with device '{ip_addr}:{port}' after {max_retries} attempts"
    )
ValueError: Failed to communicate with device '192.168.69.10:7000' after 5 attempts

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree/gree_api.py", line 719, in gree_set_status
    result = await get_result_pack(
             ^^^^^^^^^^^^^^^^^^^^^^
    ...<7 lines>...
    )
    ^
  File "/config/custom_components/gree/gree_api.py", line 428, in get_result_pack
    data = await fetch_result(
           ^^^^^^^^^^^^^^^^^^^
    ...<7 lines>...
    )
    ^
  File "/config/custom_components/gree/gree_api.py", line 376, in fetch_result
    raise ValueError(f"Error communicating with {ip_addr}: {err}") from err
ValueError: Error communicating with 192.168.69.10: Failed to communicate with device '192.168.69.10:7000' after 5 attempts

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree/gree_device.py", line 248, in update_device_status
    await gree_set_status(
    ...<10 lines>...
    )
  File "/config/custom_components/gree/gree_api.py", line 729, in gree_set_status
    raise ValueError("Error getting device status") from err
ValueError: Error getting device status

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree/climate.py", line 846, in async_set_temperature
    await self.device.update_device_status()
  File "/config/custom_components/gree/gree_device.py", line 265, in update_device_status
    raise ValueError("Error setting device status") from err
ValueError: Error setting device status

For the second question, the indoor units are not always identical. For example, my living room ac is a different one than the rest.

Can you please elaborate which parameters are missing?

@p-monteiro
Copy link
Copy Markdown
Contributor Author

@meirlo I'm having a hard time debugging the issue, sorry. Please try the latest version and provide the full debug log, not only the exception.
Your error shows a problem communicating with the device, so either the connection is the problem or the pack sent to the device is invalid, and it does not respond correctly.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

I've been using this for some time now to control my AC without any problem. It would be nice to have more people trying out the latest commit to find bugs or missing features so this can be merged, including people with VRF.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

@ChillingSilence, Your device doesn't really want to play along with the fetch_device_info() for getting the firmware version, etc.

I allow binding to occur even with an error in fetch info; let's see if the binding fails now.
I also added tests to try fetching with the device key (if it binds successfully) and the generic ones.

Please try again in alpha.81 and provide the log, even if the bind is successful

@ChillingSilence
Copy link
Copy Markdown

@p-monteiro Hope this helps, using 5e3c35f, tried auto-add, then manually adding with IP+MAC, then manually specifying the encryption key on Auto Encryption Version.

s6-rc: info: service s6rc-oneshot-runner: starting
s6-rc: info: service s6rc-oneshot-runner successfully started
s6-rc: info: service fix-attrs: starting
s6-rc: info: service fix-attrs successfully started
s6-rc: info: service legacy-cont-init: starting
s6-rc: info: service legacy-cont-init successfully started
s6-rc: info: service legacy-services: starting
services-up: info: copying legacy longrun home-assistant (no readiness notification)
s6-rc: info: service legacy-services successfully started
2026-03-18 15:05:19.951 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration ac_infinity which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2026-03-18 15:05:19.952 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration gree_custom which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2026-03-18 15:05:19.952 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration intesishome which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2026-03-18 15:05:19.953 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration hacs which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2026-03-18 15:07:23.642 DEBUG (MainThread) [custom_components.gree_custom.config_flow] Found broadcast addresses from HA: ['255.255.255.255']
2026-03-18 15:07:23.643 DEBUG (MainThread) [custom_components.gree_custom.aiogree.transport] Sending broadcast to 255.255.255.255:7000
2026-03-18 15:07:23.644 DEBUG (MainThread) [custom_components.gree_custom.aiogree.transport] Waiting 5 seconds for UDP replies... 
2026-03-18 15:07:28.645 DEBUG (MainThread) [custom_components.gree_custom.aiogree.transport] Discovery finished. Got 0 responses
2026-03-18 15:08:04.665 INFO (MainThread) [custom_components.gree_custom.aiogree.device] Initialize the GREE Device API for: 580d0d3474fc (192.168.22.120:7000)
2026-03-18 15:08:04.665 DEBUG (MainThread) [custom_components.gree_custom.aiogree.device] Version: None, Key: [omitted]
2026-03-18 15:08:06.668 WARNING (MainThread) [custom_components.gree_custom.aiogree.transport] Error communicating with 192.168.22.120. Attempt 1/2
2026-03-18 15:08:09.172 WARNING (MainThread) [custom_components.gree_custom.aiogree.transport] Error communicating with 192.168.22.120. Attempt 2/2
2026-03-18 15:08:09.974 ERROR (MainThread) [custom_components.gree_custom.aiogree.device] Could not fetch device info before binding
Traceback (most recent call last):
  File "/usr/local/lib/python3.14/asyncio/tasks.py", line 488, in wait_for
    return await fut
           ^^^^^^^^^
  File "/usr/local/lib/python3.14/site-packages/asyncio_dgram/aio.py", line 124, in recv
    data, addr = await self._recvq.get()
                 ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/queues.py", line 186, in get
    await getter
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 45, in udp_request
    received_data, _ = await asyncio.wait_for(recv_task, self.timeout)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/tasks.py", line 487, in wait_for
    async with timeouts.timeout(timeout):
               ~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/timeouts.py", line 114, in __aexit__
    raise TimeoutError from exc_val
TimeoutError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/api.py", line 173, in get_result_pack
    recv_json = await transport.request_json(json_data)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 83, in request_json
    raw = await self.udp_request(json.dumps(payload).encode("utf-8"))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 77, in udp_request
    raise GreeConnectionError(
        f"Failed to communicate with device '{self.ip_addr}:{self.port}' after {self.max_retries} attempts"
    ) from last_error
custom_components.gree_custom.aiogree.errors.GreeConnectionError: Failed to communicate with device '192.168.22.120:7000' after 2 attempts

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/device.py", line 165, in fetch_device_info
    self._raw_info = await gree_get_device_info(
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
        self._transport, cipher or self._cipher
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/config/custom_components/gree_custom/aiogree/api.py", line 514, in gree_get_device_info
    data: dict = await get_result_pack(
                 ^^^^^^^^^^^^^^^^^^^^^^
    ...<3 lines>...
    )
    ^
  File "/config/custom_components/gree_custom/aiogree/api.py", line 178, in get_result_pack
    raise GreeProtocolError("Error in device response") from err
custom_components.gree_custom.aiogree.errors.GreeProtocolError: Error in device response

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/device.py", line 113, in bind_device
    await self.fetch_device_info()
  File "/config/custom_components/gree_custom/aiogree/device.py", line 170, in fetch_device_info
    raise GreeProtocolError(
        f"Failed fetching device info for {self._ip_addr}"
    ) from e
custom_components.gree_custom.aiogree.errors.GreeProtocolError: Failed fetching device info for 192.168.22.120
2026-03-18 15:08:09.980 INFO (MainThread) [custom_components.gree_custom.aiogree.api] Trying to perform binding. Testing both versions with generic keys
2026-03-18 15:08:09.980 DEBUG (MainThread) [custom_components.gree_custom.aiogree.api] Requesting bind to device with encryption key v1
2026-03-18 15:08:09.981 DEBUG (MainThread) [custom_components.gree_custom.aiogree.api] Bind Pack: {'mac': '580d0d3474fc', 't': 'bind', 'uid': 0}
2026-03-18 15:08:09.981 DEBUG (MainThread) [custom_components.gree_custom.aiogree.cipher] Encrypting data (V1): {"mac": "580d0d3474fc", "t": "bind", "uid": 0}
2026-03-18 15:08:09.987 DEBUG (MainThread) [custom_components.gree_custom.aiogree.cipher] Encrypted data (V1): Fo0NJVLzyhX4Qh3bOqWhT4QPXnuPS0a5W/exMkAoHz3IfE1fYVsWM5kifDBw/LN1
2026-03-18 15:08:09.988 DEBUG (MainThread) [custom_components.gree_custom.aiogree.api] Payload: {'cid': 'app', 'i': 1, 'pack': 'Fo0NJVLzyhX4Qh3bOqWhT4QPXnuPS0a5W/exMkAoHz3IfE1fYVsWM5kifDBw/LN1', 't': 'pack', 'tcid': '580d0d3474fc', 'uid': 0}
2026-03-18 15:08:11.989 WARNING (MainThread) [custom_components.gree_custom.aiogree.transport] Error communicating with 192.168.22.120. Attempt 1/2
2026-03-18 15:08:14.494 WARNING (MainThread) [custom_components.gree_custom.aiogree.transport] Error communicating with 192.168.22.120. Attempt 2/2
2026-03-18 15:08:15.295 ERROR (MainThread) [custom_components.gree_custom.aiogree.api] Error in bind request using encryption key with version 1
Traceback (most recent call last):
  File "/usr/local/lib/python3.14/asyncio/tasks.py", line 488, in wait_for
    return await fut
           ^^^^^^^^^
  File "/usr/local/lib/python3.14/site-packages/asyncio_dgram/aio.py", line 124, in recv
    data, addr = await self._recvq.get()
                 ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/queues.py", line 186, in get
    await getter
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 45, in udp_request
    received_data, _ = await asyncio.wait_for(recv_task, self.timeout)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/tasks.py", line 487, in wait_for
    async with timeouts.timeout(timeout):
               ~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/timeouts.py", line 114, in __aexit__
    raise TimeoutError from exc_val
TimeoutError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/api.py", line 173, in get_result_pack
    recv_json = await transport.request_json(json_data)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 83, in request_json
    raw = await self.udp_request(json.dumps(payload).encode("utf-8"))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 77, in udp_request
    raise GreeConnectionError(
        f"Failed to communicate with device '{self.ip_addr}:{self.port}' after {self.max_retries} attempts"
    ) from last_error
custom_components.gree_custom.aiogree.errors.GreeConnectionError: Failed to communicate with device '192.168.22.120:7000' after 2 attempts

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/api.py", line 359, in gree_try_bind
    result = await get_result_pack(json_payload, cipher, transport)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/api.py", line 178, in get_result_pack
    raise GreeProtocolError("Error in device response") from err
custom_components.gree_custom.aiogree.errors.GreeProtocolError: Error in device response
2026-03-18 15:08:15.300 DEBUG (MainThread) [custom_components.gree_custom.aiogree.api] Requesting bind to device with encryption key v2
2026-03-18 15:08:15.300 DEBUG (MainThread) [custom_components.gree_custom.aiogree.api] Bind Pack: {'cid': '580d0d3474fc', 'mac': '580d0d3474fc', 't': 'bind', 'uid': 0}
2026-03-18 15:08:15.300 DEBUG (MainThread) [custom_components.gree_custom.aiogree.cipher] Encrypting data (V2): {"cid": "580d0d3474fc", "mac": "580d0d3474fc", "t": "bind", "uid": 0}
2026-03-18 15:08:15.312 DEBUG (MainThread) [custom_components.gree_custom.aiogree.cipher] Encrypted data (V2): Jtod3XIt89Dxs8SHPnkRBJt2vIVBwAvmIgk1XvjRhurELj0L3QVtft+hse+GRsWcl72qEoTtZbgS4JbKYrud0qPFjVyn, tag='qKWestnLPk4VGayIhFfpRg=='
2026-03-18 15:08:15.312 DEBUG (MainThread) [custom_components.gree_custom.aiogree.api] Payload: {'cid': 'app', 'i': 1, 'pack': 'Jtod3XIt89Dxs8SHPnkRBJt2vIVBwAvmIgk1XvjRhurELj0L3QVtft+hse+GRsWcl72qEoTtZbgS4JbKYrud0qPFjVyn', 't': 'pack', 'tcid': '580d0d3474fc', 'uid': 0, 'tag': 'qKWestnLPk4VGayIhFfpRg=='}
2026-03-18 15:08:17.314 WARNING (MainThread) [custom_components.gree_custom.aiogree.transport] Error communicating with 192.168.22.120. Attempt 1/2
2026-03-18 15:08:19.819 WARNING (MainThread) [custom_components.gree_custom.aiogree.transport] Error communicating with 192.168.22.120. Attempt 2/2
2026-03-18 15:08:20.620 ERROR (MainThread) [custom_components.gree_custom.aiogree.api] Error in bind request using encryption key with version 2
Traceback (most recent call last):
  File "/usr/local/lib/python3.14/asyncio/tasks.py", line 488, in wait_for
    return await fut
           ^^^^^^^^^
  File "/usr/local/lib/python3.14/site-packages/asyncio_dgram/aio.py", line 124, in recv
    data, addr = await self._recvq.get()
                 ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/queues.py", line 186, in get
    await getter
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 45, in udp_request
    received_data, _ = await asyncio.wait_for(recv_task, self.timeout)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/tasks.py", line 487, in wait_for
    async with timeouts.timeout(timeout):
               ~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/timeouts.py", line 114, in __aexit__
    raise TimeoutError from exc_val
TimeoutError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/api.py", line 173, in get_result_pack
    recv_json = await transport.request_json(json_data)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 83, in request_json
    raw = await self.udp_request(json.dumps(payload).encode("utf-8"))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 77, in udp_request
    raise GreeConnectionError(
        f"Failed to communicate with device '{self.ip_addr}:{self.port}' after {self.max_retries} attempts"
    ) from last_error
custom_components.gree_custom.aiogree.errors.GreeConnectionError: Failed to communicate with device '192.168.22.120:7000' after 2 attempts

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/api.py", line 359, in gree_try_bind
    result = await get_result_pack(json_payload, cipher, transport)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/api.py", line 178, in get_result_pack
    raise GreeProtocolError("Error in device response") from err
custom_components.gree_custom.aiogree.errors.GreeProtocolError: Error in device response
2026-03-18 15:08:20.626 ERROR (MainThread) [custom_components.gree_custom.config_flow] Error while binding
Traceback (most recent call last):
  File "/usr/local/lib/python3.14/asyncio/tasks.py", line 488, in wait_for
    return await fut
           ^^^^^^^^^
  File "/usr/local/lib/python3.14/site-packages/asyncio_dgram/aio.py", line 124, in recv
    data, addr = await self._recvq.get()
                 ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/queues.py", line 186, in get
    await getter
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 45, in udp_request
    received_data, _ = await asyncio.wait_for(recv_task, self.timeout)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/tasks.py", line 487, in wait_for
    async with timeouts.timeout(timeout):
               ~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/timeouts.py", line 114, in __aexit__
    raise TimeoutError from exc_val
TimeoutError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/api.py", line 173, in get_result_pack
    recv_json = await transport.request_json(json_data)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 83, in request_json
    raw = await self.udp_request(json.dumps(payload).encode("utf-8"))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 77, in udp_request
    raise GreeConnectionError(
        f"Failed to communicate with device '{self.ip_addr}:{self.port}' after {self.max_retries} attempts"
    ) from last_error
custom_components.gree_custom.aiogree.errors.GreeConnectionError: Failed to communicate with device '192.168.22.120:7000' after 2 attempts

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/api.py", line 359, in gree_try_bind
    result = await get_result_pack(json_payload, cipher, transport)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/api.py", line 178, in get_result_pack
    raise GreeProtocolError("Error in device response") from err
custom_components.gree_custom.aiogree.errors.GreeProtocolError: Error in device response

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/config_flow.py", line 675, in async_step_manual_add
    self._discovered_subdevices = await self._devices[
                                  ^^^^^^^^^^^^^^^^^^^^
        _main_device.mac_address_sub
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ].bind_device()
    ^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/device.py", line 118, in bind_device
    key, version = await gree_try_bind(
                   ^^^^^^^^^^^^^^^^^^^^
    ...<5 lines>...
    )
    ^
  File "/config/custom_components/gree_custom/aiogree/api.py", line 400, in gree_try_bind
    raise GreeBindingError(
        f"Binding failed: Unable to obtain valid encryption version and key pair for {mac_addr} at {transport.ip_addr}"
    ) from error
custom_components.gree_custom.aiogree.errors.GreeBindingError: Binding failed: Unable to obtain valid encryption version and key pair for 580d0d3474fc at 192.168.22.120
2026-03-18 15:08:20.628 DEBUG (MainThread) [custom_components.gree_custom.config_flow] Building main schema with previous values: {'host': '192.168.22.120', 'mac': '580d0d3474fc', 'advanced': {'port': 7000, 'encryption_version': 'Auto-Detect', 'encryption_key': '', 'uid': 0, 'disable_available_check': False, 'max_online_attempts': 5, 'timeout': 10}}
2026-03-18 15:08:42.549 INFO (MainThread) [custom_components.gree_custom.aiogree.device] Initialize the GREE Device API for: 580d0d3474fc (192.168.22.120:7000)
2026-03-18 15:08:42.549 DEBUG (MainThread) [custom_components.gree_custom.aiogree.device] Version: None, Key: cJS3J[omitted]
2026-03-18 15:08:44.552 WARNING (MainThread) [custom_components.gree_custom.aiogree.transport] Error communicating with 192.168.22.120. Attempt 1/2
2026-03-18 15:08:47.056 WARNING (MainThread) [custom_components.gree_custom.aiogree.transport] Error communicating with 192.168.22.120. Attempt 2/2
2026-03-18 15:08:47.858 ERROR (MainThread) [custom_components.gree_custom.aiogree.device] Could not fetch device info before binding
Traceback (most recent call last):
  File "/usr/local/lib/python3.14/asyncio/tasks.py", line 488, in wait_for
    return await fut
           ^^^^^^^^^
  File "/usr/local/lib/python3.14/site-packages/asyncio_dgram/aio.py", line 124, in recv
    data, addr = await self._recvq.get()
                 ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/queues.py", line 186, in get
    await getter
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 45, in udp_request
    received_data, _ = await asyncio.wait_for(recv_task, self.timeout)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/tasks.py", line 487, in wait_for
    async with timeouts.timeout(timeout):
               ~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/timeouts.py", line 114, in __aexit__
    raise TimeoutError from exc_val
TimeoutError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/api.py", line 173, in get_result_pack
    recv_json = await transport.request_json(json_data)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 83, in request_json
    raw = await self.udp_request(json.dumps(payload).encode("utf-8"))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 77, in udp_request
    raise GreeConnectionError(
        f"Failed to communicate with device '{self.ip_addr}:{self.port}' after {self.max_retries} attempts"
    ) from last_error
custom_components.gree_custom.aiogree.errors.GreeConnectionError: Failed to communicate with device '192.168.22.120:7000' after 2 attempts

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/device.py", line 165, in fetch_device_info
    self._raw_info = await gree_get_device_info(
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
        self._transport, cipher or self._cipher
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/config/custom_components/gree_custom/aiogree/api.py", line 514, in gree_get_device_info
    data: dict = await get_result_pack(
                 ^^^^^^^^^^^^^^^^^^^^^^
    ...<3 lines>...
    )
    ^
  File "/config/custom_components/gree_custom/aiogree/api.py", line 178, in get_result_pack
    raise GreeProtocolError("Error in device response") from err
custom_components.gree_custom.aiogree.errors.GreeProtocolError: Error in device response

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/device.py", line 113, in bind_device
    await self.fetch_device_info()
  File "/config/custom_components/gree_custom/aiogree/device.py", line 170, in fetch_device_info
    raise GreeProtocolError(
        f"Failed fetching device info for {self._ip_addr}"
    ) from e
custom_components.gree_custom.aiogree.errors.GreeProtocolError: Failed fetching device info for 192.168.22.120
2026-03-18 15:08:47.864 INFO (MainThread) [custom_components.gree_custom.aiogree.api] Trying to perform binding. Prefering provided key (cJS3J[redacted])
2026-03-18 15:08:47.864 DEBUG (MainThread) [custom_components.gree_custom.aiogree.api] Requesting bind to device with encryption key v1
2026-03-18 15:08:47.864 DEBUG (MainThread) [custom_components.gree_custom.aiogree.api] Bind Pack: {'mac': '580d0d3474fc', 't': 'bind', 'uid': 0}
2026-03-18 15:08:47.864 DEBUG (MainThread) [custom_components.gree_custom.aiogree.cipher] Encrypting data (V1): {"mac": "580d0d3474fc", "t": "bind", "uid": 0}
2026-03-18 15:08:47.864 DEBUG (MainThread) [custom_components.gree_custom.aiogree.cipher] Encrypted data (V1): Fo0NJVLzyhX4Qh3bOqWhT4QPXnuPS0a5W/exMkAoHz3IfE1fYVsWM5kifDBw/LN1
2026-03-18 15:08:47.864 DEBUG (MainThread) [custom_components.gree_custom.aiogree.api] Payload: {'cid': 'app', 'i': 1, 'pack': 'Fo0NJVLzyhX4Qh3bOqWhT4QPXnuPS0a5W/exMkAoHz3IfE1fYVsWM5kifDBw/LN1', 't': 'pack', 'tcid': '580d0d3474fc', 'uid': 0}
2026-03-18 15:08:49.866 WARNING (MainThread) [custom_components.gree_custom.aiogree.transport] Error communicating with 192.168.22.120. Attempt 1/2
2026-03-18 15:08:52.369 WARNING (MainThread) [custom_components.gree_custom.aiogree.transport] Error communicating with 192.168.22.120. Attempt 2/2
2026-03-18 15:08:53.171 ERROR (MainThread) [custom_components.gree_custom.aiogree.api] Error in bind request using encryption key with version 1
Traceback (most recent call last):
  File "/usr/local/lib/python3.14/asyncio/tasks.py", line 488, in wait_for
    return await fut
           ^^^^^^^^^
  File "/usr/local/lib/python3.14/site-packages/asyncio_dgram/aio.py", line 124, in recv
    data, addr = await self._recvq.get()
                 ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/queues.py", line 186, in get
    await getter
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 45, in udp_request
    received_data, _ = await asyncio.wait_for(recv_task, self.timeout)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/tasks.py", line 487, in wait_for
    async with timeouts.timeout(timeout):
               ~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/timeouts.py", line 114, in __aexit__
    raise TimeoutError from exc_val
TimeoutError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/api.py", line 173, in get_result_pack
    recv_json = await transport.request_json(json_data)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 83, in request_json
    raw = await self.udp_request(json.dumps(payload).encode("utf-8"))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 77, in udp_request
    raise GreeConnectionError(
        f"Failed to communicate with device '{self.ip_addr}:{self.port}' after {self.max_retries} attempts"
    ) from last_error
custom_components.gree_custom.aiogree.errors.GreeConnectionError: Failed to communicate with device '192.168.22.120:7000' after 2 attempts

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/api.py", line 359, in gree_try_bind
    result = await get_result_pack(json_payload, cipher, transport)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/api.py", line 178, in get_result_pack
    raise GreeProtocolError("Error in device response") from err
custom_components.gree_custom.aiogree.errors.GreeProtocolError: Error in device response
2026-03-18 15:08:53.176 DEBUG (MainThread) [custom_components.gree_custom.aiogree.api] Requesting bind to device with encryption key v2
2026-03-18 15:08:53.176 DEBUG (MainThread) [custom_components.gree_custom.aiogree.api] Bind Pack: {'cid': '580d0d3474fc', 'mac': '580d0d3474fc', 't': 'bind', 'uid': 0}
2026-03-18 15:08:53.176 DEBUG (MainThread) [custom_components.gree_custom.aiogree.cipher] Encrypting data (V2): {"cid": "580d0d3474fc", "mac": "580d0d3474fc", "t": "bind", "uid": 0}
2026-03-18 15:08:53.177 DEBUG (MainThread) [custom_components.gree_custom.aiogree.cipher] Encrypted data (V2): Jtod3XIt89Dxs8SHPnkRBJt2vIVBwAvmIgk1XvjRhurELj0L3QVtft+hse+GRsWcl72qEoTtZbgS4JbKYrud0qPFjVyn, tag='qKWestnLPk4VGayIhFfpRg=='
2026-03-18 15:08:53.177 DEBUG (MainThread) [custom_components.gree_custom.aiogree.api] Payload: {'cid': 'app', 'i': 1, 'pack': 'Jtod3XIt89Dxs8SHPnkRBJt2vIVBwAvmIgk1XvjRhurELj0L3QVtft+hse+GRsWcl72qEoTtZbgS4JbKYrud0qPFjVyn', 't': 'pack', 'tcid': '580d0d3474fc', 'uid': 0, 'tag': 'qKWestnLPk4VGayIhFfpRg=='}
2026-03-18 15:08:55.180 WARNING (MainThread) [custom_components.gree_custom.aiogree.transport] Error communicating with 192.168.22.120. Attempt 1/2
2026-03-18 15:08:57.684 WARNING (MainThread) [custom_components.gree_custom.aiogree.transport] Error communicating with 192.168.22.120. Attempt 2/2
2026-03-18 15:08:58.485 ERROR (MainThread) [custom_components.gree_custom.aiogree.api] Error in bind request using encryption key with version 2
Traceback (most recent call last):
  File "/usr/local/lib/python3.14/asyncio/tasks.py", line 488, in wait_for
    return await fut
           ^^^^^^^^^
  File "/usr/local/lib/python3.14/site-packages/asyncio_dgram/aio.py", line 124, in recv
    data, addr = await self._recvq.get()
                 ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/queues.py", line 186, in get
    await getter
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 45, in udp_request
    received_data, _ = await asyncio.wait_for(recv_task, self.timeout)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/tasks.py", line 487, in wait_for
    async with timeouts.timeout(timeout):
               ~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/timeouts.py", line 114, in __aexit__
    raise TimeoutError from exc_val
TimeoutError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/api.py", line 173, in get_result_pack
    recv_json = await transport.request_json(json_data)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 83, in request_json
    raw = await self.udp_request(json.dumps(payload).encode("utf-8"))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 77, in udp_request
    raise GreeConnectionError(
        f"Failed to communicate with device '{self.ip_addr}:{self.port}' after {self.max_retries} attempts"
    ) from last_error
custom_components.gree_custom.aiogree.errors.GreeConnectionError: Failed to communicate with device '192.168.22.120:7000' after 2 attempts

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/api.py", line 359, in gree_try_bind
    result = await get_result_pack(json_payload, cipher, transport)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/api.py", line 178, in get_result_pack
    raise GreeProtocolError("Error in device response") from err
custom_components.gree_custom.aiogree.errors.GreeProtocolError: Error in device response
2026-03-18 15:08:58.490 ERROR (MainThread) [custom_components.gree_custom.config_flow] Error while binding
Traceback (most recent call last):
  File "/usr/local/lib/python3.14/asyncio/tasks.py", line 488, in wait_for
    return await fut
           ^^^^^^^^^
  File "/usr/local/lib/python3.14/site-packages/asyncio_dgram/aio.py", line 124, in recv
    data, addr = await self._recvq.get()
                 ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/queues.py", line 186, in get
    await getter
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 45, in udp_request
    received_data, _ = await asyncio.wait_for(recv_task, self.timeout)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/tasks.py", line 487, in wait_for
    async with timeouts.timeout(timeout):
               ~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/usr/local/lib/python3.14/asyncio/timeouts.py", line 114, in __aexit__
    raise TimeoutError from exc_val
TimeoutError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/api.py", line 173, in get_result_pack
    recv_json = await transport.request_json(json_data)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 83, in request_json
    raw = await self.udp_request(json.dumps(payload).encode("utf-8"))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/transport.py", line 77, in udp_request
    raise GreeConnectionError(
        f"Failed to communicate with device '{self.ip_addr}:{self.port}' after {self.max_retries} attempts"
    ) from last_error
custom_components.gree_custom.aiogree.errors.GreeConnectionError: Failed to communicate with device '192.168.22.120:7000' after 2 attempts

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/aiogree/api.py", line 359, in gree_try_bind
    result = await get_result_pack(json_payload, cipher, transport)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/api.py", line 178, in get_result_pack
    raise GreeProtocolError("Error in device response") from err
custom_components.gree_custom.aiogree.errors.GreeProtocolError: Error in device response

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/gree_custom/config_flow.py", line 675, in async_step_manual_add
    self._discovered_subdevices = await self._devices[
                                  ^^^^^^^^^^^^^^^^^^^^
        _main_device.mac_address_sub
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ].bind_device()
    ^^^^^^^^^^^^^^^
  File "/config/custom_components/gree_custom/aiogree/device.py", line 118, in bind_device
    key, version = await gree_try_bind(
                   ^^^^^^^^^^^^^^^^^^^^
    ...<5 lines>...
    )
    ^
  File "/config/custom_components/gree_custom/aiogree/api.py", line 400, in gree_try_bind
    raise GreeBindingError(
        f"Binding failed: Unable to obtain valid encryption version and key pair for {mac_addr} at {transport.ip_addr}"
    ) from error
custom_components.gree_custom.aiogree.errors.GreeBindingError: Binding failed: Unable to obtain valid encryption version and key pair for 580d0d3474fc at 192.168.22.120
2026-03-18 15:08:58.491 DEBUG (MainThread) [custom_components.gree_custom.config_flow] Building main schema with previous values: {'host': '192.168.22.120', 'mac': '580d0d3474fc', 'advanced': {'port': 7000, 'encryption_version': 'Auto-Detect', 'encryption_key': 'cJS3JDim581t3914', 'uid': 0, 'disable_available_check': False, 'max_online_attempts': 5, 'timeout': 10}}

@p-monteiro
Copy link
Copy Markdown
Contributor Author

p-monteiro commented Mar 18, 2026

That's some really odd behaviour there @ChillingSilence.
There's definitely something wrong with the connection, either on HA, integration, or the host.

Just so we are on the same page:

  • What is the HA setup? Where is it installed? What's the network configuration?
  • Does the device work correctly on the public version of this integration (https://github.com/RobHofmann/HomeAssistant-GreeClimateComponent/tree/master)? If so, what is the encryption version it is using?
  • Is the device responding to pings ping 192.168.22.120 from both inside the HA container (if applicable) and its host
  • If on a Linux Docker host, what's the output of nc -u -zv 192.168.22.120 7000?

@ChillingSilence
Copy link
Copy Markdown

Home Assistant is an x86_64 HAOS install. The network is a flat 192.168.22.0/24 with an Edgerouter-X giving out DHCP and a Ubiquiti U6-LR. There's no firewall or anything on the LAN, the router is doing NAT only and the WiFi is bridging to the LAN. Other things that use broadcasting are fine, like Chromecast etc

I've just checked now. It seems the device doesn't work on the other public version either.

It responds to pings from within the HA "Terminal & SSH" addon, and also from another workstation on my network.
Netcat shows no output when run either from WSL on the workstation PC or from within HAOS.

It is a relatively new AC purchase / install / unit so I wonder if it's perhaps just a new type? I found this repo originally and this PR seemed to be getting the most love do honestly I started here. Trying the other primary public repo now though and sadly also no joy.

The app shows the following, in case it's helpful:
Screenshot_20260319-101549
Screenshot_20260319-101554

Ran nmap and it showed all TCP ports closed, but it does respond to pings... Confirmed it's the right device too, the arp table matches the DHCP lease which matches the details from luc10/gree-api-client
The details I'm getting returned from the Gree AU server are correct (I'm in New Zealand) and if I try another server (like NA or Russia) the Python script fails, so I'm confident it's being provided the right information back.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

p-monteiro commented Mar 18, 2026

@ChillingSilence ahh, alright. I was under the assumption it was working in the "master" version, and I was actually losing my head, because nothing is functionally different here. So if that is not the case, we shall move to another kind of troubleshooting.

I'm not sure the device information is very useful for Gree. I have the same model ID and version as you. However, my firmware is in the range v1.XX and yours is at v3.XX

Netcat shows no output, correct? Or does it error?

I think I read somewhere that Gree uses MQTT in some units, so maybe newer firmwares dropped the legacy UDP protocol we are using here. I will dig around.

Can you send the complete model of your indoor unit?

@ChillingSilence
Copy link
Copy Markdown

Ahh my apologies @p-monteiro I had only just tried it now with the master version so didn't know it wasn't behaving there otherwise. My bad.

Netcat shows now output, correct. No errors, just, nothing.

I have 2x Gree Kingfisher GWH24ATEXF units. I can confirm they work on the WiFi, and I can disconnect my phone to use 4G and still control them... So they're talking somehow. I wonder if I can packet capture from the router 🤔

@p-monteiro
Copy link
Copy Markdown
Contributor Author

@ChillingSilence, packet capture would be the best way if you actually know how to do it. I'm not good at it.

@ChillingSilence
Copy link
Copy Markdown

It looks like it's still doing stuff on UDP port 7000? All the five packets are pretty much the same
image
The actual commands afterwards from "the cloud" seem to happen on TCP port 1982.

Is this helpful as a starting point thought @p-monteiro ?
Grateful for your assistance, thanks again 🙏

@p-monteiro
Copy link
Copy Markdown
Contributor Author

@ChillingSilence It's performing the normal {"t":"scan"} broadcast. What is the device sending back after those?
src: 192.168.22.120 dst: 192.168.22.86

Also, I would prefer not to pollute this PR with this since it is unrelated to it. Open a new issue, and we can continue discussing there.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

p-monteiro commented Mar 26, 2026

@RobHofmann I'm down to get this merged into a different branch and published as an alpha/beta version. Fixes can then be made against that. I'll let you decide whatever you deem fit for the project. Remember, this is a breaking update.
The only thing I prefer to do extra is to drop yaml config as per HA guidelines (https://github.com/home-assistant/architecture/blob/master/adr/0010-integration-configuration.md#decision), but I understand if you are against it.

Refer to the original PR message (#373 (comment))

@RobHofmann
Copy link
Copy Markdown
Owner

RobHofmann commented Apr 15, 2026

Hey! Im unable to discover my devices through this integration. I've created a fix for this on my own version yesterday:
0134bb7

Can you please include this in your setup too?

As for your comment on YAML: I'm not sure. I'm not using it anymore. But theres a big reason why I could see people wanting to use this: Configuration as Code --> Easier to save in a repository. Same with Infrastructure as Code. This also means you can version your configuration. Reason why i'm currently not using it anymore is because I need to test the config flow for the ingration, but for other components I use YAML as long as I can :). But tbh i'm not sure how other people look at this.

PS. I've started testing your release just now.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

p-monteiro commented Apr 15, 2026

@RobHofmann Hi, thanks for the notes. Keep testing and let me know whatever you need.
I'll remove my workflows for release and use yours, but I do advise keeping the validation ones.
Yes, I saw that commit. Looked good, so yes, I intend to integrate it as well. I'm gonna be busy in the next few days, but I should be able to do it next week.

As for the YAML, that's a good and valid point, though HA backups should address the issue. I'm just more comfortable following the official guidelines. But your call.

@RobHofmann
Copy link
Copy Markdown
Owner

@RobHofmann Hi, thanks for the notes. Keep testing and let me know whatever you need. I'll remove my workflows for release and use yours, but I do advise keeping the validation ones. Yes, I saw that commit. Looked good, so yes, I intend to integrate it as well. I'm gonna be busy in the next few days, but I should be able to do it next week.

You need to brief me on the validation part here. No hurry, let me know when you get it in :).

As for the YAML, that's a good and valid point, though HA backups should address the issue. I'm just more comfortable following the official guidelines. But your call.

Backups would be nice, but for a docker setup this is not a feature. I do have backups in place, but its all "self managed". I trust more in plain code "backups" to a repository where I can also use things like branching (and test on my dev machine etc). So in short: i assume powerusers have more benefit from the YAML than "regular" users. Normally i'd absolutely go "home assistant native", but so far I'm not really seeing solutions accros the board. This is why I want to keep the options open. For us it's easy to maintain YAML for now. If these challenges get solved in the future we can always drop it.
Right now, nothing is holding anyone back from not using YAML. You just have a choice now :).

@p-monteiro
Copy link
Copy Markdown
Contributor Author

You need to brief me on the validation part here. No hurry, let me know when you get it in :).

It's just HACS and Hassfest validation to ensure integration quality.
Check the file and the related links: https://github.com/p-monteiro/HomeAssistant-GreeClimateComponent-Rewrite/blob/08402760b13fbba1f1474e79695846f00388f9e8/.github/workflows/validate.yaml

Backups would be nice, but for a docker setup this is not a feature. I do have backups in place, but its all "self managed". I trust more in plain code "backups" to a repository where I can also use things like branching (and test on my dev machine etc). So in short: i assume powerusers have more benefit from the YAML than "regular" users. Normally i'd absolutely go "home assistant native", but so far I'm not really seeing solutions accros the board. This is why I want to keep the options open. For us it's easy to maintain YAML for now. If these challenges get solved in the future we can always drop it. Right now, nothing is holding anyone back from not using YAML. You just have a choice now :).

I also have backups configured for my Docker instance, and they are automatic through the Backups page inside HA, but I do understand where you come from. That's fine, really. It requires a bit more code to do proper config validation, but that's all. It's done and working.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

Hey! Im unable to discover my devices through this integration. I've created a fix for this on my own version yesterday: 0134bb7

Can you please include this in your setup too?

While including this, I noticed that only the target host might be needed.
I have a Docker container with 2 networks (bridge and macvlan).
While only connected to the bridge, broadcasts to 255.255.255.255 obviously fail to find my devices.
However, all it takes is for me to enable the second network in HA settings, and the HA helper that I use to retrieve broadcasts gives me the generic one (255) and one for each network adapter. When performing discovery on those specific ones, it gets the proper replies with the socket bound to 0.0.0.0, so no need for a socket per interface.

@RobHofmann and anyone else, can you confirm if you can discover your devices when enabling the respective adapters in HA configuration?
your_ha_url/config/network

@RobHofmann
Copy link
Copy Markdown
Owner

Hey! Im unable to discover my devices through this integration. I've created a fix for this on my own version yesterday: 0134bb7
Can you please include this in your setup too?

While including this, I noticed that only the target host might be needed. I have a Docker container with 2 networks (bridge and macvlan). While only connected to the bridge, broadcasts to 255.255.255.255 obviously fail to find my devices. However, all it takes is for me to enable the second network in HA settings, and the HA helper that I use to retrieve broadcasts gives me the generic one (255) and one for each network adapter. When performing discovery on those specific ones, it gets the proper replies with the socket bound to 0.0.0.0, so no need for a socket per interface.

@RobHofmann and anyone else, can you confirm if you can discover your devices when enabling the respective adapters in HA configuration? your_ha_url/config/network

Can you explain what your doing here? Im unsure what you are looking for here. I dont have any network configuration in my HomeAssistant at all. In the past I did use macvlan, but i switched to docker networks due to their more secure nature.

In my cross VLAN solution, its only needed to pass networks you want to scan (since scanning cross vlan is not a default option) cross VLAN. For the same subnet, it wouldn't require input.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

@RobHofmann Oh, so your HA Docker container is only connected to a single bridged Docker network? No macvlan or host networking, and you have no adapter directly connecting HA to the VLAN, right?
You should see the available networks/adapters in HA by going to Settings > System > Network and unticking Autoconfigure if required.

In your solution, does cross-VLAN broadcast work? Or is it the case that if a cross-VLAN is specified, it targets its individual hosts?

@p-monteiro
Copy link
Copy Markdown
Contributor Author

@RobHofmann Did you manage to test this in some capacity?

@rudizl
Copy link
Copy Markdown

rudizl commented May 28, 2026

Any chances to published this as alpha/beta reliese?

@RobHofmann
Copy link
Copy Markdown
Owner

Hmm im not sure, theres no option; i assume because its not a branch in my repo.

I guess we need to PR this to a branch from main in my repo and from there create a release?

PS. I have tested it, but I'm using a very limited set of options on my devices. So I think we need to scale up our testing audience.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

p-monteiro commented May 28, 2026

I still have this PR marked as a draft.
If you create a different branch, I can retarget the PR to it.
One thing that needs to be addressed before this has any chance of going stable is to migrate the translations from the old template to the new one, but that can be another PR against the branch

@domialex
Copy link
Copy Markdown
Contributor

@RobHofmann You need to click pre-release in a github release.

@RobHofmann
Copy link
Copy Markdown
Owner

Created branch 4.0-pre-release

@domialex i tried creating a pre-release, but theres no option to select the branch of @p-monteiro. So i assume i need to pull it in to this pre-release branch and from there create the pre-release.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

@RobHofmann Yes, you can only create releases or perform your workflows on your branches. This work is still not merged into one. I'll make the PR to your new branch today.

@p-monteiro p-monteiro changed the base branch from master to 4.0-pre-release May 29, 2026 13:26
@p-monteiro p-monteiro marked this pull request as ready for review May 29, 2026 14:27
@p-monteiro
Copy link
Copy Markdown
Contributor Author

Because of the new branches and all the changes, merging this will break the commit history between the old and new files, since they are shown as new rather than modified old ones. I tried to do a manual rebase, but the changes are so complex now that it is unfeasible.

@p-monteiro
Copy link
Copy Markdown
Contributor Author

Also, @RobHofmann your version bump and release workflows need a bit of tweaking because they assume the releases are from the "master" branch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants