diff --git a/csharp/App/Backend/Services/ReportAggregationService.cs b/csharp/App/Backend/Services/ReportAggregationService.cs
index e29265c5c..824b9848b 100644
--- a/csharp/App/Backend/Services/ReportAggregationService.cs
+++ b/csharp/App/Backend/Services/ReportAggregationService.cs
@@ -739,22 +739,23 @@ Exactly 4 bullet points. Each starts with ""- Title: description"" format.";
var prompt = $@"You are an energy advisor for a sodistore home installation: ""{installationName}"".
-Write a concise monthly performance summary in {langName} (4 bullet points, plain text, no markdown).
+Write a concise monthly performance summary in {langName} (5 bullet points, plain text, no markdown).
MONTHLY FACTS for {monthName} ({weekCount} days of data):
- PV production: {totalPv:F1} kWh
- Total consumption: {totalConsump:F1} kWh
-- Self-sufficiency: {selfSufficiency:F1}% (share of energy covered by solar, without drawing from grid)
+- Self-sufficiency: {selfSufficiency:F1}% (share of energy covered by solar + battery, not bought from grid)
- Battery: {totalBattChg:F1} kWh charged, {totalBattDis:F1} kWh discharged, efficiency {batteryEff:F1}%
- Energy saved: {energySaved:F1} kWh = ~{savingsCHF:F0} CHF saved (at {ElectricityPriceCHF} CHF/kWh)
{weatherBlock}
INSTRUCTIONS:
1. Savings: state exactly how much energy and money was saved this month. Positive framing.
-2. Solar performance: how much the solar system produced and what self-sufficiency % means for the homeowner (e.g. ""Your solar system covered X% of your home's energy needs""). Do NOT mention battery here. Do NOT mention raw grid import kWh.
-3. Battery: comment on battery utilization and efficiency. If efficiency < 80%, note it may need attention.
-4. Tip: one specific actionable suggestion based on the weakest metric: {weakMetric}.{weatherTipHint} If general, suggest the most impactful habit change based on the numbers above.
+2. Energy independence: state the self-sufficiency percentage and what it means — X% of the home's energy came from the combined solar and battery system, only Y% was purchased from the grid. Do NOT repeat raw grid import kWh.
+3. Solar production: state how much the solar system produced this month and the daily average. Keep it factual. Do NOT repeat self-sufficiency percentage here.
+4. Battery: comment on battery utilization and efficiency. If efficiency < 80%, note it may need attention. Do NOT repeat self-sufficiency percentage here.
+5. Tip: one specific actionable suggestion based on the weakest metric: {weakMetric}.{weatherTipHint} If general, suggest the most impactful habit change based on the numbers above.
-Rules: Write in {langName}. Write for a homeowner, not a technician. No asterisks or formatting marks. No closing remarks. Exactly 4 bullet points starting with ""- "". Each bullet must have a short title followed by colon then description.";
+Rules: Write in {langName}. Write for a homeowner, not a technician. No asterisks or formatting marks. No closing remarks. Exactly 5 bullet points starting with ""- "". Each bullet must have a short title followed by colon then description.";
return await CallMistralAsync(apiKey, prompt);
}
@@ -774,7 +775,7 @@ Rules: Write in {langName}. Write for a homeowner, not a technician. No asterisk
var langName = GetLanguageName(language);
var prompt = $@"You are an energy advisor for a sodistore home installation: ""{installationName}"".
-Write a concise annual performance summary in {langName} (4 bullet points, plain text, no markdown).
+Write a concise annual performance summary in {langName} (5 bullet points, plain text, no markdown).
ANNUAL FACTS for {year} ({monthCount} months of data):
- Total PV production: {totalPv:F1} kWh
@@ -787,11 +788,12 @@ ANNUAL FACTS for {year} ({monthCount} months of data):
INSTRUCTIONS:
1. Annual savings highlight: total energy and money saved for the year. Use the exact numbers provided.
-2. System performance: comment on PV production and battery health indicators.
-3. Year-over-year readiness: note any trends or areas of improvement.
-4. Looking ahead: one strategic recommendation for the coming year.
+2. Energy independence: state the self-sufficiency percentage — X% of the home's energy came from the combined solar and battery system. Do NOT repeat raw grid import kWh.
+3. Solar production: state total PV production for the year. Keep it factual. Do NOT repeat self-sufficiency percentage here.
+4. Battery: comment on battery efficiency. If efficiency < 80%, note it may need attention. Do NOT repeat self-sufficiency percentage here.
+5. Looking ahead: one strategic recommendation for the coming year.
-Rules: Write in {langName}. Write for a homeowner. No asterisks or formatting marks. No closing remarks. Exactly 4 bullet points starting with ""- "". Each bullet must have a short title followed by colon then description.";
+Rules: Write in {langName}. Write for a homeowner. No asterisks or formatting marks. No closing remarks. Exactly 5 bullet points starting with ""- "". Each bullet must have a short title followed by colon then description.";
return await CallMistralAsync(apiKey, prompt);
}
diff --git a/csharp/App/Backend/Services/ReportEmailService.cs b/csharp/App/Backend/Services/ReportEmailService.cs
index 17ba54397..1026b3aaf 100644
--- a/csharp/App/Backend/Services/ReportEmailService.cs
+++ b/csharp/App/Backend/Services/ReportEmailService.cs
@@ -105,8 +105,8 @@ public static class ReportEmailService
StayedAtHome: "Solar + Batterie, nicht vom Netz",
EstMoneySaved: "Geschätzte Ersparnis",
AtRate: "bei 0.39 CHF/kWh",
- SolarCoverage: "Eigenversorgung",
- FromSolar: "aus Solar + Batterie",
+ SolarCoverage: "Energieunabhängigkeit",
+ FromSolar: "aus eigenem Solar + Batterie System",
BatteryEff: "Batterie-Eff.",
OutVsIn: "Entladung vs. Ladung",
Day: "Tag",
@@ -135,8 +135,8 @@ public static class ReportEmailService
StayedAtHome: "solaire + batterie, non achetée au réseau",
EstMoneySaved: "Économies estimées",
AtRate: "à 0.39 CHF/kWh",
- SolarCoverage: "Autosuffisance",
- FromSolar: "du solaire + batterie",
+ SolarCoverage: "Indépendance énergétique",
+ FromSolar: "de votre système solaire + batterie",
BatteryEff: "Eff. batterie",
OutVsIn: "décharge vs charge",
Day: "Jour",
@@ -165,8 +165,8 @@ public static class ReportEmailService
StayedAtHome: "solare + batteria, non acquistata dalla rete",
EstMoneySaved: "Risparmio stimato",
AtRate: "a 0.39 CHF/kWh",
- SolarCoverage: "Autosufficienza",
- FromSolar: "da solare + batteria",
+ SolarCoverage: "Indipendenza energetica",
+ FromSolar: "dal proprio impianto solare + batteria",
BatteryEff: "Eff. batteria",
OutVsIn: "scarica vs carica",
Day: "Giorno",
@@ -195,8 +195,8 @@ public static class ReportEmailService
StayedAtHome: "solar + battery, not bought from grid",
EstMoneySaved: "Est. Money Saved",
AtRate: "at 0.39 CHF/kWh",
- SolarCoverage: "Self-Sufficiency",
- FromSolar: "from solar + battery",
+ SolarCoverage: "Energy Independence",
+ FromSolar: "from your own solar + battery system",
BatteryEff: "Battery Eff.",
OutVsIn: "discharge vs charge",
Day: "Day",
@@ -534,49 +534,49 @@ public static class ReportEmailService
"Monatlicher Leistungsbericht", "Monatliche Erkenntnisse", "Monatliche Zusammenfassung", "Ihre Ersparnisse diesen Monat",
"Kennzahl", "Gesamt", "PV-Produktion", "Verbrauch", "Netzbezug", "Netzeinspeisung", "Batterie Laden / Entladen",
"Energie gespart", "Solar + Batterie, nicht vom Netz", "Geschätzte Ersparnis", "bei 0.39 CHF/kWh",
- "Eigenversorgung", "aus Solar + Batterie", "Batterie-Eff.", "Entladung vs. Ladung",
+ "Energieunabhängigkeit", "aus eigenem Solar + Batterie System", "Batterie-Eff.", "Entladung vs. Ladung",
"Tage aggregiert", "Erstellt von inesco Energy Monitor"),
("de", "yearly") => new AggregatedEmailStrings(
"Jährlicher Leistungsbericht", "Jährliche Erkenntnisse", "Jährliche Zusammenfassung", "Ihre Ersparnisse dieses Jahr",
"Kennzahl", "Gesamt", "PV-Produktion", "Verbrauch", "Netzbezug", "Netzeinspeisung", "Batterie Laden / Entladen",
"Energie gespart", "Solar + Batterie, nicht vom Netz", "Geschätzte Ersparnis", "bei 0.39 CHF/kWh",
- "Eigenversorgung", "aus Solar + Batterie", "Batterie-Eff.", "Entladung vs. Ladung",
+ "Energieunabhängigkeit", "aus eigenem Solar + Batterie System", "Batterie-Eff.", "Entladung vs. Ladung",
"Monate aggregiert", "Erstellt von inesco Energy Monitor"),
("fr", "monthly") => new AggregatedEmailStrings(
"Rapport de performance mensuel", "Aperçus du mois", "Résumé du mois", "Vos économies ce mois",
"Indicateur", "Total", "Production PV", "Consommation", "Import réseau", "Export réseau", "Batterie Charge / Décharge",
"Énergie économisée", "solaire + batterie, non achetée au réseau", "Économies estimées", "à 0.39 CHF/kWh",
- "Autosuffisance", "du solaire + batterie", "Eff. batterie", "décharge vs charge",
+ "Indépendance énergétique", "de votre système solaire + batterie", "Eff. batterie", "décharge vs charge",
"jours agrégés", "Généré par inesco Energy Monitor"),
("fr", "yearly") => new AggregatedEmailStrings(
"Rapport de performance annuel", "Aperçus de l'année", "Résumé de l'année", "Vos économies cette année",
"Indicateur", "Total", "Production PV", "Consommation", "Import réseau", "Export réseau", "Batterie Charge / Décharge",
"Énergie économisée", "solaire + batterie, non achetée au réseau", "Économies estimées", "à 0.39 CHF/kWh",
- "Autosuffisance", "du solaire + batterie", "Eff. batterie", "décharge vs charge",
+ "Indépendance énergétique", "de votre système solaire + batterie", "Eff. batterie", "décharge vs charge",
"mois agrégés", "Généré par inesco Energy Monitor"),
("it", "monthly") => new AggregatedEmailStrings(
"Rapporto mensile delle prestazioni", "Approfondimenti mensili", "Riepilogo mensile", "I tuoi risparmi questo mese",
"Metrica", "Totale", "Produzione PV", "Consumo", "Import dalla rete", "Export nella rete", "Batteria Carica / Scarica",
"Energia risparmiata", "solare + batteria, non acquistata dalla rete", "Risparmio stimato", "a 0.39 CHF/kWh",
- "Autosufficienza", "da solare + batteria", "Eff. batteria", "scarica vs carica",
+ "Indipendenza energetica", "dal proprio impianto solare + batteria", "Eff. batteria", "scarica vs carica",
"giorni aggregati", "Generato da inesco Energy Monitor"),
("it", "yearly") => new AggregatedEmailStrings(
"Rapporto annuale delle prestazioni", "Approfondimenti annuali", "Riepilogo annuale", "I tuoi risparmi quest'anno",
"Metrica", "Totale", "Produzione PV", "Consumo", "Import dalla rete", "Export nella rete", "Batteria Carica / Scarica",
"Energia risparmiata", "solare + batteria, non acquistata dalla rete", "Risparmio stimato", "a 0.39 CHF/kWh",
- "Autosufficienza", "da solare + batteria", "Eff. batteria", "scarica vs carica",
+ "Indipendenza energetica", "dal proprio impianto solare + batteria", "Eff. batteria", "scarica vs carica",
"mesi aggregati", "Generato da inesco Energy Monitor"),
(_, "monthly") => new AggregatedEmailStrings(
"Monthly Performance Report", "Monthly Insights", "Monthly Summary", "Your Savings This Month",
"Metric", "Total", "PV Production", "Consumption", "Grid Import", "Grid Export", "Battery Charge / Discharge",
"Energy Saved", "solar + battery, not bought from grid", "Est. Money Saved", "at 0.39 CHF/kWh",
- "Self-Sufficiency", "from solar + battery", "Battery Eff.", "discharge vs charge",
+ "Energy Independence", "from your own solar + battery system", "Battery Eff.", "discharge vs charge",
"days aggregated", "Generated by inesco Energy Monitor"),
_ => new AggregatedEmailStrings(
"Annual Performance Report", "Annual Insights", "Annual Summary", "Your Savings This Year",
"Metric", "Total", "PV Production", "Consumption", "Grid Import", "Grid Export", "Battery Charge / Discharge",
"Energy Saved", "solar + battery, not bought from grid", "Est. Money Saved", "at 0.39 CHF/kWh",
- "Self-Sufficiency", "from solar + battery", "Battery Eff.", "discharge vs charge",
+ "Energy Independence", "from your own solar + battery system", "Battery Eff.", "discharge vs charge",
"months aggregated", "Generated by inesco Energy Monitor")
};
diff --git a/typescript/frontend-marios2/src/content/dashboards/SodiohomeInstallations/WeeklyReport.tsx b/typescript/frontend-marios2/src/content/dashboards/SodiohomeInstallations/WeeklyReport.tsx
index b5cc1eae4..2779bb4dd 100644
--- a/typescript/frontend-marios2/src/content/dashboards/SodiohomeInstallations/WeeklyReport.tsx
+++ b/typescript/frontend-marios2/src/content/dashboards/SodiohomeInstallations/WeeklyReport.tsx
@@ -703,7 +703,7 @@ function WeeklyHistory({ installationId, latestMonthlyPeriodEnd, currentReportPe
{rec.selfSufficiencyPercent.toFixed(0)}%
-
+
@@ -798,6 +798,7 @@ function MonthlySection({
countFn={(r: MonthlyReport) => r.weekCount}
sendEndpoint="/SendMonthlyReportEmail"
sendParamsFn={(r: MonthlyReport) => ({ installationId, year: r.year, month: r.month })}
+ onRegenerate={(r: MonthlyReport) => onGenerate(r.year, r.month)}
/>
) : pendingMonths.length === 0 ? (
@@ -871,6 +872,7 @@ function YearlySection({
countFn={(r: YearlyReport) => r.monthCount}
sendEndpoint="/SendYearlyReportEmail"
sendParamsFn={(r: YearlyReport) => ({ installationId, year: r.year })}
+ onRegenerate={(r: YearlyReport) => onGenerate(r.year)}
/>
) : pendingYears.length === 0 ? (
@@ -890,7 +892,8 @@ function AggregatedSection({
countLabelId,
countFn,
sendEndpoint,
- sendParamsFn
+ sendParamsFn,
+ onRegenerate
}: {
reports: T[];
type: 'monthly' | 'yearly';
@@ -899,9 +902,11 @@ function AggregatedSection({
countFn: (r: T) => number;
sendEndpoint: string;
sendParamsFn: (r: T) => object;
+ onRegenerate?: (r: T) => void | Promise;
}) {
const intl = useIntl();
const [selectedIdx, setSelectedIdx] = useState(0);
+ const [regenerating, setRegenerating] = useState(false);
if (reports.length === 0) {
return (
@@ -947,7 +952,22 @@ function AggregatedSection({
))}
)}
-
+
+ {onRegenerate && (
+ : }
+ onClick={async () => {
+ setRegenerating(true);
+ try { await onRegenerate(r); } finally { setRegenerating(false); }
+ }}
+ sx={{ textTransform: 'none' }}
+ >
+
+
+ )}
diff --git a/typescript/frontend-marios2/src/lang/de.json b/typescript/frontend-marios2/src/lang/de.json
index e1bb76518..21520c77f 100644
--- a/typescript/frontend-marios2/src/lang/de.json
+++ b/typescript/frontend-marios2/src/lang/de.json
@@ -107,8 +107,8 @@
"daysOfYourUsage": "Tage Ihres Verbrauchs",
"estMoneySaved": "Geschätzte Ersparnisse",
"atCHFRate": "bei 0,39 CHF/kWh Ø",
- "solarCoverage": "Eigenversorgung",
- "fromSolarSub": "aus Solar + Batterie",
+ "solarCoverage": "Energieunabhängigkeit",
+ "fromSolarSub": "aus eigenem Solar + Batterie System",
"avgDailyConsumption": "Ø Tagesverbrauch",
"batteryEfficiency": "Batterieeffizienz",
"batteryEffSub": "Entladung vs. Ladung",
@@ -172,6 +172,7 @@
"availableForGeneration": "Zur Generierung verfügbar",
"generateMonth": "{month} {year} generieren ({count} Wochen)",
"generateYear": "{year} generieren ({count} Monate)",
+ "regenerateReport": "Neu generieren",
"generatingMonthly": "Wird generiert...",
"generatingYearly": "Wird generiert...",
"thisMonthWeeklyReports": "Wöchentliche Berichte dieses Monats",
diff --git a/typescript/frontend-marios2/src/lang/en.json b/typescript/frontend-marios2/src/lang/en.json
index dc98ed539..3729d5718 100644
--- a/typescript/frontend-marios2/src/lang/en.json
+++ b/typescript/frontend-marios2/src/lang/en.json
@@ -89,8 +89,8 @@
"daysOfYourUsage": "days of your usage",
"estMoneySaved": "Est. Money Saved",
"atCHFRate": "at 0.39 CHF/kWh avg.",
- "solarCoverage": "Self-Sufficiency",
- "fromSolarSub": "from solar + battery",
+ "solarCoverage": "Energy Independence",
+ "fromSolarSub": "from your own solar + battery system",
"avgDailyConsumption": "Avg Daily Consumption",
"batteryEfficiency": "Battery Efficiency",
"batteryEffSub": "discharge vs charge",
@@ -154,6 +154,7 @@
"availableForGeneration": "Available for Generation",
"generateMonth": "Generate {month} {year} ({count} weeks)",
"generateYear": "Generate {year} ({count} months)",
+ "regenerateReport": "Regenerate",
"generatingMonthly": "Generating...",
"generatingYearly": "Generating...",
"thisMonthWeeklyReports": "This Month's Weekly Reports",
diff --git a/typescript/frontend-marios2/src/lang/fr.json b/typescript/frontend-marios2/src/lang/fr.json
index 4a905fd80..afd01a19d 100644
--- a/typescript/frontend-marios2/src/lang/fr.json
+++ b/typescript/frontend-marios2/src/lang/fr.json
@@ -101,8 +101,8 @@
"daysOfYourUsage": "jours de votre consommation",
"estMoneySaved": "Économies estimées",
"atCHFRate": "à 0,39 CHF/kWh moy.",
- "solarCoverage": "Autosuffisance",
- "fromSolarSub": "du solaire + batterie",
+ "solarCoverage": "Indépendance énergétique",
+ "fromSolarSub": "de votre système solaire + batterie",
"avgDailyConsumption": "Conso. quotidienne moy.",
"batteryEfficiency": "Efficacité de la batterie",
"batteryEffSub": "décharge vs charge",
@@ -166,6 +166,7 @@
"availableForGeneration": "Disponible pour génération",
"generateMonth": "Générer {month} {year} ({count} semaines)",
"generateYear": "Générer {year} ({count} mois)",
+ "regenerateReport": "Régénérer",
"generatingMonthly": "Génération en cours...",
"generatingYearly": "Génération en cours...",
"thisMonthWeeklyReports": "Rapports hebdomadaires de ce mois",
diff --git a/typescript/frontend-marios2/src/lang/it.json b/typescript/frontend-marios2/src/lang/it.json
index 0ca4aac38..7087c6551 100644
--- a/typescript/frontend-marios2/src/lang/it.json
+++ b/typescript/frontend-marios2/src/lang/it.json
@@ -112,8 +112,8 @@
"daysOfYourUsage": "giorni del tuo consumo",
"estMoneySaved": "Risparmio stimato",
"atCHFRate": "a 0,39 CHF/kWh media",
- "solarCoverage": "Autosufficienza",
- "fromSolarSub": "da solare + batteria",
+ "solarCoverage": "Indipendenza energetica",
+ "fromSolarSub": "dal proprio impianto solare + batteria",
"avgDailyConsumption": "Consumo medio giornaliero",
"batteryEfficiency": "Efficienza della batteria",
"batteryEffSub": "scarica vs carica",
@@ -177,6 +177,7 @@
"availableForGeneration": "Disponibile per la generazione",
"generateMonth": "Genera {month} {year} ({count} settimane)",
"generateYear": "Genera {year} ({count} mesi)",
+ "regenerateReport": "Rigenera",
"generatingMonthly": "Generazione in corso...",
"generatingYearly": "Generazione in corso...",
"thisMonthWeeklyReports": "Rapporti settimanali di questo mese",