From f0e897076ba557692fc804ddbecb862a967e4b30 Mon Sep 17 00:00:00 2001 From: Varun Date: Tue, 21 Jan 2025 11:42:34 +0530 Subject: [PATCH 1/2] changes in motoraction and added all motor is on functionality --- src/controllers/tanksController.js | 142 ++++++++++++++++++++++++----- src/models/tanks.js | 1 + 2 files changed, 121 insertions(+), 22 deletions(-) diff --git a/src/controllers/tanksController.js b/src/controllers/tanksController.js index 8bf74b93..a2be8b22 100644 --- a/src/controllers/tanksController.js +++ b/src/controllers/tanksController.js @@ -216,24 +216,29 @@ exports.getTank = async (req, reply) => { const transformedDocs = docs.map((tank) => { const inputConnections = tank.connections?.inputConnections || []; + + // Count switches const switchCount = inputConnections.reduce((count, connection) => { return count + (connection.inputismotor === true ? 1 : 0); }, 0); + totalSwitchCount += switchCount; - totalSwitchCount += switchCount; // Accumulate the switch_count - - // Check if the tank has need_sensor set to "yes" + // Count sensors if (tank.need_sensor?.toLowerCase() === "yes") { totalSensorCount++; } - // Add the switch_count field inside connections + // Determine all_motor_status + const allMotorStatus = inputConnections.some(connection => connection.motor_status === "2"); + + // Add switch_count and all_motor_status to the response return { ...tank.toObject(), // Convert Mongoose document to plain object connections: { ...tank.connections, switch_count: switchCount, }, + all_motor_status: allMotorStatus, // Add all_motor_status field }; }); @@ -241,8 +246,8 @@ exports.getTank = async (req, reply) => { status_code: 200, data: transformedDocs, count: transformedDocs.length, - total_switch_count: totalSwitchCount, // Add the total switch count - total_sensor_count: totalSensorCount, // Add the total sensor count + total_switch_count: totalSwitchCount, + total_sensor_count: totalSensorCount, }); }) .catch((err) => { @@ -2262,22 +2267,8 @@ console.log(fcmToken) // const stopMessage = `The motor supplying water to '${tankName}' in block '${blockName}' was stopped manually at ${stopTime}.`; // eventEmitter.emit("sendMotorStopNotification", fcmToken, stopMessage); - await Tank.updateOne( - { customerId, "connections.inputConnections.motor_id": motorId }, - { - $set: { - "connections.inputConnections.$.motor_stop_status": motorStopStatus, - "connections.inputConnections.$.motor_on_type": "manual", - "connections.inputConnections.$.stopTime": stopTime - } - } - ); - - // Clear intervals if any - if (motorIntervals[motorId]) { - clearInterval(motorIntervals[motorId]); - delete motorIntervals[motorId]; - } + + eventEmitter.emit( "motorStop", fcmToken, @@ -2456,7 +2447,114 @@ console.log(fcmToken) }, 30000); // Check every minute } + }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() }); + + const newMotorData = new MotorData({ + customerId: customerId, + motor_id: motorId, + start_instance_id: start_instance_id, + supplierTank: req.body.from, + receiverTank: req.body.to, + supplier_type: req.body.from_type, + receiver_type: req.body.to_type, + startTime: req.body.startTime, + receiverInitialwaterlevel:parseInt(receiver_tank_info7.waterlevel, 10), + supplierInitialwaterlevel:parseInt(supplier_tank_info7.waterlevel, 10) + }); + await newMotorData.save(); + // If threshold type is percentage, calculate percentage threshold + const receiver_tank_info = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() }); + const supplier_tank_info = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() }); + if (!receiver_tank_info) { + throw new Error("Receiver tank not found."); + } + if (!supplier_tank_info) { + throw new Error("Supplierr tank not found."); + } + const supplier_capacity = parseInt(supplier_tank_info.capacity, 10); + const supplier_waterLevel = parseInt(supplier_tank_info.waterlevel, 10); + + const capacity = parseInt(receiver_tank_info.capacity, 10); + const waterLevel = parseInt(receiver_tank_info.waterlevel, 10); + const desired_percentage = parseInt(req.body.manual_threshold_litres.replace(/,/g, ''), 10); + + console.log(desired_percentage) + const threshold_water_level = waterLevel+desired_percentage; + + const supplier_threshold = supplier_waterLevel-desired_percentage + console.log(supplier_threshold,"supplier_threshold") + 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 }, + { $set: { [`connections.inputConnections.${index}.manual_threshold_percentage`]: supplier_threshold.toString(), [`connections.inputConnections.${index}.startTime`]: req.body.startTime } } + ); + } + } + + + + // Update water level threshold + + + // Start monitoring water level based on threshold percentage + motorIntervals[motorId] = setInterval(async () => { + // Check if water level has reached the threshold percentage + const supplier_tank_info1 = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() }); + const current_water_level = parseInt(supplier_tank_info1.waterlevel, 10); + if (current_water_level <= supplier_threshold) { + // Stop the motor pump + await Tank.updateOne( + { customerId, "connections.inputConnections.motor_id": motorId }, + { + $set: { + "connections.inputConnections.$.motor_stop_status": "1", + + "connections.inputConnections.$.threshold_type": null, + "connections.inputConnections.$.manual_threshold_time": null, + "connections.inputConnections.$.manual_threshold_percentage": null + } + } + ); + clearInterval(motorIntervals[motorId]); // Clear interval + delete motorIntervals[motorId]; + + this.publishMotorStopStatus(motorId, "1"); + 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 stopTime = formatDate(new Date()); + + await MotorData.updateOne( + { customerId, motor_id: motorId, start_instance_id: start_instance_id }, + { + $set: { + stopTime:stopTime, + receiverfinalwaterlevel: receiverFinalWaterLevel.toString(), + quantity_delivered: quantityDelivered.toString() + } + } + ); + } + } + }, 20000); } + + } + + } // Respond with success message reply.code(200).send({ message: `Motor ${action === "start" ? "started" : "stopped"} successfully.` }); diff --git a/src/models/tanks.js b/src/models/tanks.js index 9118b338..86506184 100644 --- a/src/models/tanks.js +++ b/src/models/tanks.js @@ -61,6 +61,7 @@ const tanksSchema = new mongoose.Schema({ notificationSentCriticalHigh: { type: Boolean }, notificationSentVeryHigh: { type: Boolean }, notificationSentHigh: { type: Boolean }, + all_motor_status: { type: Boolean }, connections: { source: { type: String }, From 2d8e1e21d767bfc786d7298a0ae218d003a5178e Mon Sep 17 00:00:00 2001 From: Bhaskar Date: Tue, 21 Jan 2025 12:21:43 +0530 Subject: [PATCH 2/2] schedule time based notifications to send all tanks details --- node_modules/.package-lock.json | 6 +- package-lock.json | 14 +-- package.json | 2 +- src/controllers/tanksController.js | 168 ++++++++++++++++++++--------- 4 files changed, 130 insertions(+), 60 deletions(-) diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json index dc790f3a..598842f9 100644 --- a/node_modules/.package-lock.json +++ b/node_modules/.package-lock.json @@ -9243,9 +9243,9 @@ "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" }, "node_modules/node-cron": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.2.tgz", - "integrity": "sha512-iP8l0yGlNpE0e6q1o185yOApANRe47UPbLf4YxfbiNHt/RU5eBcGB/e0oudruheSf+LQeDMezqC5BVAb5wwRcQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.3.tgz", + "integrity": "sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==", "dependencies": { "uuid": "8.3.2" }, diff --git a/package-lock.json b/package-lock.json index ec50fc16..e168fafe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,7 +55,7 @@ "mqtt": "^5.10.1", "multer": "^1.4.5-lts.1", "mv": "^2.1.1", - "node-cron": "^3.0.2", + "node-cron": "^3.0.3", "node-schedule": "^2.1.1", "nodemon": "^2.0.20", "nunjucks": "^3.2.3", @@ -9321,9 +9321,9 @@ "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" }, "node_modules/node-cron": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.2.tgz", - "integrity": "sha512-iP8l0yGlNpE0e6q1o185yOApANRe47UPbLf4YxfbiNHt/RU5eBcGB/e0oudruheSf+LQeDMezqC5BVAb5wwRcQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.3.tgz", + "integrity": "sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==", "dependencies": { "uuid": "8.3.2" }, @@ -20052,9 +20052,9 @@ "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" }, "node-cron": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.2.tgz", - "integrity": "sha512-iP8l0yGlNpE0e6q1o185yOApANRe47UPbLf4YxfbiNHt/RU5eBcGB/e0oudruheSf+LQeDMezqC5BVAb5wwRcQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.3.tgz", + "integrity": "sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==", "requires": { "uuid": "8.3.2" } diff --git a/package.json b/package.json index b20cf784..145aed2d 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "mqtt": "^5.10.1", "multer": "^1.4.5-lts.1", "mv": "^2.1.1", - "node-cron": "^3.0.2", + "node-cron": "^3.0.3", "node-schedule": "^2.1.1", "nodemon": "^2.0.20", "nunjucks": "^3.2.3", diff --git a/src/controllers/tanksController.js b/src/controllers/tanksController.js index 6e429ad1..27aa6fd7 100644 --- a/src/controllers/tanksController.js +++ b/src/controllers/tanksController.js @@ -2203,20 +2203,20 @@ console.log(fcmToken) // Schedule a task to send a notification when the threshold time is reached - motorIntervals[motorId] = setTimeout(async () => { - try { - // Perform threshold time logic (e.g., notification, motor stop) - console.log(`Threshold time of ${manual_threshold_time} minutes reached for motor ${motorId}`); - await Tank.updateOne( - { customerId, "connections.inputConnections.motor_id": motorId }, - { $set: { "connections.inputConnections.$.motor_stop_status": "1" } } - ); - clearTimeout(motorIntervals[motorId]); // Clear timeout - delete motorIntervals[motorId]; - } catch (error) { - console.error("Error in threshold time handling:", error); - } - }, thresholdTimeMs); + // motorIntervals[motorId] = setTimeout(async () => { + // try { + // // Perform threshold time logic (e.g., notification, motor stop) + // console.log(`Threshold time of ${manual_threshold_time} minutes reached for motor ${motorId}`); + // await Tank.updateOne( + // { customerId, "connections.inputConnections.motor_id": motorId }, + // { $set: { "connections.inputConnections.$.motor_stop_status": "1" } } + // ); + // clearTimeout(motorIntervals[motorId]); // Clear timeout + // delete motorIntervals[motorId]; + // } catch (error) { + // console.error("Error in threshold time handling:", error); + // } + // }, thresholdTimeMs); const stopCriteria = motorOnType === "time" ? `${req.body.manual_threshold_time} minutes` @@ -2258,27 +2258,27 @@ console.log(fcmToken) // Schedule threshold check // const thresholdTimeMs = manual_threshold_time * 60 * 1000; - motorIntervals[motorId] = setTimeout(async () => { - try { - // const stopMessage = `Threshold time of ${manual_threshold_time} minutes reached for motor supplying water to '${tankName}' in block '${blockName}'.`; - // eventEmitter.emit('sendThresholdTimeNotification', fcmToken, stopMessage); - - await Tank.updateOne( - { customerId, "connections.inputConnections.motor_id": motorId }, - { - $set: { - "connections.inputConnections.$.motor_stop_status": "1", - "connections.inputConnections.$.manual_threshold_time": null, - "connections.inputConnections.$.threshold_type": null, - } - } - ); - - delete motorIntervals[motorId]; - } catch (error) { - console.error("Error during threshold handling:", error); - } - }, thresholdTimeMs); + // motorIntervals[motorId] = setTimeout(async () => { + // try { + // // const stopMessage = `Threshold time of ${manual_threshold_time} minutes reached for motor supplying water to '${tankName}' in block '${blockName}'.`; + // // eventEmitter.emit('sendThresholdTimeNotification', fcmToken, stopMessage); + + // await Tank.updateOne( + // { customerId, "connections.inputConnections.motor_id": motorId }, + // { + // $set: { + // "connections.inputConnections.$.motor_stop_status": "1", + // "connections.inputConnections.$.manual_threshold_time": null, + // "connections.inputConnections.$.threshold_type": null, + // } + // } + // ); + + // delete motorIntervals[motorId]; + // } catch (error) { + // console.error("Error during threshold handling:", error); + // } + // }, thresholdTimeMs); reply.code(200).send({ message: "Motor started successfully." }); // Schedule water level checks after motor start @@ -2317,23 +2317,23 @@ console.log(fcmToken) motorOnType ); - await Tank.updateOne( - { customerId, "connections.inputConnections.motor_id": motorId }, - { - $set: { - "connections.inputConnections.$.motor_stop_status": "1", - "connections.inputConnections.$.motor_on_type": "manual", - } - } - ); + // await Tank.updateOne( + // { customerId, "connections.inputConnections.motor_id": motorId }, + // { + // $set: { + // "connections.inputConnections.$.motor_stop_status": "1", + // "connections.inputConnections.$.motor_on_type": "manual", + // } + // } + // ); // const stopMessage = `Motor supplying water to '${tankName}' in block '${blockName}' stopped manually at ${stopTime}.`; // eventEmitter.emit('sendMotorStopNotification', fcmToken, stopMessage); - if (motorIntervals[motorId]) { - clearTimeout(motorIntervals[motorId]); - delete motorIntervals[motorId]; - } + // if (motorIntervals[motorId]) { + // clearTimeout(motorIntervals[motorId]); + // delete motorIntervals[motorId]; + // } } else { throw new Error("Invalid action provided."); @@ -5340,4 +5340,74 @@ async function removeDuplicates () { // Run the remove duplicates function // removeDuplicates(); -console.log("this is for testing autopush,line located in tankscontroller") \ No newline at end of file +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 + } +); \ No newline at end of file