|  |  |  | @ -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 } } | 
			
		
	
		
			
				
					|  |  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | 
 |