@ -1758,39 +1758,39 @@ eventEmitter.on(
// });
// Event listener to handle notification
eventEmitter . on ( 'sendLowWaterNotification' , async ( fcmToken , tankInfo ) => {
const message = formatWaterLevelMessage ( tankInfo , 'low' ) ;
sendNotification ( fcmToken , message ) ;
} ) ;
// eventEmitter.on('sendLowWaterNotification', async (fcmToken, tankInfo) => {
// const message = formatWaterLevelMessage(tankInfo, 'low');
// sendNotification(fcmToken, message);
// });
eventEmitter . on ( 'sendVeryLowWaterNotification' , async ( fcmToken , tankInfo ) => {
const message = formatWaterLevelMessage ( tankInfo , 'very low' ) ;
sendNotification ( fcmToken , message ) ;
} ) ;
// eventEmitter.on('sendVeryLowWaterNotification', async (fcmToken, tankInfo) => {
// const message = formatWaterLevelMessage(tankInfo, 'very low');
// sendNotification(fcmToken, message);
// });
eventEmitter . on ( 'sendCriticalLowWaterNotification' , async ( fcmToken , tankInfo ) => {
const message = formatWaterLevelMessage ( tankInfo , 'critically low' ) ;
sendNotification ( fcmToken , message ) ;
} ) ;
// eventEmitter.on('sendCriticalLowWaterNotification', async (fcmToken, tankInfo) => {
// const message = formatWaterLevelMessage(tankInfo, 'critically low');
// sendNotification(fcmToken, message);
// });
const formatWaterLevelMessage = ( tankInfo , levelType ) => {
const tankName = tankInfo . tankName ;
const tankLocation = tankInfo . tankLocation ;
const waterLevel = parseInt ( tankInfo . waterlevel , 10 ) ;
const capacity = parseInt ( tankInfo . capacity , 10 ) ;
const volumeInLitres = ( capacity * waterLevel ) / 100 ; // assuming the capacity is in litres
let levelDescription = '' ;
if ( levelType === 'low' ) {
levelDescription = ` ${ waterLevel } % ( ${ volumeInLitres . toFixed ( 2 ) } L) ` ;
} else if ( levelType === 'very low' ) {
levelDescription = ` ${ waterLevel } % ( ${ volumeInLitres . toFixed ( 2 ) } L) ` ;
} else if ( levelType === 'critically low' ) {
levelDescription = ` ${ waterLevel } % ( ${ volumeInLitres . toFixed ( 2 ) } L) ` ;
}
// const formatWaterLevelMessage = (tankInfo, levelType) => {
// const tankName = tankInfo.tankName;
// const tankLocation = tankInfo.tankLocation;
// const waterLevel = parseInt(tankInfo.waterlevel, 10);
// const capacity = parseInt(tankInfo.capacity, 10);
// const volumeInLitres = (capacity * waterLevel) / 100; // assuming the capacity is in litres
// let levelDescription = '';
// if (levelType === 'low') {
// levelDescription = `${waterLevel}% (${volumeInLitres.toFixed(2)} L)`;
// } else if (levelType === 'very low') {
// levelDescription = `${waterLevel}% (${volumeInLitres.toFixed(2)} L)`;
// } else if (levelType === 'critically low') {
// levelDescription = `${waterLevel}% (${volumeInLitres.toFixed(2)} L)`;
// }
return ` Water level in ' ${ tankName } ', located at ' ${ tankLocation } ', type of water: ${ tankInfo . waterType } is ${ levelType } at ${ levelDescription } . Action: start motor now. ` ;
} ;
// return `Water level in '${tankName}', located at '${tankLocation}', type of water: ${tankInfo.waterType} is ${levelType} at ${levelDescription}. Action: start motor now.`;
// };
// Emit low water level event with motorId
// eventEmitter.on('lowWaterLevel', async (fcmTokens, timestamp, motorId, waterLevel) => {
@ -1827,52 +1827,201 @@ eventEmitter.on('sendThresholdTimeNotification', async (fcmTokens, message) => {
}
} ) ;
// eventEmitter.on(
// 'sendMotorStartNotification',
// async (fcmTokens, motorId, waterLevel, blockName, tankName, motorOnType, stopCriteria, manual_threshold_time) => {
// try {
// // Get the latest timestamp
// const startTime = new Date().toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' });
// // Retrieve the user information
// const users = await User.find({ fcmIds: { $in: fcmTokens } });
// const userNames = users.map(user => user.username).join(', ');
// const startMethod = motorOnType.toUpperCase() === "Forced Manual";
// // Prepare the message
// const message =
// `🚰 Tank Name: '${tankName}'\n` +
// `🕒 Pump started at: '${startTime}'\n` +
// `👤 Initiated by: ${userNames}\n` +
// `🔄 Pump started by: '${startMethod}'`;
// // Send the notification
// await sendNotification(fcmTokens, 'Motor Started 🚀', message);
// console.log('Motor start notification sent successfully!');
// } catch (error) {
// console.error('Error in sendMotorStartNotification event:', error);
// }
// }
// );
eventEmitter . on (
'sendMotorStartNotification' ,
async ( fcmTokens , motorId , waterLevel , blockName , tankName , motorOnType , stopCriteria , manual _threshold _time ) => {
async (
fcmTokens ,
blockName ,
tankName ,
motorOnType ,
stopCriteria ,
typeOfWater ,
highThreshold // Add the high threshold as a parameter
) => {
try {
// Get the latest timestamp
const startTime = new Date ( ) . toLocaleString ( 'en-IN' , { timeZone : 'Asia/Kolkata' } ) ;
const currentDateTime = new Date ( ) ;
const startTime = currentDateTime . toLocaleString ( 'en-IN' , { timeZone : 'Asia/Kolkata' } ) ;
const formattedDate = currentDateTime . toLocaleDateString ( 'en-IN' , { timeZone : 'Asia/Kolkata' } ) ;
const formattedTime = currentDateTime . toLocaleTimeString ( 'en-IN' , { timeZone : 'Asia/Kolkata' } ) ;
// Retrieve the user information
const users = await User . find ( { fcmIds : { $in : fcmTokens } } ) ;
const userNames = users . map ( user => user . username ) . join ( ', ' ) ;
const startMethod = motorOnType . toUpperCase ( ) === "Forced Manual" ;
// Prepare the message
// Determine the pump initiation method
const startMethod = motorOnType === "Forced Manual" ? "Physically" : "Manually"
// Dynamically generate the motor name
const motorName = ` ${ tankName } - ${ blockName } - ${ typeOfWater } ` ;
// Determine the stop condition message
let stopConditionMessage = "" ;
if ( stopCriteria === "manual" ) {
stopConditionMessage = ` Will stop at Manually \n ` ;
} else if ( stopCriteria === "highThreshold" ) {
stopConditionMessage = ` 🚨 Pump will stop when the water level reaches the high threshold of ${ highThreshold } %. \n ` ;
}
// Prepare the notification message
const message =
` 🚰 Motor Name: ${ motorName } \n ` +
` 🚰 Tank Name: ' ${ tankName } ' \n ` +
` 🕒 Pump started at: ' ${ startTime } ' \n ` +
` 👤 Initiated by: ${ userNames } \n ` +
` 🔄 Pump started by: ' ${ startMethod } ' ` ;
` 🏢 Block Name: ' ${ blockName } ' \n ` +
` 👤 Started by: ${ userNames } \n ` +
` 📱 Mode: ' ${ startMethod } ' \n ` +
` 🕒 Pump started at: ${ startTime } (Time: ${ formattedTime } on ${ formattedDate } ) \n ` +
stopConditionMessage ; // Add only the relevant stop condition
// Send the notification
await sendNotification ( fcmTokens , 'Motor Started 🚀' , message ) ;
console . log ( 'Motor start notification sent successfully!' ) ;
console . log ( 'Motor start notification with stop criteria sent successfully!') ;
} catch ( error ) {
console . error ( 'Error in sendMotorStartNotification event:' , error ) ;
}
}
) ;
// eventEmitter.on(
// 'sendMotorStartNotification',
// async (fcmTokens, motorId, waterLevel, blockName, tankName, motorOnType, stopCriteria, manual_threshold_time, typeOfWater) => {
// try {
// // Get the latest timestamp
// const currentDateTime = new Date();
// const startTime = currentDateTime.toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' });
// const formattedDate = currentDateTime.toLocaleDateString('en-IN', { timeZone: 'Asia/Kolkata' });
// const formattedTime = currentDateTime.toLocaleTimeString('en-IN', { timeZone: 'Asia/Kolkata' });
// // Retrieve the user information
// const users = await User.find({ fcmIds: { $in: fcmTokens } });
// const userNames = users.map(user => user.username).join(', ');
// // Determine the pump initiation method
// const startMethod = motorOnType === "Mobile APP" ? "Mobile APP" : "Manual";
// // Dynamically generate the motor name
// const motorName = `${tankName}-${blockName}-${typeOfWater}`;
// // Prepare the notification message
// const message =
// `🚰 Motor Name: '${motorName}'\n` +
// `🚰 Tank Name: '${tankName}'\n` +
// `🏢 Block Name: '${blockName}'\n` +
// `💧 Water Level: '${waterLevel}%'\n` +
// `👤 Initiated by: ${userNames}\n` +
// `📱 Pump started by: '${startMethod}'\n` +
// `🕒 Start Time: '${startTime}'\n` +
// `⏳ Will stop after: '${manual_threshold_time}' mins\n` +
// `📅 Date: '${formattedDate}'\n` +
// `⏰ Time: '${formattedTime}'`;
// // Send the notification
// await sendNotification(fcmTokens, 'Motor Started 🚀', message);
// console.log('Motor start notification sent successfully!');
// } catch (error) {
// console.error('Error in sendMotorStartNotification event:', error);
// }
// }
// );
// eventEmitter.on(
// 'sendMotorStopNotification',
// async (fcmTokens, motorId, waterLevel, blockName, tankName, motorOnType) => {
// try {
// // Get the latest timestamp
// const stopTime = new Date().toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' });
// // Retrieve the user information
// const users = await User.find({ fcmIds: { $in: fcmTokens } });
// const userNames = users.map(user => user.username).join(', ');
// const stopMethod = motorOnType.toUpperCase() === "Forced Manual";
// // Prepare the message
// const message =
// `🚰 Tank Name: '${tankName}'\n` +
// `🕒 Pump stopped at: '${stopTime}'\n` +
// `👤 Initiated by: ${userNames}\n` +
// `🔄 Pump stopped by: '${stopMethod}'\n`;
// // Send the notification
// await sendNotification(fcmTokens, 'Motor Stopped 🛑', message);
// console.log('Motor stop notification sent successfully!');
// } catch (error) {
// console.error('Error in sendMotorStopNotification event:', error);
// }
// }
// );
eventEmitter . on (
'sendMotorStopNotification' ,
async ( fcmTokens , motorId , waterLevel , blockName , tankName , motorOnType ) => {
async (
fcmTokens ,
blockName ,
tankName ,
motorOnType ,
typeOfWater
) => {
try {
// Get the latest timestamp
const stopTime = new Date ( ) . toLocaleString ( 'en-IN' , { timeZone : 'Asia/Kolkata' } ) ;
const currentDateTime = new Date ( ) ;
const stopTime = currentDateTime . toLocaleString ( 'en-IN' , { timeZone : 'Asia/Kolkata' } ) ;
const formattedDate = currentDateTime . toLocaleDateString ( 'en-IN' , { timeZone : 'Asia/Kolkata' } ) ;
const formattedTime = currentDateTime . toLocaleTimeString ( 'en-IN' , { timeZone : 'Asia/Kolkata' } ) ;
// Retrieve the user information
const users = await User . find ( { fcmIds : { $in : fcmTokens } } ) ;
const userNames = users . map ( user => user . username ) . join ( ', ' ) ;
const stopMethod = motorOnType . toUpperCase ( ) === "Forced Manual" ;
// Prepare the message
// Determine the pump stop method
const stopMethod = motorOnType === "Forced Manual" ? "Physically" : "Manually" ;
// Dynamically generate the motor name
const motorName = ` ${ tankName } - ${ blockName } - ${ typeOfWater } ` ;
// Determine the stop condition message
let stopConditionMessage = "" ;
if ( stopCriteria === "manual" ) {
stopConditionMessage = ` Stopped at Manually \n ` ;
} else if ( stopCriteria === "highThreshold" ) {
stopConditionMessage = ` 🚨 Pump will stop when the water level reaches the high threshold of ${ highThreshold } %. \n ` ;
}
// Prepare the notification message
const message =
` 🚰 Motor Name: ${ motorName } \n ` +
` 🚰 Tank Name: ' ${ tankName } ' \n ` +
` 🕒 Pump stopped at: ' ${ stopTime } ' \n ` +
` 👤 Initiated by: ${ userNames } \n ` +
` 🔄 Pump stopped by: ' ${ stopMethod } ' \n ` ;
` 🏢 Block Name: ' ${ blockName } ' \n ` +
` 📱 Mode: ' ${ stopMethod } ' \n ` +
` 🕒 Pump stopped at: ${ stopTime } (Time: ${ formattedTime } on ${ formattedDate } ) \n ` +
stopConditionMessage ;
// Send the notification
await sendNotification ( fcmTokens , 'Motor Stopped 🛑' , message ) ;
@ -1883,6 +2032,31 @@ eventEmitter.on(
}
) ;
eventEmitter . on ( 'sendLowWaterNotification' , ( fcmTokens , message ) => {
const notificationMessage = ` Warning: Water level is low in the tank.
Tank Name : $ { tankName } ,
Location : $ { receiverTank . location } ,
Type of Water : $ { receiverTank . typeOfWater } ,
Current Water Level : $ { currentWaterLevel } liters ( $ { currentWaterPercentage . toFixed ( 2 ) } % ) ,
Date & Time : $ { new Date ( ) . toLocaleString ( ) } ` ;
// Send notifications using the provided FCM tokens
sendNotification ( fcmTokens , notificationMessage ) ;
} ) ;
eventEmitter . on ( 'sendCriticalLowWaterNotification' , ( fcmTokens , message ) => {
const notificationMessage = ` Critical Alert: Water level is critically low in the tank.
Tank Name : $ { tankName } ,
Location : $ { receiverTank . location } ,
Type of Water : $ { receiverTank . typeOfWater } ,
Current Water Level : $ { currentWaterLevel } liters ( $ { currentWaterPercentage . toFixed ( 2 ) } % ) ,
Date & Time : $ { new Date ( ) . toLocaleString ( ) } ` ;
// Send notifications using the provided FCM tokens
sendNotification ( fcmTokens , notificationMessage ) ;
} ) ;
// eventEmitter.on('sendMotorStartNotification', async (fcmTokens, message) => {
// try {
@ -1956,12 +2130,21 @@ const sendNotification = async (fcmIds, title, body) => {
notification : { title , body } ,
token ,
data : {
'target' : '/ route_navigatio n',
'target' : '/ scree n',
} ,
} ) ;
console . log ( ` Notification sent successfully to token: ${ token } ` , response ) ;
} catch ( error ) {
console . error ( ` Failed to send notification to token: ${ token } ` , error ) ;
// Check for specific error indicating an invalid token
if ( error . code === 'messaging/registration-token-not-registered' ) {
// Remove the invalid token from the database
await User . updateOne (
{ fcmIds : token } , // Ensure you're targeting the right user with the invalid token
{ $pull : { fcmIds : token } } // Remove the invalid token
) ;
console . log ( ` Removed invalid token: ${ token } ` ) ;
}
}
} ) ;
@ -2313,71 +2496,90 @@ const notificationSentStatus = {
criticallyHighWater : false ,
} ;
const checkWaterLevelsAndNotify = async ( customerId , tankName , tankLocation , fcmTokens ) => {
try {
// Fetch the tank details from the database
const tank = await Tank . findOne ( { customerId , tankName , tankLocation } ) ;
let waterLevelCheckInterval ; // To hold the interval ID
if ( ! tank ) {
console . error ( ` Tank not found: ${ tankName } at location ${ tankLocation } ` ) ;
return ;
}
const checkWaterLevel = async ( customerId , motorId , fcmToken , receiverTank ) => {
const currentWaterLevel = parseInt ( receiverTank . waterlevel , 10 ) ;
const tankCapacity = parseInt ( receiverTank . capacity . replace ( /,/g , '' ) , 10 ) ;
const currentWaterPercentage = ( currentWaterLevel / tankCapacity ) * 100 ;
// Extract the current water level and capacity
const currentWaterLevel = parseInt ( tank . waterlevel , 10 ) ;
const capacity = parseInt ( tank . capacity . replace ( /,/g , '' ) , 10 ) ;
// Calculate the water level percentage
const waterLevelPercentage = ( currentWaterLevel / capacity ) * 100 ;
// Thresholds for notifications
const thresholds = {
criticallyLow : 10 ,
veryLow : 20 ,
low : 30 ,
high : 70 ,
veryHigh : 80 ,
criticallyHigh : 85 ,
} ;
// Check for low water levels
if ( currentWaterPercentage <= 20 && ! notificationSentStatus . lowWater ) {
eventEmitter . emit ( 'sendLowWaterNotification' , fcmToken , ` Water level has dropped below 20%. ` ) ;
notificationSentStatus . lowWater = true ;
}
// Check water levels and send notifications
if ( waterLevelPercentage <= thresholds . criticallyLow && ! notificationSentStatus . criticallyLowWater ) {
eventEmitter . emit ( 'sendCriticalLowWaterNotification' , fcmTokens , tank ) ;
notificationSentStatus . criticallyLowWater = true ;
await Tank . updateOne ( { customerId , tankName : tank . tankName } , { $set : { notificationSentCritical : true } } ) ;
} else if ( waterLevelPercentage <= thresholds . veryLow && ! notificationSentStatus . veryLowWater ) {
eventEmitter . emit ( 'sendVeryLowWaterNotification' , fcmTokens , tank ) ;
notificationSentStatus . veryLowWater = true ;
await Tank . updateOne ( { customerId , tankName : tank . tankName } , { $set : { notificationSentVeryLow : true } } ) ;
} else if ( waterLevelPercentage <= thresholds . low && ! notificationSentStatus . lowWater ) {
eventEmitter . emit ( 'sendLowWaterNotification' , fcmTokens , tank ) ;
notificationSentStatus . lowWater = true ;
await Tank . updateOne ( { customerId , tankName : tank . tankName } , { $set : { notificationSentLow : true } } ) ;
}
// if (waterLevelPercentage <= thresholds.criticallyLow) {
// eventEmitter.emit('sendCriticalLowWaterNotification', fcmTokens, tank);
// await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentCritical: true } });
// } else if (waterLevelPercentage <= thresholds.veryLow) {
// eventEmitter.emit('sendVeryLowWaterNotification', fcmTokens, tank);
// await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentVeryLow: true } });
// } else if (waterLevelPercentage <= thresholds.low) {
// eventEmitter.emit('sendLowWaterNotification', fcmTokens, tank);
// await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentLow: true } });
// }
// else if (waterLevelPercentage >= thresholds.criticallyHigh) {
// eventEmitter.emit('sendCriticalHighWaterNotification', fcmTokens, tank);
// await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentCriticalHigh: true } });
// } else if (waterLevelPercentage >= thresholds.veryHigh) {
// eventEmitter.emit('sendVeryHighWaterNotification', fcmTokens, tank);
// await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentVeryHigh: true } });
// } else if (waterLevelPercentage >= thresholds.high) {
// eventEmitter.emit('sendHighWaterNotification', fcmTokens, tank);
// await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentHigh: true } });
// }
} catch ( error ) {
console . error ( ` Error checking water levels for tank ${ tankName } : ` , error ) ;
// Check for critically low water levels
if ( currentWaterPercentage <= 10 && ! notificationSentStatus . criticallyLowWater ) {
eventEmitter . emit ( 'sendCriticalLowWaterNotification' , fcmToken , ` Water level has dropped below 10%. ` ) ;
notificationSentStatus . criticallyLowWater = true ;
}
} ;
// const checkWaterLevelsAndNotify = async (customerId, tankName, tankLocation, fcmTokens) => {
// try {
// // Fetch the tank details from the database
// const tank = await Tank.findOne({ customerId, tankName, tankLocation });
// if (!tank) {
// console.error(`Tank not found: ${tankName} at location ${tankLocation}`);
// return;
// }
// // Extract the current water level and capacity
// const currentWaterLevel = parseInt(tank.waterlevel, 10);
// const capacity = parseInt(tank.capacity.replace(/,/g, ''), 10);
// // Calculate the water level percentage
// const waterLevelPercentage = (currentWaterLevel / capacity) * 100;
// // Thresholds for notifications
// const thresholds = {
// criticallyLow: 10,
// veryLow: 20,
// low: 30,
// high: 70,
// veryHigh: 80,
// criticallyHigh: 85,
// };
// // Check water levels and send notifications
// if (waterLevelPercentage <= thresholds.criticallyLow && !notificationSentStatus.criticallyLowWater) {
// eventEmitter.emit('sendCriticalLowWaterNotification', fcmTokens, tank);
// notificationSentStatus.criticallyLowWater = true;
// await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentCritical: true } });
// } else if (waterLevelPercentage <= thresholds.veryLow && !notificationSentStatus.veryLowWater) {
// eventEmitter.emit('sendVeryLowWaterNotification', fcmTokens, tank);
// notificationSentStatus.veryLowWater = true;
// await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentVeryLow: true } });
// } else if (waterLevelPercentage <= thresholds.low && !notificationSentStatus.lowWater) {
// eventEmitter.emit('sendLowWaterNotification', fcmTokens, tank);
// notificationSentStatus.lowWater = true;
// await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentLow: true } });
// }
// // if (waterLevelPercentage <= thresholds.criticallyLow) {
// // eventEmitter.emit('sendCriticalLowWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentCritical: true } });
// // } else if (waterLevelPercentage <= thresholds.veryLow) {
// // eventEmitter.emit('sendVeryLowWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentVeryLow: true } });
// // } else if (waterLevelPercentage <= thresholds.low) {
// // eventEmitter.emit('sendLowWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentLow: true } });
// // }
// // else if (waterLevelPercentage >= thresholds.criticallyHigh) {
// // eventEmitter.emit('sendCriticalHighWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentCriticalHigh: true } });
// // } else if (waterLevelPercentage >= thresholds.veryHigh) {
// // eventEmitter.emit('sendVeryHighWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentVeryHigh: true } });
// // } else if (waterLevelPercentage >= thresholds.high) {
// // eventEmitter.emit('sendHighWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentHigh: true } });
// // }
// } catch (error) {
// console.error(`Error checking water levels for tank ${tankName}:`, error);
// }
// };
const monitorWaterLevels = async ( ) => {
@ -2479,7 +2681,7 @@ exports.motorAction = async (req, reply) => {
? ` ${ req . body . manual _threshold _time } minutes `
: ` ${ req . body . manual _threshold _litres } litres ` ;
await checkWaterLevelsAndNotify ( customerId , tankName , receiverTank . tankLocation , fcmToken ) ;
// await checkWaterLevelsAndNotify(customerId, tankName, receiverTank.tankLocation, fcmToken);
if ( ! notificationSentStatus . motorStart ) {
eventEmitter . emit (
@ -2494,6 +2696,12 @@ exports.motorAction = async (req, reply) => {
) ;
notificationSentStatus . motorStart = true ; // Set flag to true to prevent duplicate notifications
}
// 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 } ,
@ -2507,30 +2715,8 @@ exports.motorAction = async (req, reply) => {
} 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,
// "APP"
// );
// Emit motorStop event
const totalWaterPumped = await calculateTotalPumpedWater ( customerId , motorId , start _instance _id ) ; // A function to calculate total water pumped
@ -2554,7 +2740,11 @@ exports.motorAction = async (req, reply) => {
"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." ) ;
}
@ -2695,7 +2885,7 @@ exports.motorAction = async (req, reply) => {
// clearInterval(motorIntervals[motorId]); // Clear interval
// delete motorIntervals[motorId];
await checkWaterLevelsAndNotify ( customerId , tankName , supplierTank . tankLocation , fcmToken ) ;
// 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
@ -5237,6 +5427,7 @@ exports.getBlockData = async (req, reply) => {
const mqtt = require ( 'mqtt' ) ;
const { setMaxIdleHTTPParsers } = require ( 'http' ) ;
const client = mqtt . connect ( 'mqtt://35.207.198.4:1883' ) ; // Connect to MQTT broker
client . on ( 'connect' , ( ) => {
@ -5353,17 +5544,43 @@ client.on('message', async (topic, message) => {
inputConnection . motor _on _type = "forced_manual" ;
inputConnection . startTime = currentTime ;
// Emit motor start notification with tankName
eventEmitter . emit (
"sendMotorStartNotification" ,
fcmToken , // FCM tokens
hw _Id , // Motor ID
inputConnection . water _level || 0 , // Water level
motorTank . blockName || "N/A" , // Block name
tankName , // Tank name
inputConnection . motor _on _type , // Motor on type
"threshold" , // Stop criteria
manual _threshold _time // Threshold time in mins
) ;
// eventEmitter.emit(
// "sendMotorStartNotification",
// fcmToken, // FCM tokens
// hw_Id, // Motor ID
// inputConnection.water_level || 0, // Water level
// motorTank.blockName || "N/A", // Block name
// tankName, // Tank name
// inputConnection.motor_on_type, // Motor on type
// "threshold", // Stop criteria
// manual_threshold_time // Threshold time in mins
// );
// Define logic to determine stopCriteria
let stopCriteria = "" ;
let highThreshold = 90 ; // Example high threshold value
let stopConditionMessage = "" ;
if ( stopCriteria === "manual" ) {
stopConditionMessage = ` Will stop at Manually \n ` ;
} else if ( stopCriteria === "highThreshold" ) {
stopConditionMessage = ` 🚨 Pump will stop when the water level reaches the high threshold of ${ highThreshold } %. \n ` ;
}
// Emit the event
try {
eventEmitter . emit ( "sendMotorStartNotification" ,
fcmToken ,
motorTank . blockName || "N/A" ,
motorTank . tankName ,
"Forced Manual" ,
stopCriteria ,
motorTank . typeOfWater || "Drinking Water" ,
highThreshold
) ;
} catch ( error ) {
console . error ( 'Error emitting motor start notification:' , error ) ;
}
}
@ -5371,18 +5588,20 @@ client.on('message', async (topic, message) => {
inputConnection . motor _stop _status = "1" ;
// Emit motor stop notification with tankName
eventEmitter . emit (
"sendMotorStopNotification" ,
fcmToken , // FCM tokens
hw _Id , // Motor ID
inputConnection . water _level || 0 , // Water level
motorTank . blockName || "N/A" , // Block name
tankName , // Tank name
inputConnection . motor _on _type // Motor on type
) ;
try {
eventEmitter . emit ( "sendMotorStopNotification" ,
fcmToken ,
motorTank . blockName || "N/A" ,
motorTank . tankName ,
"Forced Manual" ,
motorTank . typeOfWater || "Drinking Water"
) ;
} catch ( error ) {
console . error ( 'Error emitting motor stop notification:' , error ) ;
}
}
await motorTank . save ( ) ; // Save the updated tank
await motorTank . save ( ) ;
}
console . log ( 'Data processed successfully for hardwareId:' , hw _Id ) ; // Updated variable name
@ -5629,13 +5848,160 @@ console.log("this is for testing autopush,line located in tankscontroller")
// const calculateDailyConsumptionAndNotify = async () => {
// try {
// const today = moment().startOf("day");
// const yesterday = moment(today).subtract(1, "days");
// // Fetch all active users
// const activeUsers = await User.find({ });
// for (const user of activeUsers) {
// const { customerId, fcmIds } = user;
// // Fetch daily consumption for the customer
// const consumptions = await TankConsumptionOriginalSchema.find({
// customerId,
// time: {
// $gte: yesterday.format("DD-MMM-YYYY - HH:mm"),
// $lt: today.format("DD-MMM-YYYY - HH:mm"),
// },
// });
// // Calculate total consumption
// const totalConsumption = consumptions.reduce((total, record) => {
// return total + parseInt(record.consumption, 10);
// }, 0);
// // Prepare tank-wise consumption details
// const tankDetails = consumptions.map((record) => ({
// tankName: record.tankName,
// consumption: record.consumption,
// }));
// // Send notification
// const notificationTitle = "Daily Water Consumption Report";
// const notificationBody = `
// Total Consumption: ${totalConsumption} liters
// Tank Details: ${tankDetails
// .map((tank) => `${tank.tankName}: ${tank.consumption} liters`)
// .join(", ")}
// `;
// if (fcmIds && fcmIds.length > 0) {
// await sendNotification(fcmIds, notificationTitle, notificationBody);
// }
// }
// console.log("Daily consumption notifications sent successfully.");
// } catch (err) {
// console.error("Error sending daily consumption notifications:", err);
// }
// };
// cron.schedule("0 11:57 * * *", async () => {
// console.log("Starting daily consumption notification task...");
// await calculateDailyConsumptionAndNotify();
// });
// cron.schedule(
// "0 9 * * *",
// async () => {
// console.log("Starting daily consumption notification task...");
// await calculateDailyConsumptionAndNotify();
// },
// {
// timezone: "Asia/Kolkata", // Specify the timezone
// }
// );
// const calculateDailyConsumptionAndNotify = async () => {
// try {
// const today = moment().startOf("day");
// const yesterday = moment(today).subtract(1, "days");
// // Fetch all active users
// const activeUsers = await User.find({});
// for (const user of activeUsers) {
// const { customerId, fcmIds } = user;
// // Fetch daily consumption for the customer
// const consumptions = await TankConsumptionOriginalSchema.find({
// customerId,
// time: {
// $gte: yesterday.format("DD-MMM-YYYY - HH:mm"),
// $lt: today.format("DD-MMM-YYYY - HH:mm"),
// },
// });
// // Calculate total consumption by type of water and the water level percentage
// const consumptionSummary = consumptions.reduce((acc, record) => {
// const typeOfWater = record.typeOfWater; // Assuming this field exists
// const consumption = parseInt(record.consumption, 10);
// const waterLevel = parseInt(record.waterLevel, 10); // Assuming waterLevel is in percentage
// if (!acc[typeOfWater]) {
// acc[typeOfWater] = {
// totalConsumption: 0,
// tankDetails: [],
// totalWaterLevel: 0,
// count: 0,
// };
// }
// acc[typeOfWater].totalConsumption += consumption;
// acc[typeOfWater].totalWaterLevel += waterLevel;
// acc[typeOfWater].count += 1;
// acc[typeOfWater].tankDetails.push({
// tankName: record.tankName,
// consumption,
// waterLevel,
// });
// return acc;
// }, {});
// // Prepare notification body
// let notificationBody = "Daily Water Consumption Report:\n";
// for (const type in consumptionSummary) {
// const { totalConsumption, tankDetails, totalWaterLevel, count } = consumptionSummary[type];
// const averageWaterLevel = (totalWaterLevel / count).toFixed(2); // Calculate average water level
// console.log("averageWaterLevel",averageWaterLevel)
// console.log("totalConsumption",totalConsumption)
// notificationBody += `
// Type of Water: ${type}
// Total Consumption: ${totalConsumption} liters
// Average Water Level: ${averageWaterLevel}%
// `;
// console.log("noti---" ,notificationBody += `
// Type of Water: ${type}
// Total Consumption: ${totalConsumption} liters
// Average Water Level: ${averageWaterLevel}%
// `)
// }
// if (fcmIds && fcmIds.length > 0) {
// await sendNotification(fcmIds, "Daily Water Consumption Report", notificationBody);
// }
// }
// console.log("Daily consumption notifications sent successfully.");
// } catch (err) {
// console.error("Error sending daily consumption notifications:", err);
// }
// };
const calculateDailyConsumptionAndNotify = async ( ) => {
try {
const today = moment ( ) . startOf ( "day" ) ;
const yesterday = moment ( today ) . subtract ( 1 , "days" ) ;
// Fetch all active users
const activeUsers = await User . find ( { } ) ;
const activeUsers = await User . find ( { } ) ;
for ( const user of activeUsers ) {
const { customerId , fcmIds } = user ;
@ -5649,28 +6015,46 @@ const calculateDailyConsumptionAndNotify = async () => {
} ,
} ) ;
// Calculate total consumption
const totalConsumption = consumptions . reduce ( ( total , record ) => {
return total + parseInt ( record . consumption , 10 ) ;
} , 0 ) ;
// Calculate total consumption and capacities based on water type
let totalBoreConsumption = 0 ;
let totalDrinkingConsumption = 0 ;
let totalBoreCapacity = 0 ;
let totalDrinkingCapacity = 0 ;
for ( const record of consumptions ) {
const typeOfWater = record . typeOfWater ; // Assuming this field exists
const consumption = parseInt ( record . consumption , 10 ) ;
const capacity = parseInt ( record . capacity , 10 ) ; // Assuming capacity field exists
if ( typeOfWater === "bore" || typeOfWater === "Bore Water" ) {
totalBoreConsumption += consumption ;
totalBoreCapacity += capacity ;
} else if ( typeOfWater === "drinking" || typeOfWater === "Drinking Water" ) {
totalDrinkingConsumption += consumption ;
totalDrinkingCapacity += capacity ;
}
}
// Prepare tank-wise consumption details
const tankDetails = consumptions . map ( ( record ) => ( {
tankName : record . tankName ,
consumption : record . consumption ,
} ) ) ;
// Calculate percentages
const boreConsumptionPercentage = totalBoreCapacity
? ( ( totalBoreConsumption / totalBoreCapacity ) * 100 ) . toFixed ( 2 )
: 0 ;
const drinkingConsumptionPercentage = totalDrinkingCapacity
? ( ( totalDrinkingConsumption / totalDrinkingCapacity ) * 100 ) . toFixed ( 2 )
: 0 ;
// Send notification
const notificationTitle = "Daily Water Consumption Report" ;
const notificationBody = `
Total Consumption : $ { totalConsumption } liters
Tank Details : $ { tankDetails
. map ( ( tank ) => ` ${ tank . tankName } : ${ tank . consumption } liters ` )
. join ( ", " ) }
` ;
// Prepare notification body
const reportDate = yesterday . format ( "DD-MMM-YYYY" ) ;
let notificationBody = ` Daily Water Consumption Report for ${ reportDate } : \n ` ;
notificationBody += ` Total Bore Consumption: ${ totalBoreConsumption } liters \n ` ;
notificationBody += ` Bore Water Consumption Percentage: ${ boreConsumptionPercentage } % \n ` ;
notificationBody += ` Total Drinking Consumption: ${ totalDrinkingConsumption } liters \n ` ;
notificationBody += ` Drinking Water Consumption Percentage: ${ drinkingConsumptionPercentage } % \n ` ;
// Send notification if FCM IDs are present
if ( fcmIds && fcmIds . length > 0 ) {
await sendNotification ( fcmIds , notificationTitle , notificationBody ) ;
await sendNotification ( fcmIds , "Daily Water Consumption Report" , notificationBody ) ;
}
}
@ -5680,12 +6064,7 @@ const calculateDailyConsumptionAndNotify = async () => {
}
} ;
// cron.schedule("0 11:57 * * *", async () => {
// console.log("Starting daily consumption notification task...");
// await calculateDailyConsumptionAndNotify();
// });
// Schedule the cron job to run daily at 9 AM
cron . schedule (
"0 9 * * *" ,
async ( ) => {
@ -5696,3 +6075,92 @@ cron.schedule(
timezone : "Asia/Kolkata" , // Specify the timezone
}
) ;
const calculateConsumptionAndNotify = async ( ) => {
try {
const now = moment ( ) ; // Current time
const sixHoursAgo = moment ( now ) . subtract ( 6 , 'hours' ) . startOf ( 'hour' ) ; // 6 hours ago
// Fetch all active users
const activeUsers = await User . find ( { } ) ;
for ( const user of activeUsers ) {
const { customerId , fcmIds } = user ;
// Fetch consumption records for the last 6 hours
const consumptions = await TankConsumptionOriginalSchema . find ( {
customerId ,
time : {
$gte : sixHoursAgo . format ( "DD-MMM-YYYY - HH:mm" ) ,
$lt : now . format ( "DD-MMM-YYYY - HH:mm" ) ,
} ,
} ) ;
// Prepare notification body
let notificationBody = ` Water Consumption Report (From ${ sixHoursAgo . format (
"hh:mm A"
) } to $ { now . format ( "hh:mm A" ) } ) : \ n ` ;
const tankDetails = { } ;
// Aggregate consumption data by tank
for ( const record of consumptions ) {
const tankName = record . tankName ; // Assuming this field exists
const tankLocation = record . tankLocation ; // Assuming this field exists
const consumption = parseInt ( record . consumption , 10 ) ; // Liters consumed
const typeOfWater = record . typeOfWater ; // Type of water (e.g., bore, drinking)
const tankCapacity = parseInt ( record . capacity , 10 ) ; // Tank capacity in liters
if ( ! tankDetails [ tankName ] ) {
tankDetails [ tankName ] = {
tankLocation ,
totalConsumption : 0 ,
typeOfWater ,
tankCapacity ,
} ;
}
tankDetails [ tankName ] . totalConsumption += consumption ;
}
// Format tank details for the notification
for ( const tankName in tankDetails ) {
const {
tankLocation ,
totalConsumption ,
typeOfWater ,
tankCapacity ,
} = tankDetails [ tankName ] ;
const consumptionPercentage = tankCapacity
? ( ( totalConsumption / tankCapacity ) * 100 ) . toFixed ( 2 )
: 0 ;
notificationBody +=
` Tank Name: ${ tankName } \n ` +
` Location: ${ tankLocation } \n ` +
` Total Consumption: ${ totalConsumption } liters ${ consumptionPercentage } % \n ` +
` Type of Water: ${ typeOfWater } ` ;
}
// Send notification if FCM IDs are present
if ( fcmIds && fcmIds . length > 0 ) {
await sendNotification ( fcmIds , "Water Consumption Report" , notificationBody ) ;
}
}
console . log ( "Consumption notifications sent successfully." ) ;
} catch ( err ) {
console . error ( "Error sending consumption notifications:" , err ) ;
}
} ;
// Schedule notifications at 6 AM, 12 PM, 6 PM, and 12 AM
cron . schedule (
"0 6,12,18,0 * * *" , // Cron expression for the required times
async ( ) => {
console . log ( "Starting scheduled consumption notification task..." ) ;
await calculateConsumptionAndNotify ( ) ;
} ,
{
timezone : "Asia/Kolkata" , // Specify the timezone
}
) ;