diff --git a/src/controllers/tanksController.js b/src/controllers/tanksController.js index 855c0a17..39ebe2c0 100644 --- a/src/controllers/tanksController.js +++ b/src/controllers/tanksController.js @@ -2841,62 +2841,215 @@ async function calculateTotalPumpedWater(customerId, motorId, start_instance_id) exports.motorAction = async (req, reply) => { try { - const { customerId } = req.params; - const { action, motor_id: motorId, start_instance_id, phone, threshold_type, manual_threshold_time, manual_threshold_litres } = req.body; - - if (!motorId) throw new Error("Motor ID is required."); + const customerId = req.params.customerId; + const action = req.body.action; + const motorId = req.body.motor_id; + const start_instance_id = req.body.start_instance_id; + + // Define thresholds for water levels + const lowWaterThreshold = 5; // Low water level percentage threshold + //const highWaterThreshold = 90; // High water level percentage threshold + const highWaterThreshold = 70; // High water level percentage threshold + const veryHighWaterThreshold = 80; // Very High water level percentage threshold + const criticalHighWaterThreshold = 85; + // Ensure motor_id is provided + if (!motorId) { + throw new Error("Motor ID is required."); + } + // Get user FCM tokens const users = await User.findOne({ customerId }); - if (!users) return reply.status(404).send({ error: "User not found" }); + console.log("users",users) + + let loggedInUser = null; - let loggedInUser = users.phone === phone ? - { role: "Customer", name: users.username, phone: users.phone } : - users.staff?.staff?.find(staff => staff.phone === phone) ? - { role: "Staff", name: users.staff.staff.find(staff => staff.phone === phone).name, phone } : null; + if (users) { + if (users.phone === req.body.phone) { + loggedInUser = { role: "Customer", name: users.username, phone: users.phone }; + } else if (users.staff && users.staff.staff) { + const staffMember = users.staff.staff.find(staff => staff.phone === req.body.phone); + if (staffMember) { + loggedInUser = { role: "Staff", name: staffMember.name, phone: staffMember.phone }; + } + } + } - if (!loggedInUser) return reply.status(404).send({ error: "User not found" }); + if (!loggedInUser) { + console.log("User not found. Cannot proceed with motorStart event."); + return reply.status(404).send({ error: "User not found" }); // ✅ FIX: Ensure a response is returned + } - const fcmToken = users.fcmIds ? users.fcmIds.filter(id => id) : []; + const fcmToken = users.fcmIds ? users.fcmIds.filter(fcmIds => fcmIds) : []; + + // const fcmToken = users.map(user => user.fcmIds).filter(fcmIds => fcmIds); + console.log(fcmToken) const receiverTank = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() }); - if (!receiverTank) throw new Error("Receiver tank not found."); - + console.log(receiverTank) + const currentWaterLevel = parseInt(receiverTank.waterlevel, 10); + const waterLevelThresholds = { low: 30, veryLow: 20, criticallyLow: 10 }; const typeOfWater = receiverTank.typeOfWater; - let motorStopStatus = action === "start" ? "2" : "1"; - const blockName = req.body.from || "Unknown Block"; - const tankName = req.body.to || "Unknown Tank"; + console.log(typeOfWater,"typeOfWater") + + // Determine the motor stop status based on the action + let motorStopStatus; + const blockName = req.body.from || "Unknown Block"; // Provide a fallback if `from` is missing + const tankName = req.body.to || "Unknown Tank"; // Provide a fallback if `to` is missing const stopTime = req.body.stopTime + const motorOnType = "manual"; + const manual_threshold_time = req.body.manual_threshold_time; + let hasNotifiedStart = false; + let hasNotifiedStop = false; if (action === "start") { - - if (motorIntervals[motorId]) { - console.log(`🛑 Clearing old interval for motorId: ${motorId}`); - clearInterval(motorIntervals[motorId]); - delete motorIntervals[motorId]; + motorStopStatus = "2"; + const startTime = req.body.startTime; + await Tank.updateOne( + { customerId, "connections.inputConnections.motor_id": motorId }, + { $set: { "connections.inputConnections.$.motor_stop_status": motorStopStatus } } + ); + const thresholdTimeMs = req.body.manual_threshold_time * 60 * 1000; // Convert minutes to milliseconds + const stopCriteria = + motorOnType === "time" + ? `${req.body.manual_threshold_time} minutes` + : `${req.body.manual_threshold_litres} litres`; + try { + eventEmitter.emit( + "motorStart", + customerId, + fcmToken, + tankName, + blockName, + startTime, + "Mobile APP", + manual_threshold_time, + typeOfWater, + motorId, + loggedInUser.phone, + ); + + reply.code(200).send({ message: "Motor started successfully." }); + } catch (error) { + console.error("Error in handleMotorStart:", error); + reply.code(500).send({ error: "Internal Server Error" }); + } + + // Start checking water level every 30 minutes + if (!waterLevelCheckInterval) { + waterLevelCheckInterval = setInterval(async () => { + await checkWaterLevel(customerId, motorId, fcmToken, receiverTank); + }, 30 * 60 * 1000); // 30 minutes + } + await Tank.updateOne( + { customerId, "connections.inputConnections.motor_id": motorId }, + { $set: { "connections.inputConnections.$.motor_stop_status": "2", + "connections.inputConnections.$.manual_threshold_time": manual_threshold_time, + "connections.inputConnections.$.threshold_type": "time", + "connections.inputConnections.$.motor_on_type": "manual" } } + ); + + reply.code(200).send({ message: "Motor started successfully." }); + + } else if (action === "stop") { + motorStopStatus = "1"; // If action is stop, set stop status to "1" - // Confirm deletion - if (!motorIntervals[motorId]) { - console.log(`✅ Old interval successfully deleted.`); - } else { - console.error(`❌ Failed to delete old interval.`); + try { + + + const totalWaterPumped = await calculateTotalPumpedWater(customerId, motorId, start_instance_id); + + eventEmitter.emit("motorStop", customerId, fcmToken, tankName, blockName, stopTime, "Mobile APP", totalWaterPumped, typeOfWater, motorId, + loggedInUser.phone,); + + reply.code(200).send({ message: "Motor stopped successfully." }); + } catch (error) { + console.error("Error in handleMotorStop:", error); + reply.code(500).send({ error: "Internal Server Error" }); + } + + + await Tank.updateOne( + { customerId, "connections.inputConnections.motor_id": motorId }, + { + $set: { + "connections.inputConnections.$.motor_stop_status": "1", + "connections.inputConnections.$.motor_on_type": motorOnType } + } + ); + // Clear the interval when the motor is stopped + if (waterLevelCheckInterval) { + clearInterval(waterLevelCheckInterval); + waterLevelCheckInterval = null; // Reset the interval ID + } + } else { + throw new Error("Invalid action provided."); + } + + // If action is stop, immediately update motor status and perform stop operations + if (action === "stop") { + console.log("enterted stop") + await Tank.updateOne( + { customerId, "connections.inputConnections.motor_id": motorId }, + { + $set: { + "connections.inputConnections.$.motor_stop_status": "1", + "connections.inputConnections.$.motor_on_type": "manual", + "connections.inputConnections.$.stopTime": req.body.stopTime, + "connections.inputConnections.$.threshold_type": null, + "connections.inputConnections.$.manual_threshold_time": null, + "connections.inputConnections.$.manual_threshold_percentage": null + } } + ); + if (motorIntervals[motorId]) { + console.log(motorIntervals[motorId],"deleted") + clearInterval(motorIntervals[motorId]); // Clear the interval + delete motorIntervals[motorId]; // Remove the interval from the object } - const startTime = moment().tz('Asia/Kolkata').format('DD-MMM-YYYY - HH:mm'); - + this.publishMotorStopStatus(motorId, motorStopStatus); + + // Send immediate response to the client + reply.code(200).send({ message: "Motor stopped successfully." }); - + // Perform stop operations in the background + (async () => { + + console.log(start_instance_id,"start_instance_id",customerId,"customerId",motorId,"motorId") + const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id }); + if (motorData) { + console.log("entered if in stop") + const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() }); + const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10); + const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10); + const water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10); + const totalwaterpumped = quantityDelivered + water_pumped_till_now; + + await Tank.findOneAndUpdate( + { customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() }, + { $set: { total_water_added_from_midnight: totalwaterpumped } } + ); + + await MotorData.updateOne( + { customerId, motor_id: motorId, start_instance_id: start_instance_id }, + { + $set: { + stopTime: req.body.stopTime, + receiverfinalwaterlevel: receiverFinalWaterLevel.toString(), + quantity_delivered: quantityDelivered.toString() + } + } + ); + } + })(); + + return; // Return early to avoid executing the start logic + } else { await Tank.updateOne( { customerId, "connections.inputConnections.motor_id": motorId }, - { $set: { - "connections.inputConnections.$.motor_stop_status": "2", - "connections.inputConnections.$.manual_threshold_time": manual_threshold_time, - "connections.inputConnections.$.threshold_type": threshold_type, - "connections.inputConnections.$.motor_on_type": "manual" - }} + { $set: { "connections.inputConnections.$.motor_stop_status": "2" } } ); - - eventEmitter.emit("motorStart", customerId, fcmToken, tankName, blockName, startTime, "Mobile APP", manual_threshold_time, typeOfWater, motorId, loggedInUser.phone); - //this.publishMotorStopStatus(motorId, motorStopStatus); - reply.code(200).send({ message: "Motor started successfully." }); - + } + + // Check threshold settings if action is start + if (action === "start") { if (req.body.threshold_type === "time") { // Create a new MotorData entry const receiverTank = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() }); @@ -2912,7 +3065,7 @@ exports.motorAction = async (req, reply) => { receiverInitialwaterlevel: parseInt(receiverTank.waterlevel, 10) }); await newMotorData.save(); - console.log("entered time",motorId,motorStopStatus) + // Update the tank connections with start time and threshold time for await (const tank of Tank.find({ "connections.inputConnections.motor_id": motorId })) { this.publishMotorStopStatus(motorId, motorStopStatus); @@ -2933,88 +3086,55 @@ exports.motorAction = async (req, reply) => { ); } } - const thresholdTime = new Date(new Date().getTime() + req.body.manual_threshold_time * 60000); - console.log("New Threshold Time:", thresholdTime); - console.log("Current Time:", new Date()); - + const thresholdTime = new Date(new Date().getTime() + req.body.manual_threshold_time * 60000); motorIntervals[motorId] = setInterval(async () => { const supplierTank = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() }); const currentWaterLevel = parseInt(supplierTank.waterlevel, 10); const currentWaterPercentage = (currentWaterLevel / parseInt(supplierTank.capacity.replace(/,/g, ''), 10)) * 100; - // const notificationTracker = new Map(); + const notificationTracker = new Map(); if (new Date() >= thresholdTime || currentWaterPercentage <= lowWaterThreshold) { console.log(new Date(),"new date") console.log(thresholdTime,"thresholdTime") - //console.log("motor stopping because it entered this condition") + console.log("motor stopping because it entered this condition") // Emit the threshold time notification - try { - console.log("motor stopping because it entered this condition") - - const tank = await Tank.findOne( - { customerId, "connections.inputConnections.motor_id": motorId }, - { "connections.inputConnections.$": 1 } // Fetch only relevant motor connection - ); - - if (tank && tank.connections.inputConnections[0].motor_stop_status === "1") { - console.log("⚠️ Motor already stopped. Skipping notification."); - } else { - console.log("🚀 Sending threshold time notification..."); - - eventEmitter.emit( - "sendThresholdTimeNotification", - customerId, - fcmToken, - manual_threshold_time, - motorId, - tankName, - blockName - ); - } - // eventEmitter.emit( - // "sendThresholdTimeNotification", - // customerId, - // fcmToken, - // manual_threshold_time, - // motorId, - // tankName, - // blockName - // ); - - reply.code(200).send({ message: "Motor stopped successfully." }); - } catch (error) { - console.error("Error in handleMotorStop:", error); - reply.code(500).send({ error: "Internal Server Error" }); - } - - - //const notificationKey = `${customerId}_${motorId}_threshold`; + // eventEmitter.emit( + // "sendThresholdTimeNotification", + // customerId, + // fcmToken, + // manual_threshold_time, + // motorId, + // tankName, + // blockName + // ); + + const notificationKey = `${customerId}_${motorId}_threshold`; // Check if the notification has already been sent - // if (!notificationTracker.get(notificationKey)) { - // console.log("Sending threshold time notification..."); + if (!notificationTracker.get(notificationKey)) { + console.log("Sending threshold time notification..."); - // eventEmitter.emit( - // "sendThresholdTimeNotification", - // customerId, - // fcmToken, - // manual_threshold_time, - // motorId, - // tankName, - // blockName - // ); - - // // Mark notification as sent - // notificationTracker.set(notificationKey, true); - - // // Optionally, reset the flag after some time (e.g., 24 hours) - // setTimeout(() => { - // notificationTracker.delete(notificationKey); - // }, 24 * 60 * 60 * 1000); // Reset after 24 hours - // } else { - // console.log("Notification already sent, skipping..."); - // } + eventEmitter.emit( + "sendThresholdTimeNotification", + customerId, + fcmToken, + manual_threshold_time, + motorId, + tankName, + blockName + ); + + // Mark notification as sent + notificationTracker.set(notificationKey, true); + + // Optionally, reset the flag after some time (e.g., 24 hours) + setTimeout(() => { + notificationTracker.delete(notificationKey); + }, 24 * 60 * 60 * 1000); // Reset after 24 hours + } else { + console.log("Notification already sent, skipping..."); + } const currentTime = moment().tz('Asia/Kolkata').format('DD-MMM-YYYY - HH:mm'); await Tank.updateOne( @@ -3030,20 +3150,28 @@ exports.motorAction = async (req, reply) => { } } ); + // eventEmitter.emit('sendLowWaterNotification', fcmToken, receiverTank); + // console.log(motorIntervals[motorId],"deleted automatically") // Emit low water level notification + // clearInterval(motorIntervals[motorId]); // Clear interval + // delete motorIntervals[motorId]; + + // await checkWaterLevelsAndNotify(customerId, tankName, supplierTank.tankLocation, fcmToken); + // if (currentWaterPercentage >= highWaterThreshold && !notificationSentStatus.highWater) { + // eventEmitter.emit('sendHighWaterNotification', fcmToken, `Water level has reached high levels.`); + // notificationSentStatus.highWater = true; // Set flag to true to prevent duplicate notifications + // } - if (motorIntervals[motorId]) { - console.log(`🛑 Clearing interval for motorId: ${motorId}`); - clearInterval(motorIntervals[motorId]); - delete motorIntervals[motorId]; - - // Confirm deletion - if (!motorIntervals[motorId]) { - console.log(`✅ Interval for motorId: ${motorId} successfully deleted.`); - } else { - console.error(`❌ Failed to delete interval for motorId: ${motorId}`); - } - } - + // if (currentWaterPercentage >= veryHighWaterThreshold && !notificationSentStatus.veryHighWater) { + // eventEmitter.emit('sendVeryHighWaterNotification', fcmToken, `Water level has reached very high levels.`); + // notificationSentStatus.veryHighWater = true; // Set flag to true to prevent duplicate notifications + // } + + // if (currentWaterPercentage >= criticalHighWaterThreshold && !notificationSentStatus.criticallyHighWater) { + // eventEmitter.emit('sendCriticalHighWaterNotification', fcmToken, `Water level has reached critically high levels.`); + // notificationSentStatus.criticallyHighWater = true; // Set flag to true to prevent duplicate notifications + // } + clearInterval(motorIntervals[motorId]); // Stop the motor if condition met + delete motorIntervals[motorId]; // Remove from interval object this.publishMotorStopStatus(motorId, "1"); console.log(start_instance_id,"start_instance_id",customerId,"customerId",motorId,"motorId") @@ -3085,8 +3213,7 @@ exports.motorAction = async (req, reply) => { }, 30000); // Check every minute } - } - else if (req.body.threshold_type === "litres") { + }else if (req.body.threshold_type === "litres") { console.log("entered litres") const receiver_tank_info7 = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() }); const supplier_tank_info7 = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() }); @@ -3192,25 +3319,12 @@ exports.motorAction = async (req, reply) => { } } - - } else if (action === "stop") { - await stopMotor(motorId, customerId, start_instance_id); - try { - - - const totalWaterPumped = await calculateTotalPumpedWater(customerId, motorId, start_instance_id); - - eventEmitter.emit("motorStop", customerId, fcmToken, tankName, blockName, stopTime, "Mobile APP", totalWaterPumped, typeOfWater, motorId, - loggedInUser.phone,); - - reply.code(200).send({ message: "Motor stopped successfully." }); - } catch (error) { - console.error("Error in handleMotorStop:", error); - reply.code(500).send({ error: "Internal Server Error" }); - } - this.publishMotorStopStatus(motorId, motorStopStatus); - reply.code(200).send({ message: "Motor stopped successfully." }); + + } + // Respond with success message + reply.code(200).send({ message: `Motor ${action === "start" ? "started" : "stopped"} successfully.` }); + } catch (err) { throw boom.boomify(err); } @@ -3235,7 +3349,7 @@ async function stopMotor(motorId, customerId, start_instance_id) { delete motorIntervals[motorId]; } - // eventEmitter.emit("motorStop", customerId, [], "", "", currentTime, "Mobile APP", 0, "", motorId, ""); + eventEmitter.emit("motorStop", customerId, [], "", "", currentTime, "Mobile APP", 0, "", motorId, ""); const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id }); if (motorData) {