Added Aggregated data (weekly and monthly)
Added set date button Added Zoom in Zoom out buttons
This commit is contained in:
parent
cacf6f7bb1
commit
4580214565
|
@ -23,6 +23,10 @@ public static partial class Db
|
||||||
.OrderBy(f => f.LastWriteTime)
|
.OrderBy(f => f.LastWriteTime)
|
||||||
.Last().Name;
|
.Last().Name;
|
||||||
|
|
||||||
|
Console.WriteLine("latestdb is "+latestDb);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//This is the file connection from the DbBackups folder
|
//This is the file connection from the DbBackups folder
|
||||||
var fileConnection = new SQLiteConnection("DbBackups/" + latestDb);
|
var fileConnection = new SQLiteConnection("DbBackups/" + latestDb);
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ public static class Aggregator
|
||||||
Console.WriteLine("-----------------------------------------------------------------------------------------------------------------");
|
Console.WriteLine("-----------------------------------------------------------------------------------------------------------------");
|
||||||
|
|
||||||
// Wait until the next rounded hour
|
// Wait until the next rounded hour
|
||||||
await Task.Delay(timeUntilNextDay);
|
//await Task.Delay(timeUntilNextDay);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -68,8 +68,8 @@ public static class Aggregator
|
||||||
dailyAggregatedData.Save("DailyData");
|
dailyAggregatedData.Save("DailyData");
|
||||||
if (await dailyAggregatedData.PushToS3())
|
if (await dailyAggregatedData.PushToS3())
|
||||||
{
|
{
|
||||||
DeleteHourlyData("HourlyData",currentTime.ToUnixTime());
|
//DeleteHourlyData("HourlyData",currentTime.ToUnixTime());
|
||||||
dailyAggregatedData.DeleteDailyData("DailyData");
|
//dailyAggregatedData.DeleteDailyData("DailyData");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
npm run build && rsync -rv .* ubuntu@91.92.154.141:~/frontend/ && ssh ubuntu@91.92.154.141 'sudo cp -rf ~/frontend/build/* /var/www/html/stage.innov.energy/html/' && ssh ubuntu@91.92.154.141 'sudo npm install -g serve'
|
|
@ -1,9 +1,12 @@
|
||||||
export function formatPowerForGraph(value, max): { value: number } {
|
export function formatPowerForGraph(value, magnitude): { value: number } {
|
||||||
if (isNaN(value)) {
|
if (isNaN(value)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const prefixes = ['', 'k', 'M', 'G', 'T'];
|
||||||
|
|
||||||
let negative = false;
|
let negative = false;
|
||||||
if (max > 1000) {
|
if (magnitude > 0) {
|
||||||
value = parseFloat(value);
|
value = parseFloat(value);
|
||||||
|
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
|
@ -11,10 +14,9 @@ export function formatPowerForGraph(value, max): { value: number } {
|
||||||
negative = true;
|
negative = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = value / 1000;
|
while (magnitude > 0) {
|
||||||
|
|
||||||
while (value >= 1000) {
|
|
||||||
value /= 1000;
|
value /= 1000;
|
||||||
|
magnitude--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
// chartOptions.ts
|
|
||||||
|
|
||||||
import { ApexOptions } from 'apexcharts';
|
import { ApexOptions } from 'apexcharts';
|
||||||
import { chartInfoInterface } from 'src/interfaces/Chart';
|
import { chartInfoInterface } from 'src/interfaces/Chart';
|
||||||
import { findPower, formatPowerForGraph } from 'src/Resources/formatPower';
|
import { findPower, formatPowerForGraph } from 'src/Resources/formatPower';
|
||||||
|
|
||||||
export const getChartOptions = (
|
export const getChartOptions = (
|
||||||
chartInfo: chartInfoInterface,
|
chartInfo: chartInfoInterface,
|
||||||
type: string
|
type: string,
|
||||||
|
dateList: string[]
|
||||||
): ApexOptions => {
|
): ApexOptions => {
|
||||||
const chartOptions: ApexOptions =
|
return type.includes('daily')
|
||||||
type == 'daily'
|
|
||||||
? {
|
? {
|
||||||
chart: {
|
chart: {
|
||||||
id: 'area-datetime',
|
id: 'area-datetime',
|
||||||
|
@ -27,18 +25,7 @@ export const getChartOptions = (
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
|
|
||||||
fill: {
|
colors: ['#3498db', '#2ecc71', '#282828'],
|
||||||
type: 'gradient',
|
|
||||||
gradient: {
|
|
||||||
shadeIntensity: 1,
|
|
||||||
opacityFrom: 0.7,
|
|
||||||
opacityTo: 0.9,
|
|
||||||
stops: [0, 100]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//colors: ['#FF5733', '#3498db'],
|
|
||||||
colors: ['#3498db', '#2ecc71'],
|
|
||||||
//colors: ['#1abc9c', '#e91e63'],
|
|
||||||
xaxis: {
|
xaxis: {
|
||||||
type: 'datetime',
|
type: 'datetime',
|
||||||
labels: {
|
labels: {
|
||||||
|
@ -55,18 +42,24 @@ export const getChartOptions = (
|
||||||
curve: 'smooth',
|
curve: 'smooth',
|
||||||
width: 2
|
width: 2
|
||||||
},
|
},
|
||||||
yaxis: {
|
yaxis:
|
||||||
|
type === 'dailyoverview'
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
seriesName: 'Grid Power',
|
||||||
min:
|
min:
|
||||||
chartInfo.min >= 0
|
chartInfo.min >= 0
|
||||||
? 0
|
? 0
|
||||||
: chartInfo.max <= 0
|
: chartInfo.max <= 0
|
||||||
? Math.ceil(chartInfo.min / findPower(chartInfo.min).value) *
|
? Math.ceil(
|
||||||
findPower(chartInfo.min).value
|
chartInfo.min / findPower(chartInfo.min).value
|
||||||
|
) * findPower(chartInfo.min).value
|
||||||
: undefined,
|
: undefined,
|
||||||
max:
|
max:
|
||||||
chartInfo.min >= 0
|
chartInfo.min >= 0
|
||||||
? Math.ceil(chartInfo.max / findPower(chartInfo.max).value) *
|
? Math.ceil(
|
||||||
findPower(chartInfo.max).value
|
chartInfo.max / findPower(chartInfo.max).value
|
||||||
|
) * findPower(chartInfo.max).value
|
||||||
: chartInfo.max <= 0
|
: chartInfo.max <= 0
|
||||||
? 0
|
? 0
|
||||||
: undefined,
|
: undefined,
|
||||||
|
@ -75,7 +68,7 @@ export const getChartOptions = (
|
||||||
style: {
|
style: {
|
||||||
fontSize: '12px'
|
fontSize: '12px'
|
||||||
},
|
},
|
||||||
offsetY: -160,
|
offsetY: -190,
|
||||||
offsetX: 25,
|
offsetX: 25,
|
||||||
rotate: 0
|
rotate: 0
|
||||||
},
|
},
|
||||||
|
@ -83,7 +76,102 @@ export const getChartOptions = (
|
||||||
formatter: function (value: number) {
|
formatter: function (value: number) {
|
||||||
return formatPowerForGraph(
|
return formatPowerForGraph(
|
||||||
value,
|
value,
|
||||||
Math.max(Math.abs(chartInfo.max), Math.abs(chartInfo.min))
|
chartInfo.magnitude
|
||||||
|
).value.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
seriesName: 'Pv Production',
|
||||||
|
show: false,
|
||||||
|
min:
|
||||||
|
chartInfo.min >= 0
|
||||||
|
? 0
|
||||||
|
: chartInfo.max <= 0
|
||||||
|
? Math.ceil(
|
||||||
|
chartInfo.min / findPower(chartInfo.min).value
|
||||||
|
) * findPower(chartInfo.min).value
|
||||||
|
: undefined,
|
||||||
|
max:
|
||||||
|
chartInfo.min >= 0
|
||||||
|
? Math.ceil(
|
||||||
|
chartInfo.max / findPower(chartInfo.max).value
|
||||||
|
) * findPower(chartInfo.max).value
|
||||||
|
: chartInfo.max <= 0
|
||||||
|
? 0
|
||||||
|
: undefined,
|
||||||
|
title: {
|
||||||
|
text: chartInfo.unit,
|
||||||
|
style: {
|
||||||
|
fontSize: '12px'
|
||||||
|
},
|
||||||
|
offsetY: -190,
|
||||||
|
offsetX: 25,
|
||||||
|
rotate: 0
|
||||||
|
},
|
||||||
|
labels: {
|
||||||
|
formatter: function (value: number) {
|
||||||
|
return formatPowerForGraph(
|
||||||
|
value,
|
||||||
|
chartInfo.magnitude
|
||||||
|
).value.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
seriesName: 'State Of Charge',
|
||||||
|
opposite: true,
|
||||||
|
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
title: {
|
||||||
|
text: '(%)',
|
||||||
|
style: {
|
||||||
|
fontSize: '12px'
|
||||||
|
},
|
||||||
|
offsetY: -190,
|
||||||
|
offsetX: -25,
|
||||||
|
rotate: 0
|
||||||
|
},
|
||||||
|
labels: {
|
||||||
|
formatter: function (value: number) {
|
||||||
|
return formatPowerForGraph(value, 0).value.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
: {
|
||||||
|
min:
|
||||||
|
chartInfo.min >= 0
|
||||||
|
? 0
|
||||||
|
: chartInfo.max <= 0
|
||||||
|
? Math.ceil(
|
||||||
|
chartInfo.min / findPower(chartInfo.min).value
|
||||||
|
) * findPower(chartInfo.min).value
|
||||||
|
: undefined,
|
||||||
|
max:
|
||||||
|
chartInfo.min >= 0
|
||||||
|
? Math.ceil(
|
||||||
|
chartInfo.max / findPower(chartInfo.max).value
|
||||||
|
) * findPower(chartInfo.max).value
|
||||||
|
: chartInfo.max <= 0
|
||||||
|
? 0
|
||||||
|
: undefined,
|
||||||
|
title: {
|
||||||
|
text: chartInfo.unit,
|
||||||
|
style: {
|
||||||
|
fontSize: '12px'
|
||||||
|
},
|
||||||
|
offsetY: -190,
|
||||||
|
offsetX: 25,
|
||||||
|
rotate: 0
|
||||||
|
},
|
||||||
|
labels: {
|
||||||
|
formatter: function (value: number) {
|
||||||
|
return formatPowerForGraph(
|
||||||
|
value,
|
||||||
|
chartInfo.magnitude
|
||||||
).value.toString();
|
).value.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,12 +182,15 @@ export const getChartOptions = (
|
||||||
format: 'dd MMM HH:mm:ss'
|
format: 'dd MMM HH:mm:ss'
|
||||||
},
|
},
|
||||||
y: {
|
y: {
|
||||||
formatter: function (val, opts) {
|
formatter: function (val, { seriesIndex, w }) {
|
||||||
|
const seriesName = w.config.series[seriesIndex].name;
|
||||||
|
if (seriesName === 'State Of Charge') {
|
||||||
|
return val.toFixed(2) + ' %';
|
||||||
|
} else {
|
||||||
return (
|
return (
|
||||||
formatPowerForGraph(
|
formatPowerForGraph(val, chartInfo.magnitude).value.toFixed(
|
||||||
val,
|
2
|
||||||
Math.max(Math.abs(chartInfo.max), Math.abs(chartInfo.min))
|
) +
|
||||||
).value.toFixed(2) +
|
|
||||||
' ' +
|
' ' +
|
||||||
chartInfo.unit
|
chartInfo.unit
|
||||||
);
|
);
|
||||||
|
@ -107,130 +198,26 @@ export const getChartOptions = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
: type == 'monthly'
|
|
||||||
? {
|
|
||||||
chart: {
|
|
||||||
height: 350,
|
|
||||||
type: 'bar'
|
|
||||||
},
|
|
||||||
plotOptions: {
|
|
||||||
bar: {
|
|
||||||
borderRadius: 10,
|
|
||||||
dataLabels: {
|
|
||||||
position: 'top' // top, center, bottom
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dataLabels: {
|
|
||||||
enabled: true,
|
|
||||||
formatter: function (val) {
|
|
||||||
return val + '%';
|
|
||||||
},
|
|
||||||
offsetY: -20,
|
|
||||||
style: {
|
|
||||||
fontSize: '12px',
|
|
||||||
colors: ['#304758']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
xaxis: {
|
|
||||||
categories: [
|
|
||||||
'Jan',
|
|
||||||
'Feb',
|
|
||||||
'Mar',
|
|
||||||
'Apr',
|
|
||||||
'May',
|
|
||||||
'Jun',
|
|
||||||
'Jul',
|
|
||||||
'Aug',
|
|
||||||
'Sep',
|
|
||||||
'Oct',
|
|
||||||
'Nov',
|
|
||||||
'Dec'
|
|
||||||
],
|
|
||||||
position: 'bottom',
|
|
||||||
axisBorder: {
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
axisTicks: {
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
enabled: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
yaxis: {
|
|
||||||
min:
|
|
||||||
chartInfo.min >= 0
|
|
||||||
? 0
|
|
||||||
: chartInfo.max <= 0
|
|
||||||
? Math.ceil(chartInfo.min / findPower(chartInfo.min).value) *
|
|
||||||
findPower(chartInfo.min).value
|
|
||||||
: undefined,
|
|
||||||
max:
|
|
||||||
chartInfo.min >= 0
|
|
||||||
? Math.ceil(chartInfo.max / findPower(chartInfo.max).value) *
|
|
||||||
findPower(chartInfo.max).value
|
|
||||||
: chartInfo.max <= 0
|
|
||||||
? 0
|
|
||||||
: undefined,
|
|
||||||
title: {
|
|
||||||
text: chartInfo.unit,
|
|
||||||
style: {
|
|
||||||
fontSize: '12px'
|
|
||||||
},
|
|
||||||
offsetY: -160,
|
|
||||||
offsetX: 25,
|
|
||||||
rotate: 0
|
|
||||||
},
|
|
||||||
labels: {
|
|
||||||
formatter: function (value: number) {
|
|
||||||
return formatPowerForGraph(
|
|
||||||
value,
|
|
||||||
Math.max(Math.abs(chartInfo.max), Math.abs(chartInfo.min))
|
|
||||||
).value.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// yaxis: {
|
|
||||||
// axisBorder: {
|
|
||||||
// show: false
|
|
||||||
// },
|
|
||||||
// axisTicks: {
|
|
||||||
// show: false
|
|
||||||
// },
|
|
||||||
// labels: {
|
|
||||||
// show: false,
|
|
||||||
// formatter: function (val) {
|
|
||||||
// return val + '%';
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
chart: {
|
chart: {
|
||||||
height: 350,
|
height: 380,
|
||||||
type: 'bar'
|
type: 'bar',
|
||||||
|
stacked: chartInfo.unit !== '(%)' && type != 'overview'
|
||||||
},
|
},
|
||||||
plotOptions: {
|
plotOptions: {
|
||||||
bar: {
|
bar: {
|
||||||
borderRadius: 10,
|
borderRadius: 10,
|
||||||
dataLabels: {
|
dataLabels: {
|
||||||
position: 'top' // top, center, bottom
|
position: 'top'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dataLabels: {
|
dataLabels: {
|
||||||
enabled: true,
|
enabled: false,
|
||||||
formatter: function (val, opts) {
|
formatter: function (val) {
|
||||||
return (
|
return (
|
||||||
formatPowerForGraph(
|
formatPowerForGraph(val, chartInfo.magnitude).value.toFixed(2) +
|
||||||
val,
|
|
||||||
Math.max(Math.abs(chartInfo.max), Math.abs(chartInfo.min))
|
|
||||||
).value.toFixed(2) +
|
|
||||||
' ' +
|
' ' +
|
||||||
chartInfo.unit
|
chartInfo.unit
|
||||||
);
|
);
|
||||||
|
@ -243,7 +230,7 @@ export const getChartOptions = (
|
||||||
},
|
},
|
||||||
|
|
||||||
xaxis: {
|
xaxis: {
|
||||||
categories: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
|
categories: dateList,
|
||||||
position: 'bottom',
|
position: 'bottom',
|
||||||
axisBorder: {
|
axisBorder: {
|
||||||
show: false
|
show: false
|
||||||
|
@ -275,7 +262,7 @@ export const getChartOptions = (
|
||||||
style: {
|
style: {
|
||||||
fontSize: '12px'
|
fontSize: '12px'
|
||||||
},
|
},
|
||||||
offsetY: -160,
|
offsetY: type === 'monthly' ? -176 : -178,
|
||||||
offsetX: 25,
|
offsetX: 25,
|
||||||
rotate: 0
|
rotate: 0
|
||||||
},
|
},
|
||||||
|
@ -283,40 +270,21 @@ export const getChartOptions = (
|
||||||
formatter: function (value: number) {
|
formatter: function (value: number) {
|
||||||
return formatPowerForGraph(
|
return formatPowerForGraph(
|
||||||
value,
|
value,
|
||||||
Math.max(Math.abs(chartInfo.max), Math.abs(chartInfo.min))
|
chartInfo.magnitude
|
||||||
).value.toString();
|
).value.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
y: {
|
y: {
|
||||||
formatter: function (val, opts) {
|
formatter: function (val) {
|
||||||
return (
|
return (
|
||||||
formatPowerForGraph(
|
formatPowerForGraph(val, chartInfo.magnitude).value.toFixed(2) +
|
||||||
val,
|
|
||||||
Math.max(Math.abs(chartInfo.max), Math.abs(chartInfo.min))
|
|
||||||
).value.toFixed(2) +
|
|
||||||
' ' +
|
' ' +
|
||||||
chartInfo.unit
|
chartInfo.unit
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// yaxis: {
|
|
||||||
// axisBorder: {
|
|
||||||
// show: false
|
|
||||||
// },
|
|
||||||
// axisTicks: {
|
|
||||||
// show: false
|
|
||||||
// },
|
|
||||||
// labels: {
|
|
||||||
// show: false,
|
|
||||||
// formatter: function (val) {
|
|
||||||
// return val + '%';
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return chartOptions;
|
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,30 +1,7 @@
|
||||||
import { Maybe } from 'yup';
|
import { Maybe } from 'yup';
|
||||||
import { Timestamped } from './types';
|
import { Timestamped } from './types';
|
||||||
import { isDefined } from './utils/maybe';
|
|
||||||
import { I_CsvEntry } from 'src/content/dashboards/Log/graph.util';
|
import { I_CsvEntry } from 'src/content/dashboards/Log/graph.util';
|
||||||
|
|
||||||
export type DataRecord = Record<string, I_CsvEntry>;
|
export type DataRecord = Record<string, I_CsvEntry>;
|
||||||
export type DataPoint = Timestamped<Maybe<DataRecord>>;
|
export type DataPoint = Timestamped<Maybe<DataRecord>>;
|
||||||
export type RecordSeries = Array<DataPoint>;
|
export type RecordSeries = Array<DataPoint>;
|
||||||
export type DataRecordSeries = Array<DataRecord>;
|
|
||||||
export type PointSeries = Array<Timestamped<Maybe<I_CsvEntry>>>;
|
|
||||||
export type DataSeries = Array<Maybe<I_CsvEntry>>;
|
|
||||||
|
|
||||||
export function getPoints(
|
|
||||||
recordSeries: RecordSeries,
|
|
||||||
series: keyof DataRecord
|
|
||||||
): PointSeries {
|
|
||||||
return recordSeries.map((p) => ({
|
|
||||||
time: p.time,
|
|
||||||
value: isDefined(p.value) ? p.value[series] : undefined
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getData(
|
|
||||||
recordSeries: RecordSeries,
|
|
||||||
series: keyof DataRecord
|
|
||||||
): DataSeries {
|
|
||||||
return recordSeries.map((p) =>
|
|
||||||
isDefined(p.value) ? p.value[series] : undefined
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { ApexOptions } from 'apexcharts';
|
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import {
|
import {
|
||||||
fetchDailyData,
|
fetchDailyData,
|
||||||
|
@ -15,6 +14,7 @@ export interface overviewInterface {
|
||||||
gridPower: chartInfoInterface;
|
gridPower: chartInfoInterface;
|
||||||
pvProduction: chartInfoInterface;
|
pvProduction: chartInfoInterface;
|
||||||
dcBusVoltage: chartInfoInterface;
|
dcBusVoltage: chartInfoInterface;
|
||||||
|
overview: chartInfoInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface chartInfoInterface {
|
export interface chartInfoInterface {
|
||||||
|
@ -25,18 +25,22 @@ export interface chartInfoInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface chartAggregatedDataInterface {
|
export interface chartAggregatedDataInterface {
|
||||||
soc: [{ data: number[] }];
|
minsoc: { name: string; data: number[] };
|
||||||
pvProduction: [{ data: number[] }];
|
maxsoc: { name: string; data: number[] };
|
||||||
dcPower: [{ data: number[] }];
|
pvProduction: { name: string; data: number[] };
|
||||||
|
dcChargingPower: { name: string; data: number[] };
|
||||||
|
dcDischargingPower: { name: string; data: number[] };
|
||||||
|
gridImportPower: { name: string; data: number[] };
|
||||||
|
gridExportPower: { name: string; data: number[] };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface chartDataInterface {
|
export interface chartDataInterface {
|
||||||
soc: ApexOptions['series'];
|
soc: { name: string; data: number[] };
|
||||||
temperature: ApexOptions['series'];
|
temperature: { name: string; data: number[] };
|
||||||
dcPower: ApexOptions['series'];
|
dcPower: { name: string; data: number[] };
|
||||||
gridPower: ApexOptions['series'];
|
gridPower: { name: string; data: number[] };
|
||||||
pvProduction: ApexOptions['series'];
|
pvProduction: { name: string; data: number[] };
|
||||||
dcBusVoltage: ApexOptions['series'];
|
dcBusVoltage: { name: string; data: number[] };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const transformInputToDailyData = async (
|
export const transformInputToDailyData = async (
|
||||||
|
@ -61,12 +65,12 @@ export const transformInputToDailyData = async (
|
||||||
];
|
];
|
||||||
|
|
||||||
const chartData: chartDataInterface = {
|
const chartData: chartDataInterface = {
|
||||||
soc: [],
|
soc: { name: 'State Of Charge', data: [] },
|
||||||
temperature: [],
|
temperature: { name: 'Battery Temperature', data: [] },
|
||||||
dcPower: [],
|
dcPower: { name: 'Battery Power', data: [] },
|
||||||
gridPower: [],
|
gridPower: { name: 'Grid Power', data: [] },
|
||||||
pvProduction: [],
|
pvProduction: { name: 'Pv Production', data: [] },
|
||||||
dcBusVoltage: []
|
dcBusVoltage: { name: 'DC Bus Voltage', data: [] }
|
||||||
};
|
};
|
||||||
|
|
||||||
const chartOverview: overviewInterface = {
|
const chartOverview: overviewInterface = {
|
||||||
|
@ -75,7 +79,8 @@ export const transformInputToDailyData = async (
|
||||||
dcPower: { magnitude: 0, unit: '', min: 0, max: 0 },
|
dcPower: { magnitude: 0, unit: '', min: 0, max: 0 },
|
||||||
gridPower: { magnitude: 0, unit: '', min: 0, max: 0 },
|
gridPower: { magnitude: 0, unit: '', min: 0, max: 0 },
|
||||||
pvProduction: { magnitude: 0, unit: '', min: 0, max: 0 },
|
pvProduction: { magnitude: 0, unit: '', min: 0, max: 0 },
|
||||||
dcBusVoltage: { magnitude: 0, unit: '', min: 0, max: 0 }
|
dcBusVoltage: { magnitude: 0, unit: '', min: 0, max: 0 },
|
||||||
|
overview: { magnitude: 0, unit: '', min: 0, max: 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
pathsToSearch.forEach((path) => {
|
pathsToSearch.forEach((path) => {
|
||||||
|
@ -88,25 +93,14 @@ export const transformInputToDailyData = async (
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// const currentTimestamp = UnixTime.now();
|
|
||||||
// const twentyFourHoursAgoRange = currentTimestamp.rangeBefore(
|
|
||||||
// TimeSpan.fromDays(1)
|
|
||||||
// );
|
|
||||||
|
|
||||||
let startTimestampToNum = Number(startTimestamp);
|
let startTimestampToNum = Number(startTimestamp);
|
||||||
if (startTimestampToNum % 2 != 0) {
|
if (startTimestampToNum % 2 != 0) {
|
||||||
startTimestampToNum += 1;
|
startTimestampToNum += 1;
|
||||||
}
|
}
|
||||||
let startUnixTime = UnixTime.fromTicks(startTimestampToNum);
|
let startUnixTime = UnixTime.fromTicks(startTimestampToNum);
|
||||||
|
|
||||||
let diff = endTimestamp.ticks - startUnixTime.ticks;
|
let diff = endTimestamp.ticks - startUnixTime.ticks;
|
||||||
|
|
||||||
//console.log('Current Unix Timestamp:', currentTimestamp);
|
|
||||||
//console.log('Unix Timestamp 24 hours ago (even):', startTimestamp);
|
|
||||||
|
|
||||||
while (startUnixTime < endTimestamp) {
|
while (startUnixTime < endTimestamp) {
|
||||||
// console.log('Current day:', currentDay.format('YYYY-MM-DD'));
|
|
||||||
|
|
||||||
let result = await Promise.resolve(fetchData(startUnixTime, s3Credentials));
|
let result = await Promise.resolve(fetchData(startUnixTime, s3Credentials));
|
||||||
if (
|
if (
|
||||||
result === FetchResult.notAvailable ||
|
result === FetchResult.notAvailable ||
|
||||||
|
@ -148,40 +142,6 @@ export const transformInputToDailyData = async (
|
||||||
console.log('Try next timestamp: ', startUnixTime);
|
console.log('Try next timestamp: ', startUnixTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.log(input);
|
|
||||||
// input.forEach((item) => {
|
|
||||||
// const csvContent = item.value;
|
|
||||||
// pathsToSearch.forEach((path) => {
|
|
||||||
// if (csvContent) {
|
|
||||||
// const timestamp = item.time.ticks * 1000;
|
|
||||||
//
|
|
||||||
// const adjustedTimestamp = new Date(timestamp);
|
|
||||||
// adjustedTimestamp.setHours(adjustedTimestamp.getHours() + 1);
|
|
||||||
//
|
|
||||||
// if (csvContent[path]) {
|
|
||||||
// const value = csvContent[path];
|
|
||||||
//
|
|
||||||
// if (value.value < overviewData[path].min) {
|
|
||||||
// overviewData[path].min = value.value;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (value.value > overviewData[path].max) {
|
|
||||||
// overviewData[path].max = value.value;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// data[path].push([adjustedTimestamp, value.value]);
|
|
||||||
// } else {
|
|
||||||
// //data[path].push([adjustedTimestamp, null]);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// // data[path].push([
|
|
||||||
// // addHours(new Date(item.time.ticks * 1000), 2),
|
|
||||||
// // null
|
|
||||||
// // ]);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
|
|
||||||
pathsToSearch.forEach((path) => {
|
pathsToSearch.forEach((path) => {
|
||||||
let value = Math.max(
|
let value = Math.max(
|
||||||
Math.abs(overviewData[path].max),
|
Math.abs(overviewData[path].max),
|
||||||
|
@ -196,11 +156,11 @@ export const transformInputToDailyData = async (
|
||||||
value /= 1000;
|
value /= 1000;
|
||||||
magnitude++;
|
magnitude++;
|
||||||
}
|
}
|
||||||
overviewData[path].magnitude = prefixes[magnitude];
|
overviewData[path].magnitude = magnitude;
|
||||||
});
|
});
|
||||||
|
|
||||||
let path = '/Battery/Soc';
|
let path = '/Battery/Soc';
|
||||||
chartData.soc = [{ name: 'State of Charge', data: data[path] }];
|
chartData.soc.data = data[path];
|
||||||
|
|
||||||
chartOverview.soc = {
|
chartOverview.soc = {
|
||||||
unit: '(%)',
|
unit: '(%)',
|
||||||
|
@ -210,7 +170,7 @@ export const transformInputToDailyData = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
path = '/Battery/Temperature';
|
path = '/Battery/Temperature';
|
||||||
chartData.temperature = [{ name: 'Battery Temperature:', data: data[path] }];
|
chartData.temperature.data = data[path];
|
||||||
|
|
||||||
chartOverview.temperature = {
|
chartOverview.temperature = {
|
||||||
unit: '(°C)',
|
unit: '(°C)',
|
||||||
|
@ -220,45 +180,63 @@ export const transformInputToDailyData = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
path = '/Battery/Dc/Power';
|
path = '/Battery/Dc/Power';
|
||||||
chartData.dcPower = [{ name: 'Battery Power', data: data[path] }];
|
chartData.dcPower.data = data[path];
|
||||||
|
|
||||||
chartOverview.dcPower = {
|
chartOverview.dcPower = {
|
||||||
magnitude: overviewData[path].magnitude,
|
magnitude: overviewData[path].magnitude,
|
||||||
unit: '(' + overviewData[path].magnitude + 'W' + ')',
|
unit: '(' + prefixes[overviewData[path].magnitude] + 'W' + ')',
|
||||||
min: overviewData[path].min,
|
min: overviewData[path].min,
|
||||||
max: overviewData[path].max
|
max: overviewData[path].max
|
||||||
};
|
};
|
||||||
|
|
||||||
path = '/GridMeter/Ac/Power/Active';
|
path = '/GridMeter/Ac/Power/Active';
|
||||||
chartData.gridPower = [{ name: 'Grid Power', data: data[path] }];
|
chartData.gridPower.data = data[path];
|
||||||
|
|
||||||
chartOverview.gridPower = {
|
chartOverview.gridPower = {
|
||||||
magnitude: overviewData[path].magnitude,
|
magnitude: overviewData[path].magnitude,
|
||||||
unit: '(' + overviewData[path].magnitude + 'W' + ')',
|
unit: '(' + prefixes[overviewData[path].magnitude] + 'W' + ')',
|
||||||
min: overviewData[path].min,
|
min: overviewData[path].min,
|
||||||
max: overviewData[path].max
|
max: overviewData[path].max
|
||||||
};
|
};
|
||||||
|
|
||||||
path = '/PvOnDc/Dc/Power';
|
path = '/PvOnDc/Dc/Power';
|
||||||
chartData.pvProduction = [{ name: 'Pv Production', data: data[path] }];
|
chartData.pvProduction.data = data[path];
|
||||||
|
|
||||||
chartOverview.pvProduction = {
|
chartOverview.pvProduction = {
|
||||||
magnitude: overviewData[path].magnitude,
|
magnitude: overviewData[path].magnitude,
|
||||||
unit: '(' + overviewData[path].magnitude + 'W' + ')',
|
unit: '(' + prefixes[overviewData[path].magnitude] + 'W' + ')',
|
||||||
min: overviewData[path].min,
|
min: overviewData[path].min,
|
||||||
max: overviewData[path].max
|
max: overviewData[path].max
|
||||||
};
|
};
|
||||||
|
|
||||||
path = '/DcDc/Dc/Link/Voltage';
|
path = '/DcDc/Dc/Link/Voltage';
|
||||||
chartData.dcBusVoltage = [{ name: 'DC Bus Voltage', data: data[path] }];
|
chartData.dcBusVoltage.data = data[path];
|
||||||
|
|
||||||
chartOverview.dcBusVoltage = {
|
chartOverview.dcBusVoltage = {
|
||||||
magnitude: overviewData[path].magnitude,
|
magnitude: overviewData[path].magnitude,
|
||||||
unit: '(' + overviewData[path].magnitude + 'V' + ')',
|
unit: '(' + prefixes[overviewData[path].magnitude] + 'V' + ')',
|
||||||
min: overviewData[path].min,
|
min: overviewData[path].min,
|
||||||
max: overviewData[path].max
|
max: overviewData[path].max
|
||||||
};
|
};
|
||||||
|
|
||||||
|
chartOverview.overview = {
|
||||||
|
magnitude: Math.max(
|
||||||
|
overviewData['/GridMeter/Ac/Power/Active'].magnitude,
|
||||||
|
overviewData['/PvOnDc/Dc/Power'].magnitude
|
||||||
|
),
|
||||||
|
unit: '(kW)',
|
||||||
|
min: Math.min(
|
||||||
|
overviewData['/GridMeter/Ac/Power/Active'].min,
|
||||||
|
overviewData['/PvOnDc/Dc/Power'].min
|
||||||
|
),
|
||||||
|
max: Math.max(
|
||||||
|
overviewData['/GridMeter/Ac/Power/Active'].max,
|
||||||
|
overviewData['/PvOnDc/Dc/Power'].max
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('min = ', chartOverview.overview.min);
|
||||||
|
console.log('max = ', chartOverview.overview.max);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
chartData: chartData,
|
chartData: chartData,
|
||||||
chartOverview: chartOverview
|
chartOverview: chartOverview
|
||||||
|
@ -266,32 +244,42 @@ export const transformInputToDailyData = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
export const transformInputToAggregatedData = async (
|
export const transformInputToAggregatedData = async (
|
||||||
s3Credentials: I_S3Credentials
|
s3Credentials: I_S3Credentials,
|
||||||
|
type: string
|
||||||
): Promise<{
|
): Promise<{
|
||||||
chartAggregatedData: chartAggregatedDataInterface;
|
chartAggregatedData: chartAggregatedDataInterface;
|
||||||
chartOverview: overviewInterface;
|
chartOverview: overviewInterface;
|
||||||
|
dateList: string[];
|
||||||
}> => {
|
}> => {
|
||||||
const data = {};
|
const data = {};
|
||||||
const overviewData = {};
|
const overviewData = {};
|
||||||
const prefixes = ['', 'k', 'M', 'G', 'T'];
|
|
||||||
const MAX_NUMBER = 9999999;
|
const MAX_NUMBER = 9999999;
|
||||||
|
const dateList = [];
|
||||||
|
|
||||||
let currentDate = dayjs().add(1, 'day');
|
let currentDate = dayjs().add(1, 'day');
|
||||||
let currentDay = currentDate.subtract(1, 'week');
|
let currentDay =
|
||||||
|
type === 'weekly'
|
||||||
|
? currentDate.subtract(1, 'week')
|
||||||
|
: currentDate.subtract(1, 'month');
|
||||||
|
|
||||||
const pathsToSearch = [
|
const pathsToSearch = [
|
||||||
'/AvgSoc',
|
'/MinSoc',
|
||||||
'/AvgPvPower',
|
'/MaxSoc',
|
||||||
'/BatteryPowerAverage',
|
'/SumPvPower',
|
||||||
'/GridMeter/Ac/Power/Active',
|
'/SumDischargingBatteryPower',
|
||||||
'/PvOnDc/Dc/Power',
|
'/SumChargingBatteryPower',
|
||||||
'/DcDc/Dc/Link/Voltage'
|
'/SumGridImportPower',
|
||||||
|
'/SumGridExportPower'
|
||||||
];
|
];
|
||||||
|
|
||||||
const chartAggregatedData: chartAggregatedDataInterface = {
|
const chartAggregatedData: chartAggregatedDataInterface = {
|
||||||
soc: [{ data: [] }],
|
minsoc: { name: 'min SOC', data: [] },
|
||||||
pvProduction: [{ data: [] }],
|
maxsoc: { name: 'max SOC', data: [] },
|
||||||
dcPower: [{ data: [] }]
|
pvProduction: { name: 'Pv Power', data: [] },
|
||||||
|
dcChargingPower: { name: 'Charging Battery Power', data: [] },
|
||||||
|
dcDischargingPower: { name: 'Discharging Battery Power', data: [] },
|
||||||
|
gridImportPower: { name: 'Grid Import Power', data: [] },
|
||||||
|
gridExportPower: { name: 'Grid Export Power', data: [] }
|
||||||
};
|
};
|
||||||
|
|
||||||
const chartOverview: overviewInterface = {
|
const chartOverview: overviewInterface = {
|
||||||
|
@ -300,7 +288,8 @@ export const transformInputToAggregatedData = async (
|
||||||
dcPower: { magnitude: 0, unit: '', min: 0, max: 0 },
|
dcPower: { magnitude: 0, unit: '', min: 0, max: 0 },
|
||||||
gridPower: { magnitude: 0, unit: '', min: 0, max: 0 },
|
gridPower: { magnitude: 0, unit: '', min: 0, max: 0 },
|
||||||
pvProduction: { magnitude: 0, unit: '', min: 0, max: 0 },
|
pvProduction: { magnitude: 0, unit: '', min: 0, max: 0 },
|
||||||
dcBusVoltage: { magnitude: 0, unit: '', min: 0, max: 0 }
|
dcBusVoltage: { magnitude: 0, unit: '', min: 0, max: 0 },
|
||||||
|
overview: { magnitude: 0, unit: '', min: 0, max: 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
pathsToSearch.forEach((path) => {
|
pathsToSearch.forEach((path) => {
|
||||||
|
@ -313,11 +302,23 @@ export const transformInputToAggregatedData = async (
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
while (currentDay.isBefore(currentDate)) {
|
let fake_data = [
|
||||||
|
'temp0',
|
||||||
|
'temp1',
|
||||||
|
'temp2',
|
||||||
|
'temp3',
|
||||||
|
'temp4',
|
||||||
|
'temp5',
|
||||||
|
'temp6'
|
||||||
|
];
|
||||||
|
|
||||||
|
//while (currentDay.isBefore(currentDate)) {
|
||||||
|
for (let i = 0; i < 7; i++) {
|
||||||
// console.log('Current day:', currentDay.format('YYYY-MM-DD'));
|
// console.log('Current day:', currentDay.format('YYYY-MM-DD'));
|
||||||
|
|
||||||
let result = await Promise.resolve(
|
let result = await Promise.resolve(
|
||||||
fetchDailyData(currentDay.format('YYYY-MM-DD'), s3Credentials)
|
//fetchDailyData(currentDay.format('YYYY-MM-DD'), s3Credentials)
|
||||||
|
fetchDailyData(fake_data[i], s3Credentials)
|
||||||
);
|
);
|
||||||
if (
|
if (
|
||||||
result === FetchResult.notAvailable ||
|
result === FetchResult.notAvailable ||
|
||||||
|
@ -326,6 +327,7 @@ export const transformInputToAggregatedData = async (
|
||||||
// Handle not available or try later case
|
// Handle not available or try later case
|
||||||
} else {
|
} else {
|
||||||
console.log('Received data:', result);
|
console.log('Received data:', result);
|
||||||
|
dateList.push(currentDay.format('DD-MM'));
|
||||||
pathsToSearch.forEach((path) => {
|
pathsToSearch.forEach((path) => {
|
||||||
if (result[path]) {
|
if (result[path]) {
|
||||||
if (result[path].value < overviewData[path].min) {
|
if (result[path].value < overviewData[path].min) {
|
||||||
|
@ -357,11 +359,14 @@ export const transformInputToAggregatedData = async (
|
||||||
value /= 1000;
|
value /= 1000;
|
||||||
magnitude++;
|
magnitude++;
|
||||||
}
|
}
|
||||||
overviewData[path].magnitude = prefixes[magnitude];
|
overviewData[path].magnitude = magnitude;
|
||||||
});
|
});
|
||||||
|
|
||||||
let path = '/AvgSoc';
|
let path = '/MinSoc';
|
||||||
chartAggregatedData.soc[0].data = data[path];
|
chartAggregatedData.minsoc.data = data[path];
|
||||||
|
|
||||||
|
path = '/MaxSoc';
|
||||||
|
chartAggregatedData.maxsoc.data = data[path];
|
||||||
|
|
||||||
chartOverview.soc = {
|
chartOverview.soc = {
|
||||||
unit: '(%)',
|
unit: '(%)',
|
||||||
|
@ -370,28 +375,78 @@ export const transformInputToAggregatedData = async (
|
||||||
max: 100
|
max: 100
|
||||||
};
|
};
|
||||||
|
|
||||||
path = '/AvgPvPower';
|
path = '/SumPvPower';
|
||||||
chartAggregatedData.pvProduction[0].data = data[path];
|
chartAggregatedData.pvProduction.data = data[path];
|
||||||
|
|
||||||
chartOverview.pvProduction = {
|
chartOverview.pvProduction = {
|
||||||
magnitude: overviewData[path].magnitude,
|
magnitude: overviewData[path].magnitude,
|
||||||
unit: '(' + overviewData[path].magnitude + 'W' + ')',
|
unit: '(kWh)',
|
||||||
min: overviewData[path].min,
|
min: overviewData[path].min,
|
||||||
max: overviewData[path].max
|
max: overviewData[path].max
|
||||||
};
|
};
|
||||||
|
|
||||||
path = '/BatteryPowerAverage';
|
path = '/SumChargingBatteryPower';
|
||||||
chartAggregatedData.dcPower[0].data = data[path];
|
chartAggregatedData.dcChargingPower.data = data[path];
|
||||||
|
|
||||||
|
path = '/SumDischargingBatteryPower';
|
||||||
|
chartAggregatedData.dcDischargingPower.data = data[path];
|
||||||
|
|
||||||
chartOverview.dcPower = {
|
chartOverview.dcPower = {
|
||||||
magnitude: overviewData[path].magnitude,
|
magnitude: Math.max(
|
||||||
unit: '(' + overviewData[path].magnitude + 'W' + ')',
|
overviewData['/SumChargingBatteryPower'].magnitude,
|
||||||
min: overviewData[path].min,
|
overviewData['/SumDischargingBatteryPower'].magnitude
|
||||||
max: overviewData[path].max
|
),
|
||||||
|
unit: '(kWh)',
|
||||||
|
min: Math.min(
|
||||||
|
overviewData['/SumChargingBatteryPower'].min,
|
||||||
|
overviewData['/SumDischargingBatteryPower'].min
|
||||||
|
),
|
||||||
|
max: Math.max(
|
||||||
|
overviewData['/SumChargingBatteryPower'].max,
|
||||||
|
overviewData['/SumDischargingBatteryPower'].max
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
path = '/SumGridImportPower';
|
||||||
|
chartAggregatedData.gridImportPower.data = data[path];
|
||||||
|
|
||||||
|
path = '/SumGridExportPower';
|
||||||
|
chartAggregatedData.gridExportPower.data = data[path];
|
||||||
|
|
||||||
|
chartOverview.gridPower = {
|
||||||
|
magnitude: Math.max(
|
||||||
|
overviewData['/SumGridImportPower'].magnitude,
|
||||||
|
overviewData['/SumGridExportPower'].magnitude
|
||||||
|
),
|
||||||
|
unit: '(kWh)',
|
||||||
|
min: Math.min(
|
||||||
|
overviewData['/SumGridImportPower'].min,
|
||||||
|
overviewData['/SumGridExportPower'].min
|
||||||
|
),
|
||||||
|
max: Math.max(
|
||||||
|
overviewData['/SumGridImportPower'].max,
|
||||||
|
overviewData['/SumGridExportPower'].max
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
chartOverview.overview = {
|
||||||
|
magnitude: 0,
|
||||||
|
unit: '(kWh)',
|
||||||
|
min: Math.min(
|
||||||
|
overviewData['/SumGridImportPower'].min,
|
||||||
|
overviewData['/SumGridExportPower'].min,
|
||||||
|
overviewData['/SumPvPower'].min
|
||||||
|
),
|
||||||
|
max: Math.max(
|
||||||
|
overviewData['/SumGridImportPower'].max,
|
||||||
|
overviewData['/SumGridExportPower'].max,
|
||||||
|
overviewData['/SumPvPower'].max
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
chartAggregatedData: chartAggregatedData,
|
chartAggregatedData: chartAggregatedData,
|
||||||
chartOverview: chartOverview
|
chartOverview: chartOverview,
|
||||||
|
dateList: dateList
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue