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

Improved Area Support #88

Draft
wants to merge 6 commits into
base: develop
Choose a base branch
from
Draft

Improved Area Support #88

wants to merge 6 commits into from

Conversation

Alexwijn
Copy link
Owner

@Alexwijn Alexwijn commented Jan 20, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced room weight configuration to allow for weighted temperature control across different areas.
    • Added ability to identify a focus area with the most significant temperature deviation.
    • Enhanced configuration flow to allow users to set room weights dynamically.
    • Added a new menu option for managing heating weights for individual rooms.
  • Improvements

    • Enhanced temperature management logic to consider room-specific weights.
    • Simplified error handling and temperature control mechanisms.
  • Configuration

    • New configuration option CONF_ROOM_WEIGHTS for specifying room-specific heating priorities.
    • Updated user interface for managing room-specific heating settings.

These updates provide more granular and flexible temperature control for multi-room heating systems.

image

Copy link
Contributor

coderabbitai bot commented Jan 20, 2025

Walkthrough

The pull request introduces a new configuration option, CONF_ROOM_WEIGHTS, enabling the specification of weights for individual rooms in a heating system. Modifications to the Area and Areas classes allow for the incorporation of these weights into the heating curve and PID controller logic. Additionally, the SatClimate class has been updated to streamline temperature management and error handling. User configuration flow has been enhanced with a new method for setting room weights, and a new menu option has been added to the user interface for better accessibility.

Changes

File Changes
custom_components/sat/const.py Added new constant CONF_ROOM_WEIGHTS for room weight configuration
custom_components/sat/area.py - Added weight property to Area class
- Introduced focus property in Areas class
- Modified heating curve and PID update methods to incorporate room weights
- Added update_reset method to _PIDs class
custom_components/sat/climate.py - Removed max_error property
- Updated requested_setpoint property with more detailed calculation
- Modified PID controller update logic
custom_components/sat/config_flow.py Added async_step_areas method for configuring room weights
custom_components/sat/translations/en.json Added new "areas" menu option and section for room weight configuration

Possibly related PRs

  • Connected Thermostat #83: The changes in the SatClimate class regarding the integration of a connected thermostat are related to the main PR's updates on room weights and the focus property, as both involve enhancements to the climate control logic.
  • Bugfix release #84: The modifications to the SatClimate class, particularly the cascading behavior for HVAC mode and target temperature settings, relate to the main PR's updates to the heating control logic, which also involves managing temperature settings based on room weights.
  • More bugfixes #86: The changes in the Areas class constructor and the introduction of the items() method are relevant to the main PR's modifications in the Area and Areas classes, as both involve managing configurations and entity IDs for heating areas.
✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

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>, please review it.
    • 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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

🧹 Nitpick comments (3)
custom_components/sat/area.py (1)

141-141: Consider rounding weighted values to prevent floating-point precision issues.

The multiplication of values by weights could lead to floating-point precision issues. Consider rounding the results to maintain consistent precision.

-                area.heating_curve.update(area.target_temperature * area.weight, current_outside_temperature)
+                area.heating_curve.update(round(area.target_temperature * area.weight, 2), current_outside_temperature)

-                    area.pid.update(area.error * area.weight, area.heating_curve.value, boiler_temperature)
+                    area.pid.update(round(area.error * area.weight, 2), area.heating_curve.value, boiler_temperature)

Also applies to: 150-150

custom_components/sat/climate.py (2)

Line range hint 793-817: Enhance logging for better debugging of PID controller updates.

The current logging could be more informative by including additional context about the weight-based calculations and state transitions.

-            _LOGGER.info(f"Updating error value to {self.error} (Reset: False)")
+            _LOGGER.info(f"Updating PID with error: {self.error}, heating curve: {self.heating_curve.value}, boiler temp: {self._coordinator.boiler_temperature_filtered} (Reset: False)")

-            _LOGGER.info(f"Updating error value to {self.error} (Reset: True)")
+            _LOGGER.info(f"Resetting PID with error: {self.error}, heating curve: {self.heating_curve.value} (Reset: True)")

519-528: Improve import clarity by explicitly importing constants.

The code uses star imports which make it difficult to track where constants are defined. Consider explicitly importing the constants to improve code clarity and maintainability.

-from .const import *
+from .const import (
+    HEATING_MODE_COMFORT,
+    MINIMUM_SETPOINT,
+    DEADBAND,
+    # ... other constants
+)
🧰 Tools
🪛 Ruff (0.8.2)

519-519: HEATING_MODE_COMFORT may be undefined, or defined from star imports

(F405)


525-525: MINIMUM_SETPOINT may be undefined, or defined from star imports

(F405)


528-528: MINIMUM_SETPOINT may be undefined, or defined from star imports

(F405)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 42d3c45 and df767e9.

📒 Files selected for processing (3)
  • custom_components/sat/area.py (6 hunks)
  • custom_components/sat/climate.py (4 hunks)
  • custom_components/sat/const.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
custom_components/sat/climate.py

519-519: HEATING_MODE_COMFORT may be undefined, or defined from star imports

(F405)


525-525: MINIMUM_SETPOINT may be undefined, or defined from star imports

(F405)


528-528: MINIMUM_SETPOINT may be undefined, or defined from star imports

(F405)


796-796: DEADBAND may be undefined, or defined from star imports

(F405)


796-796: DEADBAND may be undefined, or defined from star imports

(F405)

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

🧹 Nitpick comments (1)
custom_components/sat/area.py (1)

151-156: Consider adding bounds checking for the weighted error.

The multiplication of error with weight could lead to disproportionate PID responses.

Apply this diff to add bounds checking:

         def update(self, boiler_temperature: float) -> None:
             for area in self.areas:
                 if area.error is not None:
-                    area.pid.update(area.error * area.weight, area.heating_curve.value, boiler_temperature)
+                    weighted_error = min(max(area.error * area.weight, -10), 10)  # Limit weighted error to [-10, 10]
+                    area.pid.update(weighted_error, area.heating_curve.value, boiler_temperature)

         def update_reset(self) -> None:
             for area in self.areas:
                 if area.error is not None:
-                    area.pid.update_reset(area.error * area.weight, area.heating_curve.value)
+                    weighted_error = min(max(area.error * area.weight, -10), 10)  # Limit weighted error to [-10, 10]
+                    area.pid.update_reset(weighted_error, area.heating_curve.value)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between df767e9 and 6b05774.

📒 Files selected for processing (4)
  • custom_components/sat/area.py (6 hunks)
  • custom_components/sat/config_flow.py (2 hunks)
  • custom_components/sat/const.py (2 hunks)
  • custom_components/sat/translations/en.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • custom_components/sat/const.py
🧰 Additional context used
🪛 Ruff (0.8.2)
custom_components/sat/config_flow.py

553-553: CONF_ROOMS may be undefined, or defined from star imports

(F405)


680-680: CONF_ROOM_WEIGHTS may be undefined, or defined from star imports

(F405)


681-681: CONF_ROOMS may be undefined, or defined from star imports

(F405)


685-685: CONF_ROOM_WEIGHTS may be undefined, or defined from star imports

(F405)

🔇 Additional comments (5)
custom_components/sat/config_flow.py (1)

551-556: LGTM!

The menu options are correctly updated to include the "areas" option when rooms are configured.

🧰 Tools
🪛 Ruff (0.8.2)

553-553: CONF_ROOMS may be undefined, or defined from star imports

(F405)

custom_components/sat/area.py (3)

37-40: LGTM!

The weight property is correctly implemented with proper type hints.


100-104: LGTM!

The focus property correctly handles None error values by filtering them out before finding the maximum.


26-26: ⚠️ Potential issue

Improve error handling in weight initialization.

The current implementation might raise AttributeError if config_options.get(CONF_ROOM_WEIGHTS) returns None.

Apply this diff to fix the error handling:

-        self._weight: float = config_options.get(CONF_ROOM_WEIGHTS).get(entity_id, 1.0)
+        self._weight: float = config_options.get(CONF_ROOM_WEIGHTS, {}).get(entity_id, 1.0)

Likely invalid or redundant comment.

custom_components/sat/translations/en.json (1)

217-217: LGTM!

The translations are clear, descriptive, and correctly formatted.

Also applies to: 221-224

Alexwijn and others added 2 commits January 20, 2025 23:53
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Repository owner deleted a comment from coderabbitai bot Jan 20, 2025
Repository owner deleted a comment from coderabbitai bot Jan 20, 2025
Repository owner deleted a comment from coderabbitai bot Jan 20, 2025
Repository owner deleted a comment from coderabbitai bot Jan 20, 2025
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

🧹 Nitpick comments (1)
custom_components/sat/config_flow.py (1)

679-703: Improve error handling and define constants.

The implementation looks good but could benefit from these improvements:

  1. Add error handling for state retrieval
  2. Define the default weight as a constant

Apply this diff to improve the implementation:

+ DEFAULT_ROOM_WEIGHT = 1.0  # Add at the top with other constants
+
  async def async_step_areas(self, _user_input: dict[str, Any] | None = None):
      room_labels: dict[str, str] = {}
      room_weights: dict[str, float] = self._options.get(CONF_ROOM_WEIGHTS, {})

      for entity_id in self._config_entry.data.get(CONF_ROOMS, []):
          state = self.hass.states.get(entity_id)
-         name = state.name if state else entity_id
+         try:
+             name = state.name if state and state.name else entity_id
+         except (AttributeError, KeyError):
+             name = entity_id
          room_labels[entity_id] = f"{name} ({entity_id})"

      if _user_input is not None:
          return await self.update_options({
              CONF_ROOM_WEIGHTS: {
                  entity_id: float(_user_input[friendly_name])
                  for entity_id, friendly_name in room_labels.items()
              }
          })

      return self.async_show_form(
          step_id="areas",
          data_schema=vol.Schema({
-             vol.Required(friendly_name, default=room_weights.get(entity_id, 1.0)): selector.NumberSelector(
+             vol.Required(friendly_name, default=room_weights.get(entity_id, DEFAULT_ROOM_WEIGHT)): selector.NumberSelector(
                  selector.NumberSelectorConfig(min=0.1, max=3.0, step=0.1)
              ) for entity_id, friendly_name in room_labels.items()
          })
      )
🧰 Tools
🪛 Ruff (0.8.2)

681-681: CONF_ROOM_WEIGHTS may be undefined, or defined from star imports

(F405)


683-683: CONF_ROOMS may be undefined, or defined from star imports

(F405)


690-690: CONF_ROOM_WEIGHTS may be undefined, or defined from star imports

(F405)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b05774 and 824038e.

📒 Files selected for processing (3)
  • custom_components/sat/area.py (5 hunks)
  • custom_components/sat/climate.py (4 hunks)
  • custom_components/sat/config_flow.py (2 hunks)
👮 Files not reviewed due to content moderation or server errors (2)
  • custom_components/sat/area.py
  • custom_components/sat/climate.py
🧰 Additional context used
🪛 Ruff (0.8.2)
custom_components/sat/climate.py

520-520: HEATING_MODE_COMFORT may be undefined, or defined from star imports

(F405)


527-527: MINIMUM_SETPOINT may be undefined, or defined from star imports

(F405)


530-530: MINIMUM_SETPOINT may be undefined, or defined from star imports

(F405)


798-798: DEADBAND may be undefined, or defined from star imports

(F405)


798-798: DEADBAND may be undefined, or defined from star imports

(F405)

custom_components/sat/config_flow.py

553-553: CONF_ROOMS may be undefined, or defined from star imports

(F405)


681-681: CONF_ROOM_WEIGHTS may be undefined, or defined from star imports

(F405)


683-683: CONF_ROOMS may be undefined, or defined from star imports

(F405)


690-690: CONF_ROOM_WEIGHTS may be undefined, or defined from star imports

(F405)

🔇 Additional comments (2)
custom_components/sat/config_flow.py (2)

551-556: LGTM!

The conditional addition of the "areas" menu option based on room configuration is well-implemented.

🧰 Tools
🪛 Ruff (0.8.2)

553-553: CONF_ROOMS may be undefined, or defined from star imports

(F405)


553-553: Verify star imports.

The static analysis tool flags potential undefined imports from star imports. Please verify that these constants are properly imported:

  • CONF_ROOMS
  • CONF_ROOM_WEIGHTS

Run this script to verify the imports:

Also applies to: 681-681, 683-683, 690-690

✅ Verification successful

Star imports are properly resolved

The constants CONF_ROOMS and CONF_ROOM_WEIGHTS are defined in const.py and are correctly imported into config_flow.py via the star import from .const import *. While explicit imports would be preferable for maintainability, the current implementation is functionally correct.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the constants are properly imported
# Test: Search for the constant definitions
rg -l "^CONF_ROOM_WEIGHTS\s*=|^CONF_ROOMS\s*=" 

Length of output: 79


Script:

#!/bin/bash
# Get the constant definitions from const.py
echo "=== Checking constant definitions in const.py ==="
rg "^CONF_ROOM_WEIGHTS\s*=|^CONF_ROOMS\s*=" custom_components/sat/const.py -A 1

echo -e "\n=== Checking imports in config_flow.py ==="
rg "^from.*const.*import|^import.*const" custom_components/sat/config_flow.py

Length of output: 552

🧰 Tools
🪛 Ruff (0.8.2)

553-553: CONF_ROOMS may be undefined, or defined from star imports

(F405)

@Yveaux
Copy link

Yveaux commented Feb 8, 2025

Hey there @Alexwijn! Very interesting PR, especially since I'm struggling to balance my boiler's output for floor heating w.r.t. radiators in sleeping rooms.
Is this functionality complete/ready for testing?
Anything I can do yo help out?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants