Skip to content
This repository was archived by the owner on May 13, 2026. It is now read-only.

Modernize entity state via _attr_ pattern instead of @property#120

Merged
shbatm merged 6 commits into
devfrom
feat/attr-property-migration
Apr 30, 2026
Merged

Modernize entity state via _attr_ pattern instead of @property#120
shbatm merged 6 commits into
devfrom
feat/attr-property-migration

Conversation

@shbatm

@shbatm shbatm commented Apr 30, 2026

Copy link
Copy Markdown
Owner

Summary

Migrates entity state accessors from @property to the modern _attr_* pattern across 6 platform files, following current Home Assistant development standards. Intended to merge after chore/modernize-linting-tooling.

  • climate: Remove redundant @property target_temperature_step and @property fan_modes — both shadowed already-correct class-level _attr_ variables (silent bugs)
  • entity (ISYNodeEntity.available): Set _attr_available in __init__ from node's initial enabled state; refreshed in async_on_update on availability events
  • switch (ISYEnableSwitchEntity): Replace trivial available = True @property with class-level _attr_available = True
  • lock: Both ISYLockEntity and ISYLockProgramEntity initialise _attr_is_locked in async_added_to_hass and update it in an overridden async_on_update
  • cover: ISYCoverEntity extracts a _update_cover_attrs() helper for is_closed and current_cover_position; ISYCoverProgramEntity follows the same pattern
  • fan: speed_count is set in __init__/class-level (protocol-based, constant); is_on and percentage computed in async_on_update via _update_fan_attrs()

Relates to

Modernization review item #2 — Modernizing HA Core Patterns.

Test plan

  • Load integration with Insteon thermostat — verify target_temperature_step and fan_modes still reported correctly
  • Toggle a node-enabled flag on ISY — verify available updates on HA entity
  • Lock/unlock ISY lock device — verify is_locked state updates correctly
  • Open/close/position a cover — verify is_closed and current_cover_position update correctly
  • Control a fan — verify is_on, percentage, and speed_count report correctly for both Insteon (3-speed) and generic fans

🤖 Generated with Claude Code

shbatm and others added 6 commits April 30, 2026 07:49
- Replace black + isort with ruff-format and ruff I rules
- Update ruff config to modern [tool.ruff.lint] structure with PyISY's
  comprehensive rule selection and required-version = ">=0.15.12"
- Set line-length = 88 (HA Core standard)
- Fix per-file-ignores that incorrectly referenced pyisyox/ paths
- Remove [tool.black], [tool.isort], and [tool.pylint.*] from pyproject.toml
  (pylint config lives in .pylintrc; black/isort replaced by ruff)
- Add [tool.pytest.ini_options] and [tool.codespell] to pyproject.toml
- Update codespell to use pyproject.toml [tool.codespell] section instead of
  inline --ignore-words-list arg
- Bump ruff -> v0.15.12, codespell -> v2.4.2, yamllint -> v1.38.0,
  prettier-plugin-sort-json -> 4.2.0 (matches HA Core)
- Consolidate pull.yml + push.yml + validate.yaml into single ci.yml; replace
  bare black style job with pre-commit/action; skip mypy and pylint in CI
  (require full venv via run-in-env.sh, matching HA Core pattern); bump action
  versions to checkout@v5, setup-python@v6
- Delete setup.cfg: pytest config migrated to pyproject.toml; isort config dropped

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix import ordering (isort)
- Simplify nested conditionals (SIM102) and string concatenation (RUF005)
- Apply PIE810 startswith-with-tuple and SIM103 return-condition-directly
- Wrap long lines in comments, docstrings, and code
- Suppress RUF012 (mutable class attrs) and PERF401 (list comprehension
  in entity setup) as they require broader refactors or match HA patterns

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Apply ruff-format to const.py, light.py, number.py
- Wrap long comment lines in tests/conftest.py (E501)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces dynamic @Property state accessors with _attr_* instance
variables updated in async_on_update callbacks, following current
Home Assistant patterns. Static values become class-level attributes.

- climate: remove @Property overrides for target_temperature_step and
  fan_modes that shadowed already-set _attr_ class variables
- entity (ISYNodeEntity): migrate available to _attr_available, set on
  init and refreshed in async_on_update
- switch (ISYEnableSwitchEntity): available=True becomes class-level
  _attr_available, eliminating a trivial @Property
- lock: both ISYLockEntity and ISYLockProgramEntity compute is_locked
  in async_on_update and initialise in async_added_to_hass
- cover: ISYCoverEntity extracts _update_cover_attrs helper for
  current_cover_position and is_closed; ISYCoverProgramEntity follows
  same pattern for is_closed
- fan: speed_count set in __init__ (ISYFanEntity) or as class attr
  (ISYFanProgramEntity) since protocol does not change; is_on and
  percentage computed in async_on_update via shared _update_fan_attrs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lbacks

Two fixes from PR review:

[CRITICAL] ISYEnableSwitchEntity.available must always be True regardless
of node.enabled. ISYNodeEntity.__init__ now sets _attr_available =
node.enabled, and async_on_update keeps it in sync — both of which would
incorrectly mark the enable switch unavailable when the node is disabled,
locking the user out from re-enabling via HA.

Fix: set self._attr_available = True in ISYEnableSwitchEntity.__init__
*after* super().__init__ runs, and override async_on_update to skip the
availability update entirely (just calls async_write_ha_state directly).

[SUGGESTION] Program-based entities (ISYCoverProgramEntity,
ISYFanProgramEntity, ISYLockProgramEntity) were calling
self.async_write_ha_state() directly in async_on_update. Changed to
super().async_on_update(event, key) for consistency with node-based
entities and to pick up any future base-class behaviour automatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@shbatm
shbatm merged commit 4facc97 into dev Apr 30, 2026
2 checks passed
@shbatm
shbatm deleted the feat/attr-property-migration branch April 30, 2026 18:52
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant