diff --git a/src/controllers/installationController.js b/src/controllers/installationController.js index 6cc867b9..1cedbcf3 100644 --- a/src/controllers/installationController.js +++ b/src/controllers/installationController.js @@ -1228,95 +1228,95 @@ exports.createMasterSlaveData = async (req, reply) => { } }; -exports.masterConnectedSlaveList = async (req, reply) => { - try { - const { connectedTo } = req.params; +// exports.masterConnectedSlaveList = async (req, reply) => { +// try { +// const { connectedTo } = req.params; - // Step 1: Get master device details - const master = await Insensors.findOne({ hardwareId: connectedTo, type: 'master' }).lean(); - if (!master) { - return reply.status(404).send({ - success: false, - message: "Master device not found" - }); - } +// // Step 1: Get master device details +// const master = await Insensors.findOne({ hardwareId: connectedTo, type: 'master' }).lean(); +// if (!master) { +// return reply.status(404).send({ +// success: false, +// message: "Master device not found" +// }); +// } - // Step 2: Get tank metadata for master - const tankDetails = await Tank.findOne({ hardwareId: connectedTo }, { tankLocation: 1, typeOfWater: 1 }).lean(); +// // Step 2: Get tank metadata for master +// const tankDetails = await Tank.findOne({ hardwareId: connectedTo }, { tankLocation: 1, typeOfWater: 1 }).lean(); - const masterTypeOfWater = tankDetails?.typeOfWater || null; +// const masterTypeOfWater = tankDetails?.typeOfWater || null; - // Step 3: Get slave tanks connected to master - const slaveTanks = await Insensors.find({ connected_to: connectedTo, type: 'slave' }).lean(); - const slaveCount = slaveTanks.length; +// // Step 3: Get slave tanks connected to master +// const slaveTanks = await Insensors.find({ connected_to: connectedTo, type: 'slave' }).lean(); +// const slaveCount = slaveTanks.length; - // Step 4: Get latest IotData for master - const latestIotData = await IotData.findOne({ hardwareId: connectedTo }).sort({ date: -1 }).lean(); +// // Step 4: Get latest IotData for master +// const latestIotData = await IotData.findOne({ hardwareId: connectedTo }).sort({ date: -1 }).lean(); - // Step 5: Fetch order to get masterName and location - const order = await Order.findOne({ "master_connections.hardwareId": connectedTo }).lean(); - let masterOrderInfo = {}; - if (order) { - const match = order.master_connections.find(mc => mc.hardwareId === connectedTo); - if (match) { - masterOrderInfo = { - masterName: match.master_name || "", - location: match.location || "" - }; - } - } +// // Step 5: Fetch order to get masterName and location +// const order = await Order.findOne({ "master_connections.hardwareId": connectedTo }).lean(); +// let masterOrderInfo = {}; +// if (order) { +// const match = order.master_connections.find(mc => mc.hardwareId === connectedTo); +// if (match) { +// masterOrderInfo = { +// masterName: match.master_name || "", +// location: match.location || "" +// }; +// } +// } - // Step 6: Prepare master object for response - const masterResponse = { - ...master, - isMaster: true, - tankLocation: tankDetails?.tankLocation || null, - typeOfWater: masterTypeOfWater, - tankHeight: null, - masterName: masterOrderInfo.masterName, - location: masterOrderInfo.location - }; +// // Step 6: Prepare master object for response +// const masterResponse = { +// ...master, +// isMaster: true, +// tankLocation: tankDetails?.tankLocation || null, +// typeOfWater: masterTypeOfWater, +// tankHeight: null, +// masterName: masterOrderInfo.masterName, +// location: masterOrderInfo.location +// }; - // Step 7: Process each slave - const processedSlaves = slaveTanks.map(slave => { - const originalHardwareId = slave.hardwareId; - const tankHardwareId = slave.tankhardwareId; +// // Step 7: Process each slave +// const processedSlaves = slaveTanks.map(slave => { +// const originalHardwareId = slave.hardwareId; +// const tankHardwareId = slave.tankhardwareId; - // Determine final hardwareId: prefer tankhardwareId if exists - const finalHardwareId = tankHardwareId || originalHardwareId; +// // Determine final hardwareId: prefer tankhardwareId if exists +// const finalHardwareId = tankHardwareId || originalHardwareId; - const matchingTankData = latestIotData?.tanks?.find(t => - t.tankhardwareId === finalHardwareId || t.hardwareId === finalHardwareId - ); +// const matchingTankData = latestIotData?.tanks?.find(t => +// t.tankhardwareId === finalHardwareId || t.hardwareId === finalHardwareId +// ); - return { - ...slave, - isMaster: false, - hardwareId: finalHardwareId, // Replace hardwareId with tankhardwareId if present - tankHeight: matchingTankData?.tankHeight ?? null, - typeOfWater: masterTypeOfWater === 'bore' ? 'bore' : (slave.typeOfWater || null) - }; - }); +// return { +// ...slave, +// isMaster: false, +// hardwareId: finalHardwareId, // Replace hardwareId with tankhardwareId if present +// tankHeight: matchingTankData?.tankHeight ?? null, +// typeOfWater: masterTypeOfWater === 'bore' ? 'bore' : (slave.typeOfWater || null) +// }; +// }); - // Step 8: Combine master and slaves into one array - const combinedData = [masterResponse, ...processedSlaves]; +// // Step 8: Combine master and slaves into one array +// const combinedData = [masterResponse, ...processedSlaves]; - return reply.send({ - success: true, - tankLocation: tankDetails?.tankLocation || null, - typeOfWater: masterTypeOfWater, - connectedSlaveCount: slaveCount, - data: combinedData - }); +// return reply.send({ +// success: true, +// tankLocation: tankDetails?.tankLocation || null, +// typeOfWater: masterTypeOfWater, +// connectedSlaveCount: slaveCount, +// data: combinedData +// }); - } catch (error) { - console.error("Error fetching master connected slave data:", error); - return reply.status(500).send({ - success: false, - message: "Internal Server Error" - }); - } -}; +// } catch (error) { +// console.error("Error fetching master connected slave data:", error); +// return reply.status(500).send({ +// success: false, +// message: "Internal Server Error" +// }); +// } +// }; @@ -1452,6 +1452,116 @@ exports.masterConnectedSlaveList = async (req, reply) => { // }; +exports.masterConnectedSlaveList = async (req, reply) => { + try { + const { connectedTo } = req.params; + + // Step 1: Get master device details + const master = await Insensors.findOne({ hardwareId: connectedTo, type: 'master' }).lean(); + if (!master) { + return reply.status(404).send({ + success: false, + message: "Master device not found" + }); + } + + // Step 2: Get tank metadata for master (including height, length, width) + const tankDetails = await Tank.findOne( + { hardwareId: connectedTo }, + { + tankLocation: 1, + typeOfWater: 1, + height: 1, + length: 1, + width: 1 + } + ).lean(); + + const masterTypeOfWater = tankDetails?.typeOfWater || null; + + // Step 3: Get slave tanks connected to master + const slaveTanks = await Insensors.find({ connected_to: connectedTo, type: 'slave' }).lean(); + const slaveCount = slaveTanks.length; + + // Step 4: Get latest IotData for master + const latestIotData = await IotData.findOne({ hardwareId: connectedTo }).sort({ date: -1 }).lean(); + + // Step 5: Fetch order to get masterName and location + const order = await Order.findOne({ "master_connections.hardwareId": connectedTo }).lean(); + let masterOrderInfo = {}; + if (order) { + const match = order.master_connections.find(mc => mc.hardwareId === connectedTo); + if (match) { + masterOrderInfo = { + masterName: match.master_name || "", + location: match.location || "" + }; + } + } + + // Step 6: Prepare master object for response + const masterResponse = { + ...master, + isMaster: true, + tankLocation: tankDetails?.tankLocation || null, + typeOfWater: masterTypeOfWater, + tankHeight: null, + masterName: masterOrderInfo.masterName, + location: masterOrderInfo.location, + height: tankDetails?.height || null, + length: tankDetails?.length || null, + width: tankDetails?.width || null + }; + + // Step 7: Process each slave + const processedSlaves = await Promise.all(slaveTanks.map(async slave => { + const originalHardwareId = slave.hardwareId; + const tankHardwareId = slave.tankhardwareId; + + const finalHardwareId = tankHardwareId || originalHardwareId; + + const matchingTankData = latestIotData?.tanks?.find(t => + t.tankhardwareId === finalHardwareId || t.hardwareId === finalHardwareId + ); + + // Optionally fetch tank meta for slave too (if needed) + const slaveTankMeta = await Tank.findOne( + { hardwareId: slave.hardwareId }, + { height: 1, length: 1, width: 1 } + ).lean(); + + return { + ...slave, + isMaster: false, + hardwareId: finalHardwareId, + tankHeight: matchingTankData?.tankHeight ?? null, + typeOfWater: masterTypeOfWater === 'bore' ? 'bore' : (slave.typeOfWater || null), + height: slaveTankMeta?.height || null, + length: slaveTankMeta?.length || null, + width: slaveTankMeta?.width || null + }; + })); + + // Step 8: Combine master and slaves into one array + const combinedData = [masterResponse, ...processedSlaves]; + + return reply.send({ + success: true, + tankLocation: tankDetails?.tankLocation || null, + typeOfWater: masterTypeOfWater, + connectedSlaveCount: slaveCount, + data: combinedData + }); + + } catch (error) { + console.error("Error fetching master connected slave data:", error); + return reply.status(500).send({ + success: false, + message: "Internal Server Error" + }); + } +}; + exports.mastrerList = async (req, reply) => { try { diff --git a/src/controllers/tanksController.js b/src/controllers/tanksController.js index 1c0b917e..1d5ef4bd 100644 --- a/src/controllers/tanksController.js +++ b/src/controllers/tanksController.js @@ -7828,42 +7828,124 @@ exports.validateTankHeight = async (req, reply) => { } }; +// exports.getActualWaterLevelInCm = async (req, reply) => { +// try { +// const { tankName } = req.params; + +// if (!tankName) { +// return reply.status(400).send({ message: "Tank name is required." }); +// } + +// // Fetch tank details using tankName +// const tank = await Tank.findOne({ tankName }); +// console.log("tank",tank) +// if (!tank) { +// return reply.status(404).send({ message: "Tank not found." }); +// } + +// const actualWaterLevel = parseFloat(tank.waterlevel); // Current water level in liters +// const waterCapacityPerCm = parseFloat(tank.waterCapacityPerCm); // Liters per cm + +// if (!actualWaterLevel || !waterCapacityPerCm) { +// return reply.status(400).send({ message: "Tank data is incomplete for conversion." }); +// } + +// // Convert actual water level from liters to cm +// const actualWaterLevelInCm = actualWaterLevel / waterCapacityPerCm; + +// reply.send({ +// status_code: 200, +// data: { +// tankName, +// actualWaterLevel: actualWaterLevel.toFixed(2) + " L", +// actualWaterLevelInCm: actualWaterLevelInCm.toFixed(2) + " cm" +// } +// }); + +// } catch (err) { +// reply.status(500).send({ message: err.message }); +// } +// }; + exports.getActualWaterLevelInCm = async (req, reply) => { try { - const { tankName } = req.params; + const { tankName } = req.params; + + 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 = tankHeightFeet * 30.48; + + let actualWaterLevelInCm; + let actualWaterLevelLiters; + + if (parseFloat(tank.waterlevel) > 0) { + // ✅ Direct conversion from liters to cm + const waterlevelLiters = parseFloat(tank.waterlevel); + const capacityPerCm = parseFloat(tank.waterCapacityPerCm); - if (!tankName) { - return reply.status(400).send({ message: "Tank name is required." }); + if (!capacityPerCm || capacityPerCm <= 0) { + return reply.status(400).send({ message: "Invalid waterCapacityPerCm value." }); } - // Fetch tank details using tankName - const tank = await Tank.findOne({ tankName }); + actualWaterLevelInCm = waterlevelLiters / capacityPerCm; + actualWaterLevelLiters = waterlevelLiters; - if (!tank) { - return reply.status(404).send({ message: "Tank not found." }); + } else { + // ✅ Fallback to IoT data to calculate cm & liters + const iotData = await IotData.findOne({ + hardwareId: tank.hardwareId, + "tanks.tankhardwareId": tank.tankhardwareId + }).sort({ date: -1 }); + + if (!iotData) { + return reply.status(404).send({ message: "No IoT data found for this tank." }); } - const actualWaterLevel = parseFloat(tank.waterlevel); // Current water level in liters - const waterCapacityPerCm = parseFloat(tank.waterCapacityPerCm); // Liters per cm + const matchingTank = iotData.tanks.find( + t => t.tankhardwareId === tank.tankhardwareId + ); - if (!actualWaterLevel || !waterCapacityPerCm) { - return reply.status(400).send({ message: "Tank data is incomplete for conversion." }); + if (!matchingTank) { + return reply.status(404).send({ message: "No matching tank found in IoT data." }); } - // Convert actual water level from liters to cm - const actualWaterLevelInCm = actualWaterLevel / waterCapacityPerCm; + const tankHeightFromSensor = parseFloat(matchingTank.tankHeight); - reply.send({ - status_code: 200, - data: { - tankName, - actualWaterLevel: actualWaterLevel.toFixed(2) + " L", - actualWaterLevelInCm: actualWaterLevelInCm.toFixed(2) + " cm" - } - }); + if (isNaN(tankHeightFromSensor)) { + return reply.status(400).send({ message: "Invalid tankHeight from IoT data." }); + } + + actualWaterLevelInCm = tankHeightCm - tankHeightFromSensor; + + const capacityPerCm = parseFloat(tank.waterCapacityPerCm); + if (!capacityPerCm || capacityPerCm <= 0) { + return reply.status(400).send({ message: "Invalid waterCapacityPerCm value." }); + } + + // ✅ Convert back to liters using height in cm + actualWaterLevelLiters = actualWaterLevelInCm * capacityPerCm; + } + + reply.send({ + status_code: 200, + data: { + tankName: tank.tankName, + actualWaterLevel: `${actualWaterLevelLiters.toFixed(2)} L`, + actualWaterLevelInCm: `${actualWaterLevelInCm.toFixed(2)} cm` + } + }); } catch (err) { - reply.status(500).send({ message: err.message }); + console.error(err); + reply.status(500).send({ message: err.message || "Internal Server Error" }); } };