Compare commits
No commits in common. "e6c32b716234f6e7f94062f882fb72589cd1c2e0" and "b0117e514879999947ed943ae2e6d6e01c44c443" have entirely different histories.
e6c32b7162
...
b0117e5148
|
@ -29,6 +29,7 @@ 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';
|
import { UserContext } from '../../../contexts/userContext';
|
||||||
|
|
||||||
interface ConfigurationProps {
|
interface ConfigurationProps {
|
||||||
|
@ -135,6 +136,14 @@ function Configuration(props: ConfigurationProps) {
|
||||||
.add(localOffset, 'minute')
|
.add(localOffset, 'minute')
|
||||||
.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);
|
||||||
|
@ -151,10 +160,23 @@ 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 = () => {
|
||||||
|
|
|
@ -122,42 +122,30 @@ function HistoryOfActions(props: HistoryProps) {
|
||||||
<FormattedMessage id="time" defaultMessage="Time" />
|
<FormattedMessage id="time" defaultMessage="Time" />
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
<div
|
{/*<div*/}
|
||||||
style={{
|
{/* style={{*/}
|
||||||
flex: 1,
|
{/* flex: 1,*/}
|
||||||
marginTop: '15px',
|
{/* marginTop: '15px',*/}
|
||||||
display: 'flex',
|
{/* display: 'flex',*/}
|
||||||
alignItems: 'center',
|
{/* alignItems: 'center',*/}
|
||||||
justifyContent: 'center'
|
{/* justifyContent: 'center'*/}
|
||||||
}}
|
{/* }}*/}
|
||||||
>
|
{/*>*/}
|
||||||
<Typography
|
{/* <Typography*/}
|
||||||
variant="body1"
|
{/* variant="body1"*/}
|
||||||
color="dimgrey"
|
{/* color="dimgrey"*/}
|
||||||
fontWeight="bold"
|
{/* fontWeight="bold"*/}
|
||||||
fontSize="1rem"
|
{/* fontSize="1rem"*/}
|
||||||
gutterBottom
|
{/* gutterBottom*/}
|
||||||
noWrap
|
{/* noWrap*/}
|
||||||
>
|
{/* >*/}
|
||||||
<FormattedMessage
|
{/* <FormattedMessage id="seen" defaultMessage="Seen" />*/}
|
||||||
id="description"
|
{/* </Typography>*/}
|
||||||
defaultMessage="Description"
|
{/*</div>*/}
|
||||||
/>
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<Divider />
|
<Divider />
|
||||||
<div style={{ maxHeight: '400px', overflowY: 'auto' }}>
|
<div style={{ maxHeight: '400px', overflowY: 'auto' }}>
|
||||||
{history.map((action, index) => {
|
{history.map((action, index) => (
|
||||||
// Parse the timestamp string to a Date object
|
|
||||||
const date = new Date(action.timestamp);
|
|
||||||
|
|
||||||
// Extract the date part (e.g., "2023-05-31")
|
|
||||||
const datePart = date.toLocaleDateString();
|
|
||||||
|
|
||||||
// Extract the time part (e.g., "12:34:56")
|
|
||||||
const timePart = date.toLocaleTimeString();
|
|
||||||
return (
|
|
||||||
<>
|
<>
|
||||||
<Divider />
|
<Divider />
|
||||||
<div
|
<div
|
||||||
|
@ -185,7 +173,7 @@ function HistoryOfActions(props: HistoryProps) {
|
||||||
gutterBottom
|
gutterBottom
|
||||||
noWrap
|
noWrap
|
||||||
>
|
>
|
||||||
{action.userName}
|
{action.user}
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -205,7 +193,7 @@ function HistoryOfActions(props: HistoryProps) {
|
||||||
gutterBottom
|
gutterBottom
|
||||||
noWrap
|
noWrap
|
||||||
>
|
>
|
||||||
{datePart}
|
{action.date}
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -224,33 +212,12 @@ function HistoryOfActions(props: HistoryProps) {
|
||||||
gutterBottom
|
gutterBottom
|
||||||
noWrap
|
noWrap
|
||||||
>
|
>
|
||||||
{timePart}
|
{action.time}
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex: 3,
|
|
||||||
display: 'flex',
|
|
||||||
marginTop: '15px',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Typography
|
|
||||||
variant="body1"
|
|
||||||
fontWeight="bold"
|
|
||||||
color="text.primary"
|
|
||||||
gutterBottom
|
|
||||||
noWrap
|
|
||||||
>
|
|
||||||
{action.description}
|
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
))}
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
@ -24,7 +24,6 @@ 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';
|
import HistoryOfActions from '../History/History';
|
||||||
import PvView from '../PvView/PvView';
|
|
||||||
|
|
||||||
interface singleInstallationProps {
|
interface singleInstallationProps {
|
||||||
current_installation?: I_Installation;
|
current_installation?: I_Installation;
|
||||||
|
@ -125,7 +124,6 @@ function Installation(props: singleInstallationProps) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
currentTab == 'live' ||
|
currentTab == 'live' ||
|
||||||
currentTab == 'pvview' ||
|
|
||||||
currentTab == 'configuration' ||
|
currentTab == 'configuration' ||
|
||||||
location.includes('batteryview')
|
location.includes('batteryview')
|
||||||
) {
|
) {
|
||||||
|
@ -133,8 +131,7 @@ function Installation(props: singleInstallationProps) {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
currentTab == 'live' ||
|
currentTab == 'live' ||
|
||||||
(location.includes('batteryview') && !location.includes('mainstats')) ||
|
(location.includes('batteryview') && !location.includes('mainstats'))
|
||||||
currentTab == 'pvview'
|
|
||||||
) {
|
) {
|
||||||
fetchDataPeriodically();
|
fetchDataPeriodically();
|
||||||
interval = setInterval(fetchDataPeriodically, 2000);
|
interval = setInterval(fetchDataPeriodically, 2000);
|
||||||
|
@ -147,7 +144,6 @@ function Installation(props: singleInstallationProps) {
|
||||||
return () => {
|
return () => {
|
||||||
if (
|
if (
|
||||||
currentTab == 'live' ||
|
currentTab == 'live' ||
|
||||||
currentTab == 'pvview' ||
|
|
||||||
(location.includes('batteryview') && !location.includes('mainstats'))
|
(location.includes('batteryview') && !location.includes('mainstats'))
|
||||||
) {
|
) {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
|
@ -318,7 +314,13 @@ function Installation(props: singleInstallationProps) {
|
||||||
<Route
|
<Route
|
||||||
path={routes.pvview + '*'}
|
path={routes.pvview + '*'}
|
||||||
element={
|
element={
|
||||||
<PvView values={values} connected={connected}></PvView>
|
<PvView
|
||||||
|
values={values}
|
||||||
|
s3Credentials={s3Credentials}
|
||||||
|
installationId={props.current_installation.id}
|
||||||
|
productNum={props.current_installation.product}
|
||||||
|
connected={connected}
|
||||||
|
></PvView>
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
|
|
|
@ -140,15 +140,15 @@ function InstallationTabs() {
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
value: 'history',
|
// value: 'history',
|
||||||
label: (
|
// label: (
|
||||||
<FormattedMessage
|
// <FormattedMessage
|
||||||
id="history"
|
// id="history"
|
||||||
defaultMessage="History Of Actions"
|
// defaultMessage="History Of Actions"
|
||||||
/>
|
// />
|
||||||
)
|
// )
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
value: 'pvview',
|
value: 'pvview',
|
||||||
label: <FormattedMessage id="pvview" defaultMessage="Pv View" />
|
label: <FormattedMessage id="pvview" defaultMessage="Pv View" />
|
||||||
|
@ -271,16 +271,16 @@ function InstallationTabs() {
|
||||||
defaultMessage="Configuration"
|
defaultMessage="Configuration"
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'history',
|
|
||||||
label: (
|
|
||||||
<FormattedMessage
|
|
||||||
id="history"
|
|
||||||
defaultMessage="History Of Actions"
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
// {
|
||||||
|
// value: 'history',
|
||||||
|
// label: (
|
||||||
|
// <FormattedMessage
|
||||||
|
// id="history"
|
||||||
|
// defaultMessage="History Of Actions"
|
||||||
|
// />
|
||||||
|
// )
|
||||||
|
// }
|
||||||
]
|
]
|
||||||
: currentUser.userType == UserType.partner
|
: currentUser.userType == UserType.partner
|
||||||
? [
|
? [
|
||||||
|
|
|
@ -35,12 +35,7 @@ export type ConfigurationValues = {
|
||||||
calibrationChargeDate: Date | null;
|
calibrationChargeDate: Date | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface Pv {
|
export interface Pv {}
|
||||||
PvId: number;
|
|
||||||
Power: I_BoxDataValue;
|
|
||||||
Voltage: I_BoxDataValue;
|
|
||||||
Current: I_BoxDataValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Battery {
|
export interface Battery {
|
||||||
BatteryId: number;
|
BatteryId: number;
|
||||||
|
@ -86,8 +81,6 @@ export interface Battery {
|
||||||
MaxDischargePower: I_BoxDataValue;
|
MaxDischargePower: I_BoxDataValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PvKeys = ['PvId', 'Power', 'Voltage', 'Current'];
|
|
||||||
|
|
||||||
const BatteryKeys = [
|
const BatteryKeys = [
|
||||||
'BatteryId',
|
'BatteryId',
|
||||||
'FwVersion',
|
'FwVersion',
|
||||||
|
@ -179,15 +172,10 @@ 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 pvIds = [
|
|
||||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
|
|
||||||
23, 24, 25, 26, 27, 28, 29, 30
|
|
||||||
];
|
|
||||||
|
|
||||||
const PvPaths = [
|
const PvPaths = [
|
||||||
'/PvOnDc/Strings/%id%/Power',
|
|
||||||
'/PvOnDc/Strings/%id%/Voltage',
|
'/PvOnDc/Strings/%id%/Voltage',
|
||||||
'/PvOnDc/Strings/%id%/Current'
|
'/PvOnDc/Strings/%id%/Current',
|
||||||
|
'/PvOnDc/Strings/%id%/Power'
|
||||||
];
|
];
|
||||||
|
|
||||||
const batteryPaths = [
|
const batteryPaths = [
|
||||||
|
@ -312,7 +300,7 @@ export const topologyPaths: TopologyPaths = {
|
||||||
batteryPaths.map((path) => path.replace('%id%', id.toString()))
|
batteryPaths.map((path) => path.replace('%id%', id.toString()))
|
||||||
),
|
),
|
||||||
|
|
||||||
pvView: pvIds.flatMap((id) =>
|
pvView: batteryIds.flatMap((id) =>
|
||||||
PvPaths.map((path) => path.replace('%id%', id.toString()))
|
PvPaths.map((path) => path.replace('%id%', id.toString()))
|
||||||
),
|
),
|
||||||
|
|
||||||
|
@ -343,47 +331,15 @@ export const extractValues = (
|
||||||
timeSeriesData: DataPoint
|
timeSeriesData: DataPoint
|
||||||
): TopologyValues | null => {
|
): TopologyValues | null => {
|
||||||
const extractedValues: TopologyValues = {} as TopologyValues;
|
const extractedValues: TopologyValues = {} as TopologyValues;
|
||||||
|
|
||||||
|
// console.log('timeSeriesData=', timeSeriesData);
|
||||||
|
|
||||||
for (const topologyKey of Object.keys(topologyPaths)) {
|
for (const topologyKey of Object.keys(topologyPaths)) {
|
||||||
//Each topologykey may have more than one paths (for example inverter)
|
//Each topologykey may have more than one paths (for example inverter)
|
||||||
const paths = topologyPaths[topologyKey];
|
const paths = topologyPaths[topologyKey];
|
||||||
let topologyValues: { unit: string; value: string | number }[] = [];
|
let topologyValues: { unit: string; value: string | number }[] = [];
|
||||||
|
|
||||||
if (topologyKey === 'pvView') {
|
if (topologyKey === 'batteryView') {
|
||||||
extractedValues[topologyKey] = [];
|
|
||||||
let pv_index = 0;
|
|
||||||
let pathIndex = 0;
|
|
||||||
|
|
||||||
while (pathIndex < paths.length) {
|
|
||||||
let pv = {};
|
|
||||||
let existingKeys = 0;
|
|
||||||
|
|
||||||
//We prepare a pv object for each node. We extract the number of nodes from the '/PvOnDc/NbrOfStrings' path.
|
|
||||||
//PvKeys[0] is the pv id.
|
|
||||||
pv[PvKeys[0]] = pv_index;
|
|
||||||
//Then, search all the remaining battery keys
|
|
||||||
for (let i = 1; i < PvKeys.length; i++) {
|
|
||||||
const path = paths[pathIndex];
|
|
||||||
if (timeSeriesData.value.hasOwnProperty(path)) {
|
|
||||||
existingKeys++;
|
|
||||||
|
|
||||||
pv[PvKeys[i]] = {
|
|
||||||
unit: timeSeriesData.value[path].unit.includes('~')
|
|
||||||
? timeSeriesData.value[path].unit.replace('~', '')
|
|
||||||
: timeSeriesData.value[path].unit,
|
|
||||||
value:
|
|
||||||
typeof timeSeriesData.value[path].value === 'string'
|
|
||||||
? timeSeriesData.value[path].value
|
|
||||||
: Number(timeSeriesData.value[path].value).toFixed(1)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pathIndex++;
|
|
||||||
}
|
|
||||||
pv_index++;
|
|
||||||
if (existingKeys > 0) {
|
|
||||||
extractedValues[topologyKey].push(pv as Pv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (topologyKey === 'batteryView') {
|
|
||||||
extractedValues[topologyKey] = [];
|
extractedValues[topologyKey] = [];
|
||||||
const node_ids_from_csv = timeSeriesData.value[
|
const node_ids_from_csv = timeSeriesData.value[
|
||||||
'/Config/Devices/BatteryNodes'
|
'/Config/Devices/BatteryNodes'
|
||||||
|
|
|
@ -1,187 +0,0 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
|
||||||
import {
|
|
||||||
Container,
|
|
||||||
Paper,
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableContainer,
|
|
||||||
TableHead,
|
|
||||||
TableRow,
|
|
||||||
Typography
|
|
||||||
} from '@mui/material';
|
|
||||||
import { TopologyValues } from '../Log/graph.util';
|
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
|
||||||
import routes from '../../../Resources/routes.json';
|
|
||||||
import CircularProgress from '@mui/material/CircularProgress';
|
|
||||||
|
|
||||||
interface PvViewProps {
|
|
||||||
values: TopologyValues;
|
|
||||||
connected: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
function PvView(props: PvViewProps) {
|
|
||||||
if (props.values === null && props.connected == true) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const currentLocation = useLocation();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const sortedPvView =
|
|
||||||
props.values != null
|
|
||||||
? [...props.values.pvView].sort((a, b) => a.PvId - b.PvId)
|
|
||||||
: [];
|
|
||||||
|
|
||||||
const [loading, setLoading] = useState(sortedPvView.length == 0);
|
|
||||||
|
|
||||||
const handleMainStatsButton = () => {
|
|
||||||
navigate(routes.mainstats);
|
|
||||||
};
|
|
||||||
|
|
||||||
const findBatteryData = (batteryId: number) => {
|
|
||||||
for (let i = 0; i < props.values.batteryView.length; i++) {
|
|
||||||
if (props.values.batteryView[i].BatteryId == batteryId) {
|
|
||||||
return props.values.batteryView[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (sortedPvView.length == 0) {
|
|
||||||
setLoading(true);
|
|
||||||
} else {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
}, [sortedPvView]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{!props.connected && (
|
|
||||||
<Container
|
|
||||||
maxWidth="xl"
|
|
||||||
sx={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
height: '70vh'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CircularProgress size={60} style={{ color: '#ffc04d' }} />
|
|
||||||
<Typography
|
|
||||||
variant="body2"
|
|
||||||
style={{ color: 'black', fontWeight: 'bold' }}
|
|
||||||
mt={2}
|
|
||||||
>
|
|
||||||
Unable to communicate with the installation
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body2" style={{ color: 'black' }}>
|
|
||||||
Please wait or refresh the page
|
|
||||||
</Typography>
|
|
||||||
</Container>
|
|
||||||
)}
|
|
||||||
{loading && props.connected && (
|
|
||||||
<Container
|
|
||||||
maxWidth="xl"
|
|
||||||
sx={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
height: '70vh'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CircularProgress size={60} style={{ color: '#ffc04d' }} />
|
|
||||||
<Typography
|
|
||||||
variant="body2"
|
|
||||||
style={{ color: 'black', fontWeight: 'bold' }}
|
|
||||||
mt={2}
|
|
||||||
>
|
|
||||||
Battery service is not available at the moment
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body2" style={{ color: 'black' }}>
|
|
||||||
Please wait or refresh the page
|
|
||||||
</Typography>
|
|
||||||
</Container>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!loading && props.connected && (
|
|
||||||
<Container maxWidth="xl">
|
|
||||||
<TableContainer
|
|
||||||
component={Paper}
|
|
||||||
sx={{
|
|
||||||
marginTop: '20px',
|
|
||||||
marginBottom: '20px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Table sx={{ minWidth: 250 }} aria-label="simple table">
|
|
||||||
<TableHead>
|
|
||||||
<TableRow>
|
|
||||||
<TableCell align="center">Pv</TableCell>
|
|
||||||
<TableCell align="center">Power</TableCell>
|
|
||||||
<TableCell align="center">Voltage</TableCell>
|
|
||||||
<TableCell align="center">Current</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
</TableHead>
|
|
||||||
<TableBody>
|
|
||||||
{sortedPvView.map((pv) => (
|
|
||||||
<TableRow
|
|
||||||
key={pv.PvId}
|
|
||||||
style={{
|
|
||||||
height: '10px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TableCell
|
|
||||||
component="th"
|
|
||||||
scope="row"
|
|
||||||
align="center"
|
|
||||||
sx={{ width: '10%', fontWeight: 'bold', color: 'black' }}
|
|
||||||
>
|
|
||||||
{'String ' + pv.PvId}
|
|
||||||
</TableCell>
|
|
||||||
|
|
||||||
<TableCell
|
|
||||||
sx={{
|
|
||||||
width: '10%',
|
|
||||||
textAlign: 'center',
|
|
||||||
backgroundColor:
|
|
||||||
pv.Current.value == 0 ? '#FF033E' : '#32CD32',
|
|
||||||
color: pv.Power.value === '' ? 'white' : 'inherit'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{pv.Power.value + ' ' + pv.Power.unit}
|
|
||||||
</TableCell>
|
|
||||||
<TableCell
|
|
||||||
sx={{
|
|
||||||
width: '10%',
|
|
||||||
textAlign: 'center',
|
|
||||||
|
|
||||||
backgroundColor:
|
|
||||||
pv.Current.value == 0 ? '#FF033E' : '#32CD32',
|
|
||||||
color: pv.Voltage.value === '' ? 'white' : 'inherit'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{pv.Voltage.value + ' ' + pv.Voltage.unit}
|
|
||||||
</TableCell>
|
|
||||||
<TableCell
|
|
||||||
sx={{
|
|
||||||
width: '10%',
|
|
||||||
textAlign: 'center',
|
|
||||||
backgroundColor:
|
|
||||||
pv.Current.value == 0 ? '#FF033E' : '#32CD32',
|
|
||||||
color: pv.Current.value === '' ? 'white' : 'inherit'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{pv.Current.value + ' ' + pv.Current.unit}
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</TableContainer>
|
|
||||||
</Container>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default PvView;
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
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,9 +20,8 @@ export interface ErrorMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Action {
|
export interface Action {
|
||||||
id: number;
|
configuration: ConfigurationValues;
|
||||||
userName: string;
|
date: string;
|
||||||
installationId: number;
|
time: string;
|
||||||
timestamp: string;
|
user: string;
|
||||||
description: String;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue