Merge branch 'main' into CEC-5443

This commit is contained in:
Paul Adamsen
2024-01-18 17:24:28 -05:00
committed by GitHub
4 changed files with 116 additions and 18 deletions

View File

@@ -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 (
<div>
<Box minHeight="185px">
<p>
Attempt to send a vehicle diagnostic command to the following VINs: {idCSV}.
</p>
<AllECUsCommand
classes={classes}
ecus={command.allowAll ? [...ecus, { ecu: "*" }] : ecus}
currentECU={currentECU}
setCurrentECU={setCurrentECU}
/>
<FormControl className={classes.formControl} variant="outlined" size="small" margin="normal">
<InputLabel htmlFor="send-command" className={classes.whiteBackground}>
@@ -117,6 +145,57 @@ export default forwardRef(({
))}
</Select>
</FormControl>
</div>
{["remote_reset", "read_ecu_versions"].includes(command.val) && <AllECUsCommand
classes={classes}
ecus={command.allowAll ? [...ecus, { ecu: "*" }] : ecus}
currentECU={currentECU}
setCurrentECU={setCurrentECU}
/>}
{["can_network", "remote_ignition"].includes(command.val) && (
<Grid container direction="row" alignItems="flex-end" >
<div>
<FormControlLabel
label="State"
labelPlacement="end"
control={<Switch checked={checked} onChange={handleSwitch} />}
/>
</div>
<TextField
label="Seconds"
type="number"
onChange={handleSecondsChange}
value={seconds}
disabled={!checked}
inputProps={{
min: "0",
step: "10",
}}
/>
</Grid>
)}
</Box>
);
});
});
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;
}

View File

@@ -14,6 +14,8 @@ function parseVin(vin = "") {
return [true, vin.replace(prefix, "")];
}
vin = vin.replace(/[^\p{L}\d]/gu, '');
var re = new RegExp("^[A-HJ-NPR-Z0-9]{8}[0-9X][A-HJ-NPR-Z0-9]{2}[0-9]{6}$");
return [vin.match(re), vin];
}

View File

@@ -89,6 +89,22 @@ describe("useQuery", () => {
["test", "VCF1EBE2008016235,VCF1EBE20PG001002,VCF1EBE20PG001162", "test vin:VCF1EBE2008016235 vin:VCF1EBE20PG001002 vin:VCF1EBE20PG001162"]
],
[
"parses a space separated search query with special characters",
"[ocean] pe@r a!aska r*nin",
["[ocean] pe@r a!aska r*nin", "", "[ocean] pe@r a!aska r*nin"]
],
[
"parses a space separated vin query with special characters",
"[\"VCF1EBE2008016235\", \"VCF1EBE20PG001002\", \"VCF1EBE20PG001162\"]",
["", "VCF1EBE2008016235,VCF1EBE20PG001002,VCF1EBE20PG001162", "vin:VCF1EBE2008016235 vin:VCF1EBE20PG001002 vin:VCF1EBE20PG001162"]
],
[
"parses a space separated mixed search and vin query with special characters",
"te$t VCF1EBE20@*(08016235 [VCF1EBE2]0PG001002 VCF*1EBE20PG001162",
["te$t", "VCF1EBE2008016235,VCF1EBE20PG001002,VCF1EBE20PG001162", "te$t vin:VCF1EBE2008016235 vin:VCF1EBE20PG001002 vin:VCF1EBE20PG001162"]
],
[
"trims extraneous values from search",
"ocean,, , ,,,,pear,,, ",

View File

@@ -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"
>
<InputLabel className={classes.whiteBackground}>
ECU