fixed monthly and yearly report overlap issue of PV and Battery performance
This commit is contained in:
parent
6cf14e3483
commit
ac034b9983
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <strong style=\"color:#666\">inesco Energy Monitor</strong>"),
|
||||
("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 <strong style=\"color:#666\">inesco Energy Monitor</strong>"),
|
||||
("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 <strong style=\"color:#666\">inesco Energy Monitor</strong>"),
|
||||
("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 <strong style=\"color:#666\">inesco Energy Monitor</strong>"),
|
||||
("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 <strong style=\"color:#666\">inesco Energy Monitor</strong>"),
|
||||
("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 <strong style=\"color:#666\">inesco Energy Monitor</strong>"),
|
||||
(_, "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 <strong style=\"color:#666\">inesco Energy Monitor</strong>"),
|
||||
_ => 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 <strong style=\"color:#666\">inesco Energy Monitor</strong>")
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -703,7 +703,7 @@ function WeeklyHistory({ installationId, latestMonthlyPeriodEnd, currentReportPe
|
|||
<Grid item xs={6} sm={3}>
|
||||
<Box sx={{ textAlign: 'center' }}>
|
||||
<Typography variant="body1" fontWeight="bold" color="#8e44ad">{rec.selfSufficiencyPercent.toFixed(0)}%</Typography>
|
||||
<Typography variant="caption" color="#888"><FormattedMessage id="solarCoverage" defaultMessage="Self-Sufficiency" /></Typography>
|
||||
<Typography variant="caption" color="#888"><FormattedMessage id="solarCoverage" defaultMessage="Energy Independence" /></Typography>
|
||||
</Box>
|
||||
</Grid>
|
||||
<Grid item xs={6} sm={3}>
|
||||
|
|
@ -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 ? (
|
||||
<Alert severity="info">
|
||||
|
|
@ -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 ? (
|
||||
<Alert severity="info">
|
||||
|
|
@ -890,7 +892,8 @@ function AggregatedSection<T extends ReportSummary>({
|
|||
countLabelId,
|
||||
countFn,
|
||||
sendEndpoint,
|
||||
sendParamsFn
|
||||
sendParamsFn,
|
||||
onRegenerate
|
||||
}: {
|
||||
reports: T[];
|
||||
type: 'monthly' | 'yearly';
|
||||
|
|
@ -899,9 +902,11 @@ function AggregatedSection<T extends ReportSummary>({
|
|||
countFn: (r: T) => number;
|
||||
sendEndpoint: string;
|
||||
sendParamsFn: (r: T) => object;
|
||||
onRegenerate?: (r: T) => void | Promise<void>;
|
||||
}) {
|
||||
const intl = useIntl();
|
||||
const [selectedIdx, setSelectedIdx] = useState(0);
|
||||
const [regenerating, setRegenerating] = useState(false);
|
||||
|
||||
if (reports.length === 0) {
|
||||
return (
|
||||
|
|
@ -947,7 +952,22 @@ function AggregatedSection<T extends ReportSummary>({
|
|||
))}
|
||||
</Select>
|
||||
)}
|
||||
<Box sx={{ ml: 'auto' }}>
|
||||
<Box sx={{ ml: 'auto', display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
{onRegenerate && (
|
||||
<Button
|
||||
variant="outlined"
|
||||
size="small"
|
||||
disabled={regenerating}
|
||||
startIcon={regenerating ? <CircularProgress size={14} /> : <RefreshIcon />}
|
||||
onClick={async () => {
|
||||
setRegenerating(true);
|
||||
try { await onRegenerate(r); } finally { setRegenerating(false); }
|
||||
}}
|
||||
sx={{ textTransform: 'none' }}
|
||||
>
|
||||
<FormattedMessage id="regenerateReport" defaultMessage="Regenerate" />
|
||||
</Button>
|
||||
)}
|
||||
<EmailBar onSend={handleSendEmail} />
|
||||
</Box>
|
||||
</Box>
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Reference in New Issue