//const Tank = require("../models/tanks");
const { Tank , MotorData , IotData , MotorIot , TankWaterLevel , TankConsumptionSchema , TankConsumptionOriginalSchema , CustomerAutoPercentages } = 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 ) ;
}
} ;
exports . deleteTanksInfo = async ( req , reply ) => {
try {
const { customerId } = req . params ;
const { tankName } = req . query ;
const tankLocation = req . body . tankLocation . toLowerCase ( ) ;
if ( ! tankName || ! tankLocation ) {
return reply . code ( 400 ) . send ( { message : "Tank name and location are required" } ) ;
}
// Convert tankLocation to lowercase (for case-insensitive match)
const normalizedTankLocation = tankLocation . toLowerCase ( ) ;
// Find and delete the main tank
const deletedTank = await Tank . findOneAndDelete ( {
customerId ,
tankName ,
tankLocation : normalizedTankLocation
} ) ;
if ( ! deletedTank ) {
return reply . code ( 404 ) . send ( { message : "Tank not found" } ) ;
}
// Remove the deleted tank from inputConnections and outputConnections in all other tanks
await Tank . updateMany (
{ customerId } ,
{
$pull : {
"connections.inputConnections" : { inputConnections : tankName } ,
"connections.outputConnections" : { outputConnections : tankName }
}
}
) ;
return reply . send ( { message : "Tank deleted successfully" } ) ;
} catch ( error ) {
console . error ( "Error deleting tank:" , error ) ;
return reply . code ( 500 ) . send ( { message : "Internal Server Error" } ) ;
}
} ;
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 || [ ] ;
// Count switches
const switchCount = inputConnections . reduce ( ( count , connection ) => {
return count + ( connection . inputismotor === true ? 1 : 0 ) ;
} , 0 ) ;
totalSwitchCount += switchCount ;
// Count sensors
if ( tank . need _sensor ? . toLowerCase ( ) === "yes" ) {
totalSensorCount ++ ;
}
// Determine all_motor_status
const allMotorStatus = inputConnections . some ( connection => connection . motor _status === "2" ) ;
// Add switch_count and all_motor_status to the response
return {
... tank . toObject ( ) , // Convert Mongoose document to plain object
connections : {
... tank . connections ,
switch _count : switchCount ,
} ,
all _motor _status : allMotorStatus , // Add all_motor_status field
} ;
} ) ;
reply . send ( {
status _code : 200 ,
data : transformedDocs ,
count : transformedDocs . length ,
total _switch _count : totalSwitchCount ,
total _sensor _count : totalSensorCount ,
} ) ;
} )
. 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);
// }
//};
// const boom = require("@hapi/boom"); // Assuming you are using boom for error handling
exports . getTankmotordata = async ( req , reply ) => {
try {
const { startDate , stopDate , pumps , users } = req . body ;
const { customerId } = req . params ;
// Validate and format the input dates
if ( ! moment ( startDate , "DD-MMM-YYYY - HH:mm" , true ) . isValid ( ) || ! moment ( stopDate , "DD-MMM-YYYY - HH:mm" , true ) . isValid ( ) ) {
return reply . send ( { status _code : 400 , message : "Invalid date format" } ) ;
}
// Convert input dates to ISO 8601 format for Date comparison
const start = moment ( startDate , "DD-MMM-YYYY - HH:mm" ) . toDate ( ) ;
const end = moment ( stopDate , "DD-MMM-YYYY - HH:mm" ) . toDate ( ) ;
// Convert input dates to string format for string-based comparison
// Fetch the username based on customerId
const user = await User . findOne ( { customerId } ) . select ( "username" ) ;
if ( user ) {
const userName = user . username || "N/A" ;
let query = { customerId } ;
if ( pumps !== "All" ) {
query . motor _id = pumps ;
}
if ( users !== "All" ) {
query . started _by = users ;
}
// Fetch motor data with applied filters
const motordatas = await MotorData . find ( query ) ;
const filtereddatas = motordatas . filter ( ( record ) => {
const recordTime = moment ( record . startTime , "DD-MMM-YYYY - HH:mm" ) . toDate ( ) ;
return recordTime >= start && recordTime <= end ;
} ) ;
reply . send ( {
status _code : 200 ,
data : filtereddatas ,
count : filtereddatas . length ,
customerName : userName ,
} ) ;
} else {
reply . send ( { status _code : 404 , message : "User not found" } ) ;
}
} catch ( err ) {
console . error ( "Error in getTankmotordata:" , 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 totalavailableDrinkingwater = 0 ;
let totalDrinkingcapacity = 0 ;
let totalavailableBorewater = 0 ;
let totalBorewatercapacity = 0 ;
let sumOverheadDrinkingWater = 0 ;
let sumSumpBoreWater = 0 ;
let sumOverheadBoreWater = 0 ;
let sumSumpDrinkingWaterCapacity = 0 ;
let sumOverheadDrinkingWaterCapacity = 0 ;
let sumSumpBoreWaterCapacity = 0 ;
let sumOverheadBoreWaterCapacity = 0 ;
// Fetch only active tanks
const updated _data = await Tank . find ( { customerId : customerId , status : "active" } ) ;
console . log ( "Active Tanks 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 } ` ) ;
let totalInputPercentage = 0 ;
let inputCount = 0 ;
let totalOutputPercentage = 0 ;
let outputCount = 0 ;
// Process input connections
if ( tank . connections . inputConnections ) {
tank . connections . inputConnections . forEach ( inputConnection => {
if ( inputConnection . status === "active" ) { // Process only active connections
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 ;
}
}
} ) ;
tank . connections . inputWaterlevelPercentage = inputCount > 0 ? ( totalInputPercentage / inputCount ) . toFixed ( 2 ) : null ;
}
// Process output connections
if ( tank . connections . outputConnections ) {
tank . connections . outputConnections . forEach ( outputConnection => {
if ( outputConnection . status === "active" ) { // Process only active connections
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 ;
}
}
} ) ;
tank . connections . outputWaterlevelPercentage = outputCount > 0 ? ( totalOutputPercentage / outputCount ) . toFixed ( 2 ) : null ;
}
// Summing up the total water levels and capacities for active tanks only
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 ;
}
else if ( tank . typeOfWater === 'drinking' ) {
totalavailableDrinkingwater += waterlevel ;
totalDrinkingcapacity += capacity ;
}
else if ( tank . typeOfWater === 'bore' ) {
totalavailableBorewater += waterlevel ;
totalBorewatercapacity += 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 . typeofwater . toLowerCase ( ) ;
// 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
const tankQuery = { customerId , tankLocation : "overhead" } ;
if ( block !== "All" ) tankQuery . blockName = block ;
// Add typeofwater filter
if ( typeofwater === "bore" ) {
tankQuery . typeOfWater = { $in : [ "bore" , "Bore Water" ] } ;
} else if ( typeofwater === "drinking" ) {
tankQuery . typeOfWater = { $in : [ "drinking" , "Drinking Water" ] } ;
}
const tanks = await Tank . find ( tankQuery ) ;
const tankData = [ ] ;
const tankconsumptionData = [ ] ;
let totalConsumptionForSelectedBlockAndTypeOfWater = 0 ;
let totalBoreConsumptionForSelectedBlockAndTypeOfWater = 0 ;
let totalBoreCapacityForSelectedBlockAndTypeOfWater = 0 ;
let totalDrinkingConsumptionForSelectedBlockAndTypeOfWater = 0 ;
let totalDrinkingCapacityForSelectedBlockAndTypeOfWater = 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 capacity = parseInt ( tank . capacity . replace ( /,/g , '' ) , 10 ) ;
const tankConsumptions = await TankConsumptionOriginalSchema . find ( {
customerId ,
tankName : tank . tankName ,
tankLocation : tank . tankLocation ,
... ( block !== "All" && { block : tank . blockName } ) ,
... ( typeofwater === "bore" && { typeofwater : { $in : [ "bore" , "Bore Water" ] } } ) ,
... ( typeofwater === "drinking" && { typeofwater : { $in : [ "drinking" , "Drinking Water" ] } } ) ,
} ) ;
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 ;
// Add to the total consumption and capacities based on water type
if ( tank . typeOfWater === "bore" || tank . typeOfWater === "Bore Water" ) {
totalBoreConsumptionForSelectedBlockAndTypeOfWater += consumption ;
totalBoreCapacityForSelectedBlockAndTypeOfWater += capacity ;
} else if ( tank . typeOfWater === "drinking" || tank . typeOfWater === "Drinking Water" ) {
totalDrinkingConsumptionForSelectedBlockAndTypeOfWater += consumption ;
totalDrinkingCapacityForSelectedBlockAndTypeOfWater += capacity ;
}
tankData . push ( {
tankname ,
totalConsumption : consumption ,
block : tank . blockName ,
TypeofWater : tank . typeOfWater ,
location : tank . tankLocation ,
capacity : tank . capacity ,
waterlevel : tank . waterlevel ,
} ) ;
tankconsumptionData . push ( {
tankname ,
consumptionRecordsdatewise : filteredConsumptions ,
} ) ;
}
// Calculate total consumption percentages
const boreConsumptionPercentage = totalBoreCapacityForSelectedBlockAndTypeOfWater
? ( ( totalBoreConsumptionForSelectedBlockAndTypeOfWater / totalBoreCapacityForSelectedBlockAndTypeOfWater ) * 100 ) . toFixed ( 2 )
: 0 ;
const drinkingConsumptionPercentage = totalDrinkingCapacityForSelectedBlockAndTypeOfWater
? ( ( totalDrinkingConsumptionForSelectedBlockAndTypeOfWater / totalDrinkingCapacityForSelectedBlockAndTypeOfWater ) * 100 ) . toFixed ( 2 )
: 0 ;
const totalConsumptionPercentage =
typeofwater === "bore"
? boreConsumptionPercentage
: typeofwater === "drinking"
? drinkingConsumptionPercentage
: ( ( totalBoreConsumptionForSelectedBlockAndTypeOfWater + totalDrinkingConsumptionForSelectedBlockAndTypeOfWater ) /
( totalBoreCapacityForSelectedBlockAndTypeOfWater + totalDrinkingCapacityForSelectedBlockAndTypeOfWater ) *
100
) . toFixed ( 2 ) ;
// Include the total consumption in the response
// Construct the response
const response = {
status _code : 200 ,
tankData ,
consumptiorecordsdatewise : tankconsumptionData ,
totalConsumptionPercentage ,
totalConsumptionPercentageForBore : typeofwater !== "drinking" ? boreConsumptionPercentage : 0 ,
totalConsumptionPercentageForDrinking : typeofwater !== "bore" ? drinkingConsumptionPercentage : 0 ,
totalConsumptionForBore : typeofwater !== "drinking" ? totalBoreConsumptionForSelectedBlockAndTypeOfWater : 0 ,
totalConsumptionForDrinking : typeofwater !== "bore" ? totalDrinkingConsumptionForSelectedBlockAndTypeOfWater : 0 ,
[ ` total consumption of ${ typeofwater } and selected block ` ] : totalConsumptionForSelectedBlockAndTypeOfWater
} ;
// Send the response
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 ;
let totalAvailableCapacity = 0 ;
let totalConsumed = 0 ;
for ( const tank of tanks ) {
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 ;
} ) ;
// filteredConsumptions.forEach(record => {
// totalConsumed += parseInt(record.consumption, 10);
// totalAvailableCapacity += parseInt(record.capacity, 10);
// });
for ( const record of filteredConsumptions ) {
const recordTime = moment ( record . time , "DD-MMM-YYYY - HH:mm" ) . format ( "DD-MMM-YYYY - HH:mm" ) ;
const tank _info = await Tank . findOne ( {
customerId : record . customerId ,
tankName : record . tankName ,
tankLocation : record . tankLocation ,
} ) ;
totalConsumptionForSelectedBlockAndTypeOfWater += parseInt ( record . consumption , 10 ) ;
totalConsumed += parseInt ( record . consumption , 10 ) ;
;
// console.log( parseInt(tank_info.capacity.replace(/,/g, ''), 10))
totalAvailableCapacity += parseInt ( tank _info . capacity . replace ( /,/g , '' ) , 10 )
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 ,
available _capacity : record . available _capacity ,
time : record . time
} ) ;
tankconsumptionData [ recordTime ] . count ++ ;
}
}
}
const responseData = Object . values ( tankconsumptionData ) ;
const totalConsumptionPercentage = totalAvailableCapacity > 0 ? ( ( totalConsumed / totalAvailableCapacity ) * 100 ) . toFixed ( 2 ) : "0" ;
console . log ( totalConsumed , "totalConsumed" , totalAvailableCapacity , "totalAvailableCapacity" , totalConsumptionForSelectedBlockAndTypeOfWater , "totalConsumptionForSelectedBlockAndTypeOfWater" )
const response = {
status _code : 200 ,
consumptiorecordsdatewise : responseData ,
[ ` total consumption of ${ typeofwater } and selected block ` ] : totalConsumptionForSelectedBlockAndTypeOfWater ,
totalConsumptionPercentage : ` ${ totalConsumptionPercentage } % `
} ;
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, manual_threshold_time) => {
// try {
// // Retrieve the user information
// const users = await User.find({ fcmIds: { $in: fcmTokens } });
// console.log("users", users);
// const userNames = users.map(user => user.username).join(', ');
// console.log("userNames", userNames);
// const startMethod = motorOnType === "APP" ? "via the App" : "Manual";
// // Prepare the message
// const message =
// `🚰 Tank Name: '${tankName}'\n` +
// `🕒 Pump started at: '${startTime}'\n` +
// `👤 Started by : ${userNames}\n` +
// // `Pump started by: '${motorOnType.toUpperCase()}'\n` +
// `Mode : '${startMethod}'\n` +
// `Will stop at after: '${manual_threshold_time}' mins`;
// // Send the notification
// await sendNotification(fcmTokens, 'Arminta Water Management', message);
// } catch (error) {
// console.error('Error in motorStart event:', error);
// }
// }
// );
// Event listener for motorStart
eventEmitter . on (
'motorStart' ,
async ( fcmTokens , tankName , blockName , startTime , motorOnType , manual _threshold _time , typeOfWater ) => {
try {
// Retrieve the user information
const users = await User . find ( { fcmIds : { $in : fcmTokens } } ) ;
console . log ( "users" , users ) ;
const userNames = users . map ( user => user . username ) . join ( ', ' ) ;
console . log ( "userNames" , userNames ) ;
const startMethod = motorOnType === "Mobile APP" ? "Mobile APP" : "Manual" ;
// Generate motor name dynamically based on tank name, block name, and type of water
const motorName = ` ${ tankName } - ${ blockName } - ${ typeOfWater } ` ;
// Get current date and time for the motor start time
const currentDateTime = new Date ( ) ;
const formattedDate = currentDateTime . toLocaleDateString ( ) ; // Customize this format as needed
const formattedTime = currentDateTime . toLocaleTimeString ( ) ; // Customize this format as needed
// Prepare the message
const message =
` 🚰 Motor Name: ${ motorName } \n ` +
` 🚰 Tank Name: ' ${ tankName } ' \n ` +
` 🏢 Block Name: ' ${ blockName } ' \n ` +
` 👤 Started by: ${ userNames } \n ` +
` 📱 Mode: ' ${ startMethod } ' \n ` +
` 🕒 Pump started at: ${ startTime } \n ` +
` Will stop after: ' ${ manual _threshold _time } ' mins ` ;
// Send the notification
await sendNotification ( fcmTokens , 'Arminta Water Management' , message ) ;
} catch ( error ) {
console . error ( 'Error in motorStart event:' , error ) ;
}
}
) ;
// Event listener for motorStop
eventEmitter . on (
'motorStop' ,
async ( fcmTokens , tankName , blockName , stopTime , motorOnType , totalWaterPumped , typeOfWater ) => {
try {
// Retrieve the user information
const users = await User . find ( { fcmIds : { $in : fcmTokens } } ) ;
const userNames = users . map ( user => user . username ) . join ( ', ' ) ;
const stopMethod = motorOnType === "Mobile APP" ? "Mobile APP" : "Manual" ;
// Generate motor name dynamically based on tank name, block name, and type of water
const motorName = ` ${ tankName } - ${ blockName } - ${ typeOfWater } ` ;
// Get current date and time for the motor stop time
const currentDateTime = new Date ( ) ;
const formattedDate = currentDateTime . toLocaleDateString ( ) ; // Customize this format as needed
const formattedTime = currentDateTime . toLocaleTimeString ( ) ; // Customize this format as needed
// Prepare the message
const message =
` 🚰 Motor Name: ${ motorName } \n ` +
` 🛢️ Tank Name: ' ${ tankName } ' \n ` +
` 🏢 Block Name: ' ${ blockName } ' \n ` +
` 👤 Stopped by: ${ userNames } \n ` +
` 📱 Mode: ' ${ stopMethod } ' \n ` +
` 🕒 Pump stopped at: ${ stopTime } \n ` +
` 💧 Total water pumped: ${ totalWaterPumped } liters \n ` ; // Ensure this line is properly terminated
// Send the notification
await sendNotification ( fcmTokens , 'Arminta Water Management' , message ) ;
} catch ( error ) {
console . error ( 'Error in motorStop event:' , error ) ;
}
}
) ;
eventEmitter . on (
'motorStartAutomatic' ,
async ( fcmTokens , tankName , blockName , startTime , motorOnType , manual _threshold _time , typeOfWater , threshold ) => {
try {
// Retrieve the user information
const users = await User . find ( { fcmIds : { $in : fcmTokens } } ) ;
console . log ( "users" , users ) ;
const userNames = users . map ( user => user . username ) . join ( ', ' ) ;
console . log ( "userNames" , userNames ) ;
const startMethod = motorOnType === "Automatic" ? "Automatic" : "Manual" ;
// Generate motor name dynamically based on tank name, block name, and type of water
const motorName = ` ${ tankName } - ${ blockName } - ${ typeOfWater } ` ;
// Get current date and time for the motor start time
const currentDateTime = new Date ( ) ;
const formattedDate = currentDateTime . toLocaleDateString ( ) ; // Customize this format as needed
const formattedTime = currentDateTime . toLocaleTimeString ( ) ; // Customize this format as needed
// Prepare the message
const message =
` 🚰 Motor Name: ${ motorName } \n ` +
` 🛢️ Tank Name: ' ${ tankName } ' \n ` +
` 🏢 Block Name: ' ${ blockName } ' \n ` +
` 👤 Started by: ' ${ startMethod } ' \n ` +
` 📱 Mode: "Atomatic System" \n ` +
` 🕒 Pump started at: ${ startTime } \n ` +
` Will stop after: ' ${ threshold } ' ` ;
// 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({ fcmIds: { $in: fcmTokens } });
// console.log("users",users)
// const userNames = users.map(user => user.username).join(', ');
// console.log("userNames",userNames)
// const stopMethod = motorOnType === "Mobile APP" ? "via the App" : "manual";
// // 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 : ${userNames}\n` +
// // `Motor Off Type: '${motorOnType}'`;
// `Motor Off Type: '${stopMethod}'`;
// // 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`);
// });
eventEmitter . on ( 'sendThresholdTimeNotification' , async ( fcmTokens , message ) => {
try {
await sendNotification ( fcmTokens , 'Threshold Time Reached' , message , 'Motor Alert' ) ;
console . log ( "Threshold time notification sent successfully." ) ;
} catch ( error ) {
console . error ( "Error sending threshold time notification:" , error ) ;
}
} ) ;
// eventEmitter.on(
// 'sendMotorStartNotification',
// async (fcmTokens, motorId, waterLevel, blockName, tankName, motorOnType, stopCriteria, manual_threshold_time) => {
// try {
// // Get the latest timestamp
// const startTime = new Date().toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' });
// // Retrieve the user information
// const users = await User.find({ fcmIds: { $in: fcmTokens } });
// const userNames = users.map(user => user.username).join(', ');
// const startMethod = motorOnType.toUpperCase() === "Forced Manual";
// // Prepare the message
// const message =
// `🚰 Tank Name: '${tankName}'\n` +
// `🕒 Pump started at: '${startTime}'\n` +
// `👤 Initiated by: ${userNames}\n` +
// `🔄 Pump started by: '${startMethod}'`;
// // Send the notification
// await sendNotification(fcmTokens, 'Motor Started 🚀', message);
// console.log('Motor start notification sent successfully!');
// } catch (error) {
// console.error('Error in sendMotorStartNotification event:', error);
// }
// }
// );
eventEmitter . on (
'sendMotorStartNotification' ,
async (
fcmTokens ,
blockName ,
tankName ,
motorOnType ,
stopCriteria ,
typeOfWater ,
highThreshold // Add the high threshold as a parameter
) => {
try {
// Get the latest timestamp
const currentDateTime = new Date ( ) ;
const startTime = currentDateTime . toLocaleString ( 'en-IN' , { timeZone : 'Asia/Kolkata' } ) ;
const formattedDate = currentDateTime . toLocaleDateString ( 'en-IN' , { timeZone : 'Asia/Kolkata' } ) ;
const formattedTime = currentDateTime . toLocaleTimeString ( 'en-IN' , { timeZone : 'Asia/Kolkata' } ) ;
// Retrieve the user information
const users = await User . find ( { fcmIds : { $in : fcmTokens } } ) ;
const userNames = users . map ( user => user . username ) . join ( ', ' ) ;
// Determine the pump initiation method
const startMethod = motorOnType === "Forced Manual" ? "Physically" : "Manually"
// Dynamically generate the motor name
const motorName = ` ${ tankName } - ${ blockName } - ${ typeOfWater } ` ;
// Determine the stop condition message
let stopConditionMessage = "" ;
if ( stopCriteria === "manual" ) {
stopConditionMessage = ` Will stop at Manually \n ` ;
} else if ( stopCriteria === "highThreshold" ) {
stopConditionMessage = ` 🚨 Pump will stop when the water level reaches the high threshold of ${ highThreshold } %. \n ` ;
}
// Prepare the notification message
const message =
` 🚰 Motor Name: ${ motorName } \n ` +
` 🛢️ Tank Name: ' ${ tankName } ' \n ` +
` 🏢 Block Name: ' ${ blockName } ' \n ` +
` 👤 Started by: ${ userNames } \n ` +
` 📱 Mode: ' ${ startMethod } ' \n ` +
` 🕒 Pump started at: ${ startTime } \n ` +
stopConditionMessage ; // Add only the relevant stop condition
// Send the notification
await sendNotification ( fcmTokens , 'Motor Started 🚀' , message ) ;
console . log ( 'Motor start notification with stop criteria sent successfully!' ) ;
} catch ( error ) {
console . error ( 'Error in sendMotorStartNotification event:' , error ) ;
}
}
) ;
// eventEmitter.on(
// 'sendMotorStartNotification',
// async (fcmTokens, motorId, waterLevel, blockName, tankName, motorOnType, stopCriteria, manual_threshold_time, typeOfWater) => {
// try {
// // Get the latest timestamp
// const currentDateTime = new Date();
// const startTime = currentDateTime.toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' });
// const formattedDate = currentDateTime.toLocaleDateString('en-IN', { timeZone: 'Asia/Kolkata' });
// const formattedTime = currentDateTime.toLocaleTimeString('en-IN', { timeZone: 'Asia/Kolkata' });
// // Retrieve the user information
// const users = await User.find({ fcmIds: { $in: fcmTokens } });
// const userNames = users.map(user => user.username).join(', ');
// // Determine the pump initiation method
// const startMethod = motorOnType === "Mobile APP" ? "Mobile APP" : "Manual";
// // Dynamically generate the motor name
// const motorName = `${tankName}-${blockName}-${typeOfWater}`;
// // Prepare the notification message
// const message =
// `🚰 Motor Name: '${motorName}'\n` +
// `🚰 Tank Name: '${tankName}'\n` +
// `🏢 Block Name: '${blockName}'\n` +
// `💧 Water Level: '${waterLevel}%'\n` +
// `👤 Initiated by: ${userNames}\n` +
// `📱 Pump started by: '${startMethod}'\n` +
// `🕒 Start Time: '${startTime}'\n` +
// `⏳ Will stop after: '${manual_threshold_time}' mins\n` +
// `📅 Date: '${formattedDate}'\n` +
// `⏰ Time: '${formattedTime}'`;
// // Send the notification
// await sendNotification(fcmTokens, 'Motor Started 🚀', message);
// console.log('Motor start notification sent successfully!');
// } catch (error) {
// console.error('Error in sendMotorStartNotification event:', error);
// }
// }
// );
// eventEmitter.on(
// 'sendMotorStopNotification',
// async (fcmTokens, motorId, waterLevel, blockName, tankName, motorOnType) => {
// try {
// // Get the latest timestamp
// const stopTime = new Date().toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' });
// // Retrieve the user information
// const users = await User.find({ fcmIds: { $in: fcmTokens } });
// const userNames = users.map(user => user.username).join(', ');
// const stopMethod = motorOnType.toUpperCase() === "Forced Manual";
// // Prepare the message
// const message =
// `🚰 Tank Name: '${tankName}'\n` +
// `🕒 Pump stopped at: '${stopTime}'\n` +
// `👤 Initiated by: ${userNames}\n` +
// `🔄 Pump stopped by: '${stopMethod}'\n`;
// // Send the notification
// await sendNotification(fcmTokens, 'Motor Stopped 🛑', message);
// console.log('Motor stop notification sent successfully!');
// } catch (error) {
// console.error('Error in sendMotorStopNotification event:', error);
// }
// }
// );
eventEmitter . on (
'sendMotorStopNotification' ,
async (
fcmTokens ,
blockName ,
tankName ,
motorOnType ,
typeOfWater
) => {
try {
// Get the latest timestamp
const currentDateTime = new Date ( ) ;
const stopTime = currentDateTime . toLocaleString ( 'en-IN' , { timeZone : 'Asia/Kolkata' } ) ;
const formattedDate = currentDateTime . toLocaleDateString ( 'en-IN' , { timeZone : 'Asia/Kolkata' } ) ;
const formattedTime = currentDateTime . toLocaleTimeString ( 'en-IN' , { timeZone : 'Asia/Kolkata' } ) ;
// Retrieve the user information
const users = await User . find ( { fcmIds : { $in : fcmTokens } } ) ;
const userNames = users . map ( user => user . username ) . join ( ', ' ) ;
// Determine the pump stop method
const stopMethod = motorOnType === "Forced Manual" ? "Physically" : "Manually" ;
// Dynamically generate the motor name
const motorName = ` ${ tankName } - ${ blockName } - ${ typeOfWater } ` ;
// Determine the stop condition message
let stopConditionMessage = "" ;
if ( stopCriteria === "manual" ) {
stopConditionMessage = ` Stopped at Manually \n ` ;
} else if ( stopCriteria === "highThreshold" ) {
stopConditionMessage = ` 🚨 Pump will stop when the water level reaches the high threshold of ${ highThreshold } %. \n ` ;
}
// Prepare the notification message
const message =
` 🚰 Motor Name: ${ motorName } \n ` +
` 🛢️ Tank Name: ' ${ tankName } ' \n ` +
` 🏢 Block Name: ' ${ blockName } ' \n ` +
` 📱 Mode: ' ${ stopMethod } ' \n ` +
` 🕒 Pump stopped at: ${ stopTime } \n ` +
stopConditionMessage ;
// Send the notification
await sendNotification ( fcmTokens , 'Motor Stopped 🛑' , message ) ;
console . log ( 'Motor stop notification sent successfully!' ) ;
} catch ( error ) {
console . error ( 'Error in sendMotorStopNotification event:' , error ) ;
}
}
) ;
eventEmitter . on ( 'sendLowWaterNotification' , ( fcmTokens , message ) => {
const notificationMessage = ` Warning: Water level is low in the tank.
Tank Name : $ { tankName } ,
Location : $ { receiverTank . location } ,
Type of Water : $ { receiverTank . typeOfWater } ,
Current Water Level : $ { currentWaterLevel } liters ( $ { currentWaterPercentage . toFixed ( 2 ) } % ) ,
Date & Time : $ { new Date ( ) . toLocaleString ( ) } ` ;
// Send notifications using the provided FCM tokens
sendNotification ( fcmTokens , notificationMessage ) ;
} ) ;
eventEmitter . on ( 'sendCriticalLowWaterNotification' , ( fcmTokens , message ) => {
const notificationMessage = ` Critical Alert: Water level is critically low in the tank.
Tank Name : $ { tankName } ,
Location : $ { receiverTank . location } ,
Type of Water : $ { receiverTank . typeOfWater } ,
Current Water Level : $ { currentWaterLevel } liters ( $ { currentWaterPercentage . toFixed ( 2 ) } % ) ,
Date & Time : $ { new Date ( ) . toLocaleString ( ) } ` ;
// Send notifications using the provided FCM tokens
sendNotification ( fcmTokens , notificationMessage ) ;
} ) ;
// eventEmitter.on('sendMotorStartNotification', async (fcmTokens, message) => {
// try {
// await sendNotification(fcmTokens, "Motor Started", message);
// console.log("Manual method time notification sent successfully.");
// } catch (error) {
// console.error("Error sending thresmanual method time notification:", error);
// }
// });
// eventEmitter.on('sendMotorStopNotification', async (fcmTokens, message) => {
// try {
// await sendNotification(fcmTokens, "Motor Stopped", message);
// console.log("Manual method time notification sent successfully.");
// } catch (error) {
// console.error("Error sending thresmanual method time notification:", error);
// }
// });
// 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 sendNotification = async ( fcmIds , title , body ) => {
try {
if ( ! fcmIds || fcmIds . length === 0 ) {
throw new Error ( 'No FCM tokens provided.' ) ;
}
const flatTokens = fcmIds . flat ( ) ;
if ( flatTokens . length === 0 ) {
throw new Error ( 'Flattened FCM token list is empty.' ) ;
}
// Iterate over each token and send individually
const promises = flatTokens . map ( async ( token ) => {
try {
const response = await admin . messaging ( ) . send ( {
notification : { title , body } ,
token ,
data : {
'target' : '/screen' ,
} ,
} ) ;
console . log ( ` Notification sent successfully to token: ${ token } ` , response ) ;
} catch ( error ) {
console . error ( ` Failed to send notification to token: ${ token } ` , error ) ;
// Check for specific error indicating an invalid token
if ( error . code === 'messaging/registration-token-not-registered' ) {
// Remove the invalid token from the database
await User . updateOne (
{ fcmIds : token } , // Ensure you're targeting the right user with the invalid token
{ $pull : { fcmIds : token } } // Remove the invalid token
) ;
console . log ( ` Removed invalid token: ${ token } ` ) ;
}
}
} ) ;
await Promise . all ( promises ) ;
} catch ( error ) {
console . error ( 'Error sending notifications:' , 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 notificationSentStatus = {
motorStart : false ,
motorStop : false ,
lowWater : false ,
veryLowWater : false ,
criticallyLowWater : false ,
highWater : false ,
veryHighWater : false ,
criticallyHighWater : false ,
} ;
let waterLevelCheckInterval ; // To hold the interval ID
const checkWaterLevel = async ( customerId , motorId , fcmToken , receiverTank ) => {
const currentWaterLevel = parseInt ( receiverTank . waterlevel , 10 ) ;
const tankCapacity = parseInt ( receiverTank . capacity . replace ( /,/g , '' ) , 10 ) ;
const currentWaterPercentage = ( currentWaterLevel / tankCapacity ) * 100 ;
// Check for low water levels
if ( currentWaterPercentage <= 20 && ! notificationSentStatus . lowWater ) {
eventEmitter . emit ( 'sendLowWaterNotification' , fcmToken , ` Water level has dropped below 20%. ` ) ;
notificationSentStatus . lowWater = true ;
}
// Check for critically low water levels
if ( currentWaterPercentage <= 10 && ! notificationSentStatus . criticallyLowWater ) {
eventEmitter . emit ( 'sendCriticalLowWaterNotification' , fcmToken , ` Water level has dropped below 10%. ` ) ;
notificationSentStatus . criticallyLowWater = true ;
}
} ;
// const checkWaterLevelsAndNotify = async (customerId, tankName, tankLocation, fcmTokens) => {
// try {
// // Fetch the tank details from the database
// const tank = await Tank.findOne({ customerId, tankName, tankLocation });
// if (!tank) {
// console.error(`Tank not found: ${tankName} at location ${tankLocation}`);
// return;
// }
// // Extract the current water level and capacity
// const currentWaterLevel = parseInt(tank.waterlevel, 10);
// const capacity = parseInt(tank.capacity.replace(/,/g, ''), 10);
// // Calculate the water level percentage
// const waterLevelPercentage = (currentWaterLevel / capacity) * 100;
// // Thresholds for notifications
// const thresholds = {
// criticallyLow: 10,
// veryLow: 20,
// low: 30,
// high: 70,
// veryHigh: 80,
// criticallyHigh: 85,
// };
// // Check water levels and send notifications
// if (waterLevelPercentage <= thresholds.criticallyLow && !notificationSentStatus.criticallyLowWater) {
// eventEmitter.emit('sendCriticalLowWaterNotification', fcmTokens, tank);
// notificationSentStatus.criticallyLowWater = true;
// await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentCritical: true } });
// } else if (waterLevelPercentage <= thresholds.veryLow && !notificationSentStatus.veryLowWater) {
// eventEmitter.emit('sendVeryLowWaterNotification', fcmTokens, tank);
// notificationSentStatus.veryLowWater = true;
// await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentVeryLow: true } });
// } else if (waterLevelPercentage <= thresholds.low && !notificationSentStatus.lowWater) {
// eventEmitter.emit('sendLowWaterNotification', fcmTokens, tank);
// notificationSentStatus.lowWater = true;
// await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentLow: true } });
// }
// // if (waterLevelPercentage <= thresholds.criticallyLow) {
// // eventEmitter.emit('sendCriticalLowWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentCritical: true } });
// // } else if (waterLevelPercentage <= thresholds.veryLow) {
// // eventEmitter.emit('sendVeryLowWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentVeryLow: true } });
// // } else if (waterLevelPercentage <= thresholds.low) {
// // eventEmitter.emit('sendLowWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentLow: true } });
// // }
// // else if (waterLevelPercentage >= thresholds.criticallyHigh) {
// // eventEmitter.emit('sendCriticalHighWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentCriticalHigh: true } });
// // } else if (waterLevelPercentage >= thresholds.veryHigh) {
// // eventEmitter.emit('sendVeryHighWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentVeryHigh: true } });
// // } else if (waterLevelPercentage >= thresholds.high) {
// // eventEmitter.emit('sendHighWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentHigh: true } });
// // }
// } catch (error) {
// console.error(`Error checking water levels for tank ${tankName}:`, error);
// }
// };
exports . getPumpsAndUsers = async ( req , reply ) => {
try {
const { customerId } = req . params ;
// Fetch motor_id from inputConnections of all tanks for the customer
const tanks = await Tank . find ( { customerId } , { "connections.inputConnections.motor_id" : 1 } ) ;
const motorIds = tanks . flatMap ( ( tank ) =>
tank . connections ? . inputConnections ? . map ( ( conn ) => conn . motor _id ) . filter ( Boolean ) || [ ]
) ;
// Fetch username and staff names from User collection
const user = await User . findOne ( { customerId } , { username : 1 , "staff.staff.name" : 1 } ) ;
const staffNames = user ? . staff ? . staff ? . map ( ( s ) => s . name ) || [ ] ;
const username = user ? . username || "" ;
// Include username at the beginning of staffNames and add "manual" at the end
const updatedStaffNames = [ username , ... staffNames , "manual" , "user" ] ;
// Prepare response
const result = {
motorIds ,
staffNames : updatedStaffNames ,
} ;
return reply . send ( { success : true , data : result } ) ;
} catch ( error ) {
console . error ( "Error fetching data:" , error ) ;
return reply . status ( 500 ) . send ( { success : false , message : "Internal Server Error" } ) ;
}
} ;
const monitorWaterLevels = async ( ) => {
try {
const tanks = await Tank . find ( { } ) ;
// Iterate through each tank
for ( const tank of tanks ) {
// Fetch users associated with the customerId of the tank
const users = await User . find ( { customerId : tank . customerId } ) ;
const fcmTokens = users
. map ( user => user . fcmIds )
. filter ( fcmIds => fcmIds )
. flat ( ) ; // Flatten if there are multiple fcmIds for each user
// Ensure that fcmTokens exist before proceeding
if ( fcmTokens . length > 0 ) {
const customerId = tank . customerId ;
const tankName = tank . tankName ; // Assuming tank has a 'name' field
const tankLocation = tank . tankLocation ; // Assuming tank has a 'location' field
// Call the function to check water levels and send notifications
//await checkWaterLevelsAndNotify(customerId, tankName, tankLocation, fcmTokens);
} else {
//console.log(`No FCM tokens found for customerId ${tank.customerId}`);
}
}
} catch ( error ) {
console . error ( 'Error monitoring water levels:' , error ) ;
}
} ;
// Schedule the task to run every 30 minutes
setInterval ( monitorWaterLevels , 30 * 60 * 1000 ) ;
const motorIntervals = { } ;
async function calculateTotalPumpedWater ( customerId , motorId , start _instance _id ) {
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 waterPumpedTillNow = parseInt ( receiverTank . total _water _added _from _midnight , 10 ) ;
return quantityDelivered + waterPumpedTillNow ; // Total water pumped
}
return 0 ; // Return 0 if no data found
}
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 = 5 ; // 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 . fcmIds ) . filter ( fcmIds => fcmIds ) ;
console . log ( fcmToken )
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 } ;
const typeOfWater = receiverTank . typeOfWater ;
console . log ( typeOfWater , "typeOfWater" )
// 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
const motorOnType = "manual" ;
const manual _threshold _time = req . body . manual _threshold _time ;
let hasNotifiedStart = false ;
let hasNotifiedStop = false ;
if ( action === "start" ) {
motorStopStatus = "2" ;
const startTime = req . body . startTime ;
await Tank . updateOne (
{ customerId , "connections.inputConnections.motor_id" : motorId } ,
{ $set : { "connections.inputConnections.$.motor_stop_status" : motorStopStatus } }
) ;
const thresholdTimeMs = req . body . manual _threshold _time * 60 * 1000 ; // Convert minutes to milliseconds
const stopCriteria =
motorOnType === "time"
? ` ${ req . body . manual _threshold _time } minutes `
: ` ${ req . body . manual _threshold _litres } litres ` ;
// await checkWaterLevelsAndNotify(customerId, tankName, receiverTank.tankLocation, fcmToken);
if ( ! notificationSentStatus . motorStart ) {
eventEmitter . emit (
'motorStart' ,
fcmToken ,
tankName ,
blockName ,
startTime ,
"Mobile APP" ,
manual _threshold _time ,
typeOfWater
) ;
notificationSentStatus . motorStart = true ; // Set flag to true to prevent duplicate notifications
}
// Start checking water level every 30 minutes
if ( ! waterLevelCheckInterval ) {
waterLevelCheckInterval = setInterval ( async ( ) => {
await checkWaterLevel ( customerId , motorId , fcmToken , receiverTank ) ;
} , 30 * 60 * 1000 ) ; // 30 minutes
}
await Tank . updateOne (
{ customerId , "connections.inputConnections.motor_id" : motorId } ,
{ $set : { "connections.inputConnections.$.motor_stop_status" : "2" ,
"connections.inputConnections.$.manual_threshold_time" : manual _threshold _time ,
"connections.inputConnections.$.threshold_type" : "time" ,
"connections.inputConnections.$.motor_on_type" : "manual" } }
) ;
reply . code ( 200 ) . send ( { message : "Motor started successfully." } ) ;
} else if ( action === "stop" ) {
motorStopStatus = "1" ; // If action is stop, set stop status to "1"
if ( ! notificationSentStatus . motorStop ) {
// Emit motorStop event
const totalWaterPumped = await calculateTotalPumpedWater ( customerId , motorId , start _instance _id ) ; // A function to calculate total water pumped
eventEmitter . emit (
'motorStop' ,
fcmToken ,
tankName ,
blockName ,
stopTime ,
"Mobile APP" ,
totalWaterPumped , // Include total water pumped
typeOfWater
) ;
notificationSentStatus . motorStop = true ; // Set flag to true to prevent duplicate notifications
}
await Tank . updateOne (
{ customerId , "connections.inputConnections.motor_id" : motorId } ,
{
$set : {
"connections.inputConnections.$.motor_stop_status" : "1" ,
"connections.inputConnections.$.motor_on_type" : motorOnType }
}
) ;
// Clear the interval when the motor is stopped
if ( waterLevelCheckInterval ) {
clearInterval ( waterLevelCheckInterval ) ;
waterLevelCheckInterval = null ; // Reset the interval ID
}
} else {
throw new Error ( "Invalid action provided." ) ;
}
// 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 ( ) => {
console . log ( start _instance _id , "start_instance_id" , customerId , "customerId" , motorId , "motorId" )
const motorData = await MotorData . findOne ( { customerId , motor _id : motorId , start _instance _id : start _instance _id } ) ;
if ( motorData ) {
console . log ( "entered if in stop" )
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" )
// Emit the threshold time notification
// eventEmitter.emit(
// "sendThresholdTimeNotification",
// fcmToken,
// `Motor has reached its time threshold of ${req.body.manual_threshold_time} minutes and will stop.`
// );
const currentTime = moment ( ) . tz ( 'Asia/Kolkata' ) . format ( 'DD-MMM-YYYY - HH:mm' ) ;
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 ,
"connections.inputConnections.$.stopTime" : currentTime ,
}
}
) ;
// eventEmitter.emit('sendLowWaterNotification', fcmToken, receiverTank);
// console.log(motorIntervals[motorId],"deleted automatically") // Emit low water level notification
// clearInterval(motorIntervals[motorId]); // Clear interval
// delete motorIntervals[motorId];
// await checkWaterLevelsAndNotify(customerId, tankName, supplierTank.tankLocation, fcmToken);
// if (currentWaterPercentage >= highWaterThreshold && !notificationSentStatus.highWater) {
// eventEmitter.emit('sendHighWaterNotification', fcmToken, `Water level has reached high levels.`);
// notificationSentStatus.highWater = true; // Set flag to true to prevent duplicate notifications
// }
// if (currentWaterPercentage >= veryHighWaterThreshold && !notificationSentStatus.veryHighWater) {
// eventEmitter.emit('sendVeryHighWaterNotification', fcmToken, `Water level has reached very high levels.`);
// notificationSentStatus.veryHighWater = true; // Set flag to true to prevent duplicate notifications
// }
// if (currentWaterPercentage >= criticalHighWaterThreshold && !notificationSentStatus.criticallyHighWater) {
// eventEmitter.emit('sendCriticalHighWaterNotification', fcmToken, `Water level has reached critically high levels.`);
// notificationSentStatus.criticallyHighWater = true; // Set flag to true to prevent duplicate notifications
// }
clearInterval ( motorIntervals [ motorId ] ) ; // Stop the motor if condition met
delete motorIntervals [ motorId ] ; // Remove from interval object
this . publishMotorStopStatus ( motorId , "1" ) ;
console . log ( start _instance _id , "start_instance_id" , customerId , "customerId" , motorId , "motorId" )
const motorData = await MotorData . findOne ( { customerId , motor _id : motorId , start _instance _id : start _instance _id } ) ;
console . log ( motorData , "motorData" )
if ( motorData ) {
console . log ( "got into if" )
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 : currentTime ,
receiverfinalwaterlevel : receiverFinalWaterLevel . toString ( ) ,
quantity _delivered : quantityDelivered . toString ( )
}
}
) ;
}
}
// Check for high water level and send notification
// if (currentWaterPercentage >= highWaterThreshold) {
// // eventEmitter.emit('sendHighWaterNotification', fcmToken, receiverTank);
// await checkWaterLevelsAndNotify(customerId, tankName, supplierTank.tankLocation, fcmToken);
// }
} , 30000 ) ; // Check every minute
}
} else if ( req . body . threshold _type === "litres" ) {
console . log ( "entered litres" )
const receiver _tank _info7 = await Tank . findOne ( { customerId , tankName : req . body . to , tankLocation : req . body . to _type . toLowerCase ( ) } ) ;
const supplier _tank _info7 = await Tank . findOne ( { customerId , tankName : req . body . from , tankLocation : req . body . from _type . toLowerCase ( ) } ) ;
const newMotorData = new MotorData ( {
customerId : customerId ,
motor _id : motorId ,
start _instance _id : start _instance _id ,
supplierTank : req . body . from ,
receiverTank : req . body . to ,
supplier _type : req . body . from _type ,
receiver _type : req . body . to _type ,
startTime : req . body . startTime ,
receiverInitialwaterlevel : parseInt ( receiver _tank _info7 . waterlevel , 10 ) ,
supplierInitialwaterlevel : parseInt ( supplier _tank _info7 . waterlevel , 10 )
} ) ;
await newMotorData . save ( ) ;
// If threshold type is percentage, calculate percentage threshold
const receiver _tank _info = await Tank . findOne ( { customerId , tankName : req . body . to , tankLocation : req . body . to _type . toLowerCase ( ) } ) ;
const supplier _tank _info = await Tank . findOne ( { customerId , tankName : req . body . from , tankLocation : req . body . from _type . toLowerCase ( ) } ) ;
if ( ! receiver _tank _info ) {
throw new Error ( "Receiver tank not found." ) ;
}
if ( ! supplier _tank _info ) {
throw new Error ( "Supplierr tank not found." ) ;
}
const supplier _capacity = parseInt ( supplier _tank _info . capacity , 10 ) ;
const supplier _waterLevel = parseInt ( supplier _tank _info . waterlevel , 10 ) ;
const capacity = parseInt ( receiver _tank _info . capacity , 10 ) ;
const waterLevel = parseInt ( receiver _tank _info . waterlevel , 10 ) ;
const desired _percentage = parseInt ( req . body . manual _threshold _litres . replace ( /,/g , '' ) , 10 ) ;
console . log ( desired _percentage )
const threshold _water _level = waterLevel + desired _percentage ;
const supplier _threshold = supplier _waterLevel - desired _percentage
console . log ( supplier _threshold , "supplier_threshold" )
for await ( const tank of Tank . find ( { "connections.inputConnections.motor_id" : motorId } ) ) {
this . publishMotorStopStatus ( motorId , motorStopStatus ) ;
for await ( const tank of Tank . find ( { "connections.inputConnections.motor_id" : motorId } ) ) {
const index = tank . connections . inputConnections . findIndex ( connection => connection . motor _id === motorId ) ;
if ( index !== - 1 ) {
await Tank . updateOne (
{ customerId , "connections.inputConnections.motor_id" : motorId } ,
{ $set : { [ ` connections.inputConnections. ${ index } .manual_threshold_percentage ` ] : supplier _threshold . toString ( ) , [ ` connections.inputConnections. ${ index } .startTime ` ] : req . body . startTime } }
) ;
}
}
// Update water level threshold
// Start monitoring water level based on threshold percentage
motorIntervals [ motorId ] = setInterval ( async ( ) => {
// Check if water level has reached the threshold percentage
const supplier _tank _info1 = await Tank . findOne ( { customerId , tankName : req . body . from , tankLocation : req . body . from _type . toLowerCase ( ) } ) ;
const current _water _level = parseInt ( supplier _tank _info1 . waterlevel , 10 ) ;
if ( current _water _level <= supplier _threshold ) {
// Stop the motor pump
await Tank . updateOne (
{ customerId , "connections.inputConnections.motor_id" : motorId } ,
{
$set : {
"connections.inputConnections.$.motor_stop_status" : "1" ,
"connections.inputConnections.$.threshold_type" : null ,
"connections.inputConnections.$.manual_threshold_time" : null ,
"connections.inputConnections.$.manual_threshold_percentage" : null
}
}
) ;
clearInterval ( motorIntervals [ motorId ] ) ; // Clear interval
delete motorIntervals [ motorId ] ;
this . publishMotorStopStatus ( motorId , "1" ) ;
await delay ( 300000 ) ;
const motorData = await MotorData . findOne ( { customerId , motor _id : motorId , start _instance _id : start _instance _id } ) ;
if ( motorData ) {
const receiverTank = await Tank . findOne ( { customerId , tankName : motorData . receiverTank , tankLocation : motorData . receiver _type . toLowerCase ( ) } ) ;
const receiverFinalWaterLevel = parseInt ( receiverTank . waterlevel , 10 ) ;
const quantityDelivered = receiverFinalWaterLevel - parseInt ( motorData . receiverInitialwaterlevel , 10 ) ;
const stopTime = formatDate ( new Date ( ) ) ;
await MotorData . updateOne (
{ customerId , motor _id : motorId , start _instance _id : start _instance _id } ,
{
$set : {
stopTime : stopTime ,
receiverfinalwaterlevel : receiverFinalWaterLevel . toString ( ) ,
quantity _delivered : quantityDelivered . toString ( )
}
}
) ;
}
}
} , 20000 ) ;
}
}
}
// Respond with success message
reply . code ( 200 ) . send ( { message : ` Motor ${ action === "start" ? "started" : "stopped" } successfully. ` } ) ;
} 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
const startTime = req . body . startTime ;
const stopTime = req . body . stopTime ;
const threshold = req . body . threshold || "unknown" ;
if ( ! motorId ) {
throw new Error ( "Motor ID is required." ) ;
}
let motorStopStatus ;
const tank = await Tank . findOne ( { customerId , "connections.inputConnections.motor_id" : motorId } ) ;
if ( ! tank ) {
throw new Error ( "Tank not found for the provided motor ID." ) ;
}
const { tankName , blockName , typeOfWater , fcmTokens } = tank ; // Extracting necessary details
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" ,
}
}
) ;
eventEmitter . emit (
"motorStartAutomatic" ,
fcmTokens ,
tankName ,
blockName ,
startTime ,
"Automatic" ,
typeOfWater ,
threshold
) ;
}
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 ,
}
}
) ;
const currentDateTime = new Date ( ) ;
const formattedDate = currentDateTime . toLocaleDateString ( ) ;
const formattedTime = currentDateTime . toLocaleTimeString ( ) ;
const stopMessage =
` 🚰 Motor Name: ${ tankName } - ${ blockName } - ${ typeOfWater } \n ` +
` 🛢️ Tank Name: ' ${ tankName } ' \n ` +
` 🏢 Block Name: ' ${ blockName } ' \n ` +
` 🕒 Pump stopped at: ${ stopTime } \n ` +
` ⏳ Operation Duration: ${ threshold } ` ;
// Send stop notification
await sendNotification ( fcmTokens , "Arminta Water Management" , stopMessage ) ;
}
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 ) ;
} ;
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 ) ;
const capacity = parseInt ( ( tank . capacity ) . 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 ;
// const available_capacity = total_water_added_from_midnight + waterlevel;
const consumed _percentage = ( ( totalconsumption / capacity ) * 100 ) . toFixed ( 2 ) ;
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 ,
available _capacity : ( tank . capacity ) . toString ( ) ,
consumption : totalconsumption . toString ( ) ,
consumed _percentage : consumed _percentage . 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.' ) ;
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 ;
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 ) ;
}
} ;
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 ;
let { tankName , tankLocation , auto _min _percentage , auto _max _percentage , auto _mode _type } = req . body ;
// Handle the optional parameters
tankName = tankName ? tankName : null ;
tankLocation = tankLocation ? tankLocation . toLowerCase ( ) : null ;
const filter = { customerId } ;
// If tankName is not 'all', add it to the filter
if ( tankName && tankName !== "all" ) {
filter . tankName = tankName ;
}
// Only add tankLocation to the filter if tankName is not 'all'
if ( tankLocation && tankName !== "all" ) {
filter . tankLocation = tankLocation ;
}
console . log ( "Update filter:" , JSON . stringify ( filter , null , 2 ) ) ;
// Check if tanks exist
const matchingTanks = await Tank . find ( filter ) ;
console . log ( "Matching tanks:" , matchingTanks ) ;
if ( matchingTanks . length === 0 ) {
return reply . send ( { status _code : 400 , message : "No matching records found." } ) ;
}
// Define the update fields
const updateData = {
auto _min _percentage : String ( auto _min _percentage || "20" ) ,
auto _max _percentage : String ( auto _max _percentage || "80" ) ,
auto _mode _type : auto _mode _type || "default" ,
} ;
let result ;
if ( tankName && tankName !== "all" ) {
// Update only one tank if tankName is specified and not "all"
result = await Tank . updateOne ( filter , { $set : updateData } ) ;
} else {
// Update all tanks of the particular customer if tankName is "all"
result = await Tank . updateMany ( filter , { $set : updateData } ) ;
// If auto_mode_type is default and tankName is "all", save or update the data in CustomerAutoPercentages
if ( auto _mode _type === "default" ) {
const currentDate = new Date ( ) . toLocaleString ( "en-GB" , { timeZone : "UTC" } ) ; // Get current date in UTC
const formattedDate = currentDate . split ( "," ) . join ( " -" ) ; // Format it like '17-Dec-2024 - 15:56'
// Use findOneAndUpdate to either update the existing record or create a new one if it doesn't exist
const updateOrCreate = await CustomerAutoPercentages . findOneAndUpdate (
{ customerId } , // Search for the record with the customerId
{
$set : {
auto _min _percentage : String ( auto _min _percentage || "20" ) ,
auto _max _percentage : String ( auto _max _percentage || "80" ) ,
date : formattedDate ,
} ,
} ,
{ upsert : true , new : true } // If no record found, create a new one; return the updated record
) ;
console . log ( "CustomerAutoPercentages updated/created:" , updateOrCreate ) ;
}
}
console . log ( "Update result:" , result ) ;
reply . send ( { status _code : 200 , message : "Auto mode and percentages updated successfully." } ) ;
} catch ( error ) {
console . error ( error ) ;
reply . send ( { status _code : 500 , message : "Internal server error." } ) ;
}
} ;
// Controller function to get CustomerAutoPercentages by customerId
exports . getCustomerAutoPercentages = async ( req , reply ) => {
try {
const { customerId } = req . params ; // Extract customerId from the params
// Find the record in CustomerAutoPercentages based on customerId
const customerData = await CustomerAutoPercentages . findOne ( { customerId } ) ;
if ( ! customerData ) {
return reply . send ( {
status _code : 404 ,
message : "No data found for the provided customerId."
} ) ;
}
reply . send ( {
status _code : 200 ,
message : "Customer data retrieved successfully." ,
data : customerData
} ) ;
} catch ( error ) {
console . error ( error ) ;
reply . send ( {
status _code : 500 ,
message : "Internal server error."
} ) ;
}
} ;
// exports.update_auto_percentage = async (req, reply) => {
// try {
// const customerId = req.params.customerId;
// let { tankName, tankLocation, auto_min_percentage, auto_max_percentage, auto_mode_type } = req.body;
// // Handle the optional parameters
// tankName = tankName ? tankName : null;
// tankLocation = tankLocation ? tankLocation.toLowerCase() : null;
// const filter = { customerId };
// // If tankName is not 'all', add it to the filter
// if (tankName && tankName !== "all") {
// filter.tankName = tankName;
// }
// // Only add tankLocation to the filter if tankName is not 'all'
// if (tankLocation && tankName !== "all") {
// filter.tankLocation = tankLocation;
// }
// console.log("Update filter:", JSON.stringify(filter, null, 2));
// // Check if tanks exist
// const matchingTanks = await Tank.find(filter);
// console.log("Matching tanks:", matchingTanks);
// if (matchingTanks.length === 0) {
// return reply.send({ status_code: 400, message: "No matching records found." });
// }
// // Define the update fields
// const updateData = {
// auto_min_percentage: String(auto_min_percentage || "20"),
// auto_max_percentage: String(auto_max_percentage || "80"),
// auto_mode_type: auto_mode_type || "default",
// };
// let result;
// if (tankName && tankName !== "all") {
// // Update only one tank if tankName is specified and not "all"
// result = await Tank.updateOne(filter, { $set: updateData });
// } else {
// // Update all tanks of the particular customer if tankName is "all"
// result = await Tank.updateMany(filter, { $set: updateData });
// }
// console.log("Update result:", result);
// reply.send({ status_code: 200, message: "Auto mode and percentages updated successfully." });
// } catch (error) {
// console.error(error);
// reply.send({ status_code: 500, message: "Internal server 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 moment = require('moment-timezone');
// // const IotData = require('./models/IotData'); // Replace with your actual model
// // const Tank = require('./models/Tank'); // Replace with your actual model
// // A map to keep track of MQTT clients by hw_Id
// const mqttClients = new Map();
// // Function to create a new MQTT client for a specific hw_Id
// function createMqttClient(hw_Id) {
// const client = mqtt.connect('mqtt://35.207.198.4:1883'); // Connect to the MQTT broker
// client.on('connect', () => {
// console.log(`Client for hw_Id ${hw_Id} connected to MQTT broker`);
// client.subscribe('water/iot-data', (err) => {
// if (err) {
// console.error(`Error subscribing to topic for hw_Id ${hw_Id}:`, err);
// } else {
// console.log(`Client for hw_Id ${hw_Id} subscribed to water/iot-data topic`);
// }
// });
// });
// client.on('message', async (topic, message) => {
// if (topic === 'water/iot-data') {
// try {
// const data = JSON.parse(message.toString());
// const { hw_Id: receivedHwId, Motor_status, tanks } = data.objects;
// // Ensure we process data only for the current client
// if (receivedHwId !== hw_Id) return;
// // Get the current date and time
// 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 tank documents for the received tanks
// const tankDocuments = tanks.map(tank => ({
// tankhardwareId: tank.Id,
// tankHeight: tank.level,
// date,
// time
// }));
// // Save IoT data
// const iotTankData = new IotData({
// hardwareId: receivedHwId,
// Motor_status,
// tanks: tankDocuments,
// date,
// time
// });
// await iotTankData.save();
// // Delete excess records (keep only the latest three)
// const recordsToKeep = 3;
// const recordsToDelete = await IotData.find({ hardwareId: receivedHwId })
// .sort({ date: -1, time: -1 })
// .skip(recordsToKeep);
// for (const record of recordsToDelete) {
// await record.remove();
// }
// // Process tanks
// for (const tank of tanks) {
// const { Id: tankhardwareId, level: tankHeight } = tank;
// const existingTank = await Tank.findOne({ hardwareId: receivedHwId, tankhardwareId });
// if (!existingTank) continue;
// const customerId = existingTank.customerId;
// const tank_name = existingTank.tankName;
// const tankHeightInCm = (parseInt(existingTank.height.replace(/,/g, ''), 10)) * 30.48;
// 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);
// if (tankHeight > 0 && waterLevel >= 0) {
// existingTank.waterlevel = waterLevel;
// await existingTank.save();
// 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;
// await linkedTank.save();
// }
// }
// }
// }
// }
// }
// // Update motor status
// const status = Motor_status;
// const motorTank = await Tank.findOne({ "connections.inputConnections.motor_id": receivedHwId });
// if (motorTank) {
// const inputConnection = motorTank.connections.inputConnections.find(conn => conn.motor_id === receivedHwId);
// if (inputConnection) {
// inputConnection.motor_status = status;
// if (inputConnection.motor_stop_status === "1" && status === 2 && inputConnection.motor_on_type !== "forced_manual") {
// const currentTime = moment().tz('Asia/Kolkata').format('DD-MMM-YYYY - HH:mm');
// inputConnection.motor_stop_status = "2";
// inputConnection.motor_on_type = "forced_manual";
// inputConnection.startTime = currentTime;
// }
// if (inputConnection.motor_stop_status === "2" && status === 1) {
// inputConnection.motor_stop_status = "1";
// }
// await motorTank.save();
// }
// }
// console.log(`Data processed successfully for hw_Id: ${receivedHwId}`);
// } catch (err) {
// console.error(`Error processing message for hw_Id ${hw_Id}:`, err.message);
// }
// }
// });
// return client;
// }
// // Handle incoming MQTT messages for water/iot-data topic
// const mainClient = mqtt.connect('mqtt://35.207.198.4:1883');
// mainClient.on('connect', () => {
// console.log('Main client connected to MQTT broker');
// mainClient.subscribe('water/iot-data', (err) => {
// if (err) {
// console.error('Error subscribing to water/iot-data topic:', err);
// }
// });
// });
// mainClient.on('message', (topic, message) => {
// if (topic === 'water/iot-data') {
// try {
// const data = JSON.parse(message.toString());
// const { hw_Id } = data.objects;
// if (!mqttClients.has(hw_Id)) {
// const client = createMqttClient(hw_Id);
// mqttClients.set(hw_Id, client);
// }
// } catch (err) {
// console.error('Error handling message in main client:', 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
console . log ( tankHeight , "this is located in tank controllers at iot-data mqtt sub " )
if ( tankHeight > 0 && waterLevel >= 0 ) {
existingTank . waterlevel = waterLevel ;
await existingTank . save ( ) ;
// Update linked tanks (input/output connections)
for ( const outputConnection of existingTank . connections . outputConnections ) {
const linkedTank = await Tank . findOne ( { customerId , tankName : outputConnection . outputConnections , tankLocation : outputConnection . output _type } ) ;
if ( linkedTank ) {
for ( const inputConnection of linkedTank . connections . inputConnections ) {
if ( inputConnection . inputConnections === tank _name ) {
inputConnection . water _level = waterLevel ; // Update water level for linked tank
await linkedTank . save ( ) ; // Save updated linked tank
}
}
}
}
}
}
// Update motor status
const 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
if ( inputConnection . motor _stop _status === "1" && status === 2 && inputConnection . motor _on _type !== "forced_manual" ) {
const currentTime = moment ( ) . tz ( 'Asia/Kolkata' ) . format ( 'DD-MMM-YYYY - HH:mm' ) ;
inputConnection . motor _stop _status = "2" ;
inputConnection . motor _on _type = "forced_manual" ;
inputConnection . startTime = currentTime ;
}
if ( inputConnection . motor _stop _status === "2" && status === 1 ) {
const currentTime = moment ( ) . tz ( 'Asia/Kolkata' ) . format ( 'DD-MMM-YYYY - HH:mm' ) ;
inputConnection . motor _stop _status = "1" ;
inputConnection . stopTime = currentTime ;
}
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 ) ;
}
}
} ) ;
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" )
// const calculateDailyConsumptionAndNotify = async () => {
// try {
// const today = moment().startOf("day");
// const yesterday = moment(today).subtract(1, "days");
// // Fetch all active users
// const activeUsers = await User.find({ });
// for (const user of activeUsers) {
// const { customerId, fcmIds } = user;
// // Fetch daily consumption for the customer
// const consumptions = await TankConsumptionOriginalSchema.find({
// customerId,
// time: {
// $gte: yesterday.format("DD-MMM-YYYY - HH:mm"),
// $lt: today.format("DD-MMM-YYYY - HH:mm"),
// },
// });
// // Calculate total consumption
// const totalConsumption = consumptions.reduce((total, record) => {
// return total + parseInt(record.consumption, 10);
// }, 0);
// // Prepare tank-wise consumption details
// const tankDetails = consumptions.map((record) => ({
// tankName: record.tankName,
// consumption: record.consumption,
// }));
// // Send notification
// const notificationTitle = "Daily Water Consumption Report";
// const notificationBody = `
// Total Consumption: ${totalConsumption} liters
// Tank Details: ${tankDetails
// .map((tank) => `${tank.tankName}: ${tank.consumption} liters`)
// .join(", ")}
// `;
// if (fcmIds && fcmIds.length > 0) {
// await sendNotification(fcmIds, notificationTitle, notificationBody);
// }
// }
// console.log("Daily consumption notifications sent successfully.");
// } catch (err) {
// console.error("Error sending daily consumption notifications:", err);
// }
// };
// cron.schedule("0 11:57 * * *", async () => {
// console.log("Starting daily consumption notification task...");
// await calculateDailyConsumptionAndNotify();
// });
// cron.schedule(
// "0 9 * * *",
// async () => {
// console.log("Starting daily consumption notification task...");
// await calculateDailyConsumptionAndNotify();
// },
// {
// timezone: "Asia/Kolkata", // Specify the timezone
// }
// );
// const calculateDailyConsumptionAndNotify = async () => {
// try {
// const today = moment().startOf("day");
// const yesterday = moment(today).subtract(1, "days");
// // Fetch all active users
// const activeUsers = await User.find({});
// for (const user of activeUsers) {
// const { customerId, fcmIds } = user;
// // Fetch daily consumption for the customer
// const consumptions = await TankConsumptionOriginalSchema.find({
// customerId,
// time: {
// $gte: yesterday.format("DD-MMM-YYYY - HH:mm"),
// $lt: today.format("DD-MMM-YYYY - HH:mm"),
// },
// });
// // Calculate total consumption by type of water and the water level percentage
// const consumptionSummary = consumptions.reduce((acc, record) => {
// const typeOfWater = record.typeOfWater; // Assuming this field exists
// const consumption = parseInt(record.consumption, 10);
// const waterLevel = parseInt(record.waterLevel, 10); // Assuming waterLevel is in percentage
// if (!acc[typeOfWater]) {
// acc[typeOfWater] = {
// totalConsumption: 0,
// tankDetails: [],
// totalWaterLevel: 0,
// count: 0,
// };
// }
// acc[typeOfWater].totalConsumption += consumption;
// acc[typeOfWater].totalWaterLevel += waterLevel;
// acc[typeOfWater].count += 1;
// acc[typeOfWater].tankDetails.push({
// tankName: record.tankName,
// consumption,
// waterLevel,
// });
// return acc;
// }, {});
// // Prepare notification body
// let notificationBody = "Daily Water Consumption Report:\n";
// for (const type in consumptionSummary) {
// const { totalConsumption, tankDetails, totalWaterLevel, count } = consumptionSummary[type];
// const averageWaterLevel = (totalWaterLevel / count).toFixed(2); // Calculate average water level
// console.log("averageWaterLevel",averageWaterLevel)
// console.log("totalConsumption",totalConsumption)
// notificationBody += `
// Type of Water: ${type}
// Total Consumption: ${totalConsumption} liters
// Average Water Level: ${averageWaterLevel}%
// `;
// console.log("noti---" ,notificationBody += `
// Type of Water: ${type}
// Total Consumption: ${totalConsumption} liters
// Average Water Level: ${averageWaterLevel}%
// `)
// }
// if (fcmIds && fcmIds.length > 0) {
// await sendNotification(fcmIds, "Daily Water Consumption Report", notificationBody);
// }
// }
// console.log("Daily consumption notifications sent successfully.");
// } catch (err) {
// console.error("Error sending daily consumption notifications:", err);
// }
// };
const calculateDailyConsumptionAndNotify = async ( ) => {
try {
const today = moment ( ) . startOf ( "day" ) ;
const yesterday = moment ( today ) . subtract ( 1 , "days" ) ;
// Fetch all active users
const activeUsers = await User . find ( { } ) ;
for ( const user of activeUsers ) {
const { customerId , fcmIds } = user ;
// Fetch daily consumption for the customer
const consumptions = await TankConsumptionOriginalSchema . find ( {
customerId ,
time : {
$gte : yesterday . format ( "DD-MMM-YYYY - HH:mm" ) ,
$lt : today . format ( "DD-MMM-YYYY - HH:mm" ) ,
} ,
} ) ;
// Calculate total consumption and capacities based on water type
let totalBoreConsumption = 0 ;
let totalDrinkingConsumption = 0 ;
let totalBoreCapacity = 0 ;
let totalDrinkingCapacity = 0 ;
for ( const record of consumptions ) {
const typeOfWater = record . typeOfWater ; // Assuming this field exists
const consumption = parseInt ( record . consumption , 10 ) ;
const capacity = parseInt ( record . capacity , 10 ) ; // Assuming capacity field exists
if ( typeOfWater === "bore" || typeOfWater === "Bore Water" ) {
totalBoreConsumption += consumption ;
totalBoreCapacity += capacity ;
} else if ( typeOfWater === "drinking" || typeOfWater === "Drinking Water" ) {
totalDrinkingConsumption += consumption ;
totalDrinkingCapacity += capacity ;
}
}
// Calculate percentages
const boreConsumptionPercentage = totalBoreCapacity
? ( ( totalBoreConsumption / totalBoreCapacity ) * 100 ) . toFixed ( 2 )
: 0 ;
const drinkingConsumptionPercentage = totalDrinkingCapacity
? ( ( totalDrinkingConsumption / totalDrinkingCapacity ) * 100 ) . toFixed ( 2 )
: 0 ;
// Prepare notification body
const reportDate = yesterday . format ( "DD-MMM-YYYY" ) ;
let notificationBody = ` Daily Water Consumption Report for ${ reportDate } : \n ` ;
notificationBody += ` Total Bore Consumption: ${ totalBoreConsumption } liters \n ` ;
notificationBody += ` Bore Water Consumption Percentage: ${ boreConsumptionPercentage } % \n ` ;
notificationBody += ` Total Drinking Consumption: ${ totalDrinkingConsumption } liters \n ` ;
notificationBody += ` Drinking Water Consumption Percentage: ${ drinkingConsumptionPercentage } % \n ` ;
// Send notification if FCM IDs are present
if ( fcmIds && fcmIds . length > 0 ) {
await sendNotification ( fcmIds , "Daily Water Consumption Report" , notificationBody ) ;
}
}
console . log ( "Daily consumption notifications sent successfully." ) ;
} catch ( err ) {
console . error ( "Error sending daily consumption notifications:" , err ) ;
}
} ;
// Schedule the cron job to run daily at 9 AM
cron . schedule (
"0 9 * * *" ,
async ( ) => {
console . log ( "Starting daily consumption notification task..." ) ;
await calculateDailyConsumptionAndNotify ( ) ;
} ,
{
timezone : "Asia/Kolkata" , // Specify the timezone
}
) ;
const calculateConsumptionAndNotify = async ( ) => {
try {
const now = moment ( ) ; // Current time
const sixHoursAgo = moment ( now ) . subtract ( 6 , 'hours' ) . startOf ( 'hour' ) ; // 6 hours ago
// Fetch all active users
const activeUsers = await User . find ( { } ) ;
for ( const user of activeUsers ) {
const { customerId , fcmIds } = user ;
// Fetch consumption records for the last 6 hours
const consumptions = await TankConsumptionOriginalSchema . find ( {
customerId ,
time : {
$gte : sixHoursAgo . format ( "DD-MMM-YYYY - HH:mm" ) ,
$lt : now . format ( "DD-MMM-YYYY - HH:mm" ) ,
} ,
} ) ;
// Prepare notification body
let notificationBody = ` Water Consumption Report (From ${ sixHoursAgo . format (
"hh:mm A"
) } to $ { now . format ( "hh:mm A" ) } ) : \ n ` ;
const tankDetails = { } ;
// Aggregate consumption data by tank
for ( const record of consumptions ) {
const tankName = record . tankName ; // Assuming this field exists
const tankLocation = record . tankLocation ; // Assuming this field exists
const consumption = parseInt ( record . consumption , 10 ) ; // Liters consumed
const typeOfWater = record . typeOfWater ; // Type of water (e.g., bore, drinking)
const tankCapacity = parseInt ( record . capacity , 10 ) ; // Tank capacity in liters
if ( ! tankDetails [ tankName ] ) {
tankDetails [ tankName ] = {
tankLocation ,
totalConsumption : 0 ,
typeOfWater ,
tankCapacity ,
} ;
}
tankDetails [ tankName ] . totalConsumption += consumption ;
}
// Format tank details for the notification
for ( const tankName in tankDetails ) {
const {
tankLocation ,
totalConsumption ,
typeOfWater ,
tankCapacity ,
} = tankDetails [ tankName ] ;
const consumptionPercentage = tankCapacity
? ( ( totalConsumption / tankCapacity ) * 100 ) . toFixed ( 2 )
: 0 ;
notificationBody +=
` Tank Name: ${ tankName } \n ` +
` Location: ${ tankLocation } \n ` +
` Total Consumption: ${ totalConsumption } liters ${ consumptionPercentage } % \n ` +
` Type of Water: ${ typeOfWater } ` ;
}
// Send notification if FCM IDs are present
if ( fcmIds && fcmIds . length > 0 ) {
await sendNotification ( fcmIds , "Water Consumption Report" , notificationBody ) ;
}
}
console . log ( "Consumption notifications sent successfully." ) ;
} catch ( err ) {
console . error ( "Error sending consumption notifications:" , err ) ;
}
} ;
const calculateWaterLevelAndNotify = async ( ) => {
try {
const now = moment ( ) ;
const sixHoursAgo = moment ( ) . subtract ( 6 , "hours" ) ;
console . log ( ` Calculating water level between ${ sixHoursAgo . format ( "HH:mm A" ) } and ${ now . format ( "HH:mm A" ) } ` ) ;
const tanks = await Tank . find ( { } ) ;
for ( const tank of tanks ) {
const {
customerId ,
tankName ,
tankLocation ,
typeOfWater ,
capacity ,
waterlevel ,
waterlevel _at _midnight ,
} = tank ;
// ✅ Fix: Remove commas before parsing numbers
const tankCapacity = parseFloat ( capacity . replace ( /,/g , '' ) ) || 0 ;
const currentWaterLevel = parseFloat ( waterlevel . replace ( /,/g , '' ) ) || 0 ;
const midnightWaterLevel = parseFloat ( waterlevel _at _midnight . replace ( /,/g , '' ) ) || 0 ;
if ( tankCapacity === 0 ) {
console . log ( ` Skipping tank ${ tankName } due to zero capacity ` ) ;
continue ;
}
const currentWaterLevelPercentage = ( ( currentWaterLevel / tankCapacity ) * 100 ) . toFixed ( 2 ) ;
const waterUsedSinceMidnight = midnightWaterLevel - currentWaterLevel ;
const waterUsedPercentageSinceMidnight = ( ( waterUsedSinceMidnight / tankCapacity ) * 100 ) . toFixed ( 2 ) ;
const user = await User . findOne ( { customerId } ) ;
if ( ! user || ! user . fcmIds || user . fcmIds . length === 0 ) {
console . log ( ` No FCM tokens for customer: ${ customerId } ` ) ;
continue ;
}
let notificationBody =
` 🛢️ Tank Name: ${ tankName } \n ` +
` 🏢 Location: ${ tankLocation } \n ` +
` 💧 Type of Water: ${ typeOfWater } \n ` +
` Current Water Level: ${ currentWaterLevel } liters ( ${ currentWaterLevelPercentage } %) \n ` ;
await sendNotification ( user . fcmIds , "Water Level Update" , notificationBody ) ;
}
console . log ( "Water level notifications sent successfully." ) ;
} catch ( err ) {
console . error ( "Error in water level calculation:" , err ) ;
}
} ;
// Schedule notifications at 6 AM, 12 PM, 6 PM, and 12 AM
cron . schedule (
"0 6,12,18,0 * * *" , // Cron expression for the required times
async ( ) => {
console . log ( "Starting scheduled consumption notification task..." ) ;
//await calculateConsumptionAndNotify();
await calculateWaterLevelAndNotify ( ) ;
} ,
{
timezone : "Asia/Kolkata" , // Specify the timezone
}
) ;
// const updateStopTimeFormat = async () => {
// try {
// // Find records where stopTime is null or not in the required format
// const motorDataDocs = await MotorData.find();
// for (const doc of motorDataDocs) {
// // Parse and validate startTime
// const startTime = moment(doc.startTime, "DD-MMM-YYYY - HH:mm", true);
// if (!startTime.isValid()) {
// console.log(`Invalid startTime for record ID: ${doc._id}`);
// continue;
// }
// // Format startTime if it's not already formatted
// const formattedStartTime = startTime.format("DD-MMM-YYYY - HH:mm");
// // Check if stopTime is valid or calculate it
// let formattedStopTime = null;
// const stopTime = moment(doc.stopTime, "DD-MMM-YYYY - HH:mm", true);
// if (!stopTime.isValid()) {
// // Calculate stopTime by adding 30 minutes to startTime
// formattedStopTime = startTime.clone().add(30, "minutes").format("DD-MMM-YYYY - HH:mm");
// } else {
// // Format the existing stopTime
// formattedStopTime = stopTime.format("DD-MMM-YYYY - HH:mm");
// }
// // Update the document if startTime or stopTime is not correctly formatted
// if (doc.startTime !== formattedStartTime || doc.stopTime !== formattedStopTime) {
// await MotorData.updateOne(
// { _id: doc._id },
// {
// $set: {
// startTime: formattedStartTime,
// stopTime: formattedStopTime,
// },
// }
// );
// console.log(`Updated record ID: ${doc._id}`);
// }
// }
// console.log("StopTime format update completed.");
// } catch (err) {
// console.error("Error updating stopTime format:", err);
// }
// };
// // Call the function to update stopTime
// updateStopTimeFormat();
exports . updatetankstatus = async ( req , reply ) => {
try {
const { customerId } = req . params ;
const { tankName , tankLocation , status } = req . body ;
if ( ! [ "active" , "inactive" ] . includes ( status ) ) {
return reply . code ( 400 ) . send ( { message : "Invalid status value" } ) ;
}
// Find the main tank
const mainTank = await Tank . findOneAndUpdate (
{ customerId , tankName , tankLocation } ,
{ $set : { status } } ,
{ new : true }
) ;
if ( ! mainTank ) {
return reply . code ( 404 ) . send ( { message : "Tank not found" } ) ;
}
// Update status in related outputConnections tanks
await Tank . updateMany (
{
customerId ,
"connections.outputConnections.outputConnections" : tankName ,
} ,
{ $set : { "connections.outputConnections.$.status" : status } }
) ;
// Update status in related inputConnections tanks
await Tank . updateMany (
{
customerId ,
"connections.inputConnections.inputConnections" : tankName ,
} ,
{ $set : { "connections.inputConnections.$.status" : status } }
) ;
return reply . send ( { message : "Tank status updated successfully" } ) ;
} catch ( error ) {
console . error ( "Error updating tank status:" , error ) ;
return reply . code ( 500 ) . send ( { message : "Internal Server Error" } ) ;
}
} ;
exports . listofactiveandinactivetankstatus = async ( req , reply ) => {
try {
const { customerId } = req . params ;
const status = req . query . status . toLowerCase ( ) ;
if ( ! [ "active" , "inactive" ] . includes ( status ) ) {
return reply . code ( 400 ) . send ( { message : "Invalid status value" } ) ;
}
// Find tanks based on customerId and status
const tanks = await Tank . find ( { customerId , status } ) ;
return reply . send ( { tanks } ) ;
} catch ( error ) {
console . error ( "Error fetching tank list:" , error ) ;
return reply . code ( 500 ) . send ( { message : "Internal Server Error" } ) ;
}
} ;