Merge branch 'airflow' into dev_environment
This commit is contained in:
commit
116ad33351
11 changed files with 240 additions and 123 deletions
2
package-lock.json
generated
2
package-lock.json
generated
|
|
@ -10911,7 +10911,7 @@
|
||||||
},
|
},
|
||||||
"node_modules/protobuf-ts": {
|
"node_modules/protobuf-ts": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#1facaa10a603c0cad59adad9a7ca2283f51adb62",
|
"resolved": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#615043c402800121752f0bbe2620f7760c972110",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"protobufjs": "^6.8.8"
|
"protobufjs": "^6.8.8"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,9 @@ export default function BinsList(props: Props) {
|
||||||
}}
|
}}
|
||||||
key={i}
|
key={i}
|
||||||
className={classes.gridListTile}
|
className={classes.gridListTile}
|
||||||
onClick={() => goToBin(i)}>
|
onClick={() => {
|
||||||
|
!duplicate && goToBin(i)
|
||||||
|
}}>
|
||||||
<BinCardV2
|
<BinCardV2
|
||||||
bin={b}
|
bin={b}
|
||||||
duplicateBin={duplicateBin}
|
duplicateBin={duplicateBin}
|
||||||
|
|
@ -136,7 +138,9 @@ export default function BinsList(props: Props) {
|
||||||
key={i}
|
key={i}
|
||||||
style={{ width: "184px" }}
|
style={{ width: "184px" }}
|
||||||
className={classes.gridListTile}
|
className={classes.gridListTile}
|
||||||
onClick={() => goToBin(i)}>
|
onClick={() => {
|
||||||
|
!duplicate && goToBin(i)
|
||||||
|
}}>
|
||||||
<BinCardV2
|
<BinCardV2
|
||||||
bin={b}
|
bin={b}
|
||||||
duplicateBin={duplicateBin}
|
duplicateBin={duplicateBin}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import { Bin } from "models";
|
||||||
import moment, { Moment } from "moment";
|
import moment, { Moment } from "moment";
|
||||||
import { pond, quack } from "protobuf-ts/pond";
|
import { pond, quack } from "protobuf-ts/pond";
|
||||||
import { useBinAPI, useGlobalState } from "providers";
|
import { useBinAPI, useGlobalState } from "providers";
|
||||||
import { useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { Legend } from "recharts";
|
import { Legend } from "recharts";
|
||||||
import { getGrainUnit } from "utils";
|
import { getGrainUnit } from "utils";
|
||||||
|
|
||||||
|
|
@ -31,24 +31,13 @@ export default function BinLevelOverTime(props: Props) {
|
||||||
const { bin, fertilizerBin, colour, startDate, endDate, customHeight } = props;
|
const { bin, fertilizerBin, colour, startDate, endDate, customHeight } = props;
|
||||||
const binAPI = useBinAPI();
|
const binAPI = useBinAPI();
|
||||||
const [{as}] = useGlobalState();
|
const [{as}] = useGlobalState();
|
||||||
const [showCable, setShowCable] = useState(false);
|
const [data, setData] = useState<BarData[]>([]);
|
||||||
const [manualData, setManualData] = useState<BarData[]>([]);
|
|
||||||
const [cableData, setCableData] = useState<BarData[]>([]);
|
|
||||||
const [modeAreas, setModeAreas] = useState<RefArea[]>([]);
|
const [modeAreas, setModeAreas] = useState<RefArea[]>([]);
|
||||||
// const defaultDateRange = GetDefaultDateRange();
|
|
||||||
// const [startDate, setStartDate] = useState<Moment>(defaultDateRange.start);
|
|
||||||
// const [endDate, setEndDate] = useState<Moment>(defaultDateRange.end);
|
|
||||||
const [dataLoading, setDataLoading] = useState(false);
|
const [dataLoading, setDataLoading] = useState(false);
|
||||||
const [cableDataLoading, setCableDataLoading] = useState(false);
|
|
||||||
const [capacity, setCapacity] = useState<number | undefined>();
|
const [capacity, setCapacity] = useState<number | undefined>();
|
||||||
|
|
||||||
// const updateDateRange = (newStartDate: any, newEndDate: any) => {
|
const [modeData, setModeData] = useState<BarData[]>([]);
|
||||||
// let range = GetDefaultDateRange();
|
const [histDataLoading, setHistDataLoading] = useState(false);
|
||||||
// range.start = newStartDate;
|
|
||||||
// range.end = newEndDate;
|
|
||||||
// setStartDate(newStartDate);
|
|
||||||
// setEndDate(newEndDate);
|
|
||||||
// };
|
|
||||||
|
|
||||||
const getFill = (mode: pond.BinMode) => {
|
const getFill = (mode: pond.BinMode) => {
|
||||||
let fill = "";
|
let fill = "";
|
||||||
|
|
@ -72,8 +61,8 @@ export default function BinLevelOverTime(props: Props) {
|
||||||
return fill;
|
return fill;
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
//loads the data from the bin history table
|
||||||
if (dataLoading || bin.key() === "") return;
|
const loadHistoryData = useCallback(() => {
|
||||||
setDataLoading(true);
|
setDataLoading(true);
|
||||||
let cap = bin.settings.specs?.bushelCapacity;
|
let cap = bin.settings.specs?.bushelCapacity;
|
||||||
if (fertilizerBin && cap) {
|
if (fertilizerBin && cap) {
|
||||||
|
|
@ -146,48 +135,125 @@ export default function BinLevelOverTime(props: Props) {
|
||||||
fill: getFill(bin.settings.mode)
|
fill: getFill(bin.settings.mode)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
setManualData(data);
|
setData(data);
|
||||||
setModeAreas(modeAreas);
|
setModeAreas(modeAreas);
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setDataLoading(false);
|
setDataLoading(false);
|
||||||
});
|
});
|
||||||
}, [binAPI, bin, startDate, endDate, fertilizerBin]); // eslint-disable-line react-hooks/exhaustive-deps
|
},[startDate, endDate, bin, fertilizerBin])
|
||||||
|
|
||||||
useEffect(() => {
|
//loads the data from the measuremnts table as a unit measurement
|
||||||
if (cableDataLoading || bin.key() === "") return;
|
const loadMeasurementData = useCallback(() => {
|
||||||
setCableDataLoading(true);
|
setDataLoading(true);
|
||||||
|
let cap = bin.settings.specs?.bushelCapacity;
|
||||||
|
if (fertilizerBin && cap) {
|
||||||
|
cap = cap * 35.239;
|
||||||
|
}
|
||||||
|
if (getGrainUnit() === pond.GrainUnit.GRAIN_UNIT_WEIGHT && cap) {
|
||||||
|
cap = cap / bin.bushelsPerTonne();
|
||||||
|
}
|
||||||
|
setCapacity(cap);
|
||||||
|
let autoBarData: BarData[] = [];
|
||||||
|
|
||||||
|
//load the measurment data to build the bushel bars
|
||||||
binAPI
|
binAPI
|
||||||
.listBinMeasurements(bin.key(), startDate, endDate, 500, 0, "asc", undefined, undefined, undefined, undefined, as)
|
.listBinMeasurements(bin.key(), startDate, endDate, 500, 0, "asc")
|
||||||
.then(resp => {
|
.then(resp => {
|
||||||
|
let lastBushels = -1;
|
||||||
|
|
||||||
resp.data.measurements.forEach(objMeasurement => {
|
resp.data.measurements.forEach(objMeasurement => {
|
||||||
//set the bushel cable measurements
|
//set the bushel cable measurements
|
||||||
let m = pond.UnitMeasurementsForObject.fromObject(objMeasurement);
|
let m = pond.UnitMeasurementsForObject.fromObject(objMeasurement);
|
||||||
if (m.measurementType === quack.MeasurementType.MEASUREMENT_TYPE_BUSHEL_CABLE) {
|
|
||||||
let cableBarData: BarData[] = [];
|
|
||||||
let lastBushels = -1;
|
|
||||||
|
|
||||||
//val will be an array of only a single number since this is not a measurement that involves nodes
|
//val will be an array of only a single number since this is not a measurement that involves nodes
|
||||||
m.values.forEach((val, i) => {
|
m.values.forEach((val, i) => {
|
||||||
if (val.values[0] && m.timestamps[i]) {
|
if (val.values[0] && m.timestamps[i]) {
|
||||||
if (lastBushels !== val.values[0]) {
|
if (lastBushels !== val.values[0]) {
|
||||||
cableBarData.push({
|
autoBarData.push({
|
||||||
value: val.values[0],
|
value: val.values[0],
|
||||||
timestamp: moment(m.timestamps[i]).valueOf()
|
timestamp: moment(m.timestamps[i]).valueOf(),
|
||||||
});
|
});
|
||||||
lastBushels = val.values[0];
|
lastBushels = val.values[0];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
setCableData(cableBarData);
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
if (autoBarData.length === 0) {
|
||||||
|
let bushels = bin.settings.inventory?.grainBushels ?? 0;
|
||||||
|
let currentTime = moment().valueOf();
|
||||||
|
autoBarData.push({
|
||||||
|
value: fertilizerBin
|
||||||
|
? Math.round(bushels * 35.239)
|
||||||
|
: getGrainUnit() === pond.GrainUnit.GRAIN_UNIT_WEIGHT
|
||||||
|
? Math.round((bushels / bin.bushelsPerTonne()) * 100) / 100
|
||||||
|
: bushels,
|
||||||
|
timestamp: currentTime
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setData(autoBarData);
|
||||||
})
|
})
|
||||||
.catch(err => {})
|
.catch(err => {})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setCableDataLoading(false);
|
setDataLoading(false);
|
||||||
});
|
});
|
||||||
}, [binAPI, bin, startDate, endDate, fertilizerBin, as]); // eslint-disable-line react-hooks/exhaustive-deps
|
},[startDate, endDate, bin, fertilizerBin])
|
||||||
|
|
||||||
|
const modeDataFromHistory = useCallback(()=>{
|
||||||
|
if (histDataLoading) return;
|
||||||
|
setHistDataLoading(true)
|
||||||
|
binAPI
|
||||||
|
.listHistoryBetween(bin.key(), 500, startDate.toISOString(), endDate.toISOString())
|
||||||
|
.then(resp => {
|
||||||
|
//loop through the history finding all the times the bin mode changed
|
||||||
|
let currentMode: pond.BinMode | undefined = undefined
|
||||||
|
let modeData: BarData[] = []
|
||||||
|
resp.data.history.forEach(hist => {
|
||||||
|
let histBin = Bin.create()
|
||||||
|
histBin.settings = hist.settings ?? pond.BinSettings.create()
|
||||||
|
if(hist.settings && currentMode !== hist.settings.mode){
|
||||||
|
currentMode = hist.settings.mode
|
||||||
|
modeData.push({
|
||||||
|
timestamp: moment(hist.timestamp).valueOf(),
|
||||||
|
value: 1,
|
||||||
|
fill: getFill(currentMode)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
setModeData(modeData)
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
|
||||||
|
})
|
||||||
|
.finally(()=>{
|
||||||
|
setHistDataLoading(false)
|
||||||
|
})
|
||||||
|
},[bin, startDate, endDate])
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
//dont call a load function if loading is already in progress
|
||||||
|
if (dataLoading || bin.key() === "") return;
|
||||||
|
//check what is controlling the bin inventory
|
||||||
|
let control = bin.inventoryControl()
|
||||||
|
//for automatic lidar and cables get the data from measurements as an object measurement
|
||||||
|
if(control === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_AUTOMATIC_LIDAR ||
|
||||||
|
control === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_AUTOMATIC
|
||||||
|
){
|
||||||
|
//load the measurement data for the bar graph
|
||||||
|
loadMeasurementData()
|
||||||
|
//load the data for the storage mode changes
|
||||||
|
modeDataFromHistory()
|
||||||
|
|
||||||
|
//for manual and hybrid (lidar or in the future, cables) get the data from bin_history
|
||||||
|
}else if(control === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_MANUAL ||
|
||||||
|
control === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_HYBRID_LIDAR ||
|
||||||
|
control === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_UNKNOWN
|
||||||
|
){
|
||||||
|
loadHistoryData()
|
||||||
|
}
|
||||||
|
|
||||||
|
},[bin, loadMeasurementData, loadHistoryData])
|
||||||
|
|
||||||
const legend = () => {
|
const legend = () => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -203,15 +269,16 @@ export default function BinLevelOverTime(props: Props) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const manualChart = () => {
|
const inventoryChart = () => {
|
||||||
return (
|
return (
|
||||||
<BarGraph
|
<BarGraph
|
||||||
customHeight={customHeight}
|
customHeight={customHeight}
|
||||||
data={manualData}
|
data={data}
|
||||||
refAreas={modeAreas}
|
refAreas={modeAreas}
|
||||||
barColour={colour}
|
barColour={colour}
|
||||||
yMax={capacity}
|
yMax={capacity}
|
||||||
graphLegend={legend()}
|
yMin={0}
|
||||||
|
graphLegend={modeAreas.length > 0 ? legend() : undefined}
|
||||||
labelColour="white"
|
labelColour="white"
|
||||||
labels
|
labels
|
||||||
useGradient
|
useGradient
|
||||||
|
|
@ -219,62 +286,28 @@ export default function BinLevelOverTime(props: Props) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const cableChart = () => {
|
const autoBinModeChart = () => {
|
||||||
if (cableData.length === 0) {
|
|
||||||
return (
|
|
||||||
<Box height={customHeight} paddingTop={"25%"}>
|
|
||||||
<Typography style={{ textAlign: "center", fontSize: 25, fontWeight: 650 }}>
|
|
||||||
No cable estimates for selected time frame
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<BarGraph
|
<BarGraph
|
||||||
customHeight={customHeight}
|
data={modeData}
|
||||||
data={cableData}
|
customHeight={100}
|
||||||
//refAreas={modeAreas}
|
hideYAxis
|
||||||
barColour={colour}
|
|
||||||
yMax={capacity}
|
|
||||||
yMin={0}
|
|
||||||
graphLegend={legend()}
|
graphLegend={legend()}
|
||||||
labelColour="white"
|
yMax={1}
|
||||||
labels
|
yMin={0}
|
||||||
useGradient
|
|
||||||
/>
|
/>
|
||||||
);
|
)
|
||||||
};
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card raised style={{ padding: 5 }}>
|
<Card raised style={{ padding: 5 }}>
|
||||||
<Grid
|
<Typography style={{ fontSize: 25, fontWeight: 650, marginLeft: 20 }}>
|
||||||
container
|
Grain Levels Over Time
|
||||||
direction="row"
|
</Typography>
|
||||||
alignContent="center"
|
{dataLoading ? <CircularProgress /> : inventoryChart()}
|
||||||
alignItems="center"
|
{/* when using auto will need to make a new chart just for the bin modes since the auto inventory comes from another place */}
|
||||||
justifyContent="space-between">
|
{(bin.inventoryControl() === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_AUTOMATIC_LIDAR ||
|
||||||
<Grid>
|
bin.inventoryControl() === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_AUTOMATIC) && autoBinModeChart()}
|
||||||
<Typography style={{ fontSize: 25, fontWeight: 650, marginLeft: 20 }}>
|
|
||||||
Grain Levels Over Time
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid>
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Switch
|
|
||||||
checked={showCable}
|
|
||||||
onChange={(_, checked) => {
|
|
||||||
setShowCable(checked);
|
|
||||||
}}
|
|
||||||
color="primary"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="Cable Estimates"
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{dataLoading ? <CircularProgress /> : showCable ? cableChart() : manualChart()}
|
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import {
|
||||||
export interface BarData {
|
export interface BarData {
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
value: number;
|
value: number;
|
||||||
|
fill?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RefArea {
|
export interface RefArea {
|
||||||
|
|
@ -36,8 +37,9 @@ export interface AxisLabel {
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
data: BarData[];
|
data: BarData[];
|
||||||
barColour: string;
|
barColour?: string;
|
||||||
refAreas?: RefArea[];
|
refAreas?: RefArea[];
|
||||||
|
hideYAxis?: boolean;
|
||||||
yMin?: number;
|
yMin?: number;
|
||||||
yMax?: number;
|
yMax?: number;
|
||||||
graphLegend?: JSX.Element;
|
graphLegend?: JSX.Element;
|
||||||
|
|
@ -60,6 +62,7 @@ export default function BarGraph(props: Props) {
|
||||||
data,
|
data,
|
||||||
barColour,
|
barColour,
|
||||||
refAreas,
|
refAreas,
|
||||||
|
hideYAxis,
|
||||||
yMin,
|
yMin,
|
||||||
yMax,
|
yMax,
|
||||||
graphLegend,
|
graphLegend,
|
||||||
|
|
@ -103,6 +106,7 @@ export default function BarGraph(props: Props) {
|
||||||
{graphLegend}
|
{graphLegend}
|
||||||
<YAxis
|
<YAxis
|
||||||
domain={[yMin ?? "dataMin", yMax ?? "auto"]}
|
domain={[yMin ?? "dataMin", yMax ?? "auto"]}
|
||||||
|
hide={hideYAxis}
|
||||||
interval="preserveStartEnd"
|
interval="preserveStartEnd"
|
||||||
scale={"linear"}
|
scale={"linear"}
|
||||||
label={yLabel}
|
label={yLabel}
|
||||||
|
|
|
||||||
|
|
@ -475,6 +475,37 @@ export const GrainExtensions: Map<pond.Grain, GrainExtension> = new Map([
|
||||||
weightConversionKg: 27.2158214642112,
|
weightConversionKg: 27.2158214642112,
|
||||||
bushelsPerTonne: 36.744
|
bushelsPerTonne: 36.744
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
pond.Grain.GRAIN_DRY_BEANS_RED,
|
||||||
|
{
|
||||||
|
name: "Dry Beans Red",
|
||||||
|
group: "Dry Beans",
|
||||||
|
equation: Equation.halsey,
|
||||||
|
a: 4.2669,
|
||||||
|
b: -0.013382,
|
||||||
|
c: 1.6933,
|
||||||
|
setTempC: defaultSetTemp,
|
||||||
|
targetMC: 15.0,
|
||||||
|
colour: "red",
|
||||||
|
weightConversionKg: 27.2155,
|
||||||
|
bushelsPerTonne: 36.744
|
||||||
|
}
|
||||||
|
],[
|
||||||
|
pond.Grain.GRAIN_DRY_BEANS_BLACK,
|
||||||
|
{
|
||||||
|
name: "Dry Beans Black",
|
||||||
|
group: "Dry Beans",
|
||||||
|
equation: Equation.halsey,
|
||||||
|
a: 5.2003,
|
||||||
|
b: -0.022685,
|
||||||
|
c: 1.9656,
|
||||||
|
setTempC: defaultSetTemp,
|
||||||
|
targetMC: 15.0,
|
||||||
|
colour: "grey",
|
||||||
|
weightConversionKg: 27.2155,
|
||||||
|
bushelsPerTonne: 36.744
|
||||||
|
}
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,17 +36,17 @@ const featureVersions: Map<string, FeatureVersionByPlatform> = new Map([
|
||||||
],[
|
],[
|
||||||
"detectI2C",
|
"detectI2C",
|
||||||
{
|
{
|
||||||
photon: "NA",
|
photon: "N/A",
|
||||||
electron: "NA",
|
electron: "N/A",
|
||||||
v2Wifi: "2.1.6",
|
v2Wifi: "N/A",
|
||||||
v2Cell: "2.1.6",
|
v2Cell: "N/A",
|
||||||
v2WifiS3: "2.1.6",
|
v2WifiS3: "N/A",
|
||||||
v2CellS3: "2.1.6",
|
v2CellS3: "N/A",
|
||||||
v2CellBlack: "2.1.6",
|
v2CellBlack: "N/A",
|
||||||
v2CellGreen: "2.1.6",
|
v2CellGreen: "N/A",
|
||||||
v2WifiBlue: "2.1.6",
|
v2WifiBlue: "N/A",
|
||||||
v2CellBlue: "2.1.6",
|
v2CellBlue: "N/A",
|
||||||
v2EthBlue: "2.1.6"
|
v2EthBlue: "N/A"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
|
|
@ -256,5 +256,15 @@ function unitConversion(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (type === quack.MeasurementType.MEASUREMENT_TYPE_SPEED) {
|
||||||
|
if (user.settings.distanceUnit === pond.DistanceUnit.DISTANCE_UNIT_FEET) {
|
||||||
|
newVals.forEach((val, i) => {
|
||||||
|
val.values.forEach((v, j) => {
|
||||||
|
//convert m/s to ft/m by multiplying by 196.9
|
||||||
|
newVals[i].values[j] = v * 196.9
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
return newVals;
|
return newVals;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -544,7 +544,7 @@ export default function Bins(props: Props) {
|
||||||
|
|
||||||
const duplicateBin = (bin: Bin) => {
|
const duplicateBin = (bin: Bin) => {
|
||||||
binAPI.addBin(bin.settings, as).then(() => {
|
binAPI.addBin(bin.settings, as).then(() => {
|
||||||
loadBins();
|
loadMoreBins(contentFilter);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ export interface ComponentTypeExtension {
|
||||||
interactionResultTypes: Array<quack.InteractionResultType>;
|
interactionResultTypes: Array<quack.InteractionResultType>;
|
||||||
states: Array<string>;
|
states: Array<string>;
|
||||||
measurements: Array<ComponentMeasurement>;
|
measurements: Array<ComponentMeasurement>;
|
||||||
measurementSummary: Function; //Deprecated: this summary used the old measurement structure
|
measurementSummary?: Function; //Deprecated: this summary used the old measurement structure
|
||||||
unitMeasurementSummary: (
|
unitMeasurementSummary: (
|
||||||
measurements: convertedUnitMeasurement,
|
measurements: convertedUnitMeasurement,
|
||||||
excludedNodes?: number[]
|
excludedNodes?: number[]
|
||||||
|
|
@ -382,7 +382,8 @@ export async function getMeasurementSummary(
|
||||||
measurement: quack.IMeasurement,
|
measurement: quack.IMeasurement,
|
||||||
filters: GraphFilters
|
filters: GraphFilters
|
||||||
): Promise<Array<Summary>> {
|
): Promise<Array<Summary>> {
|
||||||
return extension(type, subtype).measurementSummary(measurement, filters);
|
let sumFunc = extension(type, subtype).measurementSummary
|
||||||
|
return sumFunc ? sumFunc(measurement, filters) : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const validNodes = (nodeVals: number[], filters?: GraphFilters) => {
|
const validNodes = (nodeVals: number[], filters?: GraphFilters) => {
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
import {
|
import {
|
||||||
ComponentTypeExtension,
|
ComponentTypeExtension,
|
||||||
Summary,
|
Summary,
|
||||||
simpleMeasurements,
|
// simpleMeasurements,
|
||||||
simpleSummaries,
|
// simpleSummaries,
|
||||||
unitMeasurementSummaries,
|
unitMeasurementSummaries,
|
||||||
AreaChartData,
|
AreaChartData,
|
||||||
GraphFilters,
|
GraphFilters,
|
||||||
simpleAreaChartData,
|
simpleAreaChartData,
|
||||||
LineChartData,
|
LineChartData,
|
||||||
simpleLineChartData
|
simpleLineChartData,
|
||||||
|
ComponentMeasurement
|
||||||
} from "pbHelpers/ComponentType";
|
} from "pbHelpers/ComponentType";
|
||||||
import PressureDarkIcon from "assets/components/pressureDark.png";
|
import PressureDarkIcon from "assets/components/pressureDark.png";
|
||||||
import PressureLightIcon from "assets/components/pressureLight.png";
|
import PressureLightIcon from "assets/components/pressureLight.png";
|
||||||
|
|
@ -18,14 +19,46 @@ import { convertedUnitMeasurement } from "models/UnitMeasurement";
|
||||||
import { pond } from "protobuf-ts/pond";
|
import { pond } from "protobuf-ts/pond";
|
||||||
|
|
||||||
export function Airflow(subtype: number = 0): ComponentTypeExtension {
|
export function Airflow(subtype: number = 0): ComponentTypeExtension {
|
||||||
let airflow = describeMeasurement(
|
let cfm = describeMeasurement(
|
||||||
quack.MeasurementType.MEASUREMENT_TYPE_CFM,
|
quack.MeasurementType.MEASUREMENT_TYPE_CFM,
|
||||||
quack.ComponentType.COMPONENT_TYPE_AIRFLOW,
|
quack.ComponentType.COMPONENT_TYPE_AIRFLOW,
|
||||||
subtype
|
subtype
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let velocity = describeMeasurement(
|
||||||
|
quack.MeasurementType.MEASUREMENT_TYPE_CFM,
|
||||||
|
quack.ComponentType.COMPONENT_TYPE_AIRFLOW,
|
||||||
|
subtype
|
||||||
|
);
|
||||||
|
|
||||||
|
let measurementTypes = [
|
||||||
|
{
|
||||||
|
measurementType: quack.MeasurementType.MEASUREMENT_TYPE_PPM,
|
||||||
|
label: cfm.label(),
|
||||||
|
colour: cfm.colour(),
|
||||||
|
graphType: cfm.graph()
|
||||||
|
} as ComponentMeasurement,
|
||||||
|
{
|
||||||
|
measurementType: quack.MeasurementType.MEASUREMENT_TYPE_VOLTAGE,
|
||||||
|
label: velocity.label(),
|
||||||
|
colour: velocity.colour(),
|
||||||
|
graphType: velocity.graph()
|
||||||
|
} as ComponentMeasurement
|
||||||
|
];
|
||||||
return {
|
return {
|
||||||
type: quack.ComponentType.COMPONENT_TYPE_AIRFLOW,
|
type: quack.ComponentType.COMPONENT_TYPE_AIRFLOW,
|
||||||
subtypes: [],
|
subtypes: [
|
||||||
|
{
|
||||||
|
key: quack.AirFlowSubtype.AIR_FLOW_SUBTYPE_PROSENSE,
|
||||||
|
value: "AIR_FLOW_SUBTYPE_PROSENSE",
|
||||||
|
friendlyName: "Prosense"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: quack.AirFlowSubtype.AIR_FLOW_SUBTYPE_ULTRASONIC,
|
||||||
|
value: "AIR_FLOW_SUBTYPE_ULTRASONIC",
|
||||||
|
friendlyName: "Ultrasonic"
|
||||||
|
},
|
||||||
|
],
|
||||||
friendlyName: "Airflow",
|
friendlyName: "Airflow",
|
||||||
description: "Measure the flow of air though a specified area",
|
description: "Measure the flow of air though a specified area",
|
||||||
isController: false,
|
isController: false,
|
||||||
|
|
@ -36,10 +69,10 @@ export function Airflow(subtype: number = 0): ComponentTypeExtension {
|
||||||
addressTypes: [quack.AddressType.ADDRESS_TYPE_I2C],
|
addressTypes: [quack.AddressType.ADDRESS_TYPE_I2C],
|
||||||
interactionResultTypes: [],
|
interactionResultTypes: [],
|
||||||
states: [],
|
states: [],
|
||||||
measurements: simpleMeasurements(airflow),
|
measurements: measurementTypes,
|
||||||
measurementSummary: async function(measurement: quack.Measurement): Promise<Array<Summary>> {
|
// measurementSummary: async function(measurement: quack.Measurement): Promise<Array<Summary>> {
|
||||||
return simpleSummaries(measurement, airflow);
|
// return simpleSummaries(measurement, airflow);
|
||||||
},
|
// },
|
||||||
unitMeasurementSummary: (
|
unitMeasurementSummary: (
|
||||||
measurements: convertedUnitMeasurement,
|
measurements: convertedUnitMeasurement,
|
||||||
excludedNodes?: number[]
|
excludedNodes?: number[]
|
||||||
|
|
|
||||||
|
|
@ -450,8 +450,9 @@ export class MeasurementDescriber {
|
||||||
this.details.max = 100000;
|
this.details.max = 100000;
|
||||||
break;
|
break;
|
||||||
case quack.MeasurementType.MEASUREMENT_TYPE_SPEED:
|
case quack.MeasurementType.MEASUREMENT_TYPE_SPEED:
|
||||||
|
let speedUnit = getDistanceUnit()
|
||||||
this.details.label = "Speed";
|
this.details.label = "Speed";
|
||||||
this.details.unit = "km/h";
|
this.details.unit = speedUnit === pond.DistanceUnit.DISTANCE_UNIT_METERS ? "m/s" : "ft/m";
|
||||||
this.details.colour = green["500"];
|
this.details.colour = green["500"];
|
||||||
this.details.path = "edgeTriggered.rises";
|
this.details.path = "edgeTriggered.rises";
|
||||||
this.details.max = 500;
|
this.details.max = 500;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue