Update frontend to support json using the same interfaces.
All the products use json over the same message interfaces. Salimax and sodistoreMax use the same files avoiding copying everything twice.
This commit is contained in:
parent
4f75912026
commit
5849507ad1
|
|
@ -30,7 +30,7 @@ function App() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const searchParams = new URLSearchParams(location.search);
|
const searchParams = new URLSearchParams(location.search);
|
||||||
const username = searchParams.get('username');
|
const username = searchParams.get('username');
|
||||||
const { setAccessToSalimax, setAccessToSalidomo,setAccessToSodiohome } =
|
const { setAccessToSalimax, setAccessToSalidomo, setAccessToSodiohome } =
|
||||||
useContext(ProductIdContext);
|
useContext(ProductIdContext);
|
||||||
|
|
||||||
const [language, setLanguage] = useState('en');
|
const [language, setLanguage] = useState('en');
|
||||||
|
|
@ -75,9 +75,9 @@ function App() {
|
||||||
setAccessToSodiohome(response.data.accessToSodiohome);
|
setAccessToSodiohome(response.data.accessToSodiohome);
|
||||||
if (response.data.accessToSalimax) {
|
if (response.data.accessToSalimax) {
|
||||||
navigate(routes.installations);
|
navigate(routes.installations);
|
||||||
} else if(response.data.accessToSalidomo){
|
} else if (response.data.accessToSalidomo) {
|
||||||
navigate(routes.salidomo_installations);
|
navigate(routes.salidomo_installations);
|
||||||
} else{
|
} else {
|
||||||
navigate(routes.sodiohome_installations);
|
navigate(routes.sodiohome_installations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -152,7 +152,16 @@ function App() {
|
||||||
path={routes.installations + '*'}
|
path={routes.installations + '*'}
|
||||||
element={
|
element={
|
||||||
<AccessContextProvider>
|
<AccessContextProvider>
|
||||||
<InstallationTabs />
|
<InstallationTabs product={0} />
|
||||||
|
</AccessContextProvider>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Route
|
||||||
|
path={routes.sodistore_installations + '*'}
|
||||||
|
element={
|
||||||
|
<AccessContextProvider>
|
||||||
|
<InstallationTabs product={3} />
|
||||||
</AccessContextProvider>
|
</AccessContextProvider>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
@ -161,7 +170,7 @@ function App() {
|
||||||
path={routes.salidomo_installations + '*'}
|
path={routes.salidomo_installations + '*'}
|
||||||
element={
|
element={
|
||||||
<AccessContextProvider>
|
<AccessContextProvider>
|
||||||
<SalidomoInstallationTabs />
|
<SalidomoInstallationTabs product={1} />
|
||||||
</AccessContextProvider>
|
</AccessContextProvider>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
"users": "/users/",
|
"users": "/users/",
|
||||||
"installations": "/installations/",
|
"installations": "/installations/",
|
||||||
"salidomo_installations": "/salidomo_installations/",
|
"salidomo_installations": "/salidomo_installations/",
|
||||||
|
"sodistore_installations": "/sodistore_installations/",
|
||||||
"sodiohome_installations": "/sodiohome_installations/",
|
"sodiohome_installations": "/sodiohome_installations/",
|
||||||
"installation": "installation/",
|
"installation": "installation/",
|
||||||
"login": "/login/",
|
"login": "/login/",
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,6 @@ function Configuration(props: ConfigurationProps) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('111111111111111111111111111111111111111111111111');
|
|
||||||
|
|
||||||
const CalibrationChargeOptions = [
|
const CalibrationChargeOptions = [
|
||||||
'Repetitive Calibration',
|
'Repetitive Calibration',
|
||||||
'Additional Calibration',
|
'Additional Calibration',
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useContext, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CircularProgress,
|
CircularProgress,
|
||||||
|
|
@ -18,6 +18,7 @@ import BuildIcon from '@mui/icons-material/Build';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
import routes from '../../../Resources/routes.json';
|
import routes from '../../../Resources/routes.json';
|
||||||
|
import { ProductIdContext } from '../../../contexts/ProductIdContextProvider';
|
||||||
|
|
||||||
interface FlatInstallationViewProps {
|
interface FlatInstallationViewProps {
|
||||||
installations: I_Installation[];
|
installations: I_Installation[];
|
||||||
|
|
@ -28,6 +29,7 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [selectedInstallation, setSelectedInstallation] = useState<number>(-1);
|
const [selectedInstallation, setSelectedInstallation] = useState<number>(-1);
|
||||||
const currentLocation = useLocation();
|
const currentLocation = useLocation();
|
||||||
|
const { product, setProduct } = useContext(ProductIdContext);
|
||||||
|
|
||||||
const sortedInstallations = [...props.installations].sort((a, b) => {
|
const sortedInstallations = [...props.installations].sort((a, b) => {
|
||||||
// Compare the status field of each installation and sort them based on the status.
|
// Compare the status field of each installation and sort them based on the status.
|
||||||
|
|
@ -45,17 +47,25 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleSelectOneInstallation = (installationID: number): void => {
|
const handleSelectOneInstallation = (installationID: number): void => {
|
||||||
|
console.log('when selecting installation', product);
|
||||||
if (selectedInstallation != installationID) {
|
if (selectedInstallation != installationID) {
|
||||||
setSelectedInstallation(installationID);
|
setSelectedInstallation(installationID);
|
||||||
setSelectedInstallation(-1);
|
setSelectedInstallation(-1);
|
||||||
|
|
||||||
navigate(
|
navigate(
|
||||||
routes.installations +
|
product === 0
|
||||||
routes.list +
|
? routes.installations +
|
||||||
routes.installation +
|
routes.list +
|
||||||
`${installationID}` +
|
routes.installation +
|
||||||
'/' +
|
`${installationID}` +
|
||||||
routes.live,
|
'/' +
|
||||||
|
routes.live
|
||||||
|
: routes.sodistore_installations +
|
||||||
|
routes.list +
|
||||||
|
routes.installation +
|
||||||
|
`${installationID}` +
|
||||||
|
'/' +
|
||||||
|
routes.live,
|
||||||
{
|
{
|
||||||
replace: true
|
replace: true
|
||||||
}
|
}
|
||||||
|
|
@ -82,7 +92,11 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => {
|
||||||
sx={{
|
sx={{
|
||||||
display:
|
display:
|
||||||
currentLocation.pathname === routes.installations + 'list' ||
|
currentLocation.pathname === routes.installations + 'list' ||
|
||||||
currentLocation.pathname === routes.installations + routes.list
|
currentLocation.pathname === routes.installations + routes.list ||
|
||||||
|
currentLocation.pathname ===
|
||||||
|
routes.sodistore_installations + 'list' ||
|
||||||
|
currentLocation.pathname ===
|
||||||
|
routes.sodistore_installations + routes.list
|
||||||
? 'block'
|
? 'block'
|
||||||
: 'none'
|
: 'none'
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useContext, useEffect, useState } from 'react';
|
||||||
import { FormControl, Grid, InputAdornment, TextField } from '@mui/material';
|
import { FormControl, Grid, InputAdornment, TextField } from '@mui/material';
|
||||||
import SearchTwoToneIcon from '@mui/icons-material/SearchTwoTone';
|
import SearchTwoToneIcon from '@mui/icons-material/SearchTwoTone';
|
||||||
import FlatInstallationView from 'src/content/dashboards/Installations/FlatInstallationView';
|
import FlatInstallationView from 'src/content/dashboards/Installations/FlatInstallationView';
|
||||||
|
|
@ -6,6 +6,7 @@ import { I_Installation } from '../../../interfaces/InstallationTypes';
|
||||||
import { Route, Routes, useLocation } from 'react-router-dom';
|
import { Route, Routes, useLocation } from 'react-router-dom';
|
||||||
import routes from '../../../Resources/routes.json';
|
import routes from '../../../Resources/routes.json';
|
||||||
import Installation from './Installation';
|
import Installation from './Installation';
|
||||||
|
import { ProductIdContext } from '../../../contexts/ProductIdContextProvider';
|
||||||
|
|
||||||
interface installationSearchProps {
|
interface installationSearchProps {
|
||||||
installations: I_Installation[];
|
installations: I_Installation[];
|
||||||
|
|
@ -15,6 +16,7 @@ function InstallationSearch(props: installationSearchProps) {
|
||||||
const [searchTerm, setSearchTerm] = useState('');
|
const [searchTerm, setSearchTerm] = useState('');
|
||||||
const currentLocation = useLocation();
|
const currentLocation = useLocation();
|
||||||
const [filteredData, setFilteredData] = useState(props.installations);
|
const [filteredData, setFilteredData] = useState(props.installations);
|
||||||
|
const { product, setProduct } = useContext(ProductIdContext);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const filtered = props.installations.filter(
|
const filtered = props.installations.filter(
|
||||||
|
|
@ -35,7 +37,11 @@ function InstallationSearch(props: installationSearchProps) {
|
||||||
sx={{
|
sx={{
|
||||||
display:
|
display:
|
||||||
currentLocation.pathname === routes.installations + 'list' ||
|
currentLocation.pathname === routes.installations + 'list' ||
|
||||||
currentLocation.pathname === routes.installations + routes.list
|
currentLocation.pathname === routes.installations + routes.list ||
|
||||||
|
currentLocation.pathname ===
|
||||||
|
routes.sodistore_installations + 'list' ||
|
||||||
|
currentLocation.pathname ===
|
||||||
|
routes.sodistore_installations + routes.list
|
||||||
? 'block'
|
? 'block'
|
||||||
: 'none'
|
: 'none'
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ export const fetchAggregatedDataJson = (
|
||||||
s3Credentials?: I_S3Credentials
|
s3Credentials?: I_S3Credentials
|
||||||
): Promise<FetchResult<any>> => {
|
): Promise<FetchResult<any>> => {
|
||||||
const s3Path = `${date}.json`;
|
const s3Path = `${date}.json`;
|
||||||
|
|
||||||
if (s3Credentials && s3Credentials.s3Bucket) {
|
if (s3Credentials && s3Credentials.s3Bucket) {
|
||||||
const s3Access = new S3Access(
|
const s3Access = new S3Access(
|
||||||
s3Credentials.s3Bucket,
|
s3Credentials.s3Bucket,
|
||||||
|
|
@ -81,7 +82,7 @@ export const fetchAggregatedDataJson = (
|
||||||
const zip = await JSZip.loadAsync(byteArray);
|
const zip = await JSZip.loadAsync(byteArray);
|
||||||
// Assuming the CSV file is named "data.csv" inside the ZIP archive
|
// Assuming the CSV file is named "data.csv" inside the ZIP archive
|
||||||
const jsonContent = await zip.file('data.json').async('text');
|
const jsonContent = await zip.file('data.json').async('text');
|
||||||
// console.log(jsonContent);
|
//console.log(jsonContent);
|
||||||
return JSON.parse(jsonContent);
|
return JSON.parse(jsonContent);
|
||||||
} else {
|
} else {
|
||||||
return Promise.resolve(FetchResult.notAvailable);
|
return Promise.resolve(FetchResult.notAvailable);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,11 @@ import Installation from './Installation';
|
||||||
import { UserType } from '../../../interfaces/UserTypes';
|
import { UserType } from '../../../interfaces/UserTypes';
|
||||||
import { ProductIdContext } from '../../../contexts/ProductIdContextProvider';
|
import { ProductIdContext } from '../../../contexts/ProductIdContextProvider';
|
||||||
|
|
||||||
function InstallationTabs() {
|
interface InstallationTabsProps {
|
||||||
|
product: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function InstallationTabs(props: InstallationTabsProps) {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const context = useContext(UserContext);
|
const context = useContext(UserContext);
|
||||||
const { currentUser } = context;
|
const { currentUser } = context;
|
||||||
|
|
@ -32,10 +36,10 @@ function InstallationTabs() {
|
||||||
];
|
];
|
||||||
|
|
||||||
const [currentTab, setCurrentTab] = useState<string>(undefined);
|
const [currentTab, setCurrentTab] = useState<string>(undefined);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
salimaxInstallations,
|
salimax_or_sodistore_Installations,
|
||||||
fetchAllInstallations,
|
fetchAllInstallations,
|
||||||
currentProduct,
|
|
||||||
socket,
|
socket,
|
||||||
openSocket,
|
openSocket,
|
||||||
closeSocket
|
closeSocket
|
||||||
|
|
@ -56,25 +60,14 @@ function InstallationTabs() {
|
||||||
}, [location]);
|
}, [location]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (salimaxInstallations.length === 0) {
|
setProduct(props.product);
|
||||||
fetchAllInstallations();
|
}, [props.product]);
|
||||||
}
|
|
||||||
}, [salimaxInstallations]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (salimaxInstallations && salimaxInstallations.length > 0) {
|
if (product == props.product) {
|
||||||
if (!socket) {
|
fetchAllInstallations(product);
|
||||||
openSocket(0);
|
|
||||||
} else if (currentProduct != 0) {
|
|
||||||
closeSocket();
|
|
||||||
openSocket(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, [salimaxInstallations, currentProduct]);
|
}, [product]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setProduct(0);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleTabsChange = (_event: ChangeEvent<{}>, value: string): void => {
|
const handleTabsChange = (_event: ChangeEvent<{}>, value: string): void => {
|
||||||
setCurrentTab(value);
|
setCurrentTab(value);
|
||||||
|
|
@ -378,7 +371,7 @@ function InstallationTabs() {
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
return salimaxInstallations.length > 1 ? (
|
return salimax_or_sodistore_Installations.length > 1 ? (
|
||||||
<>
|
<>
|
||||||
<Container maxWidth="xl" sx={{ marginTop: '20px' }} className="mainframe">
|
<Container maxWidth="xl" sx={{ marginTop: '20px' }} className="mainframe">
|
||||||
<TabsContainerWrapper>
|
<TabsContainerWrapper>
|
||||||
|
|
@ -421,17 +414,24 @@ function InstallationTabs() {
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Box p={4}>
|
<Box p={4}>
|
||||||
<InstallationSearch
|
<InstallationSearch
|
||||||
installations={salimaxInstallations}
|
installations={salimax_or_sodistore_Installations}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Grid>
|
</Grid>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Route path={routes.tree + '*'} element={<TreeView />} />
|
<Route path={routes.tree + '*'} element={<TreeView />} />
|
||||||
<Route
|
<Route
|
||||||
path={'*'}
|
path={'*'}
|
||||||
element={
|
element={
|
||||||
<Navigate to={routes.installations + routes.list}></Navigate>
|
props.product === 0 ? (
|
||||||
|
<Navigate to={routes.installations + routes.list} />
|
||||||
|
) : (
|
||||||
|
<Navigate
|
||||||
|
to={routes.sodistore_installations + routes.list}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
|
|
@ -440,7 +440,7 @@ function InstallationTabs() {
|
||||||
</Container>
|
</Container>
|
||||||
<Footer />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
) : salimaxInstallations.length === 1 ? (
|
) : salimax_or_sodistore_Installations.length === 1 ? (
|
||||||
<>
|
<>
|
||||||
<Container maxWidth="xl" sx={{ marginTop: '20px' }} className="mainframe">
|
<Container maxWidth="xl" sx={{ marginTop: '20px' }} className="mainframe">
|
||||||
<TabsContainerWrapper>
|
<TabsContainerWrapper>
|
||||||
|
|
@ -478,7 +478,9 @@ function InstallationTabs() {
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Box p={4}>
|
<Box p={4}>
|
||||||
<Installation
|
<Installation
|
||||||
current_installation={salimaxInstallations[0]}
|
current_installation={
|
||||||
|
salimax_or_sodistore_Installations[0]
|
||||||
|
}
|
||||||
type="installation"
|
type="installation"
|
||||||
></Installation>
|
></Installation>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import { UserContext } from '../../../contexts/userContext';
|
||||||
import { UserType } from '../../../interfaces/UserTypes';
|
import { UserType } from '../../../interfaces/UserTypes';
|
||||||
import { TimeSpan, UnixTime } from '../../../dataCache/time';
|
import { TimeSpan, UnixTime } from '../../../dataCache/time';
|
||||||
import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
|
import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
|
||||||
|
import { ProductIdContext } from '../../../contexts/ProductIdContextProvider';
|
||||||
|
|
||||||
interface OverviewProps {
|
interface OverviewProps {
|
||||||
s3Credentials: I_S3Credentials;
|
s3Credentials: I_S3Credentials;
|
||||||
|
|
@ -69,6 +70,8 @@ function Overview(props: OverviewProps) {
|
||||||
}[]
|
}[]
|
||||||
>([]);
|
>([]);
|
||||||
|
|
||||||
|
//console.log(dailyData);
|
||||||
|
|
||||||
const [aggregatedDataArray, setAggregatedDataArray] = useState<
|
const [aggregatedDataArray, setAggregatedDataArray] = useState<
|
||||||
{
|
{
|
||||||
chartData: chartAggregatedDataInterface;
|
chartData: chartAggregatedDataInterface;
|
||||||
|
|
@ -82,6 +85,8 @@ function Overview(props: OverviewProps) {
|
||||||
const [endDate, setEndDate] = useState(dayjs());
|
const [endDate, setEndDate] = useState(dayjs());
|
||||||
const [isZooming, setIsZooming] = useState(false);
|
const [isZooming, setIsZooming] = useState(false);
|
||||||
|
|
||||||
|
const { product } = useContext(ProductIdContext);
|
||||||
|
|
||||||
// console.log(
|
// console.log(
|
||||||
// UnixTime.fromTicks(new Date().getTime() / 1000).earlier(
|
// UnixTime.fromTicks(new Date().getTime() / 1000).earlier(
|
||||||
// TimeSpan.fromDays(1)
|
// TimeSpan.fromDays(1)
|
||||||
|
|
@ -102,6 +107,7 @@ function Overview(props: OverviewProps) {
|
||||||
chartData: chartDataInterface;
|
chartData: chartDataInterface;
|
||||||
chartOverview: overviewInterface;
|
chartOverview: overviewInterface;
|
||||||
}> = transformInputToDailyDataJson(
|
}> = transformInputToDailyDataJson(
|
||||||
|
product,
|
||||||
props.s3Credentials,
|
props.s3Credentials,
|
||||||
props.id,
|
props.id,
|
||||||
UnixTime.fromTicks(new Date().getTime() / 1000).earlier(
|
UnixTime.fromTicks(new Date().getTime() / 1000).earlier(
|
||||||
|
|
@ -137,6 +143,7 @@ function Overview(props: OverviewProps) {
|
||||||
chartData: chartDataInterface;
|
chartData: chartDataInterface;
|
||||||
chartOverview: overviewInterface;
|
chartOverview: overviewInterface;
|
||||||
}> = transformInputToDailyDataJson(
|
}> = transformInputToDailyDataJson(
|
||||||
|
product,
|
||||||
props.s3Credentials,
|
props.s3Credentials,
|
||||||
props.id,
|
props.id,
|
||||||
UnixTime.fromTicks(startX).earlier(TimeSpan.fromHours(2)),
|
UnixTime.fromTicks(startX).earlier(TimeSpan.fromHours(2)),
|
||||||
|
|
@ -265,6 +272,7 @@ function Overview(props: OverviewProps) {
|
||||||
chartData: chartDataInterface;
|
chartData: chartDataInterface;
|
||||||
chartOverview: overviewInterface;
|
chartOverview: overviewInterface;
|
||||||
}> = transformInputToDailyDataJson(
|
}> = transformInputToDailyDataJson(
|
||||||
|
product,
|
||||||
props.s3Credentials,
|
props.s3Credentials,
|
||||||
props.id,
|
props.id,
|
||||||
UnixTime.fromTicks(startDate.unix()),
|
UnixTime.fromTicks(startDate.unix()),
|
||||||
|
|
@ -1320,47 +1328,47 @@ function Overview(props: OverviewProps) {
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid
|
{dailyData && (
|
||||||
container
|
<Grid
|
||||||
direction="row"
|
container
|
||||||
justifyContent="center"
|
direction="row"
|
||||||
alignItems="stretch"
|
justifyContent="center"
|
||||||
spacing={3}
|
alignItems="stretch"
|
||||||
>
|
spacing={3}
|
||||||
<Grid item md={6} xs={12}>
|
>
|
||||||
<Card
|
<Grid item md={6} xs={12}>
|
||||||
sx={{
|
<Card
|
||||||
overflow: 'visible',
|
|
||||||
marginTop: '30px',
|
|
||||||
marginBottom: '30px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
sx={{
|
||||||
marginLeft: '20px'
|
overflow: 'visible',
|
||||||
|
marginTop: '30px',
|
||||||
|
marginBottom: '30px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box display="flex" alignItems="center">
|
|
||||||
<Box>
|
|
||||||
<Typography variant="subtitle1" noWrap>
|
|
||||||
<FormattedMessage
|
|
||||||
id="ac_load"
|
|
||||||
defaultMessage="AC Load"
|
|
||||||
/>
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: 'flex',
|
marginLeft: '20px'
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'flex-start',
|
|
||||||
pt: 3
|
|
||||||
}}
|
}}
|
||||||
></Box>
|
>
|
||||||
</Box>
|
<Box display="flex" alignItems="center">
|
||||||
|
<Box>
|
||||||
|
<Typography variant="subtitle1" noWrap>
|
||||||
|
<FormattedMessage
|
||||||
|
id="ac_load"
|
||||||
|
defaultMessage="AC Load"
|
||||||
|
/>
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'flex-start',
|
||||||
|
pt: 3
|
||||||
|
}}
|
||||||
|
></Box>
|
||||||
|
</Box>
|
||||||
|
|
||||||
{dailyData && (
|
|
||||||
<ReactApexChart
|
<ReactApexChart
|
||||||
options={{
|
options={{
|
||||||
...getChartOptions(
|
...getChartOptions(
|
||||||
|
|
@ -1387,42 +1395,41 @@ function Overview(props: OverviewProps) {
|
||||||
type="line"
|
type="line"
|
||||||
height={400}
|
height={400}
|
||||||
/>
|
/>
|
||||||
)}
|
</Card>
|
||||||
</Card>
|
</Grid>
|
||||||
</Grid>
|
<Grid item md={6} xs={12}>
|
||||||
<Grid item md={6} xs={12}>
|
<Card
|
||||||
<Card
|
|
||||||
sx={{
|
|
||||||
overflow: 'visible',
|
|
||||||
marginTop: '30px',
|
|
||||||
marginBottom: '30px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
sx={{
|
||||||
marginLeft: '20px'
|
overflow: 'visible',
|
||||||
|
marginTop: '30px',
|
||||||
|
marginBottom: '30px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box display="flex" alignItems="center">
|
|
||||||
<Box>
|
|
||||||
<Typography variant="subtitle1" noWrap>
|
|
||||||
<FormattedMessage
|
|
||||||
id="dc_load"
|
|
||||||
defaultMessage="DC Load"
|
|
||||||
/>
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: 'flex',
|
marginLeft: '20px'
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'flex-start',
|
|
||||||
pt: 3
|
|
||||||
}}
|
}}
|
||||||
></Box>
|
>
|
||||||
</Box>
|
<Box display="flex" alignItems="center">
|
||||||
{dailyData && (
|
<Box>
|
||||||
|
<Typography variant="subtitle1" noWrap>
|
||||||
|
<FormattedMessage
|
||||||
|
id="dc_load"
|
||||||
|
defaultMessage="DC Load"
|
||||||
|
/>
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'flex-start',
|
||||||
|
pt: 3
|
||||||
|
}}
|
||||||
|
></Box>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<ReactApexChart
|
<ReactApexChart
|
||||||
options={{
|
options={{
|
||||||
...getChartOptions(
|
...getChartOptions(
|
||||||
|
|
@ -1449,10 +1456,10 @@ function Overview(props: OverviewProps) {
|
||||||
type="line"
|
type="line"
|
||||||
height={400}
|
height={400}
|
||||||
/>
|
/>
|
||||||
)}
|
</Card>
|
||||||
</Card>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
)}
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => {
|
||||||
{sortedInstallations
|
{sortedInstallations
|
||||||
// .filter(
|
// .filter(
|
||||||
// (installation) =>
|
// (installation) =>
|
||||||
// installation.status === -1 &&
|
// installation.status === -1 &&
|
||||||
// installation.testingMode == false
|
// installation.testingMode == false
|
||||||
// )
|
// )
|
||||||
.map((installation) => {
|
.map((installation) => {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,11 @@ import { ProductIdContext } from '../../../contexts/ProductIdContextProvider';
|
||||||
import { UserType } from '../../../interfaces/UserTypes';
|
import { UserType } from '../../../interfaces/UserTypes';
|
||||||
import SalidomoInstallation from './Installation';
|
import SalidomoInstallation from './Installation';
|
||||||
|
|
||||||
function SalidomoInstallationTabs() {
|
interface InstallationTabsProps {
|
||||||
|
product: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SalidomoInstallationTabs(props: InstallationTabsProps) {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const context = useContext(UserContext);
|
const context = useContext(UserContext);
|
||||||
const { currentUser } = context;
|
const { currentUser } = context;
|
||||||
|
|
@ -28,12 +32,10 @@ function SalidomoInstallationTabs() {
|
||||||
];
|
];
|
||||||
|
|
||||||
const [currentTab, setCurrentTab] = useState<string>(undefined);
|
const [currentTab, setCurrentTab] = useState<string>(undefined);
|
||||||
const [fetchedInstallations, setFetchedInstallations] =
|
|
||||||
useState<boolean>(false);
|
|
||||||
const {
|
const {
|
||||||
salidomoInstallations,
|
salidomoInstallations,
|
||||||
fetchAllSalidomoInstallations,
|
fetchAllSalidomoInstallations,
|
||||||
currentProduct,
|
|
||||||
socket,
|
socket,
|
||||||
openSocket,
|
openSocket,
|
||||||
closeSocket
|
closeSocket
|
||||||
|
|
@ -55,29 +57,14 @@ function SalidomoInstallationTabs() {
|
||||||
}, [location]);
|
}, [location]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
//The first time this component will be loaded, it needs to call the fetchAllSalidomoInstallations function from the InstallationsContextProvider
|
setProduct(props.product);
|
||||||
if (salidomoInstallations.length === 0 && fetchedInstallations === false) {
|
}, [props.product]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (product == props.product) {
|
||||||
fetchAllSalidomoInstallations();
|
fetchAllSalidomoInstallations();
|
||||||
setFetchedInstallations(true);
|
|
||||||
}
|
}
|
||||||
}, [salidomoInstallations]);
|
}, [product]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
//Since we know the ids of the installations we have access to, we need to open a web socket with the backend.
|
|
||||||
if (salidomoInstallations && salidomoInstallations.length > 0) {
|
|
||||||
if (!socket) {
|
|
||||||
openSocket(1);
|
|
||||||
} else if (currentProduct != 1) {
|
|
||||||
//If there is any other open websocket for another product, close it.
|
|
||||||
closeSocket();
|
|
||||||
openSocket(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [salidomoInstallations]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setProduct(1);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleTabsChange = (_event: ChangeEvent<{}>, value: string): void => {
|
const handleTabsChange = (_event: ChangeEvent<{}>, value: string): void => {
|
||||||
setCurrentTab(value);
|
setCurrentTab(value);
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ function SodioHomeInstallationTabs() {
|
||||||
const {
|
const {
|
||||||
sodiohomeInstallations,
|
sodiohomeInstallations,
|
||||||
fetchAllSodiohomeInstallations,
|
fetchAllSodiohomeInstallations,
|
||||||
currentProduct,
|
|
||||||
socket,
|
socket,
|
||||||
openSocket,
|
openSocket,
|
||||||
closeSocket
|
closeSocket
|
||||||
|
|
@ -64,7 +63,7 @@ function SodioHomeInstallationTabs() {
|
||||||
if (sodiohomeInstallations && sodiohomeInstallations.length > 0) {
|
if (sodiohomeInstallations && sodiohomeInstallations.length > 0) {
|
||||||
if (!socket) {
|
if (!socket) {
|
||||||
openSocket(2);
|
openSocket(2);
|
||||||
} else if (currentProduct != 2) {
|
} else if (product != 2) {
|
||||||
closeSocket();
|
closeSocket();
|
||||||
openSocket(2);
|
openSocket(2);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useContext, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
CircularProgress,
|
CircularProgress,
|
||||||
Container,
|
Container,
|
||||||
|
|
@ -12,6 +12,7 @@ import {
|
||||||
getHighestConnectionValue,
|
getHighestConnectionValue,
|
||||||
JSONRecordData
|
JSONRecordData
|
||||||
} from '../Log/graph.util';
|
} from '../Log/graph.util';
|
||||||
|
import { ProductIdContext } from '../../../contexts/ProductIdContextProvider';
|
||||||
|
|
||||||
interface TopologyProps {
|
interface TopologyProps {
|
||||||
values: JSONRecordData;
|
values: JSONRecordData;
|
||||||
|
|
@ -26,6 +27,10 @@ function Topology(props: TopologyProps) {
|
||||||
const highestConnectionValue =
|
const highestConnectionValue =
|
||||||
props.values != null ? getHighestConnectionValue(props.values) : 0;
|
props.values != null ? getHighestConnectionValue(props.values) : 0;
|
||||||
|
|
||||||
|
const { product, setProduct } = useContext(ProductIdContext);
|
||||||
|
|
||||||
|
console.log('product VALUE IS ', product);
|
||||||
|
|
||||||
//console.log(props.values.DcDc.Dc.Battery.Voltage);
|
//console.log(props.values.DcDc.Dc.Battery.Voltage);
|
||||||
|
|
||||||
const [showValues, setShowValues] = useState(false);
|
const [showValues, setShowValues] = useState(false);
|
||||||
|
|
@ -514,14 +519,19 @@ function Topology(props: TopologyProps) {
|
||||||
data: props.values?.Battery
|
data: props.values?.Battery
|
||||||
? {
|
? {
|
||||||
//value: props.values.Battery.Dc.Power for salimax,
|
//value: props.values.Battery.Dc.Power for salimax,
|
||||||
value: props.values.Battery.Power,
|
value:
|
||||||
|
product == 0
|
||||||
|
? props.values.Battery.Dc.Power
|
||||||
|
: props.values.Battery.Power,
|
||||||
unit: 'W'
|
unit: 'W'
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
amount: props.values?.Battery
|
amount: props.values?.Battery
|
||||||
? getAmount(
|
? getAmount(
|
||||||
highestConnectionValue,
|
highestConnectionValue,
|
||||||
props.values.Battery.Power
|
product == 0
|
||||||
|
? props.values.Battery.Dc.Power
|
||||||
|
: props.values.Battery.Power
|
||||||
)
|
)
|
||||||
: 0,
|
: 0,
|
||||||
showValues: showValues
|
showValues: showValues
|
||||||
|
|
@ -540,18 +550,27 @@ function Topology(props: TopologyProps) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
//value: props.values.Battery.Dc.Voltage for salimax,
|
//value: props.values.Battery.Dc.Voltage for salimax,
|
||||||
value: props.values.Battery.Voltage,
|
value:
|
||||||
|
product === 0
|
||||||
|
? props.values.Battery.Dc.Voltage
|
||||||
|
: props.values.Battery.Voltage,
|
||||||
unit: 'V'
|
unit: 'V'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
//value: props.values.Battery.Dc.Current for salimax,
|
//value: props.values.Battery.Dc.Current for salimax,
|
||||||
|
|
||||||
value: props.values.Battery.Current,
|
value:
|
||||||
|
product == 0
|
||||||
|
? props.values.Battery.Dc.Current
|
||||||
|
: props.values.Battery.Current,
|
||||||
unit: 'A'
|
unit: 'A'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
//value: props.values.Battery.Temperature for salimax,
|
//value: props.values.Battery.Temperature for salimax,
|
||||||
value: props.values.Battery.TemperatureCell1,
|
value:
|
||||||
|
product == 0
|
||||||
|
? props.values.Battery.Temperature
|
||||||
|
: props.values.Battery.TemperatureCell1,
|
||||||
unit: '°C'
|
unit: '°C'
|
||||||
}
|
}
|
||||||
// {
|
// {
|
||||||
|
|
|
||||||
|
|
@ -51,14 +51,18 @@ function CustomTreeItem(props: CustomTreeItemProps) {
|
||||||
? routes.installations
|
? routes.installations
|
||||||
: installation.product == 1
|
: installation.product == 1
|
||||||
? routes.salidomo_installations
|
? routes.salidomo_installations
|
||||||
: routes.sodiohome_installations;
|
: installation.product == 2
|
||||||
|
? routes.sodiohome_installations
|
||||||
|
: routes.sodistore_installations;
|
||||||
|
|
||||||
let folder_path =
|
let folder_path =
|
||||||
product == 0
|
product == 0
|
||||||
? routes.installations
|
? routes.installations
|
||||||
: product == 1
|
: product == 1
|
||||||
? routes.salidomo_installations
|
? routes.salidomo_installations
|
||||||
: routes.sodiohome_installations;
|
: installation.product == 2
|
||||||
|
? routes.sodiohome_installations
|
||||||
|
: routes.sodistore_installations;
|
||||||
|
|
||||||
if (installation.type != 'Folder') {
|
if (installation.type != 'Folder') {
|
||||||
navigate(
|
navigate(
|
||||||
|
|
@ -175,6 +179,8 @@ function CustomTreeItem(props: CustomTreeItemProps) {
|
||||||
display:
|
display:
|
||||||
currentLocation.pathname ===
|
currentLocation.pathname ===
|
||||||
routes.salidomo_installations + routes.tree ||
|
routes.salidomo_installations + routes.tree ||
|
||||||
|
currentLocation.pathname ===
|
||||||
|
routes.sodistore_installations + routes.tree ||
|
||||||
currentLocation.pathname === routes.installations + routes.tree ||
|
currentLocation.pathname === routes.installations + routes.tree ||
|
||||||
currentLocation.pathname ===
|
currentLocation.pathname ===
|
||||||
routes.sodiohome_installations + routes.tree ||
|
routes.sodiohome_installations + routes.tree ||
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import routes from '../../../Resources/routes.json';
|
||||||
import SalidomoInstallation from '../SalidomoInstallations/Installation';
|
import SalidomoInstallation from '../SalidomoInstallations/Installation';
|
||||||
import Folder from './Folder';
|
import Folder from './Folder';
|
||||||
import SodioHomeInstallation from '../SodiohomeInstallations/Installation';
|
import SodioHomeInstallation from '../SodiohomeInstallations/Installation';
|
||||||
import { ProductIdContext } from '../../../contexts/ProductIdContextProvider';
|
|
||||||
|
|
||||||
function InstallationTree() {
|
function InstallationTree() {
|
||||||
const { foldersAndInstallations, fetchAllFoldersAndInstallations } =
|
const { foldersAndInstallations, fetchAllFoldersAndInstallations } =
|
||||||
|
|
@ -36,8 +35,6 @@ function InstallationTree() {
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
const { product } = useContext(ProductIdContext);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchAllFoldersAndInstallations();
|
fetchAllFoldersAndInstallations();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,10 @@ const InstallationsContextProvider = ({
|
||||||
}: {
|
}: {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
const [salimaxInstallations, setSalimaxInstallations] = useState<
|
const [
|
||||||
I_Installation[]
|
salimax_or_sodistore_Installations,
|
||||||
>([]);
|
setSalimax_Or_Sodistore_Installations
|
||||||
|
] = useState<I_Installation[]>([]);
|
||||||
const [salidomoInstallations, setSalidomoInstallations] = useState<
|
const [salidomoInstallations, setSalidomoInstallations] = useState<
|
||||||
I_Installation[]
|
I_Installation[]
|
||||||
>([]);
|
>([]);
|
||||||
|
|
@ -38,8 +39,11 @@ const InstallationsContextProvider = ({
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const tokencontext = useContext(TokenContext);
|
const tokencontext = useContext(TokenContext);
|
||||||
const { removeToken } = tokencontext;
|
const { removeToken } = tokencontext;
|
||||||
const [socket, setSocket] = useState<WebSocket>(null);
|
// const [socket, setSocket] = useState<WebSocket>(null);
|
||||||
const [currentProduct, setcurrentProduct] = useState<number>(0);
|
|
||||||
|
const socket = useRef<WebSocket | null>(null); // Using useRef instead of useState
|
||||||
|
|
||||||
|
//const [currentProduct, setcurrentProduct] = useState<number>(0);
|
||||||
|
|
||||||
//Store pending updates and apply them in batches
|
//Store pending updates and apply them in batches
|
||||||
const pendingUpdates = useRef<
|
const pendingUpdates = useRef<
|
||||||
|
|
@ -66,16 +70,18 @@ const InstallationsContextProvider = ({
|
||||||
: installation;
|
: installation;
|
||||||
});
|
});
|
||||||
|
|
||||||
const updatedSalimax = salimaxInstallations.map((installation) => {
|
const updatedSalimax = salimax_or_sodistore_Installations.map(
|
||||||
const update = pendingUpdates.current[installation.id];
|
(installation) => {
|
||||||
return update
|
const update = pendingUpdates.current[installation.id];
|
||||||
? {
|
return update
|
||||||
...installation,
|
? {
|
||||||
status: update.status,
|
...installation,
|
||||||
testingMode: update.testingMode
|
status: update.status,
|
||||||
}
|
testingMode: update.testingMode
|
||||||
: installation;
|
}
|
||||||
});
|
: installation;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const updatedSodiohome = sodiohomeInstallations.map((installation) => {
|
const updatedSodiohome = sodiohomeInstallations.map((installation) => {
|
||||||
const update = pendingUpdates.current[installation.id];
|
const update = pendingUpdates.current[installation.id];
|
||||||
|
|
@ -89,12 +95,16 @@ const InstallationsContextProvider = ({
|
||||||
});
|
});
|
||||||
|
|
||||||
setSalidomoInstallations(updatedSalidomo);
|
setSalidomoInstallations(updatedSalidomo);
|
||||||
setSalimaxInstallations(updatedSalimax);
|
setSalimax_Or_Sodistore_Installations(updatedSalimax);
|
||||||
setSodiohomeInstallations(updatedSodiohome);
|
setSodiohomeInstallations(updatedSodiohome);
|
||||||
|
|
||||||
// Clear the pending updates after applying
|
// Clear the pending updates after applying
|
||||||
pendingUpdates.current = {};
|
pendingUpdates.current = {};
|
||||||
}, [salidomoInstallations, salimaxInstallations, sodiohomeInstallations]);
|
}, [
|
||||||
|
salidomoInstallations,
|
||||||
|
salimax_or_sodistore_Installations,
|
||||||
|
sodiohomeInstallations
|
||||||
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timer = setInterval(() => {
|
const timer = setInterval(() => {
|
||||||
|
|
@ -104,27 +114,20 @@ const InstallationsContextProvider = ({
|
||||||
return () => clearInterval(timer); // Cleanup timer on component unmount
|
return () => clearInterval(timer); // Cleanup timer on component unmount
|
||||||
}, [applyBatchUpdates]);
|
}, [applyBatchUpdates]);
|
||||||
|
|
||||||
const openSocket = (product) => {
|
const openSocket = (installationsToSend) => {
|
||||||
setcurrentProduct(product);
|
if (socket.current) {
|
||||||
|
socket.current.close();
|
||||||
|
socket.current = null;
|
||||||
|
}
|
||||||
const tokenString = localStorage.getItem('token');
|
const tokenString = localStorage.getItem('token');
|
||||||
const token = tokenString !== null ? tokenString : '';
|
const token = tokenString !== null ? tokenString : '';
|
||||||
const urlWithToken = `wss://monitor.innov.energy/api/CreateWebSocket?authToken=${token}`;
|
const urlWithToken = `wss://monitor.innov.energy/api/CreateWebSocket?authToken=${token}`;
|
||||||
|
|
||||||
const socket = new WebSocket(urlWithToken);
|
const new_socket = new WebSocket(urlWithToken);
|
||||||
|
|
||||||
socket.addEventListener('open', () => {
|
|
||||||
let installationsToSend = [];
|
|
||||||
|
|
||||||
if (product === 0) {
|
|
||||||
installationsToSend = salimaxInstallations;
|
|
||||||
} else if (product === 1) {
|
|
||||||
installationsToSend = salidomoInstallations;
|
|
||||||
} else if (product === 2) {
|
|
||||||
installationsToSend = sodiohomeInstallations;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
new_socket.addEventListener('open', () => {
|
||||||
// Send the corresponding installation IDs to the backend
|
// Send the corresponding installation IDs to the backend
|
||||||
socket.send(
|
new_socket.send(
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
installationsToSend.map((installation) => installation.id)
|
installationsToSend.map((installation) => installation.id)
|
||||||
)
|
)
|
||||||
|
|
@ -133,12 +136,12 @@ const InstallationsContextProvider = ({
|
||||||
|
|
||||||
// Periodically send ping messages to keep the connection alive
|
// Periodically send ping messages to keep the connection alive
|
||||||
const pingInterval = setInterval(() => {
|
const pingInterval = setInterval(() => {
|
||||||
if (socket.readyState === WebSocket.OPEN) {
|
if (new_socket.readyState === WebSocket.OPEN) {
|
||||||
socket.send(JSON.stringify([-1]));
|
new_socket.send(JSON.stringify([-1]));
|
||||||
}
|
}
|
||||||
}, 10000);
|
}, 10000);
|
||||||
|
|
||||||
socket.addEventListener('message', (event) => {
|
new_socket.addEventListener('message', (event) => {
|
||||||
const message = JSON.parse(event.data); // Parse the JSON data
|
const message = JSON.parse(event.data); // Parse the JSON data
|
||||||
if (message.id !== -1) {
|
if (message.id !== -1) {
|
||||||
//For each received message (except the first one which is a batch, call the updateInstallationStatus function in order to import the message to the pendingUpdates list
|
//For each received message (except the first one which is a batch, call the updateInstallationStatus function in order to import the message to the pendingUpdates list
|
||||||
|
|
@ -150,36 +153,42 @@ const InstallationsContextProvider = ({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.addEventListener('close', () => {
|
new_socket.addEventListener('close', () => {
|
||||||
clearInterval(pingInterval); // Cleanup ping interval on socket close
|
clearInterval(pingInterval); // Cleanup ping interval on socket close
|
||||||
setSocket(null);
|
//socket.current = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
setSocket(socket);
|
socket.current = new_socket;
|
||||||
};
|
};
|
||||||
|
|
||||||
const closeSocket = () => socket?.close();
|
const closeSocket = () => socket?.current?.close();
|
||||||
|
|
||||||
const fetchAllInstallations = useCallback(async () => {
|
// Function to fetch installations and manage the socket
|
||||||
axiosConfig
|
const fetchAllInstallations = useCallback(
|
||||||
.get('/GetAllInstallations')
|
async (product: number) => {
|
||||||
.then((res: AxiosResponse<I_Installation[]>) =>
|
axiosConfig
|
||||||
setSalimaxInstallations(res.data)
|
.get(`/GetAllInstallationsFromProduct?product=${product}`)
|
||||||
)
|
.then((res: AxiosResponse<I_Installation[]>) => {
|
||||||
.catch((err: AxiosError) => {
|
setSalimax_Or_Sodistore_Installations(res.data); // Update installations
|
||||||
if (err.response?.status === 401) {
|
openSocket(res.data); // Open a new socket after installations are fetched
|
||||||
removeToken();
|
})
|
||||||
navigate(routes.login);
|
.catch((err: AxiosError) => {
|
||||||
}
|
if (err.response?.status === 401) {
|
||||||
});
|
removeToken();
|
||||||
}, [navigate, removeToken]);
|
navigate(routes.login);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[navigate, removeToken]
|
||||||
|
);
|
||||||
|
|
||||||
const fetchAllSalidomoInstallations = useCallback(async () => {
|
const fetchAllSalidomoInstallations = useCallback(async () => {
|
||||||
axiosConfig
|
axiosConfig
|
||||||
.get('/GetAllSalidomoInstallations')
|
.get('/GetAllSalidomoInstallations')
|
||||||
.then((res: AxiosResponse<I_Installation[]>) =>
|
.then((res: AxiosResponse<I_Installation[]>) => {
|
||||||
setSalidomoInstallations(res.data)
|
setSalidomoInstallations(res.data);
|
||||||
)
|
openSocket(res.data);
|
||||||
|
})
|
||||||
.catch((err: AxiosError) => {
|
.catch((err: AxiosError) => {
|
||||||
if (err.response?.status === 401) {
|
if (err.response?.status === 401) {
|
||||||
removeToken();
|
removeToken();
|
||||||
|
|
@ -244,7 +253,7 @@ const InstallationsContextProvider = ({
|
||||||
setUpdated(true);
|
setUpdated(true);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
if (formValues.product === 0 && view === 'installation')
|
if (formValues.product === 0 && view === 'installation')
|
||||||
fetchAllInstallations();
|
fetchAllInstallations(formValues.product);
|
||||||
else if (formValues.product === 1 && view === 'installation')
|
else if (formValues.product === 1 && view === 'installation')
|
||||||
fetchAllSalidomoInstallations();
|
fetchAllSalidomoInstallations();
|
||||||
else if (formValues.product === 2 && view === 'installation')
|
else if (formValues.product === 2 && view === 'installation')
|
||||||
|
|
@ -278,7 +287,7 @@ const InstallationsContextProvider = ({
|
||||||
setUpdated(true);
|
setUpdated(true);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
if (formValues.product === 0 && view === 'installation')
|
if (formValues.product === 0 && view === 'installation')
|
||||||
fetchAllInstallations();
|
fetchAllInstallations(formValues.product);
|
||||||
else if (formValues.product === 1 && view === 'installation')
|
else if (formValues.product === 1 && view === 'installation')
|
||||||
fetchAllSalidomoInstallations();
|
fetchAllSalidomoInstallations();
|
||||||
else if (formValues.product === 2 && view === 'installation')
|
else if (formValues.product === 2 && view === 'installation')
|
||||||
|
|
@ -369,7 +378,7 @@ const InstallationsContextProvider = ({
|
||||||
|
|
||||||
const contextValue = useMemo(
|
const contextValue = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
salimaxInstallations,
|
salimax_or_sodistore_Installations,
|
||||||
salidomoInstallations,
|
salidomoInstallations,
|
||||||
sodiohomeInstallations,
|
sodiohomeInstallations,
|
||||||
foldersAndInstallations,
|
foldersAndInstallations,
|
||||||
|
|
@ -389,21 +398,21 @@ const InstallationsContextProvider = ({
|
||||||
createFolder,
|
createFolder,
|
||||||
updateFolder,
|
updateFolder,
|
||||||
deleteFolder,
|
deleteFolder,
|
||||||
currentProduct,
|
//currentProduct,
|
||||||
socket,
|
socket,
|
||||||
openSocket,
|
openSocket,
|
||||||
closeSocket
|
closeSocket
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
salimaxInstallations,
|
salimax_or_sodistore_Installations,
|
||||||
salidomoInstallations,
|
salidomoInstallations,
|
||||||
sodiohomeInstallations,
|
sodiohomeInstallations,
|
||||||
foldersAndInstallations,
|
foldersAndInstallations,
|
||||||
loading,
|
loading,
|
||||||
error,
|
error,
|
||||||
updated,
|
updated,
|
||||||
socket,
|
socket
|
||||||
currentProduct
|
//currentProduct
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,11 @@ interface ProductIdContextType {
|
||||||
accessToSalimax: boolean;
|
accessToSalimax: boolean;
|
||||||
accessToSalidomo: boolean;
|
accessToSalidomo: boolean;
|
||||||
accessToSodiohome: boolean;
|
accessToSodiohome: boolean;
|
||||||
|
accessToSodistore: boolean;
|
||||||
setAccessToSalimax: (access: boolean) => void;
|
setAccessToSalimax: (access: boolean) => void;
|
||||||
setAccessToSalidomo: (access: boolean) => void;
|
setAccessToSalidomo: (access: boolean) => void;
|
||||||
setAccessToSodiohome: (access: boolean) => void;
|
setAccessToSodiohome: (access: boolean) => void;
|
||||||
|
setAccessToSodistore: (access: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the context.
|
// Create the context.
|
||||||
|
|
@ -37,6 +39,10 @@ export const ProductIdContextProvider = ({
|
||||||
const storedValue = localStorage.getItem('accessToSodiohome');
|
const storedValue = localStorage.getItem('accessToSodiohome');
|
||||||
return storedValue === 'true';
|
return storedValue === 'true';
|
||||||
});
|
});
|
||||||
|
const [accessToSodistore, setAccessToSodistore] = useState(() => {
|
||||||
|
const storedValue = localStorage.getItem('accessToSodistore');
|
||||||
|
return storedValue === 'true';
|
||||||
|
});
|
||||||
// const [product, setProduct] = useState(location.includes('salidomo') ? 1 : 0);
|
// const [product, setProduct] = useState(location.includes('salidomo') ? 1 : 0);
|
||||||
// const [product, setProduct] = useState<number>(
|
// const [product, setProduct] = useState<number>(
|
||||||
// productMapping[Object.keys(productMapping).find((key) => location.includes(key)) || ''] || -1
|
// productMapping[Object.keys(productMapping).find((key) => location.includes(key)) || ''] || -1
|
||||||
|
|
@ -70,6 +76,10 @@ export const ProductIdContextProvider = ({
|
||||||
setAccessToSodiohome(access);
|
setAccessToSodiohome(access);
|
||||||
localStorage.setItem('accessToSodiohome', JSON.stringify(access));
|
localStorage.setItem('accessToSodiohome', JSON.stringify(access));
|
||||||
};
|
};
|
||||||
|
const changeAccessSodistore = (access: boolean) => {
|
||||||
|
setAccessToSodistore(access);
|
||||||
|
localStorage.setItem('accessToSodistore', JSON.stringify(access));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ProductIdContext.Provider
|
<ProductIdContext.Provider
|
||||||
|
|
@ -79,9 +89,11 @@ export const ProductIdContextProvider = ({
|
||||||
accessToSalimax,
|
accessToSalimax,
|
||||||
accessToSalidomo,
|
accessToSalidomo,
|
||||||
accessToSodiohome,
|
accessToSodiohome,
|
||||||
|
accessToSodistore,
|
||||||
setAccessToSalimax: changeAccessSalimax,
|
setAccessToSalimax: changeAccessSalimax,
|
||||||
setAccessToSalidomo: changeAccessSalidomo,
|
setAccessToSalidomo: changeAccessSalidomo,
|
||||||
setAccessToSodiohome: changeAccessSodiohome
|
setAccessToSodiohome: changeAccessSodiohome,
|
||||||
|
setAccessToSodistore: changeAccessSodistore
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
||||||
|
|
@ -287,6 +287,7 @@ export const transformInputToBatteryViewDataJson = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
export const transformInputToDailyDataJson = async (
|
export const transformInputToDailyDataJson = async (
|
||||||
|
product: number,
|
||||||
s3Credentials: I_S3Credentials,
|
s3Credentials: I_S3Credentials,
|
||||||
id: number,
|
id: number,
|
||||||
start_time?: UnixTime,
|
start_time?: UnixTime,
|
||||||
|
|
@ -296,14 +297,17 @@ export const transformInputToDailyDataJson = async (
|
||||||
chartOverview: overviewInterface;
|
chartOverview: overviewInterface;
|
||||||
}> => {
|
}> => {
|
||||||
const prefixes = ['', 'k', 'M', 'G', 'T'];
|
const prefixes = ['', 'k', 'M', 'G', 'T'];
|
||||||
|
|
||||||
const MAX_NUMBER = 9999999;
|
const MAX_NUMBER = 9999999;
|
||||||
const pathsToSearch = [
|
const pathsToSearch = [
|
||||||
'Battery.Soc',
|
'Battery.Soc',
|
||||||
|
product == 0 ? 'Battery.Temperature' : 'Battery.TemperatureCell1',
|
||||||
|
|
||||||
//'Battery.Temperature' for salimax,
|
//'Battery.Temperature' for salimax,
|
||||||
'Battery.TemperatureCell1',
|
//'Battery.TemperatureCell1',
|
||||||
|
product == 0 ? 'Battery.Dc.Power' : 'Battery.Power',
|
||||||
//'Battery.Dc.Power' for salimax,
|
//'Battery.Dc.Power' for salimax,
|
||||||
'Battery.Power',
|
// 'Battery.Power',
|
||||||
'GridMeter.Ac.Power.Active',
|
'GridMeter.Ac.Power.Active',
|
||||||
'PvOnDc.Dc.Power',
|
'PvOnDc.Dc.Power',
|
||||||
'DcDc.Dc.Link.Voltage',
|
'DcDc.Dc.Link.Voltage',
|
||||||
|
|
@ -400,6 +404,7 @@ export const transformInputToDailyDataJson = async (
|
||||||
Object.keys(results[i]).length - 1
|
Object.keys(results[i]).length - 1
|
||||||
];
|
];
|
||||||
const result = results[i][timestamp];
|
const result = results[i][timestamp];
|
||||||
|
//console.log(result);
|
||||||
let category_index = 0;
|
let category_index = 0;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
||||||
pathsToSearch.forEach((path) => {
|
pathsToSearch.forEach((path) => {
|
||||||
|
|
@ -596,6 +601,7 @@ export const transformInputToAggregatedDataJson = async (
|
||||||
) {
|
) {
|
||||||
// Handle not available or try later case
|
// Handle not available or try later case
|
||||||
} else {
|
} else {
|
||||||
|
// console.log(result);
|
||||||
dateList.push(currentDay.format('DD-MM'));
|
dateList.push(currentDay.format('DD-MM'));
|
||||||
pathsToSearch.forEach((path) => {
|
pathsToSearch.forEach((path) => {
|
||||||
const value = path
|
const value = path
|
||||||
|
|
|
||||||
|
|
@ -164,8 +164,12 @@ function SidebarMenu() {
|
||||||
const { closeSidebar } = useContext(SidebarContext);
|
const { closeSidebar } = useContext(SidebarContext);
|
||||||
const context = useContext(UserContext);
|
const context = useContext(UserContext);
|
||||||
const { currentUser, setUser } = context;
|
const { currentUser, setUser } = context;
|
||||||
const { accessToSalimax, accessToSalidomo, accessToSodiohome } =
|
const {
|
||||||
useContext(ProductIdContext);
|
accessToSalimax,
|
||||||
|
accessToSodistore,
|
||||||
|
accessToSalidomo,
|
||||||
|
accessToSodiohome
|
||||||
|
} = useContext(ProductIdContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
@ -197,6 +201,25 @@ function SidebarMenu() {
|
||||||
</List>
|
</List>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<List component="div">
|
||||||
|
<ListItem component="div">
|
||||||
|
<Button
|
||||||
|
disableRipple
|
||||||
|
component={RouterLink}
|
||||||
|
onClick={closeSidebar}
|
||||||
|
to="/sodistore_installations"
|
||||||
|
startIcon={<BrightnessLowTwoToneIcon />}
|
||||||
|
>
|
||||||
|
<Box sx={{ marginTop: '3px' }}>
|
||||||
|
<FormattedMessage
|
||||||
|
id="sodistore"
|
||||||
|
defaultMessage="Sodistore"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Button>
|
||||||
|
</ListItem>
|
||||||
|
</List>
|
||||||
|
|
||||||
{accessToSalidomo && (
|
{accessToSalidomo && (
|
||||||
<List component="div">
|
<List component="div">
|
||||||
<ListItem component="div">
|
<ListItem component="div">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue