diff --git a/src/controllers/installationController.js b/src/controllers/installationController.js index 3d9e76ae..adf631e8 100644 --- a/src/controllers/installationController.js +++ b/src/controllers/installationController.js @@ -740,6 +740,7 @@ exports.getByHardwareIdSupport = async (req, reply) => { } }; + exports.getByHardwareAndTankId = async (req, reply) => { try { const { hardwareId, tankhardwareId } = req.params; @@ -748,11 +749,9 @@ exports.getByHardwareAndTankId = async (req, reply) => { return reply.status(400).send({ error: "Both hardwareId and tankhardwareId are required" }); } - console.log("Fetching tank data for:", { hardwareId, tankhardwareId }); + console.log("📡 Fetching data for:", { hardwareId, tankhardwareId }); - const latestData = await IotData.findOne({ hardwareId }) - .sort({ date: -1 }) - .lean(); + const latestData = await IotData.findOne({ hardwareId }).sort({ date: -1 }).lean(); if (!latestData || !Array.isArray(latestData.tanks)) { return reply.code(404).send({ message: "No data found for given hardwareId and tankhardwareId" }); @@ -760,8 +759,7 @@ exports.getByHardwareAndTankId = async (req, reply) => { const now = new Date(); const dataDate = new Date(latestData.date); - const diffInMs = now - dataDate; - const isGSMConnected = diffInMs <= 60000; + const isGSMConnected = now - dataDate <= 60000; const matchedTank = latestData.tanks.find(tank => tank.tankhardwareId === tankhardwareId); @@ -772,58 +770,50 @@ exports.getByHardwareAndTankId = async (req, reply) => { const tankHeight = parseFloat(matchedTank.tankHeight || "0"); const isLoraConnected = isGSMConnected && tankHeight > 0; + // Format date and time from matched tank const matchedTankDateObj = new Date(matchedTank.date); - const day = String(matchedTankDateObj.getDate()).padStart(2, '0'); - const month = String(matchedTankDateObj.getMonth() + 1).padStart(2, '0'); - const year = matchedTankDateObj.getFullYear(); - const formattedDate = `${day}-${month}-${year}`; + const formattedDate = moment(matchedTankDateObj).tz("Asia/Kolkata").format("DD-MM-YYYY"); + const formattedTime = matchedTank.time || moment(matchedTankDateObj).tz("Asia/Kolkata").format("HH:mm:ss"); matchedTank.date = formattedDate; + matchedTank.time = formattedTime; const updateFields = { - connected_status: isLoraConnected ? "connected" : "disconnected" + connected_status: isLoraConnected ? "connected" : "disconnected", + connected_lora_date: formattedDate, + connected_lora_time: formattedTime, + lora_last_check_time: moment().tz("Asia/Kolkata").format("DD-MM-YYYY HH:mm:ss") }; - let connected_lora_date = null; - let connected_lora_time = null; - let lora_last_check_time = null; + // Check if Insensors document exists before updating + const sensorDoc = await Insensors.findOne({ connected_to: hardwareId, hardwareId: tankhardwareId }); - if (isLoraConnected) { - connected_lora_date = formattedDate; - connected_lora_time = matchedTank.time || matchedTankDateObj.toTimeString().split(" ")[0]; - updateFields.connected_lora_date = connected_lora_date; - updateFields.connected_lora_time = connected_lora_time; + if (!sensorDoc) { + console.warn("⚠️ No Insensors doc found with:", { connected_to: hardwareId, hardwareId: tankhardwareId }); + } else { + const updated = await Insensors.findByIdAndUpdate(sensorDoc._id, { $set: updateFields }, { new: true }); + console.log("✅ Insensors updated:", updated._id); } - // ✅ Format LoRa last check time in "YYYY-MM-DD HH:mm:ss" - lora_last_check_time = moment.tz("Asia/Kolkata").format("DD-MM-YYYY HH:mm:ss"); - updateFields.lora_last_check_time = lora_last_check_time; - - await Insensors.findOneAndUpdate( - { connected_to: hardwareId, hardwareId: tankhardwareId }, - { $set: updateFields }, - { new: true } - ); - - const displayMessage = isLoraConnected ? "LoRa connected" : "LoRa not connected"; - return reply.send({ status_code: 200, - message: displayMessage, + message: isLoraConnected ? "LoRa connected" : "LoRa not connected", data: matchedTank, lora_connected_status: updateFields.connected_status, - connected_lora_date, - connected_lora_time, - lora_last_check_time + connected_lora_date: updateFields.connected_lora_date, + connected_lora_time: updateFields.connected_lora_time, + lora_last_check_time: updateFields.lora_last_check_time }); } catch (err) { - console.error("Error in getByHardwareAndTankId:", err); + console.error("❌ Error in getByHardwareAndTankId:", err); return reply.status(500).send({ error: "Internal Server Error" }); } }; + + exports.getByHardwareAndTankIdSupport = async (req, reply) => { try { const { hardwareId, tankhardwareId } = req.params; @@ -2449,76 +2439,87 @@ exports.getIotDataByCustomer = async (req, reply) => { return reply.code(400).send({ error: "customerId is required" }); } + // ✅ Get all sensors for the customer const sensors = await Insensors.find({ customerId }); if (!sensors.length) { return reply.code(404).send({ message: "No sensors found for this customer." }); } - const masterHardwareIds = [ - ...new Set(sensors.map(s => s.connected_to?.trim()).filter(Boolean)) - ]; + // ✅ Get only master hardware IDs from Insensors directly + const masterSensors = sensors.filter(s => s.type === 'master'); + const masterHardwareIds = masterSensors.map(m => m.hardwareId?.trim()); + + // ✅ Map for masterName/location from Order + const orders = await Order.find({ customerId }).lean(); + const orderMap = {}; + orders.forEach(order => { + order.master_connections.forEach(connection => { + orderMap[connection.hardwareId] = { + masterName: connection.master_name || null, + location: connection.location || null + }; + }); + }); + + // ✅ Prepare final enriched master data const enrichedMasters = await Promise.all(masterHardwareIds.map(async (hardwareId) => { const latestRecord = await IotData.findOne({ hardwareId }).sort({ date: -1 }).lean(); - + + const orderInfo = orderMap[hardwareId] || {}; + if (!latestRecord) { return { hardwareId, message: "No IoT data found", + masterName: orderInfo.masterName ?? null, + location: orderInfo.location ?? null, tanks: [] }; } - - // ✅ Use timestamp to check GSM connection + + // ✅ Check GSM status const indiaTime = moment.tz(latestRecord.date, "Asia/Kolkata"); const now = moment.tz("Asia/Kolkata"); const diffInMinutes = now.diff(indiaTime, "minutes"); const gsmConnected = diffInMinutes <= 1; - const message = gsmConnected ? "GSM is connected" : "GSM is not connected"; - - // Get all connected slaves + + // ✅ Get slaves connected to this master const connectedSlaves = sensors.filter(sensor => sensor.connected_to?.trim() === hardwareId); - - // Enrich tanks - let tanks = connectedSlaves.map(slave => { + + // ✅ Prepare tank info + const tanks = connectedSlaves.map(slave => { const slaveId = slave.hardwareId?.trim(); - const matchedTank = latestRecord.tanks.find(tank => tank.tankhardwareId === slaveId); - - let loraConnected = false; - let loraMessage = "LORA is not connected"; // Default message for LoRa not connected - - // If matchedTank exists and tankHeight is not zero, check LoRa connection + const matchedTank = latestRecord.tanks?.find(t => t.tankhardwareId === slaveId); + + let loraMessage = "LORA is not connected"; + if (matchedTank?.date && matchedTank.tankHeight !== "0") { const tankTime = moment.tz(matchedTank.date, "Asia/Kolkata"); const loraDiff = now.diff(tankTime, "minutes"); - loraConnected = loraDiff <= 1; - loraMessage = loraConnected ? "LORA is connected" : "LORA is not connected"; + loraMessage = loraDiff <= 1 ? "LORA is connected" : "LORA is not connected"; } - + return { tankhardwareId: slaveId, tankName: slave.tankName ?? null, tankLocation: slave.tankLocation ?? null, - masterName: slave.masterName ?? null, - location: slave.location ?? null, - loraMessage, // Updated LoRa message + masterName: orderInfo.masterName ?? null, + location: orderInfo.location ?? null, + loraMessage, latestTankData: matchedTank ?? null }; }); - - // ✅ Remove the first tank - tanks = tanks.slice(1); - + return { hardwareId, message, - masterName: connectedSlaves[0]?.masterName ?? null, - location: connectedSlaves[0]?.location ?? null, + masterName: orderInfo.masterName ?? null, + location: orderInfo.location ?? null, tanks }; })); - return reply.send({ status_code: 200,