prusalink: extract PrusaLinkEntityDescription base class#170092
Merged
joostlek merged 3 commits intoMay 8, 2026
Conversation
Add a shared PrusaLinkEntityDescription dataclass (inheriting from HA's EntityDescription) with `available_fn` and `supported_fn` predicates. The per-platform description classes (sensor, binary_sensor, button) now inherit from it so the duplicated `available_fn` field disappears. Camera, which had no entity description before, uses a PrusaLinkEntityDescription instance directly with `key="job_preview"` and `translation_key="job_preview"` (replacing the class-level `_attr_translation_key`). The `available` property moves from the per-entity classes to PrusaLinkEntity, so sensor.py, button.py, and camera.py drop their overrides. Direct attribute access works because `entity_description` is now typed as PrusaLinkEntityDescription on the base — no getattr fallback needed. Camera's job-data-dependent availability check is expressed as `available_fn` on its entity description. All entity description dataclasses (the Mixin classes and the main descriptions) are now `kw_only=True` so the inherited fields with defaults compose with the Mixin's required fields without ordering errors. Per @edenhaus' review feedback on home-assistant#169310. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9 tasks
Contributor
There was a problem hiding this comment.
Pull request overview
Refactors the prusalink integration’s entity-description structure by introducing a shared PrusaLinkEntityDescription so cross-platform predicates (available_fn, supported_fn) and the available implementation live in one place instead of being duplicated per platform.
Changes:
- Added
PrusaLinkEntityDescription(withavailable_fn/supported_fn) and movedavailabletoPrusaLinkEntity. - Updated sensor, binary_sensor, and button entity description dataclasses to inherit from the new base and removed duplicated
availableoverrides. - Converted the camera entity to use an
entity_descriptionwithtranslation_keyand anavailable_fn, removing the customavailableoverride.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| homeassistant/components/prusalink/entity.py | Introduces shared PrusaLinkEntityDescription and centralizes available logic in PrusaLinkEntity. |
| homeassistant/components/prusalink/sensor.py | Uses the shared base description and removes the sensor-specific available override. |
| homeassistant/components/prusalink/binary_sensor.py | Uses the shared base description and sets description dataclasses to kw_only=True. |
| homeassistant/components/prusalink/button.py | Uses the shared base description and removes the button-specific available override. |
| homeassistant/components/prusalink/camera.py | Adds an entity_description for the camera with availability defined via available_fn and switches to translation_key. |
Camera entities expect a `CameraEntityDescription` (HA's `Camera` base class declares the type), so the camera's description should also satisfy that contract — not just `PrusaLinkEntityDescription`. Introduce `PrusaLinkCameraEntityDescription` that inherits from both, mirroring the pattern used by the sensor/binary_sensor/button descriptions which combine HA's platform description with ours. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
joostlek
requested changes
May 8, 2026
Contributor
|
Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍 |
The Mixin pattern was needed to keep required fields (no default) ahead of default fields in dataclass field ordering. With the recent move to `kw_only=True` on every description dataclass, fields are keyword-only and order between defaulted and required fields no longer matters — so the Mixin classes are pure indirection. Per @joostlek's review feedback. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
joostlek
approved these changes
May 8, 2026
heikkih
added a commit
to heikkih/homeassistant-core
that referenced
this pull request
May 8, 2026
Three binary sensors backed by data already fetched by existing coordinators — no pyprusalink changes needed. All inherit the shared `PrusaLinkEntityDescription` (which provides `available_fn` and `supported_fn`) introduced in home-assistant#170092. | Entity | Source | Default | Created when | |---|---|---|---| | SD card (`info.sd_ready`) | /api/v1/info | Disabled | Printer firmware exposes `sd_ready` | | Farm mode (`info.farm_mode`) | /api/v1/info | Disabled | Printer firmware exposes `farm_mode` | | Connectivity (`printer.status_connect.ok`) | /api/v1/status | Enabled | User has set up PrusaConnect (`status_connect` is in the response) | The Connectivity sensor uses `BinarySensorDeviceClass.CONNECTIVITY`, so HA provides the entity name and `_connectivity` entity_id suffix automatically — no `translation_key` or strings entry needed for it. `supported_fn` filters out unsupported entities at setup time so they are not created (rather than created and marked unavailable). This matches the pattern used by sensor.py and the contract documented in home-assistant#170092. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proposed change
Extracts a shared
PrusaLinkEntityDescriptionbase class so the per-platform descriptions (sensor, binary_sensor, button, camera) no longer duplicate theavailable_fnfield, and so theavailableproperty can live onPrusaLinkEntityinstead of being copy-pasted across the per-platform entity classes.PrusaLinkEntityDescription(EntityDescription)inentity.pycarriesavailable_fnandsupported_fnPrusaLinkSensorEntityDescription,PrusaLinkBinarySensorEntityDescription,PrusaLinkButtonEntityDescription, and the newPrusaLinkCameraEntityDescriptionall inherit from it (combined with their respective HA platform descriptions)PrusaLinkEntity.availablereadsentity_description.available_fndirectly — nogetattrfallback needed since the description type is knownPrusaLinkCameraEntityDescription(which inherits from bothCameraEntityDescriptionandPrusaLinkEntityDescription). Its job-data-dependent availability check is expressed asavailable_fnon the description, so theavailableoverride is gone too. The class-level_attr_translation_keyis replaced bytranslation_key="job_preview"on the description.kw_only=Trueso inherited fields with defaults compose cleanly with required fields.*EntityDescriptionMixinclasses are merged into the main description classes — they were only needed to keep required fields ahead of default fields in dataclass ordering, which no longer matters withkw_only=True.Notes for reviewers
translation_key(unchanged). Camera previously used_attr_translation_key="job_preview"; nowentity_description.translation_key="job_preview"— same resulting entity_id (camera.<device>_job_preview).bool()so the property's declaredboolreturn type is satisfied (the previous version could return a truthy thumbnail string).kw_only=Trueon the description dataclasses doesn't change call sites since all existing instantiations already use keyword arguments. It's required so the inherited defaulted fields (available_fn,supported_fn) compose with the platform descriptions' required fields without dataclass field-ordering errors.PrusaLinkCameraEntityDescriptioncombinesCameraEntityDescription(HA's contract forCameraentities) andPrusaLinkEntityDescription(our shared predicates), mirroring the pattern used by the other platforms.Why
This is the canonical HA pattern for integrations with multiple entity platforms: a single base entity description carries the cross-platform predicates (
available_fn,supported_fn) so each platform doesn't redefine them, and theavailableproperty lives on the shared base entity. Beyond removing duplication, it makes the typing precise — we can drop thegetattrfallbacks I had added in #169310 becauseentity_descriptionis now typed asPrusaLinkEntityDescriptionon the base.Credit to @edenhaus for catching this during review of #169310 and pointing toward the right structure, and to @joostlek for the follow-up that we no longer need the Mixin classes once descriptions are
kw_only=True. Splitting it into its own PR because the typing change touchesbutton.pyandcamera.pywhich are otherwise unrelated to that PR's scope (binary sensors).Type of change
Checklist