Skip to content

Add Data Grand Lyon integration#167946

Open
Crocmagnon wants to merge 5 commits intohome-assistant:devfrom
Crocmagnon:devel/Crocmagnon/tcl
Open

Add Data Grand Lyon integration#167946
Crocmagnon wants to merge 5 commits intohome-assistant:devfrom
Crocmagnon:devel/Crocmagnon/tcl

Conversation

@Crocmagnon
Copy link
Copy Markdown

@Crocmagnon Crocmagnon commented Apr 10, 2026

Proposed change

New integration for Data Grand Lyon open data platform. Supports config subentries for transit stops (with estimated/theoretical passage merging) and bike sharing stations (with electrical/mechanical bike breakdown).

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

Checklist

  • I understand the code I am submitting and can explain how it works.
  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist (documentation TODO)
  • I have followed the perfect PR recommendations
  • The code has been formatted using Ruff (ruff format homeassistant tests)
  • Tests have been added to verify that the new code works.
  • Any generated code has been carefully reviewed for correctness and compliance with project standards.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • For the updated dependencies a diff between library versions and ideally a link to the changelog/release notes is added to the PR description.

To help with the load of incoming pull requests:

Enregistrement d'écran_20260411_104705.webm
Enregistrement d'écran_20260411_104606.webm

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a new tcl Home Assistant integration for Lyon (TCL) public transit and Vélo'v bike-sharing, including config flows with subentries and sensor entities backed by a coordinator.

Changes:

  • Adds TCL integration implementation (config flow + coordinator + sensor platform + translations/manifest/quality scale).
  • Adds automated tests for the integration’s config flow and subentry flows.
  • Registers the integration in generated indices and adds the upstream dependency to requirements.

Reviewed changes

Copilot reviewed 14 out of 16 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
tests/components/tcl/test_config_flow.py Adds config flow + subentry flow tests for TCL integration.
tests/components/tcl/conftest.py Adds shared fixture to patch async_setup_entry during tests.
tests/components/tcl/init.py Adds tests package marker for TCL.
requirements_test_all.txt Adds transports-commun-lyon to the test requirements set.
requirements_all.txt Adds transports-commun-lyon to the runtime requirements set.
homeassistant/generated/integrations.json Registers the new tcl integration for discovery/metadata.
homeassistant/generated/config_flows.py Registers tcl as supporting config flows.
homeassistant/components/tcl/strings.json Adds UI strings for config flow, subentries, and entity translations.
homeassistant/components/tcl/sensor.py Implements stop and Vélo'v sensors using the coordinator pattern.
homeassistant/components/tcl/quality_scale.yaml Declares current quality-scale rule status for the new integration.
homeassistant/components/tcl/manifest.json Adds manifest metadata and pins dependency version.
homeassistant/components/tcl/coordinator.py Adds coordinator to fetch/merge passages and fetch station status.
homeassistant/components/tcl/const.py Defines constants for keys/subentry types and passage count.
homeassistant/components/tcl/config_flow.py Implements main config flow, reauth, and subentry flows.
homeassistant/components/tcl/init.py Wires up coordinator, update listener, and forwards platform setup.
CODEOWNERS Assigns ownership for new integration code and tests.

Comment thread homeassistant/components/tcl/config_flow.py Outdated
Comment thread homeassistant/components/tcl/config_flow.py Outdated
Comment thread homeassistant/components/data_grandlyon/config_flow.py Outdated
Comment thread homeassistant/components/data_grandlyon/config_flow.py Outdated
Comment thread homeassistant/components/tcl/sensor.py Outdated
Comment thread homeassistant/components/tcl/coordinator.py Outdated
Comment thread homeassistant/components/tcl/coordinator.py Outdated
Comment thread homeassistant/components/data_grandlyon/quality_scale.yaml Outdated
Comment thread homeassistant/components/tcl/quality_scale.yaml Outdated
Comment thread homeassistant/components/tcl/quality_scale.yaml Outdated
Copilot AI review requested due to automatic review settings April 10, 2026 22:27
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 17 changed files in this pull request and generated 9 comments.

Comments suppressed due to low confidence (1)

homeassistant/components/tcl/manifest.json:1

  • The manifest includes several empty fields (dependencies, homekit, ssdp, zeroconf). If these are not intentionally required by hassfest for this integration, consider removing them to reduce noise and keep the manifest focused on meaningful declarations.
{

Comment thread homeassistant/components/data_grandlyon/config_flow.py Outdated
Comment thread homeassistant/components/data_grandlyon/coordinator.py Outdated
Comment thread homeassistant/components/tcl/coordinator.py Outdated
Comment thread homeassistant/components/tcl/config_flow.py Outdated
Comment thread homeassistant/components/tcl/config_flow.py Outdated
Comment thread homeassistant/components/tcl/coordinator.py Outdated
Comment thread homeassistant/components/data_grandlyon/quality_scale.yaml
Comment thread homeassistant/components/tcl/quality_scale.yaml Outdated
Comment thread tests/components/tcl/conftest.py
@Crocmagnon Crocmagnon marked this pull request as draft April 10, 2026 22:31
Copilot AI review requested due to automatic review settings April 10, 2026 22:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 17 changed files in this pull request and generated 6 comments.

Comment thread homeassistant/components/tcl/config_flow.py Outdated
Comment thread homeassistant/components/tcl/config_flow.py Outdated
Comment thread homeassistant/components/tcl/config_flow.py Outdated
Comment thread homeassistant/components/tcl/sensor.py Outdated
Comment thread homeassistant/components/tcl/manifest.json Outdated
Comment thread homeassistant/components/tcl/manifest.json Outdated
Copilot AI review requested due to automatic review settings April 10, 2026 22:47
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 17 changed files in this pull request and generated 3 comments.

Comment thread homeassistant/components/tcl/coordinator.py Outdated
Comment thread homeassistant/components/tcl/sensor.py Outdated
Comment thread homeassistant/components/tcl/sensor.py Outdated
Copilot AI review requested due to automatic review settings April 10, 2026 22:51
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 17 changed files in this pull request and generated 4 comments.

Comment thread homeassistant/components/tcl/coordinator.py Outdated
Comment thread homeassistant/components/tcl/sensor.py Outdated
Comment thread homeassistant/components/data_grandlyon/quality_scale.yaml
Comment thread homeassistant/components/data_grandlyon/sensor.py Outdated
Copilot AI review requested due to automatic review settings April 10, 2026 23:00
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 16 out of 18 changed files in this pull request and generated 2 comments.

Comment thread homeassistant/components/tcl/coordinator.py Outdated
Comment thread tests/components/tcl/test_sensor.py
Copilot AI review requested due to automatic review settings April 11, 2026 08:11
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 17 changed files in this pull request and generated 2 comments.

Comment thread homeassistant/components/data_grandlyon/config_flow.py
Comment thread homeassistant/components/tcl/sensor.py Outdated
Copilot AI review requested due to automatic review settings April 11, 2026 13:28
@Crocmagnon Crocmagnon force-pushed the devel/Crocmagnon/tcl branch from 1e1d56d to ea8ae45 Compare April 11, 2026 13:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 19 changed files in this pull request and generated 7 comments.

Comment thread homeassistant/components/data_grandlyon/config_flow.py
Comment thread homeassistant/components/data_grandlyon/config_flow.py Outdated
Comment thread homeassistant/components/data_grandlyon/config_flow.py Outdated
Comment thread homeassistant/components/data_grandlyon/strings.json Outdated
Comment thread homeassistant/components/data_grandlyon/coordinator.py Outdated
Comment thread homeassistant/components/data_grandlyon/coordinator.py
Comment thread homeassistant/components/data_grandlyon/coordinator.py Outdated
@Crocmagnon Crocmagnon force-pushed the devel/Crocmagnon/tcl branch from ea8ae45 to 2125708 Compare April 11, 2026 13:43
@Crocmagnon Crocmagnon force-pushed the devel/Crocmagnon/tcl branch from 2125708 to c056273 Compare April 11, 2026 14:14
@Crocmagnon Crocmagnon marked this pull request as ready for review April 11, 2026 14:14
Copilot AI review requested due to automatic review settings April 11, 2026 14:14
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 19 changed files in this pull request and generated 6 comments.

Comment thread homeassistant/components/data_grandlyon/config_flow.py
Comment thread homeassistant/components/data_grandlyon/config_flow.py Outdated
Comment thread homeassistant/components/data_grandlyon/config_flow.py Outdated
velov[subentry.subentry_id] = velov_result

if (stop_subentries or velov_subentries) and not stops and not velov:
raise UpdateFailed("Error fetching DataGrandLyon data: all requests failed")
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

The UpdateFailed message is user/diagnostic-facing and currently uses an internal-looking name (DataGrandLyon) and doesn’t provide actionable context. Consider using the proper integration name (Data Grand Lyon) and adding minimal detail (e.g., number of stop/station requests and that all failed) to improve troubleshooting without being overly verbose.

Suggested change
raise UpdateFailed("Error fetching DataGrandLyon data: all requests failed")
raise UpdateFailed(
f"Error fetching Data Grand Lyon data: all {len(stop_subentries)} "
f"stop request(s) and {len(velov_subentries)} Vélo'v station "
"request(s) failed"
)

Copilot uses AI. Check for mistakes.
Comment on lines +89 to +93
LOGGER.warning(
"Error fetching passages for stop %s: %s",
subentry.subentry_id,
result,
)
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

These warnings drop the traceback even though you have the actual exception object. Logging with exc_info=... (or using LOGGER.exception where appropriate) would preserve stack traces, which materially improves field diagnostics when API/library failures occur.

Copilot uses AI. Check for mistakes.
Comment on lines +100 to +105
if isinstance(velov_result, BaseException):
LOGGER.warning(
"Error fetching Vélo'v station %s: %s",
subentry.subentry_id,
velov_result,
)
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

These warnings drop the traceback even though you have the actual exception object. Logging with exc_info=... (or using LOGGER.exception where appropriate) would preserve stack traces, which materially improves field diagnostics when API/library failures occur.

Copilot uses AI. Check for mistakes.
New integration for Data Grand Lyon open data platform.
Supports config subentries for transit stops (with estimated/theoretical
passage merging) and bike sharing stations (with electrical/mechanical bike
breakdown).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Crocmagnon Crocmagnon force-pushed the devel/Crocmagnon/tcl branch from c056273 to ab0f34c Compare April 11, 2026 14:20
Comment on lines +69 to +78
@classmethod
@callback
def async_get_supported_subentry_types(
cls, config_entry: ConfigEntry
) -> dict[str, type[ConfigSubentryFlow]]:
"""Return subentry types supported by this integration."""
return {
SUBENTRY_TYPE_STOP: StopSubentryFlowHandler,
SUBENTRY_TYPE_VELOV: VelovSubentryFlowHandler,
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we start with a single sub entry type?

Comment on lines +106 to +139
async def async_step_reconfigure(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle reconfiguration of the main config entry."""
errors: dict[str, str] = {}

if user_input is not None:
data: dict[str, Any] = {}
if username := user_input.get(CONF_USERNAME):
data[CONF_USERNAME] = username
if password := user_input.get(CONF_PASSWORD):
data[CONF_PASSWORD] = password

if error := await self._test_connection(data):
errors["base"] = error
else:
return self.async_update_reload_and_abort(
self._get_reconfigure_entry(),
data=data,
)

return self.async_show_form(
step_id="reconfigure",
data_schema=self.add_suggested_values_to_schema(
STEP_USER_DATA_SCHEMA,
self._get_reconfigure_entry().data,
),
errors=errors,
)

async def async_step_reauth(
self, entry_data: Mapping[str, Any]
) -> ConfigFlowResult:
"""Handle initiation of re-authentication."""
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we keep reconfigure and reauth out for the first PR?

Comment on lines +32 to +33
stops: dict[str, list[TclPassage]] = field(default_factory=dict)
velov: dict[str, VelovStation | None] = field(default_factory=dict)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

no need for a default factory right?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why do you run a single coordinator? You could split it in theory

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.

I'm not very familiar with HA core, this is my first experience. How do you suggest to split the coordinator? One for each sub-entry type?

Comment on lines +45 to +50
discovery-update-info:
status: exempt
comment: Devices can't be discovered.
discovery:
status: exempt
comment: Devices can't be discovered.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

rather explain that this is a service

Comment on lines +104 to +120
for subentry_id, subentry in entry.subentries.items():
if subentry.subentry_type == SUBENTRY_TYPE_STOP:
async_add_entities(
(
DataGrandLyonStopSensor(coordinator, subentry, description)
for description in STOP_SENSOR_DESCRIPTIONS
),
config_subentry_id=subentry_id,
)
elif subentry.subentry_type == SUBENTRY_TYPE_VELOV:
async_add_entities(
(
DataGrandLyonVelovSensor(coordinator, subentry, description)
for description in VELOV_SENSOR_DESCRIPTIONS
),
config_subentry_id=subentry_id,
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ideally we run async_add_entities as little as possible, so if we can limit it to 2 by iterating over the list (which you can make smaller with the entry.get_subentries_of_type helper)

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.

I'm not sure I understand. The config_subentry_id param for async_add_entities forces me to call it for each sub-entry, doesn't it?

@home-assistant home-assistant bot marked this pull request as draft April 17, 2026 22:10
@home-assistant
Copy link
Copy Markdown

Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍

Learn more about our pull request process.

Crocmagnon and others added 2 commits April 18, 2026 14:29
- Remove Vélo'v (bike-sharing) subentry type; keep only TCL transit stop
- Remove reconfigure and reauth flows (defer to follow-up PR)
- Simplify coordinator to stop-only data, remove unused default_factory
- Use entry.get_subentries_of_type() in sensor setup
- Downgrade quality scale to bronze (silver requires reauthentication-flow)
- Update quality_scale.yaml: mark reauthentication-flow and
  reconfiguration-flow as todo, clarify discovery exemption comments

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 18, 2026 14:30
@Crocmagnon
Copy link
Copy Markdown
Author

Thank you for your review @joostlek, I've pushed a commit to address your feedback. I got a bit carried away in my initial commit so the PR was indeed not as minimal as it could've been.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 19 changed files in this pull request and generated 5 comments.

Comment on lines +27 to +31
STEP_USER_DATA_SCHEMA = vol.Schema(
{
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
}
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

Allow credentials to be optional here if the integration supports an unauthenticated setup (tests submit an empty dict); otherwise the flow can never be completed without entering both fields.

Copilot uses AI. Check for mistakes.
Comment on lines +73 to +76
if error := await self._test_connection(data):
errors["base"] = error
else:
return self.async_create_entry(title="Data Grand Lyon", data=data)
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

Avoid running the connection test when both username and password are omitted (currently an empty submission will still reach _test_connection and be treated as an auth error).

Suggested change
if error := await self._test_connection(data):
errors["base"] = error
else:
return self.async_create_entry(title="Data Grand Lyon", data=data)
if data:
if error := await self._test_connection(data):
errors["base"] = error
else:
return self.async_create_entry(title="Data Grand Lyon", data=data)

Copilot uses AI. Check for mistakes.
Returns None on success, or an error key for the errors dict.
"""
if not data.get(CONF_USERNAME):
return "invalid_auth"
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

Don’t return invalid_auth just because username is missing; if anonymous mode is supported, treat missing credentials as a successful no-op test (or skip this method entirely) so the flow can create the entry.

Suggested change
return "invalid_auth"
return None

Copilot uses AI. Check for mistakes.
stops: dict[str, list[TclPassage]] = {}
for i, subentry in enumerate(stop_subentries):
result = stop_results[i]
if isinstance(result, BaseException):
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

Handle asyncio.CancelledError separately (or only treat Exception as a per-stop failure) so cancellation isn’t swallowed/logged as a normal fetch error.

Suggested change
if isinstance(result, BaseException):
if isinstance(result, asyncio.CancelledError):
raise result
if isinstance(result, Exception):

Copilot uses AI. Check for mistakes.
Comment on lines +2 to +6
"domain": "data_grandlyon",
"name": "Data Grand Lyon",
"codeowners": ["@Crocmagnon"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/data_grandlyon",
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

Align the PR description with the code in this PR: the current implementation only adds transit stop subentries/sensors (no bike sharing subentries or passage merging logic are present).

Copilot uses AI. Check for mistakes.
Username and password are required since the only subentry type (TCL
stop) needs authentication. Update the schema to vol.Required and
drop the no-credentials test; fix test_form_already_configured to
pass credentials and mock the API call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 18, 2026 15:04
@Crocmagnon Crocmagnon force-pushed the devel/Crocmagnon/tcl branch from ee5bd7a to 3c1bafe Compare April 18, 2026 15:04
@Crocmagnon Crocmagnon marked this pull request as ready for review April 18, 2026 15:05
@home-assistant home-assistant bot requested a review from joostlek April 18, 2026 15:05
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 19 changed files in this pull request and generated 5 comments.

Comment on lines +62 to +75
stop_results: list[list[TclPassage] | BaseException] = await asyncio.gather(
*stop_tasks, return_exceptions=True
)

stops: dict[str, list[TclPassage]] = {}
for i, subentry in enumerate(stop_subentries):
result = stop_results[i]
if isinstance(result, BaseException):
LOGGER.warning(
"Error fetching passages for stop %s: %s",
subentry.subentry_id,
result,
)
continue
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

Avoid swallowing asyncio.CancelledError by treating only Exception results from asyncio.gather(..., return_exceptions=True) as failures (or explicitly re-raising cancellations).

Copilot uses AI. Check for mistakes.
if err.status in (401, 403):
return "invalid_auth"
return "cannot_connect"
except ClientError, TimeoutError:
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

Fix the exception handler syntax by using a tuple in the except clause so the module parses on current Python versions.

Suggested change
except ClientError, TimeoutError:
except (ClientError, TimeoutError):

Copilot uses AI. Check for mistakes.
Comment on lines +67 to +71
data: dict[str, Any] = {}
if username := user_input.get(CONF_USERNAME):
data[CONF_USERNAME] = username
if password := user_input.get(CONF_PASSWORD):
data[CONF_PASSWORD] = password
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

Store required credentials directly from user_input instead of conditionally adding them, since the current truthy checks can drop empty strings and create entries missing required keys.

Suggested change
data: dict[str, Any] = {}
if username := user_input.get(CONF_USERNAME):
data[CONF_USERNAME] = username
if password := user_input.get(CONF_PASSWORD):
data[CONF_PASSWORD] = password
data: dict[str, Any] = {
CONF_USERNAME: user_input[CONF_USERNAME],
CONF_PASSWORD: user_input[CONF_PASSWORD],
}

Copilot uses AI. Check for mistakes.
) -> SubentryFlowResult:
"""Handle the user step to add a new stop."""
entry = self._get_entry()
if not entry.data.get(CONF_USERNAME):
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

Require both username and password (or otherwise verify auth is configured) before allowing the stop subentry flow to proceed, since checking only CONF_USERNAME can allow creating subentries with incomplete credentials.

Suggested change
if not entry.data.get(CONF_USERNAME):
if not entry.data.get(CONF_USERNAME) or not entry.data.get(CONF_PASSWORD):

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +10
{
"domain": "data_grandlyon",
"name": "Data Grand Lyon",
"codeowners": ["@Crocmagnon"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/data_grandlyon",
"integration_type": "service",
"iot_class": "cloud_polling",
"quality_scale": "bronze",
"requirements": ["data-grand-lyon-ha==0.5.0"]
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

Align the PR description with the implementation, since this integration currently only adds transit stop subentries/sensors and does not include the described bike-station support.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants