Skip to content

zgp: add the Green Power types, frame, and crypto parsing core#1847

Open
nmingam wants to merge 4 commits into
zigpy:devfrom
nmingam:zgp-types-core
Open

zgp: add the Green Power types, frame, and crypto parsing core#1847
nmingam wants to merge 4 commits into
zigpy:devfrom
nmingam:zgp-types-core

Conversation

@nmingam

@nmingam nmingam commented Jul 2, 2026

Copy link
Copy Markdown

Standalone Green Power parsing core, split out of #1814 so it can land on its own — following @puddly's suggestion to get the types/command parsing in first and shrink the larger PR.

Contents

  • zgp/types.py: GPD command IDs, GP endpoint/cluster/group constants, the default GP link key, and fixes to SecurityLevel and the ProxyCommissioningModeExitMode bitmap
  • zgp/frame.py: GP Commissioning (0xE0) and Channel Request (0xE3) payload parsing and serialization
  • zgp/crypto.py: AES-128-CCM* nonce construction, key and payload (de)encryption per ZGP spec A.1.5.4 / A.3.7.1.2.3
  • zcl/clusters/greenpower.py: GP Commissioning Notification / Response / Proxy Commissioning Mode ZCL schema fixes
  • tests/zgp/: test_types, test_frame, test_crypto — 100% line coverage of the four modules above

The manager, device, and proxy layers that build on this core are intentionally left out and will follow in separate PRs.

Credits

  • @puddly — the CCM* associated-data (SrcID) fix for GPD key (de)encryption (A.3.7.1.2.3); credited as co-author on the commit.
  • Thanks to @konistehrad (original draft ZGP implementation), @mineshaftgap (radio-side/EZSP fixes) and @dmatscheko (real-hardware testing) for the broader ZGP effort this series is part of.

Carve out the radio-agnostic Green Power parsing layer as a standalone,
self-contained unit:

- types.py: GPD command IDs, GP endpoint/cluster/group constants, the
  default GP link key, and fixes to SecurityLevel and the
  ProxyCommissioningModeExitMode bitmap
- frame.py: GP Commissioning (0xE0) and Channel Request (0xE3) payload
  parsing and serialization
- crypto.py: AES-128-CCM* nonce construction, key (de)encryption, and
  payload (de)encryption per ZGP spec A.1.5.4 / A.3.7.1.2.3
- greenpower.py: correct the GP Commissioning Notification, Response, and
  Proxy Commissioning Mode ZCL schemas against the spec figures

The manager, device, and proxy layers that build on this core are left
out and will follow in separate PRs.

Co-authored-by: puddly <[email protected]>
@codecov

codecov Bot commented Jul 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.48%. Comparing base (925ea3d) to head (4634b55).

Additional details and impacted files
@@           Coverage Diff            @@
##              dev    #1847    +/-   ##
========================================
  Coverage   99.47%   99.48%            
========================================
  Files          57       59     +2     
  Lines       12026    12214   +188     
========================================
+ Hits        11963    12151   +188     
  Misses         63       63            

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@puddly puddly left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This looks good, just a few comments.

Comment thread tests/zgp/test_types.py Outdated
assert "0x" in repr(d).lower()


def test_no_security():

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can remove any unit tests that assert that value of an enum. They're not really useful tests.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dropped the bare assert Enum.Member == 0bNN tests — agreed they weren't pulling weight. Kept the handful that check actual behavior: the protocol constants (endpoint/cluster/group IDs, the default link key), DeviceID uint32 coercion + hex repr, and the bitmap OR-composition test.

Comment thread zigpy/zgp/crypto.py Outdated
Comment thread zigpy/zgp/frame.py Outdated
nmingam added 3 commits July 3, 2026 08:58
Replace the manual bit masks and offset parsing in frame.py with
IntStruct options bytes and a Struct payload with requires-gated
fields, per review. GPChannelRequestPayload now exposes the raw
channel nibbles; consumers apply the +11 offset.
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.

2 participants