Skip to content

feat: add Panasonic A/C protocol and Hong Kong/Macau model#45

Draft
sam0737 wants to merge 2 commits into
home-assistant-libs:mainfrom
sam0737:panasonic-ac-hk
Draft

feat: add Panasonic A/C protocol and Hong Kong/Macau model#45
sam0737 wants to merge 2 commits into
home-assistant-libs:mainfrom
sam0737:panasonic-ac-hk

Conversation

@sam0737
Copy link
Copy Markdown

@sam0737 sam0737 commented May 31, 2026

Summary

Adds support for encoding Panasonic air-conditioner IR signals.

Following review, this was reworked to build on the existing Kaseikyo (AEHA) support rather than adding a separate framing layer: a Panasonic A/C frame is a Kaseikyo frame with the Panasonic vendor address 0x2002, and the full state is simply two such frames. The only missing piece in KaseikyoCommand was multi-frame support, which had been removed in 869f5d8 (#27) and is re-added here.

Changes

  • commands/kaseikyo.py — re-add multi-frame support. KaseikyoCommand(data=...) now accepts either a single bytes (one frame, unchanged behaviour) or a list[bytes] (several same-address frames emitted as one message, separated by an inter-frame gap). Single-frame callers (e.g. the Panasonic ceiling light) are unaffected.
  • commands/panasonic_ac.py — a generic, model-agnostic Panasonic A/C encoder built on KaseikyoCommand:
    • PanasonicAcCommand — full 27-byte state. Keyword-only __init__ exposing the complete field set (power, mode, temperature with 0.5 °C step, fan, two swing axes, nanoex) with sensible defaults, so callers drive whichever combination their unit supports. temperature is validated against MIN_TEMP/MAX_TEMP.
    • PanasonicAcToggleCommand — the short 16-byte Quiet/Powerful toggle frame.
    • Field values are IntEnums carrying the protocol nibble as their value (no lookup dicts): PanasonicAcMode, PanasonicAcFanSpeed, PanasonicAcSwingAxis1 (byte 16 low nibble), PanasonicAcSwingAxis2 (byte 17 low nibble), and PanasonicAcToggle.

Notes (responses to review)

  • Dropped the HK-specific class. PanasonicAcHkCommand and the separate framing base are gone; everything is the generic PanasonicAcCommand on top of Kaseikyo.
  • Swing is modelled per protocol slot, not physical direction. The physical louver a slot drives depends on the unit (window units: axis 1 = horizontal; split units: axis 1 = vertical, axis 2 = horizontal), so the enums are named Axis1/Axis2 and the caller maps axis → real-world direction. The 2-axis swing values follow the IRremoteESP8266 constants.
  • Timings use Kaseikyo's canonical base unit (~421 µs at 38 kHz) rather than the ~432 µs Panasonic-AC values; the small delta is well within IR receiver tolerance (will re-verify on hardware).

The reverse-engineered protocol (frame layout, field encodings, checksum, timings) is documented here: https://github.com/sam0737/panasonic_window_ac_hk/blob/main/custom_components/panasonic_window_ac_hk/PROTOCOL.md

Testing

  • tests/commands/test_panasonic_ac.py — encodes through the full stack, then decodes the raw timings back to bytes and asserts against the documented known-good frames. This keeps the tests robust to Kaseikyo timing-constant tweaks (those exact timings stay pinned in test_kaseikyo.py). Plus field-level checks: power bit, nanoeX, both swing axes, and out-of-range temperature.
  • uv run pytest -q — all pass.
  • uv run prek --all-files — ruff + basedpyright pass.

Related work

This backs the Home Assistant panasonic_window_ac_hk integration (see home-assistant/home-assistant.io#45662), which has been updated to map its state onto these generic commands once this is released.

Made with Cursor

Introduce a generic PanasonicAcCommand that encodes the shared Panasonic A/C
two-section framing (8-byte section 1 + variable section 2, LSB-first, 38 kHz),
and a PanasonicAcHkCommand subclass that builds the full state and
Quiet/Powerful short frames for Hong Kong/Macau models (CW-HU/HZ/SU/SUL).

Co-authored-by: Cursor <cursoragent@cursor.com>
Copilot AI review requested due to automatic review settings May 31, 2026 14:56
Comment thread infrared_protocols/commands/panasonic_ac_hk.py Outdated
Comment thread infrared_protocols/commands/panasonic_ac_hk.py Outdated
Comment thread infrared_protocols/commands/panasonic_ac_hk.py Outdated
Comment thread infrared_protocols/commands/panasonic_ac.py Outdated
Comment thread tests/commands/test_panasonic_ac.py Outdated
Comment thread infrared_protocols/commands/panasonic_ac.py Outdated
Comment thread infrared_protocols/commands/panasonic_ac_hk.py Outdated
Comment thread infrared_protocols/commands/panasonic_ac_hk.py Outdated
Comment thread tests/commands/test_panasonic_ac.py Outdated
Comment thread tests/commands/test_panasonic_ac_hk.py Outdated
Comment thread infrared_protocols/commands/panasonic_ac.py
@abmantis abmantis marked this pull request as draft June 1, 2026 17:55
…stead, and add multi-frame data support to it. Remove PanasonicAcHkCommand

- Modified KaseikyoCommand to accept `data` as either a single `bytes` or a `list[bytes]`, allowing for multi-frame IR commands.
- Enhanced the initialization docstring to clarify the usage of `data`.
- Removed the PanasonicAcHkCommand and its associated tests, consolidating functionality into the PanasonicAcCommand.
- Updated PanasonicAcCommand to handle the new multi-frame structure and maintain compatibility with existing features.
@sam0737 sam0737 requested review from abmantis and stephenwq June 2, 2026 20:36
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.

3 participants