Enabled set date button in front end

Use s3cmd in backend to search the corresponding timestamps
This commit is contained in:
Noe 2024-08-02 16:15:12 +02:00
parent b499d01473
commit cce3a6f9bd
22 changed files with 254 additions and 203 deletions

View File

@ -1,4 +1,6 @@
using System.Diagnostics;
using System.Net;
using System.Text.RegularExpressions;
using InnovEnergy.App.Backend.Database;
using InnovEnergy.App.Backend.DataTypes;
using InnovEnergy.App.Backend.DataTypes.Methods;
@ -145,8 +147,10 @@ public class Controller : ControllerBase
.ToList();
}
[HttpGet(nameof(GetCsvTimestampsForInstallation))]
public ActionResult<IEnumerable<CsvTimestamp>> GetCsvTimestampsForInstallation(Int64 id, Int32 start, Int32 end, Token authToken)
public ActionResult<IEnumerable<Int64>> GetCsvTimestampsForInstallation(Int64 id, Int32 start, Int32 end, Token authToken)
{
var user = Db.GetSession(authToken)?.User;
if (user == null)
@ -158,21 +162,84 @@ public class Controller : ControllerBase
return Unauthorized();
var sampleSize = 100;
var allTimestamps = new List<CsvTimestamp>();
var allTimestamps = new List<Int64>();
if (start != 0 && end != 0)
static string FindCommonPrefix(string str1, string str2)
{
allTimestamps = Db.CsvTimestamps
.Where(csvTimestamp => csvTimestamp.InstallationId == id && csvTimestamp.Timestamp > start && csvTimestamp.Timestamp < end)
.OrderBy(csvTimestamp => csvTimestamp.Timestamp).ToList();
int minLength = Math.Min(str1.Length, str2.Length);
int i = 0;
while (i < minLength && str1[i] == str2[i])
{
i++;
}
return str1.Substring(0, i);
}
else
{
allTimestamps = Db.CsvTimestamps
.Where(csvTimestamp => csvTimestamp.InstallationId == id)
.OrderBy(csvTimestamp => csvTimestamp.Timestamp).ToList();
string commonPrefix = FindCommonPrefix(start.ToString(), end.ToString());
string bucketPath = "s3://"+installation.S3BucketId + "-3e5b3069-214a-43ee-8d85-57d72000c19d/"+commonPrefix;
string configPath = "/home/ubuntu/.s3cfg";
try
{
// Set up process start info
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "s3cmd",
Arguments = $"--config {configPath} ls {bucketPath}",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
// Start the process
Process process = new Process
{
StartInfo = startInfo
};
process.Start();
// Read the output
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
process.WaitForExit();
// Check for errors
if (process.ExitCode != 0)
{
Console.WriteLine("Error executing command:");
Console.WriteLine(error);
}
else
{
Console.WriteLine("Command output:");
//Console.WriteLine(output);
// Define a regex pattern to match the filenames without .csv extension
var pattern = @"/([^/]+)\.csv$";
var regex = new Regex(pattern);
// Process each line of the output
foreach (var line in output.Split('\n'))
{
var match = regex.Match(line);
if (match.Success && long.Parse(match.Groups[1].Value)>=start && long.Parse(match.Groups[1].Value)<=end)
{
allTimestamps.Add(long.Parse(match.Groups[1].Value));
//Console.WriteLine(match.Groups[1].Value);
}
}
}
}
catch (Exception e)
{
Console.WriteLine($"Exception: {e.Message}");
}
int totalRecords = allTimestamps.Count;
if (totalRecords <= sampleSize)
@ -186,7 +253,7 @@ public class Controller : ControllerBase
int interval = totalRecords / sampleSize;
var sampledTimestamps = new List<CsvTimestamp>();
var sampledTimestamps = new List<Int64>();
for (int i = 0; i < totalRecords; i += interval)
{
@ -204,11 +271,6 @@ public class Controller : ControllerBase
Console.WriteLine("SampledTimestamps = " + sampledTimestamps.Count);
return sampledTimestamps;
// return Db.CsvTimestamps
// .Where(csvTimestamp => csvTimestamp.InstallationId == id)
// .OrderByDescending(csvTimestamp => csvTimestamp.Timestamp)
// .ToList();
}
[HttpGet(nameof(GetUserById))]

View File

@ -1,11 +0,0 @@
using SQLite;
namespace InnovEnergy.App.Backend.DataTypes;
public class CsvTimestamp{
[PrimaryKey, AutoIncrement]
public Int64 Id { get; set; }
public Int64 InstallationId { get; set; }
public Int32 Timestamp { get; set; }
}

View File

@ -105,7 +105,7 @@ public static class InstallationMethods
public static Installation HideWriteKeyIfUserIsNotAdmin(this Installation installation, int userIsAdmin)
{
if(userIsAdmin!=2)
if(userIsAdmin==2)
return installation;
installation.S3WriteKey = "";

View File

@ -42,11 +42,6 @@ public static partial class Db
return Insert(warning);
}
public static Boolean Create(CsvTimestamp csvTimestamp)
{
return Insert(csvTimestamp);
}
public static Boolean Create(Folder folder)
{
return Insert(folder);
@ -176,34 +171,4 @@ public static partial class Db
}
}
public static void AddCsvTimestamp(CsvTimestamp newCsvTimestamp,int installationId)
{
var maxCSvPerInstallation = 60 * 24;
//Find the total number of warnings for this installation
var totalCsvNames = CsvTimestamps.Count(csvTimestamp => csvTimestamp.InstallationId == installationId);
//If there are 100 warnings, remove the one with the oldest timestamp
if (totalCsvNames == maxCSvPerInstallation)
{
var oldestCSvTimestamp =
CsvTimestamps.Where(csvTimestamp => csvTimestamp.InstallationId == installationId)
.OrderBy(csvTimestamp => csvTimestamp.Timestamp)
.FirstOrDefault();
//Remove the old error
Delete(oldestCSvTimestamp);
//Add the new error
Create(newCsvTimestamp);
}
else
{
//Console.WriteLine("---------------Added the new Csv Timestamp to the database-----------------");
Create(newCsvTimestamp);
}
}
}

View File

@ -37,7 +37,6 @@ public static partial class Db
fileConnection.CreateTable<Error>();
fileConnection.CreateTable<Warning>();
fileConnection.CreateTable<UserAction>();
fileConnection.CreateTable<CsvTimestamp>();
return fileConnection;
//return CopyDbToMemory(fileConnection);
@ -58,7 +57,6 @@ public static partial class Db
memoryConnection.CreateTable<Error>();
memoryConnection.CreateTable<Warning>();
fileConnection.CreateTable<UserAction>();
fileConnection.CreateTable<CsvTimestamp>();
//Copy all the existing tables from the disk to main memory
fileConnection.Table<Session>().ForEach(memoryConnection.Insert);
@ -71,7 +69,6 @@ public static partial class Db
fileConnection.Table<Error>().ForEach(memoryConnection.Insert);
fileConnection.Table<Warning>().ForEach(memoryConnection.Insert);
fileConnection.Table<UserAction>().ForEach(memoryConnection.Insert);
fileConnection.Table<CsvTimestamp>().ForEach(memoryConnection.Insert);
return memoryConnection;
}
@ -92,7 +89,6 @@ public static partial class Db
public static TableQuery<Error> Errors => Connection.Table<Error>();
public static TableQuery<Warning> Warnings => Connection.Table<Warning>();
public static TableQuery<UserAction> UserActions => Connection.Table<UserAction>();
public static TableQuery<CsvTimestamp> CsvTimestamps => Connection.Table<CsvTimestamp>();
public static void Init()
{
@ -115,7 +111,6 @@ public static partial class Db
Connection.CreateTable<Error>();
Connection.CreateTable<Warning>();
Connection.CreateTable<UserAction>();
Connection.CreateTable<CsvTimestamp>();
});
//UpdateKeys();

View File

@ -90,20 +90,6 @@ public static partial class Db
}
}
public static Boolean Delete(CsvTimestamp csvTimestampToDelete)
{
var deleteSuccess = RunTransaction(DeleteCsvTimestampToDelete);
if (deleteSuccess)
Backup();
return deleteSuccess;
Boolean DeleteCsvTimestampToDelete()
{
return CsvTimestamps.Delete(csvTimestamp => csvTimestamp.Id == csvTimestampToDelete.Id) >0;
}
}
public static Boolean Delete(Installation installation)
{
var deleteSuccess = RunTransaction(DeleteInstallationAndItsDependencies);

View File

@ -1,3 +1,4 @@
using System.Diagnostics;
using Flurl.Http;
using Hellang.Middleware.ProblemDetails;
using InnovEnergy.App.Backend.Database;
@ -22,6 +23,7 @@ public static class Program
RabbitMqManager.StartRabbitMqConsumer();
WebsocketManager.MonitorInstallationTable();
builder.Services.AddControllers();
builder.Services.AddProblemDetails(setup =>
{

View File

@ -52,8 +52,6 @@ public static class RabbitMqManager
//A message can be an alarm, a warning or a heartbit
StatusMessage? receivedStatusMessage = JsonSerializer.Deserialize<StatusMessage>(message);
lock (WebsocketManager.InstallationConnections)
{
//Consumer received a message
@ -69,17 +67,6 @@ public static class RabbitMqManager
if (receivedStatusMessage.Type == MessageType.Heartbit)
{
//Console.WriteLine("This is a heartbit message from installation: " + installationId + " Name of the file is "+ receivedStatusMessage.Timestamp);
if (receivedStatusMessage.Timestamp != 0)
{
CsvTimestamp newCsvTimestamp = new CsvTimestamp
{
InstallationId = installationId,
Timestamp = receivedStatusMessage.Timestamp
};
Db.AddCsvTimestamp(newCsvTimestamp, installationId);
}
}
else
{
@ -133,7 +120,7 @@ public static class RabbitMqManager
Seen = false
};
Console.WriteLine("Add an alarm for installation "+installationId);
//Console.WriteLine("Add an alarm for installation "+installationId);
// Send replace battery email to support team if this alarm is "NeedToReplaceBattery"
if (alarm.Description == "2 or more string are disabled")
@ -187,9 +174,7 @@ public static class RabbitMqManager
{
WebsocketManager.InformWebsocketsForInstallation(installationId);
}
}
}
};
Channel.BasicConsume(queue: "statusQueue", autoAck: true, consumer: consumer);

View File

@ -19,7 +19,6 @@ public static class WebsocketManager
lock (InstallationConnections){
foreach (var installationConnection in InstallationConnections){
if ((DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(1)){
Console.WriteLine("Installation "+installationConnection.Key+" is offline, latest timestamp was "+installationConnection.Value.Timestamp);
installationConnection.Value.Status = -1;
if (installationConnection.Value.Connections.Count > 0){InformWebsocketsForInstallation(installationConnection.Key);}
}
@ -94,7 +93,7 @@ public static class WebsocketManager
continue;
}
Console.WriteLine("Received a new message from websocket");
//Console.WriteLine("Received a new message from websocket");
lock (InstallationConnections)
{
//Each front-end will send the list of the installations it wants to access
@ -102,6 +101,7 @@ public static class WebsocketManager
//Then, report the status of each requested installation to the front-end that created the websocket connection
foreach (var installationId in installationIds)
{
//Console.WriteLine("New id is "+installationId);
var installation = Db.GetInstallationById(installationId);
if (!InstallationConnections.ContainsKey(installationId))
{

View File

@ -9,5 +9,5 @@ Salimax0005 ie-entwicklung@10.2.4.36 Schreinerei Schönthal (Thu
Salimax0006 ie-entwicklung@10.2.4.35 Steakhouse Mettmenstetten
Salimax0007 ie-entwicklung@10.2.4.154 LerchenhofHerr Twannberg
Salimax0008 ie-entwicklung@10.2.4.113 Wittmann Kottingbrunn
Salimax0010 ie-entwicklung@10.2.4.211 Mohatech 1
Salimax0010 ie-entwicklung@10.2.4.211 Mohatech 1 (Beat Moser)
SalidomoServer ig@134.209.238.170

View File

@ -54,6 +54,6 @@ INNOVENERGY_PROTOCOL_VERSION = '48TL200V3'
# S3 Credentials
S3BUCKET = "10-c0436b6a-d276-4cd8-9c44-1eae86cf5d0e"
S3KEY = "EXOa8cc58d2e51e389fed9ccbfa"
S3SECRET = "hofDGMmSSN1OACYXHWRUGdG61mFjBxKC18sF0VpMQgY"
S3BUCKET = "35-c0436b6a-d276-4cd8-9c44-1eae86cf5d0e"
S3KEY = "EXO2a70f415b6b387b5628020bd"
S3SECRET = "qdlYoXDZyME8LEB8BFTuCmJoTzkP2Nebr2jVmlXUzgY"

View File

@ -448,22 +448,25 @@ function Configuration(props: ConfigurationProps) {
fullWidth
/>
</div>
<div style={{ marginBottom: '5px' }}>
<TextField
label={
<FormattedMessage
id="Maximum_Discharge_Power"
defaultMessage="Maximum Discharge Power (W)"
/>
}
value={
(props.values.maximumDischargePower[0].value as number) *
48 *
(props.values.DcDcNum[0].value as number)
}
fullWidth
/>
</div>
{props.values.maximumDischargePower && (
<div style={{ marginBottom: '5px' }}>
<TextField
label={
<FormattedMessage
id="Maximum_Discharge_Power"
defaultMessage="Maximum Discharge Power (W)"
/>
}
value={
(props.values.maximumDischargePower[0].value as number) *
48 *
(props.values.DcDcNum[0].value as number)
}
fullWidth
/>
</div>
)}
<div>
<TextField
label={

View File

@ -387,6 +387,26 @@ function HistoryOfActions(props: HistoryProps) {
/>
</Typography>
</div>
<div
style={{
flex: 1,
marginTop: '15px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<Typography
variant="body1"
color="dimgrey"
fontWeight="bold"
fontSize="1rem"
gutterBottom
noWrap
>
<FormattedMessage id="edit" defaultMessage="Edit" />
</Typography>
</div>
</div>
<Divider />
<div style={{ maxHeight: '600px', overflowY: 'auto' }}>

View File

@ -282,30 +282,10 @@ function Information(props: InformationProps) {
/>
</div>
{/*<div>*/}
{/* <TextField*/}
{/* label="S3 Write Key"*/}
{/* name="s3writekey"*/}
{/* value={formValues.s3WriteKey}*/}
{/* variant="outlined"*/}
{/* fullWidth*/}
{/* />*/}
{/*</div>*/}
{/*<div>*/}
{/* <TextField*/}
{/* label="S3 Write Secret Key"*/}
{/* name="s3writesecretkey"*/}
{/* value={formValues.s3WriteSecret}*/}
{/* variant="outlined"*/}
{/* fullWidth*/}
{/* />*/}
{/*</div>*/}
<div>
<TextField
label="S3 Bucket Name"
name="s3writesecretkey"
name="s3bucketname"
value={
formValues.s3BucketId +
'-3e5b3069-214a-43ee-8d85-57d72000c19d'
@ -314,6 +294,25 @@ function Information(props: InformationProps) {
fullWidth
/>
</div>
<div>
<TextField
label="S3 Write Key"
name="s3writekey"
value={formValues.s3WriteKey}
variant="outlined"
fullWidth
/>
</div>
<div>
<TextField
label="S3 Write Secret Key"
name="s3writesecretkey"
value={formValues.s3WriteSecret}
variant="outlined"
fullWidth
/>
</div>
</>
)}

View File

@ -117,11 +117,11 @@ function Installation(props: singleInstallationProps) {
};
const fetchDataPeriodically = async () => {
var timeperiodToSearch = 70;
var timeperiodToSearch = 90;
let res;
let timestampToFetch;
for (var i = timeperiodToSearch; i > 0; i -= 2) {
for (var i = 0; i < timeperiodToSearch; i += 2) {
if (!continueFetching.current) {
return false;
}
@ -379,6 +379,7 @@ function Installation(props: singleInstallationProps) {
{loading &&
currentTab != 'information' &&
currentTab != 'history' &&
currentTab != 'overview' &&
currentTab != 'log' && (
<Container
maxWidth="xl"

View File

@ -85,7 +85,14 @@ function Overview(props: OverviewProps) {
const resultPromise: Promise<{
chartData: chartDataInterface;
chartOverview: overviewInterface;
}> = transformInputToDailyData(props.s3Credentials, props.id);
}> = transformInputToDailyData(
props.s3Credentials,
props.id,
UnixTime.fromTicks(new Date().getTime() / 1000).earlier(
TimeSpan.fromDays(1)
),
UnixTime.fromTicks(new Date().getTime() / 1000)
);
resultPromise
.then((result) => {
@ -169,6 +176,7 @@ function Overview(props: OverviewProps) {
const resultPromise: Promise<{
chartAggregatedData: chartAggregatedDataInterface;
chartOverview: overviewInterface;
dateList: string[];
}> = transformInputToAggregatedData(
props.s3Credentials,
dayjs().subtract(1, 'week'),
@ -193,7 +201,7 @@ function Overview(props: OverviewProps) {
prevData.concat({
chartData: result.chartAggregatedData,
chartOverview: result.chartOverview,
datelist: computeLast7Days(),
datelist: result.dateList,
netbalance: powerDifference
})
);
@ -482,22 +490,22 @@ function Overview(props: OverviewProps) {
<FormattedMessage id="lastweek" defaultMessage="Last week" />
</Button>
{aggregatedData && (
<Button
variant="contained"
onClick={handleSetDate}
disabled={loading}
sx={{
marginTop: '20px',
marginLeft: '10px',
backgroundColor: dateOpen ? '#808080' : '#ffc04d',
color: '#000000',
'&:hover': { bgcolor: '#f7b34d' }
}}
>
<FormattedMessage id="set_date" defaultMessage="Set Date" />
</Button>
)}
{/*{aggregatedData && (*/}
<Button
variant="contained"
onClick={handleSetDate}
disabled={loading}
sx={{
marginTop: '20px',
marginLeft: '10px',
backgroundColor: dateOpen ? '#808080' : '#ffc04d',
color: '#000000',
'&:hover': { bgcolor: '#f7b34d' }
}}
>
<FormattedMessage id="set_date" defaultMessage="Set Date" />
</Button>
{/*)}*/}
</Grid>
<Grid

View File

@ -78,6 +78,7 @@ function SalidomoOverview(props: salidomoOverviewProps) {
const resultPromise: Promise<{
chartAggregatedData: chartAggregatedDataInterface;
chartOverview: overviewInterface;
dateList: string[];
}> = transformInputToAggregatedData(
props.s3Credentials,
dayjs().subtract(1, 'week'),
@ -102,7 +103,7 @@ function SalidomoOverview(props: salidomoOverviewProps) {
prevData.concat({
chartData: result.chartAggregatedData,
chartOverview: result.chartOverview,
datelist: computeLast7Days(),
datelist: result.dateList,
netbalance: powerDifference
})
);

View File

@ -18,6 +18,7 @@ import { FormattedMessage } from 'react-intl';
import { useLocation, useNavigate } from 'react-router-dom';
import routes from '../../../Resources/routes.json';
import CancelIcon from '@mui/icons-material/Cancel';
import BuildIcon from '@mui/icons-material/Build';
interface FlatInstallationViewProps {
installations: I_Installation[];
@ -26,7 +27,7 @@ interface FlatInstallationViewProps {
const FlatInstallationView = (props: FlatInstallationViewProps) => {
const [isRowHovered, setHoveredRow] = useState(-1);
const webSocketContext = useContext(WebSocketContext);
const { getStatus } = webSocketContext;
const { getStatus, getTestingMode } = webSocketContext;
const navigate = useNavigate();
const [selectedInstallation, setSelectedInstallation] = useState<number>(-1);
const currentLocation = useLocation();
@ -320,6 +321,19 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => {
: 'green'
}}
/>
{getTestingMode(installation.id) && (
<BuildIcon
style={{
width: '23px',
height: '23px',
color: 'purple',
borderRadius: '50%',
position: 'relative',
zIndex: 1,
marginLeft: '15px'
}}
/>
)}
</div>
</TableCell>
</TableRow>

View File

@ -24,6 +24,9 @@ import BatteryView from '../BatteryView/BatteryView';
import Log from '../Log/Log';
import CancelIcon from '@mui/icons-material/Cancel';
import SalidomoOverview from '../Overview/salidomoOverview';
import { UserType } from '../../../interfaces/UserTypes';
import HistoryOfActions from '../History/History';
import BuildIcon from '@mui/icons-material/Build';
interface singleInstallationProps {
current_installation?: I_Installation;
@ -36,7 +39,7 @@ function Installation(props: singleInstallationProps) {
const location = useLocation().pathname;
const [errorLoadingS3Data, setErrorLoadingS3Data] = useState(false);
const webSocketsContext = useContext(WebSocketContext);
const { getStatus } = webSocketsContext;
const { getStatus, getTestingMode } = webSocketsContext;
const [currentTab, setCurrentTab] = useState<string>(undefined);
const [values, setValues] = useState<TopologyValues | null>(null);
const status = getStatus(props.current_installation.id);
@ -74,11 +77,11 @@ function Installation(props: singleInstallationProps) {
const continueFetching = useRef(false);
const fetchDataPeriodically = async () => {
var timeperiodToSearch = 70;
var timeperiodToSearch = 90;
let res;
let timestampToFetch;
for (var i = timeperiodToSearch; i > 0; i -= 2) {
for (var i = 0; i < timeperiodToSearch; i += 2) {
if (!continueFetching.current) {
return false;
}
@ -274,11 +277,26 @@ function Installation(props: singleInstallationProps) {
: 'green'
}}
/>
{getTestingMode(props.current_installation.id) && (
<BuildIcon
style={{
width: '23px',
height: '23px',
color: 'purple',
borderRadius: '50%',
position: 'relative',
zIndex: 1,
marginLeft: '15px'
}}
/>
)}
</div>
</div>
{loading &&
currentTab != 'information' &&
currentTab != 'overview' &&
currentTab != 'history' &&
currentTab != 'log' && (
<Container
maxWidth="xl"
@ -354,6 +372,18 @@ function Installation(props: singleInstallationProps) {
}
></Route>
{currentUser.userType == UserType.admin && (
<Route
path={routes.history}
element={
<HistoryOfActions
errorLoadingS3Data={errorLoadingS3Data}
id={props.current_installation.id}
></HistoryOfActions>
}
/>
)}
<Route
path={'*'}
element={<Navigate to={routes.information}></Navigate>}

View File

@ -14,7 +14,7 @@ function SalidomoInstallationTabs() {
const location = useLocation();
const context = useContext(UserContext);
const { currentUser } = context;
const tabList = ['batteryview', 'information', 'overview', 'log'];
const tabList = ['batteryview', 'information', 'overview', 'log', 'history'];
const [currentTab, setCurrentTab] = useState<string>(undefined);
const [fetchedInstallations, setFetchedInstallations] =
@ -106,6 +106,15 @@ function SalidomoInstallationTabs() {
label: (
<FormattedMessage id="information" defaultMessage="Information" />
)
},
{
value: 'history',
label: (
<FormattedMessage
id="history"
defaultMessage="History Of Actions"
/>
)
}
]
: [

View File

@ -380,47 +380,30 @@ export const transformInputToDailyData = async (
};
});
let timestampArray: CsvTimestamp[] = [];
let timestampArray: number[] = [];
let adjustedTimestampArray = [];
const timestampPromises = [];
if (start_time && end_time) {
await axiosConfig
.get(
`/GetCsvTimestampsForInstallation?id=${id}&start=${start_time.ticks}&end=${end_time.ticks}`
)
.then((res: AxiosResponse<CsvTimestamp[]>) => {
timestampArray = res.data;
})
.catch((err: AxiosError) => {
if (err.response && err.response.status == 401) {
//removeToken();
//navigate(routes.login);
}
});
} else {
await axiosConfig
.get(`/GetCsvTimestampsForInstallation?id=${id}&start=${0}&end=${0}`)
.then((res: AxiosResponse<CsvTimestamp[]>) => {
timestampArray = res.data;
})
.catch((err: AxiosError) => {
if (err.response && err.response.status == 401) {
//removeToken();
//navigate(routes.login);
}
});
}
await axiosConfig
.get(
`/GetCsvTimestampsForInstallation?id=${id}&start=${start_time.ticks}&end=${end_time.ticks}`
)
.then((res: AxiosResponse<number[]>) => {
timestampArray = res.data;
})
.catch((err: AxiosError) => {
if (err.response && err.response.status == 401) {
//removeToken();
//navigate(routes.login);
}
});
for (var i = 0; i < timestampArray.length; i++) {
timestampPromises.push(
fetchDataForOneTime(
UnixTime.fromTicks(timestampArray[i].timestamp),
s3Credentials
)
fetchDataForOneTime(UnixTime.fromTicks(timestampArray[i]), s3Credentials)
);
const adjustedTimestamp = new Date(timestampArray[i].timestamp * 1000);
const adjustedTimestamp = new Date(timestampArray[i] * 1000);
//Timezone offset is negative, so we convert the timestamp to the current zone by subtracting the corresponding offset
adjustedTimestamp.setHours(
adjustedTimestamp.getHours() - adjustedTimestamp.getTimezoneOffset() / 60
@ -619,7 +602,6 @@ export const transformInputToAggregatedData = async (
if (result[path].value < overviewData[path].min) {
overviewData[path].min = result[path].value;
}
if (result[path].value > overviewData[path].max) {
overviewData[path].max = result[path].value;
}