homebridge / homebridge/plugins
Verification Request: homebridge-gree-hvac
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 369
- Forks
- 24
- PR merge metrics
- No merged PRs in 30d
Description
Plugin Name
homebridge-gree-hvac
Link To GitHub Repo
https://github.com/mashgundash/homebridge-gree-hvac
Plugin Icon (Optional)
![]()
Square PNG with sharp corners and a solid background, also committed at icon.png in the repository. Happy to send a 100 × 100 version if you prefer it.
The plugin does not offer the same nor less functionality than that of any existing verified plugin.
🟢 Yes
The plugin successfully installs and does not start unless it is configured.
🟢 Yes
The plugin does not require the user to run Homebridge in a TTY or with non-standard startup parameters, even for initial configuration.
🟢 Yes
The plugin does not contain any analytics or calls that enable you to track the user.
🟢 Yes
If the plugin needs to write files to disk (cache, keys, etc.), it stores them inside the Homebridge storage directory.
🟢 Yes
The plugin does not throw unhandled exceptions, the plugin must catch and log its own errors.
🟢 Yes
More Information
Relationship to homebridge-gree-ac (verified)
homebridge-gree-ac by @eibenp is verified, targets the same hardware and the same local UDP protocol, and is under active maintenance (v2.3.2, published 2026-05-08, Apache-2.0). I want to name it myself rather than have you find it. I am not asking for it to be un-verified, and nothing below is offered as a defect: its README states the plugin is built to be as simple and clear as possible around the Home app's Heater Cooler accessory, and its Known limitations section documents what that deliberately leaves out. Those are its author's choices, and they are the reason the two plugins do not overlap.
The left-hand column below is taken from its own README, its published config.schema.json, and its src/settings.ts — not from my reading of its behaviour.
homebridge-gree-ac 2.3.2 |
homebridge-gree-hvac 1.0.1 |
|
|---|---|---|
| Dry / dehumidify mode | documented as not supported; a unit running in dry mode reads as off in the Home app | dedicated Dry switch (Mod=2), on by default |
| Display light | documented as not controllable | Display light switch (Lig), on by default — deliberately a Switch and never a Lightbulb, so "turn off all the lights" cannot catch an air conditioner |
| Sleep, Health, SE | documented as not supported | Sleep (SwhSlp + SlpMod) on by default; Health/ioniser (Health), Fresh air (Air), Frost protection 8 °C (StHt) and Energy saving (SvSt) available as opt-in switches |
| Horizontal swing | documented as not controllable; stays as set on the unit | modelled over SwingLfRig 0–7, with five fixed side-louvre positions exposed as exclusive switches, opt-in per unit |
| Vertical swing | on/off in the Home app; a fixed position can be chosen only in the config (modifyVerticalSwingPosition, defaultVerticalSwing, defaultFanVerticalSwing) |
SwingMode on the Heater Cooler, plus five fixed vertical positions exposed as exclusive switches in the Home app; modelled over SwUpDn 0–11 |
| Quiet / Turbo | folded into the fan-speed slider (minimum = Quiet, next = Auto, maximum = Powerful) | separate switches. Quiet is treated as the 0/1/2 integer the firmware stores, with 2 as the activating value; the slider carries the five real speeds only, at 20 % per step |
| Per-unit configuration fields | 20 in config.schema.json |
4 — MAC, side-louvre motor fitted, temperature step, plus a last-resort encryption override. Name, model, IP, port and encryption version all come from the unit |
| Config UI languages | 7 (English + 6 files in schemas/) |
29 (English + 28 files in schemas/), including zh-CN and zh-TW |
| Automated tests | no test files in the repository | 432 (node --test), including a UDP device simulator that replays packet loss, an invalidated session key, a changed IP, a silent unit and an undecryptable pack |
| Runtime dependencies | homebridge-lib |
none — node:dgram, node:crypto, node:events only |
| Default polling | statusUpdateInterval 10 s per unit |
30 s (configurable 15–600), ±20 % jitter, one request in flight at a time, 3 s timeout, 2 retransmissions |
| Binding failure | retried once with the other encryption version; the log then asks for a Homebridge restart | retried indefinitely with a bounded exponential backoff, 5 s → 300 s; no manual restart is ever required |
| Half-degree setpoint | a Fahrenheit-derived conversion table indexed on SetTem / TemRec |
SetTem + (Add0.5 × 0.5), established on the hardware against a control unit — see docs/PROTOCOLE.md |
| Sockets | one UDP socket per unit, plus one for discovery | a single UDP socket for every unit, demultiplexed on source address and pack MAC |
Where homebridge-gree-ac covers ground this plugin does not
For completeness, so you do not have to find these yourself. All four are areas where its author went further, and I would not want the table above read as a clean sweep:
- 3-speed units. Its
speedStepsparameter adapts the slider to 3- or 5-speed models. This plugin's fan slider is fixed at five steps. - Beep muting. Its
silentTimeRangeparameter mutes command beeps over a time window.Buzzer_ON_OFFis read into the device state here but is not exposed as a control. - GCloud topology. Its README lists units reached through a GCloud bridge with subdevices. This plugin talks only to units addressable directly on the network.
- A separate Fan accessory. It publishes fan mode as its own
Fanaccessory with an independent speed control. Here, fan-only mode is a switch on the same accessory.
Notes against the individual criteria
- Does not start unless configured. The platform is only constructed when a
GreeHVACblock exists inconfig.json. The constructor opens nothing: the single UDP socket is created inside thedidFinishLaunchinghandler inplatform.js, never at module import, specifically so that no socket exists in an environment wheredgramcannot bind. - No TTY, no startup parameters. There is no pairing step, no interactive prompt and no custom UI. Units are discovered by UDP broadcast on port 7000 and adopted on their own; MAC, name, model, IP and encryption version all come from the unit's own scan reply. A working configuration is one platform block with a name.
- Analytics. None. The only outbound traffic is UDP to port 7000 of the units on the user's own network and to the configured broadcast address. There is no HTTP client anywhere in the published tree — the complete set of imports is
node:dgram,node:cryptoandnode:events, andpackage.jsondeclares no dependencies at all. - Disk. The plugin never calls
fs; there is nofsimport in the published tree, so the storage-directory rule is not engaged. Per-unit identity is kept inaccessory.context, which Homebridge itself persists in its own storage directory. Session keys are held in memory only and re-negotiated on every start. - Unhandled exceptions. Every
dgramcallback is wrapped intry/catchinlib/transport.js; a malformed or undecryptable datagram is dropped and logged, never propagated. ThedidFinishLaunchingandshutdownhandlers are wrapped, and even the logger wrapper catches its own failures so that a failing log call cannot interrupt a network cycle. This is the point the whole design is built around: an uncaught exception raised inside a socket callback is fatal to the Homebridge process, and a plugin on the main bridge takes every other plugin down with it. The README therefore recommends a child bridge as well. - Failure behaviour in the Home app. A transient network loss does not produce No Response, which is sticky and can leave the accessory blank in the Home app long after the network is back. The last known state is served and the degradation is reported through
StatusActiveandStatusFaulton the Temperature Sensor service — the only one of the plugin's services that HAP allows to carry them. A unit that stops answering keeps its accessory and is never removed. - Cached accessories.
setPropsis re-applied unconditionally at every start, including on accessories restored from cache, and every value is clamped against its own props beforeupdateValue. Props are serialised into the accessory cache, so an accessory created before a bounds change would otherwise keep the old bounds permanently. - Protocol facts. The 27 protocol fields, the two encryption versions, the half-degree encoding and the absence of mutual exclusion between Quiet, Turbo and fan speed were all measured on five units in service and are written up in
docs/PROTOCOLE.md, with the design decisions that follow from them indocs/CONCEPTION.md. Both documents are in French. - Hardware claimed. Gree, Sinclair and Inventor, plus any unit whose Wi-Fi module pairs with EWPE Smart. Brands listed by other projects without corroboration are deliberately not claimed.
- Environment.
engines.nodeis^22.12.0 || ^24.0.0andengines.homebridgeis^1.8.0 || ^2.0.0. Nopreinstall,installorpostinstallscript anywhere; the only npm script istest. MIT.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the linked homebridge-gree-hvac repository, especially platform.js and lib/transport.js, then run its node --test suite. Read docs/PROTOCOLE.md and docs/CONCEPTION.md alongside the verification criteria in this issue. Done means confirming the plugin meets the stated requirements and recording a verification decision.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- release, testing-qa
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100