You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							7622 lines
						
					
					
						
							286 KiB
						
					
					
				
			
		
		
	
	
							7622 lines
						
					
					
						
							286 KiB
						
					
					
				//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');
 | 
						|
EventEmitter.defaultMaxListeners = 50; // Increase listener limit
 | 
						|
 | 
						|
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"] } }),
 | 
						|
      });
 | 
						|
 | 
						|
      let filteredConsumptions;
 | 
						|
      if (start.getTime() === end.getTime()) {
 | 
						|
        // If start and end are the same, filter for exact match
 | 
						|
        filteredConsumptions = tankConsumptions.filter((record) => {
 | 
						|
          return moment(record.time, "DD-MMM-YYYY - HH:mm").toDate().getTime() === start.getTime();
 | 
						|
        });
 | 
						|
      } else {
 | 
						|
        // Normal range filter
 | 
						|
        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);
 | 
						|
 | 
						|
      let consumption;
 | 
						|
 | 
						|
const isSameTime = start.getTime() === end.getTime();
 | 
						|
const isToday = moment(start).isSame(moment(), 'day');
 | 
						|
 | 
						|
if (isSameTime && !isToday) {
 | 
						|
  // Same date & time and NOT today => use only records
 | 
						|
  consumption = total_consumption_from_records;
 | 
						|
} else {
 | 
						|
  // Normal case => use full calculation
 | 
						|
  consumption = (waterlevel_at_midnight + total_water_added_from_midnight) - waterlevel + total_consumption_from_records;
 | 
						|
}
 | 
						|
     
 | 
						|
      // Add to the total consumption and capacities based on water type
 | 
						|
      if (tank.typeOfWater === "bore" || tank.typeOfWater === "Bore Water") {
 | 
						|
        totalBoreConsumptionForSelectedBlockAndTypeOfWater += consumption;
 | 
						|
        totalConsumptionForSelectedBlockAndTypeOfWater += consumption
 | 
						|
        totalBoreCapacityForSelectedBlockAndTypeOfWater += capacity;
 | 
						|
      } else if (tank.typeOfWater === "drinking" || tank.typeOfWater === "Drinking Water") {
 | 
						|
        totalDrinkingConsumptionForSelectedBlockAndTypeOfWater += consumption;
 | 
						|
        totalConsumptionForSelectedBlockAndTypeOfWater += 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 all 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 })
 | 
						|
      });
 | 
						|
 | 
						|
      let filteredConsumptions;
 | 
						|
      if (start.getTime() === end.getTime()) {
 | 
						|
        // If start and end are the same, filter for exact match
 | 
						|
        filteredConsumptions = tankConsumptions.filter((record) => {
 | 
						|
          return moment(record.time, "DD-MMM-YYYY - HH:mm").toDate().getTime() === start.getTime();
 | 
						|
        });
 | 
						|
      } else {
 | 
						|
        // Normal range filter
 | 
						|
        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}`;
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
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),
 | 
						|
});
 | 
						|
 | 
						|
 | 
						|
eventEmitter.on(
 | 
						|
  "motorStart",
 | 
						|
  async (customerId, fcmTokens, tankName, blockName, startTime, motorOnType, manual_threshold_time, typeOfWater, hw_Id, phoneNumber) => {
 | 
						|
    try {
 | 
						|
      console.log("Motor Start Event Triggered for:", customerId);
 | 
						|
 | 
						|
      // Fetch user or staff based on customerId
 | 
						|
      const user = await User.findOne({ customerId });
 | 
						|
 | 
						|
      if (!user) {
 | 
						|
        console.log(`No user found for customerId: ${customerId}`);
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      // Identify who started the motor
 | 
						|
      let startedBy = "Unknown"; // Default value
 | 
						|
 | 
						|
      if (user.phone === phoneNumber) {
 | 
						|
        startedBy = user.username; // Customer's name
 | 
						|
      } else {
 | 
						|
        const staffMember = user.staff.staff.find(staff => staff.phone === phoneNumber);
 | 
						|
        if (staffMember) {
 | 
						|
          startedBy = staffMember.name; // Staff's name
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (startedBy === "Unknown") {
 | 
						|
        console.log("User not found. Cannot proceed with motorStart event.");
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      const startMethod = motorOnType === "Mobile APP" ? "Mobile APP" : "Manual";
 | 
						|
      const motorName = `${tankName}-${blockName}-${typeOfWater}`;
 | 
						|
 | 
						|
      const message =
 | 
						|
        `🚰 Motor Name: ${motorName}\n` +
 | 
						|
        `🚰 Tank Name: '${tankName}'\n` +
 | 
						|
        `🏢 Block Name: '${blockName}'\n` +
 | 
						|
        `👤 Started by: ${startedBy}\n` +  // Only name is displayed
 | 
						|
        `📱 Mode: '${startMethod}'\n` +
 | 
						|
        `🕒 Pump started at: ${startTime} \n` +
 | 
						|
        `Will stop after: '${manual_threshold_time}' mins`;
 | 
						|
 | 
						|
      await sendNotification(hw_Id, customerId, fcmTokens, "ARMINTA : MOTOR STARTED", message);
 | 
						|
    } catch (error) {
 | 
						|
      console.error("Error in motorStart event:", error);
 | 
						|
    }
 | 
						|
  }
 | 
						|
);
 | 
						|
 | 
						|
eventEmitter.on(
 | 
						|
  "motorStop",
 | 
						|
  async (
 | 
						|
    customerId,
 | 
						|
    fcmTokens,
 | 
						|
    tankName,
 | 
						|
    blockName,
 | 
						|
    stopTime,
 | 
						|
    motorOnType,
 | 
						|
    totalWaterPumped,
 | 
						|
    typeOfWater,
 | 
						|
    hw_Id,
 | 
						|
    phoneNumber
 | 
						|
  ) => {
 | 
						|
    try {
 | 
						|
      console.log("Motor Stop Event Triggered for:", customerId);
 | 
						|
 | 
						|
      // Fetch user or staff based on customerId
 | 
						|
      const user = await User.findOne({ customerId });
 | 
						|
 | 
						|
      if (!user) {
 | 
						|
        console.log(`No user found for customerId: ${customerId}`);
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      // Identify who stopped the motor
 | 
						|
      let stoppedBy = "Unknown"; // Default value
 | 
						|
 | 
						|
      if (user.phone === phoneNumber) {
 | 
						|
        stoppedBy = user.username; // Customer's name
 | 
						|
      } else if (user.staff && user.staff.staff) {
 | 
						|
        const staffMember = user.staff.staff.find((staff) => staff.phone === phoneNumber);
 | 
						|
        if (staffMember) {
 | 
						|
          stoppedBy = staffMember.name; // Staff's name
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (stoppedBy === "Unknown") {
 | 
						|
        console.log("User not found. Cannot proceed with motorStop event.");
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      const stopMethod = motorOnType === "Mobile APP" ? "Mobile APP" : "Manual";
 | 
						|
      const motorName = `${tankName}-${blockName}-${typeOfWater}`;
 | 
						|
 | 
						|
      const message =
 | 
						|
        `🚰 Motor Name: ${motorName}\n` +
 | 
						|
        `🛢️ Tank Name: '${tankName}'\n` +
 | 
						|
        `🏢 Block Name: '${blockName}'\n` +
 | 
						|
        `👤 Stopped by: ${stoppedBy}\n` + // Only name is displayed
 | 
						|
        `📱 Mode: '${stopMethod}'\n` +
 | 
						|
        `🕒 Pump stopped at: ${stopTime}\n` +
 | 
						|
        `💧 Total water pumped: ${totalWaterPumped} liters\n`;
 | 
						|
 | 
						|
      await sendNotification(hw_Id, customerId, fcmTokens, "ARMINTA : MOTOR STOPPED", 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('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 (customerId, fcmTokens, thresholdTime, hw_Id, tankName, blockName) => {
 | 
						|
  try {
 | 
						|
    const message = 
 | 
						|
    `🛢️ Tank Name: '${tankName}'\n` +
 | 
						|
    `🏢 Block Name: '${blockName}'\n` +
 | 
						|
    `Motor Stopped as it completed ${thresholdTime} minutes.`;
 | 
						|
    await sendNotification(hw_Id, customerId, fcmTokens, 'Motor Alert', message);
 | 
						|
    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 (hw_Id, fcmTokens, waterLevel, blockName, tankName, motorOnType, stopCriteria, typeOfWater, manualThresholdTime) => {
 | 
						|
//     try {
 | 
						|
//       const formattedTime = new Date().toLocaleTimeString("en-IN", { timeZone: "Asia/Kolkata" });
 | 
						|
 | 
						|
//       if (motorOnType !== "forced_manual") {
 | 
						|
//         console.log(`Skipping notification: Motor was started in ${motorOnType} mode.`);
 | 
						|
//         return;
 | 
						|
//       }
 | 
						|
 | 
						|
//       const stopConditionMessage = stopCriteria === "manual"
 | 
						|
//         ? `⚠️ Pump will stop **manually**.`
 | 
						|
//         : `🚨 Pump will stop when the water level reaches **${manualThresholdTime}%**.`;
 | 
						|
 | 
						|
//       const message = `🚰 **Motor Started** 🚀\n` +
 | 
						|
//         `🔹 **Motor Name:** ${tankName}-${blockName}-${typeOfWater}\n` +
 | 
						|
//         `🏢 **Block Name:** ${blockName}\n` +
 | 
						|
//         `💧 **Water Level:** ${waterLevel}%\n` +
 | 
						|
//         `📱 **Mode:** Physically Started\n` +
 | 
						|
//         `🕒 **Pump started at:** ${formattedTime}\n` +
 | 
						|
//         stopConditionMessage;
 | 
						|
 | 
						|
//       await sendNotification(hw_Id, fcmTokens, "Motor Started 🚀", message);
 | 
						|
//       console.log(`✅ Motor start notification sent for Motor ID: ${hw_Id}`);
 | 
						|
 | 
						|
//     } catch (error) {
 | 
						|
//       console.error(`❌ Error in sendMotorStartNotification for Motor ID: ${hw_Id}`, 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 (hw_Id, fcmTokens, waterLevel, blockName, tankName, motorOnType, typeOfWater) => {
 | 
						|
//     try {
 | 
						|
//       const formattedTime = new Date().toLocaleTimeString("en-IN", { timeZone: "Asia/Kolkata" });
 | 
						|
 | 
						|
//       const message = `⏹️ **Motor Stopped** 🛑\n` +
 | 
						|
//         `🔹 **Motor Name:** ${tankName}-${blockName}-${typeOfWater}\n` +
 | 
						|
//         `🏢 **Block Name:** ${blockName}\n` +
 | 
						|
//         `💧 **Water Level:** ${waterLevel}%\n` +
 | 
						|
//         `📱 **Mode:** Forced Manual\n` +
 | 
						|
//         `🕒 **Pump stopped at:** ${formattedTime}`;
 | 
						|
 | 
						|
//       await sendNotification(hw_Id, fcmTokens, "Motor Stopped 🛑", message);
 | 
						|
//       console.log(`✅ Motor stop notification sent for Motor ID: ${hw_Id}`);
 | 
						|
 | 
						|
//     } catch (error) {
 | 
						|
//       console.error(`❌ Error in sendMotorStopNotification for Motor ID: ${hw_Id}`, error);
 | 
						|
//     }
 | 
						|
//   }
 | 
						|
// );
 | 
						|
 | 
						|
// 🚀 Motor Start Notification
 | 
						|
 | 
						|
eventEmitter.on("sendMotorStartNotification", async (hw_Id, customerId, fcmTokens, waterLevel, blockName, tankName, motorOnType, manualThresholdTime) => {
 | 
						|
  try {
 | 
						|
      console.log(`✅ Received sendMotorStartNotification event for ${customerId}`);
 | 
						|
      
 | 
						|
      const formattedTime = new Date().toLocaleTimeString("en-IN", { timeZone: "Asia/Kolkata" });
 | 
						|
 | 
						|
      const normalizedMotorOnType = motorOnType.toLowerCase();
 | 
						|
      if (normalizedMotorOnType !== "forced_manual") {
 | 
						|
          console.log(`⚠️ Skipping notification: Motor started in **${motorOnType}** mode.`);
 | 
						|
          return;
 | 
						|
      }
 | 
						|
 | 
						|
      if (!Array.isArray(fcmTokens) || fcmTokens.length === 0) {
 | 
						|
          console.warn(`⚠️ No valid FCM tokens found for Customer ID: ${customerId}`);
 | 
						|
          return;
 | 
						|
      }
 | 
						|
 | 
						|
      // const stopConditionMessage = stopCriteria === "level"
 | 
						|
      //     ? `🚨 Pump will stop when the water level reaches **${manualThresholdTime}%**.`
 | 
						|
      //     : `⚠️ Pump will stop **manually**.`;
 | 
						|
 | 
						|
      const message = `🚰 Motor Started 🚀\n` +
 | 
						|
          `👤 Customer ID: ${customerId}\n` +
 | 
						|
          `🔹 Motor Name: ${tankName} - ${blockName}\n` +
 | 
						|
          `💧 Water Level: ${waterLevel}\n` +
 | 
						|
          `📱 Mode: Manually Started\n` +
 | 
						|
          `🕒 Pump started at: ${formattedTime}\n`;
 | 
						|
 | 
						|
      await sendNotification(hw_Id, customerId, fcmTokens, "Motor Started 🚀", message);
 | 
						|
      console.log(`✅ Motor start notification sent for Customer ID: ${customerId}`);
 | 
						|
  } catch (error) {
 | 
						|
      console.error(`❌ Error in sendMotorStartNotification for Customer ID: ${customerId}`, error);
 | 
						|
  }
 | 
						|
});
 | 
						|
 | 
						|
eventEmitter.on("sendMotorStopNotification", async (hw_Id, customerId, fcmTokens, waterLevel, blockName, tankName, motorOnType) => {
 | 
						|
  try {
 | 
						|
      console.log(`✅ Received sendMotorStopNotification event for ${customerId}`);
 | 
						|
 | 
						|
      const formattedTime = new Date().toLocaleTimeString("en-IN", { timeZone: "Asia/Kolkata" });
 | 
						|
 | 
						|
      const normalizedMotorOnType = motorOnType.toLowerCase();
 | 
						|
      if (normalizedMotorOnType !== "forced_manual") {
 | 
						|
          console.log(`⚠️ Skipping notification: Motor stopped in **${motorOnType}** mode.`);
 | 
						|
          return;
 | 
						|
      }
 | 
						|
 | 
						|
      if (!Array.isArray(fcmTokens) || fcmTokens.length === 0) {
 | 
						|
          console.warn(`⚠️ No valid FCM tokens found for Customer ID: ${customerId}`);
 | 
						|
          return;
 | 
						|
      }
 | 
						|
 | 
						|
      const message = `🛑 Motor Stopped ❌\n` +
 | 
						|
          `👤 Customer ID: ${customerId}\n` +
 | 
						|
          `🔹 Motor Name: ${tankName} - ${blockName}\n` +
 | 
						|
          `💧 Water Level: ${waterLevel}\n` +
 | 
						|
          `📱 Mode: Manually Stopped\n` +
 | 
						|
          `🕒 Pump stopped at: ${formattedTime}`;
 | 
						|
 | 
						|
      await sendNotification(hw_Id, customerId, fcmTokens, "Motor Stopped ❌", message);
 | 
						|
      console.log(`✅ Motor stop notification sent for Customer ID: ${customerId}`);
 | 
						|
  } catch (error) {
 | 
						|
      console.error(`❌ Error in sendMotorStopNotification for Customer ID: ${customerId}`, error);
 | 
						|
  }
 | 
						|
});
 | 
						|
 | 
						|
eventEmitter.on('sendLowWaterNotification', async (customerId, fcmTokens, hw_Id, tankName, blockName, lowWaterLevel, currentWaterLevel, currentWaterPercentage) => {
 | 
						|
  try {
 | 
						|
    const message = 
 | 
						|
    `⚠️ Warning: Low water level detected!\n` +
 | 
						|
    `🛢️ Tank Name: '${tankName}'\n` +
 | 
						|
    `🏢 Block Name: '${blockName}'\n` +
 | 
						|
    `📉 Low Water Threshold: '${lowWaterLevel} liters'\n` +
 | 
						|
    `📌 Current Water Level: '${currentWaterLevel} liters'\n` +
 | 
						|
    `📅 Date & Time: '${new Date().toLocaleString()}'`;
 | 
						|
 | 
						|
    await sendNotification(hw_Id, customerId, fcmTokens, 'Low Water Alert', message);
 | 
						|
    console.log("✅ Low water notification sent successfully.");
 | 
						|
  } catch (error) {
 | 
						|
    console.error("❌ Error sending low water notification:", error);
 | 
						|
  }
 | 
						|
});
 | 
						|
 | 
						|
eventEmitter.on('sendCriticalLowWaterNotification', async (customerId, fcmTokens, hw_Id, tankName, blockName, criticalLowWaterLevel, currentWaterLevel, currentWaterPercentage) => {
 | 
						|
  try {
 | 
						|
    const message = 
 | 
						|
    `🚨 Critical Alert: Water level is **critically low!**\n` +
 | 
						|
    `🛢️ Tank Name: '${tankName}'\n` +
 | 
						|
    `🏢 Block Name: '${blockName}'\n` +
 | 
						|
    `🔴 Critical Low Threshold: '${criticalLowWaterLevel} liters'\n` +
 | 
						|
    `📌 Current Water Level: '${currentWaterLevel} liters'\n` +
 | 
						|
    `📅 Date & Time: '${new Date().toLocaleString()}'`;
 | 
						|
 | 
						|
    await sendNotification(hw_Id, customerId, fcmTokens, 'Critical Water Alert', message);
 | 
						|
    console.log("✅ Critical low water notification sent successfully.");
 | 
						|
  } catch (error) {
 | 
						|
    console.error("❌ Error sending critical low water notification:", 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': 'tank_levels',  
 | 
						|
//           },
 | 
						|
//         });
 | 
						|
//         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 sendNotification = async (customerId, fcmIds, title, body) => {
 | 
						|
//   try {
 | 
						|
//     if (!customerId) {
 | 
						|
//       throw new Error("Customer ID is required.");
 | 
						|
//     }
 | 
						|
 | 
						|
//     if (!Array.isArray(fcmIds) || fcmIds.length === 0) {
 | 
						|
//       throw new Error("No FCM tokens provided or invalid format.");
 | 
						|
//     }
 | 
						|
 | 
						|
//     // Safely flatten the tokens
 | 
						|
//     const flatTokens = fcmIds.flat ? fcmIds.flat() : fcmIds; // Use flat() if available
 | 
						|
//     if (flatTokens.length === 0) {
 | 
						|
//       throw new Error("Flattened FCM token list is empty.");
 | 
						|
//     }
 | 
						|
 | 
						|
//     // Fetch user notification settings
 | 
						|
//     const users = await User.find({ customerId }).select("fcmIds notificationPreference lastNotificationSent");
 | 
						|
 | 
						|
//     // Iterate over users to send notifications based on their preferences
 | 
						|
//     const promises = users.map(async (user) => {
 | 
						|
//       const { fcmIds: userFcmIds, notificationPreference, lastNotificationSent } = user;
 | 
						|
 | 
						|
//       // Check if userFcmIds is an array
 | 
						|
//       if (!Array.isArray(userFcmIds)) {
 | 
						|
//         console.log(`Invalid fcmIds for customer ID: ${customerId}`);
 | 
						|
//         return;
 | 
						|
//       }
 | 
						|
 | 
						|
//       // Filter tokens that belong to the user
 | 
						|
//       const validTokens = flatTokens.filter(token => userFcmIds.includes(token));
 | 
						|
 | 
						|
//       if (validTokens.length === 0) {
 | 
						|
//         console.log(`No matching FCM tokens for customer ID: ${customerId}`);
 | 
						|
//         return;
 | 
						|
//       }
 | 
						|
 | 
						|
//       // // Handle notification preference
 | 
						|
//       // if (notificationPreference === "never") {
 | 
						|
//       //   console.log(`Notifications disabled for customer ID: ${customerId}`);
 | 
						|
//       //   return;
 | 
						|
//       // }
 | 
						|
 | 
						|
//       const now = new Date();
 | 
						|
//       const lastSent = new Date(lastNotificationSent || 0);
 | 
						|
 | 
						|
//      // If preference is not "always", check the timing
 | 
						|
//       // if (notificationPreference !== "always") {
 | 
						|
//       //   let minInterval = 0;
 | 
						|
 | 
						|
//       //   switch (notificationPreference) {
 | 
						|
//       //     case "6_hours":
 | 
						|
//       //       minInterval = 6 * 60 * 60 * 1000; // 6 hours
 | 
						|
//       //       break;
 | 
						|
//       //     case "8_hours":
 | 
						|
//       //       minInterval = 8 * 60 * 60 * 1000; // 8 hours
 | 
						|
//       //       break;
 | 
						|
//       //     case "1_month":
 | 
						|
//       //       minInterval = 30 * 24 * 60 * 60 * 1000; // 1 month
 | 
						|
//       //       break;
 | 
						|
//       //   }
 | 
						|
 | 
						|
//       //   // Skip sending if the time restriction hasn't passed
 | 
						|
//       //   if (now - lastSent < minInterval) {
 | 
						|
//       //     console.log(`Skipping notification for customer ID: ${customerId} due to time restriction.`);
 | 
						|
//       //     return;
 | 
						|
//       //   }
 | 
						|
//       // }
 | 
						|
 | 
						|
//       // Send notifications
 | 
						|
//       const notificationPromises = flatTokens.map(async (token) => {
 | 
						|
//         try {
 | 
						|
//           const response = await admin.messaging().send({
 | 
						|
//             notification: { title, body },
 | 
						|
//             token,
 | 
						|
//             data: { target: "/tank_levels" },
 | 
						|
//           });
 | 
						|
 | 
						|
//           console.log(`Notification sent successfully to token: ${token}`);
 | 
						|
//           console.log("FCM Response:", response); // Log the full response
 | 
						|
//           console.log(`Title: ${title}, Body: ${body}`); // Log title and body before sending
 | 
						|
 | 
						|
 | 
						|
//         } catch (error) {
 | 
						|
//           console.error(`Failed to send notification to token: ${token}`, error);
 | 
						|
 | 
						|
//           // Handle token errors
 | 
						|
//           if (error.code === "messaging/registration-token-not-registered") {
 | 
						|
//             await User.updateOne(
 | 
						|
//               { customerId },
 | 
						|
//               { $pull: { fcmIds: token } } // Remove invalid token
 | 
						|
//             );
 | 
						|
//             console.log(`Removed invalid token: ${token}`);
 | 
						|
//           }
 | 
						|
//         }
 | 
						|
//       });
 | 
						|
 | 
						|
//       await Promise.all(notificationPromises);
 | 
						|
 | 
						|
//       // Update lastNotificationSent timestamp if not "always"
 | 
						|
//       if (notificationPreference !== "always") {
 | 
						|
//         await User.updateOne({ customerId }, { lastNotificationSent: now });
 | 
						|
//       }
 | 
						|
//     });
 | 
						|
 | 
						|
//     await Promise.all(promises);
 | 
						|
 | 
						|
//   } catch (error) {
 | 
						|
//     console.error("Error sending notifications:", error);
 | 
						|
//   }
 | 
						|
// };
 | 
						|
 | 
						|
// important
 | 
						|
// const sendNotification = async (customerId, fcmIds, title, body) => {
 | 
						|
//   try {
 | 
						|
//     if (!customerId) {
 | 
						|
//       throw new Error("Customer ID is required.");
 | 
						|
//     }
 | 
						|
 | 
						|
//     if (!Array.isArray(fcmIds) || fcmIds.length === 0) {
 | 
						|
//       console.log("No valid FCM tokens provided.");
 | 
						|
//       return;
 | 
						|
//     }
 | 
						|
 | 
						|
//     // Flatten nested arrays
 | 
						|
//     const flatFcmIds = fcmIds.flat();
 | 
						|
 | 
						|
//     // Fetch user from database
 | 
						|
//     const user = await User.findOne({ customerId }).select("fcmIds");
 | 
						|
//     if (!user || !Array.isArray(user.fcmIds)) {
 | 
						|
//       console.log(`No valid FCM tokens found for customer ID: ${customerId}`);
 | 
						|
//       return;
 | 
						|
//     }
 | 
						|
 | 
						|
//     console.log("User's stored FCM tokens:", user.fcmIds);
 | 
						|
//     console.log("FCM tokens passed to function:", flatFcmIds);
 | 
						|
 | 
						|
//     // Proper token filtering
 | 
						|
//     const validTokens = user.fcmIds.filter(token => flatFcmIds.some(t => t.trim() === token.trim()));
 | 
						|
 | 
						|
//     console.log("Valid tokens for notification:", validTokens);
 | 
						|
 | 
						|
//     if (validTokens.length === 0) {
 | 
						|
//       console.log(`No matching FCM tokens for customer ID: ${customerId}`);
 | 
						|
//       return;
 | 
						|
//     }
 | 
						|
 | 
						|
//     const promises = validTokens.map(async (token) => {
 | 
						|
//       try {
 | 
						|
//         console.log(`Sending notification to token: ${token}`);
 | 
						|
 | 
						|
//         const response = await admin.messaging().send({
 | 
						|
//           notification: { title, body },
 | 
						|
//           token,
 | 
						|
//           data: { target: "/tank_levels" },
 | 
						|
//         });
 | 
						|
 | 
						|
//         console.log(`Notification sent successfully:`, response);
 | 
						|
//         console.log(`title:`, title);
 | 
						|
//         console.log(`body:`, body);
 | 
						|
 | 
						|
 | 
						|
//       } catch (error) {
 | 
						|
//         console.error(`Failed to send notification to token: ${token}`, error);
 | 
						|
        
 | 
						|
//         if (error?.errorInfo?.code === "messaging/registration-token-not-registered") {
 | 
						|
//           await User.updateOne({ customerId }, { $pull: { fcmIds: token } });
 | 
						|
//           console.log(`Removed invalid token: ${token}`);
 | 
						|
//         }
 | 
						|
//       }
 | 
						|
//     });
 | 
						|
 | 
						|
//     await Promise.all(promises);
 | 
						|
//   } catch (error) {
 | 
						|
//     console.error("Error sending notifications:", error);
 | 
						|
//   }
 | 
						|
// };
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
const sendNotification = async (hw_Id, customerId, fcmIds, title, body) => {
 | 
						|
  try {
 | 
						|
    if (!customerId) throw new Error("Customer ID is required.");
 | 
						|
    if (!Array.isArray(fcmIds) || fcmIds.length === 0) {
 | 
						|
      throw new Error("No FCM tokens provided or invalid format.");
 | 
						|
    }
 | 
						|
 | 
						|
    const flatTokens = fcmIds.flat ? fcmIds.flat() : fcmIds;
 | 
						|
    if (flatTokens.length === 0) throw new Error("Flattened FCM token list is empty.");
 | 
						|
 | 
						|
    console.log(`📨 Preparing to send notification to Customer ID: ${customerId}`);
 | 
						|
    
 | 
						|
    // Fetch users with FCM tokens & preferences
 | 
						|
    const users = await User.find({ customerId }).select("fcmIds notificationPreference lastNotificationSent");
 | 
						|
    
 | 
						|
    const promises = users.map(async (user) => {
 | 
						|
      const { fcmIds: userFcmIds, notificationPreference, lastNotificationSent } = user;
 | 
						|
      if (!Array.isArray(userFcmIds)) return console.log(`⚠️ Invalid fcmIds for customer ID: ${customerId}`);
 | 
						|
 | 
						|
      const validTokens = flatTokens.filter(token => userFcmIds.includes(token));
 | 
						|
      if (validTokens.length === 0) return console.log(`⚠️ No matching FCM tokens for customer ID: ${customerId}`);
 | 
						|
 | 
						|
      // Handle notification preferences
 | 
						|
      if (notificationPreference === "never") return console.log(`🔕 Notifications disabled for Customer ID: ${customerId}`);
 | 
						|
 | 
						|
      const now = new Date();
 | 
						|
      const lastSent = new Date(lastNotificationSent || 0);
 | 
						|
      let minInterval = 0;
 | 
						|
 | 
						|
      switch (notificationPreference) {
 | 
						|
        case "6_hours":
 | 
						|
          minInterval = 6 * 60 * 60 * 1000;
 | 
						|
          break;
 | 
						|
        case "8_hours":
 | 
						|
          minInterval = 8 * 60 * 60 * 1000;
 | 
						|
          break;
 | 
						|
        case "1_month":
 | 
						|
          minInterval = 30 * 24 * 60 * 60 * 1000;
 | 
						|
          break;
 | 
						|
      }
 | 
						|
 | 
						|
      if (notificationPreference !== "always" && now - lastSent < minInterval) {
 | 
						|
        return console.log(`⏳ Skipping notification for Customer ID: ${customerId} due to preference (${notificationPreference}).`);
 | 
						|
      }
 | 
						|
 | 
						|
      console.log(`🚀 Sending notification to Customer ID: ${customerId}, Tokens: ${validTokens.length}`);
 | 
						|
 | 
						|
      const notificationPromises = validTokens.map(async (token) => {
 | 
						|
        try {
 | 
						|
          const response = await admin.messaging().send({
 | 
						|
            token,
 | 
						|
            notification: { title, body },
 | 
						|
            data: { 
 | 
						|
              hw_Id: String(hw_Id),  
 | 
						|
              target: "/tank_levels"
 | 
						|
            },
 | 
						|
          });
 | 
						|
 | 
						|
          console.log(`✅ Notification sent successfully to token: ${token}`);
 | 
						|
          console.log("📬 FCM Response:", response);
 | 
						|
          console.log(`📡 Sending notification to Customer ID: ${customerId}`);
 | 
						|
          //console.log(`🔍 FCM Tokens:`, fcmTokens);
 | 
						|
 | 
						|
 | 
						|
        } catch (error) {
 | 
						|
         // console.error(`❌ Failed to send notification to token: ${token}`, error);
 | 
						|
 | 
						|
          if (error.code === "messaging/registration-token-not-registered") {
 | 
						|
            await User.updateOne({ customerId }, { $pull: { fcmIds: token } });
 | 
						|
            console.log(`🗑️ Removed invalid token: ${token}`);
 | 
						|
          }
 | 
						|
        }
 | 
						|
      });
 | 
						|
 | 
						|
      await Promise.all(notificationPromises);
 | 
						|
 | 
						|
      if (notificationPreference !== "always") {
 | 
						|
        await User.updateOne({ customerId }, { $set: { lastNotificationSent: now } });
 | 
						|
      }
 | 
						|
    });
 | 
						|
 | 
						|
    await Promise.all(promises);
 | 
						|
 | 
						|
  } catch (error) {
 | 
						|
    console.error("❌ Error sending notifications:", error);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// Function to send notifications
 | 
						|
const sendDailyConsumptionNotification = async () => {
 | 
						|
  try {
 | 
						|
    const now = new Date();
 | 
						|
    const currentTime = moment(now).format("HH:mm"); // e.g., "09:30"
 | 
						|
    const currentDate = moment(now).format("DD-MMM-YYYY"); // e.g., "28-Feb-2025"
 | 
						|
 | 
						|
    console.log(`🕒 Checking users for scheduled notifications at ${currentTime}`);
 | 
						|
 | 
						|
    // Fetch unique users who have enabled notifications for the current time
 | 
						|
    const users = await User.find({
 | 
						|
      allowNotifications: true,
 | 
						|
      notificationTime: currentTime,
 | 
						|
    }).select("customerId fcmIds lastNotificationSent").lean();
 | 
						|
 | 
						|
    // Ensure unique customers only
 | 
						|
    const uniqueUsers = users.filter((user, index, self) =>
 | 
						|
      index === self.findIndex((u) => u.customerId === user.customerId)
 | 
						|
    );
 | 
						|
 | 
						|
    if (uniqueUsers.length === 0) {
 | 
						|
      console.log("⏳ No users have notifications scheduled for this time.");
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    for (const user of uniqueUsers) {
 | 
						|
      const { customerId, fcmIds, lastNotificationSent } = user;
 | 
						|
 | 
						|
      // Ensure user has valid FCM tokens
 | 
						|
      if (!Array.isArray(fcmIds) || fcmIds.length === 0) {
 | 
						|
        console.log(`⚠️ No valid FCM tokens for customer ID: ${customerId}`);
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      // Remove duplicate and trim tokens
 | 
						|
      const uniqueTokens = [...new Set(fcmIds.map(token => token.trim()))];
 | 
						|
 | 
						|
      // Check if notification should be sent based on lastNotificationSent
 | 
						|
      const lastSent = new Date(lastNotificationSent || 0);
 | 
						|
      if (now - lastSent < 24 * 60 * 60 * 1000) {
 | 
						|
        console.log(`⏳ Skipping notification for ${customerId}, already sent in the last 24 hours.`);
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      // Fetch last 24-hour consumption data
 | 
						|
      const startTime = moment(now).subtract(1, "days").format("DD-MMM-YYYY - HH:mm");
 | 
						|
      const endTime = moment(now).format("DD-MMM-YYYY - HH:mm");
 | 
						|
 | 
						|
      console.log(`📅 Fetching consumption for ${customerId} from ${startTime} to ${endTime}`);
 | 
						|
 | 
						|
      const consumptions = await TankConsumptionOriginalSchema.find({
 | 
						|
        customerId,
 | 
						|
        time: { $gte: startTime, $lt: endTime },
 | 
						|
      });
 | 
						|
 | 
						|
      if (consumptions.length === 0) {
 | 
						|
        console.log(`❌ No consumption data found for ${customerId}`);
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      // Standardized mapping for water types
 | 
						|
      const typeMapping = {
 | 
						|
        "bore water": "Bore Water",
 | 
						|
        "bore": "Bore Water",
 | 
						|
        "drinking": "Drinking Water",
 | 
						|
        "drink": "Drinking Water",
 | 
						|
        "DRINK": "Drinking Water"
 | 
						|
      };
 | 
						|
 | 
						|
      // Calculate consumption per water type
 | 
						|
      let totalConsumption = 0;
 | 
						|
      let consumptionByType = {};
 | 
						|
 | 
						|
      for (const record of consumptions) {
 | 
						|
        let { typeofwater, consumption } = record;
 | 
						|
        typeofwater = (typeofwater || "").trim().toLowerCase(); // Normalize case
 | 
						|
        const standardType = typeMapping[typeofwater] || typeofwater; // Use mapped name or original
 | 
						|
 | 
						|
        const consumptionValue = parseInt(consumption, 10) || 0;
 | 
						|
        if (!consumptionByType[standardType]) {
 | 
						|
          consumptionByType[standardType] = 0;
 | 
						|
        }
 | 
						|
 | 
						|
        consumptionByType[standardType] += consumptionValue;
 | 
						|
        totalConsumption += consumptionValue;
 | 
						|
      }
 | 
						|
 | 
						|
      // Prepare notification message
 | 
						|
      let notificationBody = `🚰 Water Consumption Report for ${currentDate}:\n`;
 | 
						|
 | 
						|
      for (const type in consumptionByType) {
 | 
						|
        const percentage = totalConsumption ? ((consumptionByType[type] / totalConsumption) * 100).toFixed(2) : 0;
 | 
						|
        notificationBody += `\n💧 Type: ${type}\n` +
 | 
						|
                            `Total Consumption: ${consumptionByType[type]} liters (${percentage}%)\n`;
 | 
						|
      }
 | 
						|
 | 
						|
      console.log(`📩 Preparing notification for ${customerId}:`, notificationBody);
 | 
						|
 | 
						|
      // Update lastNotificationSent before sending
 | 
						|
      await User.updateOne(
 | 
						|
        { customerId },
 | 
						|
        { $set: { lastNotificationSent: new Date() } }
 | 
						|
      );
 | 
						|
 | 
						|
      // Send notification to FCM tokens
 | 
						|
      const notificationPromises = uniqueTokens.map(async (token) => {
 | 
						|
        try {
 | 
						|
          await admin.messaging().send({
 | 
						|
            notification: { title: "Daily Water Consumption Report", body: notificationBody },
 | 
						|
            token,
 | 
						|
            data: { target: "/tank_levels" },
 | 
						|
          });
 | 
						|
 | 
						|
          console.log(`✅ Notification sent to token: ${token}`);
 | 
						|
        } catch (error) {
 | 
						|
          console.error(`❌ Failed to send notification to token: ${token}`, error);
 | 
						|
 | 
						|
          if (error.code === "messaging/registration-token-not-registered") {
 | 
						|
            await User.updateOne({ customerId }, { $pull: { fcmIds: token } });
 | 
						|
            console.log(`🚫 Removed invalid token: ${token}`);
 | 
						|
          }
 | 
						|
        }
 | 
						|
      });
 | 
						|
 | 
						|
      await Promise.all(notificationPromises);
 | 
						|
    }
 | 
						|
  } catch (error) {
 | 
						|
    console.error("❌ Error sending daily consumption notifications:", error);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
cron.schedule("* * * * *", async () => {
 | 
						|
  console.log("🔄 Running daily consumption notification check...");
 | 
						|
  await sendDailyConsumptionNotification();
 | 
						|
}, {
 | 
						|
  timezone: "Asia/Kolkata",
 | 
						|
});
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// 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) => {
 | 
						|
 // console.log("entered publish",motor_id,motor_stop_status)
 | 
						|
  const deviceTopic = `water/operation/${motor_id}`; // Target specific IoT
 | 
						|
  //console.log(deviceTopic,"deviceTopic")
 | 
						|
  const payload = {
 | 
						|
    topic: 'operation',
 | 
						|
    object: {
 | 
						|
      'motor-id': motor_id,
 | 
						|
      control: motor_stop_status
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  //console.log(`📡 Publishing to ${deviceTopic}`);
 | 
						|
  console.log(payload);
 | 
						|
 | 
						|
  // Publish to the specific device's control topic
 | 
						|
  client.publish(deviceTopic, 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
 | 
						|
 | 
						|
 | 
						|
 | 
						|
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 = ["All",username, ...staffNames, "manual","user"];
 | 
						|
    
 | 
						|
    const updatedmotorIds = ["All",...motorIds];
 | 
						|
 | 
						|
 | 
						|
    // Prepare response
 | 
						|
    const result = {
 | 
						|
      motorIds: updatedmotorIds,
 | 
						|
      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 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;
 | 
						|
    const { action, motor_id: motorId, start_instance_id, phone, threshold_type, manual_threshold_time, manual_threshold_litres } = req.body;
 | 
						|
    
 | 
						|
    if (!motorId) throw new Error("Motor ID is required.");
 | 
						|
 | 
						|
    const users = await User.findOne({ customerId });
 | 
						|
    if (!users) return reply.status(404).send({ error: "User not found" });
 | 
						|
    
 | 
						|
    let loggedInUser = users.phone === phone ? 
 | 
						|
      { role: "Customer", name: users.username, phone: users.phone } : 
 | 
						|
      users.staff?.staff?.find(staff => staff.phone === phone) ?
 | 
						|
      { role: "Staff", name: users.staff.staff.find(staff => staff.phone === phone).name, phone } : null;
 | 
						|
    
 | 
						|
    if (!loggedInUser) return reply.status(404).send({ error: "User not found" });
 | 
						|
    console.log(loggedInUser)
 | 
						|
    
 | 
						|
    const fcmToken = users.fcmIds ? users.fcmIds.filter(id => id) : [];
 | 
						|
    const receiverTank = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() });
 | 
						|
    if (!receiverTank) throw new Error("Receiver tank not found.");
 | 
						|
    
 | 
						|
    const typeOfWater = receiverTank.typeOfWater;
 | 
						|
    let motorStopStatus = action === "start" ? "2" : "1";
 | 
						|
    const blockName = req.body.from || "Unknown Block";
 | 
						|
    const tankName = req.body.to || "Unknown Tank";
 | 
						|
    const stopTime = req.body.stopTime 
 | 
						|
    if (action === "start") {
 | 
						|
          
 | 
						|
      if (motorIntervals[motorId]) {
 | 
						|
        console.log(`🛑 Clearing old interval for motorId: ${motorId}`);
 | 
						|
        clearInterval(motorIntervals[motorId]);
 | 
						|
        delete motorIntervals[motorId];
 | 
						|
      
 | 
						|
        // Confirm deletion
 | 
						|
        if (!motorIntervals[motorId]) {
 | 
						|
          console.log(`✅ Old interval successfully deleted.`);
 | 
						|
        } else {
 | 
						|
          console.error(`❌ Failed to delete old interval.`);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      const startTime = 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": "2",
 | 
						|
            "connections.inputConnections.$.manual_threshold_time": manual_threshold_time,
 | 
						|
            "connections.inputConnections.$.threshold_type": threshold_type,
 | 
						|
            "connections.inputConnections.$.motor_on_type": "manual" 
 | 
						|
        }}
 | 
						|
      );
 | 
						|
      
 | 
						|
     eventEmitter.emit("motorStart", customerId, fcmToken, tankName, blockName, startTime, "Mobile APP", manual_threshold_time, typeOfWater, motorId, loggedInUser.phone);
 | 
						|
      //this.publishMotorStopStatus(motorId, motorStopStatus);
 | 
						|
      reply.code(200).send({ message: "Motor started successfully." });
 | 
						|
      
 | 
						|
      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),
 | 
						|
          started_by:loggedInUser.name
 | 
						|
        });
 | 
						|
        await newMotorData.save();
 | 
						|
            console.log("entered time",motorId,motorStopStatus)
 | 
						|
        // Update the tank connections with start time and threshold time
 | 
						|
        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);
 | 
						|
        console.log("New Threshold Time:", thresholdTime);
 | 
						|
        console.log("Current Time:", new Date());
 | 
						|
       
 | 
						|
        
 | 
						|
        motorIntervals[motorId]  = setInterval(async () => {
 | 
						|
          console.log(motorId,"interval created")
 | 
						|
          console.log(customerId,req.body.from,req.body.from_type.toLowerCase())
 | 
						|
          const supplierTank = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() });
 | 
						|
          console.log("up",supplierTank)
 | 
						|
          console.log(supplierTank.waterlevel,"parseInt(supplierTank.waterlevel, 10)")
 | 
						|
          const lowWaterThreshold =  20; 
 | 
						|
 | 
						|
          const currentWaterLevel = parseInt(supplierTank.waterlevel, 10);
 | 
						|
          const currentWaterPercentage = (currentWaterLevel / parseInt(supplierTank.capacity.replace(/,/g, ''), 10)) * 100;
 | 
						|
          const notificationTracker = new Map();
 | 
						|
          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
 | 
						|
            try {
 | 
						|
              console.log("motor stopping because it entered this condition")
 | 
						|
    
 | 
						|
              const tank = await Tank.findOne(
 | 
						|
                { customerId, "connections.inputConnections.motor_id": motorId },
 | 
						|
                { "connections.inputConnections.$": 1 } // Fetch only relevant motor connection
 | 
						|
            );
 | 
						|
    
 | 
						|
            if (tank && tank.connections.inputConnections[0].motor_stop_status === "1") {
 | 
						|
                console.log("⚠️ Motor already stopped. Skipping notification.");
 | 
						|
            } else {
 | 
						|
                console.log("🚀 Sending threshold time notification...");
 | 
						|
    
 | 
						|
                eventEmitter.emit(
 | 
						|
                    "sendThresholdTimeNotification",
 | 
						|
                    customerId,
 | 
						|
                    fcmToken,
 | 
						|
                    manual_threshold_time,
 | 
						|
                    motorId,
 | 
						|
                    tankName,
 | 
						|
                    blockName
 | 
						|
                );
 | 
						|
              }
 | 
						|
             
 | 
						|
          
 | 
						|
              reply.code(200).send({ message: "Motor stopped successfully." });
 | 
						|
            } catch (error) {
 | 
						|
              console.error("Error in handleMotorStop:", error);
 | 
						|
              reply.code(500).send({ error: "Internal Server Error" });
 | 
						|
            }
 | 
						|
 | 
						|
 | 
						|
    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.$.start_instance_id": null,
 | 
						|
                  "connections.inputConnections.$.threshold_type": null,
 | 
						|
                  "connections.inputConnections.$.manual_threshold_time": null,
 | 
						|
                  "connections.inputConnections.$.manual_threshold_percentage": null,
 | 
						|
                  "connections.inputConnections.$.stopTime": currentTime,
 | 
						|
                }
 | 
						|
              }
 | 
						|
            );
 | 
						|
          
 | 
						|
            if (motorIntervals[motorId]) {
 | 
						|
              console.log(`🛑 Clearing interval for motorId: ${motorId}`);
 | 
						|
              clearInterval(motorIntervals[motorId]);
 | 
						|
              delete motorIntervals[motorId];
 | 
						|
            
 | 
						|
              // Confirm deletion
 | 
						|
              if (!motorIntervals[motorId]) {
 | 
						|
                console.log(`✅ Interval for motorId: ${motorId} successfully deleted.`);
 | 
						|
              } else {
 | 
						|
                console.error(`❌ Failed to delete interval for motorId: ${motorId}`);
 | 
						|
              }
 | 
						|
            }
 | 
						|
            
 | 
						|
           
 | 
						|
            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;
 | 
						|
              const start = moment(motorData.startTime, 'DD-MMM-YYYY - HH:mm');
 | 
						|
              const stop = moment(currentTime, 'DD-MMM-YYYY - HH:mm');
 | 
						|
              const duration = moment.duration(stop.diff(start));
 | 
						|
              const runtime = Math.floor(duration.asMinutes()); // runtime in minutes
 | 
						|
 | 
						|
 | 
						|
              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(),
 | 
						|
                    runtime: runtime.toString(),
 | 
						|
                    stopped_by:loggedInUser.name
 | 
						|
                  }
 | 
						|
                }
 | 
						|
              );
 | 
						|
            }
 | 
						|
          }
 | 
						|
 | 
						|
          
 | 
						|
 | 
						|
          // 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),
 | 
						|
          started_by:loggedInUser.name
 | 
						|
        });
 | 
						|
        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.$.start_instance_id": null,
 | 
						|
                  "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(),
 | 
						|
                    stopped_by:loggedInUser.name
 | 
						|
                  }
 | 
						|
                }
 | 
						|
              );
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }, 20000); 
 | 
						|
      }
 | 
						|
      
 | 
						|
    }
 | 
						|
      
 | 
						|
    } else if (action === "stop") {
 | 
						|
      // Dynamically find start_instance_id from tank
 | 
						|
          const tankWithMotor = await Tank.findOne({
 | 
						|
            customerId,
 | 
						|
            "connections.inputConnections.motor_id": motorId
 | 
						|
          });
 | 
						|
 | 
						|
          let dynamicInstanceId = null;
 | 
						|
          let user_name = loggedInUser.name
 | 
						|
          console.log(user_name,"user_name in stop1")
 | 
						|
          if (tankWithMotor) {
 | 
						|
            const connection = tankWithMotor.connections.inputConnections.find(conn => conn.motor_id === motorId);
 | 
						|
            if (connection && connection.start_instance_id) {
 | 
						|
              dynamicInstanceId = connection.start_instance_id;
 | 
						|
            }
 | 
						|
          }
 | 
						|
 | 
						|
          await stopMotor(motorId, customerId, dynamicInstanceId,user_name);
 | 
						|
 | 
						|
     
 | 
						|
      try {
 | 
						|
        const motorData = await MotorData.findOne({
 | 
						|
          customerId,
 | 
						|
          motor_id: motorId,
 | 
						|
          start_instance_id: dynamicInstanceId
 | 
						|
        });
 | 
						|
  
 | 
						|
        let totalWaterPumped = 0; // Default value in case data is missing
 | 
						|
        if (motorData && motorData.quantity_delivered) {
 | 
						|
          totalWaterPumped = motorData.quantity_delivered;
 | 
						|
        }
 | 
						|
  
 | 
						|
        console.log("quantity_delivered:", totalWaterPumped);
 | 
						|
  
 | 
						|
    
 | 
						|
        //const totalWaterPumped = await motorData.quantity_delivered
 | 
						|
     // console.log("quantity_delivered",totalWaterPumped)
 | 
						|
        eventEmitter.emit("motorStop", customerId, fcmToken, tankName, blockName, stopTime, "Mobile APP", totalWaterPumped, typeOfWater, motorId,  
 | 
						|
          loggedInUser.phone,);
 | 
						|
    
 | 
						|
        reply.code(200).send({ message: "Motor stopped successfully." });
 | 
						|
      } catch (error) {
 | 
						|
        console.error("Error in handleMotorStop:", error);
 | 
						|
        reply.code(500).send({ error: "Internal Server Error" });
 | 
						|
      }
 | 
						|
      this.publishMotorStopStatus(motorId, motorStopStatus);
 | 
						|
      reply.code(200).send({ message: "Motor stopped successfully." });
 | 
						|
    }
 | 
						|
  } catch (err) {
 | 
						|
    throw boom.boomify(err);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
async function stopMotor(motorId, customerId, start_instance_id,user_name) {
 | 
						|
  console.log(user_name,"user_name in stop2")
 | 
						|
  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.$.stopTime": currentTime,
 | 
						|
        "connections.inputConnections.$.start_instance_id": null,
 | 
						|
        "connections.inputConnections.$.threshold_type": null,
 | 
						|
        "connections.inputConnections.$.manual_threshold_time": null,
 | 
						|
        "connections.inputConnections.$.manual_threshold_percentage": null
 | 
						|
    }}
 | 
						|
  );
 | 
						|
 | 
						|
  if (motorIntervals[motorId]) {
 | 
						|
    clearInterval(motorIntervals[motorId]);
 | 
						|
    delete motorIntervals[motorId];
 | 
						|
  }
 | 
						|
 | 
						|
 // eventEmitter.emit("motorStop", customerId, [], "", "", currentTime, "Mobile APP", 0, "", motorId, "");
 | 
						|
  
 | 
						|
  const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id });
 | 
						|
  if (motorData) {
 | 
						|
              const start = moment(motorData.startTime, 'DD-MMM-YYYY - HH:mm');
 | 
						|
              const stop = moment(currentTime, 'DD-MMM-YYYY - HH:mm');
 | 
						|
              const duration = moment.duration(stop.diff(start));
 | 
						|
              const runtime = Math.floor(duration.asMinutes()); // runtime in minutes
 | 
						|
    
 | 
						|
    const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() });
 | 
						|
    const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel.replace(/,/g, ''), 10);
 | 
						|
    const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel.replace(/,/g, ''), 10);
 | 
						|
 | 
						|
    await MotorData.updateOne(
 | 
						|
      { customerId, motor_id: motorId, start_instance_id },
 | 
						|
      { $set: { stopTime: currentTime, receiverfinalwaterlevel: receiverFinalWaterLevel.toString(), quantity_delivered: quantityDelivered.toString(), runtime: runtime,stopped_by:user_name } }
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
const monitorWaterLevels = async () => {
 | 
						|
  try {
 | 
						|
   // console.log("⏳ Monitoring water levels...");
 | 
						|
 | 
						|
    const tanks = await Tank.find(); // Fetch all tanks
 | 
						|
    //console.log("Fetched Tanks:", tanks.length);
 | 
						|
 | 
						|
    for (const tank of tanks) {
 | 
						|
    
 | 
						|
      const {
 | 
						|
        _id,
 | 
						|
        customerId,  // Move this to the top
 | 
						|
        motor_id,
 | 
						|
        tankName,
 | 
						|
        blockName,
 | 
						|
        waterlevel: currentWaterLevel,
 | 
						|
        capacity,
 | 
						|
        auto_min_percentage,
 | 
						|
        reserved_percentage,
 | 
						|
        notificationSentLow,
 | 
						|
        notificationSentCritical,
 | 
						|
      } = tank;
 | 
						|
    
 | 
						|
      const users = await User.find({ customerId });
 | 
						|
      const fcmTokens = users
 | 
						|
        .map(user => user.fcmIds)
 | 
						|
        .filter(fcmIds => Array.isArray(fcmIds) && fcmIds.length > 0) // Ensure it's an array
 | 
						|
        .flat();
 | 
						|
    
 | 
						|
      if (!fcmTokens || fcmTokens.length === 0) {
 | 
						|
        //console.error("❌ No valid FCM tokens found for customerId:", customerId);
 | 
						|
        continue; // Skip this tank
 | 
						|
      }
 | 
						|
      const LOW_PERCENTAGE = 20;  // 20% threshold
 | 
						|
      const CRITICAL_PERCENTAGE = 10; // 10% threshold
 | 
						|
 | 
						|
      // **Calculate thresholds based on tank capacity**
 | 
						|
      const lowWaterLevel = (LOW_PERCENTAGE / 100) * capacity; 
 | 
						|
      const criticalLowWaterLevel = (CRITICAL_PERCENTAGE / 100) * capacity; 
 | 
						|
      const currentWaterPercentage = (currentWaterLevel / capacity) * 100; 
 | 
						|
      // const lowWaterLevel = 9483; // Low threshold in liters
 | 
						|
      // const criticalLowWaterLevel = 9483; 
 | 
						|
      if (currentWaterLevel <= criticalLowWaterLevel) {
 | 
						|
        if (!notificationSentCritical) {
 | 
						|
          console.log("🚨 Sending Critical Low Water Notification...");
 | 
						|
          eventEmitter.emit("sendCriticalLowWaterNotification", customerId, fcmTokens, motor_id, tankName, blockName, criticalLowWaterLevel, currentWaterLevel, currentWaterPercentage);
 | 
						|
          await Tank.updateOne({ _id }, { notificationSentCritical: true, notificationSentLow: true });
 | 
						|
        }
 | 
						|
      } 
 | 
						|
      else if (currentWaterLevel <= lowWaterLevel) {
 | 
						|
        if (!notificationSentLow) {
 | 
						|
          console.log("⚠️ Sending Low Water Notification...");
 | 
						|
          eventEmitter.emit("sendLowWaterNotification", customerId, fcmTokens, motor_id, tankName, blockName, lowWaterLevel, currentWaterLevel, currentWaterPercentage);
 | 
						|
          await Tank.updateOne({ _id }, { notificationSentLow: true });
 | 
						|
        }
 | 
						|
      } 
 | 
						|
      else if (currentWaterLevel > lowWaterLevel && (notificationSentLow || notificationSentCritical)) {
 | 
						|
        console.log("🔄 Water level restored. Resetting flags.");
 | 
						|
        await Tank.updateOne({ _id }, { notificationSentCritical: false, notificationSentLow: false });
 | 
						|
      }
 | 
						|
      
 | 
						|
    }
 | 
						|
  } catch (error) {
 | 
						|
    console.error("❌ Error monitoring water levels:", error);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
setInterval(monitorWaterLevels, 1000);
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// async function stopMotor(motorId, customerId, start_instance_id) {
 | 
						|
//   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.$.stopTime": currentTime,
 | 
						|
//         "connections.inputConnections.$.threshold_type": null,
 | 
						|
//         "connections.inputConnections.$.manual_threshold_time": null,
 | 
						|
//         "connections.inputConnections.$.manual_threshold_percentage": null
 | 
						|
//     }}
 | 
						|
//   );
 | 
						|
 | 
						|
//   if (motorIntervals[motorId]) {
 | 
						|
//     clearInterval(motorIntervals[motorId]);
 | 
						|
//     delete motorIntervals[motorId];
 | 
						|
//   }
 | 
						|
 | 
						|
//   eventEmitter.emit("motorStop", customerId, [], "", "", currentTime, "Mobile APP", 0, "", motorId, "");
 | 
						|
  
 | 
						|
//   const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id });
 | 
						|
//   if (motorData) {
 | 
						|
//     const startTime = moment(motorData.startTime, 'DD-MMM-YYYY - HH:mm');
 | 
						|
//     const runtime = moment.duration(moment(currentTime, 'DD-MMM-YYYY - HH:mm').diff(startTime)).asSeconds();
 | 
						|
    
 | 
						|
//     const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() });
 | 
						|
//     const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel.replace(/,/g, ''), 10);
 | 
						|
//     const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel.replace(/,/g, ''), 10);
 | 
						|
 | 
						|
//     await MotorData.updateOne(
 | 
						|
//       { customerId, motor_id: motorId, start_instance_id },
 | 
						|
//       { $set: { stopTime: currentTime, receiverfinalwaterlevel: receiverFinalWaterLevel.toString(), quantity_delivered: quantityDelivered.toString(), runtime: runtime } }
 | 
						|
//     );
 | 
						|
//   }
 | 
						|
// }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// 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 });
 | 
						|
    const user = await User.findOne({ customerId });
 | 
						|
    const allowNotifications = user?.automaticStartAndStopNotify ?? true; // Default to true if not set
 | 
						|
 | 
						|
    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",
 | 
						|
          
 | 
						|
          }
 | 
						|
        }
 | 
						|
      );
 | 
						|
 | 
						|
      if (allowNotifications) {
 | 
						|
        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();
 | 
						|
 | 
						|
      if (allowNotifications) {
 | 
						|
        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;
 | 
						|
    
 | 
						|
    console.log(status,"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');
 | 
						|
require('dotenv').config();
 | 
						|
 | 
						|
// **Persistent MQTT Connection**
 | 
						|
const client = mqtt.connect('mqtt://35.207.198.4:1883', {
 | 
						|
  clientId: `mqtt_server_${Math.random().toString(16).substr(2, 8)}`,
 | 
						|
  clean: false, // Ensures MQTT retains subscriptions
 | 
						|
  reconnectPeriod: 2000, // Reconnect every 2 seconds
 | 
						|
});
 | 
						|
 | 
						|
const subscribedTopics = new Set();
 | 
						|
const activeDevices = new Set(); // Keep track of active devices
 | 
						|
 | 
						|
client.on('connect', () => {
 | 
						|
  console.log('✅ Connected to MQTT broker');
 | 
						|
 | 
						|
  // **Ensure re-subscriptions after reconnect**
 | 
						|
  subscribedTopics.forEach(topic => {
 | 
						|
    client.subscribe(topic, { qos: 1 }, (err) => {
 | 
						|
      if (err) {
 | 
						|
        console.error(`❌ Error resubscribing to ${topic}:`, err);
 | 
						|
      } else {
 | 
						|
        console.log(`🔄 Resubscribed to ${topic}`);
 | 
						|
      }
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  // **Subscribe to new device announcements**
 | 
						|
  client.subscribe('water/iot-data/announce', { qos: 1 }, (err) => {
 | 
						|
    if (err) {
 | 
						|
      console.error('❌ Error subscribing to announcement topic:', err);
 | 
						|
    } else {
 | 
						|
      console.log('📡 Subscribed to water/iot-data/announce');
 | 
						|
    }
 | 
						|
  });
 | 
						|
});
 | 
						|
 | 
						|
client.on('message', async (topic, message) => {
 | 
						|
  console.log(`📩 Message received on topic ${topic}: ${message.toString()}`);
 | 
						|
 | 
						|
  try {
 | 
						|
    const data = JSON.parse(message.toString());
 | 
						|
 | 
						|
    // **Handle device announcements**
 | 
						|
    if (topic === 'water/iot-data/announce') {
 | 
						|
      if (!data.objects || !data.objects.hw_Id) {
 | 
						|
        console.error("❌ Invalid announcement format. Missing hw_Id.");
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      const hw_Id = data.objects.hw_Id;
 | 
						|
      const deviceTopic = `water/iot-data/${hw_Id}`;
 | 
						|
 | 
						|
      if (!subscribedTopics.has(deviceTopic)) {
 | 
						|
        client.subscribe(deviceTopic, { qos: 1 }, (err) => {
 | 
						|
          if (err) {
 | 
						|
            console.error(`❌ Error subscribing to ${deviceTopic}:`, err);
 | 
						|
          } else {
 | 
						|
            console.log(`✅ Subscribed to ${deviceTopic}`);
 | 
						|
            subscribedTopics.add(deviceTopic);
 | 
						|
            activeDevices.add(hw_Id);
 | 
						|
            console.log('📡 Active Devices:', Array.from(activeDevices));
 | 
						|
 | 
						|
            // ✅ **Now also process data**
 | 
						|
            processIotData(hw_Id, data);
 | 
						|
          }
 | 
						|
        });
 | 
						|
      } else {
 | 
						|
        console.log(`🔄 Already subscribed to ${deviceTopic}, processing data.`);
 | 
						|
        processIotData(hw_Id, data);
 | 
						|
      }
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    // **Process IoT Data for device topics**
 | 
						|
    if (topic.startsWith('water/iot-data/')) {
 | 
						|
      setImmediate(() => {
 | 
						|
        console.log(`🚀 Entering processIotData() for topic: ${topic}`);
 | 
						|
        const hw_Id = topic.split('/')[2];
 | 
						|
        processIotData(hw_Id, data);
 | 
						|
      });
 | 
						|
    }
 | 
						|
  } catch (err) {
 | 
						|
    console.error('❌ Error processing message:', err.message);
 | 
						|
  }
 | 
						|
});
 | 
						|
 | 
						|
 | 
						|
client.on('error', (err) => console.error('❌ MQTT Error:', err));
 | 
						|
client.on('close', () => console.log('⚠️ MQTT Connection Closed.'));
 | 
						|
client.on('offline', () => console.log('⚠️ MQTT Broker Offline.'));
 | 
						|
 | 
						|
async function processIotData(hw_Id, data) {
 | 
						|
  try {
 | 
						|
    console.log(`📡 Processing IoT Data for hw_Id: ${hw_Id}`, JSON.stringify(data, null, 2));
 | 
						|
 | 
						|
    if (!data.objects || !data.objects.tanks) {
 | 
						|
      console.error(`❌ Missing 'tanks' in data for hw_Id: ${hw_Id}`);
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    const { Motor_status, tanks } = data.objects;
 | 
						|
    const currentDate = new Date();
 | 
						|
    const date = currentDate.toISOString(); // ISO string for date
 | 
						|
    const time = currentDate.toLocaleTimeString('en-IN', { hour12: false, timeZone: 'Asia/Kolkata' });
 | 
						|
 | 
						|
    const tankDocuments = tanks.map(tank => ({
 | 
						|
      tankhardwareId: tank.Id,
 | 
						|
      tankHeight: tank.level,
 | 
						|
      date,
 | 
						|
      time
 | 
						|
    }));
 | 
						|
 | 
						|
    const iotTankData = new IotData({
 | 
						|
      hardwareId: hw_Id,
 | 
						|
      Motor_status,
 | 
						|
      tanks: tankDocuments,
 | 
						|
      date,
 | 
						|
      time
 | 
						|
    });
 | 
						|
    await iotTankData.save();
 | 
						|
 | 
						|
    // Delete excess records (keep only the latest three records)
 | 
						|
    // const recordsToKeep = 3;
 | 
						|
    // const recordsToDelete = await IotData.find({ hardwareId: hw_Id })
 | 
						|
    //   .sort({ date: -1, time: -1 })
 | 
						|
    //   .skip(recordsToKeep);
 | 
						|
 | 
						|
    // for (const record of recordsToDelete) {
 | 
						|
    //   await record.remove();
 | 
						|
    // }
 | 
						|
 | 
						|
    // Process each tank
 | 
						|
    for (const tank of tanks) {
 | 
						|
      const { Id: tankhardwareId, level: tankHeight } = tank;
 | 
						|
      const existingTank = await Tank.findOne({ hardwareId: hw_Id, 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);
 | 
						|
 | 
						|
      console.log(`🚰 Tank [${tankhardwareId}] - Level: ${tankHeight}, Calculated Water Level: ${waterLevel}`);
 | 
						|
 | 
						|
      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": hw_Id });
 | 
						|
 | 
						|
    if (!motorTank) {
 | 
						|
      console.log('⚠️ Motor not found for specified motor_id');
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    const inputConnection = motorTank.connections.inputConnections.find(conn => conn.motor_id === hw_Id);
 | 
						|
    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');
 | 
						|
        const formattedTime = currentTime.format('DD-MMM-YYYY - HH:mm');
 | 
						|
        const startInstanceId = `${hw_Id}${formattedTime}`;
 | 
						|
    
 | 
						|
        inputConnection.motor_stop_status = "2";
 | 
						|
        inputConnection.motor_on_type = "forced_manual";
 | 
						|
        inputConnection.startTime = formattedTime;
 | 
						|
        inputConnection.start_instance_id = startInstanceId;
 | 
						|
        const newMotorData = new MotorData({
 | 
						|
          customerId:motorTank.customerId,
 | 
						|
          motor_id: hw_Id,
 | 
						|
          start_instance_id: startInstanceId,
 | 
						|
          supplierTank: inputConnection.inputConnections,
 | 
						|
          receiverTank: motorTank.tankName,
 | 
						|
          supplier_type: inputConnection.input_type,
 | 
						|
          receiver_type: motorTank.tankLocation,
 | 
						|
          startTime: formattedTime,
 | 
						|
          receiverInitialwaterlevel: parseInt(inputConnection.water_level, 10),
 | 
						|
          started_by:"manual"
 | 
						|
        });
 | 
						|
        await newMotorData.save();
 | 
						|
 | 
						|
      }
 | 
						|
 | 
						|
      if (inputConnection.motor_stop_status === "2" && status === 1) {
 | 
						|
        const motorData = await MotorData.findOne({ customerId:motorTank.customerId, motor_id: hw_Id, start_instance_id: inputConnection.start_instance_id });
 | 
						|
        const startinstance = inputConnection.start_instance_id;
 | 
						|
        const currentTime = moment().tz('Asia/Kolkata').format('DD-MMM-YYYY - HH:mm');
 | 
						|
        inputConnection.motor_stop_status = "1";
 | 
						|
        inputConnection.motor_on_type = "manual";
 | 
						|
        inputConnection.stopTime = currentTime;
 | 
						|
        inputConnection.start_instance_id = null;
 | 
						|
      
 | 
						|
        const motorId = hw_Id;
 | 
						|
        if (motorIntervals[motorId]) {
 | 
						|
          clearInterval(motorIntervals[motorId]);
 | 
						|
          delete motorIntervals[motorId];
 | 
						|
          console.log("motor interval deleted")
 | 
						|
        }
 | 
						|
        
 | 
						|
     
 | 
						|
      console.log(motorData,"motorData")
 | 
						|
      if (motorData) {
 | 
						|
      
 | 
						|
        const receiverTank = await Tank.findOne({ customerId:motorTank.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;
 | 
						|
        const start = moment(motorData.startTime, 'DD-MMM-YYYY - HH:mm');
 | 
						|
        const stop = moment(currentTime, 'DD-MMM-YYYY - HH:mm');
 | 
						|
        const duration = moment.duration(stop.diff(start));
 | 
						|
        const runtime = Math.floor(duration.asMinutes()); // runtime in minutes
 | 
						|
 | 
						|
 | 
						|
        await Tank.findOneAndUpdate(
 | 
						|
          { customerId:motorTank.customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() },
 | 
						|
          { $set: { total_water_added_from_midnight: totalwaterpumped } }
 | 
						|
        );
 | 
						|
 | 
						|
        await MotorData.updateOne(
 | 
						|
          { customerId:motorTank.customerId, motor_id: motorId, start_instance_id: startinstance },
 | 
						|
          {
 | 
						|
            $set: {
 | 
						|
              stopTime: currentTime,
 | 
						|
              receiverfinalwaterlevel: receiverFinalWaterLevel.toString(),
 | 
						|
              quantity_delivered: quantityDelivered.toString(),
 | 
						|
              runtime: runtime.toString(),
 | 
						|
              stopped_by:"manual"
 | 
						|
            }
 | 
						|
          }
 | 
						|
        );
 | 
						|
      }
 | 
						|
      }
 | 
						|
      await motorTank.save();
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    console.log(`✅ Data processed successfully for hw_Id: ${hw_Id}`);
 | 
						|
 | 
						|
  } catch (err) {
 | 
						|
    console.error('❌ Error processing IoT data:', err.message);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
function logSets() {
 | 
						|
  console.log("Subscribed Topics:", Array.from(subscribedTopics));
 | 
						|
  console.log("Active Devices:", Array.from(activeDevices));
 | 
						|
  console.log("motorIntervals:", motorIntervals);
 | 
						|
}
 | 
						|
 | 
						|
// Call logSets every 30 seconds
 | 
						|
setInterval(logSets, 30000);
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
const sendMotorNotifications = async () => {
 | 
						|
  // console.log("🔄 Checking for motor notifications...");
 | 
						|
 
 | 
						|
   // Find motors that need a start or stop notification
 | 
						|
   const motors = await Tank.find({
 | 
						|
     "connections.inputConnections.motor_id": { $exists: true },
 | 
						|
   });
 | 
						|
 
 | 
						|
   for (const motorTank of motors) {
 | 
						|
     const inputConnection = motorTank.connections.inputConnections.find(
 | 
						|
       (conn) => conn.motor_id
 | 
						|
     );
 | 
						|
     const status = inputConnection.motor_status
 | 
						|
 //console.log("motorTank",inputConnection)
 | 
						|
// console.log("inputConnection.motor_on_type ",inputConnection.motor_on_type )
 | 
						|
     if (!inputConnection) continue;
 | 
						|
 
 | 
						|
     const { customerId, blockName, tankName } = motorTank;
 | 
						|
     const fcmTokens = await getFcmTokens(customerId); // Get FCM tokens for this customer
 | 
						|
     if (!fcmTokens.length) continue;
 | 
						|
 
 | 
						|
     // 🔹 Motor Start Condition
 | 
						|
     if (
 | 
						|
       inputConnection.motor_stop_status === "2" && inputConnection.motor_on_type === "forced_manual" &&
 | 
						|
       !motorTank.motor_start_notified
 | 
						|
     ) {
 | 
						|
       console.log("✅ Sending Motor Start Notification...");
 | 
						|
 
 | 
						|
       eventEmitter.emit(
 | 
						|
         "sendMotorStartNotification",
 | 
						|
         inputConnection.motor_id,
 | 
						|
         customerId,
 | 
						|
         fcmTokens,
 | 
						|
         inputConnection.water_level || 0,
 | 
						|
         blockName,
 | 
						|
         tankName,
 | 
						|
         "forced_manual",
 | 
						|
         inputConnection.manual_threshold_time
 | 
						|
       );
 | 
						|
 
 | 
						|
       // Mark notification as sent
 | 
						|
       motorTank.motor_start_notified = true;
 | 
						|
       motorTank.motor_stop_notified = false; // Reset stop notification flag
 | 
						|
       await motorTank.save();
 | 
						|
     }
 | 
						|
 
 | 
						|
     // 🔹 Motor Stop Condition
 | 
						|
     if (
 | 
						|
       inputConnection.motor_stop_status === "1" &&  
 | 
						|
       !motorTank.motor_stop_notified && inputConnection.motor_on_type === "forced_manual"
 | 
						|
     ) {
 | 
						|
       console.log("✅ Sending Motor Stop Notification...");
 | 
						|
 
 | 
						|
       eventEmitter.emit(
 | 
						|
         "sendMotorStopNotification",
 | 
						|
         inputConnection.motor_id,
 | 
						|
         customerId,
 | 
						|
         fcmTokens,
 | 
						|
         inputConnection.water_level || 0,
 | 
						|
         blockName,
 | 
						|
         tankName,
 | 
						|
         "forced_manual"
 | 
						|
       );
 | 
						|
 
 | 
						|
       // Mark notification as sent
 | 
						|
       motorTank.motor_stop_notified = true;
 | 
						|
       motorTank.motor_start_notified = false; // Reset start notification flag
 | 
						|
       await motorTank.save();
 | 
						|
     }
 | 
						|
   }
 | 
						|
 };
 | 
						|
 
 | 
						|
 const getFcmTokens = async (customerId) => {
 | 
						|
   const user = await User.findOne({ customerId }).select("fcmIds");
 | 
						|
   return user?.fcmIds?.filter((token) => token) || [];
 | 
						|
 };
 | 
						|
 
 | 
						|
 //Run the notification check every second
 | 
						|
 cron.schedule("* * * * * *", async () => {
 | 
						|
   await sendMotorNotifications();
 | 
						|
 });
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
// API function to get survey data for a particular installer
 | 
						|
//
 | 
						|
exports.getPendingAndCompletedsurveyOfparticularInstaller = async (request, reply) => {
 | 
						|
  try {
 | 
						|
    const { installationId } = request.params;
 | 
						|
    const { survey_status } = request.body;
 | 
						|
 | 
						|
    const surveyData = await User.find({ installationId, survey_status });
 | 
						|
 | 
						|
    reply.send({
 | 
						|
      status_code: 200,
 | 
						|
      surveyData,
 | 
						|
    });
 | 
						|
  } catch (err) {
 | 
						|
    console.error('❌ Error fetching survey data:', err);
 | 
						|
    throw boom.boomify(err);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
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();
 | 
						|
    end.setHours(23, 59, 59, 999); // Ensure full day is included
 | 
						|
 | 
						|
    // 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,
 | 
						|
    };
 | 
						|
    const stopDateMoment = moment(stopDate, "DD-MMM-YYYY - HH:mm");
 | 
						|
const today = moment().startOf('day');
 | 
						|
 | 
						|
if (stopDateMoment.isSame(today, 'day')) {
 | 
						|
  const latestConsumption = (waterlevel_at_midnight + total_water_added_from_midnight) - waterlevel;
 | 
						|
  const nowFormatted = moment().format("DD-MMM-YYYY - HH:mm");
 | 
						|
 | 
						|
  filteredConsumptions.push({
 | 
						|
    tankName: tank.tankName,
 | 
						|
    consumption: latestConsumption.toString(),
 | 
						|
    time: nowFormatted
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
    // 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);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
exports.sendUserSetNotifications = async (request, reply) => {
 | 
						|
  const { customerId, notificationTime, allowNotifications } = request.body;
 | 
						|
 | 
						|
  try {
 | 
						|
    const user = await User.findOneAndUpdate(
 | 
						|
      { customerId },
 | 
						|
      { notificationTime, allowNotifications },
 | 
						|
      { new: true, upsert: true } // Create user if not exists
 | 
						|
    );
 | 
						|
 | 
						|
    console.log(`User ${customerId} updated: Notification Time - ${notificationTime}, Allowed - ${allowNotifications}`);
 | 
						|
 | 
						|
    return reply.send({ success: true, user });
 | 
						|
  } catch (error) {
 | 
						|
    console.error("Error setting notification time:", error);
 | 
						|
    return reply.status(500).send({ success: false, message: "Internal server error" });
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
exports.sendUserSetLowWaterNotificationsSwitch = async (request, reply) => {
 | 
						|
  const { customerId, lowWaterAlert } = request.body;
 | 
						|
 | 
						|
  try {
 | 
						|
    const user = await User.findOneAndUpdate(
 | 
						|
      { customerId },
 | 
						|
      { lowWaterAlert},
 | 
						|
      { new: true, upsert: true } // Create user if not exists
 | 
						|
    );
 | 
						|
 | 
						|
    console.log(`User ${customerId} updated: Allowed - ${lowWaterAlert}`);
 | 
						|
 | 
						|
    return reply.send({ success: true, user });
 | 
						|
  } catch (error) {
 | 
						|
    console.error("Error setting notification time:", error);
 | 
						|
    return reply.status(500).send({ success: false, message: "Internal server error" });
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
exports.sendUserSetCriticallyLowWaterNotificationsSwitch = async (request, reply) => {
 | 
						|
  const { customerId, criticalLowWaterAlert } = request.body;
 | 
						|
 | 
						|
  try {
 | 
						|
    const user = await User.findOneAndUpdate(
 | 
						|
      { customerId },
 | 
						|
      { criticalLowWaterAlert},
 | 
						|
      { new: true, upsert: true } // Create user if not exists
 | 
						|
    );
 | 
						|
 | 
						|
    console.log(`User ${customerId} updated: Allowed - ${criticalLowWaterAlert}`);
 | 
						|
 | 
						|
    return reply.send({ success: true, user });
 | 
						|
  } catch (error) {
 | 
						|
    console.error("Error setting notification time:", error);
 | 
						|
    return reply.status(500).send({ success: false, message: "Internal server error" });
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
exports.sendUserManualStartAndStop = async (request, reply) => {
 | 
						|
  const { customerId, manualStartAndStopNotify } = request.body;
 | 
						|
 | 
						|
  try {
 | 
						|
    const user = await User.findOneAndUpdate(
 | 
						|
      { customerId },
 | 
						|
      { manualStartAndStopNotify},
 | 
						|
      { new: true, upsert: true } // Create user if not exists
 | 
						|
    );
 | 
						|
 | 
						|
    console.log(`User ${customerId} updated: Allowed - ${manualStartAndStopNotify}`);
 | 
						|
 | 
						|
    return reply.send({ success: true, user });
 | 
						|
  } catch (error) {
 | 
						|
    console.error("Error setting notification time:", error);
 | 
						|
    return reply.status(500).send({ success: false, message: "Internal server error" });
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
exports.sendUserAutomaticStartAndStop = async (request, reply) => {
 | 
						|
  const { customerId, automaticStartAndStopNotify } = request.body;
 | 
						|
 | 
						|
  try {
 | 
						|
    const user = await User.findOneAndUpdate(
 | 
						|
      { customerId },
 | 
						|
      { automaticStartAndStopNotify},
 | 
						|
      { new: true, upsert: true } // Create user if not exists
 | 
						|
    );
 | 
						|
 | 
						|
    console.log(`User ${customerId} updated: Allowed - ${automaticStartAndStopNotify}`);
 | 
						|
 | 
						|
    return reply.send({ success: true, user });
 | 
						|
  } catch (error) {
 | 
						|
    console.error("Error setting notification time:", error);
 | 
						|
    return reply.status(500).send({ success: false, message: "Internal server error" });
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
// 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);
 | 
						|
//   }
 | 
						|
// };
 | 
						|
 | 
						|
const calculateWaterLevelAndNotify = async () => {
 | 
						|
  try {
 | 
						|
    const now = moment();
 | 
						|
    const currentTime = now.format("HH:mm"); // Current time in HH:mm format
 | 
						|
 | 
						|
    console.log(`Current time: ${currentTime}`);
 | 
						|
 | 
						|
    // Get all users who have allowed notifications and have set a notification time
 | 
						|
    const users = await User.find({ allowNotifications: true, notificationTime: currentTime });
 | 
						|
 | 
						|
    if (users.length === 0) {
 | 
						|
      console.log("No users to notify at this time.");
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    for (const user of users) {
 | 
						|
      const { customerId, fcmIds } = user;
 | 
						|
 | 
						|
      if (!Array.isArray(fcmIds) || fcmIds.length === 0) {
 | 
						|
        console.log(`No valid FCM tokens for customer ID: ${customerId}`);
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      // Get tanks associated with the user
 | 
						|
      const tanks = await Tank.find({ customerId });
 | 
						|
 | 
						|
      for (const tank of tanks) {
 | 
						|
        const {
 | 
						|
          tankName,
 | 
						|
          tankLocation,
 | 
						|
          typeOfWater,
 | 
						|
          capacity,
 | 
						|
          waterlevel,
 | 
						|
          waterlevel_at_midnight,
 | 
						|
        } = tank;
 | 
						|
 | 
						|
        // 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);
 | 
						|
 | 
						|
        let notificationBody =
 | 
						|
          `🛢️ Tank Name: ${tankName}\n` +
 | 
						|
          `🏢 Location: ${tankLocation}\n` +
 | 
						|
          `💧 Type of Water: ${typeOfWater}\n` +
 | 
						|
          `Current Water Level: ${currentWaterLevel} liters (${currentWaterLevelPercentage}%)\n`;
 | 
						|
 | 
						|
        await sendNotification(customerId, fcmIds, "Water Level Update", notificationBody);
 | 
						|
        console.log("Notification sent for tank:", tankName);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    console.log("Water level notifications processed.");
 | 
						|
  } catch (err) {
 | 
						|
    console.error("Error in water level calculation:", err);
 | 
						|
  }
 | 
						|
};
 | 
						|
// const calculateLowWaterLevelAndNotify = async () => {
 | 
						|
//   try {
 | 
						|
//     const now = moment();
 | 
						|
//     const currentTime = now.format("HH:mm"); // Current time in HH:mm format
 | 
						|
 | 
						|
//     console.log(`Current time: ${currentTime}`);
 | 
						|
 | 
						|
//     // Get all users who have allowed notifications and have set a notification time
 | 
						|
//     const users = await User.find({ lowWaterAlert: true });
 | 
						|
 | 
						|
//     if (users.length === 0) {
 | 
						|
//       console.log("No users to notify at this time.");
 | 
						|
//       return;
 | 
						|
//     }
 | 
						|
 | 
						|
//     for (const user of users) {
 | 
						|
//       const { customerId, fcmIds } = user;
 | 
						|
 | 
						|
//       if (!Array.isArray(fcmIds) || fcmIds.length === 0) {
 | 
						|
//         console.log(`No valid FCM tokens for customer ID: ${customerId}`);
 | 
						|
//         continue;
 | 
						|
//       }
 | 
						|
 | 
						|
//       // Get tanks associated with the user
 | 
						|
//       const tanks = await Tank.find({ customerId });
 | 
						|
 | 
						|
//       for (const tank of tanks) {
 | 
						|
//         const {
 | 
						|
//           tankName,
 | 
						|
//           tankLocation,
 | 
						|
//           typeOfWater,
 | 
						|
//           capacity,
 | 
						|
//           waterlevel,
 | 
						|
//           waterlevel_at_midnight,
 | 
						|
//         } = tank;
 | 
						|
 | 
						|
//         // Remove commas before parsing numbers
 | 
						|
//         const tankCapacity = parseFloat(capacity.replace(/,/g, '')) || 0;
 | 
						|
//         const currentWaterLevel = parseFloat(waterlevel.replace(/,/g, '')) || 0;
 | 
						|
 | 
						|
//         if (tankCapacity === 0) {
 | 
						|
//           console.log(`Skipping tank ${tankName} due to zero capacity`);
 | 
						|
//           continue;
 | 
						|
//         }
 | 
						|
 | 
						|
//         const currentWaterLevelPercentage = ((currentWaterLevel / tankCapacity) * 100).toFixed(2);
 | 
						|
 | 
						|
//         // Send notification only if water level is below 15%
 | 
						|
//         if (currentWaterLevelPercentage < 15) {
 | 
						|
//           let notificationBody =
 | 
						|
//             `🛢️ Tank Name: ${tankName}\n` +
 | 
						|
//             `🏢 Location: ${tankLocation}\n` +
 | 
						|
//             `💧 Type of Water: ${typeOfWater}\n` +
 | 
						|
//             `Current Water Level: ${currentWaterLevel} liters (${currentWaterLevelPercentage}%)\n`;
 | 
						|
 | 
						|
//           await sendNotification(customerId, fcmIds, "Low Water Level Alert", notificationBody);
 | 
						|
//           console.log("Notification sent for tank:", tankName);
 | 
						|
//         } else {
 | 
						|
//           console.log(`Skipping notification for tank ${tankName}, water level is above 15%`);
 | 
						|
//         }
 | 
						|
//       }
 | 
						|
//     }
 | 
						|
 | 
						|
//     console.log("Water level notifications processed.");
 | 
						|
//   } catch (err) {
 | 
						|
//     console.error("Error in water level calculation:", err);
 | 
						|
//   }
 | 
						|
// };
 | 
						|
// const calculateCriticalLowWaterLevelAndNotify = async () => {
 | 
						|
//   try {
 | 
						|
//     const now = moment();
 | 
						|
//     const currentTime = now.format("HH:mm"); // Current time in HH:mm format
 | 
						|
 | 
						|
//     console.log(`Current time: ${currentTime}`);
 | 
						|
 | 
						|
//     // Get all users who have allowed critical low water notifications
 | 
						|
//     const users = await User.find({ criticalLowWaterAlert: true });
 | 
						|
 | 
						|
//     if (users.length === 0) {
 | 
						|
//       console.log("No users to notify at this time.");
 | 
						|
//       return;
 | 
						|
//     }
 | 
						|
 | 
						|
//     for (const user of users) {
 | 
						|
//       const { customerId, fcmIds } = user;
 | 
						|
 | 
						|
//       if (!Array.isArray(fcmIds) || fcmIds.length === 0) {
 | 
						|
//         console.log(`No valid FCM tokens for customer ID: ${customerId}`);
 | 
						|
//         continue;
 | 
						|
//       }
 | 
						|
 | 
						|
//       // Get tanks associated with the user
 | 
						|
//       const tanks = await Tank.find({ customerId });
 | 
						|
 | 
						|
//       for (const tank of tanks) {
 | 
						|
//         const {
 | 
						|
//           tankName,
 | 
						|
//           tankLocation,
 | 
						|
//           typeOfWater,
 | 
						|
//           capacity,
 | 
						|
//           waterlevel,
 | 
						|
//         } = tank;
 | 
						|
 | 
						|
//         // Remove commas before parsing numbers
 | 
						|
//         const tankCapacity = parseFloat(capacity.replace(/,/g, '')) || 0;
 | 
						|
//         const currentWaterLevel = parseFloat(waterlevel.replace(/,/g, '')) || 0;
 | 
						|
 | 
						|
//         if (tankCapacity === 0) {
 | 
						|
//           console.log(`Skipping tank ${tankName} due to zero capacity`);
 | 
						|
//           continue;
 | 
						|
//         }
 | 
						|
 | 
						|
//         const currentWaterLevelPercentage = ((currentWaterLevel / tankCapacity) * 100).toFixed(2);
 | 
						|
 | 
						|
//         // Send notification only if water level is below 10%
 | 
						|
//         if (currentWaterLevelPercentage < 10) {
 | 
						|
//           let notificationBody =
 | 
						|
//             `🚨 *Critical Low Water Alert!*\n\n` +
 | 
						|
//             `🛢️ *Tank Name:* ${tankName}\n` +
 | 
						|
//             `🏢 *Location:* ${tankLocation}\n` +
 | 
						|
//             `💧 *Type of Water:* ${typeOfWater}\n` +
 | 
						|
//             `🔴 *Current Water Level:* ${currentWaterLevel} liters (${currentWaterLevelPercentage}%)\n\n` +
 | 
						|
//             `⚠️ Immediate action is recommended to avoid water shortage.`;
 | 
						|
 | 
						|
//           await sendNotification(customerId, fcmIds, "Critical Low Water Level Alert", notificationBody);
 | 
						|
//           console.log(`Critical low water level notification sent for tank: ${tankName}`);
 | 
						|
//         } else {
 | 
						|
//           console.log(`Skipping tank ${tankName}, water level is above 10%`);
 | 
						|
//         }
 | 
						|
//       }
 | 
						|
//     }
 | 
						|
 | 
						|
//     console.log("Critical low water level notifications processed.");
 | 
						|
//   } catch (err) {
 | 
						|
//     console.error("Error in critical water level calculation:", err);
 | 
						|
//   }
 | 
						|
// };
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// Run the function every minute to check if any user needs a notification
 | 
						|
// cron.schedule('* * * * *', async () => {
 | 
						|
//   console.log("Checking for user notification times...");
 | 
						|
//   await calculateWaterLevelAndNotify();
 | 
						|
// }, {
 | 
						|
//   timezone: "Asia/Kolkata",
 | 
						|
// });
 | 
						|
 | 
						|
//run the every one hour
 | 
						|
// cron.schedule('0 */3 * * *', async () => {  
 | 
						|
//   console.log("Checking for user notification times...");
 | 
						|
//   await calculateLowWaterLevelAndNotify();
 | 
						|
//   await calculateCriticalLowWaterLevelAndNotify();
 | 
						|
// }, {
 | 
						|
//   timezone: "Asia/Kolkata",
 | 
						|
// });
 | 
						|
 | 
						|
 | 
						|
// 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
 | 
						|
//   }
 | 
						|
// );
 | 
						|
 | 
						|
// Schedule a function to run every minute
 | 
						|
// cron.schedule('* * * * *', async () => {
 | 
						|
//   console.log("Checking for user notification times...");
 | 
						|
//   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" });
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
exports.notificationTiming = async (req, reply) => {
 | 
						|
  const { customerId, notificationPreference } = req.body;
 | 
						|
  
 | 
						|
  if (!["never", "always", "6_hours", "8_hours", "1_month"].includes(notificationPreference)) {
 | 
						|
    return reply.status(400).send({ message: "Invalid preference" });
 | 
						|
  }
 | 
						|
 | 
						|
  await User.updateOne({ customerId }, { notificationPreference });
 | 
						|
 | 
						|
  return reply.send({ message: "Preference updated successfully" });
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
exports.adjustMeasurement = async (req, reply) => {
 | 
						|
  try {
 | 
						|
      const { tankName, measuredHeight } = req.body;
 | 
						|
 | 
						|
      if (!tankName || measuredHeight === undefined) {
 | 
						|
          return reply.status(400).send({ message: "Tank name and measured height are required." });
 | 
						|
      }
 | 
						|
 | 
						|
      // Fetch tank details using tankName
 | 
						|
      const tank = await Tank.findOne({ tankName });
 | 
						|
 | 
						|
      if (!tank) {
 | 
						|
          return reply.status(404).send({ message: "Tank not found." });
 | 
						|
      }
 | 
						|
 | 
						|
      const originalHeight = parseFloat(tank.height);  // Example: 5.8 feet
 | 
						|
      const waterCapacityPerCm = parseFloat(tank.waterCapacityPerCm); // Example: 87 L/cm
 | 
						|
      const actualWaterLevel = parseFloat(tank.waterlevel); // Current water level in tank (liters)
 | 
						|
      const capacity = parseFloat(tank.capacity.replace(/,/g, ""));
 | 
						|
 | 
						|
      console.log("originalHeight",originalHeight)
 | 
						|
      console.log("waterCapacityPerCm",waterCapacityPerCm)
 | 
						|
      console.log("actualWaterLevel",actualWaterLevel)
 | 
						|
      console.log("capacity",capacity)
 | 
						|
 | 
						|
 | 
						|
      // Perform calculations
 | 
						|
      const heightDifference = originalHeight - measuredHeight;
 | 
						|
      const heightDifferenceInCm = heightDifference * 30.48; // Convert feet to cm
 | 
						|
      const calculatedWaterLevel = heightDifferenceInCm * waterCapacityPerCm; // Estimated water level in liters
 | 
						|
 | 
						|
      console.log("heightDifference",heightDifference)
 | 
						|
      console.log("heightDifferenceInCm",heightDifferenceInCm)
 | 
						|
      console.log("calculatedWaterLevel",calculatedWaterLevel)
 | 
						|
 | 
						|
      // **Ensure actualWaterLevel and calculatedWaterLevel do not exceed tank capacity**
 | 
						|
      const boundedActualWaterLevel = Math.min(actualWaterLevel, capacity);
 | 
						|
      const boundedCalculatedWaterLevel = Math.min(calculatedWaterLevel, capacity);
 | 
						|
 | 
						|
      console.log("boundedActualWaterLevel",boundedActualWaterLevel)
 | 
						|
      console.log("boundedCalculatedWaterLevel",boundedCalculatedWaterLevel)
 | 
						|
 | 
						|
      // Calculate original and calculated percentages correctly
 | 
						|
      const originalPercentage = (boundedActualWaterLevel / capacity) * 100;
 | 
						|
      const calculatedPercentage = (boundedCalculatedWaterLevel / capacity) * 100;
 | 
						|
 | 
						|
      // Calculate percentage difference
 | 
						|
      const percentageDifference = Math.abs(originalPercentage - calculatedPercentage);
 | 
						|
      let message;
 | 
						|
      if (percentageDifference  === originalPercentage) { 
 | 
						|
          message = "Tank details and measurement details match.";
 | 
						|
      } else {
 | 
						|
          message = "Please check the tank measurement.";
 | 
						|
      }
 | 
						|
 | 
						|
      reply.send({
 | 
						|
          status_code: 200,
 | 
						|
          data: {
 | 
						|
              tankName,
 | 
						|
              originalHeight,
 | 
						|
              measuredHeight,
 | 
						|
              heightDifference: heightDifference.toFixed(2),
 | 
						|
              heightDifferenceInCm: heightDifferenceInCm.toFixed(2),
 | 
						|
              calculatedWaterLevel: calculatedWaterLevel.toFixed(2),
 | 
						|
              actualWaterLevel: actualWaterLevel.toFixed(2),
 | 
						|
              originalPercentage: originalPercentage.toFixed(2) + "%",
 | 
						|
              calculatedPercentage: calculatedPercentage.toFixed(2) + "%",
 | 
						|
              percentageDifference: percentageDifference.toFixed(2) + "%",
 | 
						|
              message
 | 
						|
          }
 | 
						|
      });
 | 
						|
 | 
						|
  } catch (err) {
 | 
						|
      reply.status(500).send({ message: err.message });
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
exports.validateTankHeight = async (req, reply) => {
 | 
						|
  try {
 | 
						|
      const { hardwareId, tankhardwareId } = req.params;
 | 
						|
 | 
						|
      if (!tankhardwareId || !hardwareId) {
 | 
						|
          return reply.status(400).send({ message: "Both tankhardwareId and hardwareId are required." });
 | 
						|
      }
 | 
						|
 | 
						|
      // Find tank details from tanksSchema
 | 
						|
      const tank = await Tank.findOne({ tankhardwareId, hardwareId });
 | 
						|
 | 
						|
      if (!tank) {
 | 
						|
          return reply.status(404).send({ message: "Tank not found with the given tankhardwareId and hardwareId." });
 | 
						|
      }
 | 
						|
 | 
						|
      // Find corresponding IoT data from IOttankSchema
 | 
						|
      const iotTank = await IotData.findOne({ hardwareId, "tanks.tankhardwareId": tankhardwareId });
 | 
						|
 | 
						|
      if (!iotTank) {
 | 
						|
          return reply.status(404).send({ message: "IoT tank data not found for the given hardwareId and tankhardwareId." });
 | 
						|
      }
 | 
						|
 | 
						|
      // Convert tank height from feet to cm
 | 
						|
      const heightInCm = parseFloat(tank.height) * 30.48;
 | 
						|
      const iotTankHeight = parseFloat(iotTank.tanks.find(t => t.tankhardwareId === tankhardwareId).tankHeight);
 | 
						|
 | 
						|
      console.log("Converted Tank Height (cm):", heightInCm);
 | 
						|
      console.log("IoT Tank Height (cm):", iotTankHeight);
 | 
						|
 | 
						|
      // Check for extreme values
 | 
						|
      if (heightInCm < iotTankHeight) {
 | 
						|
          return reply.status(400).send({ 
 | 
						|
              message: "Extreme high values detected! Tank height exceeds IoT data." 
 | 
						|
          });
 | 
						|
      }
 | 
						|
 | 
						|
      reply.send({ 
 | 
						|
          status_code: 200, 
 | 
						|
          message: "Tank height is within the valid range." 
 | 
						|
      });
 | 
						|
 | 
						|
  } catch (err) {
 | 
						|
      reply.status(500).send({ message: err.message });
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
exports.getActualWaterLevelInCm = async (req, reply) => {
 | 
						|
  try {
 | 
						|
      const { tankName } = req.params;
 | 
						|
 | 
						|
      if (!tankName) {
 | 
						|
          return reply.status(400).send({ message: "Tank name is required." });
 | 
						|
      }
 | 
						|
 | 
						|
      // Fetch tank details using tankName
 | 
						|
      const tank = await Tank.findOne({ tankName });
 | 
						|
 | 
						|
      if (!tank) {
 | 
						|
          return reply.status(404).send({ message: "Tank not found." });
 | 
						|
      }
 | 
						|
 | 
						|
      const actualWaterLevel = parseFloat(tank.waterlevel); // Current water level in liters
 | 
						|
      const waterCapacityPerCm = parseFloat(tank.waterCapacityPerCm); // Liters per cm
 | 
						|
 | 
						|
      if (!actualWaterLevel || !waterCapacityPerCm) {
 | 
						|
          return reply.status(400).send({ message: "Tank data is incomplete for conversion." });
 | 
						|
      }
 | 
						|
 | 
						|
      // Convert actual water level from liters to cm
 | 
						|
      const actualWaterLevelInCm = actualWaterLevel / waterCapacityPerCm;
 | 
						|
 | 
						|
      reply.send({
 | 
						|
          status_code: 200,
 | 
						|
          data: {
 | 
						|
              tankName,
 | 
						|
              actualWaterLevel: actualWaterLevel.toFixed(2) + " L",
 | 
						|
              actualWaterLevelInCm: actualWaterLevelInCm.toFixed(2) + " cm"
 | 
						|
          }
 | 
						|
      });
 | 
						|
 | 
						|
  } catch (err) {
 | 
						|
      reply.status(500).send({ message: err.message });
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
exports.compareMeasuredHeight = async (req, reply) => {
 | 
						|
  try {
 | 
						|
    const { measuredHeight, tankName } = req.body;
 | 
						|
 | 
						|
    if (!tankName || measuredHeight === undefined) {
 | 
						|
      return reply.status(400).send({ message: "Tank name and measured height are required." });
 | 
						|
    }
 | 
						|
 | 
						|
    // Convert measuredHeight to a number
 | 
						|
    const measuredHeightNum = parseFloat(measuredHeight);
 | 
						|
    if (isNaN(measuredHeightNum)) {
 | 
						|
      return reply.status(400).send({ message: "Invalid measuredHeight. It must be a number." });
 | 
						|
    }
 | 
						|
 | 
						|
    // Fetch tank details using tankName
 | 
						|
    const tank = await Tank.findOne({ tankName });
 | 
						|
 | 
						|
    if (!tank) {
 | 
						|
      return reply.status(404).send({ message: "Tank not found." });
 | 
						|
    }
 | 
						|
 | 
						|
    const actualWaterLevel = parseFloat(tank.waterlevel); // Current water level in liters
 | 
						|
    const waterCapacityPerCm = parseFloat(tank.waterCapacityPerCm); // Liters per cm
 | 
						|
 | 
						|
    if (isNaN(actualWaterLevel) || isNaN(waterCapacityPerCm)) {
 | 
						|
      return reply.status(400).send({ message: "Tank data is incomplete for conversion." });
 | 
						|
    }
 | 
						|
 | 
						|
    // Convert actual water level from liters to cm
 | 
						|
    const actualWaterLevelInCm = actualWaterLevel / waterCapacityPerCm;
 | 
						|
 | 
						|
    // Calculate difference between measured and actual water level in cm
 | 
						|
    const heightDifferenceInCm = Math.abs(actualWaterLevelInCm - measuredHeightNum);
 | 
						|
 | 
						|
    let message;
 | 
						|
    if (heightDifferenceInCm <= 10) {  // Within 10 cm is considered a match
 | 
						|
      message = "Measured height is within an acceptable range of actual water level.";
 | 
						|
    } else {
 | 
						|
      message = "Measured height differs significantly from actual water level.";
 | 
						|
    }
 | 
						|
 | 
						|
    reply.send({
 | 
						|
      status_code: 200,
 | 
						|
      data: {
 | 
						|
        tankName,
 | 
						|
        measuredHeight: measuredHeightNum.toFixed(2) + " cm",
 | 
						|
        actualWaterLevelInCm: actualWaterLevelInCm.toFixed(2) + " cm",
 | 
						|
        heightDifferenceInCm: heightDifferenceInCm.toFixed(2) + " cm",
 | 
						|
        message
 | 
						|
      }
 | 
						|
    });
 | 
						|
 | 
						|
  } catch (err) {
 | 
						|
    console.error("Error in compareMeasuredHeight:", err);
 | 
						|
    reply.status(500).send({ message: err.message });
 | 
						|
  }
 | 
						|
};
 |