added function to the bin model to get the bushels from either the settings or the status based on the inventory control and replaced the instances in the bin card and visualizer where it was getting it from the settings with the function

This commit is contained in:
csawatzky 2025-04-30 17:01:55 -06:00
parent acbd49b907
commit b197f34f33
5 changed files with 132 additions and 109 deletions

View file

@ -419,16 +419,12 @@ export default function BinCard(props: Props) {
Math.round(current * 35.239).toLocaleString() +
"/" +
Math.round(capacity * 35.239).toLocaleString() +
(lidarBushels ? "(" + Math.round(lidarBushels * 35.239).toLocaleString() + " est)" : "") +
" L"
);
}
if (getGrainUnit() === pond.GrainUnit.GRAIN_UNIT_WEIGHT && bin.bushelsPerTonne() > 1) {
return (
bin.grainTonnes().toLocaleString() +
(lidarBushels
? "(" + Math.round(lidarBushels / bin.bushelsPerTonne()).toLocaleString() + " est)"
: "") +
" mT " +
bin.fillPercent() +
"%"
@ -438,7 +434,6 @@ export default function BinCard(props: Props) {
current.toLocaleString() +
"/" +
capacity.toLocaleString() +
(lidarBushels ? "(" + lidarBushels.toLocaleString() + " est)" : "") +
" bu"
);
};
@ -469,10 +464,10 @@ export default function BinCard(props: Props) {
const info = () => {
const inv = bin.settings.inventory;
let bushelAmount = inv?.grainBushels;
let bushelAmount = bin.bushels();
let bushelCapacity = bin.settings.specs?.bushelCapacity;
const empty =
!inv || inv.empty || !bushelCapacity || bushelCapacity <= 0 || inv.grainBushels <= 0;
!inv || inv.empty || !bushelCapacity || bushelCapacity <= 0 || bushelAmount <= 0;
return (
<Box width={1} marginTop={0}>
<Typography align="center" color="textSecondary" noWrap style={{ fontSize: "0.65rem" }}>

View file

@ -362,95 +362,95 @@ export default function BinVisualizer(props: Props) {
let trendCables = cables;
if (bin.key() !== "" && !loadingTrend) {
setLoadingTrend(true);
// binAPI
// .getBinsTrendData([bin.key()], 7)
// .then(resp => {
// let binTrend = resp.data.trendData[bin.key()];
// //the variables to use to build the average conditions
// let temps: number[] = [];
// let humids: number[] = [];
// let emcs: number[] = [];
// let tempTrends: number[] = [];
// let humidTrends: number[] = [];
// let emcTrends: number[] = [];
binAPI
.getBinsTrendData([bin.key()], 7)
.then(resp => {
let binTrend = resp.data.trendData[bin.key()];
//the variables to use to build the average conditions
let temps: number[] = [];
let humids: number[] = [];
let emcs: number[] = [];
let tempTrends: number[] = [];
let humidTrends: number[] = [];
let emcTrends: number[] = [];
// let lowNodeConditions: GrainConditions | undefined = undefined;
// let highNodeConditions: GrainConditions | undefined = undefined;
// let avgConditions: GrainConditions | undefined = undefined;
// trendCables.forEach(cable => {
// //only use the values below the top node
// //because splice mutates the original array make a clone in the cables so the svg still has all of them for display
// //also reverse it so that the node 1 (end of the cable) is in the first position
// let tempClone = cloneDeep(cable.temperatures).reverse();
// let humClone = cloneDeep(cable.humidities).reverse();
// let emcClone = cloneDeep(cable.grainMoistures).reverse();
// //add the cable data to the proper arrays
// if (cable.topNode > 0) {
// temps.push(...tempClone.splice(0, cable.topNode));
// humids.push(...humClone.splice(0, cable.topNode));
// emcs.push(...emcClone.splice(0, cable.topNode));
// } else {
// //if the cable has no fill set (top node) then use all of the nodes
// temps = tempClone;
// humids = humClone;
// emcs = emcClone;
// }
// //add the trend data to the proper arrays if the top node is set
// let cableTrendData = binTrend.cableTrend[cable.key()];
// tempTrends.push(cableTrendData.grainCelciusTrend);
// humidTrends.push(cableTrendData.grainHumidityTrend);
// emcTrends.push(cableTrendData.grainEmcTrend);
let lowNodeConditions: GrainConditions | undefined = undefined;
let highNodeConditions: GrainConditions | undefined = undefined;
let avgConditions: GrainConditions | undefined = undefined;
trendCables.forEach(cable => {
//only use the values below the top node
//because splice mutates the original array make a clone in the cables so the svg still has all of them for display
//also reverse it so that the node 1 (end of the cable) is in the first position
let tempClone = cloneDeep(cable.temperatures).reverse();
let humClone = cloneDeep(cable.humidities).reverse();
let emcClone = cloneDeep(cable.grainMoistures).reverse();
//add the cable data to the proper arrays
if (cable.topNode > 0) {
temps.push(...tempClone.splice(0, cable.topNode));
humids.push(...humClone.splice(0, cable.topNode));
emcs.push(...emcClone.splice(0, cable.topNode));
} else {
//if the cable has no fill set (top node) then use all of the nodes
temps = tempClone;
humids = humClone;
emcs = emcClone;
}
//add the trend data to the proper arrays if the top node is set
let cableTrendData = binTrend.cableTrend[cable.key()];
tempTrends.push(cableTrendData.grainCelciusTrend);
humidTrends.push(cableTrendData.grainHumidityTrend);
emcTrends.push(cableTrendData.grainEmcTrend);
// //if the lowest temp for this cable is less than the temp in the low node conditions or the low node conditions are not set
// //use this cables lowest node and trend data in the condition
// if (!lowNodeConditions || Math.min(...temps) < lowNodeConditions.tempC) {
// //determine which node is the coldest so that the data displayed is for the same node
// let lowTempIndex =
// temps.indexOf(Math.min(...temps)) === -1 ? 0 : temps.indexOf(Math.min(...temps));
// lowNodeConditions = {
// tempC: temps[lowTempIndex],
// humidity: humids[lowTempIndex],
// emc: emcs[lowTempIndex],
// tempCTrend: cableTrendData.coldNodeTrend?.tempTrend ?? 0,
// humidityTrend: cableTrendData.coldNodeTrend?.humidityTrend ?? 0,
// emcTrend: cableTrendData.coldNodeTrend?.emcTrend ?? 0
// };
// }
//if the lowest temp for this cable is less than the temp in the low node conditions or the low node conditions are not set
//use this cables lowest node and trend data in the condition
if (!lowNodeConditions || Math.min(...temps) < lowNodeConditions.tempC) {
//determine which node is the coldest so that the data displayed is for the same node
let lowTempIndex =
temps.indexOf(Math.min(...temps)) === -1 ? 0 : temps.indexOf(Math.min(...temps));
lowNodeConditions = {
tempC: temps[lowTempIndex],
humidity: humids[lowTempIndex],
emc: emcs[lowTempIndex],
tempCTrend: cableTrendData.coldNodeTrend?.tempTrend ?? 0,
humidityTrend: cableTrendData.coldNodeTrend?.humidityTrend ?? 0,
emcTrend: cableTrendData.coldNodeTrend?.emcTrend ?? 0
};
}
// //do the same for the high node
// if (!highNodeConditions || cable.maxTemp() > highNodeConditions.tempC) {
// let highTempIndex =
// temps.indexOf(Math.max(...temps)) === -1 ? 0 : temps.indexOf(Math.max(...temps));
// highNodeConditions = {
// tempC: temps[highTempIndex],
// humidity: humids[highTempIndex],
// emc: emcs[highTempIndex],
// tempCTrend: cableTrendData.hotNodeTrend?.tempTrend ?? 0,
// humidityTrend: cableTrendData.hotNodeTrend?.humidityTrend ?? 0,
// emcTrend: cableTrendData.hotNodeTrend?.emcTrend ?? 0
// };
// }
// });
// //set the average conditions
// avgConditions = {
// tempC: average(temps),
// humidity: average(humids),
// emc: average(emcs),
// tempCTrend: average(tempTrends),
// humidityTrend: average(humidTrends),
// emcTrend: average(emcTrends)
// };
// setAverageConditions(avgConditions);
// setLowNodeConditions(lowNodeConditions);
// setHighNodeConditions(highNodeConditions);
// })
// .catch(err => {
// console.log(err);
// openSnack("Failed to retrieve trend data");
// })
// .finally(() => {
// setLoadingTrend(false);
// });
//do the same for the high node
if (!highNodeConditions || cable.maxTemp() > highNodeConditions.tempC) {
let highTempIndex =
temps.indexOf(Math.max(...temps)) === -1 ? 0 : temps.indexOf(Math.max(...temps));
highNodeConditions = {
tempC: temps[highTempIndex],
humidity: humids[highTempIndex],
emc: emcs[highTempIndex],
tempCTrend: cableTrendData.hotNodeTrend?.tempTrend ?? 0,
humidityTrend: cableTrendData.hotNodeTrend?.humidityTrend ?? 0,
emcTrend: cableTrendData.hotNodeTrend?.emcTrend ?? 0
};
}
});
//set the average conditions
avgConditions = {
tempC: average(temps),
humidity: average(humids),
emc: average(emcs),
tempCTrend: average(tempTrends),
humidityTrend: average(humidTrends),
emcTrend: average(emcTrends)
};
setAverageConditions(avgConditions);
setLowNodeConditions(lowNodeConditions);
setHighNodeConditions(highNodeConditions);
})
.catch(err => {
console.log(err);
openSnack("Failed to retrieve trend data");
})
.finally(() => {
setLoadingTrend(false);
});
}
}
}, [binAPI, bin, cables, openSnack]); //eslint-disable-line react-hooks/exhaustive-deps
@ -485,7 +485,7 @@ export default function BinVisualizer(props: Props) {
if (bin.settings.inventory && bin.settings.specs) {
const isEmpty = bin.settings.inventory?.empty === true;
const capacity = bin.settings.specs.bushelCapacity;
const grainBushels = bin.settings.inventory.grainBushels;
const grainBushels = bin.bushels();
setSliderCoulour("gold");
if (!capacity) {
setFillPercentage(null);
@ -535,7 +535,7 @@ export default function BinVisualizer(props: Props) {
const inventoryOverview = () => {
const capacity = bin.settings.specs?.bushelCapacity ?? 0;
const grainBushels = bin.settings.inventory?.grainBushels ?? 0;
const grainBushels = bin.bushels();
const isEmpty = bin.settings.inventory?.empty === true || !grainBushels || grainBushels <= 0;
const grainType = bin.settings.inventory?.grainType;
const grainTypeName = isEmpty || !grainType ? "" : GrainDescriber(grainType).name;
@ -1481,9 +1481,7 @@ export default function BinVisualizer(props: Props) {
onChange={(_, value) => {
setFillPercentage(value as number);
const capacity = bin.settings.specs ? bin.settings.specs.bushelCapacity : 0;
const current = bin.settings.inventory
? bin.settings.inventory.grainBushels
: 0;
const current = bin.bushels()
let grainAmount = ((value as number) / 100) * capacity;
if (grainAmount < current) {

View file

@ -185,6 +185,8 @@ import { Result } from "@mapbox/mapbox-gl-geocoder";
const [measurement, setMeasurement] = useState(false);
const [measurementData, setMeasurementData] = useState<Map<string, MeasurementData>>(new Map());
const measurementRef = useRef(measurementData);
const zoomRef = useRef(15)
const fieldMarkerZoom = 15
//watches for changes to the viewing as and sets the load boolean to trigger a load
useEffect(() => {
@ -591,12 +593,13 @@ import { Result } from "@mapbox/mapbox-gl-geocoder";
}
let newFM = fieldMarkers.get(newKey);
if (newFM) {
setCurrentView({
let view = {
latitude: newFM.lat(),
longitude: newFM.long(),
zoom: 12,
zoom: currentView.zoom,
transitionDuration: 1000
});
}
setCurrentView(view);
}
setObjectKey(newKey);
setFMIndexKey(newID);
@ -621,12 +624,13 @@ import { Result } from "@mapbox/mapbox-gl-geocoder";
}
let newFM = fieldMarkers.get(newKey);
if (newFM) {
setCurrentView({
let view = {
latitude: newFM.lat(),
longitude: newFM.long(),
zoom: 12,
zoom: currentView.zoom,
transitionDuration: 1000
});
}
setCurrentView(view);
}
setObjectKey(newKey);
setFMIndexKey(newID);
@ -728,13 +732,14 @@ import { Result } from "@mapbox/mapbox-gl-geocoder";
subtype: fm.type(),
mini: true,
clickFunc: (event, index) => {
console.log(zoomRef)
clickDelay();
closeDrawers();
setIgnoreFeatures(true);
setCurrentView({
latitude: fm.lat(),
longitude: fm.long(),
zoom: 12,
zoom: zoomRef.current,
transitionDuration: 0
//transitionInterpolator: new FlyToInterpolator()
});
@ -1115,14 +1120,16 @@ import { Result } from "@mapbox/mapbox-gl-geocoder";
let xOff = !mobileOffset ? -250 : undefined;
let yOff = mobileOffset ? -150 : undefined;
setCurrentView({
let view = {
latitude: lat,
longitude: long,
zoom: zoom,
transitionDuration: transDuration,
xOffset: center ? 0 : xOff,
yOffset: center ? 0 : yOff
});
}
setCurrentView(view);
zoomRef.current = zoom
};
const markerDialog = () => {

View file

@ -125,11 +125,23 @@ export class Bin {
return colour;
}
public bushels(): number {
let bushels = this.settings.inventory?.grainBushels || 0
if (this.settings.inventory?.inventoryControl === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_AUTOMATIC_LIDAR){
bushels = this.status.grainBushels
}
return bushels
}
public fillPercent(): number {
let fill = 0;
if (this.settings.inventory && this.settings.specs) {
let bushels = this.settings.inventory.grainBushels
if (this.settings.inventory.inventoryControl === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_AUTOMATIC_LIDAR){
bushels = this.status.grainBushels
}
fill = Math.round(
(this.settings.inventory.grainBushels / this.settings.specs.bushelCapacity) * 100
(bushels / this.settings.specs.bushelCapacity) * 100
);
}
return fill;

View file

@ -126,6 +126,10 @@ export interface IBinAPIContext {
showErrors?: boolean,
otherTeam?: string
) => Promise<AxiosResponse<pond.ListObjectMeasurementsResponse>>;
getBinsTrendData: (
bins: string[],
days: number
) => Promise<AxiosResponse<pond.GetBinsTrendDataResponse>>;
}
export const BinAPIContext = createContext<IBinAPIContext>({} as IBinAPIContext);
@ -629,6 +633,12 @@ export default function BinProvider(props: PropsWithChildren<Props>) {
})
};
const getBinsTrendData = (bins: string[], days: number) => {
return get<pond.GetBinsTrendDataResponse>(
pondURL("/binTrends?bins=" + bins.toString() + "&days=" + days + (as ? "&as=" + as : ""))
);
};
return (
<BinAPIContext.Provider
value={{
@ -655,7 +665,8 @@ export default function BinProvider(props: PropsWithChildren<Props>) {
listHistoryBetween,
listBinPrefs,
updateTopNodes,
listBinMeasurements
listBinMeasurements,
getBinsTrendData
}}>
{children}
</BinAPIContext.Provider>