From ea5d9db7906d94cf387aeb908f0245fee83be01d Mon Sep 17 00:00:00 2001 From: Tristan Timblin Date: Thu, 18 Jan 2024 13:25:41 -0800 Subject: [PATCH] CEC-5618: add state and timeout toggles (#495) --- .../BulkActions/actions/Diagnostic.jsx | 111 +++++++++++++++--- .../Controls/SendDiagnosticCommand/index.jsx | 5 +- 2 files changed, 98 insertions(+), 18 deletions(-) diff --git a/src/components/BulkActions/actions/Diagnostic.jsx b/src/components/BulkActions/actions/Diagnostic.jsx index 2120abb..a124957 100644 --- a/src/components/BulkActions/actions/Diagnostic.jsx +++ b/src/components/BulkActions/actions/Diagnostic.jsx @@ -1,17 +1,31 @@ import { forwardRef, useImperativeHandle, useState, useEffect } from "react"; import { + Box, FormControl, + FormControlLabel, + Grid, + TextField, InputLabel, Select, + Switch, } from "@material-ui/core"; import api from "../../../services/vehiclesAPI"; import TaskRunner from "../../../utils/taskRunner"; -import { AllECUsCommand, DIAGNOSTIC_COMMANDS } from "../../Controls/SendDiagnosticCommand"; +import { AllECUsCommand } from "../../Controls/SendDiagnosticCommand"; import useStyles from "../../useStyles"; import { useStatusContext } from "../../Contexts/StatusContext"; import { useUserContext } from "../../Contexts/UserContext"; import unionIntersect from "../../../utils/unionIntersect"; +const DIAGNOSTIC_COMMANDS = [ + { displayname: "Reset", val: "remote_reset", ecu_name: true }, + { displayname: "Set CAN Network State", val: "can_network", state: "can_net_action" }, + { displayname: "Set Remote Ignition", val: "remote_ignition", state: "can_net_action" }, + { displayname: "Read ECU versions", val: "read_ecu_versions", allowAll: true, ecu_name: true }, +]; + +const DEFAULT_SECONDS = 180; + async function getECUsByVINs(vins, token) { return new Promise((resolve, reject) => { const taskRunner = new TaskRunner(30, vins.length); @@ -46,6 +60,8 @@ export default forwardRef(({ const [currentECU, setCurrentECU] = useState(""); const [validateECUs, setValidateECUs] = useState(false); const [command, setCommand] = useState(DIAGNOSTIC_COMMANDS[0]); + const [checked, setChecked] = useState(false); + const [seconds, setSeconds] = useState(DEFAULT_SECONDS); const classes = useStyles(); const { setMessage } = useStatusContext(); const { token: { idToken: { jwtToken: token } } } = useUserContext(); @@ -56,15 +72,12 @@ export default forwardRef(({ return Promise.reject("Invalid ECUs found, cannot submit"); } - return api.sendDiagnosticCommand(ids, { - command: command.val, - ecu_name: currentECU, - }, token) + return api.sendDiagnosticCommand(ids, createDiagnosticPayload(command, checked, currentECU, seconds), token) .then(() => { - setMessage(`Sent ${command} command to ${ids.length} vehicles.`); + setMessage(`Sent ${command.val} command to ${ids.length} vehicles.`); }) .catch(() => { - setMessage(`Failed to send ${command} command.`); + setMessage(`Failed to send ${command.val} command.`); }); } })); @@ -73,6 +86,17 @@ export default forwardRef(({ setCommand(DIAGNOSTIC_COMMANDS[e.target.value]); }; + const handleSwitch = (e) => { + setChecked(e.target.checked); + } + + const handleSecondsChange = (e) => { + const value = Number(e.target.value); + if (value > 0) { + setSeconds(); + } + } + useEffect(() => { async function fetchData() { setValidateECUs(false); @@ -82,22 +106,26 @@ export default forwardRef(({ fetchData(); }, [ids, token]); + useEffect(() => { + if (!checked) { + setSeconds(DEFAULT_SECONDS); + } + }, [checked, setSeconds]); + + useEffect(() => { + setChecked(false); + }, [command, setChecked]); + useEffect(() => { setValidateECUs(true); setCurrentECU(ecus[0].ecu); }, [ecus]); return ( -
+

Attempt to send a vehicle diagnostic command to the following VINs: {idCSV}.

- @@ -117,6 +145,57 @@ export default forwardRef(({ ))} -
+ + {["remote_reset", "read_ecu_versions"].includes(command.val) && } + + {["can_network", "remote_ignition"].includes(command.val) && ( + +
+ } + /> +
+ +
+ )} + ); -}); \ No newline at end of file +}); + +const hasOwnProperty = (obj, key) => { + return Object.prototype.hasOwnProperty.call(obj, key); +} + +const createDiagnosticPayload = (command = {}, checked, ecu, seconds) => { + const payload = { + command: command.val, + }; + + if (hasOwnProperty(command, "ecu_name")) { + payload.ecu_name = ecu; + } + + if (hasOwnProperty(command, "state")) { + payload[command.state] = checked ? "on" : "off"; + payload.timeout = seconds; + } + + return payload; +} \ No newline at end of file diff --git a/src/components/Controls/SendDiagnosticCommand/index.jsx b/src/components/Controls/SendDiagnosticCommand/index.jsx index 68c878b..cdcfc6c 100644 --- a/src/components/Controls/SendDiagnosticCommand/index.jsx +++ b/src/components/Controls/SendDiagnosticCommand/index.jsx @@ -13,13 +13,13 @@ import { useVehicleContext } from "../../Contexts/VehicleContext"; -export const DIAGNOSTIC_COMMANDS = [ +const DIAGNOSTIC_COMMANDS = [ { displayname: "Reset", val: "remote_reset" }, { displayname: "Set CAN Network State", val: "can_network" }, { displayname: "Set Remote Ignition", val: "remote_ignition" }, { displayname: "Send Wake Up SMS", val: "sms" }, // { displayname: "Update SecOC keys", val: "write_secoc_key" }, - { displayname: "Read ECU versions", val: "read_ecu_versions", allowAll: true }, + { displayname: "Read ECU versions", val: "read_ecu_versions" }, ] const SendDiagnosticCommand = ({ vin, token, classes }) => { @@ -195,6 +195,7 @@ export const AllECUsCommand = ({ classes, ecus, currentECU, setCurrentECU }) => className={classes.formControl} variant="outlined" size="small" + margin="normal" > ECU