diff --git a/package.json b/package.json index 3aa75a85..aef128eb 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Arminta Tank API", "main": "index.js", "scripts": { - "start": "./node_modules/nodemon/bin/nodemon.js ./src/index.js", + "start": "nodemon ./src/index.js", "start:dev": "nodemon ./src/index.js" }, "author": "", @@ -17,7 +17,7 @@ "@fastify/view": "^7.1.2", "@google-cloud/storage": "^6.10.1", "adminjs": "^6.7.2", - "axios": "^1.3.3", + "axios": "^1.7.2", "bcrypt": "^5.0.0", "body-parser": "^1.19.0", "boom": "^7.3.0", @@ -40,6 +40,7 @@ "fastify-static": "^4.7.0", "fastify-swagger": "^5.2.0", "file-type": "^18.5.0", + "firebase-admin": "^12.2.0", "form-data": "^2.3.3", "formidable": "^2.1.1", "fs": "^0.0.1-security", diff --git a/src/arminta-water-notification-firebase-adminsdk-mhjrk-c90bbe0594.json b/src/arminta-water-notification-firebase-adminsdk-mhjrk-c90bbe0594.json new file mode 100644 index 00000000..7fbb9ecb --- /dev/null +++ b/src/arminta-water-notification-firebase-adminsdk-mhjrk-c90bbe0594.json @@ -0,0 +1,13 @@ +{ + "type": "service_account", + "project_id": "arminta-water-notification", + "private_key_id": "c90bbe0594640e5f30977820c1f31fe5b2e87b3c", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCj3mnqTMlUVGy/\nQ5wRwczOk95L0TNQPdKeiDwLihQfL8seA5Dt9J2N1yTWkfnDCWXWBIPVR9JSp4uT\nMR6KDB8MAkeQvpfxIST7WRigR7myTvBNJuOVjaJNYQeE+dYRmEewBL7o6PCzEvrK\nB5lbISKRASnFUScbLAx1REQsuh0taKtetEfZYdMw0Fc6bog9KVRbbtblhTETZXBV\niAyK2A0LwXvw0Jh4lvQW7hhkW04kTsn75A2ziUq7bP3y+B6LCNaYPCFTTXpWXMh4\nfVRJwptc7vaaR+As+59SkLxuu+dGzPpwXL30iupcUT1cqyA7gSip+sw+X5/RPQps\nlszdBDifAgMBAAECggEAHgIxcDQ+nEBXp9D4SDIu0Ne4WjcFyBiCNQDqygwvsiRc\n9HKfvEvS/HIdL2QNEn/qk75A7DJaXEONZleU6Z/doaPbOjEE/yXcMWE4BsYLxhD5\npY9NFwqYYcY2i836uz8hRaUg1uMtjQWZQp0QouUXAOnvHdDGMg4ne+QT/gLZLALX\nbNN355Sff6i7P/0ll7FvBekzA1UVOT73JNbABle7ZkDiwWLQBnb0Enc8RhX9a9yW\n9Ctitxoq/ZXbderDIeJGXWfsOTDlP2lod34RHKWw4w1OEDnBzOwYY1tHwWXCjrrn\nUt2Nch6VdeOBxyRluiifHVfmju2Fk1yV0mPLHJfZcQKBgQDTm68RK54fmsiI/00u\n+Ky0LyDdm8A095XlZ97rt4bq4CKmkClR+Ic/yywiZ+gD/PqZ7wt0wvHZOZr+vdoT\npWqzTFs75sX+GM1Eo0yPtu6ymYFuaxHZCVK33d8nhCXiL+y5MuHeIyML8vNFJm7B\n4kuxXUu2SvGSVOAxAHJQckNzTwKBgQDGPulBPIT0pjRz3pxW72toP1Oo94QxE4qC\nIjYFKxOUI/TnDgyIsa1LYf0CfV4F2Ge4SJt8zg9Jqqv5WKu6//PRX0MOoeKnZYJ2\nk/B0JEZuz4+YNrkoWOn879T/txfssq0PYnhRkh300e5B38dk2ma5Lhht6VwwLARu\nBeb1KWLRsQKBgDALiRQ88wn5+s4gKUYg8BV5Hd0zH9Dm5gHQM60RXnC1syheUwNp\nikvRtZOaQ/Oj3MJWpCM+n+rSSX7NXFZZmIBdNdnD6/BlcTXEXf3Day7h66FGbib5\nFu7oUWKHfpJ8jyL9iosFL0/nOZTZxQwAdW8v36DkIzU2UDDQCSR6zRXBAoGAdvcJ\nwrwujSGwGFheOU0zhzt5WMwv58NyOuWMxU00UpHBRWaI3v7An5wN2JCi+58BnvTz\nWdHOGsbwrJEpfO5bwikIdJ9xBENGJyJgCVI7cgPch9tPAYdZ4w+JImsdUE1ozPKq\ngUjN8TyJXb6MSVlGi5m9zzdauw2vGtcv4a8UPgECgYEAz+EaYCQgorHsOucZDDHF\nMS8pr7BMpGtOg3tdRv/YZEyW3Xt1h5BjbwBQiM6FzSjnamrxgq6JCuvvdVM4e866\n0oguzIcrKsQkMAR9n0xMDY0Craxhw4pvkCcVdGiAhcozCnq8+qpg1ExS+H90yCiJ\nW6Oz+mDV1BhPdowaKmAN4/g=\n-----END PRIVATE KEY-----\n", + "client_email": "firebase-adminsdk-mhjrk@arminta-water-notification.iam.gserviceaccount.com", + "client_id": "102304340577897136338", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-mhjrk%40arminta-water-notification.iam.gserviceaccount.com", + "universe_domain": "googleapis.com" +} diff --git a/src/controllers/tanksController.js b/src/controllers/tanksController.js index 25a490ad..d0a7d56b 100644 --- a/src/controllers/tanksController.js +++ b/src/controllers/tanksController.js @@ -1,5 +1,5 @@ //const Tank = require("../models/tanks"); -const { Tank, MotorData, IotData,MotorIot,TankWaterLevel,TankConsumptionSchema } = require('../models/tanks') +const { Tank, MotorData, IotData,MotorIot } = require('../models/tanks') const User = require("../models/User"); const boom = require("boom"); @@ -824,85 +824,31 @@ let supplier_tanks = []; // }; -// exports.consumption = async (request, reply) => { -// try { -// const customerId = req.params.customerId; -// const tanks = await Tank.find({ customerId,tankLocation:"overhead"}); -// const tankData = []; -// for (const tank of tanks) { -// const tankId = tank._id; -// const waterlevel_at_midnight = parseInt(tank.waterlevel_at_midnight.replace(/,/g, ''), 10); -// const total_water_added_from_midnight = parseInt(tank.total_water_added_from_midnight.replace(/,/g, ''), 10); -// const waterlevel = parseInt(tank.waterlevel.replace(/,/g, ''), 10); - -// const tankname = tank.tankName -// const consumption = (waterlevel_at_midnight+total_water_added_from_midnight)-waterlevel - -// tankData.push({ tankname, waterLevel: consumption }); - - -// // console.log(newWaterLevel); - -// } -// reply.send({ status_code: 200, tankData }); - -// return { message: 'Water level updates started' }; -// } catch (err) { -// throw boom.boomify(err); -// } - - - - - -function parseDateTime(dateTimeStr) { - const [datePart, timePart] = dateTimeStr.split(' - '); - const [day, month, year] = datePart.split('-'); - const monthIndex = new Date(Date.parse(month +" 1, 2024")).getMonth(); // Parse the month name to get its index - const [hours, minutes] = timePart.split(':'); - return new Date(year, monthIndex, day, hours, minutes); -} - - - -exports.consumption = async (request, reply) => { +exports.consumption = async (req, reply) => { try { - - const { customerId } = request.params; - const { startDate, stopDate } = request.body; - - const start = parseDateTime(startDate); - const end = parseDateTime(stopDate); - const tanks = await Tank.find({ customerId, tankLocation: "overhead" }); - const tankData = []; - + const customerId = req.params.customerId; + const tanks = await Tank.find({ customerId,tankLocation:"overhead"}); + const tankData = []; for (const tank of tanks) { const tankId = tank._id; const waterlevel_at_midnight = parseInt(tank.waterlevel_at_midnight.replace(/,/g, ''), 10); const total_water_added_from_midnight = parseInt(tank.total_water_added_from_midnight.replace(/,/g, ''), 10); const waterlevel = parseInt(tank.waterlevel.replace(/,/g, ''), 10); - const tankname = tank.tankName; - console.log(waterlevel_at_midnight,total_water_added_from_midnight,waterlevel) - const tankConsumptions = await TankConsumptionSchema.find({ - customerId, - tankName: tank.tankName, - tankLocation: tank.tankLocation, - time: { - $gte: start, - $lte: end - } - }); + + const tankname = tank.tankName + const consumption = (waterlevel_at_midnight+total_water_added_from_midnight)-waterlevel + + const newWaterLevel1 = Math.floor(consumption); + const newWaterLevel=Math.abs(newWaterLevel1) + tankData.push({ tankname, waterLevel: newWaterLevel }); - const total_consumption_from_records = tankConsumptions.reduce((acc, record) => { - return acc + parseInt(record.consumption, 10); - }, 0); + + // console.log(newWaterLevel); - const consumption = (waterlevel_at_midnight + total_water_added_from_midnight) - waterlevel + total_consumption_from_records; - - tankData.push({ tankname, totalConsumption: consumption }); } + reply.send({ status_code: 200, tankData }); - reply.send({ status_code: 200, tankData }); + return { message: 'Water level updates started' }; } catch (err) { throw boom.boomify(err); } @@ -910,135 +856,173 @@ exports.consumption = async (request, reply) => { +//const moment = require('moment'); // Import moment.js for date/time operations + -const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); +const admin = require('firebase-admin'); -//const moment = require('moment'); // Import moment.js for date/time operations -const formatDate = (date) => { - const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; - const day = String(date.getDate()).padStart(2, '0'); - const month = months[date.getMonth()]; - const year = date.getFullYear(); - const hours = String(date.getHours()).padStart(2, '0'); - const minutes = String(date.getMinutes()).padStart(2, '0'); - return `${day}-${month}-${year} - ${hours}:${minutes}`; +// Initialize Firebase Admin SDK (make sure this is done once in your app) +const serviceAccount = require('../arminta-water-notification-firebase-adminsdk-mhjrk-c90bbe0594.json'); + +admin.initializeApp({ + credential: admin.credential.cert(serviceAccount), +}); + +// Helper function to send push notifications +const sendPushNotification = async (registrationToken, title, body) => { + const message = { + notification: { + title: title, + body: body, + }, + token: registrationToken, + }; + + try { + const response = await admin.messaging().send(message); + console.log('FCM response:', response); // Log the FCM response + return response; // Return the FCM response object + } catch (error) { + console.error('FCM error:', error); + throw error; // Throw the error to handle it further up the call stack + } }; +// Example usage in your motorAction function exports.motorAction = async (req, reply) => { try { const customerId = req.params.customerId; const action = req.body.action; const motorId = req.body.motor_id; - const start_instance_id = req.body.start_instance_id - console.log(req.body.startTime) - // Ensure motor_id is provided + const start_instance_id = req.body.start_instance_id; + const startTime = req.body.startTime; + const stopTime = req.body.stopTime; + const threshold_type = req.body.threshold_type; + const manual_threshold_time = req.body.manual_threshold_time; + const manual_threshold_litres = req.body.manual_threshold_litres; + const from = req.body.from; + const to = req.body.to; + const from_type = req.body.from_type; + const to_type = req.body.to_type; + + console.log(startTime); + if (!motorId) { throw new Error("Motor ID is required."); } - // Determine the motor stop status based on the action let motorStopStatus; if (action === "start") { - motorStopStatus = "2"; // If action is start, set stop status to "2" + motorStopStatus = "2"; } else if (action === "stop") { - motorStopStatus = "1"; // If action is stop, set stop status to "1" + motorStopStatus = "1"; } else { throw new Error("Invalid action provided."); } - // Update the motor stop status immediately if action is stop + const users = await User.find({ customerId: customerId }); + const fcmIds = users.map(user => user.fcmId).filter(fcmId => fcmId); + if (action === "stop") { await Tank.updateOne( { customerId, "connections.inputConnections.motor_id": motorId }, - { - $set: { + { + $set: { "connections.inputConnections.$.motor_stop_status": "1", - "connections.inputConnections.$.stopTime": req.body.stopTime, + "connections.inputConnections.$.stopTime": stopTime, "connections.inputConnections.$.threshold_type": null, "connections.inputConnections.$.manual_threshold_time": null, - "connections.inputConnections.$.manual_threshold_percentage": null - } + "connections.inputConnections.$.manual_threshold_percentage": null, + }, } ); await delay(300000); - // Update the existing motor data entry with stop details const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id }); if (motorData) { const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() }); const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10); const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10); const water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10); - const totalwaterpumped = quantityDelivered + water_pumped_till_now - await Tank.findOneAndUpdate({customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase()}, { $set: { total_water_added_from_midnight: totalwaterpumped } }) + const totalwaterpumped = quantityDelivered + water_pumped_till_now; + await Tank.findOneAndUpdate({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() }, { $set: { total_water_added_from_midnight: totalwaterpumped } }); await MotorData.updateOne( { customerId, motor_id: motorId, start_instance_id: start_instance_id }, - { - $set: { - stopTime: req.body.stopTime, + { + $set: { + stopTime: stopTime, receiverfinalwaterlevel: receiverFinalWaterLevel.toString(), - quantity_delivered: quantityDelivered.toString() - } + quantity_delivered: quantityDelivered.toString(), + }, } ); - } - - + // Send notification for motor stop + for (const fcmId of fcmIds) { + try { + const response = await sendPushNotification(fcmId, 'Motor Stopped', `Motor has stopped at ${stopTime}. Quantity delivered: ${quantityDelivered} litres.`); + console.log('Notification sent successfully:', response); + } catch (error) { + console.error('Error sending notification:', error); + } + } + } } else { - // Update the motor stop status to "2" for start action await Tank.updateOne( { customerId, "connections.inputConnections.motor_id": motorId }, { $set: { "connections.inputConnections.$.motor_stop_status": "2" } } ); + + // Send notification for motor start + for (const fcmId of fcmIds) { + try { + const response = await sendPushNotification(fcmId, 'Motor Started', `Motor has started at ${startTime}.`); + console.log('Notification sent successfully:', response); + } catch (error) { + console.error('Error sending notification:', error); + } + } } - // Check threshold settings if action is start if (action === "start") { - if (req.body.threshold_type === "time") { - // If threshold type is time, update threshold time - // await Tank.updateOne( - // { customerId, "connections.inputConnections.motor_id": motorId }, - // { $set: { "connections.inputConnections.$.manual_threshold_time": req.body.manual_threshold_time,startTime:req.body.startTime } } - // ); - const receiver_tank_info7 = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() }); + if (threshold_type === "time") { + const receiverTank = await Tank.findOne({ customerId, tankName: to, tankLocation: to_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) + supplierTank: from, + receiverTank: to, + supplier_type: from_type, + receiver_type: to_type, + startTime: startTime, + receiverInitialwaterlevel: parseInt(receiverTank.waterlevel, 10), }); await newMotorData.save(); - for await (const tank of Tank.find({ "connections.inputConnections.motor_id": motorId })) { + 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_time`]: req.body.manual_threshold_time, [`connections.inputConnections.${index}.startTime`]: req.body.startTime,[`connections.inputConnections.${index}.start_instance_id`]: start_instance_id } } + { $set: { [`connections.inputConnections.${index}.manual_threshold_time`]: manual_threshold_time, [`connections.inputConnections.${index}.startTime`]: startTime, [`connections.inputConnections.${index}.start_instance_id`]: start_instance_id } } ); } } - - // Start monitoring water level based on threshold time - const thresholdTime = moment().add(req.body.manual_threshold_time, 'minutes').toDate(); + const thresholdTime = moment().add(manual_threshold_time, 'minutes').toDate(); const intervalId = setInterval(async () => { - const splr_tank_info3 = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() }); - const splr_tank_info3_waterlevel = parseInt(splr_tank_info3.waterlevel, 10); - const splr_tank_info3_capacity = parseInt(splr_tank_info3.capacity, 10); - const splr_tank_info3_percentage = (splr_tank_info3_waterlevel / splr_tank_info3_capacity) * 100; - console.log(splr_tank_info3_percentage, "percentage for less than 20"); + const splrTank = await Tank.findOne({ customerId, tankName: from, tankLocation: from_type.toLowerCase() }); + const splrWaterLevel = parseInt(splrTank.waterlevel, 10); + const splrCapacity = parseInt(splrTank.capacity, 10); + const splrPercentage = (splrWaterLevel / splrCapacity) * 100; - if (new Date() >= thresholdTime || splr_tank_info3_percentage <= 20) { + console.log(splrPercentage, "percentage for less than 20"); + + if (new Date() >= thresholdTime || splrPercentage <= 20) { await Tank.updateOne( { customerId, "connections.inputConnections.motor_id": motorId }, { @@ -1046,8 +1030,8 @@ exports.motorAction = async (req, reply) => { "connections.inputConnections.$.motor_stop_status": "1", "connections.inputConnections.$.threshold_type": null, "connections.inputConnections.$.manual_threshold_time": null, - "connections.inputConnections.$.manual_threshold_percentage": null - } + "connections.inputConnections.$.manual_threshold_percentage": null, + }, } ); clearInterval(intervalId); @@ -1060,94 +1044,100 @@ exports.motorAction = async (req, reply) => { const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10); const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10); const water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10); - const totalwaterpumped = quantityDelivered + water_pumped_till_now - await Tank.findOneAndUpdate({customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase()}, { $set: { total_water_added_from_midnight: totalwaterpumped } }) + const totalwaterpumped = quantityDelivered + water_pumped_till_now; + await Tank.findOneAndUpdate({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() }, { $set: { total_water_added_from_midnight: totalwaterpumped } }); - const stopTime = formatDate(new Date()); + const stopTime = new Date().toISOString(); await MotorData.updateOne( { customerId, motor_id: motorId, start_instance_id: start_instance_id }, { $set: { - stopTime:stopTime, + stopTime: stopTime, receiverfinalwaterlevel: receiverFinalWaterLevel.toString(), - quantity_delivered: quantityDelivered.toString() - } + quantity_delivered: quantityDelivered.toString(), + }, } ); + + // Send notification for motor stop due to threshold + for (const fcmId of fcmIds) { + try { + const response = await sendPushNotification(fcmId, 'Motor Stopped', `Motor has stopped at ${stopTime}. Quantity delivered: ${quantityDelivered} litres.`); + console.log('Notification sent successfully:', response); + } catch (error) { + console.error('Error sending notification:', error); + } + } + } + + if (splrPercentage <= 20) { + for (const fcmId of fcmIds) { + try { + const response = await sendPushNotification(fcmId, 'Warning', 'Sump tank water level is below 20%.'); + console.log('Notification sent successfully:', response); + } catch (error) { + console.error('Error sending notification:', error); + } + } } } }, 60000); - } else if (req.body.threshold_type === "litres") { - const receiver_tank_info7 = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() }); + } else if (threshold_type === "litres") { + const receiverTank = await Tank.findOne({ customerId, tankName: to, tankLocation: to_type.toLowerCase() }); const newMotorData = new MotorData({ customerId: customerId, - motor_id: motor_id, + 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, - receiverwaterlevel:parseInt(receiver_tank_info7.waterlevel, 10) + supplierTank: from, + receiverTank: to, + supplier_type: from_type, + receiver_type: to_type, + startTime: startTime, + receiverwaterlevel: parseInt(receiverTank.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, 10); - const threshold_water_level = waterLevel+desired_percentage; + const receiverTankInfo = await Tank.findOne({ customerId, tankName: to, tankLocation: to_type.toLowerCase() }); + const supplierTankInfo = await Tank.findOne({ customerId, tankName: from, tankLocation: from_type.toLowerCase() }); + if (!receiverTankInfo) throw new Error("Receiver tank not found."); + if (!supplierTankInfo) throw new Error("Supplier tank not found."); - const supplier_threshold = supplier_waterLevel-desired_percentage - console.log(supplier_threshold,"supplier_threshold") + const supplierCapacity = parseInt(supplierTankInfo.capacity, 10); + const supplierWaterLevel = parseInt(supplierTankInfo.waterlevel, 10); + const capacity = parseInt(receiverTankInfo.capacity, 10); + const waterLevel = parseInt(receiverTankInfo.waterlevel, 10); + const desiredLitres = parseInt(manual_threshold_litres, 10); + const thresholdWaterLevel = waterLevel + desiredLitres; + const supplierThreshold = supplierWaterLevel - desiredLitres; - for await (const tank of Tank.find({ "connections.inputConnections.motor_id": motorId })) { + 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 } } + { $set: { [`connections.inputConnections.${index}.manual_threshold_percentage`]: supplierThreshold.toString(), [`connections.inputConnections.${index}.startTime`]: startTime } } ); } } - - - // Update water level threshold - - - // Start monitoring water level based on threshold percentage const intervalId = 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 + const supplierTank = await Tank.findOne({ customerId, tankName: from, tankLocation: from_type.toLowerCase() }); + const currentWaterLevel = parseInt(supplierTank.waterlevel, 10); + if (currentWaterLevel <= supplierThreshold) { await Tank.updateOne( { customerId, "connections.inputConnections.motor_id": motorId }, - { - $set: { + { + $set: { "connections.inputConnections.$.motor_stop_status": "1", - "connections.inputConnections.$.threshold_type": null, "connections.inputConnections.$.manual_threshold_time": null, - "connections.inputConnections.$.manual_threshold_percentage": null - } + "connections.inputConnections.$.manual_threshold_percentage": null, + }, } ); - clearInterval(intervalId); // Stop monitoring water level + clearInterval(intervalId); await delay(300000); const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id }); @@ -1156,148 +1146,202 @@ exports.motorAction = async (req, reply) => { const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10); const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10); - - const stopTime = formatDate(new Date()); + const stopTime = new Date().toISOString(); await MotorData.updateOne( { customerId, motor_id: motorId, start_instance_id: start_instance_id }, { $set: { - stopTime:stopTime, + stopTime: stopTime, receiverfinalwaterlevel: receiverFinalWaterLevel.toString(), - quantity_delivered: quantityDelivered.toString() - } + quantity_delivered: quantityDelivered.toString(), + }, } ); + + // Send notification for motor stop due to threshold + for (const fcmId of fcmIds) { + try { + const response = await sendPushNotification(fcmId, 'Motor Stopped', `Motor has stopped at ${stopTime}. Quantity delivered: ${quantityDelivered} litres.`); + console.log('Notification sent successfully:', response); + } catch (error) { + console.error('Error sending notification:', error); + } + } } } - }, 20000); // Check water level every minute + }, 20000); } } - // Respond with success message reply.code(200).send({ message: `Motor ${action === "start" ? "started" : "stopped"} successfully.` }); } catch (err) { - // Handle errors throw boom.boomify(err); } }; +// exports.motorAction = async (req, reply) => { +// try { +// const customerId = req.params.customerId; +// const action = req.body.action; +// const motorId = req.body.motor_id; +// console.log(req.body.startTime) +// // Ensure motor_id is provided +// if (!motorId) { +// throw new Error("Motor ID is required."); +// } +// // Determine the motor stop status based on the action +// let motorStopStatus; +// if (action === "start") { +// motorStopStatus = "2"; // If action is start, set stop status to "2" +// } else if (action === "stop") { +// motorStopStatus = "1"; // If action is stop, set stop status to "1" +// } else { +// throw new Error("Invalid action provided."); +// } -const motorActionAuto = async (req, reply) => { - try { - const customerId = req.params.customerId; - const action = req.body.action; - const motorId = req.body.motor_id; - const motor_on_type = req.body.motor_on_type +// // Update the motor stop status immediately if action is stop +// if (action === "stop") { +// await Tank.updateOne( +// { customerId, "connections.inputConnections.motor_id": motorId }, +// { +// $set: { +// "connections.inputConnections.$.motor_stop_status": "1", +// "connections.inputConnections.$.stopTime": req.body.stopTime, +// "connections.inputConnections.$.threshold_type": null, +// "connections.inputConnections.$.manual_threshold_time": null, +// "connections.inputConnections.$.manual_threshold_percentage": null +// } +// } +// ); + - if (!motorId) { - throw new Error("Motor ID is required."); - } - let motorStopStatus; - if (action === "start") { - await Tank.updateOne( - { customerId, "connections.inputConnections.motor_id": motorId }, - { - $set: { - "connections.inputConnections.$.motor_stop_status": "2", - "connections.inputConnections.$.startTime": req.body.startTime, - "connections.inputConnections.$.motor_on_type": "auto", - - } - } - ); - ; - } + +// } else { +// // Update the motor stop status to "2" for start action +// await Tank.updateOne( +// { customerId, "connections.inputConnections.motor_id": motorId }, +// { $set: { "connections.inputConnections.$.motor_stop_status": "2" } } +// ); +// } - if (action === "stop") { - await Tank.updateOne( - { customerId, "connections.inputConnections.motor_id": motorId }, - { - $set: { - "connections.inputConnections.$.motor_stop_status": "1", - "connections.inputConnections.$.stopTime": req.body.stopTime, - "connections.inputConnections.$.motor_on_type": null, - } - } - ); - } +// // Check threshold settings if action is start +// if (action === "start") { +// if (req.body.threshold_type === "time") { +// // If threshold type is time, update threshold time +// // await Tank.updateOne( +// // { customerId, "connections.inputConnections.motor_id": motorId }, +// // { $set: { "connections.inputConnections.$.manual_threshold_time": req.body.manual_threshold_time,startTime:req.body.startTime } } +// // ); + + +// 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_time`]: req.body.manual_threshold_time, [`connections.inputConnections.${index}.startTime`]: req.body.startTime } } +// ); +// } +// } + - +// // Start monitoring water level based on threshold time +// const thresholdTime = moment().add(req.body.manual_threshold_time, 'minutes').toDate(); +// const intervalId = setInterval(async () => { +// // Check if threshold time has been reached +// if (new Date() >= thresholdTime) { +// // 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(intervalId); // Stop monitoring water level +// } +// }, 60000); // Check water level every minute +// } else if (req.body.threshold_type === "litres") { +// // 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); - reply.code(200).send({ message: `Motor ${action === "start" ? "started" : "stopped"} successfully.` }); - } catch (err) { - console.error("Error in motorActionAuto:", err); - reply.code(500).send({ error: err.message }); - } -}; -const checkAutoMode = async () => { - try { - const tanks = await Tank.find(); - for (const tank of tanks) { - for (const inputConnection of tank.connections.inputConnections) { - if (inputConnection.auto_mode === "active") { - console.log("This is automation for tank: " + tank.tankName); - const waterLevel = parseFloat(tank.waterlevel.replace(/,/g, '')); - const capacity = parseFloat(tank.capacity.replace(/,/g, '')); - const autoMinPercentage = parseFloat(tank.auto_min_percentage); - const autoMaxPercentage = parseFloat(tank.auto_max_percentage); - console.log(waterLevel,capacity,autoMinPercentage,autoMaxPercentage) - - if (isNaN(waterLevel) || isNaN(capacity) || capacity === 0) { - console.error(`Invalid water level or capacity for tank: ${tank.tankName}`); - continue; // Skip this tank if the values are not valid - } - const currentPercentage = (waterLevel / capacity) * 100; - console.log("This is automation percentage: " + currentPercentage); - const now = moment().format('DD-MMM-YYYY - HH:mm'); - console.log(now) - if (currentPercentage <= autoMinPercentage) { - await motorActionAuto({ - params: { customerId: tank.customerId }, - body: { - action: "start", - motor_id: inputConnection.motor_id, - motor_on_type: "auto", - startTime: now - } - }, { - code: (statusCode) => ({ send: (response) => console.log(response) }) - }); - } else if (currentPercentage >= autoMaxPercentage && inputConnection.motor_on_type === "auto") { - await motorActionAuto({ - params: { customerId: tank.customerId }, - body: { - action: "stop", - motor_id: inputConnection.motor_id, - motor_on_type: "auto", - stopTime: now - } - }, { - code: (statusCode) => ({ send: (response) => console.log(response) }) - }); - } - } - } - } - } catch (err) { - console.error("Error checking auto mode:", err); - } -}; +// 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, 10); +// const threshold_water_level = waterLevel+desired_percentage; + +// const supplier_threshold = supplier_waterLevel-desired_percentage + +// 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 } } +// ); +// } +// } + -// Set the interval to check every 15 seconds (15000 milliseconds) -setInterval(checkAutoMode, 15000); +// // Update water level threshold + +// // Start monitoring water level based on threshold percentage +// const intervalId = 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(intervalId); // Stop monitoring water level +// } +// }, 20000); // Check water level every minute +// } +// } +// // Respond with success message +// reply.code(200).send({ message: `Motor ${action === "start" ? "started" : "stopped"} successfully.` }); +// } catch (err) { +// // Handle errors +// throw boom.boomify(err); +// } +// }; @@ -1595,7 +1639,6 @@ exports.calculateCapacity = async (req, reply) => { // }; - exports.IotDevice = async (req, reply) => { try { const { hardwareId, mode, tanks } = req.body; @@ -1651,26 +1694,23 @@ exports.IotDevice = async (req, reply) => { const waterCapacityPerCm = parseInt(existingTank.waterCapacityPerCm.replace(/,/g, ''), 10); const water_level = water_level_height * waterCapacityPerCm; - if (water_level >= 0) { - existingTank.waterlevel = water_level; - - // Save the updated tank document - await existingTank.save(); - - // Update linked tanks - 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 = water_level; - await linkedTank.save(); - } + existingTank.waterlevel = water_level; + + // Save the updated tank document + await existingTank.save(); + + // Update linked tanks + 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 = water_level; + await linkedTank.save(); } } } } - } // Send the latest three documents @@ -1691,7 +1731,6 @@ exports.IotDevice = async (req, reply) => { - // exports.IotDevice3 = async (req, reply) => { // try { // const { hardwareId, mode, tanks } = req.body; @@ -2174,102 +2213,37 @@ exports.startUpdateLoop = async (request, reply) => { }; -// exports.updatewaterlevelsatmidnight = async (req, reply) => { -// try { -// // Schedule the task to run every day at 10 seconds past the minute -// cron.schedule('0 0 * * *', async () => { -// try { -// const tanks = await Tank.find({ customerId: req.query.customerId }); -// for (const tank of tanks) { -// tank.waterlevel_at_midnight = tank.waterlevel; -// console.log(tank.waterlevel_at_midnight) -// await tank.save(); -// } -// console.log('Waterlevel noted in waterlevel_at_midnight'); -// } catch (error) { -// console.error('Error occurred:', error); -// } -// }); - -// await Tank.find({ customerId: req.query.customerId }) -// .exec() -// .then((docs) => { -// reply.send({ status_code: 200, data: docs, count: docs.length }); -// }) -// .catch((err) => { -// console.log(err); -// reply.send({ error: err }); -// }); -// } catch (err) { -// throw boom.boomify(err); -// } -// }; - - -const updatewaterlevelsatmidnight = async () => { - console.log('Cron job triggered at:', moment().tz('Asia/Kolkata').format()); - +exports.updatewaterlevelsatmidnight = async (req, reply) => { try { - const tanks = await Tank.find({}); - for (const tank of tanks) { - tank.waterlevel_at_midnight = tank.waterlevel; - tank.total_water_added_from_midnight = "0"; - await tank.save(); - console.log(`Updated tank ${tank._id} waterlevel_at_midnight to ${tank.waterlevel}`); - } - console.log('Waterlevel noted in waterlevel_at_midnight'); - } catch (error) { - console.error('Error occurred:', error); - } -}; - -// Schedule the task to run every day at 13:49 IST (1:49 PM IST) -cron.schedule('0 0 * * *', updatewaterlevelsatmidnight, { - timezone: "Asia/Kolkata" -}); - - - - - - - -const updatetotalConsumptiontillmidnight = async () => { - console.log('Cron job triggered at:', moment().tz('Asia/Kolkata').format()); + // Schedule the task to run every day at 10 seconds past the minute + cron.schedule('0 0 * * *', async () => { + try { + const tanks = await Tank.find({ customerId: req.query.customerId }); + for (const tank of tanks) { + tank.waterlevel_at_midnight = tank.waterlevel; + console.log(tank.waterlevel_at_midnight) + await tank.save(); + } + console.log('Waterlevel noted in waterlevel_at_midnight'); + } catch (error) { + console.error('Error occurred:', error); + } + }); - try { - const tanks = await Tank.find({}); - for (const tank of tanks) { - const waterlevel_at_midnight = parseInt((tank.waterlevel_at_midnight).replace(/,/g, ''), 10); - const total_water_added_from_midnight = parseInt((tank.total_water_added_from_midnight).replace(/,/g, ''), 10); - const waterlevel = parseInt((tank.waterlevel).replace(/,/g, ''), 10); - const totalconsumption = (waterlevel_at_midnight + total_water_added_from_midnight) - waterlevel - const newTankConsumption = new TankConsumptionSchema({ - customerId: tank.customerId, - tankName: tank.tankName, - tankLocation: tank.tankLocation, - consumption: totalconsumption.toString(), - time: new Date().toISOString() + await Tank.find({ customerId: req.query.customerId }) + .exec() + .then((docs) => { + reply.send({ status_code: 200, data: docs, count: docs.length }); + }) + .catch((err) => { + console.log(err); + reply.send({ error: err }); }); - - // Save the new document - await newTankConsumption.save(); - - } - console.log('Waterlevel noted in waterlevel_at_midnight'); - } catch (error) { - console.error('Error occurred:', error); + } catch (err) { + throw boom.boomify(err); } }; -// Schedule the task to run every day at 13:49 IST (1:49 PM IST) -cron.schedule('55 23 * * *', updatetotalConsumptiontillmidnight, { - timezone: "Asia/Kolkata" -}); - - - - exports.deletemotordatarecordsbefore7days = async (req, reply) => { try { @@ -2459,7 +2433,8 @@ exports.writeMotorStatus = async (req, reply) => { } }; - +// exports.writeMotorStatus = async (req, reply) => { +// try { // const motor_id = req.body.motor_id; // const status = req.body.status; @@ -2554,7 +2529,7 @@ exports.motortemperature = async (req, reply) => { exports.update_auto_mode = async (req, reply) => { try { const customerId = req.params.customerId; - const { motor_id, auto_mode } = req.body; + const { motor_id, auto_min_percentage, auto_max_percentage, auto_mode } = req.body; // Update inputConnections' auto_mode await Tank.updateOne( @@ -2562,25 +2537,9 @@ exports.update_auto_mode = async (req, reply) => { { $set: { "connections.inputConnections.$.auto_mode": auto_mode } } ); - - - reply.send({ status_code: 200, message: "Auto mode and percentages updated successfully." }); - } catch (error) { - throw boom.boomify(error); - } -}; - -exports.update_auto_percentage = async (req, reply) => { - try { - const customerId = req.params.customerId; - const { tankName,tankLocation, auto_min_percentage, auto_max_percentage } = req.body; - - // Update inputConnections' auto_mode - - // Update auto_min_percentage and auto_max_percentage - await Tank.updateOne( - { customerId: customerId,tankLocation, tankName}, + await Tank.updateMany( + { customerId: customerId }, { $set: { "auto_min_percentage": auto_min_percentage, @@ -2595,36 +2554,3 @@ exports.update_auto_percentage = async (req, reply) => { } }; - -//storing water level for every 15 minutes - -const getFormattedISTTime = () => { - return moment().tz('Asia/Kolkata').format('DD-MM-YYYY hh:mm:ss A'); -}; - -const storeWaterLevels = async () => { - try { - const tanks = await Tank.find({}); - const currentTime = getFormattedISTTime(); - - const waterLevelRecords = tanks.map(tank => ({ - customerId: tank.customerId, - tankName: tank.tankName, - tankLocation: tank.tankLocation, - waterlevel: tank.waterlevel, - time: currentTime - })); - - await TankWaterLevel.insertMany(waterLevelRecords); - console.log('Water levels stored successfully'); - } catch (error) { - console.error('Error storing water levels:', error); - } -}; - -setInterval(storeWaterLevels, 15 * 60 * 1000); - - - - -console.log('Cron job scheduled to update water levels at midnight'); \ No newline at end of file