Bump pyisy to 3.6.1 and modernize TLS handling for isy994#170136
Conversation
Drop the legacy TLS-version dropdown and let pyisy 3.6.0 negotiate TLS automatically with a 1.2 floor. Add a "Verify SSL" toggle (default off) that matches how eisy/Polisy/ISY-994 ship their self-signed certificates. Existing v1 config entries are migrated to v2 by silently dropping the stored "tls" key — no reauth required. Also distinguish TLS handshake failures from generic connection errors in the config flow, surfacing a dedicated "ssl_error" message via __cause__ inspection on aiohttp.ClientSSLError. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Hey there @bdraco, mind taking a look at this pull request as it has been labeled with an integration ( Code owner commandsCode owners of
|
There was a problem hiding this comment.
Pull request overview
Updates the isy994 integration to use pyisy 3.6.0 and shifts TLS handling from a user-selected TLS version to automatic negotiation plus an explicit “Verify SSL” option.
Changes:
- Bump
pyisydependency to 3.6.0 (and update derived requirements files). - Remove legacy TLS version selection and add
verify_sslhandling + a dedicatedssl_errorflow error. - Add config entry migration (v1 → v2) to drop the stored legacy
"tls"key, with new/updated tests.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/components/isy994/test_init.py | Adds coverage for config entry migration behavior. |
| tests/components/isy994/test_config_flow.py | Updates config flow tests for the new verify_ssl field (TLS version removed). |
| requirements_test_all.txt | Updates pinned test dependency for pyisy. |
| requirements_all.txt | Updates pinned runtime dependency for pyisy. |
| homeassistant/components/isy994/strings.json | Adds ssl_error messaging and updates user-step fields for verify_ssl. |
| homeassistant/components/isy994/manifest.json | Bumps integration requirement to pyisy==3.6.0. |
| homeassistant/components/isy994/const.py | Removes TLS-version constants and introduces DEFAULT_VERIFY_SSL. |
| homeassistant/components/isy994/config_flow.py | Implements verify_ssl + SSL-specific error mapping and bumps config flow version. |
| homeassistant/components/isy994/init.py | Adds config entry migration and passes verify_ssl into pyisy initialization. |
- Bump pyisy 3.6.0 → 3.6.1 (drops the stray top-level tests/ dir from the published wheel that hassfest rejected). - Pass verify_ssl into the aiohttp ClientSession for HTTPS in both the config flow and async_setup_entry, so the user's "Verify SSL" choice takes effect at the session level instead of relying solely on pyisy's per-request SSL context. - Add a config flow test covering the new ssl_error mapping path (ISYConnectionError chained from aiohttp.ClientSSLError). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Codecov flagged the new ssl_error catch in async_step_reauth_confirm and the verify_ssl-aware HTTPS session branch in validate_input as uncovered: - Extend test_reauth to chain a ClientSSLError-cause through the reauth flow before the success path, exercising the new except SslError branch. - Switch test_form_isy_ssl_error to use an HTTPS URL so the async_get_clientsession(..., verify_ssl=...) line in the HTTPS branch is also covered. Brings config_flow.py patch coverage to 100%; only remaining miss is a pre-existing line in OptionsFlowHandler unrelated to this PR. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@home-assistant update-branch |
|
Failed to update branch: refusing to allow a GitHub App to create or update workflow |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
tests/components/isy994/test_init.py:45
- Remove the unused
mock_isyfixture argument (it’s not referenced in the test body); relying on the autouse fixture avoids unused test parameters and keeps the test signature minimal.
async def test_migrate_future_version_fails(
hass: HomeAssistant,
mock_isy: MagicMock,
) -> None:
| async def async_migrate_entry(hass: HomeAssistant, entry: IsyConfigEntry) -> bool: | ||
| """Migrate old config entries.""" | ||
| _LOGGER.debug("Migrating ISY config entry from version %s", entry.version) | ||
|
|
||
| if entry.version > 2: | ||
| return False | ||
|
|
||
| if entry.version == 1: | ||
| # Drop the legacy "tls" version field; pyisy now negotiates automatically. | ||
| new_data = {key: value for key, value in entry.data.items() if key != "tls"} | ||
| hass.config_entries.async_update_entry(entry, data=new_data, version=2) | ||
|
|
||
| return True |
There was a problem hiding this comment.
So in a way I am like, by bumping the major version and removing the value, we kinda eliminate the ability to rollback for people, so I'd almost just avoid migrating
There was a problem hiding this comment.
I will re-work it to just add the new config option and silently ignore the old tls_version key without migrating. Now that I'm looking at it again I remember doing something similar back in #80984 and not forcing a migration. Do you want the version to be tagged as a minor bump (e.g. 1.1) if I do that?
There was a problem hiding this comment.
Reworked in b41568b to use MINOR_VERSION = 2 instead of bumping the major version — mirrors the pattern in yale_smart_alarm (drop legacy key + seed new key, no major bump, rollback preserved).
|
Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍 |
Address review feedback on home-assistant#170136: instead of bumping the major config entry version (which would have broken rollback), use MINOR_VERSION = 2 with an async_migrate_entry that drops the legacy "tls" key and seeds verify_ssl. Mirrors the pattern in yale_smart_alarm. Also use direct key indexing for verify_ssl now that migration guarantees the key is present, switch test_config_flow string literals to the matching CONF_* constants, and drop the unused mock_isy fixture arg in the new test_init. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Failed test on 89883bc looks unrelated ( |
Add parametrized assertions that the verify_ssl entry option is forwarded to pyisy's ISY constructor during async_setup_entry and to its Connection during config flow validation, so a future regression that drops the plumbing cannot pass tests. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
|
||
| # Optional | ||
| tls_version = isy_config.get(CONF_TLS_VER) | ||
| verify_ssl = isy_config[CONF_VERIFY_SSL] |
| password = data[CONF_PASSWORD] | ||
| host = urlparse(data[CONF_HOST]) | ||
| tls_version = data.get(CONF_TLS_VER) | ||
| verify_ssl = data[CONF_VERIFY_SSL] |
| ssl_cause = aiohttp.ClientSSLError( | ||
| connection_key=None, os_error=ssl.SSLError("handshake failed") | ||
| ) |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| async def async_migrate_entry(hass: HomeAssistant, entry: IsyConfigEntry) -> bool: | ||
| """Migrate old config entries.""" | ||
| if entry.version == 1 and entry.minor_version == 1: | ||
| new_data = {key: value for key, value in entry.data.items() if key != "tls"} | ||
| new_data.setdefault(CONF_VERIFY_SSL, DEFAULT_VERIFY_SSL) | ||
| hass.config_entries.async_update_entry(entry, data=new_data, minor_version=2) | ||
|
|
||
| return True |
|
|
||
| # Optional | ||
| tls_version = isy_config.get(CONF_TLS_VER) | ||
| verify_ssl = isy_config[CONF_VERIFY_SSL] |
There was a problem hiding this comment.
This is contrary to reviewer's original suggestion to NOT use .get(). Holding for @joostlek's preference.
| "invalid_auth": "[%key:common::config_flow::error::invalid_auth%]", | ||
| "invalid_host": "The host entry was not in full URL format, e.g., {sample_ip}", | ||
| "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]", | ||
| "ssl_error": "TLS handshake failed. The controller may require a newer TLS version, or SSL verification may be failing due to a self-signed certificate.", |
There was a problem hiding this comment.
Copilot doesn't like it's own suggested change...
Proposed change
Bumps
pyisyto 3.6.1 and modernizes TLS handling for theisy994integration:tls_ver). pyisy 3.6.x negotiates TLS automatically with a TLSv1.2 floor, so users no longer need to know what their controller supports.async_get_clientsession(..., verify_ssl=verify_ssl), so the user's choice applies at both the session layer and pyisy's per-request SSL context."tls"key on existing config entries via aMINOR_VERSION = 2bump —async_migrate_entrydrops the obsolete"tls"value and seedsCONF_VERIFY_SSLwith the default. A minor-version bump (rather than a major one) preserves rollback for users who need to downgrade, mirroring the pattern used inyale_smart_alarm.ssl_errormessage. Detection usesisinstance(error.__cause__, aiohttp.ClientSSLError), which covers both protocol mismatch (ClientConnectorSSLError) and certificate verification failure (ClientConnectorCertificateError).Library changes
__cause__for SSL errors), fix: enable legacy-renegotiation TLS compat on demand for ISY-994 automicus/PyISY#508 (legacy-renegotiation TLS compat for ISY-994)Type of change
Additional information
Checklist
ruff format homeassistant tests)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest.requirements_all.txt.Updated by running
python3 -m script.gen_requirements_all.