Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create, update and delete KNX entities from UI / WS-commands #104079

Merged
merged 51 commits into from
Jul 21, 2024

Conversation

farmio
Copy link
Contributor

@farmio farmio commented Nov 16, 2023

Proposed change

Create, update and delete KNX entities from Websocket commands.

This is the base for creating KNX entities from UI. The related frontend PR is found here: XKNX/knx-frontend#112 . Once this is merged the frontend can be released so a dependency upgrade can set this working.

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

  • This PR fixes or closes issue: fixes #
  • This PR is related to issue:
  • Link to documentation pull request:

Checklist

  • 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
  • I have followed the perfect PR recommendations
  • The code has been formatted using Black (black --fast homeassistant tests)
  • Tests have been added to verify that the new code works.

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 link to the changelog, or at minimum a diff between library versions is added to the PR description.
  • Untested files have been added to .coveragerc.

To help with the load of incoming pull requests:

@home-assistant
Copy link

Hey there @Julius2342, @marvin-w, mind taking a look at this pull request as it has been labeled with an integration (knx) you are listed as a code owner for? Thanks!

Code owner commands

Code owners of knx can trigger bot actions by commenting:

  • @home-assistant close Closes the pull request.
  • @home-assistant rename Awesome new title Renames the pull request.
  • @home-assistant reopen Reopen the pull request.
  • @home-assistant unassign knx Removes the current integration label and assignees on the pull request, add the integration domain after the command.

@farmio farmio force-pushed the knx-entity-creation branch 2 times, most recently from 8673b57 to 1736de7 Compare January 8, 2024 10:23
@farmio farmio force-pushed the knx-entity-creation branch from 1736de7 to 8a830f4 Compare January 18, 2024 15:44
@farmio farmio force-pushed the knx-entity-creation branch 2 times, most recently from 4477ac4 to b852ba4 Compare February 6, 2024 16:38
@farmio farmio force-pushed the knx-entity-creation branch from 2549850 to 3d7de94 Compare February 21, 2024 21:32
@farmio farmio force-pushed the knx-entity-creation branch 2 times, most recently from 5db4065 to 3b74b5d Compare March 27, 2024 21:41
@farmio farmio force-pushed the knx-entity-creation branch from 3b74b5d to f0876a5 Compare May 2, 2024 19:58
@farmio farmio force-pushed the knx-entity-creation branch from 53f21d5 to 02cb264 Compare May 15, 2024 08:12
@farmio farmio marked this pull request as ready for review May 18, 2024 12:36
@farmio farmio requested a review from marvin-w as a code owner May 18, 2024 12:36
@farmio farmio changed the title Create, update and delete KNX entities from WS-commands Create, update and delete KNX entities from UI / WS-commands May 18, 2024
@farmio
Copy link
Contributor Author

farmio commented May 23, 2024

@coderabbitai review

Copy link

coderabbitai bot commented May 23, 2024

Actions Performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

coderabbitai bot commented May 23, 2024

Walkthrough

The updates to the KNX component in Home Assistant introduce new functionalities, restructure existing code, and enhance the configuration management. Key changes include the introduction of a KNXConfigStore class for managing KNX entity configurations, modifications to the setup and unloading processes for KNX entries, and new methods for entity creation, validation, and deletion via WebSocket commands. Additionally, new test cases and fixtures have been added to ensure the robustness of these changes.

Changes

Files Change Summary
homeassistant/components/knx/__init__.py Added new imports, updated platform constants, setup/unload entry adjustments, new method for removing config entry devices, introduced KNXConfigStore class.
homeassistant/components/knx/config_flow.py Updated import paths for keyring-related functions.
homeassistant/components/knx/const.py Adjusted ColorTempModes enum values, changed SUPPORTED_PLATFORMS to dictionaries for YAML and UI configurations.
homeassistant/components/knx/storage/config_store.py Introduced KNXConfigStore class for managing KNX entity configurations.
homeassistant/components/knx/storage/entity_store_schema.py Defined schemas for entity store data, including base entity schema, switch schema, and data schema.
homeassistant/components/knx/storage/entity_store_validation.py Added functionality for validating entity store data, including validation errors and successes.
homeassistant/components/knx/storage/knx_selector.py Introduced GASelector class for handling KNX group address structures.
homeassistant/components/knx/switch.py Added new imports, refactored setup function, introduced KnxYamlSwitch and KnxUiSwitch classes, modified base class _KnxSwitch.
homeassistant/components/knx/validation.py Added maybe_ga_validator function for validating group addresses.
homeassistant/components/knx/websocket.py Added new WebSocket functions for validating, creating, updating, and deleting KNX entities.
tests/components/knx/README.md Added optional response parameter to knx.assert_read function.
tests/components/knx/__init__.py Updated imports for Awaitable and Callable, added KnxEntityGenerator type signature.
tests/components/knx/conftest.py Added imports and fixtures for KNX storage and entity registry.
tests/components/knx/fixtures/config_store.json Defined configurations for KNX devices, including switch and light entities.
tests/components/knx/test_config_flow.py Updated import paths for keyring-related functions.
tests/components/knx/test_config_store.py Added test cases for creating, updating, deleting, and validating KNX entities.
tests/components/knx/test_device.py Added test functions for creating and removing KNX devices.
tests/components/knx/test_interface_device.py Renamed test module, added imports, introduced test function for device removal.
tests/components/knx/test_knx_selectors.py Added test function test_ga_selector for testing GASelector functionality.
tests/components/knx/test_switch.py Added test function test_switch_ui_create for testing switch creation and state assertion.
tests/components/knx/test_websocket.py Added assertion for KNX project storage key, modified handling of project file removal.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 11

Outside diff range and nitpick comments (2)
tests/components/knx/README.md (1)

Line range hint 1-73: The testing documentation is clear and detailed. Consider the following grammatical improvements for better readability:

  • Line 5: Add a comma after "telegrams" before "To test something".
  • Line 28 and 56: Vary the sentence structure to avoid repetition.
  • Line 73: Replace "form" with "from".
- To test something add a test function requesting the `hass` and `knx` fixture and
+ To test something, add a test function requesting the `hass` and `knx` fixture and

- Asserts that a GroupValueRead telegram was sent to `group_address`.
+ A GroupValueRead telegram was sent to `group_address`, this is asserted.

- Inject and process a GroupValueWrite telegram addressed to `group_address`.
+ A GroupValueWrite telegram addressed to `group_address` is processed and injected.

- for every Read-request sent form StateUpdater, or to pass its timeout,
+ for every Read-request sent from StateUpdater, or to pass its timeout,
tests/components/knx/test_config_store.py (1)

92-108: Clarify the comment about the TTS platform.

The comment on line 96 could be clearer. Consider rephrasing to "The 'tts' platform is not supported for KNX entities and is unlikely to ever be."

tests/components/knx/test_config_store.py Show resolved Hide resolved
tests/components/knx/test_config_store.py Show resolved Hide resolved
tests/components/knx/test_config_store.py Show resolved Hide resolved
tests/components/knx/test_config_store.py Show resolved Hide resolved
tests/components/knx/test_config_store.py Show resolved Hide resolved
tests/components/knx/test_config_store.py Show resolved Hide resolved
Comment on lines +283 to +294
except ConfigStoreException as err:
connection.send_error(
msg["id"], websocket_api.const.ERR_HOME_ASSISTANT_ERROR, str(err)
)
return
Copy link

Choose a reason for hiding this comment

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

Tip

Codebase Verification

Exception handling in ws_create_entity is not covered by tests. Please add tests to ensure this path is properly tested.

  • homeassistant/components/knx/websocket.py lines 283-287
Analysis chain

Ensure exception handling in ws_create_entity is covered by tests.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that exception handling paths in `ws_create_entity` are covered by tests.

# Test: Search for tests covering lines 283-287 in `ws_create_entity`.
rg --type python --context 5 'ws_create_entity' homeassistant/components/knx/tests/

Length of output: 114



Script:

#!/bin/bash
# Description: Verify that exception handling paths in `ws_create_entity` are covered by tests.

# Test: Search for tests covering lines 283-287 in `ws_create_entity`.
rg --type py --context 5 'ws_create_entity' homeassistant/components/knx/tests/

Length of output: 155



Script:

#!/bin/bash
# Description: Locate test files for the KNX component and verify that exception handling paths in `ws_create_entity` are covered by tests.

# Step 1: Locate test files related to the KNX component.
test_files=$(fd --type f --glob '*test*.py' homeassistant/components/knx/)

# Step 2: Search for tests covering `ws_create_entity` in the located test files.
if [ -n "$test_files" ]; then
  rg --context 5 'ws_create_entity' $test_files
else
  echo "No test files found for the KNX component."
fi

Length of output: 188



Script:

#!/bin/bash
# Description: Locate test files for the KNX component across the entire repository and verify that exception handling paths in `ws_create_entity` are covered by tests.

# Step 1: Locate test files related to the KNX component across the entire repository.
test_files=$(fd --type f --glob '*test*.py' | grep 'knx')

# Step 2: Search for tests covering `ws_create_entity` in the located test files.
if [ -n "$test_files" ]; then
  rg --context 5 'ws_create_entity' $test_files
else
  echo "No test files found for the KNX component."
fi

Length of output: 3805

homeassistant/components/knx/__init__.py Show resolved Hide resolved
homeassistant/components/knx/__init__.py Show resolved Hide resolved
@@ -315,6 +335,7 @@
async def start(self) -> None:
"""Start XKNX object. Connect to tunneling or Routing device."""
await self.project.load_project()
await self.config_store.load_data()
Copy link

Choose a reason for hiding this comment

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

Ensure data loading in KNXModule.start() is robust and error-handled.

Consider adding error handling around the data loading calls in KNXModule.start() to manage potential failures gracefully. This could improve the robustness of the module startup process.

@Kolbi
Copy link

Kolbi commented Jun 11, 2024

Really looking forward seeing this PR in the release soon :)

@farmio farmio force-pushed the knx-entity-creation branch from 0453857 to f08ca44 Compare June 20, 2024 21:16
hass: HomeAssistant, config_entry: ConfigEntry, device_entry: DeviceEntry
) -> bool:
"""Remove a config entry from a device."""
knx_module: KNXModule = hass.data[DOMAIN]
Copy link
Member

Choose a reason for hiding this comment

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

If you feel extra fancy, maybe you can do https://developers.home-assistant.io/blog/2024/05/01/improved-hass-data-typing (but in a separate PR of course)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I do fancy type safety for sure!
Maybe I can even use runtime_data, but for now I'm trying to avoid merge conflict hell 😬 (I have some follow-ups ready locally 🙃)

},
extra=vol.ALLOW_EXTRA,
),
msg="One of `Device` or `Name` is required",
Copy link
Member

Choose a reason for hiding this comment

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

the fields in there are device_info and name right? Is there a reason we call them Device and Name here? The backticks will make them look like they are code, but apparently they are not

Copy link
Contributor Author

@farmio farmio Jul 18, 2024

Choose a reason for hiding this comment

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

This refers to the 2 selectors in the frontend. One is a custom device selector (like an area selector where you can select a knx device, or create a new), the other is the entity name. The name selector is prefixed with the device name (in UI, not in schema). If there is no device selected, a user has to enter some entity name, if there is a device, it can be None or empty (_attr_has_entity_name).
Bildschirmfoto 2024-07-18 um 22 47 00
Here with the error shown:
Bildschirmfoto 2024-07-19 um 07 17 48

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, it's nasty because they can be translated

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The custom panel doesn't have translation in place yet. I guess this can be worked on when translation was implemented... for other things we use voluptuous error messages which are english too.

from ..validation import ga_validator, maybe_ga_validator


class GASelector:
Copy link
Member

Choose a reason for hiding this comment

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

What's GA?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is a common (in the KNX world) abbreviation for "Group Address". That's used to assign KNX telegram payloads to specific entity functions - and thus the main thing we need a user to configure (1-2 for each function - set and state address). Thats vaguely comparable to an MQTT topic or Modbus register address.


async_add_entities(KNXSwitch(xknx, entity_config) for entity_config in config)
yaml_config: list[ConfigType] | None
if yaml_config := hass.data[DATA_KNX_CONFIG].get(Platform.SWITCH):
Copy link
Member

Choose a reason for hiding this comment

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

Side note: do we have multiple places within hass.data where we store KNX data? Ideally we only use the hass.data[DOMAIN]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, there is the yaml config in DATA_KNX_CONFIG and an instance of the base class KNXModule in DOMAIN. I recall there was a reason why we did it that way, but tbh I can't remember why anymore 😬 had something to do with config entry reloads 🤔
This should be addressed together with typing improvements of hass.data I guess.

homeassistant/components/knx/switch.py Outdated Show resolved Hide resolved
homeassistant/components/knx/websocket.py Show resolved Hide resolved
tests/components/knx/conftest.py Outdated Show resolved Hide resolved
tests/components/knx/conftest.py Outdated Show resolved Hide resolved
tests/components/knx/test_config_store.py Outdated Show resolved Hide resolved
@home-assistant home-assistant bot marked this pull request as draft July 18, 2024 07:59
@farmio farmio force-pushed the knx-entity-creation branch from 28cf36d to d0fc065 Compare July 19, 2024 11:55
@farmio farmio marked this pull request as ready for review July 19, 2024 12:01
@home-assistant home-assistant bot requested a review from joostlek July 19, 2024 12:01
@cdce8p
Copy link
Member

cdce8p commented Jul 21, 2024

FYI pushed a new commit to fix the mypy errors / type ignores. @joostlek messaged me on discord about #104079 (comment) and I figured it'd probably be easier to push the changes directly then leaving a long comment. The gist of it though is to use the VolSchemaType and VolDictType type aliases when annotating schemas / dicts. It's not always necessary but when you encounter a type error, that usually resolves it.

@joostlek
Copy link
Member

That was the last thing remaining for this PR. Much thanks @cdce8p

@joostlek joostlek merged commit d418a40 into dev Jul 21, 2024
26 checks passed
@joostlek joostlek deleted the knx-entity-creation branch July 21, 2024 18:01
@farmio
Copy link
Contributor Author

farmio commented Jul 21, 2024

Thanks for your review @joostlek and thanks for the typing help @cdce8p 😃

@github-actions github-actions bot locked and limited conversation to collaborators Jul 22, 2024
@home-assistant home-assistant unlocked this conversation Aug 26, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Aug 27, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants