CEC-222, CEC-214 Send car commands and log filtering (#41)

* Send car commands

* Log filter control

* Fix message format

* Move VehicleContext
This commit is contained in:
John Wu
2021-05-18 12:51:24 -07:00
committed by GitHub
parent 0d71a3f235
commit 64995ef7a6
9 changed files with 811 additions and 190 deletions

View File

@@ -0,0 +1,123 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import {
FormControlLabel,
Grid,
IconButton,
TextField,
Switch,
} from "@material-ui/core";
import SendIcon from "@material-ui/icons/Send";
import { useVehicleContext } from "../../Contexts/VehicleContext";
import { useUserContext } from "../../Contexts/UserContext";
import { useStatusContext } from "../../Contexts/StatusContext";
const LogFilter = ({ vin }) => {
const { sendLogFilter, busy } = useVehicleContext();
const {
token: {
idToken: { jwtToken: token },
},
} = useUserContext();
const { setMessage } = useStatusContext();
const [filter, setFilter] = useState("");
const [enableLog, setEnableLog] = useState(true);
const [freq, setFreq] = useState(0);
const changeFilterHandler = (e) => {
setFilter(e.target.value);
};
const changeStartHandler = (e) => {
setEnableLog(e.target.checked);
};
const changeFreqHandler = (e) => {
setFreq(e.target.value);
};
const clickHandler = async (e) => {
try {
const data = {
enable: enableLog,
frequency: freq,
filter,
};
await sendLogFilter(vin, data, token);
setMessage(`Sent log command to ${vin}`);
} catch (e) {
setMessage(e.message);
}
};
return (
<Grid
container
direction="row"
justify="flex-start"
alignItems="center"
spacing={2}
>
<Grid item>
<FormControlLabel
control={
<Switch
checked={enableLog}
onChange={changeStartHandler}
name="logStart"
color="primary"
/>
}
labelPlacement="top"
label="Logging"
/>
</Grid>
<Grid item>
<TextField
id="log-filter"
name="log-filter"
label="Filter"
variant="outlined"
margin="normal"
inputProps={{
maxLength: "17",
}}
disabled={!enableLog}
value={filter}
onChange={changeFilterHandler}
/>
</Grid>
<Grid item>
<TextField
id="log-frequency"
label="Frequency"
type="number"
disabled={!enableLog}
InputLabelProps={{
shrink: true,
}}
value={freq}
onChange={changeFreqHandler}
/>
</Grid>
<Grid item>
<IconButton
color="primary"
aria-label="send log command"
component="span"
onClick={clickHandler}
disabled={busy}
>
<SendIcon fontSize="large" />
</IconButton>
</Grid>
</Grid>
);
};
LogFilter.propTypes = {
vin: PropTypes.string.isRequired,
};
export default LogFilter;

View File

@@ -0,0 +1,81 @@
import React, { useEffect, useState } from "react";
import PropTypes from "prop-types";
import { FormControl, IconButton, InputLabel, Select } from "@material-ui/core";
import SendIcon from "@material-ui/icons/Send";
import { useVehicleContext } from "../../Contexts/VehicleContext";
import commands from "../../../services/commands";
import useStyles from "../../useStyles";
import { useUserContext } from "../../Contexts/UserContext";
import { useStatusContext } from "../../Contexts/StatusContext";
const SendCommand = ({ vin }) => {
const classes = useStyles();
const { sendCommand, busy } = useVehicleContext();
const {
token: {
idToken: { jwtToken: token },
},
} = useUserContext();
const { setMessage } = useStatusContext();
const [command, setCommand] = useState("");
const changeHandler = (e) => {
setCommand(e.target.value);
};
const clickHandler = async (e) => {
try {
await sendCommand(vin, command, token);
setMessage(`Sent command to ${vin}`);
} catch (e) {
setMessage(e.message);
}
};
useEffect(() => {
if (!commands || commands.length === 0) return;
setCommand(commands[0].value);
}, []);
return (
<div className={classes.form}>
<FormControl className={classes.formControlInline} variant="outlined">
<InputLabel htmlFor="send-command" style={{ backgroundColor: "White" }}>
Command
</InputLabel>
<Select
native
value={command}
variant="outlined"
inputProps={{
name: "send-command",
id: "send-command",
}}
onChange={changeHandler}
>
{commands.map((item) => (
<option key={item.value} value={item.value}>
{item.label}
</option>
))}
</Select>
</FormControl>
<IconButton
color="primary"
aria-label="send command"
component="span"
onClick={clickHandler}
disabled={busy}
>
<SendIcon fontSize="large" />
</IconButton>
</div>
);
};
SendCommand.propTypes = {
vin: PropTypes.string.isRequired,
};
export default SendCommand;

View File

@@ -1,6 +1,7 @@
import React, { useEffect, useState } from "react";
import { useParams } from "react-router";
import {
Grid,
Table,
TableBody,
TableCell,
@@ -16,10 +17,14 @@ import {
UpdatesProvider,
useUpdatesContext,
} from "../../Contexts/UpdatesContext";
import { VehicleProvider } from "../../Contexts/VehicleContext";
import { useUserContext } from "../../Contexts/UserContext";
import { useStatusContext } from "../../Contexts/StatusContext";
import useStyles from "../../useStyles";
import { LocalDateTimeString } from "../../../utils/dates";
import SendCommand from "../SendCommand";
import LogFilter from "../LogFilter";
const MainForm = () => {
const { vin } = useParams();
@@ -109,14 +114,24 @@ const MainForm = () => {
</TableFooter>
</Table>
</TableContainer>
<Grid container className={classes.root} spacing={2}>
<Grid item lg={6} md={12}>
<SendCommand vin={vin} />
</Grid>
<Grid item lg={6} md={12} style={{ textAlign: "right" }}>
<LogFilter vin={vin} />
</Grid>
</Grid>
</div>
);
};
const CarUpdates = () => (
<UpdatesProvider>
<MainForm />
</UpdatesProvider>
<VehicleProvider>
<UpdatesProvider>
<MainForm />
</UpdatesProvider>
</VehicleProvider>
);
export default CarUpdates;