Compare commits
No commits in common. "c19c32a1ecfb90043fd96663149d362a58e7b128" and "3deee7bbac2a7ba909b8dc3cf8c6e220fe8d5533" have entirely different histories.
c19c32a1ec
...
3deee7bbac
|
@ -679,35 +679,34 @@ internal static class Program
|
||||||
// This is temporary for Wittman, but now it's for all Instalattion
|
// This is temporary for Wittman, but now it's for all Instalattion
|
||||||
await File.WriteAllTextAsync("/var/www/html/status.csv", csv.SplitLines().Where(l => !l.Contains("Secret")).JoinLines());
|
await File.WriteAllTextAsync("/var/www/html/status.csv", csv.SplitLines().Where(l => !l.Contains("Secret")).JoinLines());
|
||||||
|
|
||||||
var response = await request.PutAsync(new StringContent(csv));
|
|
||||||
|
|
||||||
// Compress CSV data to a byte array
|
// Compress CSV data to a byte array
|
||||||
// byte[] compressedBytes;
|
byte[] compressedBytes;
|
||||||
// using (var memoryStream = new MemoryStream())
|
using (var memoryStream = new MemoryStream())
|
||||||
// {
|
{
|
||||||
// //Create a zip directory and put the compressed file inside
|
//Create a zip directory and put the compressed file inside
|
||||||
// using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
|
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
|
||||||
// {
|
{
|
||||||
// var entry = archive.CreateEntry("data.csv", CompressionLevel.SmallestSize); // Add CSV data to the ZIP archive
|
var entry = archive.CreateEntry("data.csv", CompressionLevel.SmallestSize); // Add CSV data to the ZIP archive
|
||||||
// using (var entryStream = entry.Open())
|
using (var entryStream = entry.Open())
|
||||||
// using (var writer = new StreamWriter(entryStream))
|
using (var writer = new StreamWriter(entryStream))
|
||||||
// {
|
{
|
||||||
// writer.Write(csv);
|
writer.Write(csv);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// compressedBytes = memoryStream.ToArray();
|
compressedBytes = memoryStream.ToArray();
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// // Encode the compressed byte array as a Base64 string
|
// Encode the compressed byte array as a Base64 string
|
||||||
// string base64String = Convert.ToBase64String(compressedBytes);
|
string base64String = Convert.ToBase64String(compressedBytes);
|
||||||
//
|
|
||||||
// // Create StringContent from Base64 string
|
// Create StringContent from Base64 string
|
||||||
// var stringContent = new StringContent(base64String, Encoding.UTF8, "application/base64");
|
var stringContent = new StringContent(base64String, Encoding.UTF8, "application/base64");
|
||||||
//
|
|
||||||
// // Upload the compressed data (ZIP archive) to S3
|
// Upload the compressed data (ZIP archive) to S3
|
||||||
// var response = await request.PutAsync(stringContent);
|
var response = await request.PutAsync(stringContent);
|
||||||
//
|
|
||||||
if (response.StatusCode != 200)
|
if (response.StatusCode != 200)
|
||||||
{
|
{
|
||||||
Console.WriteLine("ERROR: PUT");
|
Console.WriteLine("ERROR: PUT");
|
||||||
|
|
|
@ -70,8 +70,7 @@ public record S3Config
|
||||||
// CanonicalizedResource;
|
// CanonicalizedResource;
|
||||||
|
|
||||||
|
|
||||||
//contentType = "application/base64; charset=utf-8";
|
contentType = "application/base64; charset=utf-8";
|
||||||
contentType = "text/plain; charset=utf-8";
|
|
||||||
|
|
||||||
var payload = $"{method}\n{md5Hash}\n{contentType}\n{date}\n/{bucket.Trim('/')}/{s3Path.Trim('/')}";
|
var payload = $"{method}\n{md5Hash}\n{contentType}\n{date}\n/{bucket.Trim('/')}/{s3Path.Trim('/')}";
|
||||||
using var hmacSha1 = new HMACSHA1(UTF8.GetBytes(s3Secret));
|
using var hmacSha1 = new HMACSHA1(UTF8.GetBytes(s3Secret));
|
||||||
|
|
|
@ -11,12 +11,10 @@
|
||||||
"overview": "overview",
|
"overview": "overview",
|
||||||
"manage": "manage",
|
"manage": "manage",
|
||||||
"batteryview": "batteryview",
|
"batteryview": "batteryview",
|
||||||
"pvview": "pvview",
|
|
||||||
"log": "log",
|
"log": "log",
|
||||||
"live": "live",
|
"live": "live",
|
||||||
"information": "information",
|
"information": "information",
|
||||||
"configuration": "configuration",
|
"configuration": "configuration",
|
||||||
"history": "history",
|
|
||||||
"mainstats": "mainstats",
|
"mainstats": "mainstats",
|
||||||
"detailed_view": "detailed_view/"
|
"detailed_view": "detailed_view/"
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,8 +246,8 @@ function MainStats(props: MainStatsProps) {
|
||||||
chartOverview: BatteryOverviewInterface;
|
chartOverview: BatteryOverviewInterface;
|
||||||
}> = transformInputToBatteryViewData(
|
}> = transformInputToBatteryViewData(
|
||||||
props.s3Credentials,
|
props.s3Credentials,
|
||||||
UnixTime.fromTicks(startX).earlier(TimeSpan.fromHours(2)),
|
UnixTime.fromTicks(startX),
|
||||||
UnixTime.fromTicks(endX).earlier(TimeSpan.fromHours(2))
|
UnixTime.fromTicks(endX)
|
||||||
);
|
);
|
||||||
|
|
||||||
resultPromise
|
resultPromise
|
||||||
|
|
|
@ -15,7 +15,7 @@ import {
|
||||||
Typography,
|
Typography,
|
||||||
useTheme
|
useTheme
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import React, { useContext, useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import Button from '@mui/material/Button';
|
import Button from '@mui/material/Button';
|
||||||
import { Close as CloseIcon } from '@mui/icons-material';
|
import { Close as CloseIcon } from '@mui/icons-material';
|
||||||
|
@ -29,8 +29,6 @@ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import axiosConfig from '../../../Resources/axiosConfig';
|
import axiosConfig from '../../../Resources/axiosConfig';
|
||||||
import utc from 'dayjs/plugin/utc';
|
import utc from 'dayjs/plugin/utc';
|
||||||
import { Action } from '../../../interfaces/S3Types';
|
|
||||||
import { UserContext } from '../../../contexts/userContext';
|
|
||||||
|
|
||||||
interface ConfigurationProps {
|
interface ConfigurationProps {
|
||||||
values: TopologyValues;
|
values: TopologyValues;
|
||||||
|
@ -84,8 +82,6 @@ function Configuration(props: ConfigurationProps) {
|
||||||
const [updated, setUpdated] = useState(false);
|
const [updated, setUpdated] = useState(false);
|
||||||
const [dateSelectionError, setDateSelectionError] = useState('');
|
const [dateSelectionError, setDateSelectionError] = useState('');
|
||||||
const [isErrorDateModalOpen, setErrorDateModalOpen] = useState(false);
|
const [isErrorDateModalOpen, setErrorDateModalOpen] = useState(false);
|
||||||
const context = useContext(UserContext);
|
|
||||||
const { currentUser, setUser } = context;
|
|
||||||
|
|
||||||
const [formValues, setFormValues] = useState<ConfigurationValues>({
|
const [formValues, setFormValues] = useState<ConfigurationValues>({
|
||||||
minimumSoC: props.values.minimumSoC[0].value,
|
minimumSoC: props.values.minimumSoC[0].value,
|
||||||
|
@ -137,13 +133,6 @@ function Configuration(props: ConfigurationProps) {
|
||||||
.toDate()
|
.toDate()
|
||||||
};
|
};
|
||||||
|
|
||||||
const historyAction: Action = {
|
|
||||||
configuration: configurationToSend,
|
|
||||||
date: new Date().toISOString().split('T')[0], // Gets the current date in YYYY-MM-DD format
|
|
||||||
time: new Date().toISOString().split('T')[1].split('.')[0], // Gets the current time in HH:MM:SS format
|
|
||||||
user: currentUser.name
|
|
||||||
};
|
|
||||||
|
|
||||||
// console.log('will send ', dayjs(formValues.calibrationChargeDate));
|
// console.log('will send ', dayjs(formValues.calibrationChargeDate));
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
@ -160,23 +149,10 @@ function Configuration(props: ConfigurationProps) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
const historyRes = await axiosConfig
|
|
||||||
.post(
|
|
||||||
`/UpdateActionHistory?installationId=${props.id}`,
|
|
||||||
historyAction
|
|
||||||
)
|
|
||||||
.catch((err) => {
|
|
||||||
if (err.response) {
|
|
||||||
setError(true);
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (historyRes) {
|
|
||||||
setUpdated(true);
|
setUpdated(true);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOkOnErrorDateModal = () => {
|
const handleOkOnErrorDateModal = () => {
|
||||||
|
|
|
@ -1,275 +0,0 @@
|
||||||
import React, { useContext, useEffect, useState } from 'react';
|
|
||||||
import {
|
|
||||||
Alert,
|
|
||||||
Card,
|
|
||||||
Container,
|
|
||||||
Divider,
|
|
||||||
Grid,
|
|
||||||
IconButton,
|
|
||||||
useTheme
|
|
||||||
} from '@mui/material';
|
|
||||||
import Typography from '@mui/material/Typography';
|
|
||||||
import { FormattedMessage } from 'react-intl';
|
|
||||||
import axiosConfig from '../../../Resources/axiosConfig';
|
|
||||||
import { AxiosError, AxiosResponse } from 'axios/index';
|
|
||||||
import routes from '../../../Resources/routes.json';
|
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
import { TokenContext } from '../../../contexts/tokenContext';
|
|
||||||
import { Action } from '../../../interfaces/S3Types';
|
|
||||||
|
|
||||||
interface HistoryProps {
|
|
||||||
errorLoadingS3Data: boolean;
|
|
||||||
id: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
function HistoryOfActions(props: HistoryProps) {
|
|
||||||
const theme = useTheme();
|
|
||||||
const searchParams = new URLSearchParams(location.search);
|
|
||||||
|
|
||||||
const [history, setHistory] = useState<Action[]>([]);
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const tokencontext = useContext(TokenContext);
|
|
||||||
const { removeToken } = tokencontext;
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
axiosConfig
|
|
||||||
.get(`/GetHistoryForInstallation?id=${props.id}`)
|
|
||||||
.then((res: AxiosResponse<Action[]>) => {
|
|
||||||
setHistory(res.data);
|
|
||||||
})
|
|
||||||
.catch((err: AxiosError) => {
|
|
||||||
if (err.response && err.response.status == 401) {
|
|
||||||
removeToken();
|
|
||||||
navigate(routes.login);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Container maxWidth="xl">
|
|
||||||
<Grid container>
|
|
||||||
<Grid item xs={12} md={12}>
|
|
||||||
{history.length > 0 && (
|
|
||||||
<Card sx={{ marginTop: '10px' }}>
|
|
||||||
<Divider />
|
|
||||||
<div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: '40px',
|
|
||||||
marginBottom: '10px',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<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="user" defaultMessage="User" />
|
|
||||||
</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="date" defaultMessage="Date" />
|
|
||||||
</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="time" defaultMessage="Time" />
|
|
||||||
</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="seen" defaultMessage="Seen" />*/}
|
|
||||||
{/* </Typography>*/}
|
|
||||||
{/*</div>*/}
|
|
||||||
</div>
|
|
||||||
<Divider />
|
|
||||||
<div style={{ maxHeight: '400px', overflowY: 'auto' }}>
|
|
||||||
{history.map((action, index) => (
|
|
||||||
<>
|
|
||||||
<Divider />
|
|
||||||
<div
|
|
||||||
key={index}
|
|
||||||
style={{
|
|
||||||
height: '40px',
|
|
||||||
marginBottom: '10px',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex: 1,
|
|
||||||
marginTop: '15px',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Typography
|
|
||||||
variant="body1"
|
|
||||||
fontWeight="bold"
|
|
||||||
color="text.primary"
|
|
||||||
gutterBottom
|
|
||||||
noWrap
|
|
||||||
>
|
|
||||||
{action.user}
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex: 1,
|
|
||||||
marginTop: '15px',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Typography
|
|
||||||
variant="body1"
|
|
||||||
fontWeight="bold"
|
|
||||||
color="text.primary"
|
|
||||||
gutterBottom
|
|
||||||
noWrap
|
|
||||||
>
|
|
||||||
{action.date}
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex: 1,
|
|
||||||
marginTop: '15px',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Typography
|
|
||||||
variant="body1"
|
|
||||||
fontWeight="bold"
|
|
||||||
color="text.primary"
|
|
||||||
gutterBottom
|
|
||||||
noWrap
|
|
||||||
>
|
|
||||||
{action.time}
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!props.errorLoadingS3Data && history.length == 0 && (
|
|
||||||
<Alert
|
|
||||||
severity="error"
|
|
||||||
sx={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
marginTop: '20px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id="nohistory"
|
|
||||||
defaultMessage="There is no history of actions"
|
|
||||||
/>
|
|
||||||
<IconButton
|
|
||||||
color="inherit"
|
|
||||||
size="small"
|
|
||||||
sx={{ marginLeft: '4px' }}
|
|
||||||
></IconButton>
|
|
||||||
</Alert>
|
|
||||||
)}
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Grid item xs={12} md={12} style={{ marginBottom: '20px' }}>
|
|
||||||
{props.errorLoadingS3Data && (
|
|
||||||
<Alert
|
|
||||||
severity="error"
|
|
||||||
sx={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
marginTop: '20px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id="cannotloadloggingdata"
|
|
||||||
defaultMessage="Cannot load logging data"
|
|
||||||
/>
|
|
||||||
<IconButton
|
|
||||||
color="inherit"
|
|
||||||
size="small"
|
|
||||||
sx={{ marginLeft: '4px' }}
|
|
||||||
></IconButton>
|
|
||||||
</Alert>
|
|
||||||
)}
|
|
||||||
</Grid>
|
|
||||||
</Container>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default HistoryOfActions;
|
|
|
@ -23,7 +23,6 @@ import routes from '../../../Resources/routes.json';
|
||||||
import Information from '../Information/Information';
|
import Information from '../Information/Information';
|
||||||
import BatteryView from '../BatteryView/BatteryView';
|
import BatteryView from '../BatteryView/BatteryView';
|
||||||
import { UserType } from '../../../interfaces/UserTypes';
|
import { UserType } from '../../../interfaces/UserTypes';
|
||||||
import HistoryOfActions from '../History/History';
|
|
||||||
|
|
||||||
interface singleInstallationProps {
|
interface singleInstallationProps {
|
||||||
current_installation?: I_Installation;
|
current_installation?: I_Installation;
|
||||||
|
@ -310,20 +309,6 @@ function Installation(props: singleInstallationProps) {
|
||||||
></BatteryView>
|
></BatteryView>
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
<Route
|
|
||||||
path={routes.pvview + '*'}
|
|
||||||
element={
|
|
||||||
<PvView
|
|
||||||
values={values}
|
|
||||||
s3Credentials={s3Credentials}
|
|
||||||
installationId={props.current_installation.id}
|
|
||||||
productNum={props.current_installation.product}
|
|
||||||
connected={connected}
|
|
||||||
></PvView>
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path={routes.overview}
|
path={routes.overview}
|
||||||
element={<Overview s3Credentials={s3Credentials}></Overview>}
|
element={<Overview s3Credentials={s3Credentials}></Overview>}
|
||||||
|
@ -357,18 +342,6 @@ function Installation(props: singleInstallationProps) {
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{currentUser.userType == UserType.admin && (
|
|
||||||
<Route
|
|
||||||
path={routes.history}
|
|
||||||
element={
|
|
||||||
<HistoryOfActions
|
|
||||||
errorLoadingS3Data={errorLoadingS3Data}
|
|
||||||
id={props.current_installation.id}
|
|
||||||
></HistoryOfActions>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{currentUser.userType == UserType.admin && (
|
{currentUser.userType == UserType.admin && (
|
||||||
<Route
|
<Route
|
||||||
path={routes.manage}
|
path={routes.manage}
|
||||||
|
|
|
@ -26,9 +26,7 @@ function InstallationTabs() {
|
||||||
'batteryview',
|
'batteryview',
|
||||||
'log',
|
'log',
|
||||||
'information',
|
'information',
|
||||||
'configuration',
|
'configuration'
|
||||||
'history',
|
|
||||||
'pvview'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const [currentTab, setCurrentTab] = useState<string>(undefined);
|
const [currentTab, setCurrentTab] = useState<string>(undefined);
|
||||||
|
@ -139,19 +137,6 @@ function InstallationTabs() {
|
||||||
defaultMessage="Configuration"
|
defaultMessage="Configuration"
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
|
||||||
// {
|
|
||||||
// value: 'history',
|
|
||||||
// label: (
|
|
||||||
// <FormattedMessage
|
|
||||||
// id="history"
|
|
||||||
// defaultMessage="History Of Actions"
|
|
||||||
// />
|
|
||||||
// )
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
value: 'pvview',
|
|
||||||
label: <FormattedMessage id="pvview" defaultMessage="Pv View" />
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
: currentUser.userType == UserType.partner
|
: currentUser.userType == UserType.partner
|
||||||
|
@ -173,10 +158,6 @@ function InstallationTabs() {
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
|
||||||
value: 'pvview',
|
|
||||||
label: <FormattedMessage id="pvview" defaultMessage="Pv View" />
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
value: 'information',
|
value: 'information',
|
||||||
|
@ -236,10 +217,6 @@ function InstallationTabs() {
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
|
||||||
value: 'pvview',
|
|
||||||
label: <FormattedMessage id="pvview" defaultMessage="Pv View" />
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
value: 'manage',
|
value: 'manage',
|
||||||
label: (
|
label: (
|
||||||
|
@ -272,15 +249,6 @@ function InstallationTabs() {
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// {
|
|
||||||
// value: 'history',
|
|
||||||
// label: (
|
|
||||||
// <FormattedMessage
|
|
||||||
// id="history"
|
|
||||||
// defaultMessage="History Of Actions"
|
|
||||||
// />
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
]
|
]
|
||||||
: currentUser.userType == UserType.partner
|
: currentUser.userType == UserType.partner
|
||||||
? [
|
? [
|
||||||
|
@ -312,10 +280,6 @@ function InstallationTabs() {
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
|
||||||
value: 'pvview',
|
|
||||||
label: <FormattedMessage id="pvview" defaultMessage="Pv View" />
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
value: 'information',
|
value: 'information',
|
||||||
|
|
|
@ -35,8 +35,6 @@ export type ConfigurationValues = {
|
||||||
calibrationChargeDate: Date | null;
|
calibrationChargeDate: Date | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface Pv {}
|
|
||||||
|
|
||||||
export interface Battery {
|
export interface Battery {
|
||||||
BatteryId: number;
|
BatteryId: number;
|
||||||
FwVersion: I_BoxDataValue;
|
FwVersion: I_BoxDataValue;
|
||||||
|
@ -165,19 +163,11 @@ export type TopologyValues = {
|
||||||
additionalCalibrationChargeDate: I_BoxDataValue[];
|
additionalCalibrationChargeDate: I_BoxDataValue[];
|
||||||
|
|
||||||
batteryView: Battery[];
|
batteryView: Battery[];
|
||||||
|
|
||||||
pvView: Pv[];
|
|
||||||
};
|
};
|
||||||
type TopologyPaths = { [key in keyof TopologyValues]: string[] };
|
type TopologyPaths = { [key in keyof TopologyValues]: string[] };
|
||||||
|
|
||||||
const batteryIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
const batteryIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||||
|
|
||||||
const PvPaths = [
|
|
||||||
'/PvOnDc/Strings/%id%/Voltage',
|
|
||||||
'/PvOnDc/Strings/%id%/Current',
|
|
||||||
'/PvOnDc/Strings/%id%/Power'
|
|
||||||
];
|
|
||||||
|
|
||||||
const batteryPaths = [
|
const batteryPaths = [
|
||||||
'/Battery/Devices/%id%/FwVersion',
|
'/Battery/Devices/%id%/FwVersion',
|
||||||
'/Battery/Devices/%id%/Dc/Power',
|
'/Battery/Devices/%id%/Dc/Power',
|
||||||
|
@ -300,10 +290,6 @@ export const topologyPaths: TopologyPaths = {
|
||||||
batteryPaths.map((path) => path.replace('%id%', id.toString()))
|
batteryPaths.map((path) => path.replace('%id%', id.toString()))
|
||||||
),
|
),
|
||||||
|
|
||||||
pvView: batteryIds.flatMap((id) =>
|
|
||||||
PvPaths.map((path) => path.replace('%id%', id.toString()))
|
|
||||||
),
|
|
||||||
|
|
||||||
minimumSoC: ['/Config/MinSoc'],
|
minimumSoC: ['/Config/MinSoc'],
|
||||||
installedDcDcPower: ['/DcDc/SystemControl/NumberOfConnectedSlaves'],
|
installedDcDcPower: ['/DcDc/SystemControl/NumberOfConnectedSlaves'],
|
||||||
gridSetPoint: ['/Config/GridSetPoint'],
|
gridSetPoint: ['/Config/GridSetPoint'],
|
||||||
|
|
|
@ -119,8 +119,8 @@ function Overview(props: OverviewProps) {
|
||||||
chartOverview: overviewInterface;
|
chartOverview: overviewInterface;
|
||||||
}> = transformInputToDailyData(
|
}> = transformInputToDailyData(
|
||||||
props.s3Credentials,
|
props.s3Credentials,
|
||||||
UnixTime.fromTicks(startX).earlier(TimeSpan.fromHours(2)),
|
UnixTime.fromTicks(startX),
|
||||||
UnixTime.fromTicks(endX).earlier(TimeSpan.fromHours(2))
|
UnixTime.fromTicks(endX)
|
||||||
);
|
);
|
||||||
|
|
||||||
let isComponentMounted = true;
|
let isComponentMounted = true;
|
||||||
|
|
|
@ -58,28 +58,6 @@ function Installation(props: singleInstallationProps) {
|
||||||
|
|
||||||
const s3Credentials = { s3Bucket, ...S3data };
|
const s3Credentials = { s3Bucket, ...S3data };
|
||||||
|
|
||||||
const fetchDataOnlyOneTime = async () => {
|
|
||||||
var timeperiodToSearch = 70;
|
|
||||||
|
|
||||||
for (var i = timeperiodToSearch; i > 0; i -= 2) {
|
|
||||||
const now = UnixTime.now().earlier(TimeSpan.fromSeconds(i));
|
|
||||||
|
|
||||||
const res = await fetchData(now, s3Credentials);
|
|
||||||
|
|
||||||
if (res != FetchResult.notAvailable && res != FetchResult.tryLater) {
|
|
||||||
setConnected(true);
|
|
||||||
setFailedToCommunicateWithInstallation(0);
|
|
||||||
setValues(
|
|
||||||
extractValues({
|
|
||||||
time: now,
|
|
||||||
value: res
|
|
||||||
})
|
|
||||||
);
|
|
||||||
return now;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchDataPeriodically = async () => {
|
const fetchDataPeriodically = async () => {
|
||||||
const now = UnixTime.now().earlier(TimeSpan.fromSeconds(20));
|
const now = UnixTime.now().earlier(TimeSpan.fromSeconds(20));
|
||||||
|
|
||||||
|
@ -98,7 +76,7 @@ function Installation(props: singleInstallationProps) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
setFailedToCommunicateWithInstallation((prevCount) => {
|
setFailedToCommunicateWithInstallation((prevCount) => {
|
||||||
if (prevCount + 1 >= 20) {
|
if (prevCount + 1 >= 3) {
|
||||||
setConnected(false);
|
setConnected(false);
|
||||||
}
|
}
|
||||||
return prevCount + 1;
|
return prevCount + 1;
|
||||||
|
@ -109,6 +87,19 @@ function Installation(props: singleInstallationProps) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchDataOnlyOneTime = async () => {
|
||||||
|
let success = false;
|
||||||
|
const max_retransmissions = 3;
|
||||||
|
|
||||||
|
for (let i = 0; i < max_retransmissions; i++) {
|
||||||
|
success = await fetchDataPeriodically();
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||||
|
if (success) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let path = location.split('/');
|
let path = location.split('/');
|
||||||
|
|
||||||
|
@ -127,7 +118,7 @@ function Installation(props: singleInstallationProps) {
|
||||||
currentTab == 'live' ||
|
currentTab == 'live' ||
|
||||||
(location.includes('batteryview') && !location.includes('mainstats'))
|
(location.includes('batteryview') && !location.includes('mainstats'))
|
||||||
) {
|
) {
|
||||||
fetchDataOnlyOneTime();
|
fetchDataPeriodically();
|
||||||
interval = setInterval(fetchDataPeriodically, 2000);
|
interval = setInterval(fetchDataPeriodically, 2000);
|
||||||
}
|
}
|
||||||
if (currentTab == 'configuration' || location.includes('mainstats')) {
|
if (currentTab == 'configuration' || location.includes('mainstats')) {
|
||||||
|
|
|
@ -222,7 +222,6 @@ function Topology(props: TopologyProps) {
|
||||||
}}
|
}}
|
||||||
bottomBox={{
|
bottomBox={{
|
||||||
title: 'AC Loads',
|
title: 'AC Loads',
|
||||||
|
|
||||||
data: props.values.islandBusToLoadOnIslandBusConnection,
|
data: props.values.islandBusToLoadOnIslandBusConnection,
|
||||||
connected:
|
connected:
|
||||||
props.values.loadOnIslandBusBox[0].value.toString() !=
|
props.values.loadOnIslandBusBox[0].value.toString() !=
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import { ConfigurationValues } from '../content/dashboards/Log/graph.util';
|
|
||||||
|
|
||||||
export interface I_S3Credentials {
|
export interface I_S3Credentials {
|
||||||
s3Region: string;
|
s3Region: string;
|
||||||
s3Provider: string;
|
s3Provider: string;
|
||||||
|
@ -18,10 +16,3 @@ export interface ErrorMessage {
|
||||||
deviceCreatedTheMessage: string;
|
deviceCreatedTheMessage: string;
|
||||||
seen: boolean;
|
seen: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Action {
|
|
||||||
configuration: ConfigurationValues;
|
|
||||||
date: string;
|
|
||||||
time: string;
|
|
||||||
user: string;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue