284 lines
9.6 KiB
TypeScript
284 lines
9.6 KiB
TypeScript
import {
|
|
Box,
|
|
Grid,
|
|
Typography,
|
|
Theme
|
|
} from "@mui/material";
|
|
import { makeStyles } from "@mui/styles";
|
|
import { Component } from "models";
|
|
import moment from "moment";
|
|
import { getMeasurementSummary, Summary } from "pbHelpers/ComponentType";
|
|
import { pond } from "protobuf-ts/pond";
|
|
import { quack } from "protobuf-ts/quack";
|
|
import React, { useEffect, useState } from "react";
|
|
import { or } from "utils/types";
|
|
|
|
interface Props {
|
|
component: Component;
|
|
reading?: pond.Measurement | null;
|
|
tableCell?: boolean;
|
|
centered?: boolean;
|
|
dense?: boolean;
|
|
omitTime?: boolean;
|
|
}
|
|
|
|
const useStyles = makeStyles((theme: Theme) => {
|
|
return ({
|
|
"@keyframes ripple": {
|
|
from: {
|
|
transform: "scale(.8)",
|
|
opacity: 1
|
|
},
|
|
to: {
|
|
transform: "scale(1.4)",
|
|
opacity: 0
|
|
}
|
|
},
|
|
on: {
|
|
boxShadow: `0 0 0 2px ${theme.palette.background.paper}`,
|
|
animationName: "$ripple",
|
|
animationDuration: "1.2s",
|
|
animationTimingFunction: "ease-in-out",
|
|
animationIterationCount: "infinite"
|
|
},
|
|
off: {
|
|
backgroundColor: "transparent"
|
|
}
|
|
})
|
|
});
|
|
|
|
//TODO: deprecated as unit measurements use a new measurement summary file
|
|
export default function MeasurementSummary(props: Props) {
|
|
const { component, reading, tableCell, centered, dense } = props;
|
|
const [summaries, setSummaries] = useState<Summary[]>([]);
|
|
const [timestamp, setTimestamp] = useState("");
|
|
const classes = useStyles();
|
|
|
|
const grainCableFilters = () => {
|
|
const { component } = props;
|
|
return {
|
|
grainType: component.settings.grainType,
|
|
grainFilledTo: component.settings.grainFilledTo
|
|
};
|
|
};
|
|
|
|
useEffect(() => {
|
|
async function getSummary() {
|
|
if (
|
|
reading &&
|
|
reading.measurement &&
|
|
reading.measurement.id &&
|
|
reading.measurement.id.type !== null &&
|
|
reading.measurement.id.type !== undefined
|
|
) {
|
|
let id = quack.ComponentID.fromObject(reading.measurement.id);
|
|
let filters = { isTableCellMode: tableCell };
|
|
if (id.type === quack.ComponentType.COMPONENT_TYPE_GRAIN_CABLE) {
|
|
filters = { ...filters, ...grainCableFilters() };
|
|
}
|
|
await getMeasurementSummary(
|
|
id.type,
|
|
or(component.settings.subtype, 0),
|
|
quack.Measurement.create(reading.measurement ? reading.measurement : undefined),
|
|
filters
|
|
).then(summaries => {
|
|
setSummaries(summaries);
|
|
});
|
|
setTimestamp(reading.timestamp);
|
|
}
|
|
}
|
|
|
|
getSummary();
|
|
}, [component, reading]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
|
|
const noSummary = () => {
|
|
return (
|
|
<Typography variant="body2" color="textPrimary">
|
|
No Data
|
|
</Typography>
|
|
);
|
|
};
|
|
|
|
const getSummaryComponent = (summaries: Summary[]): any => {
|
|
if (summaries.length < 1) {
|
|
return noSummary();
|
|
}
|
|
|
|
return (
|
|
<Grid container>
|
|
<Grid item xs={12}>
|
|
<Typography variant="body2" color="textPrimary">
|
|
{summaries.map((summary: Summary, index: number) => {
|
|
let sumVal = summary.value;
|
|
if (component.settings.type === quack.ComponentType.COMPONENT_TYPE_EDGE_TRIGGERED) {
|
|
if (
|
|
component.settings.subtype ===
|
|
quack.EdgeTriggeredSubtype.EDGE_TRIGGERED_SUBTYPE_WIND_SPEED &&
|
|
!isNaN(Number(sumVal))
|
|
) {
|
|
//make sure sumVal is a number
|
|
sumVal = Number(sumVal);
|
|
|
|
//get the period of time that all the measurements are in and convert it to seconds
|
|
let measurementInterval = Number(component.settings.measurementPeriodMs) / 1000;
|
|
//formula to determine the km/h
|
|
sumVal = (sumVal / measurementInterval) * 2.4;
|
|
//round to 2 decimal places and add the units
|
|
sumVal = Math.round(sumVal * 100) / 100 + "km/h";
|
|
}
|
|
}
|
|
return (
|
|
<span key={index}>
|
|
{summary.label + ": "} <span style={{ color: summary.colour }}>{sumVal}</span>{" "}
|
|
<br />
|
|
</span>
|
|
);
|
|
})}
|
|
</Typography>
|
|
</Grid>
|
|
{!props.omitTime && (
|
|
<Grid item xs={12}>
|
|
<Typography color="textSecondary" variant="caption">
|
|
{moment(timestamp).fromNow()}
|
|
</Typography>
|
|
</Grid>
|
|
)}
|
|
</Grid>
|
|
);
|
|
};
|
|
|
|
const getTableCellSummaryComponent = (summaries: Summary[]): any => {
|
|
if (summaries.length < 1) {
|
|
return <span>Unknown</span>;
|
|
}
|
|
const blacklist: Array<any> = [];
|
|
const filteredSummaries = summaries.filter((item: any) => !blacklist.includes(item.label));
|
|
return (
|
|
<Grid container direction="row" justifyContent={centered ? "center" : "flex-start"} spacing={1}>
|
|
{filteredSummaries.map((summary: Summary, i: number) => {
|
|
let sumVal = summary.value;
|
|
if (component.settings.type === quack.ComponentType.COMPONENT_TYPE_EDGE_TRIGGERED) {
|
|
if (
|
|
component.settings.subtype ===
|
|
quack.EdgeTriggeredSubtype.EDGE_TRIGGERED_SUBTYPE_WIND_SPEED &&
|
|
!isNaN(Number(sumVal))
|
|
) {
|
|
//make sure sumVal is a number
|
|
sumVal = Number(sumVal);
|
|
//get the period of time that all the measurements are in and convert it to seconds
|
|
let measurementInterval = Number(component.settings.measurementPeriodMs) / 1000;
|
|
//formula to determine the km/h
|
|
sumVal = (sumVal / measurementInterval) * 2.4;
|
|
//round to 2 decimal places and add the units
|
|
sumVal = Math.round(sumVal * 100) / 100 + "km/h";
|
|
}
|
|
}
|
|
return (
|
|
<Grid item key={summary.label}>
|
|
{summary.label + ": "}
|
|
<span style={{ color: summary.colour }}>{sumVal}</span>
|
|
{i + 1 !== filteredSummaries.length && ","}
|
|
</Grid>
|
|
);
|
|
})}
|
|
</Grid>
|
|
);
|
|
};
|
|
|
|
const getDenseSummary = (summaries: Summary[]): any => {
|
|
if (summaries.length < 1) {
|
|
return null;
|
|
}
|
|
|
|
const blacklist: Array<any> = ["Temperature (Air)", "Moisture (Air)"];
|
|
const filteredSummaries = summaries.filter(
|
|
(item: any) =>
|
|
!blacklist.includes(item.label) && (item.label !== "Grain Type" || item.value !== "None")
|
|
);
|
|
|
|
let overlays: any = [];
|
|
|
|
return (
|
|
<Box width={"100%"} component="div">
|
|
{filteredSummaries.map((summary: Summary, i: number) => {
|
|
let sumVal = summary.value;
|
|
if (component.settings.type === quack.ComponentType.COMPONENT_TYPE_EDGE_TRIGGERED) {
|
|
if (
|
|
component.settings.subtype ===
|
|
quack.EdgeTriggeredSubtype.EDGE_TRIGGERED_SUBTYPE_WIND_SPEED &&
|
|
!isNaN(Number(sumVal))
|
|
) {
|
|
//make sure sumVal is a number
|
|
sumVal = Number(sumVal);
|
|
//get the period of time that all the measurements are in and convert it to seconds
|
|
let measurementInterval = Number(component.settings.measurementPeriodMs) / 1000;
|
|
//formula to determine the km/h
|
|
sumVal = (sumVal / measurementInterval) * 2.4;
|
|
//round to 2 decimal places and add the units
|
|
sumVal = Math.round(sumVal * 100) / 100 + "km/h";
|
|
}
|
|
}
|
|
if (component.settings.hasOverlays) {
|
|
let overlay: pond.ComponentOverlays = pond.ComponentOverlays.create();
|
|
let found = false;
|
|
component.settings.overlays.forEach(ov => {
|
|
if (ov.measurementType === summary.type) {
|
|
//check if the sum value is within the overlay min-max
|
|
let numVal = parseFloat(sumVal);
|
|
if (numVal >= ov.min && numVal <= ov.max) {
|
|
overlay = ov;
|
|
found = true;
|
|
}
|
|
}
|
|
});
|
|
if (found) {
|
|
overlays.push(
|
|
<React.Fragment key={"overlay" + i}>
|
|
<Grid item>
|
|
<Box
|
|
width="20px"
|
|
height="20px"
|
|
borderRadius="50%"
|
|
className={classes.on}
|
|
style={{ background: overlay.colour }}
|
|
/>
|
|
</Grid>
|
|
<Grid item>
|
|
<Typography
|
|
variant="caption"
|
|
component="span"
|
|
style={{ marginLeft: 5, marginRight: 5 }}>
|
|
{overlay.message}
|
|
</Typography>
|
|
</Grid>
|
|
</React.Fragment>
|
|
);
|
|
}
|
|
}
|
|
return (
|
|
<Typography key={summary.label} variant="caption" component="span">
|
|
<span style={{ color: summary.colour }}>{sumVal}</span>
|
|
{i + 1 !== filteredSummaries.length && ", "}
|
|
</Typography>
|
|
);
|
|
})}
|
|
{!props.omitTime && (
|
|
<Box component="span">
|
|
{" - "}
|
|
<Typography color="textSecondary" variant="caption">
|
|
{moment(timestamp).fromNow()}
|
|
</Typography>
|
|
</Box>
|
|
)}
|
|
<Grid container direction="row">
|
|
{overlays}
|
|
</Grid>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
if (summaries.length <= 0) return noSummary();
|
|
if (dense) return getDenseSummary(summaries);
|
|
if (tableCell) return getTableCellSummaryComponent(summaries);
|
|
return getSummaryComponent(summaries);
|
|
}
|