CEC-4517 reset TBOX remote command (#369)
* CEC-4517 Diagnostic Commands tab * snapshot
This commit is contained in:
@@ -11242,7 +11242,7 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
<span
|
<span
|
||||||
class="MuiTab-wrapper"
|
class="MuiTab-wrapper"
|
||||||
>
|
>
|
||||||
Fleets
|
Remote Diagnostic Commands
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="MuiTouchRipple-root"
|
class="MuiTouchRipple-root"
|
||||||
@@ -11256,6 +11256,24 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
role="tab"
|
role="tab"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
type="button"
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTab-wrapper"
|
||||||
|
>
|
||||||
|
Fleets
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-controls="tabpanel-10"
|
||||||
|
aria-selected="false"
|
||||||
|
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
||||||
|
id="tab-10"
|
||||||
|
role="tab"
|
||||||
|
tabindex="-1"
|
||||||
|
type="button"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="MuiTab-wrapper"
|
class="MuiTab-wrapper"
|
||||||
@@ -11590,6 +11608,13 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
id="tabpanel-9"
|
id="tabpanel-9"
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
|
aria-labelledby="tab-10"
|
||||||
|
class="makeStyles-tabContainer-0"
|
||||||
|
hidden=""
|
||||||
|
id="tabpanel-10"
|
||||||
|
role="tabpanel"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
30
src/components/Cars/Status/RemoteDiagnosticCommands.jsx
Normal file
30
src/components/Cars/Status/RemoteDiagnosticCommands.jsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import useStyles from "../../useStyles";
|
||||||
|
import clsx from "clsx";
|
||||||
|
import Typography from "@material-ui/core/Typography";
|
||||||
|
import SendDiagnosticCommand from "../../Controls/SendDiagnosticCommand";
|
||||||
|
import { useParams } from "react-router";
|
||||||
|
|
||||||
|
import { useUserContext } from "../../Contexts/UserContext";
|
||||||
|
|
||||||
|
import {VehicleProvider} from "../../Contexts/VehicleContext";
|
||||||
|
|
||||||
|
const RemoteDiagnosticCommandsTab = (props) => {
|
||||||
|
const { vin } = useParams();
|
||||||
|
const classes = useStyles();
|
||||||
|
const {
|
||||||
|
token: {
|
||||||
|
idToken: { jwtToken: token },
|
||||||
|
},
|
||||||
|
} = useUserContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={clsx(classes.paper, classes.tableSize)}>
|
||||||
|
<Typography variant="h6">Vehicle Diagnostic Commands</Typography>
|
||||||
|
<VehicleProvider>
|
||||||
|
<SendDiagnosticCommand vin={vin} token={token} classes={classes}></SendDiagnosticCommand>
|
||||||
|
</VehicleProvider>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RemoteDiagnosticCommandsTab
|
||||||
@@ -189,7 +189,7 @@ exports[`CarStatus Render 1`] = `
|
|||||||
<span
|
<span
|
||||||
class="MuiTab-wrapper"
|
class="MuiTab-wrapper"
|
||||||
>
|
>
|
||||||
Fleets
|
Remote Diagnostic Commands
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="MuiTouchRipple-root"
|
class="MuiTouchRipple-root"
|
||||||
@@ -203,6 +203,24 @@ exports[`CarStatus Render 1`] = `
|
|||||||
role="tab"
|
role="tab"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
type="button"
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTab-wrapper"
|
||||||
|
>
|
||||||
|
Fleets
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-controls="tabpanel-10"
|
||||||
|
aria-selected="false"
|
||||||
|
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
||||||
|
id="tab-10"
|
||||||
|
role="tab"
|
||||||
|
tabindex="-1"
|
||||||
|
type="button"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="MuiTab-wrapper"
|
class="MuiTab-wrapper"
|
||||||
@@ -480,6 +498,13 @@ exports[`CarStatus Render 1`] = `
|
|||||||
id="tabpanel-9"
|
id="tabpanel-9"
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
|
aria-labelledby="tab-10"
|
||||||
|
class="makeStyles-tabContainer-0"
|
||||||
|
hidden=""
|
||||||
|
id="tabpanel-10"
|
||||||
|
role="tabpanel"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import DigitalTwinTab from "./DigitalTwinTab";
|
|||||||
import ECUsTab from "./ECUsTab";
|
import ECUsTab from "./ECUsTab";
|
||||||
import FleetsTab from "./FleetsTab";
|
import FleetsTab from "./FleetsTab";
|
||||||
import RemoteCommandsTab from "./RemoteCommandsTab";
|
import RemoteCommandsTab from "./RemoteCommandsTab";
|
||||||
|
import RemoteDiagnosticCommandsTab from "./RemoteDiagnosticCommands";
|
||||||
import TRexLogsTab from "./TRexLogsTab";
|
import TRexLogsTab from "./TRexLogsTab";
|
||||||
|
|
||||||
const tabHashes = ["details", "updates", "filters"];
|
const tabHashes = ["details", "updates", "filters"];
|
||||||
@@ -63,6 +64,11 @@ const TabViews = [
|
|||||||
component: RemoteCommandsTab,
|
component: RemoteCommandsTab,
|
||||||
rolesPerProvider: Permissions.FiskerMagnaCreate,
|
rolesPerProvider: Permissions.FiskerMagnaCreate,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "Remote Diagnostic Commands",
|
||||||
|
component: RemoteDiagnosticCommandsTab,
|
||||||
|
rolesPerProvider: Permissions.FiskerMagnaCreate,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "Fleets",
|
label: "Fleets",
|
||||||
component: FleetsTab,
|
component: FleetsTab,
|
||||||
|
|||||||
@@ -202,6 +202,18 @@ export const VehicleProvider = ({ children }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sendDiagnosticCommand = async (vins, command, token) => {
|
||||||
|
try {
|
||||||
|
setBusy(true);
|
||||||
|
const result = await api.sendDiagnosticCommand(vins, command, token);
|
||||||
|
if (result.error)
|
||||||
|
throw new Error(`Send diagnostic command error. ${result.message}`);
|
||||||
|
return result;
|
||||||
|
} finally {
|
||||||
|
setBusy(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const updateVehicle = async (vin, v, token) => {
|
const updateVehicle = async (vin, v, token) => {
|
||||||
try {
|
try {
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
@@ -313,6 +325,7 @@ export const VehicleProvider = ({ children }) => {
|
|||||||
getVehicle,
|
getVehicle,
|
||||||
getVehicles,
|
getVehicles,
|
||||||
sendCommand,
|
sendCommand,
|
||||||
|
sendDiagnosticCommand,
|
||||||
updateVehicle,
|
updateVehicle,
|
||||||
getFleets,
|
getFleets,
|
||||||
getVersionLog,
|
getVersionLog,
|
||||||
|
|||||||
119
src/components/Controls/SendDiagnosticCommand/index.jsx
Normal file
119
src/components/Controls/SendDiagnosticCommand/index.jsx
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
import clsx from "clsx";
|
||||||
|
|
||||||
|
import { Button, FormControl, InputLabel, Select, FormControlLabel, FormGroup } from "@material-ui/core";
|
||||||
|
import Checkbox from '@mui/material/Checkbox';
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||||
|
import { logger } from "../../../services/monitoring";
|
||||||
|
|
||||||
|
|
||||||
|
import {
|
||||||
|
useVehicleContext
|
||||||
|
} from "../../Contexts/VehicleContext";
|
||||||
|
|
||||||
|
const commands = ["Reset"]
|
||||||
|
const ecus = ["TBOX"]
|
||||||
|
|
||||||
|
const SendDiagnosticCommand = ({ vin, token, classes }) => {
|
||||||
|
|
||||||
|
const { getState, sendDiagnosticCommand } = useVehicleContext();
|
||||||
|
|
||||||
|
const [carState, setCarState] = useState(null);
|
||||||
|
const { setMessage } = useStatusContext();
|
||||||
|
|
||||||
|
const [currentCommand, setCurrentCommand] = useState(commands[0].toLowerCase());
|
||||||
|
const [currentECUs] = useState([ecus[0]]);
|
||||||
|
|
||||||
|
const changeCommandHandler = (e) => {
|
||||||
|
setCurrentCommand(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//Update online/offline state
|
||||||
|
useEffect(() => {
|
||||||
|
if (!vin) return;
|
||||||
|
getCarState();
|
||||||
|
const interval = setInterval(getCarState, 5000);
|
||||||
|
return () => { clearInterval(interval); }
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [vin]);
|
||||||
|
|
||||||
|
const getCarState = async () => {
|
||||||
|
try {
|
||||||
|
const result = await getState(token, vin);
|
||||||
|
setCarState(result.data);
|
||||||
|
} catch (e) {
|
||||||
|
setMessage(e.message);
|
||||||
|
logger.warn(e.stack);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const clickHandler = async (_) => {
|
||||||
|
try {
|
||||||
|
await sendDiagnosticCommand([vin], { body: { command: currentCommand, ecus: currentECUs } }, token);
|
||||||
|
setMessage(`Sent diagnostic command to ${vin}`);
|
||||||
|
} catch (error) {
|
||||||
|
setMessage(error.message);
|
||||||
|
logger.error(error.stack);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={clsx(classes.paper, classes.tableSize)}>
|
||||||
|
<FormControl
|
||||||
|
className={classes.formControl}
|
||||||
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<InputLabel htmlFor="send-command" className={classes.whiteBackground}>
|
||||||
|
Diagnostic Command
|
||||||
|
</InputLabel>
|
||||||
|
<Select
|
||||||
|
native
|
||||||
|
variant="outlined"
|
||||||
|
inputProps={{
|
||||||
|
name: "send-command",
|
||||||
|
id: "send-command",
|
||||||
|
}}
|
||||||
|
onChange={changeCommandHandler}
|
||||||
|
>
|
||||||
|
{commands.map((command, index) => (
|
||||||
|
<option key={index} value={command.toLowerCase()}>
|
||||||
|
{command}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
<FormGroup>
|
||||||
|
{
|
||||||
|
ecus.map((ecu, idx) => {
|
||||||
|
return <FormControlLabel
|
||||||
|
control={<Checkbox key={idx} />}
|
||||||
|
label={ecu}
|
||||||
|
value={ecu}
|
||||||
|
checked={true} />
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</FormGroup>
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
aria-label="send command"
|
||||||
|
fullWidth
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
className={classes.submit}
|
||||||
|
onClick={clickHandler}
|
||||||
|
disabled={!carState.online}
|
||||||
|
>
|
||||||
|
Send
|
||||||
|
</Button>
|
||||||
|
<div>
|
||||||
|
<b>
|
||||||
|
{carState && carState.online ? "ONLINE" : "OFFLINE"}
|
||||||
|
</b>
|
||||||
|
</div>
|
||||||
|
</div >
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SendDiagnosticCommand;
|
||||||
@@ -173,6 +173,21 @@ const vehiclesAPI = {
|
|||||||
.then(fetchRespHandler)
|
.then(fetchRespHandler)
|
||||||
.catch(errorHandler),
|
.catch(errorHandler),
|
||||||
|
|
||||||
|
sendDiagnosticCommand: async (vins, command, token) =>
|
||||||
|
fetch(`${API_ENDPOINT}/vehiclediagnosticcommand`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: Object.assign(
|
||||||
|
{ "Content-Type": "application/json" },
|
||||||
|
getAuthHeaderOptions(token)
|
||||||
|
),
|
||||||
|
body: JSON.stringify({
|
||||||
|
vins,
|
||||||
|
...command,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then(fetchRespHandler)
|
||||||
|
.catch(errorHandler),
|
||||||
|
|
||||||
updateVehicle: async (vin, vehicle, token) =>
|
updateVehicle: async (vin, vehicle, token) =>
|
||||||
fetch(`${API_ENDPOINT}/vehicle/${vin}`, {
|
fetch(`${API_ENDPOINT}/vehicle/${vin}`, {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
|
|||||||
Reference in New Issue
Block a user