Skip to content

Conversation

@bouwew
Copy link
Contributor

@bouwew bouwew commented Jan 29, 2025

All changes:

  • Replace PlugwiseData by a single data-dict, move gateway-items to Smile properties
  • Move SmileComm class to it's own file
  • Move notifications-content into the gateway-dict
  • Big code clean-up
  • Rename and clean-up fixtures
  • Improve legacy async_update() so that the testcode can be simpler --> 2 smile-helper-functions can be removed

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new data structure for managing gateway entity data and properties.
    • Enhanced device configuration management with detailed sensor and device information.
  • Improvements

    • Streamlined data handling for Zigbee devices.
    • Simplified management of gateway and device data.
    • Enhanced tracking of firmware versions and attribute access.
  • Changes

    • Renamed and restructured data classes for better organization.
    • Removed legacy methods related to power data collection.
    • Updated the handling of firmware versioning.
  • Refactoring

    • Consolidated the extraction of Zigbee data into a single function.
    • Simplified constructors and property access across classes.
    • Reduced complexity in data management processes.
  • Bug Fixes

    • Improved consistency in the representation of device and gateway data.
  • Version Update

    • Project version updated from "1.6.4" to "1.7.0".

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 29, 2025

Walkthrough

The pull request introduces a significant rework of the code to output a single dictionary and add gw_data items as Smile-properties. The changes primarily focus on restructuring how device and gateway data are managed across multiple files in the Plugwise library, including modifications to data handling, constants, and helper classes. The goal is to consolidate and simplify the data representation, making it more consistent and easier to integrate.

Changes

File Change Summary
CHANGELOG.md Added entry about reworking code to output a single dictionary and add gw_data items as Smile-properties
plugwise/__init__.py Updated Smile class with new properties and modified async_update method to return dict[str, GwEntityData]
plugwise/common.py Added get_zigbee_data function, removed power-related methods, modified class attributes
plugwise/constants.py Renamed GatewayData to SmileProps, added notifications field, removed PlugwiseData class
plugwise/data.py Added _smile_props attribute, modified data handling methods
plugwise/helper.py Removed SmileComm class, updated variable signatures
fixtures/ Replaced all_data.json files with new data.json files across multiple directories

Possibly related PRs

  • Rename mode to climate_mode #643: The changes in this PR involve renaming the mode variable to climate_mode, which directly relates to the main PR's focus on enhancing the integration of gw_data items as Smile-properties in a unified dictionary format.
  • Implement zone-based approach to correctly represent climate-entities in HA #652: This PR introduces a zone-based approach for representing climate entities, which aligns with the main PR's objective of consolidating data output and improving the representation of climate-related data.
  • Improve control_state processing #659: The modifications in this PR include updates to the control_state processing, changing values from off to idle, which is relevant to the main PR's changes in how data is structured and represented.

Suggested labels

enhancement, bug

Poem

🐰 A Rabbit's Ode to Data Delight
In Plugwise's realm of bits and bytes,
A single dict now takes its flight,
Smile-properties dancing free,
Simplicity's sweet melody!
Code refactored with bunny's care,
Complexity vanished into thin air! 🌟


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 or @coderabbitai title 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: 5

🧹 Nitpick comments (35)
fixtures/m_adam_multiple_devices_per_zone/data.json (5)

43-48: Consider adding validation for thermostat bounds.

Multiple thermostat configurations have an upper bound of 100.0°C, which seems unrealistically high for residential heating. Consider using more realistic temperature bounds (e.g., 30°C or 35°C) to catch potential issues during testing.

Also applies to: 80-85, 124-129, 272-277, 419-424, 471-476, 525-530


572-576: Enhance notification data structure.

The notification structure uses a UUID as a key which makes it difficult to test deterministically. Consider using a more predictable key format for testing purposes.

   "notifications": {
-    "af82e4ccf9c548528166d38e560662a4": {
+    "test_notification_1": {
       "warning": "Node Plug (with MAC address 000D6F000D13CB01, in room 'n.a.') has been unreachable since 23:03 2020-01-18. Please check the connection and restart the device."
     }
   },

191-191: Add boundary testing for battery levels.

The fixture includes various battery levels (34%, 37%, 51%, etc.) but doesn't cover edge cases. Consider adding test cases for:

  • Critical battery level (≤ 10%)
  • Full battery (100%)
  • Invalid battery levels (negative or >100%)

Also applies to: 219-219, 384-384, 465-465, 493-493, 519-519, 547-547


565-567: Update firmware version format.

The firmware version "3.0.15" should follow a consistent format with a timestamp like other devices in the fixture (e.g., "2019-06-21T02:00:00+02:00").

-    "firmware": "3.0.15",
+    "firmware": "2023-01-01T00:00:00+00:00",

25-32: Standardize schedule names.

The available schedules contain inconsistent naming patterns:

  • Some use spaces ("GF7 Woonkamer" has double spaces)
  • Different capitalization ("CV Roan" vs "off")
    Consider standardizing the schedule names for consistency.

Also applies to: 60-67, 254-261, 399-406

plugwise/common.py (1)

50-50: Initialize _cooling_present.

self._cooling_present: bool is declared without an initial value. To avoid potential usage before assignment, consider initializing it explicitly (e.g., self._cooling_present = False).

plugwise/helper.py (4)

83-83: Uninitialized _zones.

The type hint is good, but _zones is declared without an initial value. Consider something like self._zones = {} to prevent potential runtime issues.


452-452: Maintain consistency in _notifications.

Storing notifications in self._notifications is consistent. Ensure _notifications is initialized in the constructor or a similar place to prevent accidental usage before assignment.


628-632: Docstring formatting style.

The docstring clarifies Elga cooling states. Although it starts with a comment line, it’s still understandable. Optional style improvement: remove the leading # to standardize docstring conventions.


654-658: Docstring for Loria/Thermastage logic.

This clarifies how cooling is determined for heat pumps. The multi-line docstring is helpful. Same minor docstring style note applies if you want to keep it consistent across the codebase.

plugwise/legacy/data.py (1)

20-20: Uninitialized _smile_props.

self._smile_props: SmileProps is typed but not initialized. Consider setting self._smile_props = SmileProps() or a similar initial assignment to avoid referencing it prematurely.

plugwise/data.py (3)

44-50: Consider using a dictionary literal for better readability.

The sequential assignments to _smile_props could be combined into a single dictionary literal for better readability and maintainability.

-        self._smile_props["gateway_id"] = self._gateway_id
-        self._smile_props["item_count"] = self._count
-        self._smile_props["reboot"] = True
-        self._smile_props["smile_name"] = self.smile_name
+        self._smile_props.update({
+            "gateway_id": self._gateway_id,
+            "item_count": self._count,
+            "reboot": True,
+            "smile_name": self.smile_name
+        })

123-131: Document the reason for incrementing count by 2.

The count increment changed from 1 to 2, presumably because we're adding both a binary sensor and notifications. This change should be documented to explain why we're incrementing by 2.

             data["binary_sensors"]["plugwise_notification"] = bool(self._notifications)
             data["notifications"] = self._notifications
-            self._count += 2
+            # Increment by 2: one for binary sensor and one for notifications
+            self._count += 2

306-309: Add error handling for missing gateway_id.

The method assumes self._gateway_id exists in self.gw_entities. Consider adding error handling for cases where the gateway entity might not exist.

     def check_reg_mode(self, mode: str) -> bool:
         """Helper-function for device_data_climate()."""
-        gateway = self.gw_entities[self._gateway_id]
+        gateway = self.gw_entities.get(self._gateway_id)
+        if not gateway:
+            return False
         return (
             "regulation_modes" in gateway and gateway["select_regulation_mode"] == mode
         )
plugwise/legacy/helper.py (2)

75-77: Consider using a more specific type for smile_version.

The Version type is used without a version specifier. Consider adding type bounds or constraints if specific version ranges are expected.


Line range hint 181-189: Add error handling for None values.

The method should handle cases where smile_version or other values might be None.

-            "firmware": str(self.smile_version),
+            "firmware": str(self.smile_version) if self.smile_version is not None else None,
plugwise/__init__.py (2)

Line range hint 324-332: Enhance error message with more context.

The error message could be more specific about what data is missing.

-            raise PlugwiseError("No Plugwise data received") from err
+            raise PlugwiseError(f"Failed to update Plugwise data: {err}") from err

210-226: Consider extracting version validation logic.

The version parsing and validation logic could be extracted into a separate method for better maintainability.

+    def _validate_version(self, model: str) -> None:
+        """Validate the smile version and model."""
+        if model == "Unknown" or self.smile_version is None:
+            LOGGER.error(
+                "Unable to find model or version information, please create"
+                " an issue on http://github.com/plugwise/python-plugwise"
+            )
+            raise UnsupportedDeviceError
+
     async def _smile_detect(self, result: etree, dsmrmain: etree) -> None:
         # ... existing code ...
-        if model == "Unknown" or self.smile_version is None:
-            LOGGER.error(
-                "Unable to find model or version information, please create"
-                " an issue on http://github.com/plugwise/python-plugwise"
-            )
-            raise UnsupportedDeviceError
+        self._validate_version(model)
fixtures/smile_p1_v2/data.json (1)

25-33: Consider using UUID format for gateway ID

The gateway ID aaaa0000aaaa0000aaaa0000aaaa00aa appears to be a placeholder. Consider using a UUID format consistent with other device IDs for better maintainability of test fixtures.

-  "aaaa0000aaaa0000aaaa0000aaaa00aa": {
+  "a455b61e52394b2db5081ce025a430f3": {
fixtures/p1v4_442_single/data.json (1)

41-41: Consider normalizing Unicode characters in vendor name

The vendor name contains Unicode characters (\uff08 and \uff09) which might cause issues in some environments. Consider normalizing to standard ASCII parentheses.

-    "vendor": "SHENZHEN KAIFA TECHNOLOGY \uff08CHENGDU\uff09 CO., LTD."
+    "vendor": "SHENZHEN KAIFA TECHNOLOGY (CHENGDU) CO., LTD."
fixtures/legacy_anna/data.json (1)

2-10: Maintain consistent ID format across fixtures

The gateway ID format differs from other fixtures. Consider using the same format (either UUID or the 'a' pattern) consistently across all test fixtures for better maintainability.

-  "0000aaaa0000aaaa0000aaaa0000aa00": {
+  "a270735e4ccd45239424badc0578a2b1": {
fixtures/anna_loria_heating_idle/data.json (1)

4-4: Remove trailing space in schedule name.

The schedule name "Test " contains a trailing space which might cause comparison issues.

-    "available_schedules": ["Winter", "Test ", "off"],
+    "available_schedules": ["Winter", "Test", "off"],
fixtures/anna_loria_driessens/data.json (1)

22-28: Implement i18n for schedule names.

Schedule names are hardcoded in a specific language. Consider implementing proper internationalization:

  1. Extract schedule names to language-specific resource files
  2. Use translation keys instead of hardcoded strings
fixtures/adam_plus_anna/data.json (1)

87-91: Enhance error notification structure.

The OpenTherm communication error notification should include:

  1. Timestamp of the error
  2. Error severity level
  3. Suggested troubleshooting steps
fixtures/stretch_v31/data.json (1)

101-116: Add metadata for report groups.

Consider enhancing the report group structure with:

  1. Creation timestamp
  2. Last modified timestamp
  3. Report generation frequency
  4. Report type/category
fixtures/m_adam_heating/data.json (1)

183-197: Consider adding low battery warning threshold.

The zone thermostat "Lisa Badkamer" shows low battery (14%) but there's no configuration for the warning threshold.

Consider adding a low_battery_threshold configuration to standardize when the low_battery binary sensor is triggered.

fixtures/stretch_v27_no_domain/data.json (1)

113-131: Standardize device class naming.

The device class "zz_misc" appears to be a placeholder or temporary classification. Consider using more descriptive and standardized device classes.

fixtures/m_adam_jip/data.json (2)

214-236: Gateway configuration looks good but consider adding version constraints.

The gateway configuration includes all necessary fields including the new notifications field. However, consider adding version constraints for firmware compatibility.

   "dev_class": "gateway",
   "firmware": "3.2.8",
+  "min_firmware": "3.0.0",
+  "recommended_firmware": "3.2.8",
   "hardware": "AME Smile 2.0 board",

227-227: Empty notifications object may need documentation.

The empty notifications object might benefit from a comment explaining its purpose and expected structure.

-  "notifications": {},
+  "notifications": {
+    // Example structure:
+    // "notification_id": {
+    //   "warning": "Description of the warning"
+    // }
+  },
fixtures/adam_jip/data.json (2)

Line range hint 567-589: Gateway notification structure provides good example.

The notification structure here provides a good template for handling device unreachability warnings. Consider documenting this as the standard format.

Consider extracting common notification types to a constants file:

# Example constants.py
NOTIFICATION_TYPES = {
    'DEVICE_UNREACHABLE': 'Node {device_name} (with MAC address {mac}, in room {room}) has been unreachable since {timestamp}. Please check the connection and restart the device.'
}

Line range hint 584-584: Warning message contains hardcoded values.

The warning message contains a hardcoded timestamp and MAC address. Consider using placeholders for better maintainability.

-        "warning": "Node Plug (with MAC address 000D6F000D13CB01, in room 'n.a.') has been unreachable since 23:03 2020-01-18. Please check the connection and restart the device."
+        "warning": "Node {device_type} (with MAC address {mac_address}, in room '{room}') has been unreachable since {timestamp}. Please check the connection and restart the device.",
+        "parameters": {
+          "device_type": "Plug",
+          "mac_address": "000D6F000D13CB01",
+          "room": "n.a.",
+          "timestamp": "23:03 2020-01-18"
+        }
fixtures/adam_zone_per_device/data.json (1)

25-31: Consider localizing schedule names.

The schedule names appear to be in a mix of languages. Consider using a translation system for better internationalization.

   "available_schedules": [
-      "CV Roan",
-      "Bios Schema met Film Avond",
-      "GF7  Woonkamer",
-      "Badkamer Schema",
-      "CV Jessie",
+      {"id": "cv_roan", "name": "CV Roan"},
+      {"id": "bios_schema", "name": "Bios Schema met Film Avond"},
+      {"id": "gf7_woonkamer", "name": "GF7  Woonkamer"},
+      {"id": "badkamer_schema", "name": "Badkamer Schema"},
+      {"id": "cv_jessie", "name": "CV Jessie"},
       "off"
   ],
fixtures/anna_v4_dhw/data.json (1)

4-4: Standardize language usage in configuration.

The schedule names are in Dutch ("Standaard", "Thuiswerken") while the rest of the configuration is in English. Consider standardizing the language usage for better maintainability.

Consider translating schedule names to English or providing language-specific configuration files.

Also applies to: 61-66

fixtures/anna_elga_no_cooling/data.json (1)

31-36: Review cooling activation threshold configuration.

The cooling activation temperature (21.0°C) is set very close to the current room temperature (19.3°C), with a deactivation threshold of 4.0°C. This narrow margin might cause frequent switching between heating and cooling modes.

Consider implementing hysteresis or a wider temperature band to prevent system oscillation.

Also applies to: 73-75

fixtures/anna_heatpump_cooling/data.json (1)

42-50: Consider adding documentation for heat pump specific parameters.

The heat pump configuration includes several specialized parameters that would benefit from documentation:

  • dhw_temperature
  • modulation_level (integer percentage?)
  • water_pressure (units?)
  • Various temperature readings and their relationships

Consider adding a schema file or documentation to explain these parameters and their valid ranges.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f9dacc6 and d617297.

📒 Files selected for processing (82)
  • CHANGELOG.md (1 hunks)
  • fixtures/adam_heatpump_cooling/all_data.json (0 hunks)
  • fixtures/adam_heatpump_cooling/data.json (1 hunks)
  • fixtures/adam_jip/all_data.json (0 hunks)
  • fixtures/adam_jip/data.json (1 hunks)
  • fixtures/adam_multiple_devices_per_zone/all_data.json (0 hunks)
  • fixtures/adam_multiple_devices_per_zone/data.json (1 hunks)
  • fixtures/adam_onoff_cooling_fake_firmware/all_data.json (0 hunks)
  • fixtures/adam_onoff_cooling_fake_firmware/data.json (1 hunks)
  • fixtures/adam_plus_anna/all_data.json (0 hunks)
  • fixtures/adam_plus_anna/data.json (1 hunks)
  • fixtures/adam_plus_anna_new/all_data.json (0 hunks)
  • fixtures/adam_plus_anna_new/data.json (1 hunks)
  • fixtures/adam_plus_anna_new_regulation_off/all_data.json (0 hunks)
  • fixtures/adam_plus_anna_new_regulation_off/data.json (1 hunks)
  • fixtures/adam_zone_per_device/all_data.json (0 hunks)
  • fixtures/adam_zone_per_device/data.json (1 hunks)
  • fixtures/anna_elga_2/all_data.json (0 hunks)
  • fixtures/anna_elga_2/data.json (1 hunks)
  • fixtures/anna_elga_2_cooling/all_data.json (0 hunks)
  • fixtures/anna_elga_2_cooling/data.json (1 hunks)
  • fixtures/anna_elga_2_schedule_off/all_data.json (0 hunks)
  • fixtures/anna_elga_2_schedule_off/data.json (1 hunks)
  • fixtures/anna_elga_no_cooling/all_data.json (0 hunks)
  • fixtures/anna_elga_no_cooling/data.json (1 hunks)
  • fixtures/anna_heatpump_cooling/all_data.json (0 hunks)
  • fixtures/anna_heatpump_cooling/data.json (1 hunks)
  • fixtures/anna_heatpump_cooling_fake_firmware/all_data.json (0 hunks)
  • fixtures/anna_heatpump_cooling_fake_firmware/data.json (1 hunks)
  • fixtures/anna_heatpump_heating/all_data.json (0 hunks)
  • fixtures/anna_heatpump_heating/data.json (1 hunks)
  • fixtures/anna_loria_cooling_active/all_data.json (0 hunks)
  • fixtures/anna_loria_cooling_active/data.json (1 hunks)
  • fixtures/anna_loria_driessens/all_data.json (0 hunks)
  • fixtures/anna_loria_driessens/data.json (1 hunks)
  • fixtures/anna_loria_heating_idle/all_data.json (0 hunks)
  • fixtures/anna_loria_heating_idle/data.json (1 hunks)
  • fixtures/anna_v4/all_data.json (0 hunks)
  • fixtures/anna_v4/data.json (1 hunks)
  • fixtures/anna_v4_dhw/all_data.json (0 hunks)
  • fixtures/anna_v4_dhw/data.json (1 hunks)
  • fixtures/anna_v4_no_tag/all_data.json (0 hunks)
  • fixtures/anna_v4_no_tag/data.json (1 hunks)
  • fixtures/anna_without_boiler_fw441/all_data.json (0 hunks)
  • fixtures/anna_without_boiler_fw441/data.json (1 hunks)
  • fixtures/legacy_anna/all_data.json (0 hunks)
  • fixtures/legacy_anna/data.json (1 hunks)
  • fixtures/legacy_anna_2/all_data.json (0 hunks)
  • fixtures/legacy_anna_2/data.json (1 hunks)
  • fixtures/m_adam_cooling/all_data.json (0 hunks)
  • fixtures/m_adam_cooling/data.json (1 hunks)
  • fixtures/m_adam_heating/all_data.json (0 hunks)
  • fixtures/m_adam_heating/data.json (1 hunks)
  • fixtures/m_adam_jip/all_data.json (0 hunks)
  • fixtures/m_adam_jip/data.json (1 hunks)
  • fixtures/m_adam_multiple_devices_per_zone/all_data.json (0 hunks)
  • fixtures/m_adam_multiple_devices_per_zone/data.json (1 hunks)
  • fixtures/m_anna_heatpump_cooling/all_data.json (0 hunks)
  • fixtures/m_anna_heatpump_cooling/data.json (1 hunks)
  • fixtures/m_anna_heatpump_idle/all_data.json (0 hunks)
  • fixtures/m_anna_heatpump_idle/data.json (1 hunks)
  • fixtures/p1v4_442_single/all_data.json (0 hunks)
  • fixtures/p1v4_442_single/data.json (1 hunks)
  • fixtures/p1v4_442_triple/all_data.json (0 hunks)
  • fixtures/p1v4_442_triple/data.json (1 hunks)
  • fixtures/smile_p1_v2/all_data.json (0 hunks)
  • fixtures/smile_p1_v2/data.json (1 hunks)
  • fixtures/smile_p1_v2_2/all_data.json (0 hunks)
  • fixtures/smile_p1_v2_2/data.json (1 hunks)
  • fixtures/stretch_v23/all_data.json (0 hunks)
  • fixtures/stretch_v23/data.json (1 hunks)
  • fixtures/stretch_v27_no_domain/all_data.json (0 hunks)
  • fixtures/stretch_v27_no_domain/data.json (1 hunks)
  • fixtures/stretch_v31/all_data.json (0 hunks)
  • fixtures/stretch_v31/data.json (1 hunks)
  • plugwise/__init__.py (11 hunks)
  • plugwise/common.py (2 hunks)
  • plugwise/constants.py (2 hunks)
  • plugwise/data.py (5 hunks)
  • plugwise/helper.py (12 hunks)
  • plugwise/legacy/data.py (2 hunks)
  • plugwise/legacy/helper.py (5 hunks)
⛔ Files not processed due to max files limit (12)
  • plugwise/legacy/smile.py
  • plugwise/smile.py
  • plugwise/smilecomm.py
  • plugwise/util.py
  • pyproject.toml
  • scripts/manual_fixtures.py
  • tests/test_adam.py
  • tests/test_anna.py
  • tests/test_generic.py
  • tests/test_init.py
  • tests/test_legacy_anna.py
  • tests/test_p1.py
💤 Files with no reviewable changes (37)
  • fixtures/m_adam_heating/all_data.json
  • fixtures/anna_loria_driessens/all_data.json
  • fixtures/stretch_v23/all_data.json
  • fixtures/adam_plus_anna/all_data.json
  • fixtures/anna_elga_2/all_data.json
  • fixtures/p1v4_442_single/all_data.json
  • fixtures/anna_heatpump_cooling_fake_firmware/all_data.json
  • fixtures/adam_onoff_cooling_fake_firmware/all_data.json
  • fixtures/anna_v4_no_tag/all_data.json
  • fixtures/adam_multiple_devices_per_zone/all_data.json
  • fixtures/anna_heatpump_cooling/all_data.json
  • fixtures/legacy_anna/all_data.json
  • fixtures/anna_elga_no_cooling/all_data.json
  • fixtures/stretch_v27_no_domain/all_data.json
  • fixtures/stretch_v31/all_data.json
  • fixtures/anna_elga_2_schedule_off/all_data.json
  • fixtures/smile_p1_v2/all_data.json
  • fixtures/smile_p1_v2_2/all_data.json
  • fixtures/anna_loria_cooling_active/all_data.json
  • fixtures/adam_plus_anna_new_regulation_off/all_data.json
  • fixtures/m_adam_multiple_devices_per_zone/all_data.json
  • fixtures/m_adam_cooling/all_data.json
  • fixtures/p1v4_442_triple/all_data.json
  • fixtures/anna_v4_dhw/all_data.json
  • fixtures/m_adam_jip/all_data.json
  • fixtures/adam_plus_anna_new/all_data.json
  • fixtures/m_anna_heatpump_cooling/all_data.json
  • fixtures/anna_v4/all_data.json
  • fixtures/anna_elga_2_cooling/all_data.json
  • fixtures/anna_heatpump_heating/all_data.json
  • fixtures/m_anna_heatpump_idle/all_data.json
  • fixtures/anna_without_boiler_fw441/all_data.json
  • fixtures/adam_jip/all_data.json
  • fixtures/adam_zone_per_device/all_data.json
  • fixtures/anna_loria_heating_idle/all_data.json
  • fixtures/legacy_anna_2/all_data.json
  • fixtures/adam_heatpump_cooling/all_data.json
🧰 Additional context used
📓 Learnings (1)
fixtures/m_adam_heating/data.json (1)
Learnt from: bouwew
PR: plugwise/python-plugwise#630
File: tests/data/adam/adam_g_o.json:0-0
Timestamp: 2024-11-12T13:49:49.714Z
Learning: The minimal information for the `heater_central` device is due to a known bug still present in the code.
🔇 Additional comments (61)
fixtures/m_adam_multiple_devices_per_zone/data.json (1)

1-584: LGTM! Well-structured test fixture with comprehensive device configurations.

The JSON structure is well-organized and provides a realistic test dataset for various device types and configurations.

plugwise/common.py (5)

12-12: Import statement looks good.

Importing NONE from plugwise.constants aligns with its usage in _heater_id. No concerns here.


30-43: Consider unifying the behavior for legacy and non-legacy.

The get_zigbee_data function updates zigbee_mac_address and reachable only in the non-legacy (elif) path. You might want to clarify whether reachable should also be considered in the legacy path to keep behavior consistent. Also, if router.find("mac_address") or coord.find("mac_address") is None, using .text may cause an AttributeError. Ensure these elements are always present or guard against None.


53-53: Default assignment for _heater_id looks appropriate.

Setting self._heater_id to NONE provides a clear default state.


55-55: gw_entities initialization is fine.

Initializing an empty dictionary for gw_entities will help ensure no KeyErrors when populating it later.


245-245: Function call is well-integrated.

Calling get_zigbee_data from _get_module_data centralizes Zigbee parsing logic, improving maintainability. No issues here.

plugwise/helper.py (6)

47-47: Import for collect_power_values is consistent.

You’re introducing a new helper function usage from plugwise.util. This is good for modularity.


49-49: Newly imported count_data_items.

Same as above, modularizing counting logic into a utility function is beneficial.


82-82: Verify usage of _gateway_id.

Assigning _gateway_id to NONE ensures a default fallback. Double-check external references to ensure they use _gateway_id properly.


393-393: collect_power_values usage is appropriate.

This call cleanly delegates logic to a dedicated function, enhancing readability and reducing duplication.


429-429: Counting data items.

Good approach in calling count_data_items to consistently track your _count variable.


570-570: Conditional for _is_thermostat and _gateway_id.

This check precisely focuses on whether the entity is the gateway in a thermostat scenario. Looks fine.

plugwise/legacy/data.py (4)

10-10: Import statements look correct.

Adding SmileProps aligns well with the new property-based approach.


26-26: Clear docstring explanation.

The docstring clarifies the method’s purpose: collecting data into _smile_props and gw_entities.


29-30: Assigning gateway properties.

Storing gateway_id and item_count in _smile_props is consistent with the new property-based data model.


33-33: Adding heater_id to _smile_props.

This is consistent with the property-based approach. Ensures relevant data is consolidated in a single structure.

plugwise/data.py (1)

30-31: LGTM! Good use of type hints.

The initialization of _smile_props and _zones with proper type hints improves code clarity and type safety.

plugwise/constants.py (2)

396-405: LGTM! Well-structured TypedDict definition.

The SmileProps TypedDict is well-defined with clear field names and types. The use of total=False is appropriate as not all fields will be present in every instance.


553-553: LGTM! Consistent type definition.

The addition of the notifications field to GwEntityData maintains type consistency across the codebase.

plugwise/__init__.py (1)

86-117: LGTM! Well-designed property accessors.

The properties provide a clean and type-safe interface to access _smile_props values. Good use of docstrings and proper handling of optional values.

fixtures/smile_p1_v2_2/data.json (1)

1-34: LGTM! Data structure is consistent with other fixtures

The file maintains consistent structure with other fixtures while providing variant test data.

fixtures/anna_without_boiler_fw441/data.json (1)

1-61: LGTM! Well-structured thermostat configuration

The file provides a comprehensive test fixture for thermostat functionality with appropriate value ranges and consistent decimal precision.

fixtures/anna_heatpump_cooling_fake_firmware/data.json (1)

33-38: Verify vector length validation.

The dot product calculation correctly validates vector lengths before computation, but consider adding input type validation to ensure both inputs are numeric arrays.

fixtures/anna_loria_cooling_active/data.json (1)

66-71: Inconsistent temperature resolution values.

The resolution values differ between max_dhw_temperature (0.01) and maximum_boiler_temperature (0.01), while in other fixtures they are 1.0. This inconsistency might affect temperature control precision.

Also applies to: 72-77

fixtures/m_anna_heatpump_idle/data.json (1)

75-76: Validate cooling temperature thresholds.

The cooling activation temperature (25.0°C) and deactivation threshold (4.0°C) have a large gap. Consider if this is intentional or if tighter bounds would be more energy efficient.

✅ Verification successful

Cooling temperature thresholds are within normal ranges

The cooling activation temperature (25.0°C) and deactivation threshold (4.0°C) are consistent with patterns seen across other fixtures, where similar gaps are common. The values appear to be intentionally configured this way.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check cooling threshold ranges across fixtures
rg '"cooling_activation_outdoor_temperature":\s*(\d+\.?\d*)' fixtures/
rg '"cooling_deactivation_threshold":\s*(\d+\.?\d*)' fixtures/

Length of output: 1776

fixtures/m_anna_heatpump_cooling/data.json (2)

48-54: Validate sensor readings consistency.

The temperature readings show expected relationships:

  • outdoor_air_temperature (28.0°C) matches the gateway's outdoor_temperature (28.2°C)
  • water_temperature (22.7°C) is higher than intended_boiler_temperature (0.0°C) during cooling

23-29: Verify state consistency.

The binary sensors show that cooling is active (cooling_state: true) while heating is inactive (heating_state: false), which is correct. However, we should ensure these states are mutually exclusive across all scenarios.

✅ Verification successful

States are properly mutually exclusive

The comprehensive analysis of all JSON fixtures confirms that heating and cooling states are never simultaneously active, maintaining proper system state consistency.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any cases where both heating and cooling are active
rg -A 5 '"cooling_state":\s*true' fixtures/ | rg '"heating_state":\s*true'

Length of output: 76


Script:

#!/bin/bash
# Create a Python script to analyze JSON files
cat << 'EOF' > analyze_states.py
import json
import glob
import os

def check_states(data):
    if isinstance(data, dict):
        cooling = data.get('cooling_state', False)
        heating = data.get('heating_state', False)
        if cooling and heating:
            return True
        for value in data.values():
            if check_states(value):
                return True
    elif isinstance(data, list):
        return any(check_states(item) for item in data)
    return False

conflicts = []
for json_file in glob.glob('fixtures/**/*.json', recursive=True):
    try:
        with open(json_file) as f:
            data = json.load(f)
            if check_states(data):
                conflicts.append(json_file)
    except json.JSONDecodeError:
        print(f"Error parsing {json_file}")

if conflicts:
    print("Files with conflicting states:")
    for file in conflicts:
        print(file)
else:
    print("No conflicts found - heating and cooling states are mutually exclusive")
EOF

python analyze_states.py

Length of output: 103

fixtures/anna_heatpump_heating/data.json (3)

33-37: Verify temperature bounds are within safe operational limits.

The temperature bounds configuration:

  • DHW temperature: 35.0°C to 60.0°C
  • Boiler temperature: 0.0°C to 100.0°C

These ranges appear reasonable, but please verify they align with the manufacturer's specifications for safe operation.

Also applies to: 39-43


10-10: Replace placeholder MAC address with a valid format.

The MAC address appears to be a placeholder value. In production, ensure MAC addresses follow the standard format (XX:XX:XX:XX:XX:XX).


73-74: Consider adding validation for schedule names.

The schedule names contain non-ASCII characters. Ensure the system properly handles Unicode strings in schedule names across all interfaces.

fixtures/anna_loria_driessens/data.json (1)

70-70: Consider adding data validation for sensor readings.

The sensor readings (temperatures, modulation levels) should be validated against expected ranges:

  • DHW temperature: 49.5°C
  • Water temperature: 23.3°C
  • Return temperature: 23.0°C

Also applies to: 88-95

fixtures/adam_onoff_cooling_fake_firmware/data.json (2)

44-44: Review safety implications of regulation modes.

The regulation modes include maintenance operations (bleeding_cold, bleeding_hot). Ensure these modes:

  1. Have proper safety interlocks
  2. Cannot be activated during normal operation
  3. Are properly documented for maintenance personnel

Also applies to: 53-59


106-109: Consider implementing proper error handling for thermostats array.

The thermostats.secondary array is empty. Ensure the system properly handles cases where:

  1. No secondary thermostats are present
  2. Primary thermostat becomes unavailable
fixtures/adam_plus_anna/data.json (1)

117-122: Add validation for electricity consumption metrics.

Consider adding validation for electricity consumption values:

  1. Ensure consumed values are non-negative
  2. Verify interval values are consistent with total consumption
  3. Add maximum threshold alerts
fixtures/m_adam_cooling/data.json (3)

12-16: Verify maximum boiler temperature bounds for cooling mode.

The maximum boiler temperature bounds (25.0-95.0°C) seem more appropriate for heating than cooling mode. Consider adjusting these bounds for cooling operation.


74-96: LGTM: Gateway configuration for cooling mode is complete.

The gateway configuration correctly includes:

  • Cooling in regulation modes
  • Current regulation mode set to cooling
  • Appropriate gateway modes

137-169: Verify climate control configuration for cooling mode.

The living room climate control shows:

  • Appropriate control_state: "cooling"
  • Consistent climate_mode: "cool"
  • Temperature setpoint (23.5°C) within bounds
fixtures/m_adam_heating/data.json (2)

11-31: Verify DHW temperature configuration.

The domestic hot water (DHW) configuration shows:

  • Maximum temperature of 60°C is appropriate for safety
  • Setpoint within safe bounds

74-96: LGTM: Gateway configuration for heating mode is complete.

The gateway configuration correctly includes:

  • Heating in regulation modes
  • Current regulation mode set to heating
  • Appropriate gateway modes
fixtures/adam_plus_anna_new_regulation_off/data.json (1)

172-175: LGTM: Gateway configuration for regulation off mode is complete.

The gateway configuration correctly shows:

  • Regulation mode set to off
  • Maintained gateway modes for user control
fixtures/adam_plus_anna_new/data.json (1)

229-231: Verify climate mode and control state consistency.

The climate configuration shows:

  • climate_mode: "auto"
  • control_state: "heating"
    This is a valid combination indicating proper automatic temperature control.
fixtures/stretch_v27_no_domain/data.json (1)

73-91: Consider updating firmware versions.

Multiple Circle type F devices show firmware dates from 2011:

  • "2011-05-13T09:19:23+02:00"
  • "2011-06-27T10:52:18+02:00"

Consider checking if newer firmware versions are available for these devices.

Run the following script to check for newer firmware versions:

Also applies to: 173-191

fixtures/m_adam_jip/data.json (1)

332-337: Verify sensor value ranges.

The sensor values for the central heater should be validated against expected operational ranges:

  • water_temperature: 37.3°C seems low for a central heater
  • water_pressure: 1.4 bar is within normal range but close to low pressure
✅ Verification successful

Temperature and pressure values are normal for idle state

The current values are appropriate for a system in idle mode:

  • Water temperatures (37.3°C/37.1°C) are normal when no heating is requested (modulation_level: 0.0)
  • Water pressure of 1.4 bar is within safe operating range
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for typical water temperature ranges in the codebase
rg -A 2 "water_temperature.*setpoint" 

Length of output: 1850


Script:

#!/bin/bash
# Search for temperature-related patterns and ranges
rg -i "temperature.*range|min.*temperature|max.*temperature"

# Look for other test fixtures with similar data structure
fd "data.json" --exec grep -A 5 "water_temperature"

Length of output: 69981

fixtures/stretch_v23/data.json (1)

2-11: Gateway configuration is missing fields present in other fixtures.

The gateway configuration is missing several fields that are present in other fixture files:

  • notifications
  • regulation_modes
  • select_regulation_mode
fixtures/adam_zone_per_device/data.json (1)

579-584: Warning message format matches previous fixture.

Good consistency in notification format with adam_jip/data.json.

fixtures/adam_multiple_devices_per_zone/data.json (2)

50-54: Multiple primary thermostats configuration looks good.

The support for multiple primary thermostats in a zone is well-structured and consistent with the PR's objectives.


569-592: Gateway configuration matches expected structure.

The gateway configuration includes all required fields and maintains consistency with other fixtures.

fixtures/adam_heatpump_cooling/data.json (3)

285-313: LGTM: Gateway configuration is complete and well-structured.

The gateway configuration includes all necessary elements:

  • Firmware version
  • Hardware details
  • MAC addresses
  • Regulation modes
  • Gateway modes
  • Notifications handling

10-11: Verify climate mode consistency.

The climate modes vary between "cool", "auto", and "cool" across different zones. This mix of modes needs verification to ensure it aligns with the system's capabilities.

Let's check the climate mode distribution:

Also applies to: 128-129, 242-243, 416-417, 467-468, 551-552, 681-682, 783-784

✅ Verification successful

Climate mode distribution is consistent with system capabilities

The mix of "auto" and "cool" modes across different zones in this heat pump cooling system is valid and expected behavior. The same pattern is consistently reflected in the test data, confirming this is the intended configuration.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check climate mode distribution across zones
rg '"climate_mode":\s*"[^"]+"' -o | sort | uniq -c

Length of output: 4832


22-27: Inconsistent temperature bounds across thermostats.

Most thermostats have bounds of 0.0-99.9°C, but the Woonkamer thermostat has bounds of 1.0-35.0°C. This inconsistency could cause issues with temperature control and user experience.

Let's verify if this is intentional:

Also applies to: 140-145, 396-401, 479-484, 563-568, 693-698, 795-800

✅ Verification successful

Different temperature bounds are intentionally set based on thermostat type

The variation in temperature bounds is an intentional design pattern:

  • Anna (main room) thermostats: 4.0-30.0°C
  • Zone thermostats: 0.0-99.9°C or 0.0-100.0°C
  • Some specific models: 1.0-35.0°C

This consistent pattern across multiple test fixtures indicates the bounds are deliberately set based on the thermostat's role and capabilities, not an inconsistency that needs to be fixed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check temperature bounds across all thermostats
rg -A 5 '"thermostat":\s*{' | grep -E "lower_bound|upper_bound"

Length of output: 163


Script:

#!/bin/bash
# Search for thermostat configurations with context
rg -U --json "thermostat" | jq -r 'select(.type == "match") | .data.lines.text' | grep -A 5 "thermostat"

Length of output: 65639


Script:

#!/bin/bash
# Find all JSON files in fixtures directory and extract thermostat configurations
fd -e json . fixtures/ -x sh -c 'echo "=== $1 ==="; cat "$1" | jq -r ".thermostat? // empty"' sh {}

Length of output: 1825


Script:

#!/bin/bash
# Extract thermostat bounds from all JSON files
fd -e json . fixtures/ -x sh -c 'echo "=== $1 ==="; cat "$1" | jq -r ".. | select(.thermostat?) | .thermostat | select(.lower_bound != null) | \"lower_bound: \(.lower_bound), upper_bound: \(.upper_bound)\""' sh {}

Length of output: 3944

CHANGELOG.md (1)

7-7: LGTM: Clear and well-formatted changelog entry.

The new entry follows the established format and clearly describes the changes made in PR #690.

fixtures/legacy_anna_2/data.json (2)

10-10: Verify location references.

The location IDs appear to be UUIDs that cross-reference between devices. Ensure these references are valid and consistent.

Also applies to: 31-31, 46-46

✅ Verification successful

Location references are valid and consistent

All devices (thermostat, gateway, heater_central) properly reference the same location ID and can see each other within that location. The cross-referencing system is working as expected.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Extract and verify location references
jq -r '.[] | select(.location != null) | [.location, .dev_class] | @tsv' fixtures/legacy_anna_2/data.json | \
while IFS=$'\t' read -r loc dev; do
  echo "Checking references to location $loc from device type $dev"
  jq --arg loc "$loc" '.[] | select(.location == $loc) | .dev_class' fixtures/legacy_anna_2/data.json
done

Length of output: 1310


20-25: Verify temperature bounds and setpoints.

The thermostat configuration shows overlapping temperature control mechanisms:

  • temperature_offset: -2.0 to 2.0
  • thermostat: 4.0 to 30.0

Please verify that these ranges are correct and don't conflict with each other.

Also applies to: 26-31

✅ Verification successful

Temperature ranges are correctly configured and serve complementary purposes

The temperature ranges in the configuration are valid and don't conflict:

  • Thermostat range (4°C to 30°C): Primary temperature control for the room
  • Temperature offset (-2°C to +2°C): Fine-tuning adjustment to the main setpoint
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for temperature range definitions across the codebase
rg -A 2 "lower_bound.*temperature|upper_bound.*temperature" --type py

Length of output: 71


Script:

#!/bin/bash
# Search for thermostat configurations in fixture files
fd -e json -x cat {} \; | jq -c 'select(.thermostat != null) | .thermostat'

# Search for any temperature-related settings
rg -g '!*.json' -i "temperature|thermostat" -A 2

Length of output: 92249

fixtures/p1v4_442_triple/data.json (1)

28-53: Validate electricity readings and units.

The electricity readings include various measurements that should be validated:

  • Cumulative values should be non-negative
  • Interval values should be within expected ranges
  • Point values should correlate with phase readings
✅ Verification successful

Electricity readings validation successful

All electrical measurements are valid and consistent:

  • Cumulative values are non-negative
  • Interval values are within expected ranges
  • Phase readings (5546W total) correlate with net point value (5553W)
  • Phase voltages show normal residential levels (233-235V)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Analyze electricity readings across all fixture files
for f in fixtures/*/data.json; do
  echo "Analyzing $f"
  jq -r '.[] | select(.sensors.electricity_consumed_peak_cumulative != null) | 
    [.sensors.electricity_consumed_peak_cumulative, 
     .sensors.electricity_consumed_peak_point,
     (.sensors.electricity_phase_one_consumed // 0 + 
      .sensors.electricity_phase_two_consumed // 0 + 
      .sensors.electricity_phase_three_consumed // 0)] | @csv' "$f"
done

Length of output: 19579

fixtures/anna_v4_dhw/data.json (1)

61-72: Validate temperature bounds for DHW and boiler.

Please verify that the temperature bounds are safe and comply with regulations:

  • DHW: 30.0°C to 60.0°C
  • Boiler: 0.0°C to 100.0°C
✅ Verification successful

Temperature bounds are within safe operating ranges

The temperature bounds in the file are consistent with standard safety practices and match the common patterns across the codebase:

  • DHW range (30-60°C) prevents legionella growth while avoiding scalding risks
  • Boiler range (0-100°C) provides safe operation margins below water's boiling point
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for temperature safety guidelines in documentation
rg -l "temperature.*safety|temperature.*regulation" --type md

# Extract and compare temperature bounds across fixtures
for f in fixtures/*/data.json; do
  echo "Analyzing $f"
  jq -r '.[] | select(.max_dhw_temperature != null) | 
    [.max_dhw_temperature.lower_bound, 
     .max_dhw_temperature.upper_bound,
     .maximum_boiler_temperature.lower_bound,
     .maximum_boiler_temperature.upper_bound] | @csv' "$f"
done

Length of output: 15434

fixtures/anna_v4/data.json (1)

1-88: Configuration structure looks good.

The file follows the same structure as anna_v4_dhw/data.json with appropriate state variations.

fixtures/anna_v4_no_tag/data.json (1)

1-88: Configuration structure looks good.

The file follows the same structure as other Anna configurations with appropriate mode variations.

fixtures/anna_elga_2/data.json (2)

21-21: Verify outdoor temperature synchronization between devices.

The outdoor temperature values are inconsistent:

  • Heater sensor: 6.0°C
  • Gateway sensor: 6.38°C

Consider implementing a single source of truth for outdoor temperature readings.

Also applies to: 27-27, 81-81, 87-87


5-11: Verify the consistency of binary sensor states.

The heater shows potentially conflicting states:

  • Both heating_state and flame_state are true while compressor_state is also true
  • cooling_enabled is false but compressor_state is true

This combination of states might indicate a synchronization issue or invalid state transition.

✅ Verification successful

State combination is valid for this hybrid heating system

The combination of heating_state: true, flame_state: true, and compressor_state: true is valid for this device model ("Generic heater/cooler"). This is a known state combination for hybrid heating systems where both traditional heating and heat pump operation can work simultaneously.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for similar state combinations in other fixtures
rg -l --json '"heating_state": true.*"flame_state": true.*"compressor_state": true' || echo "No other instances found"

Length of output: 540


Script:

#!/bin/bash
# Find all JSON files first
echo "=== Searching for JSON files with state combinations ==="
rg -A 10 '"heating_state":' --type json

echo -e "\n=== Looking for schema or documentation files ==="
fd -e md -e json -e yaml -e yml . | grep -i "schema\|doc\|readme"

Length of output: 43828


Script:

#!/bin/bash
# Check README files for state documentation
echo "=== Checking README files for state documentation ==="
for f in $(fd -e md); do
  echo "=== Content of $f ==="
  cat "$f" | grep -A 5 -i "state\|mode\|heating\|cooling"
done

Length of output: 22475

fixtures/anna_elga_2_schedule_off/data.json (1)

39-41: Configuration looks good for schedule-off mode.

The system is properly configured with:

  • Schedule set to "off"
  • Climate mode set to "heat_cool"
  • Control state "idle"
  • All actuators inactive

Also applies to: 49-49

fixtures/anna_elga_2_cooling/data.json (1)

5-11: Cooling mode configuration is properly structured.

The system shows correct state combinations for active cooling:

  • All cooling-related binary sensors are true
  • Heating-related sensors are false
  • Setpoints and current temperature values align with cooling operation
  • Outdoor temperature (31.0°C) is above cooling activation threshold (26.0°C)

Also applies to: 51-56

Comment on lines +88 to +100
"d03738edfcc947f7b8f4573571d90d2d": {
"dev_class": "switching",
"members": [
"059e4d03c7a34d278add5c7a4a781d19",
"cfe95cf3de1948c0b8955125bf754614"
],
"model": "Switchgroup",
"name": "Schakel",
"switches": {
"relay": true
},
"vendor": "Plugwise"
},
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Validation logic for switching groups is missing and should be implemented

The codebase analysis confirms that there's no validation logic for:

  • Verifying the existence of member IDs
  • Checking if members support switching operations
  • Enforcing group size limits

The original review suggestions are valid and should be implemented to ensure data integrity and prevent operational issues.

🔗 Analysis chain

Enhance switching group validation.

For the switching group:

  1. Validate that all member IDs exist
  2. Ensure members support the switching operation
  3. Consider adding a maximum group size limit
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for group member validation patterns
ast-grep --pattern 'function validate_group_members($members) {
  $$$
}'

Length of output: 74


Script:

#!/bin/bash
# Search for validation-related code
echo "=== Searching for group validation patterns ==="
rg -i "validate.*group|group.*validate" -g "!*.{json,md}" -A 5

echo -e "\n=== Searching for member validation patterns ==="
rg -i "validate.*member|member.*validate" -g "!*.{json,md}" -A 5

echo -e "\n=== Searching for group-related size limits or constants ==="
rg -i "group.*size|max.*group|group.*limit" -g "!*.{json,md}" -A 5

echo -e "\n=== Finding potential validation files ==="
fd -e js -e ts "valid|group|switch"

Length of output: 694

Comment on lines +19 to +22
"sensors": {
"intended_boiler_temperature": 0.0,
"water_temperature": 30.0
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Verify intended boiler temperature for regulation off mode.

The intended boiler temperature is 0.0°C which seems incorrect. Even in regulation off mode, it should maintain a minimum safe temperature to prevent freezing.

Consider implementing a minimum safe temperature even when regulation is off.

Comment on lines +14 to +18
"notifications": {
"97a04c0c263049b29350a660b4cdd01e": {
"warning": "The Smile P1 is not connected to a smart meter."
}
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Resolve contradiction between warning and sensor data.

The gateway shows a warning that "The Smile P1 is not connected to a smart meter" (lines 14-18), but the device provides detailed electricity and gas readings (lines 27-53). This appears to be inconsistent.

Please verify if this is the intended behavior or if the warning should be removed.

Also applies to: 27-53

@codecov
Copy link

codecov bot commented Jan 29, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (f9dacc6) to head (340f795).
Report is 67 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #698   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           20        21    +1     
  Lines         3449      3408   -41     
=========================================
- Hits          3449      3408   -41     

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

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 (7)
plugwise/legacy/smile.py (7)

43-44: Clarify and document new constructor parameters
The _request and _smile_props parameters introduce a new async request logic and configuration data. It would be helpful to add docstrings explaining their roles and any constraints on their usage or lifecycle.


62-63: Ensure consistent error handling for the request
self._request may raise exceptions if the device is unreachable. Currently, there is partial handling under KeyError and ConnectionFailedError, but consider verifying or enhancing it to handle all relevant exception types.


81-86: Handle potential request errors
Retrieving _domain_objects, _locations, _modules, and _appliances could fail if the device is offline. Currently, only a KeyError path is handled. Consider capturing other relevant exceptions (ConnectionFailedError) for a robust and user-friendly error boundary.


106-106: Refine debug logging
“HOI First update” might be a leftover debugging string. Consider rewording it for clarity or removing it if no longer needed.


123-128: Partial update checks
For partial updates, _locations is skipped. Verify if that is intentional and that location data remains valid until the next full update.


138-138: Returning mutable state
return self.gw_entities returns a mutable dictionary. If consumers might unintentionally modify it, consider returning a copy or a read-only proxy.


298-298: Consider surfacing more descriptive errors
Re-raising ConnectionFailedError captures reachability issues well. To aid debugging, consider logging details (like URI/method) or re-raising with added context.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between d617297 and d0863cb.

📒 Files selected for processing (2)
  • plugwise/legacy/smile.py (5 hunks)
  • pyproject.toml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Run pytest using Python 3.12
  • GitHub Check: Run pytest using Python 3.13.0
🔇 Additional comments (9)
plugwise/legacy/smile.py (7)

22-22: Validate usage of newly imported entities
SmileProps and ThermoLoc are newly imported. Ensure these types are leveraged consistently throughout the codebase and that their usage aligns with the new data-structure design.


53-53: Double-check version usage
Storing smile_version: Version | None is fine, but confirm that downstream logic gracefully handles the None case (e.g., if version-based features are disabled or defaulted).


72-72: Confirm version logic
Assigning self.smile_version directly is correct, but confirm if additional validation or fallback (e.g., default version) is needed.


76-76: Initialization clarity
self._first_update = True helps differentiate first-run logic, but ensure there are no race conditions if multiple updates run concurrently on startup.


101-101: Updated return type
The async_update method returning dict[str, GwEntityData] aligns well with the new single dict output structure. Just confirm that other references match this updated signature.


108-108: Day-change logic
Using weekday (%w) logic to trigger a full update is straightforward but might skip certain edge cases if the system time changes abruptly. If that’s acceptable, no further action is needed.


136-136: State management
self._first_update = False looks correct. Just be mindful of any concurrency if multiple updates can overlap.

pyproject.toml (2)

7-7: Version bump to 1.7.0a9 aligns with architectural changes.

The version change from 1.6.4 to 1.7.0a9 follows semantic versioning principles and correctly reflects the significant architectural changes described in the PR objectives (restructuring data handling, relocating classes).

Let's verify the version change is documented in the changelog:

✅ Verification successful

Version 1.7.0a9 is properly documented under "Ongoing" section

The version bump aligns with the significant architectural changes documented in the "Ongoing" section of CHANGELOG.md, particularly PR #690 which implements the core restructuring work.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if version change is documented
rg -A 5 "1\.7\.0" CHANGELOG.md || echo "Version 1.7.0 not found in changelog"

Length of output: 115


Script:

#!/bin/bash
# Check the structure of CHANGELOG.md
echo "=== First 20 lines of CHANGELOG.md ==="
head -n 20 CHANGELOG.md

echo -e "\n=== Searching for unreleased sections ==="
rg -i "unreleased|development|next" CHANGELOG.md

Length of output: 1706


Line range hint 18-19: Consider updating Python version specifications for consistency.

The project requires Python >=3.12.0 but includes classifiers for both Python 3.12 and 3.13. The tool configurations (pylint, mypy) are set to Python 3.13. Consider aligning these version specifications for consistency.

Let's check the Python version requirements across the codebase:

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)
plugwise/legacy/smile.py (1)

122-127: Consider using an enum for _target_smile values.

The match statement improves readability, but using string literals for _target_smile values could be error-prone. Consider using an enum for type safety.

from enum import Enum, auto

class SmileTarget(Enum):
    SMILE_V2 = auto()
    # Add other targets here

# Then use it in the match statement:
match self._target_smile:
    case SmileTarget.SMILE_V2:
        self._modules = await self._request(MODULES)
    case target if target in REQUIRE_APPLIANCES:
        self._appliances = await self._request(APPLIANCES)
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between d0863cb and 0f9315e.

📒 Files selected for processing (1)
  • plugwise/legacy/smile.py (5 hunks)
🔇 Additional comments (5)
plugwise/legacy/smile.py (5)

22-22: LGTM: Import of SmileProps aligns with PR objectives.

The addition of SmileProps supports the architectural change of converting gateway items to Smile properties.


43-44: LGTM: New parameters improve encapsulation.

The addition of _request and _smile_props as constructor parameters improves dependency injection and aligns with the PR's goal of restructuring gateway data handling.


101-107: LGTM: Improved update logic with explicit full update conditions.

The return type change to dict[str, GwEntityData] aligns with the PR's goal of using a single dictionary. The update logic is now more explicit with the _first_update flag.


135-137: LGTM: Proper state management in update method.

The update method correctly manages state by updating _first_update and _previous_day_number before returning the gateway entities.


76-76: Verify the initialization of _first_update.

The _first_update flag controls when to perform full updates. Ensure this doesn't cause unnecessary full updates in edge cases like rapid consecutive calls to async_update.

✅ Verification successful

_first_update implementation is safe and efficient

The flag is properly implemented to ensure full updates only occur on first run and day changes, while using incremental updates for all other cases. This prevents unnecessary full updates during rapid consecutive calls to async_update.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any existing update throttling or debouncing mechanisms
rg -A 5 "first_update|update_interval|throttle|debounce" --type python

Length of output: 103


Script:

#!/bin/bash
# Search for _first_update usage and update-related logic
rg -A 10 "_first_update|async_update|update" "*.py"

# Also search specifically in the smile.py file
cat plugwise/legacy/smile.py

Length of output: 11795

Copy link
Member

@CoMPaTech CoMPaTech left a comment

Choose a reason for hiding this comment

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

Lot's to digest :) But looking very thorough! Good work

@CoMPaTech
Copy link
Member

Checked off sonar cloud http complaint as well

@CoMPaTech
Copy link
Member

@coderabbitai full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 29, 2025

✅ Actions performed

Full review triggered.

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 (19)
plugwise/legacy/helper.py (1)

181-181: Handle None firmware versions carefully.
If self.smile_version is None, calling str(self.smile_version) will produce "None", which might be confusing to end users. Consider handling this condition explicitly.

- "firmware": str(self.smile_version),
+ "firmware": str(self.smile_version) if self.smile_version is not None else "unknown",
plugwise/__init__.py (2)

191-191: Pass smile_version carefully.
Ensure that subsequent operations in SmileLegacyAPI or SmileAPI handle a potentially None version.


226-226: String conversion of major version.
version_major = str(self.smile_version.major) is valid. Confirm no further usage demands minor/patch details.

plugwise/data.py (1)

306-309: Enhance error handling in check_reg_mode.

The function assumes gateway will have a select_regulation_mode key. Consider adding a defensive check.

 def check_reg_mode(self, mode: str) -> bool:
     """Helper-function for device_data_climate()."""
     gateway = self.gw_entities[self._gateway_id]
-    return (
-        "regulation_modes" in gateway and gateway["select_regulation_mode"] == mode
-    )
+    return (
+        "regulation_modes" in gateway
+        and "select_regulation_mode" in gateway
+        and gateway["select_regulation_mode"] == mode
+    )
fixtures/p1v4_442_single/data.json (1)

41-41: Fix Unicode characters in vendor name.

The vendor name contains Unicode escape sequences \uff08 and \uff09 instead of regular parentheses.

-    "vendor": "SHENZHEN KAIFA TECHNOLOGY \uff08CHENGDU\uff09 CO., LTD."
+    "vendor": "SHENZHEN KAIFA TECHNOLOGY (CHENGDU) CO., LTD."
fixtures/anna_without_boiler_fw441/data.json (1)

42-42: Consider masking sensitive MAC address.

The MAC address is exposed in plain text. Consider masking part of the MAC address in test fixtures to prevent potential security risks.

-    "mac_address": "D40FB200FA1C",
+    "mac_address": "D4:0F:B2:XX:XX:XX",
fixtures/legacy_anna/data.json (1)

5-6: Use realistic test data for location IDs.

The location IDs use a pattern of zeros and 'a's which is clearly test data. Consider using realistic UUIDs for better test coverage.

-    "location": "0000aaaa0000aaaa0000aaaa0000aa00",
+    "location": "550e8400-e29b-41d4-a716-446655440000",

Also applies to: 31-33

fixtures/anna_v4/data.json (2)

1-88: Consider adding JSON schema validation.

The file contains well-structured device configurations, but lacks formal schema validation. This could lead to potential issues with malformed data during testing.

Consider adding a JSON schema file to validate:

  • Required fields for each device type
  • Value ranges for temperature settings
  • Enumerated values for modes and states
  • Data types for all fields

Would you like me to generate a JSON schema file for validation?


61-72: Document temperature units and ranges.

The temperature-related configurations would benefit from explicit documentation of:

  • Units (Celsius/Fahrenheit)
  • Valid ranges and their real-world implications
  • Resolution constraints
fixtures/anna_elga_2_cooling/data.json (1)

39-39: Ensure consistent schedule naming across fixtures.

The schedule name "Thermostat schedule" differs from "Winter" used in other fixture files. Consider standardizing schedule names across test fixtures for consistency.

fixtures/anna_loria_cooling_active/data.json (1)

64-71: Schema differences between vendors need documentation.

The Atlantic vendor device includes additional features not present in Techneco devices:

  • DHW modes: ["off", "auto", "boost", "eco", "comfort"]
  • Additional switch: cooling_ena_switch

Consider documenting these vendor-specific differences in the schema documentation.

Also applies to: 90-93

fixtures/anna_loria_heating_idle/data.json (1)

4-4: Remove trailing whitespace in schedule name.

The schedule name "Test " contains trailing whitespace which should be removed for consistency.

-    "available_schedules": ["Winter", "Test ", "off"],
+    "available_schedules": ["Winter", "Test", "off"],
plugwise/common.py (1)

50-55: Add type hints for class attributes.

Consider adding type hints for all class attributes to improve code maintainability and IDE support.

Apply this diff:

-        self._cooling_present: bool
+        self._cooling_present: bool = False
         self._count: int
         self._domain_objects: etree
-        self._heater_id: str = NONE
+        self._heater_id: str = NONE
         self._on_off_device: bool
-        self.gw_entities: dict[str, GwEntityData] = {}
+        self.gw_entities: dict[str, GwEntityData] = {}
plugwise/helper.py (3)

82-84: Consider using a dataclass for initialization.

The initialization of multiple related attributes could be simplified using a dataclass to improve code organization and maintainability.

+from dataclasses import dataclass
+
+@dataclass
+class SmileHelperState:
+    gateway_id: str = NONE
+    zones: dict[str, GwEntityData] = field(default_factory=dict)
+    gw_entities: dict[str, GwEntityData] = field(default_factory=dict)

 class SmileHelper(SmileCommon):
     def __init__(self) -> None:
-        self._gateway_id: str = NONE
-        self._zones: dict[str, GwEntityData]
-        self.gw_entities: dict[str, GwEntityData]
+        self._state = SmileHelperState()

628-632: Improve docstring formatting.

The docstring formatting could be improved to follow standard conventions.

-        """# Anna+Elga: base cooling_state on the elga-status-code.
-
-        For Elga, 'elga_status_code' in (8, 9) means cooling is enabled.
-        'elga_status_code' = 8 means cooling is active, 9 means idle.
-        """
+        """Base cooling_state on the elga-status-code for Anna+Elga.
+
+        For Elga:
+        - 'elga_status_code' in (8, 9) means cooling is enabled
+        - 'elga_status_code' = 8 means cooling is active
+        - 'elga_status_code' = 9 means idle
+        """

654-658: Improve docstring formatting.

Similar to the previous comment, the docstring formatting could be improved.

-        """Loria/Thermastage: base cooling-related on cooling_state and modulation_level.
-
-        For the Loria or Thermastage heatpump connected to an Anna cooling-enabled is
-        indicated via the Cooling Enable switch in the Plugwise App.
-        """
+        """Base cooling-related settings on cooling_state and modulation_level for Loria/Thermastage.
+
+        For Loria or Thermastage heatpump connected to an Anna:
+        Cooling is enabled via the Cooling Enable switch in the Plugwise App.
+        """
fixtures/anna_loria_driessens/data.json (1)

22-28: Standardize schedule naming convention.

The schedule names mix languages and formats:

  • "Verwarmen@9-23u" (Dutch)
  • "VAKANTIE (winter)" (Dutch)
  • "VERWARMEN" (Dutch)
  • "KOELEN" (Dutch)
  • "off" (English)

Consider standardizing to a single language and format for consistency.

fixtures/adam_jip/data.json (1)

Line range hint 581-585: Enhance notification message format.

The warning message contains embedded device details that could be structured better:

"warning": "Node Plug (with MAC address 000D6F000D13CB01, in room 'n.a.') has been unreachable since 23:03 2020-01-18..."

Consider restructuring as:

"warning": {
  "device_type": "Node Plug",
  "mac_address": "000D6F000D13CB01",
  "room": "n.a.",
  "last_seen": "2020-01-18T23:03:00",
  "message": "Device has been unreachable"
}
fixtures/adam_heatpump_cooling/data.json (1)

34-73: Consider optimizing temperature bounds for energy efficiency.

While the configuration is valid, consider reviewing these temperature settings for optimal energy efficiency:

  • DHW temperature upper bound (65.0°C) could potentially be lowered
  • Maximum boiler temperature setpoint (35.0°C) seems high for a cooling system
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f9dacc6 and 0f9315e.

📒 Files selected for processing (82)
  • CHANGELOG.md (1 hunks)
  • fixtures/adam_heatpump_cooling/all_data.json (0 hunks)
  • fixtures/adam_heatpump_cooling/data.json (1 hunks)
  • fixtures/adam_jip/all_data.json (0 hunks)
  • fixtures/adam_jip/data.json (1 hunks)
  • fixtures/adam_multiple_devices_per_zone/all_data.json (0 hunks)
  • fixtures/adam_multiple_devices_per_zone/data.json (1 hunks)
  • fixtures/adam_onoff_cooling_fake_firmware/all_data.json (0 hunks)
  • fixtures/adam_onoff_cooling_fake_firmware/data.json (1 hunks)
  • fixtures/adam_plus_anna/all_data.json (0 hunks)
  • fixtures/adam_plus_anna/data.json (1 hunks)
  • fixtures/adam_plus_anna_new/all_data.json (0 hunks)
  • fixtures/adam_plus_anna_new/data.json (1 hunks)
  • fixtures/adam_plus_anna_new_regulation_off/all_data.json (0 hunks)
  • fixtures/adam_plus_anna_new_regulation_off/data.json (1 hunks)
  • fixtures/adam_zone_per_device/all_data.json (0 hunks)
  • fixtures/adam_zone_per_device/data.json (1 hunks)
  • fixtures/anna_elga_2/all_data.json (0 hunks)
  • fixtures/anna_elga_2/data.json (1 hunks)
  • fixtures/anna_elga_2_cooling/all_data.json (0 hunks)
  • fixtures/anna_elga_2_cooling/data.json (1 hunks)
  • fixtures/anna_elga_2_schedule_off/all_data.json (0 hunks)
  • fixtures/anna_elga_2_schedule_off/data.json (1 hunks)
  • fixtures/anna_elga_no_cooling/all_data.json (0 hunks)
  • fixtures/anna_elga_no_cooling/data.json (1 hunks)
  • fixtures/anna_heatpump_cooling/all_data.json (0 hunks)
  • fixtures/anna_heatpump_cooling/data.json (1 hunks)
  • fixtures/anna_heatpump_cooling_fake_firmware/all_data.json (0 hunks)
  • fixtures/anna_heatpump_cooling_fake_firmware/data.json (1 hunks)
  • fixtures/anna_heatpump_heating/all_data.json (0 hunks)
  • fixtures/anna_heatpump_heating/data.json (1 hunks)
  • fixtures/anna_loria_cooling_active/all_data.json (0 hunks)
  • fixtures/anna_loria_cooling_active/data.json (1 hunks)
  • fixtures/anna_loria_driessens/all_data.json (0 hunks)
  • fixtures/anna_loria_driessens/data.json (1 hunks)
  • fixtures/anna_loria_heating_idle/all_data.json (0 hunks)
  • fixtures/anna_loria_heating_idle/data.json (1 hunks)
  • fixtures/anna_v4/all_data.json (0 hunks)
  • fixtures/anna_v4/data.json (1 hunks)
  • fixtures/anna_v4_dhw/all_data.json (0 hunks)
  • fixtures/anna_v4_dhw/data.json (1 hunks)
  • fixtures/anna_v4_no_tag/all_data.json (0 hunks)
  • fixtures/anna_v4_no_tag/data.json (1 hunks)
  • fixtures/anna_without_boiler_fw441/all_data.json (0 hunks)
  • fixtures/anna_without_boiler_fw441/data.json (1 hunks)
  • fixtures/legacy_anna/all_data.json (0 hunks)
  • fixtures/legacy_anna/data.json (1 hunks)
  • fixtures/legacy_anna_2/all_data.json (0 hunks)
  • fixtures/legacy_anna_2/data.json (1 hunks)
  • fixtures/m_adam_cooling/all_data.json (0 hunks)
  • fixtures/m_adam_cooling/data.json (1 hunks)
  • fixtures/m_adam_heating/all_data.json (0 hunks)
  • fixtures/m_adam_heating/data.json (1 hunks)
  • fixtures/m_adam_jip/all_data.json (0 hunks)
  • fixtures/m_adam_jip/data.json (1 hunks)
  • fixtures/m_adam_multiple_devices_per_zone/all_data.json (0 hunks)
  • fixtures/m_adam_multiple_devices_per_zone/data.json (1 hunks)
  • fixtures/m_anna_heatpump_cooling/all_data.json (0 hunks)
  • fixtures/m_anna_heatpump_cooling/data.json (1 hunks)
  • fixtures/m_anna_heatpump_idle/all_data.json (0 hunks)
  • fixtures/m_anna_heatpump_idle/data.json (1 hunks)
  • fixtures/p1v4_442_single/all_data.json (0 hunks)
  • fixtures/p1v4_442_single/data.json (1 hunks)
  • fixtures/p1v4_442_triple/all_data.json (0 hunks)
  • fixtures/p1v4_442_triple/data.json (1 hunks)
  • fixtures/smile_p1_v2/all_data.json (0 hunks)
  • fixtures/smile_p1_v2/data.json (1 hunks)
  • fixtures/smile_p1_v2_2/all_data.json (0 hunks)
  • fixtures/smile_p1_v2_2/data.json (1 hunks)
  • fixtures/stretch_v23/all_data.json (0 hunks)
  • fixtures/stretch_v23/data.json (1 hunks)
  • fixtures/stretch_v27_no_domain/all_data.json (0 hunks)
  • fixtures/stretch_v27_no_domain/data.json (1 hunks)
  • fixtures/stretch_v31/all_data.json (0 hunks)
  • fixtures/stretch_v31/data.json (1 hunks)
  • plugwise/__init__.py (11 hunks)
  • plugwise/common.py (2 hunks)
  • plugwise/constants.py (2 hunks)
  • plugwise/data.py (5 hunks)
  • plugwise/helper.py (12 hunks)
  • plugwise/legacy/data.py (2 hunks)
  • plugwise/legacy/helper.py (5 hunks)
⛔ Files not processed due to max files limit (12)
  • plugwise/legacy/smile.py
  • plugwise/smile.py
  • plugwise/smilecomm.py
  • plugwise/util.py
  • pyproject.toml
  • scripts/manual_fixtures.py
  • tests/test_adam.py
  • tests/test_anna.py
  • tests/test_generic.py
  • tests/test_init.py
  • tests/test_legacy_anna.py
  • tests/test_p1.py
💤 Files with no reviewable changes (37)
  • fixtures/stretch_v23/all_data.json
  • fixtures/adam_plus_anna/all_data.json
  • fixtures/p1v4_442_single/all_data.json
  • fixtures/m_adam_heating/all_data.json
  • fixtures/adam_zone_per_device/all_data.json
  • fixtures/anna_loria_driessens/all_data.json
  • fixtures/adam_onoff_cooling_fake_firmware/all_data.json
  • fixtures/adam_jip/all_data.json
  • fixtures/m_adam_cooling/all_data.json
  • fixtures/anna_loria_cooling_active/all_data.json
  • fixtures/anna_heatpump_heating/all_data.json
  • fixtures/anna_elga_2/all_data.json
  • fixtures/adam_plus_anna_new_regulation_off/all_data.json
  • fixtures/legacy_anna/all_data.json
  • fixtures/stretch_v27_no_domain/all_data.json
  • fixtures/m_anna_heatpump_idle/all_data.json
  • fixtures/adam_multiple_devices_per_zone/all_data.json
  • fixtures/adam_heatpump_cooling/all_data.json
  • fixtures/anna_elga_no_cooling/all_data.json
  • fixtures/adam_plus_anna_new/all_data.json
  • fixtures/m_adam_jip/all_data.json
  • fixtures/m_adam_multiple_devices_per_zone/all_data.json
  • fixtures/anna_elga_2_schedule_off/all_data.json
  • fixtures/stretch_v31/all_data.json
  • fixtures/legacy_anna_2/all_data.json
  • fixtures/anna_loria_heating_idle/all_data.json
  • fixtures/anna_v4_no_tag/all_data.json
  • fixtures/anna_heatpump_cooling/all_data.json
  • fixtures/smile_p1_v2/all_data.json
  • fixtures/anna_elga_2_cooling/all_data.json
  • fixtures/anna_v4/all_data.json
  • fixtures/anna_v4_dhw/all_data.json
  • fixtures/anna_without_boiler_fw441/all_data.json
  • fixtures/p1v4_442_triple/all_data.json
  • fixtures/anna_heatpump_cooling_fake_firmware/all_data.json
  • fixtures/smile_p1_v2_2/all_data.json
  • fixtures/m_anna_heatpump_cooling/all_data.json
👮 Files not reviewed due to content moderation or server errors (5)
  • fixtures/anna_v4_no_tag/data.json
  • fixtures/anna_elga_no_cooling/data.json
  • fixtures/anna_elga_2_schedule_off/data.json
  • fixtures/m_anna_heatpump_idle/data.json
  • fixtures/m_anna_heatpump_cooling/data.json
🧰 Additional context used
📓 Learnings (1)
fixtures/m_adam_heating/data.json (1)
Learnt from: bouwew
PR: plugwise/python-plugwise#630
File: tests/data/adam/adam_g_o.json:0-0
Timestamp: 2024-11-12T13:49:49.714Z
Learning: The minimal information for the `heater_central` device is due to a known bug still present in the code.
🔇 Additional comments (80)
fixtures/adam_onoff_cooling_fake_firmware/data.json (4)

1-112: LGTM! Well-structured device configuration data.

The JSON structure is clean, consistent, and follows best practices with proper use of UUIDs as unique identifiers and a clear hierarchy of device configurations.


2-38: Verify cooling and heating states consistency.

The central heater configuration shows both cooling_enabled and cooling_state as true, while heating_state is false, which is the expected behavior for a cooling operation. However, please verify that:

  1. The modulation_level of 0.0 is expected during cooling operation
  2. The water_temperature (24.5°C) and return_temperature (24.9°C) values are reasonable for the cooling mode

80-111: Verify climate control state consistency.

The climate unit shows:

  • control_state: "idle"
  • climate_mode: "auto"
  • active_preset: "away"
  • setpoint: 21.5°C

Please verify if this combination of states is valid:

  1. Should the control_state be "idle" when cooling is active in the system?
  2. Is the "away" preset compatible with maintaining a 21.5°C setpoint?

39-67: Verify firmware version and regulation modes.

The gateway configuration shows firmware version "3.2.8". Please verify:

  1. Is this the latest available firmware version for the AME Smile 2.0 board?
  2. Do all regulation modes listed (especially "bleeding_cold" and "bleeding_hot") match the current firmware's capabilities?
✅ Verification successful

Test fixture configuration is valid for its purpose

This is a test fixture specifically designed to test cooling functionality, as indicated by the directory name "adam_onoff_cooling_fake_firmware". While firmware version 3.2.8 is not the latest version, it is a valid version used in other test fixtures. The unique regulation modes, including "cooling", are intentionally configured for testing purposes.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other firmware versions in the fixtures
echo "Searching for firmware versions in fixtures..."
rg -g '*.json' '"firmware":\s*"[0-9.]*"' ./fixtures

Length of output: 2600


Script:

#!/bin/bash
# Search for regulation modes in fixtures
echo "Searching for regulation modes..."
rg -g '*.json' '"regulation_modes":\s*\[.*\]' ./fixtures

Length of output: 713

plugwise/legacy/helper.py (4)

38-40: Use of specialized utilities for power and data counting is a solid approach.
These imports from plugwise.util (collect_power_values and count_data_items) promote modularity and cleaner code. Ensure that any exceptional cases (e.g., malformed inputs causing errors in these utilities) are handled, either here or in the calling functions.


75-75: Consistency in version naming.
Renaming self.smile_fw_version to self.smile_version makes the naming more uniform. Verify that all references to the old property name have been updated to prevent attribute errors.


312-312: Recommend confirming the return structure of collect_power_values.
Using the external function collect_power_values directly allows for better modularity. Ensure that all calling sites correctly handle any edge cases or errors that might arise from this utility, especially if incomplete data is provided.


345-345: Confirm the logic for item counting.
count_data_items updates the entity count in a single step, reducing potential duplication. Double-check that subsequent code doesn't inadvertently rely on the old counting mechanism, particularly in dependent methods like _get_entity_data.

plugwise/__init__.py (16)

20-21: Expanded imports for new data structures.
Incorporating GwEntityData and SmileProps centralizes entity and property handling. Confirm that these imports are used consistently across relevant modules.


34-34: Explicit import for SmileComm.
Bringing SmileComm into __init__.py clarifies dependencies and code organization. No issues identified.


55-60: Constructor alignment with super class.
Passing host, password, port, username, and websession directly to super().__init__ clarifies the flow and reduces duplication. Ensure that defaults (e.g., timeouts) remain correctly configured inside SmileComm.


72-72: Introducing a dedicated _smile_props.
Storing relevant Smile properties in _smile_props aligns with the new design and simplifies property access. Double-check that all read/write operations are consistent throughout the codebase.


86-92: Property cooling_present with a safe fallback.
This property gracefully returns False if "cooling_present" is missing from _smile_props. This is a good defensive approach.


93-97: Gateway ID property lacks a fallback.
gateway_id directly indexes _smile_props["gateway_id"] without a fallback in case the key is absent. Confirm that gateway_id always gets set; otherwise, this might raise a KeyError.


98-104: Heater ID property with partial fallback.
Here, you handle the missing "heater_id" case by returning NONE. This approach is consistent with fallback logic.


105-109: Item count is exposed elegantly.
The item_count property references _smile_props["item_count"]. Ensure _smile_props["item_count"] is consistently set and updated alongside changes in gw_entities.


110-117: reboot property for non-legacy devices.
Returning not self.smile_legacy clarifies that modern devices can reboot. This is correct usage, as legacy might not support reboots.


163-165: Combined usage of _request and _smile_props.
When instantiating SmileAPI or SmileLegacyAPI, passing _request and _smile_props signals a clear separation of networking logic (in _request) vs. data storage (in _smile_props). Maintain consistent usage patterns to avoid confusion.


181-182: Re-confirm references to _smile_props within SmileLegacyAPI.
Sharing data through _smile_props ensures a single source of truth. Double-check that unexpected mutation in SmileLegacyAPI won't break the Smile class state.


210-210: Extracting firmware version from gateway info.
Reading 'firmware_version' from gateway.find("firmware_version").text is appropriate. Validate that the XML field is always present or handle the situation if it's absent or invalid.


218-218: Check for model == "Unknown" or self.smile_version is None.
This explicit check prevents the code from continuing when insufficient device info is provided. Good defensive logic.


298-298: Legacy detection with updated approach.
Parsing firmware from system.find("./gateway/firmware").text in legacy code ensures consistency with modern logic. Confirm that older legacy devices indeed place firmware version under <gateway><firmware> in SYSTEM data.


309-309: Fallback to STATUS for some legacy setups.
This approach ensures coverage of devices providing version details under <system><version>. Continue to monitor for devices that might require additional fallback.


324-326: Switching from PlugwiseData to dict[str, GwEntityData].
Returning a standard dictionary clarifies data structures and reduces maintenance overhead. Ensure all consumer code adjusts accordingly to accept the new return type.

plugwise/legacy/data.py (4)

10-10: Importing new types for cohesive data management.
Bringing in GwEntityData and SmileProps supports the unified approach for gateway and property data introduced across the refactoring.


20-20: Introducing _smile_props.
Defining self._smile_props: SmileProps inside SmileLegacyData aligns with the new design scheme, centralizing gateway-related properties.


26-26: Invocation of _update_gw_entities.
_update_gw_entities() ensures the gateway entities are refreshed before populating _smile_props. Confirm no concurrency issues when gw_entities updates simultaneously in other parts of the code.


29-33: Populating _smile_props with gateway attributes.
Storing gateway_id, item_count, smile_name, and optionally heater_id centralizes metadata. This is consistent with the rest of the refactor. Validate that all references to these keys (e.g., in __init__.py or any consumer code) are aligned with these new storage patterns.

plugwise/data.py (3)

30-31: LGTM: New attributes align with PR objectives.

The addition of _smile_props and _zones attributes supports the consolidation of data handling into a single dictionary structure.


123-131: Review the notification handling changes.

The changes integrate notifications into the gateway data structure and modify the counter increment. Consider the following:

  1. The condition for notification handling has been improved to include power-type smiles
  2. Counter increment changed from +1 to +2 to account for both binary sensor and notifications dictionary

44-50: Verify data migration from gw_data to _smile_props.

The gateway data has been moved to _smile_props. Let's verify that all consumers of this data have been updated accordingly.

✅ Verification successful

Migration from gw_data to _smile_props is complete and correct

The codebase shows a clean migration with all necessary properties moved to _smile_props and no remaining references to gw_data in the actual code. Both main and legacy implementations have been properly updated.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining references to gw_data
rg "gw_data" -A 3

Length of output: 377


Script:

#!/bin/bash
# Search for any variations of gw_data
rg -i "gw.*data" -A 3

# Search for _smile_props usage
rg "_smile_props" -A 3

Length of output: 30551

fixtures/smile_p1_v2_2/data.json (1)

1-34: Verify test data completeness.

The fixture provides comprehensive test data for both smart meter and gateway entities. However, consider adding test cases for:

  1. Notifications (currently missing in gateway data)
  2. Binary sensors (currently missing in gateway data)
fixtures/smile_p1_v2/data.json (1)

1-34: LGTM: Test data maintains consistency.

The fixture follows the same structure as smile_p1_v2_2/data.json, providing good test coverage for different device IDs.

fixtures/p1v4_442_single/data.json (1)

3-15: LGTM: Comprehensive gateway test data.

The gateway entity includes notifications and binary sensors, providing good test coverage for the consolidated data structure.

fixtures/anna_without_boiler_fw441/data.json (1)

26-31: Verify temperature bounds and resolution.

Please ensure that the thermostat bounds (4.0-30.0°C) and resolution (0.1°C) align with the actual device specifications.

fixtures/legacy_anna_2/data.json (2)

56-59: Validate zero sensor values.

Multiple sensor values are set to 0.0, which might indicate missing data or sensor errors. Consider adding test cases for non-zero values to ensure proper handling of actual readings.


3-3: Resolve preset inconsistency.

The active_preset is null while preset_modes contains valid options and select_schedule is set to "off". This might indicate an invalid state.

Also applies to: 13-14

fixtures/p1v4_442_triple/data.json (1)

14-18: Resolve contradiction between warning and sensor data.

The gateway shows a warning that "The Smile P1 is not connected to a smart meter", but the device provides detailed electricity and gas readings. This appears to be inconsistent.

Also applies to: 27-53

fixtures/anna_v4_dhw/data.json (1)

67-72: Review boiler temperature bounds for safety.

The maximum boiler temperature bounds (0-100°C) seem unusually wide. Consider reviewing these values:

  • Lower bound of 0°C might be too low and could cause freezing issues
  • Upper bound of 100°C might exceed safety limits for residential boilers
✅ Verification successful

Temperature bounds are appropriate for this device type

The maximum boiler temperature bounds (0-100°C) are consistent with other modern heating systems in the codebase, particularly for Anna v4 and heat pump configurations. The setpoint of 70°C is well within safe operating ranges for residential boilers.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other boiler temperature bounds across the codebase
rg '"maximum_boiler_temperature".*"lower_bound".*"upper_bound"' --type json

Length of output: 77


Script:

#!/bin/bash
# Find all JSON files that might contain boiler settings
echo "=== Searching for JSON files with boiler settings ==="
rg -i "boiler.*temperature" --type json -A 5 -B 5

echo -e "\n=== Looking for documentation about boiler settings ==="
fd -e md -e txt | xargs rg -i "boiler.*temperature|temperature.*limit"

echo -e "\n=== Checking for similar configuration files ==="
fd -e json | xargs rg -i "temperature.*bound|bound.*temperature"

Length of output: 68908

fixtures/anna_v4/data.json (1)

1-88: Verify test coverage for all device configurations.

The test fixtures cover various device configurations:

  • Basic heating setup (anna_v4)
  • Cooling capabilities (anna_elga_2)
  • Different vendors (Bosch/Techneco)

However, consider adding test fixtures for:

  • Edge cases in temperature ranges
  • All possible device states
  • Error conditions

Run this script to analyze test coverage:

fixtures/anna_elga_2/data.json (2)

17-24: Verify temperature ranges for different heating systems.

The configuration includes multiple temperature settings with different ranges:

  • DHW: 30.0-60.0°C (0.01°C resolution)
  • Boiler: 0.0-100.0°C (1.0°C resolution)
  • Room: 4.0-30.0°C (0.1°C resolution)

Consider documenting:

  • Why these specific ranges were chosen
  • How they relate to real-world heating systems
  • Impact of different resolutions

Also applies to: 61-66


44-51: Validate cooling threshold logic.

The cooling configuration includes activation temperature (24.0°C) and deactivation threshold (2.0°C), but their relationship should be validated to prevent issues like:

  • Short cycling of the cooling system
  • Conflicts between heating and cooling modes

Run this script to verify cooling thresholds across fixtures:

✅ Verification successful

Cooling thresholds are valid and consistent with other fixtures

The cooling activation temperature (24.0°C) and deactivation threshold (2.0°C) are within the normal range observed across similar configurations, which use activation temperatures between 21-26°C and thresholds between 2-6°C.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify cooling threshold logic

echo "Analyzing cooling thresholds..."
for file in fixtures/anna*/data.json; do
  echo "File: $file"
  jq -r '.[] | select(.sensors.cooling_activation_outdoor_temperature != null) | {
    name: .name,
    activation: .sensors.cooling_activation_outdoor_temperature,
    deactivation_threshold: .sensors.cooling_deactivation_threshold,
    climate_mode: .climate_mode
  }' "$file"
done

Length of output: 7075

fixtures/anna_elga_2_cooling/data.json (1)

50-57: Verify temperature sensor values are within operational bounds.

The temperature readings show:

  • Room temperature: 24.9°C
  • Setpoint high: 23.0°C

The current room temperature (24.9°C) is above the cooling setpoint (23.0°C) while cooling is active, which correctly represents a cooling scenario.

fixtures/anna_heatpump_cooling/data.json (1)

23-30: Verify modulation level during cooling operation.

The device shows:

  • Cooling state: active
  • Modulation level: 40%
  • Other heating states: inactive

This represents a valid combination of states during cooling operation.

Also applies to: 45-45

fixtures/anna_heatpump_cooling_fake_firmware/data.json (1)

7-7: Verify firmware version format consistency.

The firmware version "4.10.10" follows a different pattern compared to other fixtures. Ensure this represents a valid version number for testing firmware-specific behavior.

✅ Verification successful

Firmware version format is consistent with testing purposes

The version "4.10.10" follows the same semantic versioning pattern (major.minor.patch) as other fixtures, and its presence in a fixture explicitly named "fake_firmware" suggests it's intentionally different for testing purposes.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check firmware version patterns across fixtures
echo "Analyzing firmware version patterns:"
rg -g "*.json" '"firmware": "4' fixtures/

Length of output: 1295

fixtures/anna_loria_heating_idle/data.json (1)

57-62: Verify idle state consistency.

The idle state shows consistent values:

  • All heating/cooling states: false
  • Modulation level: 0.0
  • No active temperature control

This represents a valid combination for an idle system.

Also applies to: 85-85

fixtures/stretch_v31/data.json (2)

88-100: Verify member references in switching group.

The switching group references two members:

  • 059e4d03c7a34d278add5c7a4a781d19 (Wasmachine)
  • cfe95cf3de1948c0b8955125bf754614 (Droger)

Both members exist in the file and support switching operations.


101-116: Verify member references in report group.

The report group references five members, all of which exist in the file:

  • 059e4d03... (Wasmachine)
  • 587131... (Boiler)
  • aac7b7... (Vaatwasser)
  • cfe95c... (Droger)
  • e1c884... (Koelkast)
fixtures/m_adam_cooling/data.json (2)

74-89: Gateway configuration is correctly set for cooling mode.

The gateway configuration shows:

  • Cooling mode is available in regulation_modes
  • select_regulation_mode is set to "cooling"

Also applies to: 90-92


145-148: Climate mode settings are consistent with cooling operation.

The climate devices are correctly configured:

  • climate_mode: "cool"
  • control_state: "cooling"

Also applies to: 229-231

fixtures/m_adam_heating/data.json (2)

88-90: Gateway configuration is correctly set for heating mode.

The gateway configuration shows:

  • Heating mode is available in regulation_modes
  • select_regulation_mode is set to "heating"

145-147: Climate mode settings are consistent with heating operation.

The climate devices are correctly configured:

  • climate_mode: "heat"/"auto"
  • control_state: "preheating"/"idle"

Also applies to: 178-180

fixtures/adam_plus_anna_new_regulation_off/data.json (2)

19-22: Verify safe temperature settings in regulation off mode.

The intended boiler temperature is set to 0.0°C which could potentially lead to freezing. Consider implementing a minimum safe temperature even when regulation is off.


229-230: Climate mode settings are consistent with regulation off.

The climate devices are correctly configured:

  • climate_mode: "off"
  • control_state: "idle"

Also applies to: 262-263

fixtures/adam_plus_anna_new/data.json (2)

172-174: Gateway configuration is correctly set for normal operation.

The gateway configuration shows:

  • Heating mode is available in regulation_modes
  • select_regulation_mode is set to "heating"

229-230: Climate mode settings are consistent with normal operation.

The climate devices are correctly configured:

  • climate_mode: "auto"
  • control_state: "heating"/"preheating"

Also applies to: 262-263

fixtures/stretch_v27_no_domain/data.json (2)

71-89: Inconsistent device class naming.

The device class "zz_misc" appears to be a temporary or placeholder name. Consider using a more descriptive and standardized name.


1-271: LGTM! Well-structured JSON data.

The JSON structure is well-organized with consistent attribute naming and proper nesting of objects.

plugwise/common.py (1)

30-42: LGTM! Well-structured helper function.

The function handles both legacy and new cases clearly with proper error handling.

fixtures/m_adam_jip/data.json (1)

1-370: Verify temperature setpoints and readings.

Several temperature-related values require verification:

  1. Low setpoints: Multiple zones have setpoints of 9.0°C and 13.0°C, which seem unusually low for comfort.
  2. High readings: Several temperature sensors show readings of 30.0°C, which might indicate overheating.

Please verify if these values are intentional or if they need adjustment.

fixtures/stretch_v23/data.json (2)

293-297: Verify high power consumption for TV device.

The TV device shows unusually high power consumption:

  • Consumed: 33.3 units
  • Interval: 4.93 units

Please verify if these values are expected for this device type.


1-354: LGTM! Well-structured device data.

The JSON structure effectively organizes various device types with consistent attribute naming and proper power consumption tracking.

plugwise/constants.py (2)

Line range hint 396-406: Well-structured TypedDict for gateway properties!

The SmileProps class is well-designed with appropriate field types and total=False for optional fields, making it flexible for partial data representation.


553-553: Good addition of notifications field!

The notifications field with type dict[str, dict[str, str]] is well-structured for handling nested notification data, aligning with the JSON structure in the fixtures.

fixtures/m_adam_multiple_devices_per_zone/data.json (1)

Line range hint 1-593: Well-structured device configuration data!

The JSON structure maintains consistency across different device types while properly representing their unique characteristics. The mock MAC addresses are appropriately used for testing purposes.

fixtures/adam_zone_per_device/data.json (1)

1-590: Consistent with established data structure!

The fixture maintains the same well-structured format as other fixtures, properly representing device configurations with different locations.

plugwise/helper.py (1)

47-47: LGTM! Good modularization.

The functions collect_power_values and count_data_items have been properly extracted into utility functions, improving code modularity.

Also applies to: 49-49

fixtures/anna_heatpump_heating/data.json (3)

33-38: Verify the DHW temperature setpoint is within safe operating range.

The maximum DHW temperature setpoint of 53.0°C with bounds [35.0, 60.0] might be too low for legionella prevention in some regions. Many safety guidelines recommend periodic heating to 60°C or higher.

Consider:

  1. Adding a periodic high-temperature cycle for legionella prevention
  2. Validating against local safety regulations

39-44: Validate maximum boiler temperature configuration.

The maximum boiler temperature has a lower bound of 0.0°C which could allow for unsafe conditions:

  1. Risk of freezing damage to the system
  2. Potential condensation issues

Consider setting a minimum safe temperature (typically 20-25°C) to prevent system damage.


82-87: Review temperature offset configuration.

The temperature offset configuration looks good with reasonable bounds (-2.0 to 2.0) and appropriate resolution (0.1).

fixtures/anna_loria_driessens/data.json (1)

78-83: Review maximum boiler temperature configuration.

The maximum boiler temperature configuration has tight constraints:

  • Upper and setpoint both at 45.0°C
  • Lower bound at 25.0°C
    This is a safe configuration that prevents both freezing and overheating.
fixtures/adam_plus_anna/data.json (2)

87-91: Review notification structure and error handling.

The notification structure provides good error tracking:

"notifications": {
  "6fb89e35caeb4b1cb275184895202d84": {
    "error": "There is no OpenTherm communication with the boiler."
  }
}

The UUID-based notification system allows for proper tracking and management of multiple issues.


62-67: Validate electricity consumption metrics.

The sensor data includes both interval and cumulative measurements:

"sensors": {
  "electricity_consumed": 10.3,
  "electricity_consumed_interval": 0.0,
  "electricity_produced": 0.0,
  "electricity_produced_interval": 0.0
}

This provides good granularity for power monitoring and billing purposes.

fixtures/adam_jip/data.json (1)

Line range hint 473-479: Monitor low battery levels.

Several devices show battery levels below 70%:

  • "battery": 62 (current device)
  • Other devices show similar low levels

Consider implementing a proactive battery replacement strategy when levels drop below 75% to prevent device failures.

fixtures/adam_multiple_devices_per_zone/data.json (2)

25-31: Standardize schedule naming convention.

Similar to previous files, schedule names lack consistency:

"available_schedules": [
  "CV Roan",
  "Bios Schema met Film Avond",
  "GF7  Woonkamer",
  "Badkamer Schema",
  "CV Jessie",
  "off"
]

Refer to previous comment about standardizing schedule names.


366-370: Review valve position and temperature differential.

The configuration shows:

  • Valve position: 100 (fully open)
  • Temperature difference: 3.5°C
  • Current temp: 26.0°C vs Setpoint: 21.5°C

This suggests potential inefficiency in the heating system. Consider implementing PID control for better temperature regulation.

fixtures/adam_heatpump_cooling/data.json (3)

285-313: Gateway configuration looks good!

The gateway device configuration is well-structured with all necessary attributes including:

  • Firmware version (3.2.8)
  • Hardware details (AME Smile 2.0 board)
  • Supported modes for both heating and cooling
  • Properly obfuscated MAC addresses

212-233: Consistent thermostat configuration across zones.

The thermostat configurations show good consistency in their structure:

  • Uniform resolution (0.01) across all thermostats
  • Consistent temperature offset ranges (-2.0 to 2.0)
  • Well-defined setpoints for each zone

Also applies to: 652-672


153-171: Smart plug configurations are consistent and well-structured.

All smart plug devices follow a consistent pattern with:

  • Power monitoring capabilities
  • Relay state tracking
  • Firmware version 2020-05-13T02:00:00+02:00

Also applies to: 575-594

CHANGELOG.md (1)

Line range hint 1-807: Changelog follows best practices.

The changelog is well-maintained with:

  • Clear version numbering
  • Descriptive entries for each change
  • Proper linking to issues and PRs

@sonarqubecloud
Copy link

@bouwew bouwew marked this pull request as ready for review January 30, 2025 07:09
@bouwew bouwew requested a review from a team as a code owner January 30, 2025 07:09
@bouwew bouwew merged commit 1800bc7 into main Jan 30, 2025
19 checks passed
@bouwew bouwew deleted the test_smile_props branch January 30, 2025 07:10
@coderabbitai coderabbitai bot mentioned this pull request Nov 8, 2025
@coderabbitai coderabbitai bot mentioned this pull request Dec 20, 2025
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.

3 participants