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

Add XML command "SetFanSpeed" #560

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from

Conversation

flubshi
Copy link
Contributor

@flubshi flubshi commented Aug 26, 2024

Adds support for deebot 900 XML command "SetFanSpeed".

@edenhaus Could you please review?

Runtime tested:

image

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Introduced enhanced command handling for XML messages.
    • Added commands for getting and setting clean speed, improving device operation control.
    • Expanded fan speed options with new levels: STANDARD and STRONG.
  • Bug Fixes

    • Improved handling of command execution success and failure notifications.
  • Tests

    • Added tests for the new clean speed commands to ensure expected behavior and outputs.

Copy link
Contributor

coderabbitai bot commented Aug 26, 2024

Walkthrough

The changes introduce new classes and methods to enhance command handling within the deebot_client package. The GetFanSpeed command has been replaced with GetCleanSpeed, and a new SetCleanSpeed command has been added for controlling cleaning speed. The common.py module has been updated with ExecuteCommand and XmlSetCommand classes to improve XML message processing. Additionally, tests for the new functionality are introduced in the test_fan_speed.py file.

Changes

Files Change Summary
deebot_client/commands/xml/__init__.py Removed GetFanSpeed; added GetCleanSpeed and SetCleanSpeed.
deebot_client/commands/xml/common.py Added ExecuteCommand and XmlSetCommand classes; implemented _handle_xml method.
deebot_client/commands/xml/fan_speed.py Renamed GetFanSpeed to GetCleanSpeed; added SetCleanSpeed class with speed parameter handling.
deebot_client/events/fan_speed.py Added STANDARD and STRONG values to FanSpeedLevel enumeration.
tests/commands/xml/test_fan_speed.py Updated tests for GetCleanSpeed; added tests for SetCleanSpeed command behavior.

Possibly related PRs

Poem

In the world of commands, we hop and play,
With clean speeds soaring, brightening the day.
New classes and tests, oh what a delight,
Our code's now a garden, blooming so bright!
🐇💨✨


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 using 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.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

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
Contributor

@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: 4

Outside diff range, codebase verification and nitpick comments (2)
deebot_client/commands/xml/common.py (2)

71-71: Add docstring for the class.

The class ExecuteCommand is missing a docstring.

Apply this diff to add a docstring for the class:

 class ExecuteCommand(XmlCommandWithMessageHandling, ABC):
+    """Command, which is executing something (ex. Charge)."""

88-92: Add docstring for the class.

The class XmlSetCommand is missing a docstring.

Apply this diff to add a docstring for the class:

 class XmlSetCommand(ExecuteCommand, SetCommand, ABC):
+    """Xml base set command.
+
+    Command needs to be linked to the "get" command, for handling (updating) the sensors.
+    """
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 5da23d7 and 296ae89.

Files selected for processing (3)
  • deebot_client/commands/xml/common.py (3 hunks)
  • deebot_client/commands/xml/fan_speed.py (2 hunks)
  • tests/commands/xml/test_fan_speed.py (2 hunks)
Additional context used
Ruff
tests/commands/xml/test_fan_speed.py

15-15: ..json.assert_set_command imported but unused

Remove unused import: ..json.assert_set_command

(F401)


50-50: f-string without any placeholders

Remove extraneous f prefix

(F541)

deebot_client/commands/xml/common.py

38-38: Use False instead of False and ...

Replace with False

(SIM223)

Additional comments not posted (1)
deebot_client/commands/xml/fan_speed.py (1)

5-5: Remove unused import.

The import TYPE_CHECKING is not used in the file.

Apply this diff to remove the unused import:

-from typing import TYPE_CHECKING

Likely invalid or redundant comment.

tests/commands/xml/test_fan_speed.py Outdated Show resolved Hide resolved
tests/commands/xml/test_fan_speed.py Outdated Show resolved Hide resolved
deebot_client/commands/xml/fan_speed.py Outdated Show resolved Hide resolved
deebot_client/commands/xml/common.py Outdated Show resolved Hide resolved
Copy link

codecov bot commented Aug 26, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 86.86%. Comparing base (fafef75) to head (315307a).
Report is 10 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev     #560      +/-   ##
==========================================
+ Coverage   86.67%   86.86%   +0.19%     
==========================================
  Files          89       89              
  Lines        3324     3343      +19     
  Branches      533      534       +1     
==========================================
+ Hits         2881     2904      +23     
+ Misses        389      384       -5     
- Partials       54       55       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@flubshi flubshi force-pushed the xml_set_fanspeed branch 2 times, most recently from 70ae3c9 to b968b6c Compare August 26, 2024 20:40
Copy link
Contributor

@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.

Caution

Inline review comments failed to post

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 296ae89 and 70ae3c9.

Files selected for processing (3)
  • deebot_client/commands/xml/common.py (3 hunks)
  • deebot_client/commands/xml/fan_speed.py (2 hunks)
  • tests/commands/xml/test_fan_speed.py (2 hunks)
Additional context used
Ruff
tests/commands/xml/test_fan_speed.py

15-15: ..json.assert_set_command imported but unused

Remove unused import: ..json.assert_set_command

(F401)

deebot_client/commands/xml/common.py

38-38: Use False instead of False and ...

Replace with False

(SIM223)

Additional comments not posted (8)
deebot_client/commands/xml/fan_speed.py (2)

Line range hint 12-46: LGTM!

The _handle_xml method correctly processes the XML response and notifies the event bus for different fan speed levels.

The code changes are approved.


49-59: Improve readability and maintainability.

The constructor logic can be simplified for better readability and maintainability.

Apply this diff to simplify the constructor logic:

 def __init__(self, speed: FanSpeedLevel | str) -> None:
-    if isinstance(speed, int):
-        speed = "strong" if speed in [1, 2] else "normal"
+    if isinstance(speed, int) and speed in [1, 2]:
+        speed = "strong"
+    elif isinstance(speed, int):
+        speed = "normal"
    super().__init__({"speed": speed})

Likely invalid or redundant comment.

tests/commands/xml/test_fan_speed.py (4)

Line range hint 17-31: LGTM!

The function correctly tests the GetFanSpeed command for different fan speed levels using parameterized tests.

The code changes are approved.

Tools
Ruff

15-15: ..json.assert_set_command imported but unused

Remove unused import: ..json.assert_set_command

(F401)


Line range hint 34-46: LGTM!

The function correctly tests the GetFanSpeed command for different error scenarios using parameterized tests.

The code changes are approved.


48-51: LGTM!

The function correctly tests the SetFanSpeed command for the maximum fan speed level.

The code changes are approved.


53-56: LGTM!

The function correctly tests the SetFanSpeed command for an invalid fan speed value.

The code changes are approved.

deebot_client/commands/xml/common.py (2)

71-85: LGTM!

The _handle_xml method correctly handles the success and failure of XML commands.

The code changes are approved.


88-92: LGTM!

The class correctly serves as a base for XML set commands and links to "get" commands for sensor updates.

The code changes are approved.

Comments failed to post (1)
deebot_client/commands/xml/common.py (1)

37-38: Fix the TypeError in _get_payload method.

The FIXME comment indicates a potential issue with the has_sub_element method being a class method. Address this to prevent the TypeError.

Apply this diff to fix the issue:

-            # FIXME TypeError: 'classmethod' object is not callable
-            if False and self.has_sub_element:
+            if self.has_sub_element():

Committable suggestion was skipped due to low confidence.

Tools
Ruff

38-38: Use False instead of False and ...

Replace with False

(SIM223)

Copy link
Contributor

@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: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 70ae3c9 and 87b1512.

Files selected for processing (3)
  • deebot_client/commands/xml/common.py (3 hunks)
  • deebot_client/commands/xml/fan_speed.py (2 hunks)
  • tests/commands/xml/test_fan_speed.py (2 hunks)
Additional context used
Ruff
tests/commands/xml/test_fan_speed.py

15-15: ..json.assert_set_command imported but unused

Remove unused import: ..json.assert_set_command

(F401)

deebot_client/commands/xml/common.py

38-38: Use False instead of False and ...

Replace with False

(SIM223)

Additional comments not posted (13)
deebot_client/commands/xml/fan_speed.py (5)

Line range hint 16-46: LGTM!

The code changes are approved.


52-52: LGTM!

The code changes are approved.


53-53: LGTM!

The code changes are approved.


54-54: LGTM!

The code changes are approved.


56-59: Improve readability and maintainability.

The constructor logic can be simplified for better readability and maintainability.

Apply this diff to simplify the constructor logic:

 def __init__(self, speed: FanSpeedLevel | str) -> None:
-    if isinstance(speed, int):
-        speed = "strong" if speed in [1, 2] else "normal"
+    if isinstance(speed, int) and speed in [1, 2]:
+        speed = "strong"
+    elif isinstance(speed, int):
+        speed = "normal"
    super().__init__({"speed": speed})
tests/commands/xml/test_fan_speed.py (4)

Line range hint 18-29: LGTM!

The code changes are approved.

Tools
Ruff

15-15: ..json.assert_set_command imported but unused

Remove unused import: ..json.assert_set_command

(F401)


Line range hint 32-45: LGTM!

The code changes are approved.


48-51: LGTM!

The code changes are approved.


53-56: LGTM!

The code changes are approved.

deebot_client/commands/xml/common.py (4)

Line range hint 30-38: Address the FIXME comment.

The FIXME comment indicates a potential issue with the has_sub_element method. The method is defined as a class method but is being called as an instance method.

Apply this diff to fix the issue:

-            # FIXME TypeError: 'classmethod' object is not callable
-            if False and self.has_sub_element:
+            if False and cls.has_sub_element():
Tools
Ruff

38-38: Use False instead of False and ...

Replace with False

(SIM223)


Line range hint 49-68: LGTM!

The code changes are approved.


71-85: LGTM!

The code changes are approved.


88-92: LGTM!

The code changes are approved.

Copy link
Contributor

@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: 2

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 87b1512 and e117ac2.

Files selected for processing (4)
  • deebot_client/commands/xml/init.py (2 hunks)
  • deebot_client/commands/xml/common.py (3 hunks)
  • deebot_client/commands/xml/fan_speed.py (2 hunks)
  • tests/commands/xml/test_fan_speed.py (2 hunks)
Files skipped from review as they are similar to previous changes (1)
  • deebot_client/commands/xml/fan_speed.py
Additional context used
Ruff
tests/commands/xml/test_fan_speed.py

15-15: ..json.assert_set_command imported but unused

Remove unused import: ..json.assert_set_command

(F401)

deebot_client/commands/xml/common.py

38-38: Use False instead of False and ...

Replace with False

(SIM223)

Additional comments not posted (8)
deebot_client/commands/xml/__init__.py (2)

11-11: LGTM!

The import statement for SetFanSpeed is correctly added.


21-21: LGTM!

The addition of SetFanSpeed to the __all__ list is correctly done.

tests/commands/xml/test_fan_speed.py (2)

9-9: LGTM!

The import statement for SetFanSpeed is correctly added.


48-51: LGTM!

The new test function test_set_fan_speed is correctly implemented.

deebot_client/commands/xml/common.py (4)

11-14: LGTM!

The import statements for SetCommand and HandlingState are correctly added.


71-73: LGTM!

The new class ExecuteCommand is correctly implemented.


74-85: LGTM!

The new method _handle_xml is correctly implemented.


88-92: LGTM!

The new class XmlSetCommand is correctly implemented.

tests/commands/xml/test_fan_speed.py Outdated Show resolved Hide resolved
deebot_client/commands/xml/common.py Outdated Show resolved Hide resolved
Copy link
Contributor

@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: 1

Outside diff range, codebase verification and nitpick comments (2)
deebot_client/commands/xml/fan_speed.py (1)

Line range hint 23-45: Add a default case to the match statement.

The match statement does not handle unexpected values gracefully. Consider adding a default case to handle unexpected values.

match speed.lower():
    case "standard":
        event = FanSpeedEvent(FanSpeedLevel.NORMAL)
    case "strong":
        event = FanSpeedEvent(FanSpeedLevel.MAX)
+   case _:
+       _LOGGER.warning('Unexpected fan speed value: %s', speed)
tests/commands/xml/test_fan_speed.py (1)

Line range hint 27-30: Remove extraneous f prefix.

The f-string does not contain any placeholders.

json = get_request_xml(f"<ctl ret='ok' speed='{speed}'/>")
json = get_request_xml("<ctl ret='ok' speed='{speed}'/>")
Tools
Ruff

15-15: ..json.assert_set_command imported but unused

Remove unused import: ..json.assert_set_command

(F401)

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between e117ac2 and 136fb4d.

Files selected for processing (4)
  • deebot_client/commands/xml/init.py (2 hunks)
  • deebot_client/commands/xml/common.py (3 hunks)
  • deebot_client/commands/xml/fan_speed.py (2 hunks)
  • tests/commands/xml/test_fan_speed.py (2 hunks)
Files skipped from review as they are similar to previous changes (1)
  • deebot_client/commands/xml/init.py
Additional context used
Ruff
tests/commands/xml/test_fan_speed.py

15-15: ..json.assert_set_command imported but unused

Remove unused import: ..json.assert_set_command

(F401)

Additional comments not posted (5)
deebot_client/commands/xml/fan_speed.py (1)

56-59: Simplify the constructor logic.

The constructor logic can be simplified for better readability and maintainability.

def __init__(self, speed: FanSpeedLevel | str) -> None:
    if isinstance(speed, int) and speed in [1, 2]:
        speed = "strong"
    elif isinstance(speed, int):
        speed = "normal"
    super().__init__({"speed": speed})

Likely invalid or redundant comment.

tests/commands/xml/test_fan_speed.py (2)

48-51: LGTM!

The code changes are approved.


53-56: LGTM!

The code changes are approved.

deebot_client/commands/xml/common.py (2)

Line range hint 36-66: LGTM!

The code changes are approved.


86-90: LGTM!

The code changes are approved.

deebot_client/commands/xml/common.py Show resolved Hide resolved
Copy link
Contributor

@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: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 136fb4d and 366e96a.

Files selected for processing (1)
  • deebot_client/commands/xml/init.py (2 hunks)
Files skipped from review as they are similar to previous changes (1)
  • deebot_client/commands/xml/init.py

@@ -25,7 +25,6 @@ class XmlCommand(Command):
data_type: DataType = DataType.XML

@property # type: ignore[misc]
@classmethod
Copy link
Contributor

Choose a reason for hiding this comment

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

Why did you remove it?

Copy link
Contributor Author

@flubshi flubshi Sep 4, 2024

Choose a reason for hiding this comment

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

Otherwise it throws an error TypeError: 'classmethod' object is not callable.
Maybe you can reproduce it locally when reverting and running the tests.

@edenhaus Do you have a better solution?

deebot_client/commands/xml/fan_speed.py Outdated Show resolved Hide resolved
deebot_client/commands/xml/fan_speed.py Outdated Show resolved Hide resolved
tests/commands/xml/test_fan_speed.py Outdated Show resolved Hide resolved
@edenhaus edenhaus added the pr: new-feature PR, which adds a new feature label Sep 3, 2024
Copy link
Contributor

@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: 2

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 366e96a and 315307a.

Files selected for processing (4)
  • deebot_client/commands/xml/init.py (1 hunks)
  • deebot_client/commands/xml/fan_speed.py (2 hunks)
  • deebot_client/events/fan_speed.py (1 hunks)
  • tests/commands/xml/test_fan_speed.py (3 hunks)
Additional comments not posted (10)
deebot_client/commands/xml/__init__.py (4)

11-11: LGTM!

The import statement is updated to reflect the new commands for cleaning speed control, which is consistent with the list of alterations.


19-20: LGTM!

The __all__ list is updated to export the new commands for cleaning speed control, which is consistent with the list of alterations.


30-31: LGTM!

The _COMMANDS list is updated to include the new commands for cleaning speed control, which is consistent with the list of alterations.


Line range hint 1-45: Overall assessment: The changes look good!

The changes in this file are focused on replacing the fan speed control commands with cleaning speed control commands. The import statements, __all__ list, and _COMMANDS list are updated consistently to reflect these changes.

The AI-generated summary accurately captures the essence of the changes, which enhance the module's capabilities related to cleaning operations.

No further changes are required in this file.

tests/commands/xml/test_fan_speed.py (4)

22-29: LGTM!

The changes to the test function and the parameterized test cases align with the shift from GetFanSpeed to GetCleanSpeed. The expected events have been updated correctly.


40-44: LGTM!

The changes to the test function align with the shift from GetFanSpeed to GetCleanSpeed. The test cases for error scenarios remain valid.


47-50: LGTM!

The new test function test_set_fan_speed correctly validates the successful execution of the SetCleanSpeed command when provided with a valid speed level.


53-56: LGTM!

The new test function test_set_fan_speed_error correctly validates the error scenario for the SetCleanSpeed command when provided with an invalid speed level.

deebot_client/commands/xml/fan_speed.py (2)

Line range hint 20-46: LGTM!

The changes to the GetCleanSpeed class are approved.


49-60: LGTM!

The SetCleanSpeed class is correctly implemented and follows the naming convention.

@@ -14,8 +14,10 @@ class FanSpeedLevel(IntEnum):

# Values should be sort from low to high on their meanings
QUIET = 1000
STANDARD = -1
Copy link
Contributor

Choose a reason for hiding this comment

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

Inconsistent enumeration value.

The STANDARD value is assigned a negative value (-1), which is inconsistent with the existing positive values in the FanSpeedLevel enumeration. This breaks the ordering of the values from low to high based on their meanings, as stated in the comment above the enumeration.

Consider assigning a positive value to STANDARD that maintains the correct ordering of the values based on their meanings. For example:

QUIET = 1000
STANDARD = 1500
NORMAL = 2000
MAX = 2500
STRONG = 3000
MAX_PLUS = 3500

NORMAL = 0
MAX = 1
STRONG = -2
Copy link
Contributor

Choose a reason for hiding this comment

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

Inconsistent enumeration value.

The STRONG value is assigned a negative value (-2), which is inconsistent with the existing positive values in the FanSpeedLevel enumeration. This breaks the ordering of the values from low to high based on their meanings, as stated in the comment above the enumeration.

Consider assigning a positive value to STRONG that maintains the correct ordering of the values based on their meanings. For example:

QUIET = 1000
STANDARD = 1500
NORMAL = 2000
MAX = 2500
STRONG = 3000
MAX_PLUS = 3500

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr: new-feature PR, which adds a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants