SKILL.md
Review Integration
Reviews a meter or charger integration for pattern compliance, correctness, and completeness.
Step 1: Resolve Target
If PR number (e.g., 42):
- Run
gh pr diff $ARGUMENTSto get changed files - Read all modified/added Python files in
meters/orchargers/
If file path (e.g., customcomponents/evseloadbalancer/meters/shellymeter.py):
- Read the file directly
- Infer related files: test file, const.py changes, factory changes
Step 2: Determine Type
From file paths, determine if this is a meter or charger. Read the implementation file(s).
Step 3: Read Reference Files
Read for comparison:
customcomponents/evseload_balancer/const.py(check registration)- Relevant factory
init.py(check registration) customcomponents/evseloadbalancer/configflow.py(check filter list for chargers)- One existing implementation of the same type for pattern comparison
- The base class (
meters/meter.pyorchargers/charger.py)
Step 4: Run Checklist
Evaluate each item. Mark as PASS, FAIL, or WARN with specific file:line references.
Base Class Compliance
- Correct inheritance order (
Meter, HaDeviceorHaDevice, ChargerorZigbee2Mqtt, Charger) - Both parent
initcalled explicitly (notsuper()) -
self.refresh_entities()called at end ofinit(HaDevice-based only) - All abstract methods implemented
- Correct return types
Entity Lookup
- Entity map defined with phase keys using
cf.CONFPHASEKEY_*constants - Entity map covers all three phases (L1, L2, L3)
- Consistent lookup method (not mixing key/translationkey/uniqueid)
-
getentitymapfor_phasehandles all phases + raises ValueError for invalid - Comment with link to upstream HA integration source
Error Handling
- None checks on all entity state reads
-
_LOGGER.warning()for missing states (not errors, not silent) - Error messages assigned to
msgbefore raise - No bare
raise Exception - Division by zero protected (voltage check before current calculation)
Naming & Style
- File:
<name>meter.pyor<name>charger.py - Class:
<Name>Meteror<Name>Charger - EntityMap/StatusMap follow naming convention
- Module docstring present
-
_LOGGERdefined at module level -
# noqa: TID252on parent package imports
Charger-Specific
-
ischargerdeviceis static, checksdevice.identifiers -
setcurrentlimitusesmin(limit.values())for single-value chargers -
setcurrentlimitusesblocking=Trueon service calls - Status hierarchy:
ischargingsubset ofcanchargesubset ofcar_connected -
asyncsetupandasyncunloadimplemented
Meter-Specific
-
getactivephase_currentreturnsint | None -
floor()used when computing current from power/voltage - Power units documented/converted correctly
-
gettrackingentitiesreturns correct entity_ids
Registration
- Domain constant in
const.py - Added to
SUPPORTEDMETERDEVICES(meters) orchargerdevicefilterlist(chargers) - Factory updated with import + branch/list entry
Tests
- Test file in
tests/meters/ortests/chargers/ - Standard fixtures (mockhass, mockconfigentry, mockdevice_entry)
- All abstract methods tested
- Status methods tested with valid AND invalid states
- None/missing state paths tested
- Factory test updated (meters)
Step 5: Automated Checks
ruff check <implementation_file>
pytest <test_file> -v 2>&1 || true
Step 6: Output Review
Format as:
## Integration Review: <Name> <Meter|Charger>
### Summary
<1-2 sentence assessment>
### Results
| Category | Status | Details |
|----------|--------|---------|
| Base Class | PASS/FAIL | ... |
| Entity Lookup | PASS/FAIL | ... |
| Error Handling | PASS/FAIL | ... |
| Naming & Style | PASS/FAIL | ... |
| Type-Specific | PASS/FAIL | ... |
| Registration | PASS/FAIL | ... |
| Tests | PASS/FAIL | ... |
### Issues
1. **[FAIL] <category>**: <description>
- File: <path>:<line>
- Fix: <specific suggestion>
### Suggestions
- <optional improvements, not blocking>
If issues are found, offer to fix them directly or describe the fixes needed for /create-integration to apply.