From 5f91b48df1d63151568a672b4751277244c9e375 Mon Sep 17 00:00:00 2001 From: Paul Frank Date: Thu, 4 Jan 2024 14:31:33 +0000 Subject: [PATCH] Improve cost, profit in forecast --- src/translations/de.json | 7 +- src/translations/en.json | 7 +- src/views/Forecast.vue | 156 ++++++++++++++++++++++++++++++--------- 3 files changed, 134 insertions(+), 36 deletions(-) diff --git a/src/translations/de.json b/src/translations/de.json index edcfb39..6336915 100644 --- a/src/translations/de.json +++ b/src/translations/de.json @@ -44,7 +44,12 @@ "pv": "PV", "consumption": "Basisverbrauch Vorhersage", "pv_forecast": "PV Vorhersage", - "no_var_loads": "Basisverbrauch" + "no_var_loads": "Basisverbrauch", + "summary": "Zusammenfassung", + "total_cost": "Total Kosten", + "total_profit": "Total Profit", + "energy": "Energie", + "cost_profit": "Kosten oder Profit" }, "power_mode": { "device_controlled": "Vom Gerät gesteuert", diff --git a/src/translations/en.json b/src/translations/en.json index a14fde7..6d984fa 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -44,7 +44,12 @@ "pv": "PV", "consumption": "Non variable loads forecast", "pv_forecast": "PV forecast", - "no_var_loads": "Non variable loads" + "no_var_loads": "Non variable loads", + "summary": "Summary", + "total_cost": "Total cost", + "total_profit": "Total profit", + "energy": "Energy", + "cost_profit": "Cost or profit" }, "power_mode": { "device_controlled": "Device controlled", diff --git a/src/views/Forecast.vue b/src/views/Forecast.vue index 010cdf6..b1da1b3 100644 --- a/src/views/Forecast.vue +++ b/src/views/Forecast.vue @@ -2,8 +2,37 @@
-
- +
+ + + {{ $t('forecast.summary') }} + + +
{{ costTotalProfitLabel }}
+
+
+ + + + {{ $t('forecast.energy') }} + + +
+ +
+
+
+ + + {{ $t('forecast.cost_profit') }} + + +
+ +
+
+
+
@@ -28,8 +57,9 @@ import { useTheme } from 'vuetify'; import { color } from 'chart.js/helpers'; import { Result } from 'postcss'; import { $t } from '@/plugins/i18n'; +import { servicesVersion } from 'typescript'; -const { t } = useI18n(); +//const { t } = useI18n(); const theme = useTheme(); const forecast = ref(); @@ -81,11 +111,11 @@ function getDataSetColor(name: string) { function getDataSetLabel(name: string) { switch (name) { case 'pv': - return t('forecast.pv'); + return $t('forecast.pv'); case 'pv_forecast': - return t('forecast.pv_forecast'); + return $t('forecast.pv_forecast'); case 'consumption': - return t('forecast.consumption'); + return $t('forecast.consumption'); case 'no_var_loads': return $t('forecast.no_var_loads'); default: @@ -96,21 +126,10 @@ function getDataSetLabel(name: string) { function getDataSets(forecast: IForecast) { if (forecast && forecast.series) { let colorIterator = new ColorIterator(); - return forecast.series.map((serie) => { - if (serie.name == 'pv' || serie.name == 'no_var_loads') { - let color = getDataSetColor(serie.name); - return { - label: getDataSetLabel(serie.name), - data: serie.data, - fill: false, - backgroundColor: color, - borderColor: color, - borderDash: [5, 5], - borderWidth: 2, - pointStyle: false, - }; - } else { - if (serie.name == 'pv_forecast' || serie.name == 'consumption') { + return forecast.series + .filter((serie) => serie.name != 'cost_profit') + .map((serie) => { + if (serie.name == 'pv' || serie.name == 'no_var_loads') { let color = getDataSetColor(serie.name); return { label: getDataSetLabel(serie.name), @@ -118,24 +137,60 @@ function getDataSets(forecast: IForecast) { fill: false, backgroundColor: color, borderColor: color, + borderDash: [5, 5], borderWidth: 2, pointStyle: false, }; } else { - let color = colorIterator.getNextColor(); - return { - label: getDataSetLabel(serie.name), - data: serie.data, - fill: false, - backgroundColor: color, - borderColor: color, - stepped: true, - borderWidth: 2, - pointStyle: false, - }; + if (serie.name == 'pv_forecast' || serie.name == 'consumption') { + let color = getDataSetColor(serie.name); + return { + label: getDataSetLabel(serie.name), + data: serie.data, + fill: false, + backgroundColor: color, + borderColor: color, + borderWidth: 2, + pointStyle: false, + }; + } else { + let color = colorIterator.getNextColor(); + return { + label: getDataSetLabel(serie.name), + data: serie.data, + fill: false, + backgroundColor: color, + borderColor: color, + stepped: true, + borderWidth: 2, + pointStyle: false, + }; + } } - } - }); + }); + } + + return []; +} + +function getCostProfitDataSets(forecast: IForecast) { + if (forecast && forecast.series) { + let colorIterator = new ColorIterator(); + return forecast.series + .filter((serie) => serie.name == 'cost_profit') + .map((serie) => { + const color = 'blue'; + return { + label: 'Cost / Profit', + data: serie.data, + fill: false, + backgroundColor: color, + borderColor: color, + borderWidth: 2, + pointStyle: false, + stepped: true, + }; + }); } return []; @@ -153,6 +208,39 @@ const data = computed(() => { }; }); +const costProfitData = computed(() => { + return { + labels: forecast.value?.time.map((t) => + new Date(t).toLocaleTimeString([], { + hour: '2-digit', + minute: '2-digit', + }), + ), + datasets: getCostProfitDataSets(forecast.value), + }; +}); + +const costTotalProfitLabel = computed(() => { + const profitSerie = forecast.value?.series.filter( + (serie) => serie.name == 'cost_profit', + )[0].data; + + const totalCostProfit = profitSerie?.reduce( + (accumulator, currentValue) => accumulator + currentValue, + 0, + ); + + if (totalCostProfit) { + if (totalCostProfit < 0) { + return $t('forecast.total_cost') + ': ' + -totalCostProfit.toFixed(2); + } else { + return $t('forecast.total_profit') + ': ' + totalCostProfit.toFixed(2); + } + } else { + return 'unknown'; + } +}); + const options = { responsive: true, maintainAspectRatio: false,