Feature/greedy priority algorithm - #196
Conversation
- Add `GreedyPriorityAlgorithm` class: deterministic two-pass algorithm that turns on highest-priority devices first within solar surplus, then turns off lowest-priority devices on deficit; supports load shedding (force-stop lower-priority active devices) when `priority_weight > 0` and device has `can_be_shed: true` - Add `SolarOptimizerAlgorithm` Protocol to enforce a shared interface between both algorithms - Add `CONF_ALGORITHM_TYPE` central config field to select between `simulated_annealing` (default) and `greedy_priority` - Add `can_be_shed` per-device flag to both managed and power-managed device schemas - Wire algorithm selection in coordinator `configure()` - Add `tests/test_greedy_algo.py`: 9 HA integration tests covering algorithm selection, priority ordering, load shedding, and no-shedding when `priority_weight=0` - Add `tests/test_day_simulation.py`: 4 pure-Python fake-day simulation tests comparing greedy vs SA over a full synthetic solar day - Update README.md and README-fr.md: document both algorithms, add algorithm selection comparison table, add `algorithm_type` and `can_be_shed` to parameter tables, scope SA advanced config as SA-only Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nvention - Replace `allowed_power_overage` (watts) with `allowed_power_overage_percent` (0-100% slider): overage = solar × percent / 100, so grid import is automatically zero at night when solar = 0 - Fix greedy Pass 2 over-shedding: only shed when deficit exceeds allowed_power_overage, preserving intentional import from Pass 1 - Fix greedy excess formula: use `excess = -power_consumption` to match the real HA sensor convention (net grid consumption, negative = exporting) - Add `allowed_power_overage` parameter to Protocol, SA (ignored), and Greedy (used in Pass 1 turn-on check) - Fix day simulation test: pass net consumption (gross - solar) so SA receives negative values when exporting, matching real HA sensor semantics - Update greedy integration tests to use net consumption values - Add `test_day_simulation_three_way_comparison`: SA vs Greedy 0% vs Greedy 20% overage with solar utilization % row Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Documents SA vs Greedy Priority behaviour from synthetic day simulation: objective function mechanics, simulation results table, key findings (SA ignores priority, Greedy respects ordering, overage percent design), input convention pitfall, and a when-to-use guide. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Hello, Yes this is fine for me. I think you can achieve almost the same result with the weight given to the algorithm but it is certainly more simple to have a different algorithm. I will study that more closely. |
jmcollin78
left a comment
There was a problem hiding this comment.
I think the tranlsations is missing. You add keys so there should be strings.json, en.json and fr.json changed.
Add SENSOR_DOMAIN to power entity selector in config schema. When a non-power-managed device has a power_entity_id configured, read current power from the sensor state instead of always defaulting to power_max. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Address PR review comments from @jmcollin78: - Rename recuit_simule → optimize across the Protocol, both algorithm implementations, coordinator call site, and tests - Make SimulatedAnnealingAlgorithm honour allowed_power_overage: imports within that watt threshold are treated as cost-free in calculer_objectif, giving SA the same grid-import tolerance as the greedy algorithm Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Thank you. I will do complete tests tomorrow before releasing. |
jmcollin78
left a comment
There was a problem hiding this comment.
Noce PR. I've got one question aboout the changes in managed_device.py
| self._can_change_power = self._power_min >= 0 | ||
| self._convert_power_divide_factor = int( | ||
| device_config.get("convert_power_divide_factor") or 1 | ||
| self._convert_power_divide_factor = ( |
There was a problem hiding this comment.
Why this change ?
You try to use the real power of a device instead of the power configured for device that cannot change power ?
If I'm right, this is a bad design and not necessary because SO will always adapt itself with the real consumption.
I guess this has nothing to do with the Greedy algo itself. Am I right ?
| power_entity_state = self._hass.states.get(self._power_entity_id) | ||
| if power_entity_state and power_entity_state.state not in [None, STATE_UNKNOWN, STATE_UNAVAILABLE]: | ||
| try: | ||
| self._current_power = round( |
There was a problem hiding this comment.
What the purpose to have power x divide_factor ?
A power is a power. If you x divide_factor the result is not a power (but a Amp for example).
If those changes are not necessary for the Greedy algorithm I suggest to rollback all the managed_device changes.
|
I actually found a deeper issue this week, with devices that are on, but not drawing power, like a thermostat that reached target temperature.
|
This is not an issue for me. If a device in on but not consuming power, then on the next cycle, the available power will be high and next devices could be started. Nothing wrong with the actual algorithm. |
Not sure if you are interested but I added a new algorithm based on https://github.com/InventoCasa/ha-advanced-blueprints/blob/main/PV_Excess_Control/README.md and the ability of choosing and compare the algorithms
This algorithm does not model energy costs, it purely maximises solar self-consumption while respecting device priorities