diff --git a/src/controllers/departmentController.js b/src/controllers/departmentController.js index b3302718..a24b7235 100644 --- a/src/controllers/departmentController.js +++ b/src/controllers/departmentController.js @@ -427,26 +427,53 @@ exports.addDepartment = async (request, reply) => { exports.getallCitiesData = async (req, reply) => { try { console.log("Fetching all cities..."); // Debug log - const cities = await Deparments.distinct('city'); // Use distinct to get unique cities - console.log("Cities fetched:", cities); // Log the fetched cities - reply.send({ status_code: 200, data: cities, count: cities.length }); + const cities = await City.distinct('city'); // Fetch distinct city names from the database + + // Normalize the city names to avoid duplicates + const normalizedCities = [...new Set(cities.map(city => city.trim().toUpperCase()))]; + + console.log("Cities fetched:", normalizedCities); // Log the cleaned cities + reply.send({ status_code: 200, data: normalizedCities, count: normalizedCities.length }); } catch (err) { console.error("Error fetching cities:", err); // Log the error for debugging throw boom.boomify(err); } }; + exports.getallZonesData = async (req, reply) => { try { console.log("Fetching all zones..."); // Debug log - const zones = await Deparments.distinct('zone'); - reply.send({ status_code: 200, data: zones, count: zones.length }); + const zones = await City.distinct('zone'); // Fetch distinct zone names from the database + + // Normalize the zone names to avoid duplicates + const normalizedZones = [...new Set(zones.map(zone => zone.trim().toUpperCase()))]; + + console.log("Zones fetched:", normalizedZones); // Log the cleaned zones + reply.send({ status_code: 200, data: normalizedZones, count: normalizedZones.length }); } catch (err) { - console.error("Error fetching cities:", err); // Log the error for debugging + console.error("Error fetching zones:", err); // Log the error for debugging throw boom.boomify(err); } }; + exports.getallLocationData = async (req, reply) => { + try { + console.log("Fetching all locations..."); // Debug log + const locations = await City.distinct('location'); // Fetch distinct locations from the database + + // Normalize the location names to uppercase and remove duplicates + const normalizedLocations = [...new Set(locations.map(location => location.trim().toUpperCase()))]; + + console.log("Locations fetched:", normalizedLocations); // Log the cleaned locations + reply.send({ status_code: 200, data: normalizedLocations, count: normalizedLocations.length }); + } catch (err) { + console.error("Error fetching locations:", err); // Log the error for debugging + throw boom.boomify(err); + } + }; + + exports.deletedepartmentInfo = async (req, reply) => { try { const departmentId = req.params.departmentId; diff --git a/src/controllers/tanksController.js b/src/controllers/tanksController.js index d31b37c1..5acde592 100644 --- a/src/controllers/tanksController.js +++ b/src/controllers/tanksController.js @@ -1787,39 +1787,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) => { @@ -1856,52 +1856,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); @@ -1912,6 +2061,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 { @@ -1985,12 +2159,21 @@ const sendNotification = async (fcmIds, title, body) => { notification: { title, body }, token, data: { - 'target': '/route_navigation', + 'target': '/screen', }, }); 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}`); + } } }); @@ -2342,71 +2525,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 () => { @@ -2508,7 +2710,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( @@ -2523,6 +2725,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 }, @@ -2536,30 +2744,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 @@ -2583,7 +2769,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."); } @@ -2724,7 +2914,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 @@ -5271,142 +5461,166 @@ exports.getBlockData = async (req, reply) => { // } // } // }); -const mqtt = require('mqtt'); -// Connect to MQTT broker -const client = mqtt.connect('mqtt://35.207.198.4:1883'); +const mqtt = require('mqtt'); +const client = mqtt.connect('mqtt://35.207.198.4:1883'); // Connect to MQTT broker client.on('connect', () => { console.log('Connected to MQTT broker'); - - // Subscribe to all topics under water/iot-data/ - client.subscribe('water/iot-data/#', (err) => { + client.subscribe('water/iot-data', (err) => { if (err) { console.error('Error subscribing to topic:', err); } else { - console.log('Subscribed to water/iot-data/#'); + console.log('Subscribed to water/iot-data topic'); } }); }); -// Handle incoming MQTT messages +// Handling incoming MQTT messages client.on('message', async (topic, message) => { - try { - const data = JSON.parse(message.toString()); - const topicParts = topic.split('/'); // Split the topic to get the hardwareId - const hardwareId = topicParts[2]; // Extract hardwareId from topic - - const { Motor_status, tanks } = data.objects; - - // Process data for the specific device - await processDeviceData(hardwareId, Motor_status, tanks); - } catch (err) { - console.error('Error processing message:', err.message); - } -}); - -// Function to process data for each device -async function processDeviceData(hw_Id, Motor_status, tanks) { - try { - const currentDate = new Date(); - const date = currentDate.toISOString(); // ISO string for date - const time = moment().tz('Asia/Kolkata').format('HH:mm:ss'); // Time in 'HH:mm:ss' - - // Prepare tank documents - const tankDocuments = tanks.map(tank => ({ - tankhardwareId: tank.Id, - tankHeight: tank.level, - date, - time - })); + console.log(`Message received on topic ${topic}:`, message.toString()); - // Save IoT data for the device - const iotTankData = new IotData({ - hardwareId: hw_Id, - Motor_status, - tanks: tankDocuments, - date, - time - }); - await iotTankData.save(); - - // Delete excess records (keep only the latest three records) - const recordsToKeep = 3; - const recordsToDelete = await IotData.find({ hardwareId: hw_Id }) - .sort({ date: -1, time: -1 }) - .skip(recordsToKeep); - - for (const record of recordsToDelete) { - await record.remove(); - } - - // Update water levels for tanks - for (const tank of tanks) { - const { Id: tankhardwareId, level: tankHeight } = tank; - - const existingTank = await Tank.findOne({ hardwareId: hw_Id, tankhardwareId }); - if (!existingTank) continue; + if (topic === 'water/iot-data') { + try { + const data = JSON.parse(message.toString()); + const { hw_Id, Motor_status, tanks } = data.objects; // Updated variable names according to new format + + // Get the current date and time in the required format + const currentDate = new Date(); + const date = currentDate.toISOString(); // ISO string for date + const time = currentDate.toLocaleTimeString('en-IN', { hour12: false, timeZone: 'Asia/Kolkata' }); // Time in 'HH:MM:SS' + + // Create array of tank documents with current date and time + const tankDocuments = tanks.map(tank => ({ + tankhardwareId: tank.Id, // Updated to match the new format + tankHeight: tank.level, // Updated to match the new format + date, + time + })); - const customerId = existingTank.customerId; - const tank_name = existingTank.tankName; + - const tankHeightInCm = parseInt(existingTank.height.replace(/,/g, ''), 10) * 30.48; - const waterLevelHeight = tankHeightInCm - tankHeight; - const waterCapacityPerCm = parseInt(existingTank.waterCapacityPerCm.replace(/,/g, ''), 10); - const waterLevel = parseInt(waterLevelHeight * waterCapacityPerCm, 10); + // Save IoT data for the received tanks + const iotTankData = new IotData({ + hardwareId: hw_Id, // Updated variable name + Motor_status, + tanks: tankDocuments, + date, + time + }); + await iotTankData.save(); - if (tankHeight > 0 && waterLevel >= 0) { - existingTank.waterlevel = waterLevel; - await existingTank.save(); + // Delete excess records (keep only the latest three records) + const recordsToKeep = 3; + const recordsToDelete = await IotData.find({ hardwareId: hw_Id }) // Updated variable name + .sort({ date: -1, time: -1 }) + .skip(recordsToKeep); - // Update linked tanks - for (const outputConnection of existingTank.connections.outputConnections) { - const linkedTank = await Tank.findOne({ - customerId, - tankName: outputConnection.outputConnections, - tankLocation: outputConnection.output_type - }); + for (const record of recordsToDelete) { + await record.remove(); + } - if (linkedTank) { - for (const inputConnection of linkedTank.connections.inputConnections) { - if (inputConnection.inputConnections === tank_name) { - inputConnection.water_level = waterLevel; - await linkedTank.save(); + // Process each tank to update water level and connections + for (const tank of tanks) { + const { Id: tankhardwareId, level: tankHeight } = tank; // Updated to match the new format + // Find the corresponding tank in the Tank schema using hardwareId and tankhardwareId + const existingTank = await Tank.findOne({ hardwareId: hw_Id, tankhardwareId }); // Updated variable name + if (!existingTank) continue; + + const customerId = existingTank.customerId; + const tank_name = existingTank.tankName; + + // Calculate water level using tank height and capacity + const tankHeightInCm = (parseInt(existingTank.height.replace(/,/g, ''), 10)) * 30.48; // Convert height to cm + const tank_height = parseInt(tankHeightInCm.toFixed(0), 10); + const waterLevelHeight = tank_height - tankHeight; + const waterCapacityPerCm = parseInt(existingTank.waterCapacityPerCm.replace(/,/g, ''), 10); + + const waterLevel = parseInt(waterLevelHeight * waterCapacityPerCm, 10); // Calculated water level + + // Update water level in the existing tank + console.log(tankHeight,"this is located in tank controllers at iot-data mqtt sub ") + if (tankHeight>0 && waterLevel >= 0) { + existingTank.waterlevel = waterLevel; + await existingTank.save(); + + // Update linked tanks (input/output connections) + for (const outputConnection of existingTank.connections.outputConnections) { + const linkedTank = await Tank.findOne({ customerId, tankName: outputConnection.outputConnections, tankLocation: outputConnection.output_type }); + if (linkedTank) { + for (const inputConnection of linkedTank.connections.inputConnections) { + if (inputConnection.inputConnections === tank_name) { + inputConnection.water_level = waterLevel; // Update water level for linked tank + await linkedTank.save(); // Save updated linked tank + } } } } } } - } - // Update motor status - const motorTank = await Tank.findOne({ "connections.inputConnections.motor_id": hw_Id }); - if (motorTank) { - const inputConnection = motorTank.connections.inputConnections.find(conn => conn.motor_id === hw_Id); + // Update motor status + const status = Motor_status; + const motorTank = await Tank.findOne({ "connections.inputConnections.motor_id": hw_Id }); // Updated variable name - if (inputConnection) { - inputConnection.motor_status = Motor_status; + if (!motorTank) { + console.log('Motor not found for the specified motor_id'); + return; + } - if (inputConnection.motor_stop_status === "1" && Motor_status === 2 && inputConnection.motor_on_type !== "forced_manual") { + // Find the inputConnection for the motor and update motor status + const inputConnection = motorTank.connections.inputConnections.find(conn => conn.motor_id === hw_Id); // Updated variable name + if (inputConnection) { + inputConnection.motor_status = status; // Update motor status + + const tankName = motorTank.tankName; + console.log(tankName,"tankName") + if (inputConnection.motor_stop_status === "1" && status === 2 && inputConnection.motor_on_type !== "forced_manual") { + + const currentTime = moment().tz('Asia/Kolkata').format('DD-MMM-YYYY - HH:mm'); inputConnection.motor_stop_status = "2"; inputConnection.motor_on_type = "forced_manual"; - inputConnection.startTime = moment().tz('Asia/Kolkata').format('DD-MMM-YYYY - HH:mm'); + 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 + ); + } - - if (inputConnection.motor_stop_status === "2" && Motor_status === 1) { + + if (inputConnection.motor_stop_status === "2" && status === 1) { inputConnection.motor_stop_status = "1"; - } - await motorTank.save(); + // 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 + ); + } + + await motorTank.save(); // Save the updated tank } - } - console.log(`Data processed successfully for hardwareId: ${hw_Id}`); - } catch (err) { - console.error(`Error processing data for hardwareId ${hw_Id}:`, err.message); - } -} + console.log('Data processed successfully for hardwareId:', hw_Id); // Updated variable name + } catch (err) { + console.error('Error processing message:', err.message); + } + } +}); @@ -5644,13 +5858,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; @@ -5664,28 +6025,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; - // 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(", ")} - `; + const drinkingConsumptionPercentage = totalDrinkingCapacity + ? ((totalDrinkingConsumption / totalDrinkingCapacity) * 100).toFixed(2) + : 0; + // 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); } } @@ -5695,12 +6074,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 () => { @@ -5711,3 +6085,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 + } +); diff --git a/src/routes/departmentRoute.js b/src/routes/departmentRoute.js index 5b51b0fd..9ebc96a7 100644 --- a/src/routes/departmentRoute.js +++ b/src/routes/departmentRoute.js @@ -157,8 +157,8 @@ module.exports = function (fastify, opts, next) { url: "/api/departmentSignup", schema: { tags: ["Department"], - description: "This is for creating a new Department Account", - summary: "This is for creating a new Department Account", + description: "This is for creating a new Team Member Account", + summary: "This is for creating a new Ream Member Account", body: { type: "object", //required: ["phone", "username", "password", "role"], // Add role to required fields @@ -239,8 +239,8 @@ module.exports = function (fastify, opts, next) { fastify.get("/api/getallcitiesdata", { schema: { tags: ["Department"], - description: "This is for Get all Cities Data", - summary: "This is for to Get all Cities Data", + description: "This is for Get all Cities Data for City Schema", + summary: "This is for to Get all Cities Data for City Schema", security: [ { @@ -254,8 +254,8 @@ module.exports = function (fastify, opts, next) { fastify.get("/api/getallzonesdata", { schema: { tags: ["Department"], - description: "This is for Get all Zones Data", - summary: "This is for to Get all Zones Data", + description: "This is for Get all Zones Data for City Schema", + summary: "This is for to Get all Zones Data for City Schema", security: [ { @@ -266,6 +266,23 @@ module.exports = function (fastify, opts, next) { //preHandler: fastify.auth([fastify.authenticate]), handler: departmentController.getallZonesData, }); + + fastify.get("/api/getalllocationsdata", { + schema: { + tags: ["Department"], + description: "This is for Get all Locations Data for City Schema", + summary: "This is for to Get all Locations Data for City Schema", + + security: [ + { + basicAuth: [], + }, + ], + }, + //preHandler: fastify.auth([fastify.authenticate]), + handler: departmentController.getallLocationData, + }); + fastify.delete("/api/deletedepartment/:departmentId", { schema: { description: "Delete a Department by departmentId", diff --git a/src/routes/tanksRoute.js b/src/routes/tanksRoute.js index 6ba0858f..4a904302 100644 --- a/src/routes/tanksRoute.js +++ b/src/routes/tanksRoute.js @@ -865,7 +865,7 @@ module.exports = function (fastify, opts, next) { startDate:{ type: "string" }, stopDate:{type:"string"}, block:{type:"string"}, - typeofwater:{type:"string"}, + },