|
|
@ -8175,12 +8175,106 @@ exports.validateTankHeight = async (req, reply) => {
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// };
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// exports.compareMeasuredHeight = async (req, reply) => {
|
|
|
|
|
|
|
|
// try {
|
|
|
|
|
|
|
|
// const { tankName, measuredHeight } = req.body;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (!tankName) {
|
|
|
|
|
|
|
|
// return reply.status(400).send({ message: "Tank name is required." });
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const tank = await Tank.findOne({ tankName });
|
|
|
|
|
|
|
|
// if (!tank) {
|
|
|
|
|
|
|
|
// return reply.status(404).send({ message: "Tank not found." });
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const tankHeightFeet = parseFloat(tank.height);
|
|
|
|
|
|
|
|
// const tankHeightCm = Math.round(tankHeightFeet * 30.48);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const capacityPerCm = parseFloat(tank.waterCapacityPerCm);
|
|
|
|
|
|
|
|
// if (!capacityPerCm || capacityPerCm <= 0) {
|
|
|
|
|
|
|
|
// return reply.status(400).send({ message: "Invalid waterCapacityPerCm value." });
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const manualWaterLevelLiters = parseFloat(tank.waterlevel) || 0;
|
|
|
|
|
|
|
|
// const manualWaterLevelInCm = Math.round(manualWaterLevelLiters / capacityPerCm);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// let sensorWaterLevelInCm = 0;
|
|
|
|
|
|
|
|
// let sensorWaterLevelLiters = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // Try to get IoT data
|
|
|
|
|
|
|
|
// const iotData = await IotData.findOne({
|
|
|
|
|
|
|
|
// hardwareId: tank.hardwareId,
|
|
|
|
|
|
|
|
// "tanks.tankhardwareId": tank.tankhardwareId
|
|
|
|
|
|
|
|
// }).sort({ date: -1 });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (iotData) {
|
|
|
|
|
|
|
|
// const matchingTank = iotData.tanks.find(
|
|
|
|
|
|
|
|
// t => t.tankhardwareId === tank.tankhardwareId
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
// if (matchingTank) {
|
|
|
|
|
|
|
|
// const tankHeightFromSensor = parseFloat(matchingTank.tankHeight);
|
|
|
|
|
|
|
|
// if (!isNaN(tankHeightFromSensor)) {
|
|
|
|
|
|
|
|
// const rawSensorWaterLevelInCm = tankHeightCm - Math.round(tankHeightFromSensor);
|
|
|
|
|
|
|
|
// sensorWaterLevelInCm = Math.max(0, rawSensorWaterLevelInCm);
|
|
|
|
|
|
|
|
// sensorWaterLevelLiters = Math.round(sensorWaterLevelInCm * capacityPerCm);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // Include comparison if measuredHeight provided
|
|
|
|
|
|
|
|
// let comparison = null;
|
|
|
|
|
|
|
|
// if (measuredHeight !== undefined) {
|
|
|
|
|
|
|
|
// const measuredHeightNum = parseFloat(measuredHeight);
|
|
|
|
|
|
|
|
// if (!isNaN(measuredHeightNum)) {
|
|
|
|
|
|
|
|
// const measuredHeightRounded = Math.round(measuredHeightNum);
|
|
|
|
|
|
|
|
// const heightDifferenceInCm = Math.abs(manualWaterLevelInCm - measuredHeightRounded);
|
|
|
|
|
|
|
|
// const message = heightDifferenceInCm <= 10
|
|
|
|
|
|
|
|
// ? "Manual measurement matches within 10 cm of sensor/manual data."
|
|
|
|
|
|
|
|
// : "Manual measurement not matched within range 10 cm.";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// comparison = {
|
|
|
|
|
|
|
|
// measuredHeight: measuredHeightRounded + " cm",
|
|
|
|
|
|
|
|
// actualWaterLevelInCm: manualWaterLevelInCm + " cm",
|
|
|
|
|
|
|
|
// heightDifferenceInCm: heightDifferenceInCm + " cm",
|
|
|
|
|
|
|
|
// message
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
// } else {
|
|
|
|
|
|
|
|
// comparison = { message: "Invalid measuredHeight; must be a number." };
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// reply.send({
|
|
|
|
|
|
|
|
// status_code: 200,
|
|
|
|
|
|
|
|
// data: {
|
|
|
|
|
|
|
|
// tankName: tank.tankName,
|
|
|
|
|
|
|
|
// tankHeightInCm: tankHeightCm,
|
|
|
|
|
|
|
|
// capacity: tank.capacity,
|
|
|
|
|
|
|
|
// manualWaterLevel: manualWaterLevelLiters, // as integer
|
|
|
|
|
|
|
|
// manualWaterLevelInCm: manualWaterLevelInCm + " cm",
|
|
|
|
|
|
|
|
// sensorWaterLevel: sensorWaterLevelLiters, // as integer
|
|
|
|
|
|
|
|
// sensorWaterLevelInCm: sensorWaterLevelInCm + " cm",
|
|
|
|
|
|
|
|
// ...(comparison && { comparison })
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// } catch (err) {
|
|
|
|
|
|
|
|
// console.error(err);
|
|
|
|
|
|
|
|
// reply.status(500).send({ message: err.message || "Internal Server Error" });
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
exports.compareMeasuredHeight = async (req, reply) => {
|
|
|
|
exports.compareMeasuredHeight = async (req, reply) => {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const { tankName, measuredHeight } = req.body;
|
|
|
|
const { tankName, measuredHeight, tankHeight } = req.body;
|
|
|
|
|
|
|
|
|
|
|
|
if (!tankName) {
|
|
|
|
if (!tankName || typeof measuredHeight !== 'number' || typeof tankHeight !== 'number') {
|
|
|
|
return reply.status(400).send({ message: "Tank name is required." });
|
|
|
|
return reply.status(400).send({ message: "tankName, tankHeight and measuredHeight (all required, as integers)." });
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (tankHeight <= 0 || measuredHeight < 0) {
|
|
|
|
|
|
|
|
return reply.status(400).send({ message: "Invalid tankHeight or measuredHeight; must be positive numbers." });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const tank = await Tank.findOne({ tankName });
|
|
|
|
const tank = await Tank.findOne({ tankName });
|
|
|
@ -8188,21 +8282,16 @@ exports.compareMeasuredHeight = async (req, reply) => {
|
|
|
|
return reply.status(404).send({ message: "Tank not found." });
|
|
|
|
return reply.status(404).send({ message: "Tank not found." });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const tankHeightFeet = parseFloat(tank.height);
|
|
|
|
|
|
|
|
const tankHeightCm = Math.round(tankHeightFeet * 30.48);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const capacityPerCm = parseFloat(tank.waterCapacityPerCm);
|
|
|
|
const capacityPerCm = parseFloat(tank.waterCapacityPerCm);
|
|
|
|
if (!capacityPerCm || capacityPerCm <= 0) {
|
|
|
|
if (!capacityPerCm || capacityPerCm <= 0) {
|
|
|
|
return reply.status(400).send({ message: "Invalid waterCapacityPerCm value." });
|
|
|
|
return reply.status(400).send({ message: "Invalid waterCapacityPerCm in tank data." });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const manualWaterLevelLiters = parseFloat(tank.waterlevel) || 0;
|
|
|
|
// 🔹 Sensor data
|
|
|
|
const manualWaterLevelInCm = Math.round(manualWaterLevelLiters / capacityPerCm);
|
|
|
|
let sensorGapCm = null;
|
|
|
|
|
|
|
|
let sensorWaterLevelInCm = null;
|
|
|
|
|
|
|
|
let sensorWaterLevelLiters = null;
|
|
|
|
|
|
|
|
|
|
|
|
let sensorWaterLevelInCm = 0;
|
|
|
|
|
|
|
|
let sensorWaterLevelLiters = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Try to get IoT data
|
|
|
|
|
|
|
|
const iotData = await IotData.findOne({
|
|
|
|
const iotData = await IotData.findOne({
|
|
|
|
hardwareId: tank.hardwareId,
|
|
|
|
hardwareId: tank.hardwareId,
|
|
|
|
"tanks.tankhardwareId": tank.tankhardwareId
|
|
|
|
"tanks.tankhardwareId": tank.tankhardwareId
|
|
|
@ -8213,48 +8302,47 @@ exports.compareMeasuredHeight = async (req, reply) => {
|
|
|
|
t => t.tankhardwareId === tank.tankhardwareId
|
|
|
|
t => t.tankhardwareId === tank.tankhardwareId
|
|
|
|
);
|
|
|
|
);
|
|
|
|
if (matchingTank) {
|
|
|
|
if (matchingTank) {
|
|
|
|
const tankHeightFromSensor = parseFloat(matchingTank.tankHeight);
|
|
|
|
const tankHeightFromSensor = parseInt(matchingTank.tankHeight, 10);
|
|
|
|
if (!isNaN(tankHeightFromSensor)) {
|
|
|
|
if (!isNaN(tankHeightFromSensor) && tankHeightFromSensor >= 0) {
|
|
|
|
const rawSensorWaterLevelInCm = tankHeightCm - Math.round(tankHeightFromSensor);
|
|
|
|
sensorGapCm = tankHeightFromSensor;
|
|
|
|
sensorWaterLevelInCm = Math.max(0, rawSensorWaterLevelInCm);
|
|
|
|
sensorWaterLevelInCm = Math.max(0, tankHeight - sensorGapCm);
|
|
|
|
sensorWaterLevelLiters = Math.round(sensorWaterLevelInCm * capacityPerCm);
|
|
|
|
sensorWaterLevelLiters = Math.round(sensorWaterLevelInCm * capacityPerCm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Include comparison if measuredHeight provided
|
|
|
|
// 🔹 Manual data
|
|
|
|
let comparison = null;
|
|
|
|
const manualWaterLevelInCm = measuredHeight;
|
|
|
|
if (measuredHeight !== undefined) {
|
|
|
|
const manualWaterLevelLiters = Math.round(manualWaterLevelInCm * capacityPerCm);
|
|
|
|
const measuredHeightNum = parseFloat(measuredHeight);
|
|
|
|
|
|
|
|
if (!isNaN(measuredHeightNum)) {
|
|
|
|
|
|
|
|
const measuredHeightRounded = Math.round(measuredHeightNum);
|
|
|
|
|
|
|
|
const heightDifferenceInCm = Math.abs(manualWaterLevelInCm - measuredHeightRounded);
|
|
|
|
|
|
|
|
const message = heightDifferenceInCm <= 10
|
|
|
|
|
|
|
|
? "Manual measurement matches within 10 cm of sensor/manual data."
|
|
|
|
|
|
|
|
: "Manual measurement not matched within range 10 cm.";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
comparison = {
|
|
|
|
// 🔹 Comparison
|
|
|
|
measuredHeight: measuredHeightRounded + " cm",
|
|
|
|
const heightDifferenceInCm = Math.abs(manualWaterLevelInCm - (sensorWaterLevelInCm ?? 0));
|
|
|
|
actualWaterLevelInCm: manualWaterLevelInCm + " cm",
|
|
|
|
const comparisonMessage = heightDifferenceInCm <= 10
|
|
|
|
heightDifferenceInCm: heightDifferenceInCm + " cm",
|
|
|
|
? "Manual measurement matches within 10 cm of sensor data."
|
|
|
|
message
|
|
|
|
: "Manual measurement not matched within range 10 cm.";
|
|
|
|
};
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
comparison = { message: "Invalid measuredHeight; must be a number." };
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
reply.send({
|
|
|
|
reply.send({
|
|
|
|
status_code: 200,
|
|
|
|
status_code: 200,
|
|
|
|
data: {
|
|
|
|
data: {
|
|
|
|
tankName: tank.tankName,
|
|
|
|
tankName,
|
|
|
|
tankHeightInCm: tankHeightCm,
|
|
|
|
tankHeightInCm: tankHeight,
|
|
|
|
capacity: tank.capacity,
|
|
|
|
capacity: tank.capacity,
|
|
|
|
manualWaterLevel: manualWaterLevelLiters, // as integer
|
|
|
|
sensor: {
|
|
|
|
manualWaterLevelInCm: manualWaterLevelInCm + " cm",
|
|
|
|
tankHeightInCm: tankHeight,
|
|
|
|
sensorWaterLevel: sensorWaterLevelLiters, // as integer
|
|
|
|
sensorGapCm: sensorGapCm ?? null,
|
|
|
|
sensorWaterLevelInCm: sensorWaterLevelInCm + " cm",
|
|
|
|
waterLevelInCm: sensorWaterLevelInCm ?? null,
|
|
|
|
...(comparison && { comparison })
|
|
|
|
waterLevelLiters: sensorWaterLevelLiters ?? null
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
manual: {
|
|
|
|
|
|
|
|
tankHeightInCm: tankHeight,
|
|
|
|
|
|
|
|
//measuredHeightCm: measuredHeight,
|
|
|
|
|
|
|
|
waterLevelInCm: manualWaterLevelInCm,
|
|
|
|
|
|
|
|
waterLevelLiters: manualWaterLevelLiters
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
comparison: {
|
|
|
|
|
|
|
|
heightDifferenceInCm,
|
|
|
|
|
|
|
|
message: comparisonMessage
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
@ -8266,8 +8354,6 @@ exports.compareMeasuredHeight = async (req, reply) => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//const ExcelJS = require('exceljs');
|
|
|
|
//const ExcelJS = require('exceljs');
|
|
|
|
//const IotData = require('../models/IotData'); // adjust the path
|
|
|
|
//const IotData = require('../models/IotData'); // adjust the path
|
|
|
|
|
|
|
|
|
|
|
|