Skip to main content

Encode and decode Gree air-conditioner IR remote control signals

Project description

gree-rc-encoder

Python library to encode and decode Gree air-conditioner IR remote-control signals (pulse timings ↔ high-level state).

Install

From PyPI:

pip install gree-rc-encoder

From a local checkout (editable, with test deps):

pip install -e ".[dev]"

Quick start

from gree_rc import (
    GreeState,
    Mode,
    FanSpeed,
    encode_control,
    encode_temperature,
    decode,
    to_ir_ctl,
)

state = GreeState(
    is_on=True,
    mode=Mode.COOL,
    temperature=24,
    fan_speed=FanSpeed.AUTO,
    light_on=True,
)

timings = encode_control(state)       # list[int] durations in microseconds
print(to_ir_ctl(timings))             # "+9000 -4500 +655 ..." for ir-ctl

result = decode(timings)
assert result.state.temperature == 24

# I Feel: remote sensor reading (sent periodically while ifeel_mode is on)
temp_frame = encode_temperature(27)
assert decode(temp_frame).temperature == 27

API overview

Function Purpose
encode_control(state) GreeState → 559 timing values
decode_control(timings) timings / ir-ctl string → GreeState
encode_temperature(temp) I Feel ambient °C (0–255) → 35 timing values
decode_temperature(timings) → int °C
decode(timings) auto-detect control / temperature / combined → DecodeResult
to_ir_ctl / from_ir_ctl convert to/from ir-ctl pulse strings
encode_gree / parse_gree nibble-level frame without IR timings

The library performs no I/O and does not print; raise GreeEncodeError, GreeDecodeError, or GreeValidationError on failure.

GreeState fields

Fields marked model-dependent exist only on some units (the remote protocol still carries the bits; unsupported hardware ignores them). Per the manual: wifi_on / wifi_reset, cold_plasma, uvc_lamp, soft_sound, fast_cool, start_auto_clean, fresh_air.

Field Meaning
is_on Unit power on/off
mode cool / dry / fan_only / heat / auto
temperature Setpoint, 16–31.5 in 0.5 steps
units "C" or "F"
fan_speed auto, speed_1speed_5, silent, turbo
x_fan X-FAN: after off in Cool/Dry, indoor fan keeps running briefly to dry the evaporator. Not available in Auto/Fan/Heat. Defaults off after the unit is powered.
cold_plasma Model-dependent. Cold Plasma health function. Requires is_on.
uvc_lamp Model-dependent. UVC lamp health function. Requires is_on. Both may be on together.
humidity_level_set Manual humidity control via the Humidity button (Cool/Dry only).
humidity_level Target humidity % when set manually (None if unused). Cool: 40–80; Dry: 30–70; multiples of 5.
humidity_level_auto Humidity button “auto” mode — meaning depends on mode: in Cool, smart dehumidification (Ao); in Dry, continuous dehumidification (Co). Mutually exclusive with humidity_level_set.
vertical_swing_mode Vertical louvre: off, full swing, or fixed positions 1–5
horizontal_swing_mode Horizontal louvre: off, full/double swing, positions, or pos_1_5
swing_started Poorly understood (empirical). Changes when automatic movement of vertical or horizontal swing is turned on or off (louvre moving, not fixed). Value is the result of that last toggle: True ≈ some swing was started, False ≈ some swing was stopped.
ifeel_mode I Feel: remote sends ambient-temperature frames from its built-in sensor (see Protocol notes).
timer_set Timer armed (True iff timer_mode is not disabled)
timer_mode disabled / off (turn off later) / on (turn on later)
timer_hours_set Timer duration in hours (0.5 steps)
timer_off_left_mins / timer_on_left_mins Remaining minutes for off/on timers (wire fields)
wifi_on Model-dependent. Wi-Fi module enabled
wifi_reset Model-dependent. One-shot: True only in a single frame; clears Wi-Fi settings so the network can be reconfigured
soft_sound Model-dependent. Manual name: Volume control of IDU Buzzer — quieter indoor-unit beeps
power_down_level Power limiting: 0 = off, 1 = level 1, 2 = level 2 (stricter than 1). Cleared when the remote turns the unit off. With two indoor units, the outdoor unit follows the stricter limit. Independent of energy_saving.
energy_saving Energy-saving (SE on the remote): Cool only; requires fan_speed=auto and sleep_mode_level=0. The unit applies a factory energy-saving setpoint — the encoded temperature is still sent but ignored. Independent of power_down_level.
light_on / light_auto Display light on; auto dimming (light_auto requires light_on)
fresh_air Model-dependent. Manual name: two-way ventilation; fan speed follows the AC / fan button
sleep_mode_level 0 = cancel; 1/2 = preset sleep curves; 3 = DIY hourly schedule (see Protocol notes; schedule payload not fully implemented)
display_indoor_temperature / display_indoor_humidity What the indoor display shows (mutually exclusive)
reset_clean_reminder One-shot: toggle/reset the filter clean-reminder function
fast_cool Model-dependent. Fast cool (Cool only): temporary 25°C or 16°C boost for ~20 minutes, then restore previous state
start_auto_clean Model-dependent. One-shot: start auto clean; unit must be off

Hardware demo

Real receive/transmit via ir-ctl lives in examples/ir_ctl_demo.py:

python3 examples/ir_ctl_demo.py receive
python3 examples/ir_ctl_demo.py send --dry-run
python3 examples/ir_ctl_demo.py temperature --dry-run

Tests

pytest

Protocol notes

Control frame

A typical control frame is four subsignals (139 timings each) separated by ~40 ms spaces. Each subsignal carries 16 nibbles (LSB-first bits), a 0,1,0 delimiter with a 20 ms space in the middle, a marker nibble, and a CRC nibble.

Markers identify the logical signal index (0..4). Captures may include more than four subsignals and may list them in any order; the decoder places each subsignal into a fixed 5-slot array by marker before parsing GreeState.

I Feel (ambient temperature)

When I Feel is enabled (GreeState.ifeel_mode), the remote periodically sends a short 35-sample frame with a different leading pulse. That frame carries the reading from the remote’s built-in temperature sensor so the indoor unit can hold the setpoint at the remote’s location rather than only at the AC.

Sleep mode level 3

sleep_mode_level values 1–2 are fixed sleep curves. Level 3 lets the user program an automatic temperature change every hour for up to eight hours. That schedule needs an extra subsignal (logical slot 4 / ~699-sample capture). This library decodes the level flag and will accept/arrange the extra subsignal by marker, but encoding and full parsing of the eight hourly setpoints is not implemented yet.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gree_rc_encoder-0.1.2.tar.gz (34.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gree_rc_encoder-0.1.2-py3-none-any.whl (32.1 kB view details)

Uploaded Python 3

File details

Details for the file gree_rc_encoder-0.1.2.tar.gz.

File metadata

  • Download URL: gree_rc_encoder-0.1.2.tar.gz
  • Upload date:
  • Size: 34.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for gree_rc_encoder-0.1.2.tar.gz
Algorithm Hash digest
SHA256 fa917ce7609ea9e49d02fe1c99064d3232f9c6dff75ec7017093ebfdc2ed054a
MD5 47a8529dade73d37bb4f8058d65da59e
BLAKE2b-256 79055ba1c6bd56ba5bb4250ee9a711280e5e67189b974380d6a21165f2d5a281

See more details on using hashes here.

File details

Details for the file gree_rc_encoder-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for gree_rc_encoder-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 69553282823edd92d3c9d04034aea1d1283252970cb396f9e5117091fcd8e447
MD5 280a7d14fc902675c12fd55e165e0d35
BLAKE2b-256 8dceb76c627c3020305bbbf463bc376d7a6407bc08ab6f849e9366f0066944f2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page