-
Notifications
You must be signed in to change notification settings - Fork 8
Collect all weather data from the Gateway #676
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThe pull request introduces a comprehensive update to the Plugwise integration, focusing on enhancing weather data representation across multiple JSON fixtures and test files. The primary change involves replacing the Changes
Possibly related PRs
Poem
Tip CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command 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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (14)
plugwise/helper.py (1)
569-569: Refactor note: Consolidate or rename
Calling _get_gateway_measurements() here is intuitive, but consider naming it more specifically (e.g., _get_gateway_weather_measurements()) if the function is intended solely for capturing weather info. This can assist maintainability and clarity of usage.tests/data/anna/anna_elga_2_cooling_UPDATED_DATA.json (1)
88-93: Consider varying test data valuesSeveral weather attributes have identical values across different test files:
- humidity: 42
- wind_bearing: 120.0
- wind_speed: 3.6
Consider varying these values to ensure the system handles different scenarios correctly.
tests/data/anna/anna_elga_2_cooling.json (1)
86-94: LGTM! Consider adding documentation for weather data unitsThe weather data structure is well-organized with appropriate data types and reasonable value ranges. However, it would be helpful to document the units of measurement (e.g., temperature in °C, wind speed in m/s, wind bearing in degrees, solar irradiance in W/m²) to ensure consistent interpretation.
tests/data/anna/anna_elga_2.json (1)
86-94: Consider varying weather test dataWhile the weather data structure is consistent, several values (humidity, wind_bearing, wind_speed, weather_description, solar_irradiance) are identical to anna_elga_2_cooling.json. Consider varying these values to test different weather scenarios and ensure the system handles a broader range of conditions.
fixtures/anna_v4/all_data.json (1)
48-55: Consider extracting common weather data to a shared fixtureThe weather data structure and values are identical between
anna_v4/all_data.jsonandanna_v4_dhw/all_data.json. Consider extracting this into a shared fixture to maintain consistency and reduce duplication.#!/bin/bash # Find similar weather data patterns across fixtures rg --json -l '"weather":\s*{.*"humidity"' fixtures/tests/data/anna/anna_loria_heating_idle.json (1)
50-57: Consider diversifying weather test dataWhile the weather data structure is consistent, consider adding test cases with different weather conditions to verify system behavior across various scenarios (e.g., extreme temperatures, different wind conditions).
Example variations to consider:
- High temperature + high humidity for cooling tests
- Low temperature + high wind for heating tests
- Various weather descriptions affecting solar gain
Would you like me to help create additional test fixtures with diverse weather scenarios?
fixtures/anna_elga_no_cooling/all_data.json (1)
16-23: Consider implementing a Weather Data InterfaceThe restructuring of weather data from 'sensors' to a dedicated 'weather' object is a good architectural decision. To further improve this:
- Create a formal interface or schema for the weather data structure
- Implement data validation for all weather attributes
- Document the expected ranges and units for each attribute
- Define an enum for possible weather descriptions
This will ensure consistency and reliability across the entire integration.
Would you like help creating a schema definition for the weather data structure?
fixtures/anna_elga_2/all_data.json (1)
87-94: LGTM! Consistent weather data implementation across fixturesThe weather data structure is consistently implemented across all test fixtures with:
- Same attribute names and data types
- Reasonable value ranges
- Correct item count adjustments
Consider adding schema validation to ensure this structure remains consistent as more weather attributes are added in the future.
Also applies to: 101-101
fixtures/m_adam_cooling/all_data.json (1)
93-100: LGTM! Consider documenting units in comments.The weather data structure is comprehensive and well-organized. However, it would be helpful to document the units for each measurement.
Add comments to clarify units:
"weather": { - "humidity": 90, - "outdoor_temperature": 29.65, - "solar_irradiance": 3.0, - "weather_description": "rain", - "wind_bearing": 291.0, - "wind_speed": 6.26 + "humidity": 90, # Percentage (%) + "outdoor_temperature": 29.65, # Celsius (°C) + "solar_irradiance": 3.0, # Watts per square meter (W/m²) + "weather_description": "rain", + "wind_bearing": 291.0, # Degrees (°) + "wind_speed": 6.26 # Meters per second (m/s) }plugwise/util.py (1)
206-213: LGTM! Consider using dict.get() for more concise code.The changes correctly handle the new weather data structure and include proper existence checks. However, the code could be more concise using Python's dict.get() method.
Consider this more concise implementation:
- if "binary_sensors" in data and not data["binary_sensors"]: - data.pop("binary_sensors") - if "sensors" in data and not data["sensors"]: - data.pop("sensors") - if "switches" in data and not data["switches"]: - data.pop("switches") - if "weather" in data and not data["weather"]: - data.pop("weather") + for key in ("binary_sensors", "sensors", "switches", "weather"): + if not data.get(key): + data.pop(key, None)tests/data/adam/adam_plus_anna_new_regulation_off.json (1)
176-183: LGTM! Consider adding documentation for the weather attributes.The new weather object structure is well-organized and includes comprehensive weather data. The data types and values are appropriate for each attribute.
Consider adding documentation (in a README or schema file) to describe:
- Units for each measurement (e.g., wind speed in m/s or km/h)
- Expected value ranges
- Update frequency
fixtures/adam_plus_anna_new_regulation_off/all_data.json (1)
176-183: Consider adding JSON schema validation.To ensure data consistency and provide better developer experience, consider adding a JSON schema that defines:
- Required weather attributes
- Data types and constraints
- Units and value ranges
This would help catch potential issues early in the development process.fixtures/m_adam_jip/all_data.json (1)
Line range hint
176-183: Well-structured approach to weather data representation.The replacement of the
sensorsfield with a comprehensiveweatherobject across all fixtures demonstrates good architectural decisions:
- Consistent schema across all gateway devices
- Logical grouping of weather-related attributes
- Appropriate data types for each measurement
- Clear separation of concerns between weather data and other sensor data
Consider documenting the weather data schema and its attributes in the project's documentation to help maintainers and contributors understand the expected format and units of measurement.
Also applies to: 229-236, 232-239
plugwise/constants.py (1)
146-152: Consider adding proper units of measurement for weather-related measurements.Some weather measurements are using
NONEas their unit when they should have specific units:
solar_irradiancetypically uses W/m² (watts per square meter)wind_vectorshould be split intowind_bearing(degrees) andwind_speed(m/s)- "solar_irradiance": UOM(NONE), - "weather_description": UOM(NONE), - "wind_vector": UOM(NONE), + "solar_irradiance": UOM("W/m²"), + "weather_description": UOM(NONE), + "wind_bearing": UOM(DEGREE), + "wind_speed": UOM("m/s"),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (59)
fixtures/adam_heatpump_cooling/all_data.json(2 hunks)fixtures/adam_jip/all_data.json(2 hunks)fixtures/adam_multiple_devices_per_zone/all_data.json(1 hunks)fixtures/adam_onoff_cooling_fake_firmware/all_data.json(2 hunks)fixtures/adam_plus_anna/all_data.json(2 hunks)fixtures/adam_plus_anna_new/all_data.json(2 hunks)fixtures/adam_plus_anna_new_regulation_off/all_data.json(2 hunks)fixtures/adam_zone_per_device/all_data.json(1 hunks)fixtures/anna_elga_2/all_data.json(1 hunks)fixtures/anna_elga_2_cooling/all_data.json(1 hunks)fixtures/anna_elga_2_schedule_off/all_data.json(1 hunks)fixtures/anna_elga_no_cooling/all_data.json(2 hunks)fixtures/anna_heatpump_cooling/all_data.json(2 hunks)fixtures/anna_heatpump_cooling_fake_firmware/all_data.json(2 hunks)fixtures/anna_heatpump_heating/all_data.json(2 hunks)fixtures/anna_loria_cooling_active/all_data.json(2 hunks)fixtures/anna_loria_driessens/all_data.json(2 hunks)fixtures/anna_loria_heating_idle/all_data.json(2 hunks)fixtures/anna_v4/all_data.json(2 hunks)fixtures/anna_v4_dhw/all_data.json(2 hunks)fixtures/anna_v4_no_tag/all_data.json(2 hunks)fixtures/anna_without_boiler_fw441/all_data.json(2 hunks)fixtures/m_adam_cooling/all_data.json(1 hunks)fixtures/m_adam_heating/all_data.json(1 hunks)fixtures/m_adam_jip/all_data.json(2 hunks)fixtures/m_adam_multiple_devices_per_zone/all_data.json(1 hunks)fixtures/m_anna_heatpump_cooling/all_data.json(2 hunks)fixtures/m_anna_heatpump_idle/all_data.json(2 hunks)plugwise/common.py(1 hunks)plugwise/constants.py(4 hunks)plugwise/helper.py(5 hunks)plugwise/util.py(1 hunks)scripts/manual_fixtures.py(3 hunks)tests/data/adam/adam_heatpump_cooling.json(1 hunks)tests/data/adam/adam_jip.json(1 hunks)tests/data/adam/adam_multiple_devices_per_zone.json(1 hunks)tests/data/adam/adam_onoff_cooling_fake_firmware.json(1 hunks)tests/data/adam/adam_plus_anna.json(1 hunks)tests/data/adam/adam_plus_anna_new.json(1 hunks)tests/data/adam/adam_plus_anna_new_regulation_off.json(1 hunks)tests/data/adam/adam_zone_per_device.json(1 hunks)tests/data/anna/anna_elga_2.json(1 hunks)tests/data/anna/anna_elga_2_cooling.json(1 hunks)tests/data/anna/anna_elga_2_cooling_UPDATED_DATA.json(1 hunks)tests/data/anna/anna_elga_2_schedule_off.json(1 hunks)tests/data/anna/anna_elga_no_cooling.json(1 hunks)tests/data/anna/anna_heatpump_cooling.json(1 hunks)tests/data/anna/anna_heatpump_cooling_fake_firmware.json(1 hunks)tests/data/anna/anna_heatpump_heating.json(1 hunks)tests/data/anna/anna_loria_cooling_active.json(1 hunks)tests/data/anna/anna_loria_driessens.json(1 hunks)tests/data/anna/anna_loria_heating_idle.json(1 hunks)tests/data/anna/anna_v4.json(1 hunks)tests/data/anna/anna_v4_UPDATED_DATA.json(1 hunks)tests/data/anna/anna_v4_dhw.json(1 hunks)tests/data/anna/anna_v4_no_tag.json(1 hunks)tests/data/anna/anna_without_boiler_fw441.json(1 hunks)tests/test_adam.py(7 hunks)tests/test_anna.py(15 hunks)
🔇 Additional comments (68)
plugwise/helper.py (5)
19-19: Import reference recognized
The addition of ATTR_UNIT_OF_MEASUREMENT helps tie measurement values to specific units, improving clarity and reducing hard-coded references.
47-47: New WeatherType import
Adding WeatherType is a logical step for storing multiple weather-related values in a typed, robust manner.
531-536: Initialization of the 'weather' dictionary
The introduction of the new "weather" field in GwEntityData is a clear and maintainable enhancement for storing exterior conditions separately from other sensor data.
773-799: New weather data gathering logic
The function clearly populates weather data for the gateway. Ensure that any gateway not providing valid or complete weather data still gracefully handles partial or missing attributes to avoid unexpected key errors.
800-821: Enhanced flexibility for measurement retrieval
The updated _object_value method now handles multiple measurement types (humidity, solar, etc.). Great approach for centralizing logic. Verify that potentially missing or null values (e.g., partial logs) are handled gracefully.
tests/data/anna/anna_v4_UPDATED_DATA.json (1)
50-56: Weather field introduction
Replacing the previous sensors block with weather ensures a richer set of weather attributes (humidity, solar, wind). Confirm that consumers of the old sensors structure have been updated to handle the new field.
tests/data/anna/anna_without_boiler_fw441.json (1)
47-55: Comprehensive weather data
Adding a dedicated weather block for humidity, temperature, solar, and wind attributes provides clarity and future extensibility. Double-check that references to the old sensors block are removed or redirected.
fixtures/anna_without_boiler_fw441/all_data.json (2)
47-55: Introduction of 'weather' field
Good move to store environmental data in one location. Ensure all references to the removed sensors field are updated accordingly.
71-71: Item count updated from 39 to 44
The new item_count matches the expanded set of weather attributes. Confirm consistency by verifying counts in upstream or downstream references.
tests/data/anna/anna_v4_dhw.json (1)
48-55: LGTM! Weather data structure looks good.
The new weather object contains all essential weather attributes with appropriate data types and reasonable values.
Please verify that the units for these weather measurements are documented in the integration's documentation:
- wind_speed (m/s?)
- solar_irradiance (W/m²?)
- wind_bearing (degrees clockwise from north?)
tests/data/anna/anna_v4.json (1)
48-55: Weather data structure is consistent with other test fixtures.
tests/data/anna/anna_v4_no_tag.json (2)
48-55: Weather data structure is consistent with other test fixtures.
48-55: Verify test coverage for new weather attributes.
The weather data structure is consistently implemented across test fixtures. Please ensure there are corresponding test cases that validate the parsing and handling of these new weather attributes.
tests/data/anna/anna_elga_no_cooling.json (2)
16-23: LGTM! Weather data structure looks good.
The weather object contains all necessary attributes with reasonable values.
18-18: Verify outdoor temperature consistency
The outdoor temperature is reported in two places:
- Gateway weather: 20.2°C
- Heater sensors: 3.0°C
This significant difference might indicate:
- Different data sources
- Different update frequencies
- Test data inconsistency
Also applies to: 45-45
✅ Verification successful
Let's check the actual temperature values in these files to understand if this is a test data inconsistency or an expected variation.
Let's search for any heater sensor temperature values in the file to verify the claim about the 3.0°C reading mentioned in the review comment.
Temperature difference is expected - different measurement points
The temperature difference in the file is not an inconsistency but rather represents two different measurements:
outdoor_temperature(20.2°C): Current gateway weather readingoutdoor_air_temperature(3.0°C): Heater sensor reading
This pattern is consistent with test data representing different temperature sensors in the system. The variation could represent:
- Historical vs current readings
- Different sensor locations
- Different measurement timestamps
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other outdoor temperature occurrences in test files
rg -l "outdoor.*temperature" tests/data/
Length of output: 1165
Script:
#!/bin/bash
# Search for outdoor temperature values in test files
rg -A 1 '"outdoor_temperature"' tests/data/anna/anna_elga_no_cooling.json
# Check a few other files to compare temperature values
echo "=== Other test files ==="
rg -A 1 '"outdoor_temperature"' tests/data/anna/anna_v4.json tests/data/anna/anna_loria_heating_idle.json tests/data/anna/anna_heatpump_heating.json
Length of output: 812
Script:
#!/bin/bash
# Search for temperature-related values in the specific file
rg "temperature|temp" tests/data/anna/anna_elga_no_cooling.json
Length of output: 473
tests/data/anna/anna_elga_2_schedule_off.json (1)
87-94: LGTM! Consistent weather data.
The weather object structure matches the expected format and shows good consistency with sensor values.
tests/data/anna/anna_elga_2_cooling_UPDATED_DATA.json (1)
87-94: LGTM! Weather data structure is consistent.
The weather object follows the established pattern and shows good consistency with sensor values.
tests/data/anna/anna_heatpump_cooling.json (1)
15-23: LGTM! Good variety in test data
This file demonstrates good test coverage with varied weather conditions:
- Non-zero solar irradiance (207.2)
- Different weather description ("overcast")
- Varied wind conditions (0.0° bearing, 2.1 speed)
- Different humidity (35%) and temperature (22.0°C)
tests/data/anna/anna_heatpump_cooling_fake_firmware.json (1)
16-23: Verify weather data units and ranges
The weather data structure looks good, but please ensure these units are correct:
- Temperature in °C
- Solar irradiance in W/m²
- Wind speed in m/s
- Wind bearing in degrees (0-360°)
- Humidity in percentage (0-100%)
✅ Verification successful
The previous search was too narrow. Let's broaden our search to:
- Find weather-related data structures and their context
- Look for schema/validation files that might define units
- Search source code for weather-related constants or configurations
Based on the search results from examining the test data files, I can verify the weather data structure and its units:
Weather data structure and units are consistent across all test files
The search results show consistent patterns across multiple test files that confirm:
- Temperature values are in °C (range observed: -1.25 to 31.0)
- Solar irradiance values are in W/m² (range observed: 0.0 to 653.6)
- Wind speed values are in m/s (range observed: 1.79 to 8.2)
- Wind bearing values are in degrees (range observed: 0.0 to 291.0)
- Humidity values are in percentage (range observed: 35 to 91)
All values across test files are within reasonable ranges and use consistent units.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for weather data validation or unit tests
rg -l "weather.*test|test.*weather" tests/
Length of output: 44
Script:
#!/bin/bash
# Search for weather-related files and patterns more broadly
rg -i "weather" --type json -A 5 .
Length of output: 37725
Script:
#!/bin/bash
# Look for any schema or validation files
fd -e json -e schema.json -e yaml -e yml . | grep -i "schema\|valid\|weather"
Length of output: 79
Script:
#!/bin/bash
# Search for weather-related constants or configurations
rg -i "weather" --type python --type typescript --type javascript .
Length of output: 98
fixtures/anna_v4_dhw/all_data.json (1)
48-55: Verify item_count increment
The item_count increase from 58 to 63 (+5) aligns with the addition of 5 new weather fields (humidity, solar_irradiance, weather_description, wind_bearing, wind_speed). The outdoor_temperature was moved from sensors to weather, so it doesn't affect the count.
Also applies to: 98-98
fixtures/anna_v4_no_tag/all_data.json (2)
48-55: LGTM: Weather data structure is well-defined and complete
The new weather object includes all essential weather metrics with appropriate data types:
- Temperature in Celsius
- Humidity as percentage
- Solar irradiance in W/m²
- Wind speed in m/s
- Wind bearing in degrees
- Weather description as string
98-98: Verify item_count increase
The item_count increase from 58 to 63 (+5) aligns with the addition of new weather attributes (humidity, solar_irradiance, weather_description, wind_bearing, wind_speed).
tests/data/anna/anna_loria_cooling_active.json (1)
50-57: LGTM: Weather data structure is consistent
The weather object maintains consistency with other fixtures and includes appropriate test values for a cooling scenario (e.g., outdoor_temperature: 15.5°C with overcast conditions).
tests/data/anna/anna_heatpump_heating.json (1)
16-23: Consider adding data validation constraints for weather attributes
The weather data structure needs validation constraints to ensure data integrity:
humidity: Should be 0-100%wind_bearing: Should be 0-360 degreesweather_description: Should be a defined enum of possible values
Consider defining a schema or data model that enforces these constraints. This will help prevent invalid data from being processed.
Let's check if there are any validation constraints defined elsewhere:
fixtures/anna_elga_no_cooling/all_data.json (1)
103-103: Verify item count increase matches new weather attributes
The item count increase from 63 to 68 (+5) appears to correspond with the newly added weather attributes: humidity, solar_irradiance, weather_description, wind_bearing, and wind_speed.
Let's verify this change is consistent across other files:
✅ Verification successful
Let me verify the item count changes by checking the actual weather attributes in the relevant files.
Item count increase correctly reflects added weather attributes
The verification confirms that the item count increase from 63 to 68 (+5) in anna_elga_no_cooling exactly matches the five newly added weather attributes that are present in the file:
- humidity
- solar_irradiance
- weather_description
- wind_bearing
- wind_speed
The outdoor_temperature attribute was already present in both files, so it doesn't contribute to the count increase.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for item_count changes in other files
rg -B 1 -A 1 '"item_count":\s*\d+'
Length of output: 8602
Script:
#!/bin/bash
# Search for weather-related attributes in anna_v4 and anna_elga_no_cooling files
rg -A 5 '"outdoor_temperature"|"humidity"|"solar_irradiance"|"weather_description"|"wind_bearing"|"wind_speed"' fixtures/anna_v4/all_data.json fixtures/anna_elga_no_cooling/all_data.json
Length of output: 1617
fixtures/anna_elga_2_schedule_off/all_data.json (2)
87-94: LGTM! Weather data structure is well-designed and consistent
The new weather object provides a comprehensive set of weather attributes with appropriate data types:
- Temperature as float (13.0°)
- Humidity as integer percentage (42%)
- Wind measurements as floats (bearing: 120.0°, speed: 3.6)
- Text description ("cloudy")
- Solar irradiance as float (0.0)
The outdoor temperature (13.0°) correctly matches the OpenTherm sensor reading.
101-101: LGTM! Item count increase is accurate
The increase from 63 to 68 items correctly reflects the addition of 5 new weather attributes (humidity, solar_irradiance, weather_description, wind_bearing, wind_speed).
fixtures/anna_elga_2_cooling/all_data.json (1)
89-89: Verify temperature discrepancy between sensors
The outdoor temperature reported by the Gateway (31.0°) differs from the OpenTherm sensor reading (30.0°). While this small difference might be expected due to different measurement times or sources, it would be good to confirm this is intended behavior.
Consider documenting which temperature source should be considered authoritative for automation purposes.
fixtures/anna_heatpump_cooling/all_data.json (2)
16-23: LGTM! Weather data structure and values look valid.
The weather object contains all expected fields with appropriate data types and reasonable value ranges:
- Humidity: 35% (0-100 range)
- Temperature: 22.0°C (typical outdoor range)
- Solar irradiance: 207.2 W/m² (typical daylight range)
- Wind speed: 2.1 m/s (light breeze)
- Wind bearing: 0.0° (valid 0-360 range)
102-102: Verify item count increase matches new weather attributes
The gateway's item_count increase from 64 to 69 (+5) correctly reflects the addition of new weather attributes (humidity, solar_irradiance, weather_description, wind_bearing, wind_speed).
✅ Verification successful
I'm requesting these scripts to:
- Verify the previous item_count value to confirm the increase from 64 to 69
- Confirm the presence of the mentioned weather attributes in the file
This will help us validate if the review comment's assertion about the +5 increase matching the new weather attributes is correct.
Weather attributes match item count increase
The verification confirms that all 5 new weather attributes (humidity, solar_irradiance, weather_description, wind_bearing, wind_speed) are present in the file, which matches the reported item_count increase from 64 to 69 (+5). The attributes are properly integrated into the weather object structure.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Verify consistent item_count changes across all gateway fixtures
rg -l '"item_count"' | while read -r file; do
echo "=== $file ==="
rg '"item_count".*(\d+)' "$file"
done
Length of output: 8636
Script:
#!/bin/bash
# Let's check the git history for the specific file to see the previous item_count value
git log -p fixtures/anna_heatpump_cooling/all_data.json | grep -A 1 -B 1 '"item_count":'
# Also let's check for weather-related attributes in this file
rg -A 1 -B 1 '"(humidity|solar_irradiance|weather_description|wind_bearing|wind_speed)"' fixtures/anna_heatpump_cooling/all_data.json
Length of output: 356
fixtures/anna_heatpump_cooling_fake_firmware/all_data.json (1)
16-23: LGTM! Weather data structure matches the non-fake firmware fixture.
The weather object maintains consistency with the previous fixture, which is appropriate for testing purposes.
tests/data/adam/adam_onoff_cooling_fake_firmware.json (1)
63-70: LGTM! Weather data structure and value correlations are valid.
The weather object:
- Maintains consistent structure across different gateway models
- Shows proper correlation between values:
- High humidity (88%) matches clouded weather description
- Moderate solar irradiance (208.2 W/m²) appropriate for cloudy conditions
- Light wind speed (1.79 m/s) at 228.0° bearing
- Preserves the outdoor temperature value (13.4°C) from the previous sensor implementation
fixtures/anna_loria_cooling_active/all_data.json (2)
50-57: LGTM! Weather data structure looks good.
The new weather object provides a clear and comprehensive representation of weather conditions with appropriate units and value ranges.
106-106: Verify item_count increase.
The increase in item_count from 66 to 71 correctly reflects the addition of 5 new weather attributes.
fixtures/anna_loria_heating_idle/all_data.json (1)
50-57: LGTM! Consistent weather data implementation.
The weather data structure and item_count changes are consistent with the cooling_active fixture, which is correct as these are structural changes independent of the heating/cooling state.
Also applies to: 106-106
fixtures/m_anna_heatpump_idle/all_data.json (2)
16-23: LGTM! Weather data values are internally consistent.
The weather attributes show good internal consistency - the "clear" weather description aligns well with the high solar irradiance (653.6 W/m²) and temperature (28.2°C).
107-107: LGTM! Correct item_count adjustment.
The item_count increase from 67 to 72 correctly reflects the addition of 5 new weather attributes.
fixtures/m_anna_heatpump_cooling/all_data.json (2)
107-107: Verify gateway item count increment
The item_count increase from 67 to 72 (+5) matches the number of new weather attributes added (humidity, solar_irradiance, weather_description, wind_bearing, wind_speed).
16-23: Verify weather data structure and ranges
The weather data structure looks good with all required attributes. Values are within expected ranges:
- Temperature (28.2°C) aligns with cooling scenario
- Humidity (42%) is within 0-100% range
- Wind bearing (50.0°) is within 0-360° range
- Solar irradiance (653.6) is consistent with "clear" weather
✅ Verification successful
Weather data structure and values are consistent with test fixtures
The weather data structure in fixtures/m_anna_heatpump_cooling/all_data.json follows the same schema found across all fixture files that contain weather data. The values are within reasonable ranges and consistent with other cooling scenario fixtures:
- All required attributes (humidity, outdoor_temperature, solar_irradiance, weather_description, wind_bearing, wind_speed) are present
- Values align with other cooling scenarios in the test fixtures (e.g., anna_heatpump_cooling_fake_firmware: 22°C, m_adam_cooling: 29.65°C)
- The structure matches the standardized format used across the test suite
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Verify consistent weather data structure across all fixture files
fd -e json -x jq -r '.devices[] | select(.weather != null) | .weather | keys' {} \; | sort | uniq -c
Length of output: 3677
Script:
#!/bin/bash
# Check the weather data structure in the specific file
jq -r '.devices[] | select(.weather != null) | .weather' fixtures/m_anna_heatpump_cooling/all_data.json
# Find all files with weather data to compare structure
fd -e json -x sh -c 'echo "=== {} ==="; jq -r ".devices[] | select(.weather != null) | .weather" {}' \;
Length of output: 12812
fixtures/anna_heatpump_heating/all_data.json (1)
18-18: Verify temperature consistency between gateway and OpenTherm
There's a significant discrepancy between temperatures reported by:
- Gateway weather: 20.2°C
- OpenTherm sensor: 3.0°C (outdoor_air_temperature)
Please verify which temperature reading should be considered authoritative.
Also applies to: 47-47
fixtures/anna_loria_driessens/all_data.json (1)
16-23: Weather data values are internally consistent
The weather data shows good internal consistency:
- Lower solar irradiance (97.6) aligns with "clouded" weather
- Higher humidity (88%) is typical for cloudy conditions
- Gateway temperature (6.81°C) closely matches OpenTherm sensor (7.5°C)
fixtures/adam_onoff_cooling_fake_firmware/all_data.json (2)
63-70: LGTM: Weather data structure is well-organized
The new weather object provides comprehensive environmental data with appropriate data types:
- Temperature in Celsius
- Humidity as percentage
- Solar irradiance in W/m²
- Wind speed in m/s
- Wind bearing in degrees
- Weather description as string
122-122: Verify item count increase
The item count increase from 64 to 69 (+5) correctly reflects the addition of new weather attributes (humidity, solar_irradiance, weather_description, wind_bearing, wind_speed).
tests/data/adam/adam_plus_anna.json (1)
90-97: LGTM: Test data matches fixture format
The weather object in the test data correctly mirrors the structure from the fixtures, maintaining consistency across the codebase.
fixtures/adam_plus_anna/all_data.json (2)
90-97: LGTM: Weather data structure maintains consistency
The weather object implementation maintains consistency with other files in the codebase, using the same structure and data types.
136-136: Verify item count increase
The item count increase from 80 to 85 (+5) correctly reflects the addition of new weather attributes.
fixtures/m_adam_heating/all_data.json (1)
92-99: LGTM! Weather data structure is consistent.
The weather data structure maintains consistency with other fixtures and correctly handles negative temperatures.
tests/data/adam/adam_plus_anna_new.json (1)
176-183: LGTM! Weather data structure is consistent across test fixtures.
The weather object maintains the same structure and data types across different test scenarios, which is good for testing reliability.
fixtures/adam_plus_anna_new_regulation_off/all_data.json (2)
176-183: LGTM! Weather data structure is consistent with other fixtures.
The weather object implementation maintains consistency across all test fixtures, which is crucial for reliable testing.
296-296: Verify the updated item count.
The increase in item_count from 177 to 182 appears to correspond with the addition of new weather attributes.
fixtures/adam_plus_anna_new/all_data.json (1)
176-183: LGTM! Weather data structure is well-organized.
The new weather object provides a comprehensive and logically structured representation of weather data, with appropriate data types for each attribute.
tests/data/adam/adam_jip.json (1)
229-236: LGTM! Consistent weather data implementation.
The weather data structure maintains consistency with other fixtures while containing appropriate test values.
fixtures/m_adam_jip/all_data.json (2)
380-380: LGTM! Item count update is consistent.
The item count increase to 249 aligns with the addition of weather attributes, maintaining consistency with the schema changes.
232-239: Verify the duplicated weather data values.
The weather data values are identical to those in adam_jip.json. While this might be intentional for testing purposes, it's worth verifying.
✅ Verification successful
The script results show that the weather data in m_adam_jip/all_data.json is indeed identical to adam_jip.json, but this appears to be intentional. Looking at the broader context, we can see that files prefixed with m_ appear to be variants of their corresponding non-prefixed fixtures, likely for testing different scenarios. For example:
m_adam_coolingvsadam_heatpump_coolingm_adam_multiple_devices_per_zonevsadam_multiple_devices_per_zone
Weather data duplication is expected in test fixtures
The identical weather data between m_adam_jip/all_data.json and adam_jip.json is intentional, as these are related test fixtures. Files prefixed with m_ appear to be variants of their base fixtures, maintaining the same weather data where appropriate for testing consistency.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Compare weather data across test fixtures
# Extract and compare weather objects
echo "Comparing weather data in test fixtures:"
for file in fixtures/*adam*/all_data.json; do
echo "=== $file ==="
jq -c '.. | select(.weather?) | .weather' "$file"
done
Length of output: 4657
fixtures/adam_jip/all_data.json (1)
233-240: LGTM! Weather data structure is well-organized.
The new weather object contains all essential weather metrics with appropriate value ranges. The item_count increase (from 244 to 249) correctly reflects the addition of these weather attributes.
scripts/manual_fixtures.py (1)
142-142: LGTM! Temperature values are appropriate for each mode.
The outdoor temperature values are correctly set for different scenarios:
- Cooling mode: 29.65°C (appropriately warm)
- Heating mode: -1.25°C (appropriately cold)
- Anna cooling mode: 28.2°C (appropriately warm)
Also applies to: 223-223, 298-298
plugwise/common.py (1)
150-151: LGTM! Weather data counting implementation is consistent.
The implementation correctly follows the existing pattern for counting dictionary items, properly accounting for the weather dictionary itself by subtracting 1 from the total count.
tests/data/adam/adam_zone_per_device.json (1)
581-588: LGTM! Consider adding data validation for weather attributes.
The weather data structure looks good with comprehensive attributes. However, it would be beneficial to ensure the values are within expected ranges:
- humidity: 0-100%
- wind_bearing: 0-360 degrees
- wind_speed: non-negative
- solar_irradiance: non-negative
✅ Verification successful
All weather data values are within valid ranges
After analyzing the weather data across all test fixtures, I can confirm that:
- All humidity values are between 0-100% (ranging from 35% to 91%)
- All wind bearing values are between 0-360 degrees (ranging from 0.0° to 291.0°)
- All wind speed values are non-negative (ranging from 1.79 to 8.2)
- All solar irradiance values are non-negative (ranging from 0.0 to 653.6)
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify weather data ranges across all test fixtures
# Search for weather data in JSON files and validate ranges
rg -U --multiline '(?s)"weather":\s*{\s*"humidity":\s*(\d+).*?"wind_bearing":\s*(\d+\.?\d*).*?"wind_speed":\s*(\d+\.?\d*).*?"solar_irradiance":\s*(\d+\.?\d*)' -g '*.json' | \
while IFS= read -r line; do
echo "Validating weather data ranges in: $line"
# Extract and validate values using awk
echo "$line" | gawk '
match($0, /"humidity":\s*(\d+)/, h) &&
match($0, /"wind_bearing":\s*(\d+\.?\d*)/, wb) &&
match($0, /"wind_speed":\s*(\d+\.?\d*)/, ws) &&
match($0, /"solar_irradiance":\s*(\d+\.?\d*)/, si) {
humidity = h[1]
wind_bearing = wb[1]
wind_speed = ws[1]
solar_irradiance = si[1]
if (humidity < 0 || humidity > 100)
print "Invalid humidity:", humidity
if (wind_bearing < 0 || wind_bearing > 360)
print "Invalid wind_bearing:", wind_bearing
if (wind_speed < 0)
print "Invalid wind_speed:", wind_speed
if (solar_irradiance < 0)
print "Invalid solar_irradiance:", solar_irradiance
}'
done
Length of output: 433
Script:
#!/bin/bash
# Description: Verify weather data ranges across all test files using a simpler pattern
rg -U --multiline '"weather":\s*{[^}]+}' -g '*.json' | while IFS= read -r line; do
echo "$line" | gawk '
match($0, /"humidity":\s*([0-9.]+)/, h) { humidity = h[1] }
match($0, /"wind_bearing":\s*([0-9.]+)/, wb) { wind_bearing = wb[1] }
match($0, /"wind_speed":\s*([0-9.]+)/, ws) { wind_speed = ws[1] }
match($0, /"solar_irradiance":\s*([0-9.]+)/, si) { solar_irradiance = si[1] }
END {
if (humidity != "" && (humidity < 0 || humidity > 100))
print "Invalid humidity:", humidity
if (wind_bearing != "" && (wind_bearing < 0 || wind_bearing > 360))
print "Invalid wind_bearing:", wind_bearing
if (wind_speed != "" && wind_speed < 0)
print "Invalid wind_speed:", wind_speed
if (solar_irradiance != "" && solar_irradiance < 0)
print "Invalid solar_irradiance:", solar_irradiance
if (humidity == "" && wind_bearing == "" && wind_speed == "" && solar_irradiance == "")
print "No weather data found"
else
print "Found values - humidity:", humidity, "wind_bearing:", wind_bearing, "wind_speed:", wind_speed, "solar_irradiance:", solar_irradiance
}
'
done
Length of output: 193
Script:
#!/bin/bash
# Description: Search for weather data in JSON files using simple grep
rg '"weather":' -g '*.json' -A 10 | while IFS= read -r line; do
echo "$line" | grep -E '"(humidity|wind_bearing|wind_speed|solar_irradiance)":'
done
Length of output: 80636
tests/data/adam/adam_multiple_devices_per_zone.json (1)
584-591: LGTM! Weather data structure is consistent.
The weather data structure matches the format in other test fixtures, maintaining consistency across the test suite.
tests/test_adam.py (1)
39-39: LGTM! Entity count updates reflect new weather attributes.
The consistent increase in entity_items count (by 5) across all test methods correctly reflects the addition of new weather attributes (humidity, solar_irradiance, weather_description, wind_bearing, wind_speed).
Also applies to: 210-210, 290-290, 328-328, 351-351, 376-376, 422-422
✅ Verification successful
Let me analyze the test files further to verify the entity count changes.
Entity count increases are consistent with the addition of 5 weather attributes
The git diff confirms that all entity_items counts in test_adam.py have been increased by exactly 5 across all test cases:
- 177 → 182 (+5)
- 369 → 374 (+5)
- 497 → 502 (+5)
- 64 → 69 (+5)
- 80 → 85 (+5)
- 244 → 249 (+5)
This consistent increment of 5 entities aligns perfectly with the addition of the five new weather attributes (humidity, solar_irradiance, weather_description, wind_bearing, wind_speed).
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify consistent entity count increase across test files
# Search for entity_items assertions and their values
rg 'assert self\.entity_items == \d+' tests/ | \
while IFS= read -r line; do
echo "Found entity count in: $line"
done
Length of output: 6165
Script:
#!/bin/bash
# Get the git diff for test_adam.py to see the actual changes in entity counts
git diff origin/main -- tests/test_adam.py | grep -A 1 -B 1 "entity_items =="
Length of output: 1450
fixtures/m_adam_multiple_devices_per_zone/all_data.json (2)
575-582: LGTM! Weather data structure looks well-designed.
The new weather object provides a comprehensive set of environmental data with appropriate data types and reasonable value ranges.
590-590: LGTM! Item count update is consistent.
The increase from 369 to 374 correctly reflects the addition of 5 new weather-related fields.
fixtures/adam_zone_per_device/all_data.json (1)
581-588: Changes match the pattern from other files.
The weather object structure and item count update follow the same well-designed pattern as in fixtures/m_adam_multiple_devices_per_zone/all_data.json.
Also applies to: 596-596
fixtures/adam_multiple_devices_per_zone/all_data.json (1)
584-591: Changes match the pattern from other files.
The weather object structure and item count update follow the same well-designed pattern as in the previous files.
Also applies to: 599-599
plugwise/constants.py (1)
524-533: LGTM! Well-structured weather data class.
The WeatherData class is well-defined with appropriate types for all weather-related fields.
tests/data/adam/adam_heatpump_cooling.json (1)
309-316: LGTM! Well-structured weather data.
The weather data structure in the test fixture is consistent with the WeatherData TypedDict and contains realistic values for all fields.
fixtures/adam_heatpump_cooling/all_data.json (2)
817-817: LGTM! Item count correctly updated.
The item count increase from 497 to 502 accurately reflects the addition of the new weather attributes.
309-316: LGTM! Consider adding value range validation.
The weather data structure is well-organized and comprehensive, including all essential weather metrics. The values appear reasonable:
- Temperature: 13.4°C (typical outdoor temperature)
- Humidity: 88% (valid percentage)
- Wind speed: 1.79 m/s (reasonable wind speed)
- Wind bearing: 228.0° (valid degree range)
- Solar irradiance: 208.2 W/m² (typical daylight value)
✅ Verification successful
Weather data structure is consistent across test fixtures
The weather data structure is consistently implemented across all test fixtures that include weather information, with values within reasonable ranges:
- Humidity: 35-91%
- Temperature: -1.25°C to 31°C
- Solar irradiance: 0-653.6 W/m²
- Wind bearing: 0-291°
- Wind speed: 1.79-8.2 m/s
- Weather descriptions: clear, cloudy, clouded, overcast, rain
The data in the reviewed file aligns with these ranges and follows the same structure used throughout the test fixtures.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Verify the weather data structure is consistent across all test fixtures
fd -e json -x jq -r '.devices | .[] | select(.model == "Gateway") | .weather // empty' {}
Length of output: 8552
| "weather": { | ||
| "humidity": 88, | ||
| "outdoor_temperature": 6.81, | ||
| "solar_irradiance": 97.6, | ||
| "weather_description": "clouded", | ||
| "wind_bearing": 230.0, | ||
| "wind_speed": 4.12 | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Standardize decimal precision across weather measurements
There are inconsistencies in decimal precision between different test fixtures:
outdoor_temperature: 6.81 vs 20.2wind_speed: 4.12 vs 4.1
Standardize the decimal precision across all weather measurements to ensure consistent data representation. Consider using a fixed precision of 1 decimal place for all float values.
"weather": {
"humidity": 88,
- "outdoor_temperature": 6.81,
+ "outdoor_temperature": 6.8,
"solar_irradiance": 97.6,
"weather_description": "clouded",
"wind_bearing": 230.0,
- "wind_speed": 4.12
+ "wind_speed": 4.1
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "weather": { | |
| "humidity": 88, | |
| "outdoor_temperature": 6.81, | |
| "solar_irradiance": 97.6, | |
| "weather_description": "clouded", | |
| "wind_bearing": 230.0, | |
| "wind_speed": 4.12 | |
| } | |
| "weather": { | |
| "humidity": 88, | |
| "outdoor_temperature": 6.8, | |
| "solar_irradiance": 97.6, | |
| "weather_description": "clouded", | |
| "wind_bearing": 230.0, | |
| "wind_speed": 4.1 | |
| } |
| "gateway_id": "da224107914542988a88561b4452b0f6", | ||
| "heater_id": "056ee145a816487eaa69243c3280f8bf", | ||
| "item_count": 177, | ||
| "item_count": 182, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Item count in JSON file needs correction
The declared item_count of 182 in the JSON file appears to be incorrect. The actual count of scalar properties in the JSON structure is 208, and this count remains unchanged from the previous version. This suggests that either:
- The
item_countfield is not meant to represent the total number of scalar properties - Or there's an error in the count that needs to be corrected
🔗 Analysis chain
Verify the updated item count.
The item count has been increased from 177 to 182, which aligns with the addition of new weather attributes.
Let me try a different approach to count the items correctly.
Let's try one more approach to understand the structure and count the items correctly.
Let's verify the exact item count by checking all the properties in the JSON structure.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that the item count matches the actual number of items
# Count all unique keys in the JSON structure
jq '[.. | objects | keys[]] | unique | length' fixtures/adam_plus_anna_new/all_data.json
Length of output: 93
Script:
#!/bin/bash
# Let's check the actual structure of the JSON file first
jq 'keys' fixtures/adam_plus_anna_new/all_data.json
# Then count the total number of items in the main data array
jq '.data | length' fixtures/adam_plus_anna_new/all_data.json
Length of output: 146
Script:
#!/bin/bash
# Let's examine the actual content structure
jq '.devices | length' fixtures/adam_plus_anna_new/all_data.json
# Also check the gateway structure
jq '.gateway | keys' fixtures/adam_plus_anna_new/all_data.json
# Count all non-null values in the entire JSON structure
jq '[.. | select(. != null)] | length' fixtures/adam_plus_anna_new/all_data.json
Length of output: 339
Script:
#!/bin/bash
# Count all properties in the JSON structure
jq '[paths(scalars)] | length' fixtures/adam_plus_anna_new/all_data.json
# Also let's see the previous version's count for comparison
git show HEAD^:fixtures/adam_plus_anna_new/all_data.json | jq '[paths(scalars)] | length'
Length of output: 176
| WeatherType = Literal[ | ||
| "humidity", | ||
| "outdoor_temperature", | ||
| "solar_irradiance", | ||
| "weather_description", | ||
| "wind_bearing", | ||
| "wind_speed", | ||
| ] | ||
| WEATHER: Final[tuple[str, ...]] = get_args(WeatherType) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Align weather types with device measurements.
There's an inconsistency between WeatherType and DEVICE_MEASUREMENTS:
WeatherTypehas separatewind_bearingandwind_speedDEVICE_MEASUREMENTShas combinedwind_vector
Please align these definitions to use consistent field names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That might make sense, unless one is from the Smile and the other the HA standardised form?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@CoMPaTech, indeed, if “wind_vector” is coming directly from the Smile in a combined format while “wind_bearing” and “wind_speed” follow HA’s standard naming, keeping them separate could be fine. Otherwise, if both are describing the same data from the same source, consolidating them into a consistent naming (either “wind_vector” or separate “wind_bearing”/“wind_speed”) would avoid confusion. Let me know if you prefer aligning these fields for a more uniform format, or if they should remain distinct.
|
I think we came across this earlier, but decided (back then) not to incorporate it as it was also just generic data from the internet (or maybe from a Core member, I don't really remember) - then again, it is provided data and as such could at least mimic what, for instance Anna, displays. |
CoMPaTech
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While reviewing, what do we do with outdoor_temperature if one has both? I remember we decided to opt for the physical sensor instead of the perceived one, just to be clear that should be (also) obvious to end users.
We solved that a long time ago by renaming it to |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #676 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 20 20
Lines 3469 3503 +34
=========================================
+ Hits 3469 3503 +34 ☔ View full report in Codecov by Sentry. |
14d2873 to
9d2bb4d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
plugwise/helper.py (1)
801-819: LGTM with minor type hint suggestionThe implementation is clean and handles different measurement types appropriately. Consider adding a more specific return type hint:
- ) -> float | int | str | None: + ) -> float | int | str | None: # float for temp/irradiance, int for humidity, str for others
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
plugwise/helper.py(5 hunks)
🔇 Additional comments (2)
plugwise/helper.py (2)
531-536: LGTM: Clean data structure initialization
The addition of the "weather" dictionary follows the existing pattern and maintains consistency with the codebase structure.
773-819: Verify weather data integration with thermostat devices
The implementation aligns with the PR objectives. Let's verify the integration:
| def _get_gateway_measurements(self, entity_id: str, data: GwEntityData) -> None: | ||
| """Adam & Anna: the Gateway weather-data is present under the Home location. | ||
| Available under the Home location. | ||
| """ | ||
| if self._is_thermostat and entity_id == self.gateway_id: | ||
| outdoor_temperature = self._object_value( | ||
| self._home_location, "outdoor_temperature" | ||
| ) | ||
| if outdoor_temperature is not None: | ||
| data.update({"sensors": {"outdoor_temperature": outdoor_temperature}}) | ||
| self._count += 1 | ||
| if not (self._is_thermostat and entity_id == self.gateway_id): | ||
| return | ||
|
|
||
| def _object_value(self, obj_id: str, measurement: str) -> float | int | None: | ||
| measurements = DEVICE_MEASUREMENTS | ||
| for measurement, attrs in measurements.items(): | ||
| value = self._location_value(self._home_location, measurement, attrs) | ||
| if value is not None: | ||
| if measurement == "wind_vector": | ||
| value_list: list[str] = str(value).split(",") | ||
| data["weather"]["wind_speed"] = format_measure( | ||
| value_list[0].strip("("), | ||
| getattr(attrs, ATTR_UNIT_OF_MEASUREMENT), | ||
| ) | ||
| data["weather"]["wind_bearing"] = format_measure( | ||
| value_list[1].strip(")"), | ||
| getattr(attrs, ATTR_UNIT_OF_MEASUREMENT), | ||
| ) | ||
| self._count += 2 | ||
| else: | ||
| key = cast(WeatherType, measurement) | ||
| data["weather"][key] = value | ||
| self._count += 1 | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider enhancing wind vector parsing robustness
While the implementation is functional, the wind vector parsing could be more robust:
- No validation of the value_list length before accessing indices
- No error handling for malformed vector strings
Consider this safer implementation:
- value_list: list[str] = str(value).split(",")
- data["weather"]["wind_speed"] = format_measure(
- value_list[0].strip("("),
- getattr(attrs, ATTR_UNIT_OF_MEASUREMENT),
- )
- data["weather"]["wind_bearing"] = format_measure(
- value_list[1].strip(")"),
- getattr(attrs, ATTR_UNIT_OF_MEASUREMENT),
- )
+ try:
+ value_list: list[str] = str(value).split(",")
+ if len(value_list) >= 2:
+ data["weather"]["wind_speed"] = format_measure(
+ value_list[0].strip("("),
+ getattr(attrs, ATTR_UNIT_OF_MEASUREMENT),
+ )
+ data["weather"]["wind_bearing"] = format_measure(
+ value_list[1].strip(")"),
+ getattr(attrs, ATTR_UNIT_OF_MEASUREMENT),
+ )
+ self._count += 2
+ except (ValueError, IndexError) as err:
+ LOGGER.warning("Failed to parse wind vector: %s", err)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def _get_gateway_measurements(self, entity_id: str, data: GwEntityData) -> None: | |
| """Adam & Anna: the Gateway weather-data is present under the Home location. | |
| Available under the Home location. | |
| """ | |
| if self._is_thermostat and entity_id == self.gateway_id: | |
| outdoor_temperature = self._object_value( | |
| self._home_location, "outdoor_temperature" | |
| ) | |
| if outdoor_temperature is not None: | |
| data.update({"sensors": {"outdoor_temperature": outdoor_temperature}}) | |
| self._count += 1 | |
| if not (self._is_thermostat and entity_id == self.gateway_id): | |
| return | |
| def _object_value(self, obj_id: str, measurement: str) -> float | int | None: | |
| measurements = DEVICE_MEASUREMENTS | |
| for measurement, attrs in measurements.items(): | |
| value = self._location_value(self._home_location, measurement, attrs) | |
| if value is not None: | |
| if measurement == "wind_vector": | |
| value_list: list[str] = str(value).split(",") | |
| data["weather"]["wind_speed"] = format_measure( | |
| value_list[0].strip("("), | |
| getattr(attrs, ATTR_UNIT_OF_MEASUREMENT), | |
| ) | |
| data["weather"]["wind_bearing"] = format_measure( | |
| value_list[1].strip(")"), | |
| getattr(attrs, ATTR_UNIT_OF_MEASUREMENT), | |
| ) | |
| self._count += 2 | |
| else: | |
| key = cast(WeatherType, measurement) | |
| data["weather"][key] = value | |
| self._count += 1 | |
| def _get_gateway_measurements(self, entity_id: str, data: GwEntityData) -> None: | |
| """Adam & Anna: the Gateway weather-data is present under the Home location. | |
| Available under the Home location. | |
| """ | |
| if not (self._is_thermostat and entity_id == self.gateway_id): | |
| return | |
| measurements = DEVICE_MEASUREMENTS | |
| for measurement, attrs in measurements.items(): | |
| value = self._location_value(self._home_location, measurement, attrs) | |
| if value is not None: | |
| if measurement == "wind_vector": | |
| try: | |
| value_list: list[str] = str(value).split(",") | |
| if len(value_list) >= 2: | |
| data["weather"]["wind_speed"] = format_measure( | |
| value_list[0].strip("("), | |
| getattr(attrs, ATTR_UNIT_OF_MEASUREMENT), | |
| ) | |
| data["weather"]["wind_bearing"] = format_measure( | |
| value_list[1].strip(")"), | |
| getattr(attrs, ATTR_UNIT_OF_MEASUREMENT), | |
| ) | |
| self._count += 2 | |
| except (ValueError, IndexError) as err: | |
| LOGGER.warning("Failed to parse wind vector: %s", err) | |
| else: | |
| key = cast(WeatherType, measurement) | |
| data["weather"][key] = value | |
| self._count += 1 |
9d2bb4d to
6488ec9
Compare
There was a problem hiding this 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/helper.py (1)
804-822: Consider adding error handling for value conversionsWhile the method is well-structured, it could benefit from error handling around the value conversions, particularly for the humidity and measurement formatting operations.
Consider this safer implementation:
def _loc_value( self, loc_id: str, measurement: str, attrs: DATA | UOM ) -> float | int | str | None: locator = f"./location[@id='{loc_id}']/logs/point_log[type='{measurement}']/period/measurement" if (found := self._domain_objects.find(locator)) is None: return None value: str = found.text try: match measurement: case "humidity": return int(float(value)) case "outdoor_temperature" | "solar_irradiance": return format_measure(value, getattr(attrs, ATTR_UNIT_OF_MEASUREMENT)) case _: return value + except (ValueError, TypeError) as err: + LOGGER.warning("Failed to convert measurement value: %s", err) + return None
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
plugwise/helper.py(5 hunks)
🔇 Additional comments (2)
plugwise/helper.py (2)
531-536: LGTM: Clean initialization of weather data structure
The addition of the "weather" dictionary to GwEntityData follows the established pattern for data organization.
773-803: LGTM: Well-structured gateway measurements collection
The method effectively collects weather data from the gateway, with clear separation of concerns and proper entity validation.
The wind vector parsing could be more robust, as noted in a previous review comment.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (11)
tests/data/anna/anna_v4_dhw.json (1)
48-48: Consider consolidating all weather-related data under theweatherobjectThe current implementation splits weather-related data between
sensors.solar_irradianceand the newweatherobject. For better organization and maintainability, consider movingsolar_irradianceinto theweatherobject alongside other weather metrics."sensors": { - "solar_irradiance": 449.4 }, "vendor": "Plugwise", "weather": { "humidity": 81, "outdoor_temperature": 7.44, + "solar_irradiance": 449.4, "weather_description": "clear", "wind_bearing": 240.0, "wind_speed": 3.6 }Also applies to: 50-57
tests/data/anna/anna_v4_no_tag.json (1)
51-57: Consider adding data source attribution for weather metricsBased on the PR objectives discussion about handling physical vs perceived weather data:
- Add a field to indicate the data source (e.g.,
source: "physical_sensor"orsource: "gateway")- Consider adding timestamp for each weather measurement
- If both physical and gateway data are available, document the precedence rules
Example structure:
"weather": { "outdoor_temperature": { "value": 7.44, "source": "physical_sensor", "timestamp": "2024-12-20T10:00:00Z" }, "humidity": { "value": 81, "source": "gateway", "timestamp": "2024-12-20T10:00:00Z" } }tests/data/anna/anna_heatpump_cooling_fake_firmware.json (2)
16-25: Document weather data structure and value rangesThe weather data structure is consistent with other files but shows different ranges:
solar_irradiance: 207.2 (vs 0.0 in other files)humidity: 35wind_speed: 2.1wind_bearing: 0.0weather_description: "overcast"Consider adding documentation or constants for:
- Expected value ranges for each weather attribute
- List of possible weather descriptions
- Units of measurement (e.g., wind speed in m/s or km/h)
This will help ensure consistent data representation across the system.
Line range hint
90-96: Consider documenting the weather data architectureThe introduction of comprehensive weather data alongside physical sensors introduces some architectural considerations:
Data Source Hierarchy:
- Physical sensors (outdoor_air_temperature)
- Gateway weather data
- Need to document the priority and usage scenarios
Data Consistency:
- Multiple temperature sources might show different values
- Need to handle data reconciliation
Data Structure:
- New weather object with multiple attributes
- Consistent structure across different device types
Consider creating an architectural document that covers:
- The relationship between physical sensors and weather data
- Data flow and update mechanisms
- Error handling for missing or inconsistent data
- Guidelines for consuming applications on which data source to use
Also applies to: 19-25, 87-96
tests/data/anna/anna_loria_heating_idle.json (1)
50-59: Test data maintains consistency across modesGood to see that the weather data remains consistent between heating_idle and cooling_active test files. This helps ensure that mode changes don't unexpectedly affect weather data representation.
Consider adding test cases to verify that:
- Weather data persists correctly during mode transitions
- Both temperature sources (weather and physical sensor) are handled properly in all modes
Would you like me to help create additional test cases for these scenarios?
fixtures/anna_elga_2_cooling/all_data.json (1)
Line range hint
19-25: Consider adding schema documentation for weather dataThe new weather data structure is consistently implemented across files. Consider:
- Documenting the relationship between
outdoor_temperature(perceived) andoutdoor_air_temperature(physical sensor)- Adding unit specifications for numeric values (e.g., temperature in °C, wind speed in m/s)
- Documenting possible values for
weather_descriptionAlso applies to: 90-96
fixtures/anna_loria_cooling_active/all_data.json (1)
50-59: Note the temperature difference between Gateway and OpenThermIn this fixture, there's a notable difference between:
- Gateway's
weather.outdoor_temperature: 15.5°C- OpenTherm's
sensors.outdoor_air_temperature: 17.2°CThis aligns with the PR's intention to maintain both values when available, but consider:
- Adding a comment in the fixture explaining why these values differ
- Documenting how consumers should handle such differences
Also applies to: 91-91
tests/data/adam/adam_plus_anna_new_regulation_off.json (1)
179-185: Diversify test data valuesThe weather attributes (humidity, wind_bearing, wind_speed) are identical across test files, suggesting hardcoded values. Consider varying these values to ensure the system handles different scenarios effectively.
Consider updating the test data to include:
- Different wind conditions
- Various humidity levels
- Different weather descriptions
- Edge cases (0% and 100% humidity)
tests/data/adam/adam_zone_per_device.json (1)
581-590: LGTM! Weather data structure is consistent and handles varying conditions well.The implementation successfully demonstrates how different weather conditions are represented while maintaining consistent data types and structure across different gateway configurations.
Consider documenting the following for future reference:
- The units of measurement for each weather attribute (e.g., wind speed in m/s or km/h)
- The expected range of values for each attribute
- The list of possible weather descriptions
tests/data/adam/adam_multiple_devices_per_zone.json (1)
584-593: LGTM: Weather data structure enhancementThe reorganization of weather data into a dedicated
weatherobject with comprehensive attributes (humidity, temperature, description, wind data) improves data organization and clarity.Consider adding data validation for the weather attributes to ensure values are within expected ranges:
- humidity: 0-100%
- wind_bearing: 0-360 degrees
- wind_speed: non-negative values
plugwise/helper.py (1)
810-828: Consider enhancing error handling in value parsingWhile the implementation is functional, it could benefit from additional error handling:
- Add try-catch blocks for float parsing
- Validate measurement values before conversion
def _loc_value( self, loc_id: str, measurement: str, attrs: DATA | UOM ) -> float | int | str | None: locator = f"./location[@id='{loc_id}']/logs/point_log[type='{measurement}']/period/measurement" if (found := self._domain_objects.find(locator)) is None: return None value: str = found.text + try: match measurement: case "humidity": return int(float(value)) case "outdoor_temperature" | "solar_irradiance": return format_measure(value, getattr(attrs, ATTR_UNIT_OF_MEASUREMENT)) case _: return value + except (ValueError, TypeError) as err: + LOGGER.warning("Failed to parse measurement %s: %s", measurement, err) + return None
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (56)
fixtures/adam_heatpump_cooling/all_data.json(2 hunks)fixtures/adam_jip/all_data.json(2 hunks)fixtures/adam_multiple_devices_per_zone/all_data.json(1 hunks)fixtures/adam_onoff_cooling_fake_firmware/all_data.json(2 hunks)fixtures/adam_plus_anna/all_data.json(2 hunks)fixtures/adam_plus_anna_new/all_data.json(2 hunks)fixtures/adam_plus_anna_new_regulation_off/all_data.json(2 hunks)fixtures/adam_zone_per_device/all_data.json(1 hunks)fixtures/anna_elga_2/all_data.json(1 hunks)fixtures/anna_elga_2_cooling/all_data.json(1 hunks)fixtures/anna_elga_2_schedule_off/all_data.json(1 hunks)fixtures/anna_elga_no_cooling/all_data.json(2 hunks)fixtures/anna_heatpump_cooling/all_data.json(2 hunks)fixtures/anna_heatpump_cooling_fake_firmware/all_data.json(2 hunks)fixtures/anna_heatpump_heating/all_data.json(2 hunks)fixtures/anna_loria_cooling_active/all_data.json(2 hunks)fixtures/anna_loria_driessens/all_data.json(2 hunks)fixtures/anna_loria_heating_idle/all_data.json(2 hunks)fixtures/anna_v4/all_data.json(2 hunks)fixtures/anna_v4_dhw/all_data.json(2 hunks)fixtures/anna_v4_no_tag/all_data.json(2 hunks)fixtures/anna_without_boiler_fw441/all_data.json(2 hunks)fixtures/m_adam_cooling/all_data.json(1 hunks)fixtures/m_adam_heating/all_data.json(1 hunks)fixtures/m_adam_jip/all_data.json(2 hunks)fixtures/m_adam_multiple_devices_per_zone/all_data.json(1 hunks)fixtures/m_anna_heatpump_cooling/all_data.json(2 hunks)fixtures/m_anna_heatpump_idle/all_data.json(2 hunks)plugwise/constants.py(6 hunks)plugwise/helper.py(5 hunks)plugwise/util.py(2 hunks)pyproject.toml(1 hunks)tests/data/adam/adam_heatpump_cooling.json(1 hunks)tests/data/adam/adam_jip.json(1 hunks)tests/data/adam/adam_multiple_devices_per_zone.json(1 hunks)tests/data/adam/adam_onoff_cooling_fake_firmware.json(1 hunks)tests/data/adam/adam_plus_anna.json(1 hunks)tests/data/adam/adam_plus_anna_new.json(1 hunks)tests/data/adam/adam_plus_anna_new_regulation_off.json(1 hunks)tests/data/adam/adam_zone_per_device.json(1 hunks)tests/data/anna/anna_elga_2.json(1 hunks)tests/data/anna/anna_elga_2_cooling.json(1 hunks)tests/data/anna/anna_elga_2_cooling_UPDATED_DATA.json(1 hunks)tests/data/anna/anna_elga_2_schedule_off.json(1 hunks)tests/data/anna/anna_elga_no_cooling.json(1 hunks)tests/data/anna/anna_heatpump_cooling.json(1 hunks)tests/data/anna/anna_heatpump_cooling_fake_firmware.json(1 hunks)tests/data/anna/anna_heatpump_heating.json(1 hunks)tests/data/anna/anna_loria_cooling_active.json(1 hunks)tests/data/anna/anna_loria_driessens.json(1 hunks)tests/data/anna/anna_loria_heating_idle.json(1 hunks)tests/data/anna/anna_v4.json(1 hunks)tests/data/anna/anna_v4_UPDATED_DATA.json(1 hunks)tests/data/anna/anna_v4_dhw.json(1 hunks)tests/data/anna/anna_v4_no_tag.json(1 hunks)tests/data/anna/anna_without_boiler_fw441.json(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (27)
- tests/data/adam/adam_heatpump_cooling.json
- fixtures/anna_heatpump_heating/all_data.json
- fixtures/m_adam_jip/all_data.json
- tests/data/anna/anna_without_boiler_fw441.json
- fixtures/anna_heatpump_cooling_fake_firmware/all_data.json
- tests/data/anna/anna_elga_2_cooling_UPDATED_DATA.json
- tests/data/anna/anna_elga_2_cooling.json
- tests/data/anna/anna_heatpump_heating.json
- fixtures/anna_heatpump_cooling/all_data.json
- plugwise/util.py
- tests/data/anna/anna_heatpump_cooling.json
- tests/data/anna/anna_v4_UPDATED_DATA.json
- fixtures/adam_plus_anna/all_data.json
- fixtures/m_anna_heatpump_idle/all_data.json
- fixtures/m_anna_heatpump_cooling/all_data.json
- fixtures/m_adam_heating/all_data.json
- fixtures/adam_plus_anna_new_regulation_off/all_data.json
- fixtures/anna_v4/all_data.json
- fixtures/anna_without_boiler_fw441/all_data.json
- fixtures/anna_loria_driessens/all_data.json
- tests/data/anna/anna_elga_no_cooling.json
- tests/data/adam/adam_onoff_cooling_fake_firmware.json
- fixtures/anna_v4_no_tag/all_data.json
- fixtures/anna_elga_2_schedule_off/all_data.json
- tests/data/adam/adam_plus_anna.json
- fixtures/adam_plus_anna_new/all_data.json
- fixtures/adam_onoff_cooling_fake_firmware/all_data.json
🔇 Additional comments (31)
tests/data/anna/anna_v4_dhw.json (1)
51-57: Verify schema validation for the new weather object
The new weather object introduces several weather-related fields. To ensure data consistency and prevent potential issues:
- Consider adding schema validation for the weather object
- Document the expected units for each metric (e.g., wind speed in m/s or km/h)
- Define acceptable ranges for each value
✅ Verification successful
Weather data validation is already handled in the codebase
After analyzing the codebase, I found that weather data validation is already properly handled:
- The weather data structure is strictly typed using
WeatherTypeinplugwise/constants.pywhich defines the exact fields and their types:
WeatherType = Literal[
"humidity",
"outdoor_temperature",
"weather_description",
"wind_bearing",
"wind_speed",
]- The units are clearly defined in the constants:
- Temperature in Celsius (TEMP_CELSIUS)
- Wind speed in unspecified units (no unit)
- Humidity in percentage (PERCENTAGE)
- Wind bearing in degrees (no unit)
- The values are automatically validated through the
format_measure()function inplugwise/util.pywhich handles type conversion and formatting based on the unit type.
The implementation provides sufficient validation and type safety for the weather object.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if schema validation exists for the weather object
rg -l "weather.*schema" --type json
rg -l "weather.*validation" --type python
Length of output: 112
Script:
#!/bin/bash
# Search for schema or validation related files
fd -e json -e py -e yaml -e yml | grep -i "schema\|valid"
# Search for weather-related validation patterns in all files
rg "weather.*schema|schema.*weather|weather.*valid|valid.*weather" -g '!{*.md,*.txt}'
# Look for any test files that might validate weather data
fd -e py -e json test | grep -i "weather"
Length of output: 189
Script:
#!/bin/bash
# Look for the structure and content of test data files
cat tests/data/anna/anna_v4_dhw.json
# Search for any files that might contain weather-related code
rg -l "weather" --type-not md --type-not txt
# Check if there are any schema files in the repository
fd schema
Length of output: 7471
Script:
#!/bin/bash
# Check the content of potential validation files
cat plugwise/constants.py
cat plugwise/util.py
# Look for any validation or schema-related code in the common module
cat plugwise/common.py
# Check if there are any test files that might contain validation logic
cat scripts/manual_fixtures.py
Length of output: 51207
tests/data/anna/anna_v4.json (1)
48-48: Verify consistency across all test fixtures
The weather data structure is identical across test fixtures, which is good for consistency. However, consider:
- Creating shared test utilities to generate consistent weather data
- Adding test cases for edge cases (e.g., missing or null weather values)
Also applies to: 50-57
✅ Verification successful
Let me generate another script to better understand the weather data structure in the specific files we're interested in.
Weather data structure is consistent across test fixtures
The weather data structure is consistent across all anna_v4* test fixtures, containing the same fields (humidity, outdoor_temperature, weather_description, wind_bearing, wind_speed) with appropriate values. The solar_irradiance field in the review is part of this consistent structure. No issues found with the test data consistency.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check for consistent weather data structure across test fixtures
echo "Checking weather object structure consistency..."
rg -l '"weather":\s*{' --type json tests/
for file in $(fd -e json . tests/); do
echo "=== $file ==="
jq -r 'if (.entities."0466eae8520144c78afb29628384edeb".weather // .device_zones."0466eae8520144c78afb29628384edeb".weather) then keys else "No weather data" end' "$file"
done
Length of output: 14634
Script:
#!/bin/bash
# Check weather data structure in anna_v4*.json files
for file in $(fd -e json anna_v4 tests/data/anna/); do
echo "=== $file ==="
jq -r '.device_zones."0466eae8520144c78afb29628384edeb".weather // .entities."0466eae8520144c78afb29628384edeb".weather' "$file"
done
Length of output: 1782
tests/data/anna/anna_elga_2_schedule_off.json (1)
87-96: Verify temperature source prioritization and potential data duplication
The Gateway entity now provides outdoor temperature in two locations:
- Via OpenTherm's physical sensor as
outdoor_air_temperature(13.0) - Via Gateway's weather data as
weather.outdoor_temperature(13.0)
While the values currently match, we should ensure:
- The system correctly prioritizes the physical sensor reading when available
- Document which source should be used in which scenarios to avoid confusion
✅ Verification successful
Based on the search results, I can now generate a final response since I have enough information about how outdoor temperature is handled in the codebase:
Physical sensor reading is correctly prioritized over weather data
The codebase shows clear evidence of proper temperature source prioritization:
-
In
plugwise/legacy/helper.py, there's a clear distinction between sources:- Physical sensor readings are obtained from APPLIANCES
- Weather data is obtained from DOMAIN_OBJECTS and LOCATIONS
-
The changelog confirms this prioritization:
- "Improve
outdoor_temperatureaccordingly (favour Auxiliary over Smile)" - Physical sensor was renamed from "outdoor_temperature" to "outdoor_air_temperature" for clarity
- "Improve
-
Test fixtures consistently show this pattern, with physical readings taking precedence when available.
The current implementation correctly handles the temperature sources, and the dual reporting serves different purposes rather than causing confusion.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for outdoor temperature usage across the codebase
rg -l "outdoor.*temperature" | while read -r file; do
echo "=== $file ==="
rg "outdoor.*temperature" "$file"
done
Length of output: 56394
fixtures/anna_v4_dhw/all_data.json (2)
100-100: Verify item count increment
The item_count increase from 58 to 63 (+5) matches the number of new weather attributes added (solar_irradiance + 4 weather fields).
48-57: Verify weather data types and ranges
The new weather structure looks good, but let's ensure the data types and ranges are appropriate:
solar_irradiance: 449.4 W/m² (reasonable for clear day)humidity: 81% (valid range 0-100)outdoor_temperature: 7.44°C (reasonable)wind_bearing: 240.0° (valid range 0-360)wind_speed: 3.6 m/s (reasonable)
Consider adding validation for these ranges in the code that processes this data.
✅ Verification successful
Weather data structure and types are properly defined and handled
Based on the codebase analysis:
- Weather data types are defined in
plugwise/constants.pywith appropriate typing:humidity: Percentage unitoutdoor_temperature: Celsius unitweather_description: Stringwind_bearing: Float (degrees)wind_speed: Float (derived from wind_vector)solar_irradiance: No specific unit constraint
The values in the JSON are consistent with these type definitions and the data is properly processed in the codebase. While there's no explicit range validation, the data handling code in plugwise/helper.py ensures proper type conversion and formatting.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check for weather data validation in the codebase
rg -l "weather.*valid|valid.*weather"
Length of output: 39
Script:
#!/bin/bash
# Search for weather-related code and validation patterns more broadly
rg -A 5 "weather" --type py --type ts --type js
# Also check for any schema or type definitions
ast-grep --pattern 'interface Weather {
$$$
}'
ast-grep --pattern 'type Weather = {
$$$
}'
# Look for any validation functions or classes
rg -A 5 "(validate|check|verify).*weather"
Length of output: 5584
tests/data/anna/anna_loria_cooling_active.json (1)
50-59: Consistent implementation of weather data structure
The weather data structure matches the implementation in other files, which is good for consistency. Note that we have two temperature sources:
- Gateway weather data:
outdoor_temperature: 15.5°C - Heater sensor:
outdoor_air_temperature: 17.2°C
This aligns with the PR comment about prioritizing physical sensor data while maintaining both sources.
✅ Verification successful
Let me gather more information to verify the consistency of weather data structure and the presence of dual temperature sources.
Let me try a different approach to verify the weather data structure and temperature sources.
Weather data structure is consistent and dual temperature sources are correctly implemented
The verification confirms that:
- The weather data structure is consistent across all test files, containing the same fields: humidity, outdoor_temperature, weather_description, wind_bearing, and wind_speed.
- The dual temperature sources are correctly implemented:
- Gateway weather data:
outdoor_temperature: 15.5°Cin the weather object - Physical sensor data:
outdoor_air_temperature: 17.2°Cin the device data
- Gateway weather data:
This implementation aligns with the PR's intention to maintain both the Gateway's weather data and the physical sensor readings, allowing the system to prioritize physical sensor data while keeping the weather service data available.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check for consistent weather data structure across all test files
fd -e json -x jq -r 'paths | select(contains(["weather"]))' {} \; | sort | uniq
Length of output: 669
Script:
#!/bin/bash
# Check for files containing both weather and outdoor_air_temperature
echo "=== Files with both weather and outdoor_air_temperature ==="
rg -l '"weather".*"outdoor_air_temperature"|"outdoor_air_temperature".*"weather"' --type json
echo -e "\n=== Weather data structure in these files ==="
rg '"weather".*\{.*\}' --type json -A 6
Length of output: 373
Script:
#!/bin/bash
# Search for weather data structure in JSON files
echo "=== Weather data structures ==="
rg -U '"weather": \{[^}]+\}' --type json
echo -e "\n=== Files with outdoor_air_temperature ==="
rg '"outdoor_air_temperature"' --type json -B 2 -A 2
Length of output: 37562
tests/data/anna/anna_loria_driessens.json (1)
19-25: Verify the relationship between outdoor temperature values
The weather data shows outdoor_temperature: 6.81 while the heater's sensors show outdoor_air_temperature: 7.5. This difference aligns with the PR discussion about handling both physical sensor and perceived data, but we should verify if this is the intended behavior.
✅ Verification successful
Based on the search results, I can now generate the final response:
Different outdoor temperature values are expected and correct
The difference between outdoor_temperature (6.81) in the weather data and outdoor_air_temperature (7.5) in the heater sensors is an intended behavior, as evidenced by:
- The pattern is consistent across multiple test fixtures where both values are present
- In
plugwise/constants.py, both fields are explicitly defined separately:outdoor_temperatureis defined as a general weather metricoutdoor_air_temperatureis specifically noted as "Outdoor temperature from APPLIANCES - present for a heatpump"
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for patterns of outdoor temperature usage across the codebase
echo "Checking for outdoor temperature patterns..."
rg -A 2 '"outdoor_temperature":'
rg -A 2 '"outdoor_air_temperature":'
Length of output: 20739
fixtures/anna_elga_no_cooling/all_data.json (2)
19-25: LGTM! Weather data structure is consistent
The weather data structure follows the same pattern as other files, with all required attributes present.
105-105: Verify item count increase
The item count increase from 63 to 68 matches the number of new weather attributes added (humidity, outdoor_temperature, weather_description, wind_bearing, wind_speed).
✅ Verification successful
Let me analyze the item count changes across the fixtures to verify the review comment.
Item count increase verified
The verification confirms that the item count increase from 63 to 68 (+5) in anna_elga_no_cooling matches exactly with the addition of five new weather attributes: humidity, outdoor_temperature, weather_description, wind_bearing, and wind_speed, which are present in the fixture data.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check for consistent item count changes across fixtures
echo "Checking item count changes in fixtures..."
rg -B 2 -A 2 '"item_count":'
Length of output: 14878
Script:
#!/bin/bash
# Let's check the content of anna_v4_no_tag and anna_elga_no_cooling to verify the item count change
echo "Comparing the two relevant fixtures..."
echo "anna_v4_no_tag items:"
rg -A 5 "outdoor_temp|humidity|weather_description|wind_bearing|wind_speed" fixtures/anna_v4_no_tag/all_data.json || echo "No weather attributes found"
echo -e "\nanna_elga_no_cooling items:"
rg -A 5 "outdoor_temp|humidity|weather_description|wind_bearing|wind_speed" fixtures/anna_elga_no_cooling/all_data.json || echo "No weather attributes found"
Length of output: 1177
fixtures/anna_elga_2_cooling/all_data.json (1)
90-96: LGTM! Weather data appropriate for cooling scenario
The weather data values (temperature: 31.0°C, humidity: 42%) are realistic for a cooling scenario, and the structure is consistent with other files.
fixtures/anna_elga_2/all_data.json (2)
87-96: Verify the coexistence of outdoor temperature values
I notice that outdoor temperature is represented in two places:
- Gateway device:
weather.outdoor_temperature - OpenTherm device:
sensors.outdoor_air_temperature
Based on the PR comments, this appears intentional to differentiate between physical sensor data (outdoor_air_temperature) and Gateway-provided weather data (outdoor_temperature). However, please verify that:
- These values can differ
- The naming distinction is documented
- Consumers of this API are aware of the difference
✅ Verification successful
The dual temperature representation is intentional and well-defined
Based on the search results, I can confirm that:
outdoor_air_temperatureis consistently used in the "sensors" object for physical sensor readings from OpenTherm/heat pump devicesoutdoor_temperatureis consistently used in the "weather" object for weather service data- The distinction is documented in
plugwise/constants.pywhereoutdoor_temperaturemaps tooutdoor_air_temperaturewith proper unit definitions
The values can and do differ in the test fixtures, confirming they serve different purposes:
- In
anna_elga_2/all_data.json:outdoor_air_temperature: 14.0vsoutdoor_temperature: 13.0 - In
anna_heatpump_heating/all_data.json:outdoor_air_temperature: 3.0vsoutdoor_temperature: 20.2
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for documentation about temperature naming convention
rg -l "outdoor.*temperature" | xargs rg -l "documentation|readme|guide"
# Search for other occurrences of both temperature fields
rg -A 1 '"outdoor_air_temperature":'
rg -A 1 '"outdoor_temperature":'
Length of output: 14377
103-103: Verify item_count increase
The gateway's item_count increased from 63 to 68 (+5). This appears to correspond to the 5 new weather attributes added (humidity, outdoor_temperature, weather_description, wind_bearing, wind_speed).
fixtures/m_adam_cooling/all_data.json (1)
98-98: Verify temperature range validation
The outdoor temperature value of 29.65°C seems unusually high compared to other temperature readings in the system (which are around 23-25°C). Consider adding range validation to ensure weather data accuracy.
tests/data/adam/adam_plus_anna_new.json (1)
176-185: LGTM: Weather data implementation aligns with objectives
The separation of weather data into a dedicated object while maintaining solar_irradiance in sensors aligns well with:
- The PR objective to collect weather data from the Gateway
- The previous decision to keep physical sensor data separate
- The need for clear data organization
tests/data/adam/adam_jip.json (1)
229-238: LGTM! Weather data structure looks well-organized.
The separation of weather-related data into a dedicated weather object while keeping solar_irradiance in sensors provides a clear and logical structure. The new weather attributes (humidity, outdoor_temperature, weather_description, wind_bearing, wind_speed) provide comprehensive weather information that can enhance thermostat functionality.
Let's verify the consistency of this weather data structure across other gateway configurations:
✅ Verification successful
Weather data structure is consistently implemented across gateway configurations
The weather data structure is consistently implemented in both Adam and Anna configurations with the same attributes:
humidityoutdoor_temperatureweather_descriptionwind_bearingwind_speed
The absence of the weather object in Stretch and P1 configurations is expected as these are different types of devices that don't require weather data for their operation.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for consistent weather data structure across gateway configurations
# Look for files containing gateway configurations
rg -l '"dev_class":\s*"gateway"' --type json
Length of output: 2954
Script:
#!/bin/bash
# Check for weather data structure in gateway configurations
# Looking specifically for the weather object structure in a few representative files
echo "=== Checking adam_jip.json (original) ==="
rg -A6 '"weather":\s*{' tests/data/adam/adam_jip.json
echo -e "\n=== Checking anna configurations ==="
rg -A6 '"weather":\s*{' tests/data/anna/anna_v4.json tests/data/anna/anna_heatpump_cooling.json
echo -e "\n=== Checking stretch configurations ==="
rg -A6 '"weather":\s*{' tests/data/stretch/stretch_v31.json
echo -e "\n=== Checking p1 configurations ==="
rg -A6 '"weather":\s*{' tests/data/p1/smile_p1_v2.json
Length of output: 1002
Script:
#!/bin/bash
# Check for weather data structure in gateway configurations with fixed regex
# Looking specifically for the weather object structure in a few representative files
echo "=== Checking adam_jip.json (original) ==="
rg -A6 '"weather": \{' tests/data/adam/adam_jip.json
echo -e "\n=== Checking anna configurations ==="
rg -A6 '"weather": \{' tests/data/anna/anna_v4.json tests/data/anna/anna_heatpump_cooling.json
echo -e "\n=== Checking stretch configurations ==="
rg -A6 '"weather": \{' tests/data/stretch/stretch_v31.json
echo -e "\n=== Checking p1 configurations ==="
rg -A6 '"weather": \{' tests/data/p1/smile_p1_v2.json
Length of output: 1698
fixtures/adam_jip/all_data.json (1)
233-242: LGTM! Weather data structure is consistent with test fixtures.
The weather data implementation matches the test fixtures, maintaining consistency across the codebase.
fixtures/m_adam_multiple_devices_per_zone/all_data.json (2)
575-584: LGTM: Consistent weather data structure
The weather data structure matches the implementation in other files, maintaining consistency across the codebase.
592-592: Verify item count increment
The item_count has been increased from 369 to 374, which appears to correspond to the addition of new weather attributes.
fixtures/adam_zone_per_device/all_data.json (2)
581-590: LGTM: Consistent implementation across fixtures
The weather data structure is consistently implemented across all fixture files, ensuring reliable test coverage.
598-598: Consistent item count update
The item count update matches other fixture files, maintaining consistency.
plugwise/constants.py (4)
146-152: Inconsistency between wind measurements.
There's a discrepancy between the wind measurements in DEVICE_MEASUREMENTS and the new WeatherData class:
DEVICE_MEASUREMENTSuseswind_vectorWeatherDatauses separatewind_bearingandwind_speed
395-402: LGTM! Well-structured weather type definitions.
The WeatherType literal and WEATHER tuple are properly defined with all necessary weather attributes.
525-533: LGTM! Well-structured weather data class.
The WeatherData class is properly defined as a TypedDict with appropriate type hints for all weather attributes.
606-606: LGTM! Proper integration of weather data.
The weather field has been correctly added to the GwEntityData class with the appropriate type.
pyproject.toml (1)
7-7: LGTM! Appropriate version bump for new feature.
The version has been updated to 1.7.0a1, which is appropriate for adding the new weather data feature in alpha testing.
plugwise/helper.py (2)
19-19: LGTM: Weather data type initialization is well structured
The initialization of weather data types and structures is clean and follows good practices:
- Proper import of measurement unit attribute
- Clear type definition for weather data
- Explicit initialization of the weather dictionary in GwEntityData
Also applies to: 47-47, 531-536
773-808: Previous wind vector parsing concern still applies
The wind vector parsing implementation remains unchanged from the previous review.
LGTM: Gateway measurements implementation is comprehensive
The method effectively:
- Collects all weather-related measurements from the home location
- Properly handles different measurement types
- Correctly formats and assigns values to appropriate data structures
fixtures/anna_loria_heating_idle/all_data.json (2)
53-59: LGTM! Well-structured weather data implementation.
The weather object provides comprehensive environmental data including temperature, humidity, wind conditions, and weather description. This aligns with the PR objective of collecting weather data from the Gateway.
50-50: Verify the temperature source prioritization.
The implementation correctly maintains both temperature sources:
- Gateway weather data (
outdoor_temperature: 15.5°C) for perceived temperature - Physical sensor data (
outdoor_air_temperature: 17.2°C) from the heater device
This aligns with the decision to prioritize physical sensor data while maintaining both readings for clarity.
Also applies to: 55-55, 74-74
✅ Verification successful
Temperature source prioritization is correctly implemented
The verification confirms that both temperature sources are consistently handled across the codebase:
- Gateway weather data (
outdoor_temperature) is present in all device fixtures - Physical sensor data (
outdoor_air_temperature) is present in heat pump and specific device fixtures where applicable - The values in the reviewed file (15.5°C and 17.2°C) match the expected pattern where physical sensor readings differ from gateway weather data
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify consistent temperature source handling across fixtures
# Expected: Both outdoor_temperature and outdoor_air_temperature should be present when applicable
# Search for outdoor temperature attributes
rg -A 1 '"outdoor_temperature":'
rg -A 1 '"outdoor_air_temperature":'
Length of output: 14290
fixtures/adam_heatpump_cooling/all_data.json (2)
312-318: LGTM! Consistent weather data structure across fixtures.
The weather object maintains the same structure and attributes as seen in the Anna fixture, ensuring consistency across different device configurations.
819-819: Verify gateway item count updates.
The item count increase (+5) consistently reflects the addition of weather attributes across fixtures:
- Anna fixture: 66 → 71
- Adam fixture: 497 → 502
| "solar_irradiance": 0.0 | ||
| }, | ||
| "vendor": "Plugwise" | ||
| "vendor": "Plugwise", | ||
| "weather": { | ||
| "humidity": 42, | ||
| "outdoor_temperature": 13.0, | ||
| "weather_description": "cloudy", | ||
| "wind_bearing": 120.0, | ||
| "wind_speed": 3.6 | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Verify inconsistent temperature values between sensors
There's a discrepancy in the outdoor temperature values:
- OpenTherm's
outdoor_air_temperature: 14.0 - Gateway's
weather.outdoor_temperature: 13.0
This inconsistency should either be:
- Fixed if it's a test data error
- Documented if it's intentionally testing the handling of different temperature sources
Consider updating the test data to maintain consistency, or add a comment explaining the intentional difference.
| "solar_irradiance": 3.0 | ||
| }, | ||
| "vendor": "Plugwise", | ||
| "weather": { | ||
| "humidity": 90, | ||
| "outdoor_temperature": 29.65, | ||
| "weather_description": "rain", | ||
| "wind_bearing": 291.0, | ||
| "wind_speed": 6.26 | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Breaking change detected in weather data structure requiring code updates
The verification reveals two implementation files that need to be updated to handle the restructured weather data:
plugwise/legacy/helper.py: Currently adds outdoor_temperature under thesensorsobjectplugwise/helper.py: Already handles some weather data in theweatherobject but needs to be updated for the outdoor_temperature relocation
The changes required are:
- Update
plugwise/legacy/helper.pyto place outdoor_temperature in the weather object instead of sensors - Ensure
plugwise/helper.pyconsistently handles all weather-related data including the relocated outdoor_temperature
🔗 Analysis chain
Consider backward compatibility impacts of the weather data restructuring
The movement of outdoor_temperature from sensors to the new weather object is a breaking change that could affect existing implementations. While the new structure better organizes weather-related data, we should ensure that:
- Consumers of the API are notified of this change
- Documentation is updated to reflect the new structure
- A migration path is provided for existing implementations
Let's verify the impact on existing code:
Let me check the specific usage in the identified file to better understand the impact.
Let me check if there are any other files that might be consuming this data structure, particularly looking for weather-related attributes.
Let me check the implementation in plugwise/helper.py to see if it's already handling the new weather structure.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for direct references to outdoor_temperature in sensors
rg -l "sensors.*outdoor_temperature"
Length of output: 64
Script:
#!/bin/bash
# Check the context of outdoor_temperature usage
rg -C 5 "sensors.*outdoor_temperature" plugwise/legacy/helper.py
Length of output: 534
Script:
#!/bin/bash
# Search for references to weather data structure
rg -l "weather.*temperature|weather.*humidity|weather.*wind"
# Also check for any test files that might need updates
fd -e test.py -e tests.py -x rg -l "outdoor_temperature|weather" {}
Length of output: 735
Script:
#!/bin/bash
# Check the context of weather-related implementations in helper.py
rg -C 5 "weather.*temperature|weather.*humidity|weather.*wind" plugwise/helper.py
Length of output: 815
| "gateway_id": "b5c2386c6f6342669e50fe49dd05b188", | ||
| "heater_id": "e4684553153b44afbef2200885f379dc", | ||
| "item_count": 244, | ||
| "item_count": 249, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
The item count of 249 in the JSON file is incorrect and should be updated to 287
The verification reveals that there are actually 287 items in the data structure (excluding the "item_count" field itself). This count represents all the actual data fields (strings, numbers, and booleans) within the JSON structure. The current value of 249 is outdated and needs to be corrected to reflect the actual count.
🔗 Analysis chain
Verify the updated item count.
The item count has increased from 244 to 249, which aligns with the addition of new weather attributes.
Let's verify if the item count matches the actual number of items:
Let me verify the specific structure of the JSON to understand why there's a discrepancy between the stated count (249) and our initial count (288).
Let me check the actual count of items that should be included based on the data structure, excluding metadata fields like "item_count" itself.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Count the actual number of items in the JSON
jq '[.. | select(type == "string" or type == "number" or type == "boolean")] | length' fixtures/adam_jip/all_data.json
Length of output: 124
Script:
#!/bin/bash
# Let's examine the structure of the JSON file to understand what should be counted
jq 'keys' fixtures/adam_jip/all_data.json
# Also get the keys at the second level to understand the data organization
jq '.[] | keys' fixtures/adam_jip/all_data.json | sort | uniq
Length of output: 821
Script:
#!/bin/bash
# Count the number of actual data fields, excluding structural/metadata fields
jq '
def count_items:
if type == "object" then
to_entries | map(
if .key == "item_count" then 0
else .value | count_items
end
) | add
elif type == "array" then
map(count_items) | add
elif type == "string" or type == "number" or type == "boolean" then
1
else
0
end;
count_items
' fixtures/adam_jip/all_data.json
Length of output: 392
| "select_regulation_mode": "heating", | ||
| "sensors": { | ||
| "outdoor_temperature": 7.81 | ||
| "solar_irradiance": 157.5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Item count verification failed - discrepancy found
The actual count of items in the JSON is 440, but there is no item_count field present in the JSON structure (returns null). This indicates a potential issue where the item count tracking is missing from the data structure.
- The JSON contains 440 primitive values (strings, numbers, or booleans)
- The
item_countfield is missing from the JSON structure - Consider adding the
item_countfield to maintain data integrity
🔗 Analysis chain
LGTM! Verify the updated item count.
The weather data structure has been properly added to the gateway section, and the sensors field has been updated accordingly. The changes align with the PR objectives to collect weather data.
Run the following script to verify the item count:
Also applies to: 587-593, 601-601
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that the item_count matches the actual number of items in the JSON
# Expected: The item_count should match the number of items in the JSON
# Count all items in the JSON (excluding the item_count itself)
jq '[.. | select(type == "string" or type == "number" or type == "boolean") | tostring] | length' fixtures/adam_multiple_devices_per_zone/all_data.json
Length of output: 157
Script:
#!/bin/bash
# Let's verify the item_count field in the JSON
jq '.item_count' fixtures/adam_multiple_devices_per_zone/all_data.json
Length of output: 75
|
Closing this PR. It's doesn't really add any value. |



@CoMPaTech I was preparing a little bit for the Anna P1 device and I realized there is also interesting data available at the Gateway / Home location for thermostat devices.
Also, this will allow us to add the weather-platform to the Integrations.
Summary by CodeRabbit
New Features
weatherdata structure for devices, replacing the previoussensorsstructure, which includes attributes like humidity, outdoor temperature, solar irradiance, weather description, wind bearing, and wind speed.Bug Fixes