Files
ota-admin-portal/src/components/DigitalTwin/index.js
John Wu 5120c27187 CEC-4581 Show battery voltage in digital twin (#365)
* CEC-4581 Show battery voltage in digital twin

* Fix warning
2023-06-20 14:46:00 -07:00

141 lines
4.5 KiB
JavaScript

import React from "react";
import { LocalDateTimeString } from "../../utils/dates";
import { ValidateLocationByParam } from "../../utils/locations";
import useStyles from "../useStyles";
const UNKNOWN = "unknown";
const LOCKED = "Locked";
const UNLOCKED = "Unlocked";
const appendUnits = (value, units) => {
if (value || value === 0) return `${value}${units}`;
return UNKNOWN;
}
const keyValueTemplate = (key, value) => (
<p key={key}>
<b>{key}</b>: {value}
</p>
);
const openCloseState = (value) => (value ? "open" : "closed");
const mapOpenCloseState = (value) =>
keyValueTemplate(value[0], openCloseState(value[1]));
const windowState = (value) => {
if (value[1] === 0 || value[1] > 100) {
return keyValueTemplate(value[0], `closed (${value[1]})`);
} else {
return keyValueTemplate(value[0], `${value[1]}% open`);
}
}
const DigitalTwin = (props) => {
const classes = useStyles();
const { battery, doors, location, trex_version, ip, updated, windows, misc_windows, sunroof, dbc_version, door_locks, vcu0x260, charging_metrics, max_range, vehicle_speed } = props;
return (
<div>
{!battery && !doors && !location && !windows && !vcu0x260 && !charging_metrics && (
<p>No vehicle data to display.</p>
)}
{(battery || max_range) && (
<div className={classes.popupSection}>
<h3>Battery</h3>
{keyValueTemplate("Percentage", appendUnits(battery?.percent || 0, "%"))}
{keyValueTemplate("Total Mileage", appendUnits(battery?.total_mileage_odometer, " km"))}
{keyValueTemplate("Voltage", appendUnits(battery?.battery_voltage, " V"))}
{keyValueTemplate("Max Range", appendUnits(max_range?.max_miles, " km"))}
</div>
)}
{(vcu0x260 || charging_metrics) && (
<div className={classes.popupSection}>
<h3>Charging</h3>
{keyValueTemplate("Charge Type", vcu0x260?.charge_type || UNKNOWN)}
{keyValueTemplate("Remaining Time", appendUnits(charging_metrics?.remaining_charging_time, " min"))}
</div>
)}
{doors && (
<div className={classes.popupSection}>
<h3>Doors</h3>
{Object.entries(doors).map(mapOpenCloseState)}
</div>
)}
{door_locks && (
<div className={classes.popupSection}>
<h3>Door Locks</h3>
{Object.entries(door_locks).map((value) => {
return keyValueTemplate(value[0], value[1] ? LOCKED : UNLOCKED);
})}
</div>
)}
{windows && (
<div className={classes.popupSection}>
<h3>Windows</h3>
{Object.entries(windows).map((value) => {
return windowState(value);
})}
</div>
)}
{misc_windows && (
<div className={classes.popupSection}>
<h3>Misc Windows</h3>
{Object.entries(misc_windows).map((value) => {
return windowState(value);
})}
</div>
)}
{sunroof && (
<div className={classes.popupSection}>
<h3>Sunroof</h3>
{Object.entries(sunroof).map((value) => {
return windowState(value);
})}
</div>
)}
{location && (
<div className={classes.popupSection}>
<h3>Location</h3>
{Object.entries(location).map((value) => {
if (ValidateLocationByParam(value[0], value[1]) === false) {
return keyValueTemplate(value[0], "Invalid")
}
if (value[0] === "altitude") {
return keyValueTemplate(value[0], appendUnits(value[1], " m"));
} else {
return keyValueTemplate(value[0], appendUnits(value[1], "°"));
}
})}
</div>
)}
{trex_version && (
<div className={classes.popupSection}>
{keyValueTemplate("Trex Version", trex_version)}
</div>
)}
{ip && (
<div className={classes.popupSection}>
{keyValueTemplate("Trex IP", ip)}
</div>
)}
{updated != null && (
<div className={classes.popupSection}>
{keyValueTemplate("Updated At", LocalDateTimeString(updated))}
</div>
)}
{dbc_version != null && (
<div className={classes.popupSection}>
{keyValueTemplate("DBC Version", dbc_version)}
</div>
)}
{vehicle_speed && (
<div className={classes.popupSection}>
{keyValueTemplate("Vehicle Speed", appendUnits(vehicle_speed?.speed, " km/h"))}
</div>
)}
</div>
);
};
export default DigitalTwin;