History of actions testing mode is enabled in the backend.
All the other connections are updated through the websocket manager Fixed bug with status value in the front-end
This commit is contained in:
parent
1e6c10b96e
commit
95798ba904
|
@ -793,7 +793,7 @@ public class Controller : ControllerBase
|
||||||
public async Task<ActionResult<IEnumerable<Object>>> InsertNewAction([FromBody] UserAction action, Token authToken)
|
public async Task<ActionResult<IEnumerable<Object>>> InsertNewAction([FromBody] UserAction action, Token authToken)
|
||||||
{
|
{
|
||||||
var session = Db.GetSession(authToken);
|
var session = Db.GetSession(authToken);
|
||||||
var actionSuccess = await session.RecordUserAction(action);
|
var actionSuccess = await session.InsertUserAction(action);
|
||||||
return actionSuccess ? Ok() : Unauthorized();
|
return actionSuccess ? Ok() : Unauthorized();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -835,7 +835,7 @@ public class Controller : ControllerBase
|
||||||
Description = config.GetConfigurationString()
|
Description = config.GetConfigurationString()
|
||||||
};
|
};
|
||||||
|
|
||||||
var actionSuccess = await session.RecordUserAction(action);
|
var actionSuccess = await session.InsertUserAction(action);
|
||||||
return actionSuccess?Ok():Unauthorized();
|
return actionSuccess?Ok():Unauthorized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ public class Installation : TreeNode
|
||||||
public int S3BucketId { get; set; } = 0;
|
public int S3BucketId { get; set; } = 0;
|
||||||
public String ReadRoleId { get; set; } = "";
|
public String ReadRoleId { get; set; } = "";
|
||||||
public String WriteRoleId { get; set; } = "";
|
public String WriteRoleId { get; set; } = "";
|
||||||
|
public Boolean TestingMode { get; set; } = false;
|
||||||
|
|
||||||
public int Product { get; set; } = 0;
|
public int Product { get; set; } = 0;
|
||||||
public int Device { get; set; } = 0;
|
public int Device { get; set; } = 0;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using InnovEnergy.App.Backend.Database;
|
using InnovEnergy.App.Backend.Database;
|
||||||
using InnovEnergy.App.Backend.Relations;
|
using InnovEnergy.App.Backend.Relations;
|
||||||
|
using InnovEnergy.App.Backend.Websockets;
|
||||||
using InnovEnergy.Lib.Utils;
|
using InnovEnergy.Lib.Utils;
|
||||||
using Org.BouncyCastle.Asn1.X509;
|
using Org.BouncyCastle.Asn1.X509;
|
||||||
|
|
||||||
|
@ -131,14 +132,17 @@ public static class SessionMethods
|
||||||
&& await installation.SendConfig(configuration);
|
&& await installation.SendConfig(configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<Boolean> RecordUserAction(this Session? session, UserAction action)
|
public static async Task<Boolean> InsertUserAction(this Session? session, UserAction action)
|
||||||
{
|
{
|
||||||
var user = session?.User;
|
var user = session?.User;
|
||||||
|
|
||||||
if (user is null || user.UserType == 0)
|
if (user is null || user.UserType == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
action.UserName = user.Name;
|
var installation = Db.GetInstallationById(action.InstallationId);
|
||||||
|
installation.TestingMode = action.TestingMode;
|
||||||
|
installation.Apply(Db.Update);
|
||||||
|
WebsocketManager.InformWebsocketsForInstallation(action.InstallationId);
|
||||||
|
|
||||||
// Save the configuration change to the database
|
// Save the configuration change to the database
|
||||||
Db.HandleAction(action);
|
Db.HandleAction(action);
|
||||||
|
@ -152,6 +156,14 @@ public static class SessionMethods
|
||||||
if (user is null || user.UserType == 0)
|
if (user is null || user.UserType == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
var installation = Db.GetInstallationById(action.InstallationId);
|
||||||
|
if (installation.TestingMode != action.TestingMode)
|
||||||
|
{
|
||||||
|
installation.TestingMode = action.TestingMode;
|
||||||
|
installation.Apply(Db.Update);
|
||||||
|
WebsocketManager.InformWebsocketsForInstallation(action.InstallationId);
|
||||||
|
}
|
||||||
|
|
||||||
Db.UpdateAction(action);
|
Db.UpdateAction(action);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ public class UserAction
|
||||||
|
|
||||||
public Int64 InstallationId { get; set; } // Installation ID where the configuration change is made
|
public Int64 InstallationId { get; set; } // Installation ID where the configuration change is made
|
||||||
|
|
||||||
|
public Boolean TestingMode { get; set; }
|
||||||
|
|
||||||
public DateTime Timestamp { get; set; } // Timestamp of the configuration change
|
public DateTime Timestamp { get; set; } // Timestamp of the configuration change
|
||||||
|
|
||||||
public String Description { get; set; } = null!;// Serialized string representing the new configuration
|
public String Description { get; set; } = null!;// Serialized string representing the new configuration
|
||||||
|
|
|
@ -111,11 +111,14 @@ public static partial class Db
|
||||||
public static void UpdateAction(UserAction updatedAction)
|
public static void UpdateAction(UserAction updatedAction)
|
||||||
{
|
{
|
||||||
var existingAction = UserActions.FirstOrDefault(action => action.Id == updatedAction.Id);
|
var existingAction = UserActions.FirstOrDefault(action => action.Id == updatedAction.Id);
|
||||||
|
|
||||||
|
|
||||||
if (existingAction != null)
|
if (existingAction != null)
|
||||||
{
|
{
|
||||||
existingAction.Description = updatedAction.Description;
|
//existingAction.Description = updatedAction.Description;
|
||||||
existingAction.Timestamp = updatedAction.Timestamp;
|
//existingAction.Timestamp = updatedAction.Timestamp;
|
||||||
Update(existingAction);
|
//existingAction.TestingMode = updatedAction.TestingMode;
|
||||||
|
Update(updatedAction);
|
||||||
Console.WriteLine("---------------Updated the Action in the database-----------------");
|
Console.WriteLine("---------------Updated the Action in the database-----------------");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace InnovEnergy.App.Backend.Websockets;
|
||||||
|
|
||||||
public static class WebsocketManager
|
public static class WebsocketManager
|
||||||
{
|
{
|
||||||
public static Dictionary<int, InstallationInfo> InstallationConnections = new Dictionary<int, InstallationInfo>();
|
public static Dictionary<Int64, InstallationInfo> InstallationConnections = new Dictionary<Int64, InstallationInfo>();
|
||||||
|
|
||||||
//Every 2 minutes, check the timestamp of the latest received message for every installation.
|
//Every 2 minutes, check the timestamp of the latest received message for every installation.
|
||||||
//If the difference between the two timestamps is more than two minutes, we consider this installation unavailable.
|
//If the difference between the two timestamps is more than two minutes, we consider this installation unavailable.
|
||||||
|
@ -30,15 +30,18 @@ public static class WebsocketManager
|
||||||
}
|
}
|
||||||
|
|
||||||
//Inform all the connected websockets regarding installation "installationId"
|
//Inform all the connected websockets regarding installation "installationId"
|
||||||
public static void InformWebsocketsForInstallation(int installationId)
|
public static void InformWebsocketsForInstallation(Int64 installationId)
|
||||||
{
|
{
|
||||||
|
var installation = Db.GetInstallationById(installationId);
|
||||||
var installationConnection = InstallationConnections[installationId];
|
var installationConnection = InstallationConnections[installationId];
|
||||||
Console.WriteLine("Update all the connected websockets for installation " + installationId);
|
Console.WriteLine("Update all the connected websockets for installation " + installationId);
|
||||||
|
|
||||||
|
|
||||||
var jsonObject = new
|
var jsonObject = new
|
||||||
{
|
{
|
||||||
id = installationId,
|
id = installationId,
|
||||||
status = installationConnection.Status
|
status = installationConnection.Status,
|
||||||
|
testingMode = installation.TestingMode
|
||||||
};
|
};
|
||||||
|
|
||||||
string jsonString = JsonSerializer.Serialize(jsonObject);
|
string jsonString = JsonSerializer.Serialize(jsonObject);
|
||||||
|
@ -99,9 +102,10 @@ public static class WebsocketManager
|
||||||
//Then, report the status of each requested installation to the front-end that created the websocket connection
|
//Then, report the status of each requested installation to the front-end that created the websocket connection
|
||||||
foreach (var installationId in installationIds)
|
foreach (var installationId in installationIds)
|
||||||
{
|
{
|
||||||
|
var installation = Db.GetInstallationById(installationId);
|
||||||
if (!InstallationConnections.ContainsKey(installationId))
|
if (!InstallationConnections.ContainsKey(installationId))
|
||||||
{
|
{
|
||||||
Console.WriteLine("Create new empty list for installation id " + installationId);
|
//Console.WriteLine("Create new empty list for installation id " + installationId);
|
||||||
InstallationConnections[installationId] = new InstallationInfo
|
InstallationConnections[installationId] = new InstallationInfo
|
||||||
{
|
{
|
||||||
Status = -1
|
Status = -1
|
||||||
|
@ -113,7 +117,8 @@ public static class WebsocketManager
|
||||||
var jsonObject = new
|
var jsonObject = new
|
||||||
{
|
{
|
||||||
id = installationId,
|
id = installationId,
|
||||||
status = InstallationConnections[installationId].Status
|
status = InstallationConnections[installationId].Status,
|
||||||
|
testingMode = installation.TestingMode
|
||||||
};
|
};
|
||||||
|
|
||||||
var jsonString = JsonSerializer.Serialize(jsonObject);
|
var jsonString = JsonSerializer.Serialize(jsonObject);
|
||||||
|
|
|
@ -11,8 +11,6 @@ import fr from './lang/fr.json';
|
||||||
import SuspenseLoader from './components/SuspenseLoader';
|
import SuspenseLoader from './components/SuspenseLoader';
|
||||||
import SidebarLayout from './layouts/SidebarLayout';
|
import SidebarLayout from './layouts/SidebarLayout';
|
||||||
import { TokenContext } from './contexts/tokenContext';
|
import { TokenContext } from './contexts/tokenContext';
|
||||||
import { TestModeProvider } from './contexts/TestModeContext';
|
|
||||||
import ResetPassword from './components/ResetPassword';
|
|
||||||
import InstallationTabs from './content/dashboards/Installations/index';
|
import InstallationTabs from './content/dashboards/Installations/index';
|
||||||
import routes from 'src/Resources/routes.json';
|
import routes from 'src/Resources/routes.json';
|
||||||
import './App.css';
|
import './App.css';
|
||||||
|
@ -143,9 +141,7 @@ function App() {
|
||||||
element={
|
element={
|
||||||
<AccessContextProvider>
|
<AccessContextProvider>
|
||||||
<InstallationsContextProvider>
|
<InstallationsContextProvider>
|
||||||
<TestModeProvider>
|
|
||||||
<InstallationTabs />
|
<InstallationTabs />
|
||||||
</TestModeProvider>
|
|
||||||
</InstallationsContextProvider>
|
</InstallationsContextProvider>
|
||||||
</AccessContextProvider>
|
</AccessContextProvider>
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ import { AxiosError, AxiosResponse } from 'axios/index';
|
||||||
import routes from '../../../Resources/routes.json';
|
import routes from '../../../Resources/routes.json';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { TokenContext } from '../../../contexts/tokenContext';
|
import { TokenContext } from '../../../contexts/tokenContext';
|
||||||
import { useTestMode } from '../../../contexts/TestModeContext';
|
|
||||||
import { Action } from '../../../interfaces/S3Types';
|
import { Action } from '../../../interfaces/S3Types';
|
||||||
import Button from '@mui/material/Button';
|
import Button from '@mui/material/Button';
|
||||||
import { DateTimePicker, LocalizationProvider } from '@mui/x-date-pickers';
|
import { DateTimePicker, LocalizationProvider } from '@mui/x-date-pickers';
|
||||||
|
@ -49,19 +48,14 @@ function HistoryOfActions(props: HistoryProps) {
|
||||||
const [newAction, setNewAction] = useState<Partial<Action>>({
|
const [newAction, setNewAction] = useState<Partial<Action>>({
|
||||||
installationId: props.id,
|
installationId: props.id,
|
||||||
timestamp: actionDate.toDate(),
|
timestamp: actionDate.toDate(),
|
||||||
description: ''
|
description: '',
|
||||||
|
testingMode: false
|
||||||
});
|
});
|
||||||
const { testModeMap, setTestMode } = useTestMode();
|
|
||||||
const isTestMode = testModeMap[props.id] || false;
|
|
||||||
const context = useContext(UserContext);
|
const context = useContext(UserContext);
|
||||||
const { currentUser, setUser } = context;
|
const { currentUser, setUser } = context;
|
||||||
const [isRowHovered, setHoveredRow] = useState(-1);
|
const [isRowHovered, setHoveredRow] = useState(-1);
|
||||||
const [selectedAction, setSelectedAction] = useState<number>(-1);
|
const [selectedAction, setSelectedAction] = useState<number>(-1);
|
||||||
const [editMode, setEditMode] = useState(false);
|
const [editMode, setEditMode] = useState(false);
|
||||||
const handleTestModeToggle = () => {
|
|
||||||
setTestMode(props.id, !isTestMode);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDateChange = (newdate) => {
|
const handleDateChange = (newdate) => {
|
||||||
setActionDate(newdate);
|
setActionDate(newdate);
|
||||||
setNewAction({
|
setNewAction({
|
||||||
|
@ -71,10 +65,10 @@ function HistoryOfActions(props: HistoryProps) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleChange = (e) => {
|
const handleChange = (e) => {
|
||||||
const { name, value } = e.target;
|
const { name, type, checked, value } = e.target;
|
||||||
setNewAction({
|
setNewAction({
|
||||||
...newAction,
|
...newAction,
|
||||||
[name]: value
|
[name]: type === 'checkbox' ? checked : value
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -83,7 +77,8 @@ function HistoryOfActions(props: HistoryProps) {
|
||||||
setActionDate(dayjs());
|
setActionDate(dayjs());
|
||||||
setNewAction({
|
setNewAction({
|
||||||
...newAction,
|
...newAction,
|
||||||
['description']: ''
|
['description']: '',
|
||||||
|
['timestamp']: dayjs().toDate()
|
||||||
});
|
});
|
||||||
setEditMode(false);
|
setEditMode(false);
|
||||||
};
|
};
|
||||||
|
@ -233,8 +228,9 @@ function HistoryOfActions(props: HistoryProps) {
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={
|
control={
|
||||||
<Switch
|
<Switch
|
||||||
checked={isTestMode}
|
name="testingMode"
|
||||||
onChange={handleTestModeToggle}
|
checked={newAction.testingMode}
|
||||||
|
onChange={handleChange}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label="Test Mode"
|
label="Test Mode"
|
||||||
|
|
|
@ -16,7 +16,6 @@ import { I_Installation } from 'src/interfaces/InstallationTypes';
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
import BuildIcon from '@mui/icons-material/Build';
|
import BuildIcon from '@mui/icons-material/Build';
|
||||||
import { WebSocketContext } from 'src/contexts/WebSocketContextProvider';
|
import { WebSocketContext } from 'src/contexts/WebSocketContextProvider';
|
||||||
import { useTestMode } from 'src/contexts/TestModeContext';
|
|
||||||
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';
|
||||||
|
@ -28,11 +27,10 @@ interface FlatInstallationViewProps {
|
||||||
const FlatInstallationView = (props: FlatInstallationViewProps) => {
|
const FlatInstallationView = (props: FlatInstallationViewProps) => {
|
||||||
const [isRowHovered, setHoveredRow] = useState(-1);
|
const [isRowHovered, setHoveredRow] = useState(-1);
|
||||||
const webSocketContext = useContext(WebSocketContext);
|
const webSocketContext = useContext(WebSocketContext);
|
||||||
const { getStatus } = webSocketContext;
|
const { getStatus, getTestingMode } = webSocketContext;
|
||||||
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 { testModeMap } = useTestMode();
|
|
||||||
|
|
||||||
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.
|
||||||
|
@ -246,7 +244,7 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{testModeMap[installation.id] && (
|
{getTestingMode(installation.id) && (
|
||||||
<BuildIcon
|
<BuildIcon
|
||||||
style={{
|
style={{
|
||||||
width: '23px',
|
width: '23px',
|
||||||
|
@ -255,7 +253,7 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => {
|
||||||
borderRadius: '50%',
|
borderRadius: '50%',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
zIndex: 1,
|
zIndex: 1,
|
||||||
marginLeft: status === -1 || status === -2 ? '-23px' : '2px',
|
marginLeft: '15px'
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -32,7 +32,6 @@ 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';
|
import PvView from '../PvView/PvView';
|
||||||
import { useTestMode } from '../../../contexts/TestModeContext';
|
|
||||||
|
|
||||||
interface singleInstallationProps {
|
interface singleInstallationProps {
|
||||||
current_installation?: I_Installation;
|
current_installation?: I_Installation;
|
||||||
|
@ -46,13 +45,12 @@ function Installation(props: singleInstallationProps) {
|
||||||
const [fetchFunctionCalled, setFetchFunctionCalled] = useState(false);
|
const [fetchFunctionCalled, setFetchFunctionCalled] = useState(false);
|
||||||
const [errorLoadingS3Data, setErrorLoadingS3Data] = useState(false);
|
const [errorLoadingS3Data, setErrorLoadingS3Data] = useState(false);
|
||||||
const webSocketsContext = useContext(WebSocketContext);
|
const webSocketsContext = useContext(WebSocketContext);
|
||||||
const { getStatus } = webSocketsContext;
|
const { getStatus, getTestingMode } = webSocketsContext;
|
||||||
const [currentTab, setCurrentTab] = useState<string>(undefined);
|
const [currentTab, setCurrentTab] = useState<string>(undefined);
|
||||||
const [values, setValues] = useState<TopologyValues | null>(null);
|
const [values, setValues] = useState<TopologyValues | null>(null);
|
||||||
const status = getStatus(props.current_installation.id);
|
const status = getStatus(props.current_installation.id);
|
||||||
const [connected, setConnected] = useState(true);
|
const [connected, setConnected] = useState(true);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const { testModeMap } = useTestMode();
|
|
||||||
|
|
||||||
if (props.current_installation == undefined) {
|
if (props.current_installation == undefined) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -362,7 +360,7 @@ function Installation(props: singleInstallationProps) {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{testModeMap[props.current_installation.id] && (
|
{getTestingMode(props.current_installation.id) && (
|
||||||
<BuildIcon
|
<BuildIcon
|
||||||
style={{
|
style={{
|
||||||
width: '23px',
|
width: '23px',
|
||||||
|
@ -371,34 +369,37 @@ function Installation(props: singleInstallationProps) {
|
||||||
borderRadius: '50%',
|
borderRadius: '50%',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
zIndex: 1,
|
zIndex: 1,
|
||||||
marginLeft: status === -1 || status === -2 ? '-23px' : '2px'
|
marginLeft: '15px'
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{loading && currentTab != 'information' && currentTab != 'history' && (
|
{loading &&
|
||||||
<Container
|
currentTab != 'information' &&
|
||||||
maxWidth="xl"
|
currentTab != 'history' &&
|
||||||
sx={{
|
currentTab != 'log' && (
|
||||||
display: 'flex',
|
<Container
|
||||||
flexDirection: 'column',
|
maxWidth="xl"
|
||||||
justifyContent: 'center',
|
sx={{
|
||||||
alignItems: 'center',
|
display: 'flex',
|
||||||
height: '70vh'
|
flexDirection: 'column',
|
||||||
}}
|
justifyContent: 'center',
|
||||||
>
|
alignItems: 'center',
|
||||||
<CircularProgress size={60} style={{ color: '#ffc04d' }} />
|
height: '70vh'
|
||||||
<Typography
|
}}
|
||||||
variant="body2"
|
|
||||||
style={{ color: 'black', fontWeight: 'bold' }}
|
|
||||||
mt={2}
|
|
||||||
>
|
>
|
||||||
Connecting to the device...
|
<CircularProgress size={60} style={{ color: '#ffc04d' }} />
|
||||||
</Typography>
|
<Typography
|
||||||
</Container>
|
variant="body2"
|
||||||
)}
|
style={{ color: 'black', fontWeight: 'bold' }}
|
||||||
|
mt={2}
|
||||||
|
>
|
||||||
|
Connecting to the device...
|
||||||
|
</Typography>
|
||||||
|
</Container>
|
||||||
|
)}
|
||||||
|
|
||||||
<Card variant="outlined">
|
<Card variant="outlined">
|
||||||
<Grid
|
<Grid
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
import React, { createContext, useContext, useState, ReactNode } from 'react';
|
|
||||||
|
|
||||||
interface TestModeContextProps {
|
|
||||||
testModeMap: { [key: number]: boolean };
|
|
||||||
setTestMode: (id: number, mode: boolean) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TestModeContext = createContext<TestModeContextProps | undefined>(undefined);
|
|
||||||
|
|
||||||
export const useTestMode = () => {
|
|
||||||
const context = useContext(TestModeContext);
|
|
||||||
if (!context) {
|
|
||||||
throw new Error('useTestMode must be used within a TestModeProvider');
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const TestModeProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
|
|
||||||
const [testModeMap, setTestModeMap] = useState<{ [key: number]: boolean }>({});
|
|
||||||
|
|
||||||
const setTestMode = (id: number, mode: boolean) => {
|
|
||||||
setTestModeMap(prev => ({ ...prev, [id]: mode }));
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TestModeContext.Provider value={{ testModeMap, setTestMode }}>
|
|
||||||
{children}
|
|
||||||
</TestModeContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -7,6 +7,7 @@ interface WebSocketContextProviderProps {
|
||||||
openSocket: (installations: I_Installation[]) => void;
|
openSocket: (installations: I_Installation[]) => void;
|
||||||
closeSocket: () => void;
|
closeSocket: () => void;
|
||||||
getStatus: (installationId: number) => number;
|
getStatus: (installationId: number) => number;
|
||||||
|
getTestingMode: (installationId: number) => boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the context.
|
// Create the context.
|
||||||
|
@ -18,7 +19,10 @@ const WebSocketContextProvider = ({ children }: { children: ReactNode }) => {
|
||||||
const [socket, setSocket] = useState<WebSocket>(null);
|
const [socket, setSocket] = useState<WebSocket>(null);
|
||||||
const [installations, setInstallations] = useState<I_Installation[]>(null);
|
const [installations, setInstallations] = useState<I_Installation[]>(null);
|
||||||
const [installationStatus, setInstallationStatus] = useState<
|
const [installationStatus, setInstallationStatus] = useState<
|
||||||
Record<number, number[]>
|
Record<number, number>
|
||||||
|
>({});
|
||||||
|
const [installationMode, setInstallatioMode] = useState<
|
||||||
|
Record<number, boolean>
|
||||||
>({});
|
>({});
|
||||||
const BUFFER_LENGTH = 5;
|
const BUFFER_LENGTH = 5;
|
||||||
|
|
||||||
|
@ -52,23 +56,19 @@ const WebSocketContextProvider = ({ children }: { children: ReactNode }) => {
|
||||||
|
|
||||||
if (message.id != -1) {
|
if (message.id != -1) {
|
||||||
const installation_id = message.id;
|
const installation_id = message.id;
|
||||||
const status = message.status;
|
|
||||||
|
|
||||||
//console.log('Message from server ', installation_id, status);
|
//console.log('Message from server ', installation_id, status);
|
||||||
|
setInstallatioMode((prevMode) => {
|
||||||
|
// Create a new object by spreading the previous state
|
||||||
|
const newMode = { ...prevMode };
|
||||||
|
newMode[installation_id] = message.testingMode;
|
||||||
|
return newMode;
|
||||||
|
});
|
||||||
|
|
||||||
setInstallationStatus((prevStatus) => {
|
setInstallationStatus((prevStatus) => {
|
||||||
// Create a new object by spreading the previous state
|
// Create a new object by spreading the previous state
|
||||||
const newStatus = { ...prevStatus };
|
const newStatus = { ...prevStatus };
|
||||||
|
newStatus[installation_id] = message.status;
|
||||||
if (!newStatus.hasOwnProperty(installation_id)) {
|
|
||||||
newStatus[installation_id] = [];
|
|
||||||
}
|
|
||||||
newStatus[installation_id].unshift(status);
|
|
||||||
newStatus[installation_id] = newStatus[installation_id].slice(
|
|
||||||
0,
|
|
||||||
BUFFER_LENGTH
|
|
||||||
);
|
|
||||||
|
|
||||||
return newStatus;
|
return newStatus;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -90,18 +90,23 @@ const WebSocketContextProvider = ({ children }: { children: ReactNode }) => {
|
||||||
if (!installationStatus.hasOwnProperty(installationId)) {
|
if (!installationStatus.hasOwnProperty(installationId)) {
|
||||||
status = -2;
|
status = -2;
|
||||||
} else {
|
} else {
|
||||||
status = installationStatus[installationId][0];
|
status = installationStatus[installationId];
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getTestingMode = (installationId: number) => {
|
||||||
|
return installationMode[installationId];
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WebSocketContext.Provider
|
<WebSocketContext.Provider
|
||||||
value={{
|
value={{
|
||||||
socket: socket,
|
socket: socket,
|
||||||
openSocket: openSocket,
|
openSocket: openSocket,
|
||||||
closeSocket: closeSocket,
|
closeSocket: closeSocket,
|
||||||
getStatus: getStatus
|
getStatus: getStatus,
|
||||||
|
getTestingMode: getTestingMode
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
@ -18,6 +18,7 @@ export interface I_Installation extends I_S3Credentials {
|
||||||
s3WriteSecret: string;
|
s3WriteSecret: string;
|
||||||
product: number;
|
product: number;
|
||||||
device: number;
|
device: number;
|
||||||
|
testingMode: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface I_Folder {
|
export interface I_Folder {
|
||||||
|
|
|
@ -29,4 +29,5 @@ export interface Action {
|
||||||
installationId: number;
|
installationId: number;
|
||||||
timestamp: Date;
|
timestamp: Date;
|
||||||
description: string;
|
description: string;
|
||||||
|
testingMode: boolean;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue