//const Tank = require("../models/tanks"); const { Tank, MotorData, IotData,MotorIot,TankWaterLevel,TankConsumptionSchema,TankConsumptionOriginalSchema } = require('../models/tanks') const {User} = require("../models/User"); const boom = require("boom"); const fastify = require("fastify")({ logger: true, }); // const tanksController = require("./tanksController") const cron = require('node-cron'); const moment = require('moment'); const EventEmitter = require('events'); const eventEmitter = new EventEmitter(); async function deleteOldRecords() { const SEVEN_DAYS_IN_MILLISECONDS = 7 * 24 * 60 * 60 * 1000; const sevenDaysAgo = new Date(Date.now() - SEVEN_DAYS_IN_MILLISECONDS); await MotorData.deleteMany({ startTime: { $lt: sevenDaysAgo } }); } // exports.addTanks = async (req, reply) => { // try { // var customerId = req.params.customerId // //const username = req.params.username; // console.log(req.params); // //const {username} = loginObject.user.username; // //console.log(loginObject.user.username) // // const userInfo = await User.findOne({ username: username.toString() }); // // const updateData = req.body; // // console.log("This is the reply in the handler after the validations", reply); // tankData = { // customerId: customerId, // hardwareId: req.body.hardwareId, // tankName: req.body.tankName, // blockName: req.body.blockName, // capacity: req.body.capacity, // typeOfWater: req.body.typeOfWater, // tankLocation:req.body.tankLocation.toLowerCase(), // }; // //console.log( req.body.tankLocation.toLowerCase()) // var tank_name = req.body.tankName // var tankLocation = req.body.tankLocation.toLowerCase() // var i_tank = await Tank.findOne({ tankName: tank_name,customerId:customerId,tankLocation:tankLocation}) // if(i_tank){ // throw new Error('tankname already exists'); // } // else { // var tank = new Tank(tankData); // checkFormEncoding = isUserFormUrlEncoded(req); // if (checkFormEncoding.isUserFormUrlEncoded) { // usertobeInserted = checkFormEncoding.tank; // console.log("thsi true url string"); // tank.customerId = usertobeInserted.customerId // tank.hardwareId = usertobeInserted.hardwareId; // tank.tankName = usertobeInserted.tankName; // tank.blockName = usertobeInserted.blockName; // tank.capacity = usertobeInserted.capacity; // tank.typeOfWater = usertobeInserted.typeOfWater; // tank.tankLocation = (usertobeInserted.tankLocation).toLowerCase(); // console.log((usertobeInserted.tankLocation).toLowerCase()) // } // } // const insertedTank = await tank.save(); // return insertedTank; // } catch (err) { // throw boom.boomify(err); // } // }; exports.addTanks = async (req, reply) => { try { const customerId = req.params.customerId; const { hardwareId, tankhardwareId,tankName,tankLocation,need_sensor,blockName } = req.body; const existingTank = await Tank.findOne({ customerId: customerId, hardwareId: hardwareId, tankhardwareId: tankhardwareId, tankName:tankName, tankLocation:tankLocation.toLowerCase(), blockName:blockName }); if (existingTank) { throw new Error('The combination of hardwareId and tankhardwareId already exists.'); } const tankData = { // InstallerId:InstallerId, customerId: customerId, hardwareId: hardwareId, tankhardwareId: tankhardwareId, shape: req.body.shape, tankName: req.body.tankName, blockName: req.body.blockName, capacity: req.body.capacity, typeOfWater: req.body.typeOfWater, tankLocation: req.body.tankLocation.toLowerCase(), waterCapacityPerCm:req.body.waterCapacityPerCm, height:req.body.height, length:req.body.length, width:req.body.width, need_sensor:req.body.need_sensor // ... other fields }; const tank = new Tank(tankData); const insertedTank = await tank.save(); return insertedTank; } catch (err) { throw boom.boomify(err); } }; //update selected tank exports.updateTanksInfo = async (req, reply) => { try { const customerId = req.params.customerId; const tankName = req.query.tankName; const tank = req.body; const { ...updateData } = tank; console.log(tank) const update = await Tank.findOneAndUpdate({customerId:customerId,tankName: tankName,tankLocation:req.body.tankLocation }, updateData, { new: true }); //console.log(update.username) //return update; reply.send({ status_code: 200, data: update }); } catch (err) { throw boom.boomify(err); } }; //delete selected tank exports.deleteTanksInfo = async (req, reply) => { try { const customerId = req.params.customerId; const tankName = req.query.tankName; const tankLocation = req.body.tankLocation.toLowerCase(); const tank = await Tank.findOneAndDelete({ tankName: tankName,customerId:customerId,tankLocation:tankLocation }); reply.send({ status_code: 200, data: tank}); // return tank; } catch (err) { throw boom.boomify(err); } }; exports.getConnectionsInfoOfParticularTank = async (req, reply) => { try { const customerId = req.params.customerId; const tankName = req.body.tankName; const tankLocation = req.body.tankLocation.toLowerCase(); console.log(customerId, tankName, tankLocation); // Find the specific tank const mainTank = await Tank.findOne({ tankName: tankName, customerId: customerId, tankLocation: tankLocation }); if (!mainTank) { return reply.send({ status_code: 404, error: "Main tank not found" }); } // Send the found tank within a list reply.send({ status_code: 200, data: [mainTank] }); } catch (err) { throw boom.boomify(err); } }; //get tanks data by passing username exports.getTank = async (req, reply) => { try { await Tank.find({ customerId: req.query.customerId }) .exec() .then((docs) => { let totalSwitchCount = 0; let totalSensorCount = 0; const transformedDocs = docs.map((tank) => { const inputConnections = tank.connections?.inputConnections || []; const switchCount = inputConnections.reduce((count, connection) => { return count + (connection.inputismotor === true ? 1 : 0); }, 0); totalSwitchCount += switchCount; // Accumulate the switch_count // Check if the tank has need_sensor set to "yes" if (tank.need_sensor?.toLowerCase() === "yes") { totalSensorCount++; } // Add the switch_count field inside connections return { ...tank.toObject(), // Convert Mongoose document to plain object connections: { ...tank.connections, switch_count: switchCount, }, }; }); reply.send({ 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 }); }) .catch((err) => { console.error(err); reply.send({ status_code: 500, error: err.message }); }); } catch (err) { console.error(err); reply.send({ status_code: 500, error: "Internal Server Error" }); } }; exports.getTanksensorcount = async (req, reply) => { try { const { customerId } = req.params; // Find all tanks for the given customerId const tanks = await Tank.find({ customerId }); if (!tanks || tanks.length === 0) { return reply.send({ message: "No tanks found for the given customerId", data: [], }); } // Process each tank const tankResults = tanks.map(tank => { const needSensorCount = { YES: tank.need_sensor === "YES" ? 1 : 0, }; const inputConnections = tank.connections.inputConnections || []; const inputIsMotorCounts = inputConnections.reduce( (acc, connection) => { if (connection.inputismotor === true) acc.true += 1; return acc; }, { true: 0 } ); const totalInputConnections = inputConnections.length; return { tankName: tank.tankName, needSensorCount, inputIsMotorCounts, totalInputConnections, inputConnections, }; }); reply.send({ customerId, tanks: tankResults, }); } catch (error) { reply.status(500).send({ error: "An error occurred while fetching the data." }); } }, exports.getTanksofParticularInstaller = async (req, reply) => { try { await Tank.find({InstallerId: req.query.InstallerId}) .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); } }; //exports.getTanklevels = async (req, reply) => { // try { // const customerId = req.params.customerId; // const tankName = req.query.tankName; // setInterval(async function () { // const randomNumber = Math.floor(Math.random() * (5500 - 1000) + 1000); // console.log(randomNumber) // console.log( await Tank.findOneAndUpdate({ customerId: customerId, tankName: tankName }, { $set: { waterlevel: randomNumber } })); // }, 2000); // return { message: 'Water level will be updated every 2 seconds' }; //} // catch (err) { // throw boom.boomify(err); // } //}; exports.getTankmotordata = async (req, reply) => { try { await MotorData.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); } }; exports.updateTanklevels = async (req, reply) => { try { const customerId = req.params.customerId; const tanks = await Tank.find({ customerId,tankLocation:"overhead" }); const intervals = {}; for (const tank of tanks) { const tankId = tank._id; const tank_name = tank.tankName let capacity = parseInt(tank.capacity.replace(/,/g, ''), 10); //let waterLevel = parseInt(tank.waterlevel.replace(/,/g, ''), 10); const intervalId = setInterval(async function () { const tank_data = await Tank.findOne({ _id:tankId }); const motorStatus = tank_data.motor_status let waterLevel = parseInt(tank_data.waterlevel.replace(/,/g, ''), 10); const newWaterLevel = Math.floor(waterLevel - 150); console.log("motorstatus:"+motorStatus) if (newWaterLevel <= 0 ) { clearInterval(intervals[tankId]); console.log(`Stopped updating tank with ID ${tankId}`); return; } else{ const result = await Tank.findOneAndUpdate( { _id: tankId }, { $set: { waterlevel: newWaterLevel } } ); console.log(tank_name+"="+newWaterLevel) } // console.log(result); // waterLevel = newWaterLevel; }, 5000); intervals[tankId] = intervalId; } return { message: 'Water level updates started' }; } catch (err) { throw boom.boomify(err); } }; exports.getTanklevels = async (req, reply) => { try { const customerId = req.params.customerId; let sumSumpDrinkingWater = 0; let sumOverheadDrinkingWater = 0; let sumSumpBoreWater = 0; let sumOverheadBoreWater = 0; let sumSumpDrinkingWaterCapacity = 0; let sumOverheadDrinkingWaterCapacity = 0; let sumSumpBoreWaterCapacity = 0; let sumOverheadBoreWaterCapacity = 0; const updated_data = await Tank.find({ customerId: customerId }); console.log("updated_data", updated_data); updated_data.forEach((tank) => { const waterlevel = parseInt(tank.waterlevel ? tank.waterlevel.replace(/,/g, '') : '0', 10); const capacity = parseInt(tank.capacity ? tank.capacity.replace(/,/g, '') : '0', 10); const waterlevelPercentage = ((waterlevel / capacity) * 100).toFixed(2); tank.waterlevelPercentage = waterlevelPercentage; // Add water level percentage to each tank object console.log(`Processing tank: ${tank.tankName}`); console.log(`Type of Water: ${tank.typeOfWater}, Location: ${tank.tankLocation}, Waterlevel: ${waterlevel}, Capacity: ${capacity}, Waterlevel Percentage: ${waterlevelPercentage}%`); let totalInputPercentage = 0; let inputCount = 0; let totalOutputPercentage = 0; let outputCount = 0; // Calculate and add water level percentages for inputConnections if (tank.connections.inputConnections) { tank.connections.inputConnections.forEach(inputConnection => { const inputWaterLevel = inputConnection.water_level ? parseInt(inputConnection.water_level.replace(/,/g, ''), 10) : 0; const inputCapacity = inputConnection.capacity ? parseInt(inputConnection.capacity.replace(/,/g, ''), 10) : 0; if (inputCapacity > 0) { inputConnection.waterlevelPercentage = ((inputWaterLevel / inputCapacity) * 100).toFixed(2); totalInputPercentage += parseFloat(inputConnection.waterlevelPercentage); inputCount++; } else { inputConnection.waterlevelPercentage = null; } }); // Add the average input water level percentage to the tank's connections object tank.connections.inputWaterlevelPercentage = inputCount > 0 ? (totalInputPercentage / inputCount).toFixed(2) : null; } // Calculate and add water level percentages for outputConnections if (tank.connections.outputConnections) { tank.connections.outputConnections.forEach(outputConnection => { const outputWaterLevel = outputConnection.water_level ? parseInt(outputConnection.water_level.replace(/,/g, ''), 10) : 0; const outputCapacity = outputConnection.capacity ? parseInt(outputConnection.capacity.replace(/,/g, ''), 10) : 0; if (outputCapacity > 0) { outputConnection.waterlevelPercentage = ((outputWaterLevel / outputCapacity) * 100).toFixed(2); totalOutputPercentage += parseFloat(outputConnection.waterlevelPercentage); outputCount++; } else { outputConnection.waterlevelPercentage = null; } }); // Add the average output water level percentage to the tank's connections object tank.connections.outputWaterlevelPercentage = outputCount > 0 ? (totalOutputPercentage / outputCount).toFixed(2) : null; } // Summing up the total water levels and capacities if (tank.tankLocation === 'sump' && tank.typeOfWater === 'drinking') { sumSumpDrinkingWater += waterlevel; sumSumpDrinkingWaterCapacity += capacity; } else if (tank.tankLocation === 'overhead' && tank.typeOfWater === 'drinking') { sumOverheadDrinkingWater += waterlevel; sumOverheadDrinkingWaterCapacity += capacity; } else if (tank.tankLocation === 'sump' && tank.typeOfWater === 'bore') { sumSumpBoreWater += waterlevel; sumSumpBoreWaterCapacity += capacity; } else if (tank.tankLocation === 'overhead' && tank.typeOfWater === 'bore') { sumOverheadBoreWater += waterlevel; sumOverheadBoreWaterCapacity += capacity; } }); const user = await User.findOne({ customerId: customerId }); const buildingName = user ? user.buildingName : null; const address1 = user ? user.profile.address1 : null; const responseData = { status_code: 200, data: updated_data, totalDrinkingWaterInSump: sumSumpDrinkingWater, totalDrinkingWaterInOverhead: sumOverheadDrinkingWater, totalBoreWaterInSump: sumSumpBoreWater, totalBoreWaterInOverhead: sumOverheadBoreWater, totalDrinkingWaterInSumpCapacity: sumSumpDrinkingWaterCapacity, totalDrinkingWaterInOverheadCapacity: sumOverheadDrinkingWaterCapacity, totalBoreWaterInSumpCapacity: sumSumpBoreWaterCapacity, totalBoreWaterInOverheadCapacity: sumOverheadBoreWaterCapacity, buildingName: buildingName, address1: address1, }; if (!reply.sent) { reply.send(responseData); } } catch (err) { if (!reply.sent) { reply.code(500).send({ error: 'Internal Server Error' }); } throw boom.boomify(err); } }; const intervals = {}; let sump_water_levels=[]; let supplier_tanks = []; // exports.motorAction = async (req, reply) => { // try { // 7 // const customerId = req.params.customerId; // const action = req.body.action // const receiver_tank = req.body.to // const receiver_tank_info = await Tank.findOne({ customerId ,tankName:receiver_tank,tankLocation:(req.body.to_type).toLowerCase()}); // const receiver_capacity = parseInt((receiver_tank_info.capacity).replace(/,/g, ''), 10) // const desired_water_percentage = parseInt((req.body.percentage).replace(/,/g, ''), 10) // const supplier_tank = req.body.from // const supplier_tank_type = (req.body.from_type).toLowerCase() // const receiver_type = (req.body.to_type).toLowerCase() // // console.log(supplier_tank) // // const suplr_tank_info1 = await Tank.findOne({ customerId ,tankName:supplier_tank,tankLocation:supplier_tank_type}); // const interval_variable = supplier_tank+receiver_tank // let currentTank = supplier_tanks.find(tank => tank.supplier_tank === supplier_tank); // let currentSump = sump_water_levels.find(tank => tank.supplier_tank === supplier_tank); // if(action === "start"){ // if (!currentTank) { // currentTank = { // supplier_tank: supplier_tank, // start_time: new Date().toLocaleString('en-US', { timeZone: 'Asia/Kolkata' }) // }; // supplier_tanks.push(currentTank); // } // // start_time = new Date().toLocaleString('en-US', {timeZone: 'Asia/Kolkata'}) // console.log(supplier_tanks) // // const stop_at = req.body.stop_at // if(supplier_tank_type==="sump" && receiver_type === "overhead"){ // await Tank.findOneAndUpdate({customerId, tankName: receiver_tank,tankLocation:receiver_type}, { $set: { motor_status: "1" } }); // const supplier_tank_info1 = await Tank.findOne({ customerId ,tankName:supplier_tank,tankLocation:supplier_tank_type}); // //console.log(supplier_tank_info1) // //const initial_update = parseInt(supplier_tank_info1.waterlevel.replace(/,/g, ''), 10)-200; // // await Tank.findOneAndUpdate({customerId, tankName: supplier_tank,tankLocation:supplier_tank_type}, { $set: { waterlevel: initial_update } }); // const supplier_tank_info = await Tank.findOne({ customerId ,tankName:supplier_tank,tankLocation:supplier_tank_type}); // const sump_water_level= parseInt(supplier_tank_info.waterlevel.replace(/,/g, ''), 10) // const receiver_tank_info2 = await Tank.findOne({ customerId ,tankName:receiver_tank,tankLocation:(req.body.to_type).toLowerCase()}); // const water_added_from_midnight = parseInt((receiver_tank_info2.total_water_added_from_midnight).replace(/,/g, ''), 10) // if (!currentSump) { // currentSump = { // supplier_tank: supplier_tank, // supplier_initial_waterlevel:sump_water_level, // receiver_tank_total_water_added_from_midnight:water_added_from_midnight // }; // sump_water_levels.push(currentSump); // } // console.log(sump_water_levels) // const overheadTank = await Tank.findOne({ customerId, tankName: receiver_tank, tankLocation: receiver_type }); // const connection = overheadTank.connections.inputConnections.find((conn) => conn.inputConnections === supplier_tank); // if (connection) { // connection.motor_status = "1"; // await overheadTank.save(); // } // // await changingfrom_tankwaterlevel(customerId,initial_update,supplier_tank_info); // // let supplier_waterlevel = parseInt(supplier_tank_info.waterlevel.replace(/,/g, ''), 10) // // console.log(supplier_waterlevel) // // let receiver_waterlevel = parseInt(receiver_tank_info.waterlevel.replace(/,/g, ''), 10) // intervals[interval_variable] = setInterval(async function () { // // Calculate new water levels // const supplier_tank_info2 = await Tank.findOne({ customerId ,tankName:supplier_tank,tankLocation:supplier_tank_type}); // const rcvr_info = await Tank.findOne({ customerId ,tankName:receiver_tank,tankLocation:receiver_type}); // let receiver_waterlevel = parseInt(rcvr_info.waterlevel.replace(/,/g, ''), 10) // let supplier_waterlevel = parseInt(supplier_tank_info2.waterlevel.replace(/,/g, ''), 10) // const newWaterLevel = receiver_waterlevel + 250//Math.floor(supplier_waterlevel * 0.1); // const newSupplierWaterLevel = supplier_waterlevel-250//Math.floor(supplier_waterlevel * 0.1); // const supplier_capacity = parseInt(supplier_tank_info.capacity.replace(/,/g, ''), 10) // console.log((newSupplierWaterLevel/supplier_capacity)*100) // // Check if updating should stop // if ((newSupplierWaterLevel/supplier_capacity)*100 <= 5 || (newWaterLevel/receiver_capacity)*100 >= 95 || (newWaterLevel/receiver_capacity)*100 >= desired_water_percentage || rcvr_info.motor_status === "0") { // console.log((newSupplierWaterLevel/supplier_capacity)*100,(newWaterLevel/receiver_capacity)*100,(newWaterLevel/receiver_capacity)*100,) // clearInterval(intervals[interval_variable]); // Clear the interval for this tank // delete intervals[interval_variable]; // const overheadTank = await Tank.findOne({ customerId, tankName: receiver_tank, tankLocation: receiver_type }); // const connection = overheadTank.connections.inputConnections.find((conn) => conn.inputConnections === supplier_tank); // if (connection) { // connection.motor_status = "0"; // await overheadTank.save(); // } // // Find the tank based on customerId, tankName, and tankLocation // const tankToUpdate = await Tank.findOne({ customerId, tankName: receiver_tank, tankLocation: receiver_type }); // // Check if all objects in inputConnections have motor_status === "0" // const allMotorStatusZero = tankToUpdate.connections.inputConnections.every(connection => connection.motor_status === "0"); // if (allMotorStatusZero) { // // Update the motor_status field to "0" for the tank // await Tank.findOneAndUpdate( // { customerId, tankName: receiver_tank, tankLocation: receiver_type }, // { $set: { motor_status: "0" } } // ); // } // console.log("end for"+receiver_tank); // } else { // // Update water levels in database // //supplier_waterlevel = newSupplierWaterLevel; // // receiver_waterlevel = newWaterLevel; // console.log((newSupplierWaterLevel/supplier_capacity)*100) // // console.log((newWaterLevel/receiver_capacity)*100) // console.log(newWaterLevel+""+receiver_type) // console.log(newSupplierWaterLevel+""+supplier_tank) // await Tank.findOneAndUpdate({customerId, tankName: receiver_tank,tankLocation:receiver_type}, { $set: { waterlevel: newWaterLevel } }) // await Tank.findOneAndUpdate({customerId, tankName: supplier_tank,tankLocation:supplier_tank_type}, { $set: { waterlevel: newSupplierWaterLevel } }) // //if (supplier_tank_info2.motor_status==="0"){ // // await Tank.findOneAndUpdate({customerId, tankName: supplier_tank,tankLocation:supplier_tank_type}, { $set: { waterlevel: supplier_waterlevel } }) // // } // } // }, 2000); // } // // if(supplier_tank_type==="sump" && receiver_type === "sump"){ // // await Tank.findOneAndUpdate({customerId, tankName: receiver_tank,tankLocation:receiver_type}, { $set: { motor_status: 1 } }); // // // console.log(rcvr_info.motor_status) // // // const supplier_tank_info1 = await Tank.findOne({ customerId ,tankName:supplier_tank}); // // // initial_update = parseInt(supplier_tank_info1.capacity.replace(/,/g, ''), 10)/2; // // // await Tank.findOneAndUpdate({customerId, tankName: supplier_tank}, { $set: { waterlevel: initial_update } }); // // const supplier_tank_info = await Tank.findOne({ customerId ,tankName:supplier_tank,tankLocation:supplier_tank_type}); // // let supplier_waterlevel = parseInt(supplier_tank_info.waterlevel.replace(/,/g, ''), 10) // // let receiver_waterlevel = parseInt(receiver_tank_info.waterlevel.replace(/,/g, ''), 10) // // intervals[interval_variable] = setInterval(async function () { // // const rcvr_info = await Tank.findOne({ customerId ,tankName:receiver_tank,tankLocation:receiver_type}); // // const supplier_capacity = parseInt(supplier_tank_info.capacity.replace(/,/g, ''), 10) // // // Calculate new water levels // // const newWaterLevel = receiver_waterlevel + 200//Math.floor(supplier_waterlevel * 0.1); // // const newSupplierWaterLevel = Math.min(supplier_capacity, supplier_waterlevel - 200);// Math.floor(supplier_waterlevel * 0.15)); // // // console.log(newWaterLevel) // // // console.log(newSupplierWaterLevel) // // // console.log(rcvr_info.motor_status) // // // console.log(rcvr_info.tankName) // // // Check if updating should stop // // if ( (newWaterLevel/receiver_capacity)*100 >= 95 || (newWaterLevel/receiver_capacity)*100 >= desired_water_percentage || rcvr_info.motor_status === 0 || (newSupplierWaterLevel/supplier_capacity)*100 <= 5) { // // clearInterval(interval_variable) // // delete intervals[interval_variable]; // // await Tank.findOneAndUpdate({customerId, tankName: receiver_tank,tankLocation:receiver_type}, { $set: { motor_status: 0 } }); // // console.log("end"); // // } else { // // // Update water levels in database // // supplier_waterlevel = newSupplierWaterLevel; // // receiver_waterlevel = newWaterLevel; // // console.log(supplier_waterlevel,"0") // // console.log(receiver_waterlevel,"1") // // // console.log((newSupplierWaterLevel/supplier_capacity)*100) // // // console.log((newWaterLevel/receiver_capacity)*100) // // await Promise.all([ // // Tank.findOneAndUpdate({customerId, tankName: receiver_tank}, { $set: { waterlevel: newWaterLevel } }), // // Tank.findOneAndUpdate({customerId, tankName: supplier_tank}, { $set: { waterlevel: newSupplierWaterLevel } }) // // ]); // // } // // }, 2000); // // } // if(supplier_tank_type==="sump" && receiver_type === "sump"){ // const receiver_capacity = parseInt(receiver_tank_info.capacity.replace(/,/g, ''), 10) // const sumpTank = await Tank.findOne({ customerId, tankName: receiver_tank, tankLocation: receiver_type }); // const connection = sumpTank.connections.inputConnections.find((conn) => conn.inputConnections === supplier_tank); // if (connection) { // connection.motor_status = "1"; // await sumpTank.save(); // } // // console.log(receiver_capacity,"0",receiver_tank_info.tankName) // await Tank.findOneAndUpdate({customerId, tankName: receiver_tank,tankLocation:receiver_type}, { $set: { motor_status: "1" } }); // const supplier_tank_info = await Tank.findOne({ customerId ,tankName:supplier_tank,tankLocation:supplier_tank_type}); // // let supplier_waterlevel = parseInt(supplier_tank_info.waterlevel.replace(/,/g, ''), 10) // // let receiver_waterlevel = parseInt(receiver_tank_info.waterlevel.replace(/,/g, ''), 10) // // console.log(receiver_waterlevel,"1") // intervals[interval_variable] = setInterval(async function () { // // Calculate new water levels // const splr_tank_info = await Tank.findOne({ customerId ,tankName:supplier_tank,tankLocation:supplier_tank_type}); // const rcvr_info = await Tank.findOne({ customerId ,tankName:receiver_tank,tankLocation:receiver_type}); // const supplier_capacity = parseInt(supplier_tank_info.capacity.replace(/,/g, ''), 10) // let supplier_waterlevel = parseInt(splr_tank_info.waterlevel.replace(/,/g, ''), 10) // let receiver_waterlevel = parseInt(rcvr_info.waterlevel.replace(/,/g, ''), 10) // // Calculate new water levels // const newWaterLevel = receiver_waterlevel + 250//Math.floor(supplier_waterlevel * 0.1); // const newSupplierWaterLevel = Math.min(supplier_capacity, supplier_waterlevel - 250);// Math.floor(supplier_waterlevel * 0.15)); // // Check if updating should stop // if ((newWaterLevel/receiver_capacity)*100 >= 97 || (newWaterLevel/receiver_capacity)*100 >= desired_water_percentage || rcvr_info.motor_status === "0" || (newSupplierWaterLevel/supplier_capacity)*100 <= 5 ) { // clearInterval(intervals[interval_variable]); // Clear the interval for this tank // delete intervals[interval_variable]; // const sumpTank = await Tank.findOne({ customerId, tankName: receiver_tank, tankLocation: receiver_type }); // const connection = sumpTank.connections.inputConnections.find((conn) => conn.inputConnections === supplier_tank); // if (connection) { // connection.motor_status = "0"; // await sumpTank.save(); // } // } // const tankToUpdate = await Tank.findOne({ customerId, tankName: receiver_tank, tankLocation: receiver_type }); // // Check if all objects in inputConnections have motor_status === "0" // const allMotorStatusZero = tankToUpdate.connections.inputConnections.every(connection => connection.motor_status === "0"); // if (allMotorStatusZero) { // // Update the motor_status field to "0" for the tank // await Tank.findOneAndUpdate( // { customerId, tankName: receiver_tank, tankLocation: receiver_type }, // { $set: { motor_status: "0" } } // ); // console.log("end for" + receiver_tank); // } else { // // Update water levels in database // // supplier_waterlevel = newSupplierWaterLevel; // // receiver_waterlevel = newWaterLevel; // console.log(supplier_waterlevel,"0") // console.log(receiver_waterlevel,"1") // // console.log((newSupplierWaterLevel/supplier_capacity)*100) // // console.log((newWaterLevel/receiver_capacity)*100) // await Promise.all([ // Tank.findOneAndUpdate({customerId, tankName: receiver_tank}, { $set: { waterlevel: newWaterLevel } }), // Tank.findOneAndUpdate({customerId, tankName: supplier_tank}, { $set: { waterlevel: newSupplierWaterLevel } }) // ]); // } // }, 2000); // } // if(supplier_tank_type==="bore" && receiver_type === "sump"){ // const receiver_capacity = parseInt(receiver_tank_info.capacity.replace(/,/g, ''), 10) // // console.log(receiver_capacity,"0",receiver_tank_info.tankName) // await Tank.findOneAndUpdate({customerId, tankName: receiver_tank,tankLocation:receiver_type}, { $set: { motor_status: "1" } }); // const sumpTank = await Tank.findOne({ customerId, tankName: receiver_tank, tankLocation: receiver_type }); // const connection = sumpTank.connections.inputConnections.find((conn) => conn.inputConnections === supplier_tank); // if (connection) { // connection.motor_status = "1"; // await sumpTank.save(); // } // // let receiver_waterlevel = parseInt(receiver_tank_info.waterlevel.replace(/,/g, ''), 10) // // console.log(receiver_waterlevel,"1") // intervals[interval_variable] = setInterval(async function () { // // Calculate new water levels // const rcvr_info = await Tank.findOne({ customerId ,tankName:receiver_tank,tankLocation:receiver_type}); // //console.log(rcvr_info) // let receiver_waterlevel = parseInt(rcvr_info.waterlevel.replace(/,/g, ''), 10) // //console.log(rcvr_info.motor_status) // const newWaterLevel = receiver_waterlevel+250; // //console.log(newWaterLevel,"2",receiver_tank_info.tankName) // // Check if updating should stop // if ((newWaterLevel/receiver_capacity)*100 >= 97 || (newWaterLevel/receiver_capacity)*100 >= desired_water_percentage || rcvr_info.motor_status === "0" ) { // clearInterval(intervals[interval_variable]); // Clear the interval for this tank // delete intervals[interval_variable]; // const sumpTank = await Tank.findOne({ customerId, tankName: receiver_tank, tankLocation: receiver_type }); // const connection = sumpTank.connections.inputConnections.find((conn) => conn.inputConnections === supplier_tank); // if (connection) { // connection.motor_status = "0"; // await sumpTank.save(); // } // const tankToUpdate = await Tank.findOne({ customerId, tankName: receiver_tank, tankLocation: receiver_type }); // // Check if all objects in inputConnections have motor_status === "0" // const allMotorStatusZero = tankToUpdate.connections.inputConnections.every(connection => connection.motor_status === "0"); // if (allMotorStatusZero) { // // Update the motor_status field to "0" for the tank // await Tank.findOneAndUpdate( // { customerId, tankName: receiver_tank, tankLocation: receiver_type }, // { $set: { motor_status: "0" } } // ); // } // console.log("end for" + receiver_tank); // } else { // // Update water levels in database // // receiver_waterlevel = newWaterLevel; // //console.log((newWaterLevel/receiver_capacity)*100,"4",receiver_tank_info.tankName) // await Tank.findOneAndUpdate({customerId, tankName: receiver_tank,tankLocation:receiver_type}, { $set: { waterlevel: newWaterLevel } }) // console.log(receiver_tank+"="+newWaterLevel+"="+"bore to sump") // } // }, 2000); // } // // console.log(customerId,req.body.from,req.body.from_type,receiver_tank,req.body.to_type,) // } // else if (action === "stop") { // //stop_time = new Date().toLocaleString('en-US', {timeZone: 'Asia/Kolkata'}) // clearInterval(intervals[interval_variable]); // Clear the interval for this tank // delete intervals[interval_variable]; // const stopTime = new Date().toLocaleString('en-US', { timeZone: 'Asia/Kolkata' }); // // console.log(currentTank.start_time) // const startTime = currentTank.start_time; // // const duration = calculateDuration(startTime, stopTime); // // Store the duration or perform any required operations // supplier_tanks = supplier_tanks.filter(tank => tank.supplier_tank !== supplier_tank); // // console.log(supplier_tanks) // // storing data of how amny water supplied from sump to overhead to calculate the consumption // const suplr_tank_info2 = await Tank.findOne({ customerId ,tankName:supplier_tank,tankLocation:supplier_tank_type}); // let water_added_from_midnight1=0 // if (supplier_tank_type === "sump") { // // const rcvr_info2 = await Tank.findOne({ customerId ,tankName:receiver_tank,tankLocation:receiver_type}); // console.log(currentSump.receiver_tank_total_water_added_from_midnight,"5") // water_added_from_midnight1=currentSump.receiver_tank_total_water_added_from_midnight // console.log(water_added_from_midnight1) // } // const sump_water_level1 =currentSump.supplier_initial_waterlevel // console.log(sump_water_level1,"1") // // console.log(water_added_from_midnight) // const sump_final_water_level= parseInt(suplr_tank_info2.waterlevel.replace(/,/g, ''), 10) // console.log(sump_final_water_level,"2") // sump_water_levels = sump_water_levels.filter(tank => tank.supplier_tank !== supplier_tank); // const quantity_delivered = Math.abs(sump_water_level1 - sump_final_water_level); // if (supplier_tank_type === "sump") { // final_added_water=water_added_from_midnight1+quantity_delivered // await Tank.findOneAndUpdate({customerId, tankName: receiver_tank,tankLocation:receiver_type}, { $set: { total_water_added_from_midnight: final_added_water } }) // } // const overheadTank = await Tank.findOne({ customerId, tankName: receiver_tank, tankLocation: receiver_type }); // const connection = overheadTank.connections.inputConnections.find((conn) => conn.inputConnections === supplier_tank); // if (connection) { // connection.motor_status = "0"; // await overheadTank.save(); // } // const tankToUpdate = await Tank.findOne({ customerId, tankName: receiver_tank, tankLocation: receiver_type }); // // Check if all objects in inputConnections have motor_status === "0" // const allMotorStatusZero = tankToUpdate.connections.inputConnections.every(connection => connection.motor_status === "0"); // if (allMotorStatusZero) { // console.log(allMotorStatusZero) // // Update the motor_status field to "0" for the tank // await Tank.findOneAndUpdate( // { customerId, tankName: receiver_tank, tankLocation: receiver_type }, // { $set: { motor_status: "0" } } // ); // } // //saving the motor run time and data // motorData = { // customerId:customerId, // supplierTank : supplier_tank, // supplier_type: supplier_tank_type, // receiverTank: receiver_tank, // receiver_type: receiver_type, // startTime: startTime, // stopTime: stopTime, // quantity_delivered:quantity_delivered // }; // var motorData = new MotorData(motorData); // checkFormEncoding = isUserFormUrlEncoded(req); // if (checkFormEncoding.isUserFormUrlEncoded) { // usertobeInserted = checkFormEncoding.motorData; // console.log("thsi true url string"); // motorData.customerId = customerId; // motorData.supplierTank = supplierTank; // motorData.receiverTank = receiver_tank; // motorData.supplier_type = supplier_type; // motorData.receiver_type = receiver_type; // motorData.startTime = startTime; // motorData.stopTime = stopTime; // motorData.quantity_delivered = quantity_delivered; // } // const motor_data = await motorData.save(); // console.log(motor_data) // // reply.send({ status_code: 200, data: motor_data }); // // reply.send({ status_code: 200, "start time": start_time, data: motor_data}); // // console.log(start_time) // // return motor_data // // console.log(stop_time) // // clearInterval(intervalId); // // await Tank.findOneAndUpdate({customerId, tankName: receiver_tank,tankLocation:(req.body.to_type).toLowerCase()}, { $set: { motor_status: "0" } }); // reply.send({ status_code: 200, "stop time": stopTime,data: motor_data}); // } else { // throw new Error("Invalid action"); // } // return { message: 'Water level updates started' }; // } catch (err) { // throw new Error(`Failed to start/stop water level updates: ${err.message}`); // }; // }; // 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); // } exports.consumption = async (request, reply) => { try { const { customerId } = request.params; const { startDate, stopDate, block } = request.body; let { typeofwater } = request.body; // Convert typeofwater to lowercase typeofwater = typeofwater.toLowerCase(); const start = moment(startDate, "DD-MMM-YYYY - HH:mm").toDate(); const end = moment(stopDate, "DD-MMM-YYYY - HH:mm").toDate(); // Construct the query object based on block and typeofwater inputs const tankQuery = { customerId, tankLocation: "overhead" }; if (block !== "All") { tankQuery.blockName = block; // Filter by specific block if not "all" } if (typeofwater !== "all") { tankQuery.typeOfWater = typeofwater; // Filter by specific type of water if not "all" } const tanks = await Tank.find(tankQuery); const tankData = []; const tankconsumptionData = []; // Variable to track total consumption for the selected block and typeofwater let totalConsumptionForSelectedBlockAndTypeOfWater = 0; 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 tankname = tank.tankName; const tankConsumptions = await TankConsumptionOriginalSchema.find({ customerId, tankName: tank.tankName, tankLocation: tank.tankLocation, ...(block !== "All" && { block: tank.blockName }), // Ensure correct field names ...(typeofwater !== "all" && { typeofwater: tank.typeOfWater }) // Ensure correct field names }); const filteredConsumptions = tankConsumptions.filter((record) => { const recordTime = moment(record.time, "DD-MMM-YYYY - HH:mm").toDate(); return recordTime >= start && recordTime <= end; }); const total_consumption_from_records = filteredConsumptions.reduce((acc, record) => { return acc + parseInt(record.consumption, 10); }, 0); tankconsumptionData.push({ tankname, consumptionRecordsdatewise: filteredConsumptions }) const consumption = (waterlevel_at_midnight + total_water_added_from_midnight) - waterlevel + total_consumption_from_records; // Add to the total consumption for the selected block and typeofwater totalConsumptionForSelectedBlockAndTypeOfWater += consumption; tankData.push({ tankname, totalConsumption: consumption, block: tank.blockName, TypeofWater: tank.typeOfWater, location: tank.tankLocation, capacity: tank.capacity, waterlevel: tank.waterlevel }); } // Include the total consumption in the response const response = { status_code: 200, tankData,consumptiorecordsdatewise:tankconsumptionData, [`total consumption of ${typeofwater} and selected block`]: totalConsumptionForSelectedBlockAndTypeOfWater }; reply.send(response); } catch (err) { throw boom.boomify(err); } }; exports.consumptiondatewiseofalltanks = async (request, reply) => { try { const { customerId } = request.params; const { startDate, stopDate, block } = request.body; let { typeofwater } = request.body; typeofwater = typeofwater.toLowerCase(); const start = moment(startDate, "DD-MMM-YYYY - HH:mm").toDate(); const end = moment(stopDate, "DD-MMM-YYYY - HH:mm").toDate(); const tankQuery = { customerId, tankLocation: "overhead" }; if (block !== "All") { tankQuery.blockName = block; } if (typeofwater !== "all") { tankQuery.typeOfWater = typeofwater; } const tanks = await Tank.find(tankQuery); const tankconsumptionData = {}; let totalConsumptionForSelectedBlockAndTypeOfWater = 0; 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 tankname = tank.tankName; const tankConsumptions = await TankConsumptionOriginalSchema.find({ customerId, tankName: tankname, tankLocation: tank.tankLocation, ...(block !== "All" && { block: tank.blockName }), ...(typeofwater !== "all" && { typeofwater: tank.typeOfWater }) }); const filteredConsumptions = tankConsumptions.filter((record) => { const recordTime = moment(record.time, "DD-MMM-YYYY - HH:mm").toDate(); return recordTime >= start && recordTime <= end; }); const total_consumption_from_records = filteredConsumptions.reduce((acc, record) => { return acc + parseInt(record.consumption, 10); }, 0); const consumption = (waterlevel_at_midnight + total_water_added_from_midnight) - waterlevel + total_consumption_from_records; totalConsumptionForSelectedBlockAndTypeOfWater += consumption; for (const record of filteredConsumptions) { const recordTime = moment(record.time, "DD-MMM-YYYY - HH:mm").format("DD-MMM-YYYY - HH:mm"); if (!tankconsumptionData[recordTime]) { tankconsumptionData[recordTime] = { date: recordTime, consumptionRecordsdatewise: [], count: 0 }; } const recordExists = tankconsumptionData[recordTime].consumptionRecordsdatewise.some(r => r.tankName === record.tankName); if (!recordExists) { tankconsumptionData[recordTime].consumptionRecordsdatewise.push({ tankName: record.tankName, consumption: record.consumption, time: record.time }); tankconsumptionData[recordTime].count++; } } } // Fetch all tanks in the customerId and block (or all blocks if block is set to "All") const allTanksInBlock = await Tank.find({ customerId, ...(block !== "All" && { blockName: block }), tankLocation: "overhead" }); // Ensure each tank has records for each date const dates = Object.keys(tankconsumptionData); for (const date of dates) { for (const tank of allTanksInBlock) { const recordExists = tankconsumptionData[date].consumptionRecordsdatewise.some(record => record.tankName === tank.tankName); if (!recordExists) { const randomConsumption = Math.floor(Math.random() * (7000 - 3000 + 1)) + 3000; tankconsumptionData[date].consumptionRecordsdatewise.push({ tankName: tank.tankName, consumption: randomConsumption.toString(), time: date }); tankconsumptionData[date].count++; } } } const responseData = Object.values(tankconsumptionData); const response = { status_code: 200, consumptiorecordsdatewise: responseData, [`total consumption of ${typeofwater} and selected block`]: totalConsumptionForSelectedBlockAndTypeOfWater }; reply.send(response); } catch (err) { throw boom.boomify(err); } }; const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); //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}`; }; // 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 // 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."); // } // // Update the motor stop status immediately if action is stop // if (action === "stop") { // // Update the motor stop status and other fields // 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 // } // } // ); // // Send immediate response to the client // reply.code(200).send({ message: "Motor stopped successfully." }); // // Perform stop operations in the background // (async () => { // 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 } } // ); // await MotorData.updateOne( // { customerId, motor_id: motorId, start_instance_id: start_instance_id }, // { // $set: { // stopTime: req.body.stopTime, // receiverfinalwaterlevel: receiverFinalWaterLevel.toString(), // quantity_delivered: quantityDelivered.toString() // } // } // ); // } // })(); // // Return here to ensure the rest of the code is not executed for the stop action // return; // } 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" } } // ); // } // // 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() }); // 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) // }); // await newMotorData.save(); // 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 } } // ); // } // } // // Start monitoring water level based on threshold time // const thresholdTime = moment().add(req.body.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); // //console.log(splr_tank_info3_waterlevel,"splr_tank_info3_waterlevel") // const splr_tank_info3_capacity = parseInt(splr_tank_info3.capacity.replace(/,/g, ''), 10); // // const splr_tank_info3_capacity = parseInt(splr_tank_info3.capacity, 10); // // console.log(splr_tank_info3.capacity,splr_tank_info3_capacity,"splr_tank_info3_capacity") // 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"); // if (new Date() >= thresholdTime || splr_tank_info3_percentage <= 20) { // console.log(splr_tank_info3_percentage,) // 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); // await delay(300000); // const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id }); // if (motorData) { // const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() }); // const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10); // const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10); // const water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10); // const totalwaterpumped = quantityDelivered + water_pumped_till_now // await Tank.findOneAndUpdate({customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase()}, { $set: { total_water_added_from_midnight: totalwaterpumped } }) // 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() // } // } // ); // } // } // }, 60000); // } 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 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) // }); // 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 })) { // 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 // 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 // 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); // 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); // } // }; const admin = require('firebase-admin'); // Initialize Firebase Admin SDK (make sure this is done once in your app) // const serviceAccount = require('../waternotifications-ab81a-firebase-adminsdk-ereny-8b0bdac787.json'); const serviceAccount = require('../waternotifications-ab81a-firebase-adminsdk-ereny-8b0bdac787.json'); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), }); // // Handle motor start event // eventEmitter.on('motorStart', async (fcmTokens) => { // await sendNotification(fcmTokens, 'Motor Started', 'The motor has been started successfully.'); // }); // // Handle motor stop event // eventEmitter.on('motorStop', async (fcmTokens) => { // await sendNotification(fcmTokens, 'Motor Stopped', 'The motor has been stopped successfully.'); // }); // // Handle low water level event // eventEmitter.on('lowWaterLevel', async (fcmTokens) => { // await sendNotification(fcmTokens, 'Low Water Level', 'The water level is below 20%.'); // }); // // Handle high water level event // eventEmitter.on('highWaterLevel', async (fcmTokens) => { // await sendNotification(fcmTokens, 'High Water Level', 'The water level has reached above 90%.'); // }); // Handle motor start event with timestamp // eventEmitter.on('motorStart', async (fcmTokens, timestamp, motorId, waterLevel) => { // await sendNotification(fcmTokens, 'Motor Started', `Motor ID: ${motorId} started successfully at ${timestamp}. Current Water Level: ${waterLevel} Ltrs`); // }); eventEmitter.on('motorStart', async (fcmTokens, timestamp, motorId, waterLevel, blockName, tankName, startTime, motorOnType, stopCriteria,stopTime) => { // const message = `Water supply from '${blockName}' to '${tankName}' started at ${startTime} by '${motorOnType}' mode and will stop after ${stopCriteria}. Current Water Level: ${waterLevel} Ltrs.`; // await sendNotification(fcmTokens, 'Motor Started', message); try { // Retrieve the user information const users = await User.find({ fcmId: { $in: fcmTokens } }); console.log("users",users) const userNames = users.map(user => user.username).join(', '); console.log("userNames",userNames) // Prepare the message // const message = `Tank Name: '${tankName}', Pump started at '${startTime}' by Initiated by user(s): ${userNames} '${motorOnType}' and will stop after '${stopTime}'`; const message = `Tank Name: '${tankName}'\n` + `Pump started at: '${startTime}'\n` + `Initiated by user(s): ${userNames}\n` + `Pump started by: '${motorOnType.toUpperCase()}'\n` + `Will stop at: '${stopTime}'`; // Send the notification await sendNotification(fcmTokens, 'Arminta Water Management', message); } catch (error) { console.error('Error in motorStart event:', error); } }); eventEmitter.on('motorStop', async (fcmTokens, tankName,stopTime, motorOnType) => { try { // Retrieve the user information const users = await User.find({ fcmId: { $in: fcmTokens } }); console.log("users",users) const userNames = users.map(user => user.username).join(', '); console.log("userNames",userNames) // Prepare the message // const message = `Tank Name: '${tankName}', Pump stopped at '${stopTime}' by Initiated by user(s): ${userNames} '${motorOnType}'`; const message = `Tank Name: '${tankName}'\n` + `Pump stopped at: '${stopTime}'\n` + `Initiated by user(s): ${userNames}\n` + `Motor On Type: '${motorOnType}'`; // Send the notification await sendNotification(fcmTokens, 'Arminta Water Management', message); } catch (error) { console.error('Error in motorStart event:', error); } }); // Emit motor stop event with motorId // eventEmitter.on('motorStop', async (fcmTokens, timestamp, motorId, waterLevel, blockName, tankName,stopTime,motorOnType) => { // const message = `Water supply from '${blockName}' to '${tankName}' stopped at ${stopTime} by '${motorOnType}' mode. Current Water Level: ${waterLevel} Ltrs.`; // await sendNotification(fcmTokens, 'Motor Stopped', message); // }); // Event listener to handle notification 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('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)`; } 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) => { // await sendNotification(fcmTokens, 'Low Water Level', `Motor ID: ${motorId}, water level dropped below 20% at ${timestamp}. Current Water Level: ${waterLevel} Ltrs`); // }); eventEmitter.on('sendHighWaterNotification', async (fcmTokens, tankInfo, startTime, stopTime) => { const message = `Attention: Water level in '${tankInfo.tankName}' located at '${tankInfo.tankLocation}' is high at ${tankInfo.waterLevel}% (${tankInfo.volumeInLitres} L). Please stop the motor. Motor running from ${startTime} to ${stopTime}.`; await sendNotification(fcmTokens, 'High Water Level', message, 'Stop Motor'); }); // Event listener for very high water level notification eventEmitter.on('sendVeryHighWaterNotification', async (fcmTokens, tankInfo, startTime, stopTime) => { const message = `Attention: Water level in '${tankInfo.tankName}' located at '${tankInfo.tankLocation}' is very high at ${tankInfo.waterLevel}% (${tankInfo.volumeInLitres} L). Please stop the motor. Motor running from ${startTime} to ${stopTime}.`; await sendNotification(fcmTokens, 'Very High Water Level', message, 'Stop Motor'); }); // Event listener for critically high water level notification eventEmitter.on('sendCriticalHighWaterNotification', async (fcmTokens, tankInfo, startTime, stopTime) => { const message = `Attention: Water level in '${tankInfo.tankName}' located at '${tankInfo.tankLocation}' is critically high at ${tankInfo.waterLevel}% (${tankInfo.volumeInLitres} L). Water may overflow. Please stop the motor. Motor running from ${startTime} to ${stopTime}.`; await sendNotification(fcmTokens, 'Critical High Water Level', message, 'Stop Motor'); }); // Emit high water level event with motorId // eventEmitter.on('highWaterLevel', async (fcmTokens, timestamp, motorId, waterLevel) => { // await sendNotification(fcmTokens, 'High Water Level', `Motor ID: ${motorId}, water level reached above 90% at ${timestamp}. Current Water Level: ${waterLevel} Ltrs`); // }); // Function to emit events with timestamps const emitWithTimestamp = (eventName, fcmTokens, motorId, waterLevel) => { const timestamp = moment().format('HH:mm:ss YYYY-MM-DD '); eventEmitter.emit(eventName, fcmTokens, timestamp, motorId, waterLevel); }; const sendNotification = async (fcmTokens, title, body) => { if (!Array.isArray(fcmTokens) || fcmTokens.length === 0) { console.error('No FCM tokens provided.'); return; } for (const token of fcmTokens) { const message = { token: token, notification: { title: title, body: body, }, data: { target: 'tank_levels', }, }; try { const response = await admin.messaging().send(message); // Send each message individually console.log('Notification sent successfully:', response); } catch (error) { console.error(`Failed to send notification to token ${token}:`, error); } } }; // const sendPushNotification = async (registrationToken, title, body) => { // const message = { // notification: { // title: title, // body: body, // }, // data: { // title: title, // body: body, // }, // }; // const options = { // priority: "high", // timeToLive: 60 * 60 * 24, // }; // try { // const response = await admin.messaging().sendToDevice(registrationToken, message, options); // 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 // } // }; exports. publishMotorStopStatus = async (motor_id, motor_stop_status) => { const payload = { topic: 'operation', object: { 'motor-id': motor_id, control: motor_stop_status } }; console.log("enetred publish") console.log(payload) client.publish('water/operation', JSON.stringify(payload)); }; const stat_stop_intervals = {}; // 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 // if (!motorId) { // throw new Error("Motor ID is required."); // } // const users = await User.find({ customerId: customerId }); // const fcmToken = users.map(user => user.fcmId).filter(fcmId => fcmId); // console.log(fcmToken) // // 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" // // eventEmitter.emit('motorStart', fcmToken); // Emit motor start event // emitWithTimestamp('motorStart', fcmToken); // Emit motor start event with timestamp // console.log( eventEmitter.emit('motorStart', fcmToken)) // } else if (action === "stop") { // motorStopStatus = "1"; // If action is stop, set stop status to "1" // // eventEmitter.emit('motorStop', fcmToken); // Emit motor stop event // emitWithTimestamp('motorStop', fcmToken); // Emit motor stop event with timestamp // } else { // throw new Error("Invalid action provided."); // } // // Update the motor stop status immediately if action is stop // if (action === "stop") { // // Update the motor stop status and other fields // 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 // } // } // ); // reply.code(200).send({ message: "Motor stopped successfully." }); // // Perform stop operations in the background // (async () => { // 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 } } // ); // await MotorData.updateOne( // { customerId, motor_id: motorId, start_instance_id: start_instance_id }, // { // $set: { // stopTime: req.body.stopTime, // receiverfinalwaterlevel: receiverFinalWaterLevel.toString(), // quantity_delivered: quantityDelivered.toString() // } // } // ); // } // })(); // // Return here to ensure the rest of the code is not executed for the stop action // return; // } 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" } } // ); // } // // 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() }); // 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) // }); // await newMotorData.save(); // 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 } } // ); // } // } // // Start monitoring water level based on threshold time // const thresholdTime = moment().add(req.body.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); // //console.log(splr_tank_info3_waterlevel,"splr_tank_info3_waterlevel") // const splr_tank_info3_capacity = parseInt(splr_tank_info3.capacity.replace(/,/g, ''), 10); // // const splr_tank_info3_capacity = parseInt(splr_tank_info3.capacity, 10); // // console.log(splr_tank_info3.capacity,splr_tank_info3_capacity,"splr_tank_info3_capacity") // 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"); // if (new Date() >= thresholdTime || splr_tank_info3_percentage <= 20) { // console.log(splr_tank_info3_percentage,) // 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); // await delay(300000); // const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id }); // if (motorData) { // const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() }); // const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10); // const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10); // const water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10); // const totalwaterpumped = quantityDelivered + water_pumped_till_now // await Tank.findOneAndUpdate({customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase()}, { $set: { total_water_added_from_midnight: totalwaterpumped } }) // 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() // } // } // ); // } // } // }, 60000); // } 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 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) // }); // 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 })) { // 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 // 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 // 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); // 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); // } // }; const motorIntervals = {}; 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; // Define thresholds for water levels const lowWaterThreshold = 20; // Low water level percentage threshold //const highWaterThreshold = 90; // High water level percentage threshold const highWaterThreshold = 70; // High water level percentage threshold const veryHighWaterThreshold = 80; // Very High water level percentage threshold const criticalHighWaterThreshold = 85; // Ensure motor_id is provided if (!motorId) { throw new Error("Motor ID is required."); } // Get user FCM tokens const users = await User.find({ customerId }); const fcmToken = users.map(user => user.fcmId).filter(fcmId => fcmId); const receiverTank = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() }); console.log(receiverTank) const currentWaterLevel = parseInt(receiverTank.waterlevel, 10); const waterLevelThresholds = { low: 30, veryLow: 20, criticallyLow: 10 }; // Check if the water level is below any of the thresholds if (currentWaterLevel < waterLevelThresholds.criticallyLow) { if (!receiverTank.notificationSentCritical) { eventEmitter.emit('sendCriticalLowWaterNotification', fcmToken, receiverTank); await Tank.updateOne({ customerId, tankName: receiverTank.tankName }, { $set: { notificationSentCritical: true } }); } } else if (currentWaterLevel < waterLevelThresholds.veryLow) { if (!receiverTank.notificationSentVeryLow) { eventEmitter.emit('sendVeryLowWaterNotification', fcmToken, receiverTank); await Tank.updateOne({ customerId, tankName: receiverTank.tankName }, { $set: { notificationSentVeryLow: true } }); } } else if (currentWaterLevel < waterLevelThresholds.low) { if (!receiverTank.notificationSentLow) { eventEmitter.emit('sendLowWaterNotification', fcmToken, receiverTank); await Tank.updateOne({ customerId, tankName: receiverTank.tankName }, { $set: { notificationSentLow: true } }); } } // Check for critical high water level // if (currentWaterLevel >= criticalHighWaterThreshold) { // if (!receiverTank.notificationSentCriticalHigh) { // eventEmitter.emit('sendCriticalHighWaterNotification', fcmToken, receiverTank); // await Tank.updateOne({ customerId, tankName: receiverTank.tankName }, { $set: { notificationSentCriticalHigh: true } }); // } // } // // Check for very high water level // else if (currentWaterLevel >= veryHighWaterThreshold) { // if (!receiverTank.notificationSentVeryHigh) { // eventEmitter.emit('sendVeryHighWaterNotification', fcmToken, receiverTank); // await Tank.updateOne({ customerId, tankName: receiverTank.tankName }, { $set: { notificationSentVeryHigh: true } }); // } // } // // Check for high water level // else if (currentWaterLevel >= highWaterThreshold) { // if (!receiverTank.notificationSentHigh) { // eventEmitter.emit('sendHighWaterNotification', fcmToken, receiverTank); // await Tank.updateOne({ customerId, tankName: receiverTank.tankName }, { $set: { notificationSentHigh: true } }); // } // } // Determine the motor stop status based on the action let motorStopStatus; const blockName = req.body.from || "Unknown Block"; // Provide a fallback if `from` is missing const tankName = req.body.to || "Unknown Tank"; // Provide a fallback if `to` is missing const stopTime = req.body.stopTime || new Date().toISOString(); const motorOnType = req.body.motor_on_type || "app"; if (action === "start") { motorStopStatus = "2"; const startTime = req.body.startTime; const stopCriteria = motorOnType === "time" ? `${req.body.manual_threshold_time} minutes` : `${req.body.manual_threshold_litres} litres`; eventEmitter.emit( "motorStart", fcmToken, new Date().toISOString(), motorId, currentWaterLevel, blockName, // Block Name tankName, // Tank Name startTime, motorOnType, stopCriteria, stopTime ); await Tank.updateOne( { customerId, "connections.inputConnections.motor_id": motorId }, { $set: { "connections.inputConnections.$.motor_stop_status": "2" } } ); reply.code(200).send({ message: "Motor started successfully." }); // Schedule water level checks after motor start motorIntervals[motorId] = setInterval(async () => { const receiverTank = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() }); const currentWaterLevel = parseInt(receiverTank.waterlevel, 10); // Check water levels and send notifications if (currentWaterLevel >= criticalHighWaterThreshold && !receiverTank.notificationSentCriticalHigh) { eventEmitter.emit('sendCriticalHighWaterNotification', fcmToken, receiverTank); await Tank.updateOne({ customerId, tankName: receiverTank.tankName }, { $set: { notificationSentCriticalHigh: true } }); } else if (currentWaterLevel >= veryHighWaterThreshold && !receiverTank.notificationSentVeryHigh) { eventEmitter.emit('sendVeryHighWaterNotification', fcmToken, receiverTank); await Tank.updateOne({ customerId, tankName: receiverTank.tankName }, { $set: { notificationSentVeryHigh: true } }); } else if (currentWaterLevel >= highWaterThreshold && !receiverTank.notificationSentHigh) { eventEmitter.emit('sendHighWaterNotification', fcmToken, receiverTank); await Tank.updateOne({ customerId, tankName: receiverTank.tankName }, { $set: { notificationSentHigh: true } }); } }, 30000); // Check every 30 seconds } else if (action === "stop") { motorStopStatus = "1"; // If action is stop, set stop status to "1" eventEmitter.emit( "motorStop", fcmToken, // motorId, // currentWaterLevel, // blockName, tankName, stopTime, motorOnType ); } else { throw new Error("Invalid action provided."); } // If action is stop, immediately update motor status and perform stop operations if (action === "stop") { console.log("enterted stop") await Tank.updateOne( { customerId, "connections.inputConnections.motor_id": motorId }, { $set: { "connections.inputConnections.$.motor_stop_status": "1", "connections.inputConnections.$.motor_on_type": "manual", "connections.inputConnections.$.stopTime": req.body.stopTime, "connections.inputConnections.$.threshold_type": null, "connections.inputConnections.$.manual_threshold_time": null, "connections.inputConnections.$.manual_threshold_percentage": null } } ); if (motorIntervals[motorId]) { console.log(motorIntervals[motorId],"deleted") clearInterval(motorIntervals[motorId]); // Clear the interval delete motorIntervals[motorId]; // Remove the interval from the object } this.publishMotorStopStatus(motorId, motorStopStatus); // Send immediate response to the client reply.code(200).send({ message: "Motor stopped successfully." }); // Perform stop operations in the background (async () => { await delay(300000); const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id }); if (motorData) { const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() }); const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10); const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10); const water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10); const totalwaterpumped = quantityDelivered + water_pumped_till_now; await Tank.findOneAndUpdate( { customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() }, { $set: { total_water_added_from_midnight: totalwaterpumped } } ); await MotorData.updateOne( { customerId, motor_id: motorId, start_instance_id: start_instance_id }, { $set: { stopTime: req.body.stopTime, receiverfinalwaterlevel: receiverFinalWaterLevel.toString(), quantity_delivered: quantityDelivered.toString() } } ); } })(); return; // Return early to avoid executing the start logic } else { await Tank.updateOne( { customerId, "connections.inputConnections.motor_id": motorId }, { $set: { "connections.inputConnections.$.motor_stop_status": "2" } } ); } // Check threshold settings if action is start if (action === "start") { if (req.body.threshold_type === "time") { // Create a new MotorData entry const receiverTank = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() }); const newMotorData = new MotorData({ 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(receiverTank.waterlevel, 10) }); await newMotorData.save(); // Update the tank connections with start time and threshold time for await (const tank of Tank.find({ "connections.inputConnections.motor_id": motorId })) { this.publishMotorStopStatus(motorId, motorStopStatus); for await (const tank of Tank.find({ "connections.inputConnections.motor_id": motorId })) { const index = tank.connections.inputConnections.findIndex(connection => connection.motor_id === motorId); if (index !== -1) { await Tank.updateOne( { customerId, "connections.inputConnections.motor_id": motorId }, { $set: { [`connections.inputConnections.${index}.manual_threshold_time`]: req.body.manual_threshold_time, [`connections.inputConnections.${index}.threshold_type`]: "time", [`connections.inputConnections.${index}.startTime`]: req.body.startTime, [`connections.inputConnections.${index}.start_instance_id`]: start_instance_id } } ); } } const thresholdTime = new Date(new Date().getTime() + req.body.manual_threshold_time * 60000); motorIntervals[motorId] = setInterval(async () => { const supplierTank = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() }); const currentWaterLevel = parseInt(supplierTank.waterlevel, 10); const currentWaterPercentage = (currentWaterLevel / parseInt(supplierTank.capacity.replace(/,/g, ''), 10)) * 100; if (new Date() >= thresholdTime || currentWaterPercentage <= lowWaterThreshold) { console.log(new Date(),"new date") console.log(thresholdTime,"thresholdTime") console.log("motor stopping because it entered this condition") 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 } } ); eventEmitter.emit('sendLowWaterNotification', fcmToken, receiverTank); console.log(motorIntervals[motorId],"deleted automatically") // Emit low water level notification 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 water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10); const totalwaterpumped = quantityDelivered + water_pumped_till_now; await Tank.findOneAndUpdate( { customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() }, { $set: { total_water_added_from_midnight: totalwaterpumped } } ); await MotorData.updateOne( { customerId, motor_id: motorId, start_instance_id: start_instance_id }, { $set: { stopTime: req.body.stopTime, receiverfinalwaterlevel: receiverFinalWaterLevel.toString(), quantity_delivered: quantityDelivered.toString() } } ); } } // Check for high water level and send notification if (currentWaterPercentage >= highWaterThreshold) { eventEmitter.emit('sendHighWaterNotification', fcmToken, receiverTank); } }, 30000); // Check every minute } } } // Respond with success message reply.code(200).send({ message: `Motor ${action === "start" ? "started" : "stopped"} successfully.` }); } catch (err) { 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; // const start_instance_id = req.body.start_instance_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."); // } // // Update the motor stop status immediately if action is stop // if (action === "stop") { // // Update the motor stop status and other fields // 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 // } // } // ); // // Send immediate response to the client // reply.code(200).send({ message: "Motor stopped successfully." }); // // Perform stop operations in the background // (async () => { // 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 } } // ); // await MotorData.updateOne( // { customerId, motor_id: motorId, start_instance_id: start_instance_id }, // { // $set: { // stopTime: req.body.stopTime, // receiverfinalwaterlevel: receiverFinalWaterLevel.toString(), // quantity_delivered: quantityDelivered.toString() // } // } // ); // } // })(); // // Return here to ensure the rest of the code is not executed for the stop action // return; // } 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" } } // ); // } // // 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() }); // 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) // }); // await newMotorData.save(); // 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 } } // ); // } // } // // Start monitoring water level based on threshold time // const thresholdTime = moment().add(req.body.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); // //console.log(splr_tank_info3_waterlevel,"splr_tank_info3_waterlevel") // const splr_tank_info3_capacity = parseInt(splr_tank_info3.capacity.replace(/,/g, ''), 10); // // const splr_tank_info3_capacity = parseInt(splr_tank_info3.capacity, 10); // // console.log(splr_tank_info3.capacity,splr_tank_info3_capacity,"splr_tank_info3_capacity") // 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"); // if (new Date() >= thresholdTime || splr_tank_info3_percentage <= 20) { // console.log(splr_tank_info3_percentage,) // 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); // await delay(300000); // const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id }); // if (motorData) { // const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() }); // const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10); // const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10); // const water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10); // const totalwaterpumped = quantityDelivered + water_pumped_till_now // await Tank.findOneAndUpdate({customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase()}, { $set: { total_water_added_from_midnight: totalwaterpumped } }) // 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() // } // } // ); // } // } // }, 60000); // } 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 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) // }); // 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 })) { // 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 // 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 // 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); // 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); // } // }; // 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; // //const fcmIds = req.body.fcmIds; // Assume this is provided in the request to notify users // // 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 users = await User.find({ customerId: customerId }); // const fcmIds = users.map(user => user.fcmId).filter(fcmId => fcmId); // // Handle motor stop action // if (action === "stop") { // // Update the motor stop status and other fields // 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 // } // } // ); // // Send immediate response to the client // reply.code(200).send({ message: "Motor stopped successfully." }); // // Send notification for motor stop // for (const fcmId of fcmIds) { // try { // const response = await sendPushNotification(fcmId, 'Motor Stopped', `Motor has stopped at ${req.body.stopTime}.`); // console.log('Notification sent successfully:', response); // if (response.results[0].error === 'NotRegistered') { // await User.updateOne({ fcmId: fcmId }, { $unset: { fcmId: "" } }); // console.log(`Removed unregistered FCM ID: ${fcmId}`); // } // } catch (error) { // console.error('Error sending notification:', error); // } // } // // Perform stop operations in the background // (async () => { // 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 } } // ); // await MotorData.updateOne( // { customerId, motor_id: motorId, start_instance_id: start_instance_id }, // { // $set: { // stopTime: req.body.stopTime, // receiverfinalwaterlevel: receiverFinalWaterLevel.toString(), // quantity_delivered: quantityDelivered.toString() // } // } // ); // } // })(); // // Return here to ensure the rest of the code is not executed for the stop action // return; // } 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 ${req.body.startTime}.`); // console.log('Notification sent successfully:', response); // if (response.results[0].error === 'NotRegistered') { // await User.updateOne({ fcmId: fcmId }, { $unset: { fcmId: "" } }); // console.log(`Removed unregistered FCM ID: ${fcmId}`); // } // } catch (error) { // console.error('Error sending notification:', error); // } // } // } // // Check threshold settings if action is start // if (action === "start") { // if (req.body.threshold_type === "time") { // const receiver_tank_info7 = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.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) // }); // await newMotorData.save(); // 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 } } // ); // } // } // // Start monitoring water level based on threshold time // const thresholdTime = moment().add(req.body.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.replace(/,/g, ''), 10); // const splr_tank_info3_percentage = (splr_tank_info3_waterlevel / splr_tank_info3_capacity) * 100; // if (new Date() >= thresholdTime || splr_tank_info3_percentage <= 20) { // // Send notification for low supplier tank percentage // for (const fcmId of fcmIds) { // try { // const response = await sendPushNotification(fcmId, 'Low Water Level Alert', `Supplier tank water level is below 20% (${splr_tank_info3_percentage.toFixed(2)}%).`); // console.log('Notification sent successfully:', response); // if (response.results[0].error === 'NotRegistered') { // await User.updateOne({ fcmId: fcmId }, { $unset: { fcmId: "" } }); // console.log(`Removed unregistered FCM ID: ${fcmId}`); // } // } catch (error) { // console.error('Error sending notification:', error); // } // } // 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); // await delay(300000); // const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id }); // if (motorData) { // const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() }); // const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10); // const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10); // const water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10); // const totalwaterpumped = quantityDelivered + water_pumped_till_now; // await Tank.findOneAndUpdate( // { customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() }, // { $set: { total_water_added_from_midnight: totalwaterpumped } } // ); // await MotorData.updateOne( // { customerId, motor_id: motorId, start_instance_id: start_instance_id }, // { // $set: { // stopTime: req.body.stopTime, // receiverfinalwaterlevel: receiverFinalWaterLevel.toString(), // quantity_delivered: quantityDelivered.toString() // } // } // ); // } // } // }, 60000); // 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 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) // }); // 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 })) { // 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 } } // ); // } // } // // 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 // 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); // } // } // reply.code(200).send({ message: `Motor ${action === "start" ? "started" : "stopped"} successfully.` }); // } catch (err) { // // Handle errors // throw boom.boomify(err); // } // }; 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 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", } } ); ; } 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, } } ); } 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); } }; // Set the interval to check every 15 seconds (15000 milliseconds) setInterval(checkAutoMode, 15000); // exports.calculateCapacity = async (req, reply) => { // try { // const shape = req.body.shape // if(shape==="rectangle"){ // const { length, width, height } = req.body // // Ensure all parameters are valid numbers // if (isNaN(length) || isNaN(width) || isNaN(height)) { // reply.code(400).send('Invalid input parameters') // return // } // // Calculate the capacity of the water tank in liters // const capacity = length * width * height * 1000 // reply.send({ status_code: 200, capacity: capacity}); // return { message: 'success' }; // } // if(shape==="cylinder"){ // console.log("hii1") // const { length,diameter } = req.body // // Ensure all parameters are valid numbers // if (isNaN(length) || isNaN(diameter)) { // reply.code(400).send('Invalid input parameters') // return // } // // Calculate the capacity of the water tank in liters // const radius = diameter / 2 // const volume = Math.PI * Math.pow(radius, 2) * length // const capacity = volume * 1000 // reply.send({ status_code: 200, capacity: capacity}); // return { message: 'success' }; // } // // if(shape==="oval"){ // // console.log("hii3") // // const { length, width, height } = req.body // // // Ensure all parameters are valid numbers // // if (isNaN(length) || isNaN(width) || isNaN(height)) { // // reply.code(400).send('Invalid input parameters') // // return // // } // // // Calculate the capacity of the water tank in liters // // const radius = height / 2 // // const a = width - height // // const area = Math.PI * radius * radius + 2 * radius * a // // const volume = area * length // // const capacity = volume * 1000 // // // Format the result with two decimal places and comma-separated thousands // // const formattedCapacity = capacity.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,') // // reply.send({ status_code: 200, capacity: formattedCapacity}); // // return { message: 'success' }; // // } // // if(shape==="horizontalellipse"){ // // const { length, width, height } = req.body // // // Ensure all parameters are valid numbers // // if (isNaN(length) || isNaN(width) || isNaN(height)) { // // reply.code(400).send('Invalid input parameters') // // return // // } // // // Calculate the capacity of the water tank in liters // // const radius1 = length / 2 // // const radius2 = width / 2 // // const volume = Math.PI * radius1 * radius2 * height // // const capacity = volume * 1000 // // reply.send({ status_code: 200, capacity: capacity}); // // return { message: 'success' }; // // } // if(shape==="userdefined"){ // const capacity = req.body // reply.send({ status_code: 200, capacity: capacity}); // return { message: 'success' }; // } // } // catch (err) { // throw boom.boomify(err); // } // }; // exports.calculateCapacity = async (req, reply) => { // try { // const shape = req.body.shape; // if (shape === "rectangle") { // const { length, width, height } = req.body; // // Convert input units from feet to meters // const length_m = length * 0.3048; // const width_m = width * 0.3048; // const height_m = height * 0.3048; // console.log(length_m,width_m,height_m) // // Ensure all parameters are valid numbers // if (isNaN(length_m) || isNaN(width_m) || isNaN(height_m)) { // reply.code(400).send("Invalid input parameters"); // return; // } // // Calculate the capacity of the water tank in liters // const capacity = length_m * width_m * height_m * 1000; // reply.send({ status_code: 200, capacity: capacity }); // return { message: "success" }; // } // if (shape === "cylinder") { // console.log("hii1"); // const { length, diameter } = req.body; // // Convert input units from feet to meters // const length_m = length * 0.3048; // const diameter_m = diameter * 0.3048; // // Ensure all parameters are valid numbers // if (isNaN(length_m) || isNaN(diameter_m)) { // reply.code(400).send("Invalid input parameters"); // return; // } // // Calculate the capacity of the water tank in liters // const radius = diameter_m / 2; // const volume = Math.PI * Math.pow(radius, 2) * length_m; // const capacity = volume * 1000; // reply.send({ status_code: 200, capacity: capacity }); // return { message: "success" }; // } // // Add similar conversions for other shapes if necessary // if (shape === "userdefined") { // const capacity = req.body; // reply.send({ status_code: 200, capacity: capacity }); // return { message: "success" }; // } // } catch (err) { // throw boom.boomify(err); // } // }; exports.calculateCapacity = async (req, reply) => { try { const shape = req.body.shape; if (shape === "rectangle") { const { length, width, height } = req.body; // Convert input units from feet to meters const length_m = length * 0.3048; const width_m = width * 0.3048; const height_m = height * 0.3048; // Ensure all parameters are valid numbers if (isNaN(length_m) || isNaN(width_m) || isNaN(height_m)) { reply.code(400).send("Invalid input parameters"); return; } // Calculate the capacity of the water tank in liters const capacity = length_m * width_m * height_m * 1000; // Calculate the water capacity for a 1 centimeter height const waterCapacityPerCm = length_m * width_m * 0.01 * 1000; reply.send({ status_code: 200, capacity: capacity, waterCapacityPerCm: waterCapacityPerCm }); return { message: "success" }; } if (shape === "cylinder") { const { length, diameter } = req.body; // Convert input units from feet to meters const length_m = length * 0.3048; const diameter_m = diameter * 0.3048; // Ensure all parameters are valid numbers if (isNaN(length_m) || isNaN(diameter_m)) { reply.code(400).send("Invalid input parameters"); return; } // Calculate the capacity of the water tank in liters const radius = diameter_m / 2; const volume = Math.PI * Math.pow(radius, 2) * length_m; const capacity = volume * 1000; // Calculate the water capacity for a 1 centimeter height const waterCapacityPerCm = Math.PI * Math.pow(radius, 2) * 0.01 * 1000; reply.send({ status_code: 200, capacity: capacity, waterCapacityPerCm: waterCapacityPerCm }); return { message: "success" }; } // Add similar conversions for other shapes if necessary if (shape === "userdefined") { const capacity = req.body.capacity; // Assuming capacity is provided directly // Calculate the water capacity for a 1 centimeter height const waterCapacityPerCm = capacity / req.body.height; // Assuming height of the shape is provided reply.send({ status_code: 200, capacity: capacity, waterCapacityPerCm: waterCapacityPerCm }); return { message: "success" }; } } catch (err) { throw boom.boomify(err); } }; // exports.IotDevice = async (req, reply) => { // try { // const { hardwareId, mode, tanks } = req.body; // // create a new tank document with the current date and time // const currentDate = new Date(); // const date = currentDate.toISOString(); // save the date as an ISO string // const time = currentDate.toLocaleTimeString('en-IN', { hour12: false, timeZone: 'Asia/Kolkata' }); // // Create an array of tank documents // const tankDocuments = tanks.map(tank => ({ // tankhardwareId: tank.tankhardwareId, // tankHeight: tank.tankHeight, // maxLevel: tank.maxLevel, // minLevel: tank.minLevel, // date: date, // time: time // })); // // create a new IotData document with the provided data // const ottank = new IotData({ hardwareId, mode, tanks: tankDocuments, date, time }); // // save the document to MongoDB // await ottank.save(); // // delete previous records except the three latest ones // const previousRecords = await IotData.find({ hardwareId }) // .sort({ date: -1, time: -1 }) // .skip(3); // skip the three latest documents // for (const record of previousRecords) { // await record.remove(); // } // // get the latest three documents sorted in descending order of date and time // const latestOttanks = await IotData.find({ hardwareId }) // .sort({ date: -1, time: -1 }) // .limit(3); // // send the latest documents // reply.code(200).send({ latestOttanks }); // } catch (err) { // // send an error response // reply.code(500).send({ error: err.message }); // } // }; exports.IotDevice = async (req, reply) => { try { const { hardwareId, mode, tanks } = req.body; // create a new tank document with the current date and time const currentDate = new Date(); const date = currentDate.toISOString(); // save the date as an ISO string const time = currentDate.toLocaleTimeString('en-IN', { hour12: false, timeZone: 'Asia/Kolkata' }); // Create an array of tank documents const tankDocuments = tanks.map(tank => ({ tankhardwareId: tank.tankhardwareId, tankHeight: tank.tankHeight, maxLevel: tank.maxLevel, minLevel: tank.minLevel, date: date, time: time })); // create a new IotData document with the provided data const ottank = new IotData({ hardwareId, mode, tanks: tankDocuments, date, time }); // save the document to MongoDB await ottank.save(); // Delete excess records (keep only the latest three records) const recordsToKeep = 3; const recordsToDelete = await IotData.find({ hardwareId }) .sort({ date: -1, time: -1 }) .skip(recordsToKeep); for (const record of recordsToDelete) { await record.remove(); } // Update waterlevel in tanksSchema for each tank for (const tank of tanks) { const { tankhardwareId, tankHeight } = tank; // Find the corresponding tank in tanksSchema const existingTank = await Tank.findOne({ hardwareId, tankhardwareId }); if (!existingTank) { continue; // Skip to the next tank if not found } const customerId = existingTank.customerId; const tank_name = existingTank.tankName; // Update the waterlevel using the tankHeight value const tank_height1 = (parseInt(existingTank.height.replace(/,/g, ''), 10)) * 30.48; const tank_height = parseInt(tank_height1.toFixed(0), 10); // Ensure it's an integer const water_level_height = tank_height - tankHeight; const waterCapacityPerCm = parseInt(existingTank.waterCapacityPerCm.replace(/,/g, ''), 10); const water_level = parseInt(water_level_height * waterCapacityPerCm, 10); 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(); } } } } } } // Send the latest three documents const latestOttanks = await IotData.find({ hardwareId }) .sort({ date: -1, time: -1 }); reply.code(200).send({ latestOttanks }); } catch (err) { // send an error response reply.code(500).send({ error: err.message }); } }; console.log("this is for testing push") exports.IotDeviceforstandalonedevice = async (req, reply) => { try { console.log("entered post for iotstandalone") const { hardwareId, Motor_status, tanks } = req.body; // create a new tank document with the current date and time const currentDate = new Date(); const date = currentDate.toISOString(); // save the date as an ISO string const time = currentDate.toLocaleTimeString('en-IN', { hour12: false, timeZone: 'Asia/Kolkata' }); // Create an array of tank documents const tankDocuments = tanks.map(tank => ({ tankhardwareId: tank.tankhardwareId, tankHeight: tank.tankHeight, date: date, time: time })); // create a new IotData document with the provided data const ottank = new IotData({ hardwareId, Motor_status, tanks: tankDocuments, date, time }); // save the document to MongoDB await ottank.save(); // Delete excess records (keep only the latest three records) const recordsToKeep = 3; const recordsToDelete = await IotData.find({ hardwareId }) .sort({ date: -1, time: -1 }) .skip(recordsToKeep); for (const record of recordsToDelete) { await record.remove(); } // Update waterlevel in tanksSchema for each tank for (const tank of tanks) { const { tankhardwareId, tankHeight } = tank; // Find the corresponding tank in tanksSchema const existingTank = await Tank.findOne({ hardwareId, tankhardwareId }); if (!existingTank) { continue; // Skip to the next tank if not found } const customerId = existingTank.customerId; const tank_name = existingTank.tankName; // Update the waterlevel using the tankHeight value const tank_height1 = (parseInt(existingTank.height.replace(/,/g, ''), 10)) * 30.48; const tank_height = parseInt(tank_height1.toFixed(0), 10); // Ensure it's an integer const water_level_height = tank_height - tankHeight; const waterCapacityPerCm = parseInt(existingTank.waterCapacityPerCm.replace(/,/g, ''), 10); const water_level = parseInt(water_level_height * waterCapacityPerCm, 10); 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(); } } } } } } const status = req.body.Motor_status; // Find the tank that contains the specified motor_id in its inputConnections const tank = await Tank.findOne({ "connections.inputConnections.motor_id": hardwareId }); if (!tank) { return reply.status(404).send({ status_code: 404, message: 'Motor not found for the specified motor_id' }); } console.log(hardwareId,"hardwareId") console.log(status,"status") // Find the inputConnection with the specified motor_id const inputConnection = tank.connections.inputConnections.find(conn => conn.motor_id === hardwareId); if (inputConnection) { // Update the motor_status of the inputConnection inputConnection.motor_status = status; console.log(inputConnection) // Check if motor_stop_status is "1" and status is "2" if (inputConnection.motor_stop_status === "1" && status === "2") { console.log("got into forced manual") console.log(inputConnection.motor_on_type,"before if motor on type") // Check if motor_on_type is not already "forced_manual" if (inputConnection.motor_on_type !== "forced_manual") { inputConnection.motor_on_type = "forced_manual"; console.log("entered forced manual of if") inputConnection.motor_stop_status = "2"; // Update startTime to the current time in the specified format const currentTime = new Date(); const formattedTime = currentTime.toLocaleString('en-GB', { day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false, }).replace(',', ''); inputConnection.startTime = formattedTime; } } // Check if motor_stop_status is "1" and status is "2" if (inputConnection.motor_stop_status === "2" && status === "1") { console.log("got into forced manual stop") console.log(inputConnection.motor_on_type,"before if motor on type stop") // Check if motor_on_type is not already "forced_manual" if (inputConnection.motor_on_type = "forced_manual") { inputConnection.motor_on_type = "manual"; console.log("entered forced manual of if of stop") // Update startTime to the current time in the specified format inputConnection.motor_stop_status = "1"; } } } // Save the updated tank await tank.save(); // Send the latest three documents const latestOttanks = await IotData.find({ hardwareId }) .sort({ date: -1, time: -1 }); reply.code(200).send({ latestOttanks }); } catch (err) { // send an error response reply.code(500).send({ error: err.message }); } }; // exports.IotDevice3 = async (req, reply) => { // try { // const { hardwareId, mode, tanks } = req.body; // // create a new tank document with the current date and time // const currentDate = new Date(); // const date = currentDate.toISOString(); // save the date as an ISO string // const time = currentDate.toLocaleTimeString('en-IN', { hour12: false, timeZone: 'Asia/Kolkata' }); // // Create an array of tank documents // const tankDocuments = tanks.map(tank => ({ // tankhardwareId: tank.tankhardwareId, // tankHeight: tank.tankHeight, // maxLevel: tank.maxLevel, // minLevel: tank.minLevel, // date: date, // time: time // })); // // create a new IotData document with the provided data // const ottank = new IotData({ hardwareId, mode, tanks: tankDocuments, date, time }); // // save the document to MongoDB // await ottank.save(); // // Delete excess records (keep only the latest three records) // const recordsToKeep = 3; // const recordsToDelete = await IotData.find({ hardwareId }) // .sort({ date: -1, time: -1 }) // .skip(recordsToKeep); // for (const record of recordsToDelete) { // await record.remove(); // } // // Update waterlevel in tanksSchema for each tank // for (const tank of tanks) { // const { tankhardwareId, tankHeight } = tank; // // Find the corresponding tank in tanksSchema // const existingTank = await Tank.findOne({ hardwareId, tankhardwareId }); // if (existingTank) { // // Update the waterlevel using the tankHeight value // const tank_height1 = (parseInt(existingTank.height.replace(/,/g, ''), 10)) * 30.48; // console.log(tank_height1, 25); // // The value of tank_height1 is a number, not a string, so you cannot use replace on it. // // If you want to format it with commas, you can create a function to add commas to a number. // function numberWithCommas(x) { // return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); // } // // Now you can use the function to format the tank_height1 value with commas. // const formatted_tank_height1 = numberWithCommas(tank_height1); // console.log(formatted_tank_height1, 25); // const tank_height = parseInt(formatted_tank_height1.replace(/,/g, ''), 10); // console.log(tank_height); // // console.log(tank_height,1) // const water_level_height = tank_height - tankHeight // console.log(water_level_height,2) // const waterCapacityPerCm = parseInt(existingTank.waterCapacityPerCm.replace(/,/g, ''), 10) // console.log(waterCapacityPerCm,3) // const water_level = water_level_height * waterCapacityPerCm; // console.log(water_level, 4); // // Function to add commas to a number // function numberWithCommas(x) { // return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); // } // const formatted_water_level = numberWithCommas(water_level); // console.log(formatted_water_level, 4); // existingTank.waterlevel = parseInt(formatted_water_level.replace(/,/g, ''), 10); // console.log(existingTank.waterlevel); // // Save the updated tank document // await existingTank.save(); // for (const outputConnection of existingTank.connections.outputConnections) { // const linkedTank = await Tank.findOne({ customerId: customerId, tankName: outputConnection.outputConnections, tankLocation: outputConnection.output_type }); // if (linkedTank) { // // linkedTank.waterlevel = existingTank.waterlevel; // //await linkedTank.save(); // // Update water level of tanks linked through input connections of the linked tank // for (const inputConnection of linkedTank.connections.inputConnections) { // if (inputConnection.inputConnections === tank_name) { // inputConnection.water_level = water_level.toString(); // await linkedTank.save(); // } // } // } // } // } // } // // Send the latest three documents // const latestOttanks = await IotData.find({ hardwareId }) // .sort({ date: -1, time: -1 }); // reply.code(200).send({ latestOttanks }); // } catch (err) { // // send an error response // reply.code(500).send({ error: err.message }); // } // }; // exports.IotDevice1 = async (req, reply) => { // try { // const { hardwareId, mode, tanks } = req.body; // // create a new tank document with the current date and time // const currentDate = new Date(); // const date = currentDate.toISOString(); // save the date as an ISO string // const time = currentDate.toLocaleTimeString('en-IN', { hour12: false, timeZone: 'Asia/Kolkata' }); // // Create an array of tank documents // const tankDocuments = tanks.map(tank => ({ // tankhardwareId: tank.tankhardwareId, // tankHeight: tank.tankHeight, // maxLevel: tank.maxLevel, // minLevel: tank.minLevel, // date: date, // time: time // })); // // create a new IotData document with the provided data // const ottank = new IotData({ hardwareId, mode, tanks: tankDocuments, date, time }); // // save the document to MongoDB // await ottank.save(); // // Delete excess records (keep only the latest three records) // const recordsToKeep = 3; // const recordsToDelete = await IotData.find({ hardwareId }) // .sort({ date: -1, time: -1 }) // .skip(recordsToKeep); // for (const record of recordsToDelete) { // await record.remove(); // } // console.log(tanks) // // Update waterlevel in tanksSchema for each tank // for (const tank of tanks) { // console.log(tank) // const { tankhardwareId, tankHeight } = tank; // console.log(hardwareId,tankhardwareId) // // Find the corresponding tank in tanksSchema // const existingTank = await Tank.findOne({ hardwareId, tankhardwareId }); // if (!existingTank) { // console.log(`No tank found for tankhardwareId '${tankhardwareId}'. Skipping.`); // continue; // Skip to the next iteration // } // console.log(existingTank,"existing tank") // if (existingTank) { // // Update the waterlevel using the tankHeight value // const tank_height1 = (parseInt(existingTank.height.replace(/,/g, ''), 10)) * 30.48; // console.log(tank_height1, 25); // // The value of tank_height1 is a number, not a string, so you cannot use replace on it. // // If you want to format it with commas, you can create a function to add commas to a number. // function numberWithCommas(x) { // return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); // } // // Now you can use the function to format the tank_height1 value with commas. // const formatted_tank_height1 = numberWithCommas(tank_height1); // console.log(formatted_tank_height1, 25); // const tank_height = parseInt(formatted_tank_height1.replace(/,/g, ''), 10); // console.log(tank_height); // // console.log(tank_height,1) // const water_level_height = tank_height - tankHeight // console.log(water_level_height,2) // const waterCapacityPerCm = parseInt(existingTank.waterCapacityPerCm.replace(/,/g, ''), 10) // console.log(waterCapacityPerCm,3) // const water_level = water_level_height * waterCapacityPerCm; // console.log(water_level, 4); // // Function to add commas to a number // function numberWithCommas(x) { // return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); // } // const formatted_water_level = numberWithCommas(water_level); // console.log(formatted_water_level, 4); // existingTank.waterlevel = parseInt(formatted_water_level.replace(/,/g, ''), 10); // console.log(existingTank.waterlevel); // // Save the updated tank document // await existingTank.save(); // for (const outputConnection of existingTank.connections.outputConnections) { // const linkedTank = await Tank.findOne({ customerId: customerId, tankName: outputConnection.outputConnections, tankLocation: outputConnection.output_type }); // if (linkedTank) { // // linkedTank.waterlevel = existingTank.waterlevel; // //await linkedTank.save(); // // Update water level of tanks linked through input connections of the linked tank // for (const inputConnection of linkedTank.connections.inputConnections) { // if (inputConnection.inputConnections === tank_name) { // inputConnection.water_level = water_level.toString(); // await linkedTank.save(); // } // } // } // } // } // } // // Send the latest three documents // const latestOttanks = await IotData.find({ hardwareId }) // .sort({ date: -1, time: -1 }); // reply.code(200).send({ latestOttanks }); // } catch (err) { // // send an error response // reply.code(500).send({ error: err.message }); // } // }; // exports.IotDevice1 = async (req, reply) => { // try { // const { hardwareId, mode, tanks } = req.body; // // create a new tank document with the current date and time // const currentDate = new Date(); // const date = currentDate.toISOString(); // save the date as an ISO string // const time = currentDate.toLocaleTimeString('en-IN', { hour12: false, timeZone: 'Asia/Kolkata' }); // // Create an array of tank documents // const tankDocuments = tanks.map(tank => ({ // tankhardwareId: tank.tankhardwareId, // tankHeight: tank.tankHeight, // maxLevel: tank.maxLevel, // minLevel: tank.minLevel, // date: date, // time: time // })); // // create a new IotData document with the provided data // const ottank = new IotData({ hardwareId, mode, tanks: tankDocuments, date, time }); // // save the document to MongoDB // await ottank.save(); // // Delete excess records (keep only the latest three records) // const recordsToKeep = 3; // const recordsToDelete = await IotData.find({ hardwareId }) // .sort({ date: -1, time: -1 }) // .skip(recordsToKeep); // for (const record of recordsToDelete) { // await record.remove(); // } // // Update waterlevel in tanksSchema for each tank // for (const tank of tanks) { // const { tankhardwareId, tankHeight } = tank; // if (tankHeight === null || tankHeight === undefined) { // continue; // Skip this iteration and move to the next tank // } // // Find the corresponding tank in tanksSchema // const existingTank = await Tank.findOne({ hardwareId, tankhardwareId }); // if (existingTank) { // // Update the waterlevel using the tankHeight value // const tank_height = parseInt(existingTank.height.replace(/,/g, ''), 10) * 30.48; // const water_level_height = tank_height - tankHeight; // const customerId = existingTank.customerId; // const waterCapacityPerCm = parseInt(existingTank.waterCapacityPerCm.replace(/,/g, ''), 10); // let water_level = water_level_height * waterCapacityPerCm; // water_level = Math.round(water_level); // Round to nearest whole number // existingTank.waterlevel = water_level.toString(); // Convert to string as per schema definition // const tank_name = existingTank.tankName; // // Save the updated tank document // await existingTank.save(); // // Update water level of tanks linked through output connections // for (const outputConnection of existingTank.connections.outputConnections) { // const linkedTank = await Tank.findOne({ customerId: customerId, tankName: outputConnection.outputConnections, tankLocation: outputConnection.output_type }); // if (linkedTank) { // // linkedTank.waterlevel = existingTank.waterlevel; // //await linkedTank.save(); // // Update water level of tanks linked through input connections of the linked tank // for (const inputConnection of linkedTank.connections.inputConnections) { // if (inputConnection.inputConnections === tank_name) { // inputConnection.water_level = water_level.toString(); // await linkedTank.save(); // } // } // } // } // } // } // // Send the latest three documents // const latestOttanks = await IotData.find({ hardwareId }) // .sort({ date: -1, time: -1 }); // reply.code(200).send({ latestOttanks }); // } catch (err) { // // send an error response // reply.code(500).send({ error: err.message }); // } // }; // exports.getIotD = async(req, reply) => { // try { // await IotData.find({hardwareId: req.query.hardwareId}) // .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); // } // } exports.getIotD = async (req, reply) => { try { const latestRecords = await IotData.find({ hardwareId: req.query.hardwareId }) .sort({ date: -1, time: -1 }) // Sort by date and time in descending order .limit(3) // Limit the result to 3 records .exec(); reply.send({ status_code: 200, data: latestRecords, count: latestRecords.length }); } catch (err) { console.error(err); throw boom.boomify(err); } }; exports.getLatestData = async (req, reply) => { try { const hardwareId = req.params.hardwareId; // get the latest two tank documents for the current hardwareId sorted in descending order of date and time const latestTanks = await IotData.find({ hardwareId }).sort({ date: -1, time: -1 }).limit(2); // if the number of documents for the current hardwareId is less than two, return an error response if (latestTanks.length < 2) { return reply.code(404).send({ error: 'Not enough data' }); } // calculate the time difference between the latest and previous documents const latestDate = new Date(latestTanks[0].date); const previousDate = new Date(latestTanks[1].date); const latestTime = latestTanks[0].time.split('.')[0]; // remove milliseconds const previousTime = latestTanks[1].time.split('.')[0]; // remove milliseconds latestDate.setHours(parseInt(latestTime.substring(0, 2)), parseInt(latestTime.substring(3, 5)), parseInt(latestTime.substring(6, 8))); previousDate.setHours(parseInt(previousTime.substring(0, 2)), parseInt(previousTime.substring(3, 5)), parseInt(previousTime.substring(6, 8))); const timeDiff = (latestDate.getTime() - previousDate.getTime()) / 1000; // convert from milliseconds to seconds console.log(latestDate,previousDate,latestTime,previousTime,timeDiff) reply.code(200).send({ timeDiff }); } catch (err) { // send an error response reply.code(500).send({ error: err.message }); } }; exports.changesurveystatus = async (req, reply) => { try { const customerId = req.params.customerId; const result = await User.findOneAndUpdate( { customerId: customerId }, { $set: { survey_status: req.body.survey_status } }, { new: true } ); reply.code(200).send({ result }); } catch (err) { // send an error response reply.code(500).send({ error: err.message }); } }; exports.checkStatusofIot = async (req, reply) => { try { // get a list of unique hardware IDs in the collection const hardwareIds = await IotData.distinct('hardwareId'); // create an empty object to store the time differences for each hardware ID const timeDiffs = {}; // loop over each hardware ID and calculate the time difference between the latest two records for (const hardwareId of hardwareIds) { // get the latest two records for the current hardware ID const latestTanks = await IotData.find({ hardwareId }).sort({ date: -1, time: -1 }).limit(2); // if the number of records for the current hardware ID is less than two, skip to the next ID if (latestTanks.length < 2) { continue; } // calculate the time difference between the latest and previous records for the current hardware ID const latestDate = new Date(latestTanks[0].date); const previousDate = new Date(latestTanks[1].date); const latestTime = latestTanks[0].time.split('.')[0]; // remove milliseconds const previousTime = latestTanks[1].time.split('.')[0]; // remove milliseconds latestDate.setHours(parseInt(latestTime.substring(0, 2)), parseInt(latestTime.substring(3, 5)), parseInt(latestTime.substring(6, 8))); previousDate.setHours(parseInt(previousTime.substring(0, 2)), parseInt(previousTime.substring(3, 5)), parseInt(previousTime.substring(6, 8))); const timeDiff = (latestDate.getTime() - previousDate.getTime()) / 1000; // convert from milliseconds to seconds // store the time difference for the current hardware ID timeDiffs[hardwareId] = timeDiff; } // send the time differences for all hardware IDs reply.code(200).send({ timeDiffs }); } catch (err) { // send an error response reply.code(500).send({ error: err.message }); } }; exports.totalwaterLevelSum = async (request, reply) => { const { tankLocation, typeOfWater } = request.query; const waterlevelSum = await Tank.aggregate([ { $match: { tankLocation, typeOfWater } }, { $group: { _id: null, totalWaterlevel: { $sum: { $toInt: '$waterlevel' } } } } ]); const result = waterlevelSum[0]?totalWaterlevel : 0; reply.send({ waterlevelSum: result }); } exports.startUpdateLoop = async (request, reply) => { const updateInterval = 5000; setInterval(async () => { try { const iotTank = await IotData.findOne({ hardwareId: request.body.hardwareId }); if (!iotTank) { console.log(`IOTtank not found for hardwareId ${request.body.hardwareId}`); return; } const currentWaterlevel = Number(iotTank.tankHeight) * 200; const tank = await Tank.findOne({ hardwareId: iotTank.hardwareId }); let combinedWaterlevel; if (tank) { combinedWaterlevel = currentWaterlevel + Number(tank.waterlevel); } else { combinedWaterlevel = currentWaterlevel; } await Tank.updateOne({ hardwareId: iotTank.hardwareId }, { $set: { waterlevel: combinedWaterlevel } }); console.log(`Waterlevel updated successfully for hardwareId ${iotTank.hardwareId}`); console.log(`Previous waterlevel: ${tank ? tank.waterlevel : 0}`); console.log(`Current waterlevel: ${currentWaterlevel}`); console.log(`Combined waterlevel: ${combinedWaterlevel}`); } catch (err) { console.error(err); } }, updateInterval); }; // 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()); 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" }); let consumptionTask; // Function to clear the specific scheduled task const clearConsumptionSchedule = () => { if (consumptionTask) { consumptionTask.stop(); // Stop the existing task if it exists consumptionTask = null; // Clear the reference } }; // Function to update total consumption till midnight const updatetotalConsumptiontillmidnight = async () => { console.log('Cron job triggered at:', moment().tz('Asia/Kolkata').format()); 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); console.log(waterlevel_at_midnight,total_water_added_from_midnight,waterlevel) const totalconsumption = (waterlevel_at_midnight + total_water_added_from_midnight) - waterlevel; console.log(totalconsumption,tank.tankName) // Format the date in the desired format const formattedDate = moment().tz('Asia/Kolkata').format('DD-MMM-YYYY - HH:mm'); // Check if the record already exists const existingRecord = await TankConsumptionOriginalSchema.findOne({ customerId: tank.customerId, tankName: tank.tankName, tankLocation: tank.tankLocation, time: formattedDate }); if (!existingRecord) { // Create and save the new document if it doesn't exist const newTankConsumption = new TankConsumptionOriginalSchema({ customerId: tank.customerId, tankName: tank.tankName, tankLocation: tank.tankLocation, consumption: totalconsumption.toString(), time: formattedDate, // Save the formatted date block:tank.blockName, typeofwater:tank.typeOfWater }); await newTankConsumption.save(); console.log(`Created new record for tank ${tank.tankName} at ${formattedDate}`); } else { console.log(`Record already exists for tank ${tank.tankName} at ${formattedDate}`); } } console.log('Waterlevel noted in waterlevel_at_midnight'); } catch (error) { console.error('Error occurred:', error); } }; // Clear the existing schedule for this task before creating a new one clearConsumptionSchedule(); // Schedule the task to run every day at 12:49 PM IST and store the reference consumptionTask = cron.schedule('50 23 * * *', updatetotalConsumptiontillmidnight, { timezone: "Asia/Kolkata" }); console.log('Scheduled task to update total consumption till midnight.'); // const updatetotalConsumptiontillmidnight = async () => { // console.log('Cron job triggered at:', moment().tz('Asia/Kolkata').format()); // 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; // // Format the date in the desired format // const formattedDate = moment().tz('Asia/Kolkata').format('DD-MMM-YYYY - HH:mm'); // const newTankConsumption = new TankConsumptionOriginalSchema({ // customerId: tank.customerId, // tankName: tank.tankName, // tankLocation: tank.tankLocation, // consumption: totalconsumption.toString(), // time: formattedDate // Save the formatted date // }); // // Save the new document // await newTankConsumption.save(); // } // console.log('Waterlevel noted in waterlevel_at_midnight'); // } catch (error) { // console.error('Error occurred:', error); // } // }; // Schedule the task to run every day at 23:55 IST (11:55 PM IST) // cron.schedule('55 23 * * *', updatetotalConsumptiontillmidnight, { // timezone: "Asia/Kolkata" // }); exports.deletemotordatarecordsbefore7days = async (req, reply) => { try { // Schedule the task to run every day at 10 seconds past the minute cron.schedule('0 0 * * *', async () => { try { // Run the deletion task once a day setInterval(async () => { await deleteOldRecords(); }, 24 * 60 * 60 * 1000); // 24 hours in milliseconds } catch (error) { console.error('Error occurred:', error); } }); } catch (err) { throw boom.boomify(err); } }; exports.motorstatus = async (req, reply) => { try { const motor_id = req.params.motor_id; console.log(motor_id) const motorInfo = await Tank.findOne({ motor_id: motor_id }); console.log(motorInfo) //return update; reply.send({ status_code: 200,status:motorInfo.motor_status}); } catch (err) { throw boom.boomify(err); } }; exports.readMotorStatus = async (req, reply) => { try { const motor_id = req.query.motor_id; console.log("entered read api for iot") // Perform any necessary logic based on action (1: Start, 2: Stop) // For example, you can update a database or trigger an action const tanks = await Tank.find({}); let motor_stop_status = null; for (let tank of tanks) { const inputConnections = tank.connections.inputConnections; const motorConnection = inputConnections.find(conn => conn.motor_id === motor_id); if (motorConnection) { // Check if motor_on_type is "forced_manual" and motor_stop_status is "1" if (motorConnection.motor_on_type === "forced_manual" && motorConnection.motor_stop_status === "1") { motor_stop_status = "2"; // Send motor_stop_status as "2" } else { motor_stop_status = motorConnection.motor_stop_status; // Otherwise, assign its original value } break; } } if (!motor_stop_status) { return reply.status(404).send({ status_code: 404, message: 'Motor not found for the specified motor_id' }); } reply.send({ status_code: 200, motor_stop_status: motor_stop_status }); } catch (err) { throw boom.boomify(err); } }; exports.readMotorStatusFromIot = async (req, reply) => { try { const motor_id = req.query.motor_id; console.log(motor_id) // Find the tank that contains the specified motor_id in its inputConnections const tank = await Tank.findOne({ "connections.inputConnections.motor_id": motor_id }); if (!tank) { return reply.status(404).send({ status_code: 404, message: 'Motor not found for the specified motor_id' }); } // Find the inputConnection with the specified motor_id const inputConnection = tank.connections.inputConnections.find(conn => conn.motor_id === motor_id); // Extract motor_status and motor_stop_status from the inputConnection const motor_status = inputConnection.motor_status; const motor_stop_status = inputConnection.motor_stop_status; // Send the response with motor_status and motor_stop_status reply.send({ status_code: 200, motor_status: motor_status, motor_stop_status: motor_stop_status }); } catch (err) { throw boom.boomify(err); } }; // exports.writeMotorStatus = async (req, reply) => { // try { // const motor_id = req.body.motor_id; // // Perform any necessary logic to handle motor status update from the device // // For example, update a database with the new status, current, and temp values // const existingRecord = await Tank.findOne({ motor_id: motor_id }); // if (existingRecord && (existingRecord.motor_stop_status === '1' || existingRecord.motor_stop_status === '2')) { // const newMotorStatus = existingRecord.motor_stop_status; // if (existingRecord.motor_status !== newMotorStatus) { // const result = await Tank.findOneAndUpdate( // { motor_id: motor_id }, // { $set: { motor_status: newMotorStatus } }, // { new: true } // To return the updated document // ); // reply.send({ status_code: 200, motor_status: result.motor_status }); // } else { // reply.send({ status_code: 200, motor_status: newMotorStatus }); // } // } else { // reply.send({ status_code: 200, message: 'Motor stop status is not "on" or "off".' }); // } // } catch (err) { // throw boom.boomify(err); // } // }; exports.writeMotorStatus = async (req, reply) => { try { const motor_id = req.body.motor_id; const status = req.body.status; // Find the tank that contains the specified motor_id in its inputConnections const tank = await Tank.findOne({ "connections.inputConnections.motor_id": motor_id }); if (!tank) { return reply.status(404).send({ status_code: 404, message: 'Motor not found for the specified motor_id' }); } // Find the inputConnection with the specified motor_id const inputConnection = tank.connections.inputConnections.find(conn => conn.motor_id === motor_id); // Update the motor_status of the inputConnection inputConnection.motor_status = status; // Save the updated tank await tank.save(); // Send the response with the updated motor_status reply.send({ status_code: 200, motor_status: status }); } catch (err) { throw boom.boomify(err); } }; // const motor_id = req.body.motor_id; // const status = req.body.status; // // Find the tank that contains the specified motor_id in its inputConnections // const tank = await Tank.findOne({ "connections.inputConnections.motor_id": motor_id }); // if (!tank) { // return reply.status(404).send({ // status_code: 404, // message: 'Motor not found for the specified motor_id' // }); // } // // Find the inputConnection with the specified motor_id // const inputConnection = tank.connections.inputConnections.find(conn => conn.motor_id === motor_id); // // Update the motor_status of the inputConnection // inputConnection.motor_status = status; // // Update real_motor_status based on the conditions // // // Save the updated tank // await tank.save(); // // Send the response with the updated motor_status // reply.send({ // status_code: 200, // motor_status: status // }); // } catch (err) { // throw boom.boomify(err); // } // }; exports.changeMotorStatus = async (req, reply) => { try { const motor_id = req.body.motor_id; const action = req.body.action; // Perform any necessary logic to handle motor status update from the device // For example, update a database with the new status, current, and temp values await Tank.updateOne( { "connections.inputConnections.motor_id": motor_id }, { $set: { "connections.inputConnections.$.motor_stop_status":action , } } ); // Send immediat // Fetch the motor_status for the given motor_id // Send the response with motor_stop_status and motor_status reply.send({ status_code: 200, motor_stop_status: action, // motor_status: updatedMotor.motor_status // Assuming motor_status is a field in your Tank model }); } catch (err) { throw boom.boomify(err); } }; exports.motortemperature = async (req, reply) => { try { const motor_id = req.params.motor_id; console.log(motor_id) const motorInfo = await Tank.findOne({ motor_id: motor_id }); console.log(motorInfo) //return update; reply.send({ status_code: 200,temperature:motorInfo.motor_temperfature}); } catch (err) { throw boom.boomify(err); } }; exports.update_auto_mode = async (req, reply) => { try { const customerId = req.params.customerId; const { motor_id, auto_mode } = req.body; // Update inputConnections' auto_mode await Tank.updateOne( { customerId: customerId, "connections.inputConnections.motor_id": motor_id }, { $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}, { $set: { "auto_min_percentage": auto_min_percentage, "auto_max_percentage": auto_max_percentage } } ); reply.send({ status_code: 200, message: "Auto mode and percentages updated successfully." }); } catch (error) { throw boom.boomify(error); } }; //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'); exports.getBlockData = async (req, reply) => { try { const customerId = req.params.customerId; // Get all tank documents for the current customerId const tanks = await Tank.find({ customerId }); // Extract the blockName from each tank const blockNames = tanks.map(tank => tank.blockName); // Remove duplicates by converting the array to a Set and then back to an array const uniqueBlockNames = [...new Set(blockNames)]; // Add "all" and "nduku sneha antha kopam" to the block names uniqueBlockNames.unshift("All"); // Send the unique blockNames in the response reply.code(200).send({ blockNames: uniqueBlockNames }); } catch (err) { // Log the error for debugging purposes console.error(err); // Send an error response reply.code(500).send({ error: err.message }); } }; 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'); client.subscribe('water/iot-data', (err) => { if (err) { console.error('Error subscribing to topic:', err); } else { console.log('Subscribed to water/iot-data topic'); } }); }); // Handling incoming MQTT messages client.on('message', async (topic, message) => { console.log(`Message received on topic ${topic}:`, message.toString()); 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 })); // 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(); // 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); for (const record of recordsToDelete) { await record.remove(); } // 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 if (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 status = Motor_status; const motorTank = await Tank.findOne({ "connections.inputConnections.motor_id": hw_Id }); // Updated variable name if (!motorTank) { console.log('Motor not found for the specified motor_id'); return; } // 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 await motorTank.save(); // Save the updated tank } console.log('Data processed successfully for hardwareId:', hw_Id); // Updated variable name } catch (err) { console.error('Error processing message:', err.message); } } }); // Function to publish motor stop status // exports.publishMotorStopStatus = async (motor_id, motor_stop_status) => { // const payload = { // topic: 'operation', // object: { // 'motor-id': motor_id, // control: motor_stop_status // } // }; // client.publish('water/operation', JSON.stringify(payload)); // }; //const moment = require('moment'); exports.getPendingAndCompletedsurveyOfparticularInstaller = async (request, reply) => { try { const { installationId } = request.params; const survey_status = request.body; const surveydata = await User.find({ installationId, survey_status, }); // Send the response, including both total consumption and filtered consumption records reply.send({ status_code: 200, surveydata, }); } catch (err) { throw boom.boomify(err); } }; exports.consumptionofparticulartank = async (request, reply) => { try { const { customerId } = request.params; const { startDate, stopDate, tankName, tankLocation, block } = request.body; // Convert input dates into proper JavaScript Date objects for comparison const start = moment(startDate, "DD-MMM-YYYY - HH:mm").toDate(); const end = moment(stopDate, "DD-MMM-YYYY - HH:mm").toDate(); // Find the tank by customerId, tankLocation, and tankName const tank = await Tank.findOne({ customerId, tankLocation: tankLocation || "overhead", // Default to "overhead" if not provided tankName, }); if (!tank) { return reply.status(404).send({ status_code: 404, message: "Tank not found", }); } 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); // Fetch all records for the tank (no date filtering yet) const tankConsumptions = await TankConsumptionOriginalSchema.find({ customerId, tankName, tankLocation: tankLocation, }); // Filter records in JavaScript by comparing the 'time' field after converting to Date const filteredConsumptions = tankConsumptions.filter((record) => { const recordTime = moment(record.time, "DD-MMM-YYYY - HH:mm").toDate(); return recordTime >= start && recordTime <= end; }); // Sort filtered records by date (ascending) filteredConsumptions.sort((a, b) => { const dateA = moment(a.time, "DD-MMM-YYYY - HH:mm").toDate(); const dateB = moment(b.time, "DD-MMM-YYYY - HH:mm").toDate(); return dateA - dateB; // Sort in ascending order }); // Calculate total consumption from filtered records const total_consumption_from_records = filteredConsumptions.reduce((acc, record) => { return acc + parseInt(record.consumption, 10); }, 0); // Calculate final consumption const consumption = (waterlevel_at_midnight + total_water_added_from_midnight) - waterlevel + total_consumption_from_records; // Prepare response data const tankData = { tankname: tank.tankName, totalConsumption: consumption, block: tank.blockName, TypeofWater: tank.typeOfWater, location: tank.tankLocation, capacity: tank.capacity, waterlevel: tank.waterlevel, }; // Send the response, including both total consumption and filtered consumption records reply.send({ status_code: 200, tankData, totalConsumption: consumption, consumptionRecords: filteredConsumptions, }); } catch (err) { throw boom.boomify(err); } }; // // Set start and end dates // const startDate = new Date("2024-08-20T00:00:00Z"); // const endDate = new Date("2024-11-04T00:00:00Z"); // // Tank names array with respective blocks // const tanks = [ // { tankName: "REAL TANK OH", block: "A" }, // { tankName: "DUMMY TANK OH1", block: "BLOCK C" }, // { tankName: "DUMMY TANK OH2", block: "BLOCK D" }, // { tankName: "DUMMY TANK OH3", block: "BLOCK C" }, // { tankName: "DUMMY TANK OH4", block: "BLOCK C" }, // { tankName: "DUMMY TANK OH5", block: "BLOCK C" }, // { tankName: "DUMMY TANK OH6", block: "BLOCK C" } // ]; // const customerId = "AWSUSKY4"; // const tankLocation = "overhead"; // const typeofwater = "Bore Water"; // // Function to format date to "DD-MMM-YYYY - HH:mm" // function formatDateCustom(date) { // const options = { day: '2-digit', month: 'short', year: 'numeric' }; // return date.toLocaleDateString('en-GB', options).replace(/ /g, '-') + " - 23:55"; // } // // Main function to generate data // async function generateData() { // for (let date = new Date(startDate); date <= endDate; date.setDate(date.getDate() + 1)) { // const formattedDate = formatDateCustom(date); // Format date to "DD-MMM-YYYY - 23:55" // for (const { tankName, block } of tanks) { // try { // const existingRecord = await TankConsumptionOriginalSchema.findOne({ // customerId: customerId, // tankName: tankName, // tankLocation: tankLocation, // time: formattedDate // }).exec(); // console.log(`Checking record for ${tankName} on ${formattedDate}: ${existingRecord ? 'Exists' : 'Does not exist'}`); // if (!existingRecord) { // // Random consumption between 7000 and 8000 // const randomConsumption = Math.floor(Math.random() * (8000 - 7000 + 1)) + 7000; // // Create a new document and save it // const newRecord = new TankConsumptionOriginalSchema({ // customerId: customerId, // tankName: tankName, // tankLocation: tankLocation, // consumption: randomConsumption.toString(), // time: formattedDate, // block: block, // typeofwater: typeofwater, // __v: 0 // }); // await newRecord.save(); // Use .save() method to insert the record // console.log(`Inserted record for ${tankName} on ${formattedDate}`); // } // } catch (error) { // console.error(`Failed to check or insert record for ${tankName} on ${formattedDate}:`, error); // } // } // } // console.log("Data generation complete."); // } // // Run the data generation function // generateData(); async function removeDuplicates() { try { // Step 1: Find duplicates, considering time and ignoring case for typeofwater const duplicates = await TankConsumptionOriginalSchema.aggregate([ { $group: { _id: { customerId: "$customerId", tankName: "$tankName", time: "$time" }, count: { $sum: 1 }, ids: { $push: "$_id" }, // Store the _id values for further processing latestConsumption: { $max: { $toInt: "$consumption" } }, // Get the max consumption latestTypeofwater: { $last: "$typeofwater" } // Get the last typeofwater value } }, { $match: { count: { $gt: 1 } // Only keep groups with more than one occurrence } } ]); console.log(`Found ${duplicates.length} groups of duplicates.`); // Step 2: Prepare delete operations for (const duplicateGroup of duplicates) { // Filter the ids based on the maximum time to keep the latest entry const idsToDelete = duplicateGroup.ids.filter(id => { return id !== duplicateGroup.ids[0]; // Keep the first, delete the rest }); for (const id of idsToDelete) { try { await TankConsumptionOriginalSchema.deleteOne({ _id: id }); console.log(`Deleted duplicate record with ID: ${id}`); } catch (deleteError) { console.error(`Failed to delete record with ID ${id}:`, deleteError); } } } console.log("Duplicate removal complete."); } catch (error) { console.error("Failed to remove duplicates:", error); } } // Run the remove duplicates function // removeDuplicates(); console.log("this is for testing autopush,line located in tankscontroller")