diff --git a/CLAUDE.md b/CLAUDE.md index d78710b6c..4faa289c0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -147,8 +147,9 @@ All under Expert Mode in `config.py`: |--------|-------------| | `predbat.fit_income` | Predicted FIT income (base plan) | | `predbat.fit_income_best` | Predicted FIT income (best/optimised plan) | +| `predbat.fit_income_yesterday` | Predicted FIT income for yesterday's baseline | -Both sensors include attributes: `generation_income`, `deemed_export_income`, `generation_rate`, `deemed_export_rate`, `deemed_export_percentage`. +All sensors include attributes: `generation_income`, `deemed_export_income`, `generation_rate`, `deemed_export_rate`, `deemed_export_percentage`. ### Key Files @@ -158,4 +159,5 @@ Both sensors include attributes: `generation_income`, `deemed_export_income`, `g | `fetch.py` | Loads FIT config values, logs when FIT is enabled | | `prediction.py` | Zeros export rate when FIT enabled; tracks FIT income per simulation step | | `plan.py` | Extracts FIT income from prediction results; publishes `fit_income` / `fit_income_best` sensors | +| `output.py` | Extracts FIT income from yesterday predictions; publishes `fit_income_yesterday` sensor | | `tests/test_infra.py` | FIT defaults added to test config and `reset_inverter()` | diff --git a/apps/predbat/output.py b/apps/predbat/output.py index ab7e26f13..2e1f038b0 100644 --- a/apps/predbat/output.py +++ b/apps/predbat/output.py @@ -2885,6 +2885,10 @@ def calculate_yesterday(self): final_carbon_g, ) = self.run_prediction(charge_limit_best, charge_window_best, [], [], False, end_record=end_record, save="yesterday") + # Extract FIT income from the baseline prediction + fit_generation_income_baseline = self.prediction.final_fit_generation_income + fit_deemed_export_income_baseline = self.prediction.final_fit_deemed_export_income + # Add back in battery value overall_metric, battery_value_baseline = self.compute_metric( end_record, final_soc, final_soc, metric_baseline, metric_baseline, final_iboost, final_iboost, battery_cycle, metric_keep, final_carbon_g, import_kwh_battery, import_kwh_house, export_kwh @@ -3079,6 +3083,25 @@ def calculate_yesterday(self): }, ) + # Publish FIT income for yesterday's baseline prediction + if self.metric_fit_generation_rate > 0: + fit_total_income_yesterday = fit_generation_income_baseline + fit_deemed_export_income_baseline + self.dashboard_item( + self.prefix + ".fit_income_yesterday", + state=dp2(fit_total_income_yesterday), + attributes={ + "friendly_name": "Predicted FIT income yesterday", + "state_class": "measurement", + "unit_of_measurement": self.currency_symbols[1], + "icon": "mdi:solar-power", + "generation_income": dp2(fit_generation_income_baseline), + "deemed_export_income": dp2(fit_deemed_export_income_baseline), + "generation_rate": dp2(self.metric_fit_generation_rate), + "deemed_export_rate": dp2(self.metric_fit_deemed_export_rate), + "deemed_export_percentage": dp2(self.metric_fit_deemed_export_percentage), + }, + ) + # Simulate no PV or battery self.soc_kw = 0 self.soc_max = 0 @@ -3086,6 +3109,10 @@ def calculate_yesterday(self): self.prediction = Prediction(self, yesterday_pv_step_zero, yesterday_pv_step_zero, yesterday_load_step, yesterday_load_step) metric_no_pvbat, import_kwh_battery, import_kwh_house, export_kwh, soc_min, final_soc, soc_min_minute, battery_cycle, metric_keep, final_iboost, final_carbon_g = self.run_prediction([], [], [], [], False, end_record=end_record, save="yesterday") + # Extract FIT income from the no-PV/battery prediction (will be zero since no PV) + fit_generation_income_no_pvbat = self.prediction.final_fit_generation_income + fit_deemed_export_income_no_pvbat = self.prediction.final_fit_deemed_export_income + # Add back in battery value overall_metric, battery_value_no_pvbat = self.compute_metric( end_record, final_soc, final_soc, metric_no_pvbat, metric_no_pvbat, final_iboost, final_iboost, battery_cycle, metric_keep, final_carbon_g, import_kwh_battery, import_kwh_house, export_kwh