From 537f1ba51513ccf24cc6ed60f52c99a010d0a11a Mon Sep 17 00:00:00 2001 From: Varun Date: Tue, 18 Mar 2025 16:47:19 +0530 Subject: [PATCH] reverted motor action --- src/controllers/tanksController.js | 368 ++++++++++++++++++----------- 1 file changed, 232 insertions(+), 136 deletions(-) diff --git a/src/controllers/tanksController.js b/src/controllers/tanksController.js index 83e472a0..c06a00d3 100644 --- a/src/controllers/tanksController.js +++ b/src/controllers/tanksController.js @@ -2838,65 +2838,216 @@ 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."); + } - const users = await User.findOne({ customerId }); - if (!users) return reply.status(404).send({ error: "User not found" }); - - 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 (!loggedInUser) return reply.status(404).send({ error: "User not found" }); - - const fcmToken = users.fcmIds ? users.fcmIds.filter(id => id) : []; + // Get user FCM tokens + const users = await User.find({ customerId }); + 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."); - - 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(receiverTank) + const currentWaterLevel = parseInt(receiverTank.waterlevel, 10); + const waterLevelThresholds = { low: 30, veryLow: 20, criticallyLow: 10 }; + + // 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 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}`); - } + + 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`; + + await checkWaterLevelsAndNotify(customerId, tankName, receiverTank.tankLocation, fcmToken); + + // eventEmitter.emit( + // "motorStart", + // fcmToken, + // new Date().toISOString(), + // motorId, + // currentWaterLevel, + // blockName, // Block Name + // tankName, // Tank Name + // startTime, + // motorOnType, + // stopCriteria, + // manual_threshold_time + // ); + if (!notificationSentStatus.motorStart) { + eventEmitter.emit( + "motorStart", + fcmToken, + new Date().toISOString(), + motorId, + currentWaterLevel, + blockName, + tankName, + startTime, + motorOnType, + manual_threshold_time + ); + notificationSentStatus.motorStart = true; // Set flag to true to prevent duplicate notifications } - - const startTime = moment().tz('Asia/Kolkata').format('DD-MMM-YYYY - HH:mm'); + 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" } } + ); + + // await Tank.updateOne( + // { customerId, "connections.inputConnections.motor_id": motorId }, + // { + // $set: { + // "connections.inputConnections.$.motor_stop_status": "2", + // "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" + + await checkWaterLevelsAndNotify(customerId, tankName, receiverTank.tankLocation, fcmToken); + + // eventEmitter.emit( + // "motorStop", + // fcmToken, + // // motorId, + // // currentWaterLevel, + // // blockName, + // tankName, + // stopTime, + // motorOnType + // ); + if (!notificationSentStatus.motorStop) { + eventEmitter.emit( + "motorStop", + fcmToken, + tankName, + stopTime, + motorOnType + ); + notificationSentStatus.motorStop = true; // Set flag to true to prevent duplicate notifications + } 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": "1", + "connections.inputConnections.$.motor_on_type": motorOnType } + } ); - - eventEmitter.emit("motorStart", customerId, fcmToken, tankName, blockName, startTime, "Mobile APP", manual_threshold_time, typeOfWater, motorId, loggedInUser.phone); + + } 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 + } this.publishMotorStopStatus(motorId, motorStopStatus); - reply.code(200).send({ message: "Motor started successfully." }); - + + // Send immediate response to the client + reply.code(200).send({ message: "Motor stopped successfully." }); + + // Perform stop operations in the background + (async () => { + await delay(300000); + + const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id }); + if (motorData) { + 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" } } + ); + } + + // 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,13 +3063,12 @@ 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); for await (const tank of Tank.find({ "connections.inputConnections.motor_id": motorId })) { const index = tank.connections.inputConnections.findIndex(connection => connection.motor_id === motorId); - if (index !== -1) { await Tank.updateOne( { customerId, "connections.inputConnections.motor_id": motorId }, @@ -2939,51 +3089,18 @@ exports.motorAction = async (req, reply) => { 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(); + 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") // Emit the threshold time notification - - // 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..."); - - // 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'); + eventEmitter.emit( + "sendThresholdTimeNotification", + fcmToken, + `Motor has reached its time threshold of ${req.body.manual_threshold_time} minutes and will stop.` + ); + await Tank.updateOne( { customerId, "connections.inputConnections.motor_id": motorId }, { @@ -2992,23 +3109,37 @@ exports.motorAction = async (req, reply) => { "connections.inputConnections.$.threshold_type": null, "connections.inputConnections.$.manual_threshold_time": null, - "connections.inputConnections.$.manual_threshold_percentage": null, - "connections.inputConnections.$.stopTime": currentTime, + "connections.inputConnections.$.manual_threshold_percentage": null } } ); + // 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 (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") - + await delay(300000); const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id }); - console.log(motorData,"motorData") if (motorData) { - console.log("got into if") 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); @@ -3024,7 +3155,7 @@ exports.motorAction = async (req, reply) => { { customerId, motor_id: motorId, start_instance_id: start_instance_id }, { $set: { - stopTime: currentTime, + stopTime: req.body.stopTime, receiverfinalwaterlevel: receiverFinalWaterLevel.toString(), quantity_delivered: quantityDelivered.toString() } @@ -3042,8 +3173,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() }); @@ -3149,52 +3279,18 @@ exports.motorAction = async (req, reply) => { } } - - } else if (action === "stop") { - await stopMotor(motorId, customerId, start_instance_id); - 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); } }; -async function stopMotor(motorId, customerId, start_instance_id) { - const currentTime = moment().tz('Asia/Kolkata').format('DD-MMM-YYYY - HH:mm'); - await Tank.updateOne( - { customerId, "connections.inputConnections.motor_id": motorId }, - { $set: { - "connections.inputConnections.$.motor_stop_status": "1", - "connections.inputConnections.$.stopTime": currentTime, - "connections.inputConnections.$.threshold_type": null, - "connections.inputConnections.$.manual_threshold_time": null, - "connections.inputConnections.$.manual_threshold_percentage": null - }} - ); - - if (motorIntervals[motorId]) { - clearInterval(motorIntervals[motorId]); - delete motorIntervals[motorId]; - } - eventEmitter.emit("motorStop", customerId, [], "", "", currentTime, "Mobile APP", 0, "", motorId, ""); - - const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id }); - if (motorData) { - const startTime = moment(motorData.startTime, 'DD-MMM-YYYY - HH:mm'); - const runtime = moment.duration(moment(currentTime, 'DD-MMM-YYYY - HH:mm').diff(startTime)).asSeconds(); - - const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() }); - const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel.replace(/,/g, ''), 10); - const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel.replace(/,/g, ''), 10); - - await MotorData.updateOne( - { customerId, motor_id: motorId, start_instance_id }, - { $set: { stopTime: currentTime, receiverfinalwaterlevel: receiverFinalWaterLevel.toString(), quantity_delivered: quantityDelivered.toString(), runtime: runtime } } - ); - } -}