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.

7616 lines
293 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

//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"] } }),
});
const filteredConsumptions = tankConsumptions.filter((record) => {
const recordTime = moment(record.time, "DD-MMM-YYYY - HH:mm").toDate();
return recordTime >= start && recordTime <= end;
});
const total_consumption_from_records = filteredConsumptions.reduce((acc, record) => {
return acc + parseInt(record.consumption, 10);
}, 0);
const consumption = (waterlevel_at_midnight + total_water_added_from_midnight) - waterlevel + total_consumption_from_records;
totalConsumptionForSelectedBlockAndTypeOfWater += consumption;
// Add to the total consumption and capacities based on water type
if (tank.typeOfWater === "bore" || tank.typeOfWater === "Bore Water") {
totalBoreConsumptionForSelectedBlockAndTypeOfWater += consumption;
totalBoreCapacityForSelectedBlockAndTypeOfWater += capacity;
} else if (tank.typeOfWater === "drinking" || tank.typeOfWater === "Drinking Water") {
totalDrinkingConsumptionForSelectedBlockAndTypeOfWater += consumption;
totalDrinkingCapacityForSelectedBlockAndTypeOfWater += capacity;
}
tankData.push({
tankname,
totalConsumption: consumption,
block: tank.blockName,
TypeofWater: tank.typeOfWater,
location: tank.tankLocation,
capacity: tank.capacity,
waterlevel: tank.waterlevel,
});
tankconsumptionData.push({
tankname,
consumptionRecordsdatewise: filteredConsumptions,
});
}
// Calculate total consumption percentages
const boreConsumptionPercentage = totalBoreCapacityForSelectedBlockAndTypeOfWater
? ((totalBoreConsumptionForSelectedBlockAndTypeOfWater / totalBoreCapacityForSelectedBlockAndTypeOfWater) * 100).toFixed(2)
: 0;
const drinkingConsumptionPercentage = totalDrinkingCapacityForSelectedBlockAndTypeOfWater
? ((totalDrinkingConsumptionForSelectedBlockAndTypeOfWater / totalDrinkingCapacityForSelectedBlockAndTypeOfWater) * 100).toFixed(2)
: 0;
const totalConsumptionPercentage =
typeofwater === "bore"
? boreConsumptionPercentage
: typeofwater === "drinking"
? drinkingConsumptionPercentage
: ((totalBoreConsumptionForSelectedBlockAndTypeOfWater + totalDrinkingConsumptionForSelectedBlockAndTypeOfWater) /
(totalBoreCapacityForSelectedBlockAndTypeOfWater + totalDrinkingCapacityForSelectedBlockAndTypeOfWater) *
100
).toFixed(2);
// Include the total consumption in the response
// Construct the response
const response = {
status_code: 200,
tankData,
consumptiorecordsdatewise: tankconsumptionData,
totalConsumptionPercentage,
totalConsumptionPercentageForBore: typeofwater !== "drinking" ? boreConsumptionPercentage : 0,
totalConsumptionPercentageForDrinking: typeofwater !== "bore" ? drinkingConsumptionPercentage : 0,
totalConsumptionForBore: typeofwater !== "drinking" ? totalBoreConsumptionForSelectedBlockAndTypeOfWater : 0,
totalConsumptionForDrinking: typeofwater !== "bore" ? totalDrinkingConsumptionForSelectedBlockAndTypeOfWater : 0,
[`total consumption of 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 })
});
const filteredConsumptions = tankConsumptions.filter((record) => {
const recordTime = moment(record.time, "DD-MMM-YYYY - HH:mm").toDate();
return recordTime >= start && recordTime <= end;
});
// filteredConsumptions.forEach(record => {
// totalConsumed += parseInt(record.consumption, 10);
// totalAvailableCapacity += parseInt(record.capacity, 10);
// });
for (const record of filteredConsumptions) {
const recordTime = moment(record.time, "DD-MMM-YYYY - HH:mm").format("DD-MMM-YYYY - HH:mm");
const tank_info = await Tank.findOne({
customerId:record.customerId,
tankName: record.tankName,
tankLocation: record.tankLocation,
});
totalConsumptionForSelectedBlockAndTypeOfWater+=parseInt(record.consumption, 10);
totalConsumed += parseInt(record.consumption, 10);
;
// console.log( parseInt(tank_info.capacity.replace(/,/g, ''), 10))
totalAvailableCapacity += parseInt(tank_info.capacity.replace(/,/g, ''), 10)
if (!tankconsumptionData[recordTime]) {
tankconsumptionData[recordTime] = {
date: recordTime,
consumptionRecordsdatewise: [],
count: 0
};
}
const recordExists = tankconsumptionData[recordTime].consumptionRecordsdatewise.some(r => r.tankName === record.tankName);
if (!recordExists) {
tankconsumptionData[recordTime].consumptionRecordsdatewise.push({
tankName: record.tankName,
consumption: record.consumption,
available_capacity: record.available_capacity,
time: record.time
});
tankconsumptionData[recordTime].count++;
}
}
}
const responseData = Object.values(tankconsumptionData);
const totalConsumptionPercentage = totalAvailableCapacity > 0 ? ((totalConsumed / totalAvailableCapacity) * 100).toFixed(2) : "0";
console.log(totalConsumed,"totalConsumed",totalAvailableCapacity,"totalAvailableCapacity",totalConsumptionForSelectedBlockAndTypeOfWater,"totalConsumptionForSelectedBlockAndTypeOfWater")
const response = {
status_code: 200,
consumptiorecordsdatewise: responseData,
[`total consumption of ${typeofwater} and selected block`]: totalConsumptionForSelectedBlockAndTypeOfWater,
totalConsumptionPercentage: `${totalConsumptionPercentage}%`
};
reply.send(response);
} catch (err) {
throw boom.boomify(err);
}
};
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
//const moment = require('moment'); // Import moment.js for date/time operations
const formatDate = (date) => {
const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
const day = String(date.getDate()).padStart(2, '0');
const month = months[date.getMonth()];
const year = date.getFullYear();
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
return `${day}-${month}-${year} - ${hours}:${minutes}`;
};
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 Water Management", 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 Water Management", message);
} catch (error) {
console.error("Error in motorStop event:", error);
}
}
);
eventEmitter.on(
'motorStartAutomatic',
async (fcmTokens, tankName, blockName, startTime, motorOnType, manual_threshold_time, typeOfWater,threshold) => {
try {
// Retrieve the user information
const users = await User.find({ fcmIds: { $in: fcmTokens } });
console.log("users", users);
const userNames = users.map(user => user.username).join(', ');
console.log("userNames", userNames);
const startMethod = motorOnType === "Automatic" ? "Automatic" : "Manual";
// Generate motor name dynamically based on tank name, block name, and type of water
const motorName = `${tankName}-${blockName}-${typeOfWater}`;
// Get current date and time for the motor start time
const currentDateTime = new Date();
const formattedDate = currentDateTime.toLocaleDateString(); // Customize this format as needed
const formattedTime = currentDateTime.toLocaleTimeString(); // Customize this format as needed
// Prepare the message
const message =
`🚰 Motor Name: ${motorName}\n` +
`🛢️ Tank Name: '${tankName}'\n` +
`🏢 Block Name: '${blockName}'\n` +
`👤 Started by: '${startMethod}' \n` +
`📱 Mode: "Atomatic System" \n` +
`🕒 Pump started at: ${startTime} \n` +
`Will stop after: '${threshold}' `;
// Send the notification
await sendNotification(fcmTokens, 'Arminta Water Management', message);
} catch (error) {
console.error('Error in motorStart event:', error);
}
}
);
eventEmitter.on('sendHighWaterNotification', async (fcmTokens, tankInfo, startTime, stopTime) => {
const message = `Attention: Water level in '${tankInfo.tankName}' located at '${tankInfo.tankLocation}' is high at ${tankInfo.waterLevel}% (${tankInfo.volumeInLitres} L). Please stop the motor. Motor running from ${startTime} to ${stopTime}.`;
await sendNotification(fcmTokens, 'High Water Level', message, 'Stop Motor');
});
// Event listener for very high water level notification
eventEmitter.on('sendVeryHighWaterNotification', async (fcmTokens, tankInfo, startTime, stopTime) => {
const message = `Attention: Water level in '${tankInfo.tankName}' located at '${tankInfo.tankLocation}' is very high at ${tankInfo.waterLevel}% (${tankInfo.volumeInLitres} L). Please stop the motor. Motor running from ${startTime} to ${stopTime}.`;
await sendNotification(fcmTokens, 'Very High Water Level', message, 'Stop Motor');
});
// Event listener for critically high water level notification
eventEmitter.on('sendCriticalHighWaterNotification', async (fcmTokens, tankInfo, startTime, stopTime) => {
const message = `Attention: Water level in '${tankInfo.tankName}' located at '${tankInfo.tankLocation}' is critically high at ${tankInfo.waterLevel}% (${tankInfo.volumeInLitres} L). Water may overflow. Please stop the motor. Motor running from ${startTime} to ${stopTime}.`;
await sendNotification(fcmTokens, 'Critical High Water Level', message, 'Stop Motor');
});
// Emit high water level event with motorId
// eventEmitter.on('highWaterLevel', async (fcmTokens, timestamp, motorId, waterLevel) => {
// await sendNotification(fcmTokens, 'High Water Level', `Motor ID: ${motorId}, water level reached above 90% at ${timestamp}. Current Water Level: ${waterLevel} Ltrs`);
// });
// eventEmitter.on('sendThresholdTimeNotification', async (fcmTokens, message) => {
// try {
// await sendNotification(fcmTokens, 'Threshold Time Reached', message, 'Motor Alert');
// console.log("Threshold time notification sent successfully.");
// } catch (error) {
// console.error("Error sending threshold time notification:", error);
// }
// });
eventEmitter.on('sendThresholdTimeNotification', async (customerId, fcmTokens, thresholdTime, hw_Id) => {
try {
const message = `Motor has reached its time threshold of ${thresholdTime} minutes and will stop.`;
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, stopCriteria, typeOfWater, manualThresholdTime) => {
try {
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);
}
});
// 🛑 Motor Stop Notification
eventEmitter.on("sendMotorStopNotification", async (hw_Id, customerId, fcmTokens, waterLevel, blockName, tankName, motorOnType, typeOfWater) => {
try {
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', (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, 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) => {
const payload = {
topic: 'operation',
object: {
'motor-id': motor_id,
control: motor_stop_status
}
};
console.log("enetred publish")
console.log(payload)
client.publish('water/operation', JSON.stringify(payload));
};
const stat_stop_intervals = {};
// exports.motorAction = async (req, reply) => {
// try {
// const customerId = req.params.customerId;
// const action = req.body.action;
// const motorId = req.body.motor_id;
// const start_instance_id = req.body.start_instance_id
// console.log(req.body.startTime)
// // Ensure motor_id is provided
// if (!motorId) {
// throw new Error("Motor ID is required.");
// }
// const users = await User.find({ customerId: customerId });
// const fcmToken = users.map(user => user.fcmId).filter(fcmId => fcmId);
// console.log(fcmToken)
// // Determine the motor stop status based on the action
// let motorStopStatus;
// if (action === "start") {
// motorStopStatus = "2"; // If action is start, set stop status to "2"
// // eventEmitter.emit('motorStart', fcmToken); // Emit motor start event
// emitWithTimestamp('motorStart', fcmToken); // Emit motor start event with timestamp
// console.log( eventEmitter.emit('motorStart', fcmToken))
// } else if (action === "stop") {
// motorStopStatus = "1"; // If action is stop, set stop status to "1"
// // eventEmitter.emit('motorStop', fcmToken); // Emit motor stop event
// emitWithTimestamp('motorStop', fcmToken); // Emit motor stop event with timestamp
// } else {
// throw new Error("Invalid action provided.");
// }
// // Update the motor stop status immediately if action is stop
// if (action === "stop") {
// // Update the motor stop status and other fields
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// {
// $set: {
// "connections.inputConnections.$.motor_stop_status": "1",
// "connections.inputConnections.$.stopTime": req.body.stopTime,
// "connections.inputConnections.$.threshold_type": null,
// "connections.inputConnections.$.manual_threshold_time": null,
// "connections.inputConnections.$.manual_threshold_percentage": null
// }
// }
// );
// reply.code(200).send({ message: "Motor stopped successfully." });
// // Perform stop operations in the background
// (async () => {
// await delay(300000);
// // Update the existing motor data entry with stop details
// const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id });
// if (motorData) {
// const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() });
// const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10);
// const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10);
// const water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10);
// const totalwaterpumped = quantityDelivered + water_pumped_till_now;
// await Tank.findOneAndUpdate(
// { customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() },
// { $set: { total_water_added_from_midnight: totalwaterpumped } }
// );
// await MotorData.updateOne(
// { customerId, motor_id: motorId, start_instance_id: start_instance_id },
// {
// $set: {
// stopTime: req.body.stopTime,
// receiverfinalwaterlevel: receiverFinalWaterLevel.toString(),
// quantity_delivered: quantityDelivered.toString()
// }
// }
// );
// }
// })();
// // Return here to ensure the rest of the code is not executed for the stop action
// return;
// } else {
// // Update the motor stop status to "2" for start action
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// { $set: { "connections.inputConnections.$.motor_stop_status": "2" } }
// );
// }
// // Check threshold settings if action is start
// if (action === "start") {
// if (req.body.threshold_type === "time") {
// // If threshold type is time, update threshold time
// // await Tank.updateOne(
// // { customerId, "connections.inputConnections.motor_id": motorId },
// // { $set: { "connections.inputConnections.$.manual_threshold_time": req.body.manual_threshold_time,startTime:req.body.startTime } }
// // );
// const receiver_tank_info7 = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() });
// const newMotorData = new MotorData({
// customerId: customerId,
// motor_id: motorId,
// start_instance_id: start_instance_id,
// supplierTank: req.body.from,
// receiverTank: req.body.to,
// supplier_type: req.body.from_type,
// receiver_type: req.body.to_type,
// startTime: req.body.startTime,
// receiverInitialwaterlevel:parseInt(receiver_tank_info7.waterlevel, 10)
// });
// await newMotorData.save();
// for await (const tank of Tank.find({ "connections.inputConnections.motor_id": motorId })) {
// const index = tank.connections.inputConnections.findIndex(connection => connection.motor_id === motorId);
// if (index !== -1) {
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// { $set: { [`connections.inputConnections.${index}.manual_threshold_time`]: req.body.manual_threshold_time, [`connections.inputConnections.${index}.startTime`]: req.body.startTime,[`connections.inputConnections.${index}.start_instance_id`]: start_instance_id } }
// );
// }
// }
// // Start monitoring water level based on threshold time
// const thresholdTime = moment().add(req.body.manual_threshold_time, 'minutes').toDate();
// const intervalId = setInterval(async () => {
// const splr_tank_info3 = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() });
// const splr_tank_info3_waterlevel = parseInt(splr_tank_info3.waterlevel, 10);
// //console.log(splr_tank_info3_waterlevel,"splr_tank_info3_waterlevel")
// const splr_tank_info3_capacity = parseInt(splr_tank_info3.capacity.replace(/,/g, ''), 10);
// // const splr_tank_info3_capacity = parseInt(splr_tank_info3.capacity, 10);
// // console.log(splr_tank_info3.capacity,splr_tank_info3_capacity,"splr_tank_info3_capacity")
// const splr_tank_info3_percentage = (splr_tank_info3_waterlevel / splr_tank_info3_capacity) * 100;
// // console.log(splr_tank_info3_percentage, "percentage for less than 20");
// if (new Date() >= thresholdTime || splr_tank_info3_percentage <= 20) {
// console.log(splr_tank_info3_percentage,)
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// {
// $set: {
// "connections.inputConnections.$.motor_stop_status": "1",
// "connections.inputConnections.$.threshold_type": null,
// "connections.inputConnections.$.manual_threshold_time": null,
// "connections.inputConnections.$.manual_threshold_percentage": null
// }
// }
// );
// clearInterval(intervalId);
// await delay(300000);
// const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id });
// if (motorData) {
// const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() });
// const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10);
// const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10);
// const water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10);
// const totalwaterpumped = quantityDelivered + water_pumped_till_now
// await Tank.findOneAndUpdate({customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase()}, { $set: { total_water_added_from_midnight: totalwaterpumped } })
// const stopTime = formatDate(new Date());
// await MotorData.updateOne(
// { customerId, motor_id: motorId, start_instance_id: start_instance_id },
// {
// $set: {
// stopTime:stopTime,
// receiverfinalwaterlevel: receiverFinalWaterLevel.toString(),
// quantity_delivered: quantityDelivered.toString()
// }
// }
// );
// }
// }
// }, 60000);
// } else if (req.body.threshold_type === "litres") {
// console.log("entered litres")
// const receiver_tank_info7 = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() });
// const newMotorData = new MotorData({
// customerId: customerId,
// motor_id: motorId,
// start_instance_id: start_instance_id,
// supplierTank: req.body.from,
// receiverTank: req.body.to,
// supplier_type: req.body.from_type,
// receiver_type: req.body.to_type,
// startTime: req.body.startTime,
// receiverInitialwaterlevel:parseInt(receiver_tank_info7.waterlevel, 10)
// });
// await newMotorData.save();
// // If threshold type is percentage, calculate percentage threshold
// const receiver_tank_info = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() });
// const supplier_tank_info = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() });
// if (!receiver_tank_info) {
// throw new Error("Receiver tank not found.");
// }
// if (!supplier_tank_info) {
// throw new Error("Supplierr tank not found.");
// }
// const supplier_capacity = parseInt(supplier_tank_info.capacity, 10);
// const supplier_waterLevel = parseInt(supplier_tank_info.waterlevel, 10);
// const capacity = parseInt(receiver_tank_info.capacity, 10);
// const waterLevel = parseInt(receiver_tank_info.waterlevel, 10);
// const desired_percentage = parseInt(req.body.manual_threshold_litres.replace(/,/g, ''), 10);
// console.log(desired_percentage)
// const threshold_water_level = waterLevel+desired_percentage;
// const supplier_threshold = supplier_waterLevel-desired_percentage
// console.log(supplier_threshold,"supplier_threshold")
// for await (const tank of Tank.find({ "connections.inputConnections.motor_id": motorId })) {
// const index = tank.connections.inputConnections.findIndex(connection => connection.motor_id === motorId);
// if (index !== -1) {
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// { $set: { [`connections.inputConnections.${index}.manual_threshold_percentage`]: supplier_threshold.toString(), [`connections.inputConnections.${index}.startTime`]: req.body.startTime } }
// );
// }
// }
// // Update water level threshold
// // Start monitoring water level based on threshold percentage
// const intervalId = setInterval(async () => {
// // Check if water level has reached the threshold percentage
// const supplier_tank_info1 = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() });
// const current_water_level = parseInt(supplier_tank_info1.waterlevel, 10);
// if (current_water_level <= supplier_threshold) {
// // Stop the motor pump
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// {
// $set: {
// "connections.inputConnections.$.motor_stop_status": "1",
// "connections.inputConnections.$.threshold_type": null,
// "connections.inputConnections.$.manual_threshold_time": null,
// "connections.inputConnections.$.manual_threshold_percentage": null
// }
// }
// );
// clearInterval(intervalId); // Stop monitoring water level
// await delay(300000);
// const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id });
// if (motorData) {
// const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() });
// const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10);
// const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10);
// const stopTime = formatDate(new Date());
// await MotorData.updateOne(
// { customerId, motor_id: motorId, start_instance_id: start_instance_id },
// {
// $set: {
// stopTime:stopTime,
// receiverfinalwaterlevel: receiverFinalWaterLevel.toString(),
// quantity_delivered: quantityDelivered.toString()
// }
// }
// );
// }
// }
// }, 20000); // Check water level every minute
// }
// }
// // Respond with success message
// reply.code(200).send({ message: `Motor ${action === "start" ? "started" : "stopped"} successfully.` });
// } catch (err) {
// // Handle errors
// throw boom.boomify(err);
// }
// };
const notificationSentStatus = {
motorStart: false,
motorStop: false,
lowWater: false,
veryLowWater: false,
criticallyLowWater: false,
highWater: false,
veryHighWater: false,
criticallyHighWater: false,
};
let waterLevelCheckInterval; // To hold the interval ID
const checkWaterLevel = async (customerId, motorId, fcmToken, receiverTank) => {
const currentWaterLevel = parseInt(receiverTank.waterlevel, 10);
const tankCapacity = parseInt(receiverTank.capacity.replace(/,/g, ''), 10);
const currentWaterPercentage = (currentWaterLevel / tankCapacity) * 100;
// Check for low water levels
if (currentWaterPercentage <= 20 && !notificationSentStatus.lowWater) {
// eventEmitter.emit('sendLowWaterNotification', fcmToken, `Water level has dropped below 20%.`);
notificationSentStatus.lowWater = true;
}
// Check for critically low water levels
if (currentWaterPercentage <= 10 && !notificationSentStatus.criticallyLowWater) {
// eventEmitter.emit('sendCriticalLowWaterNotification', fcmToken, `Water level has dropped below 10%.`);
notificationSentStatus.criticallyLowWater = true;
}
};
// const checkWaterLevelsAndNotify = async (customerId, tankName, tankLocation, fcmTokens) => {
// try {
// // Fetch the tank details from the database
// const tank = await Tank.findOne({ customerId, tankName, tankLocation });
// if (!tank) {
// console.error(`Tank not found: ${tankName} at location ${tankLocation}`);
// return;
// }
// // Extract the current water level and capacity
// const currentWaterLevel = parseInt(tank.waterlevel, 10);
// const capacity = parseInt(tank.capacity.replace(/,/g, ''), 10);
// // Calculate the water level percentage
// const waterLevelPercentage = (currentWaterLevel / capacity) * 100;
// // Thresholds for notifications
// const thresholds = {
// criticallyLow: 10,
// veryLow: 20,
// low: 30,
// high: 70,
// veryHigh: 80,
// criticallyHigh: 85,
// };
// // Check water levels and send notifications
// if (waterLevelPercentage <= thresholds.criticallyLow && !notificationSentStatus.criticallyLowWater) {
// eventEmitter.emit('sendCriticalLowWaterNotification', fcmTokens, tank);
// notificationSentStatus.criticallyLowWater = true;
// await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentCritical: true } });
// } else if (waterLevelPercentage <= thresholds.veryLow && !notificationSentStatus.veryLowWater) {
// eventEmitter.emit('sendVeryLowWaterNotification', fcmTokens, tank);
// notificationSentStatus.veryLowWater = true;
// await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentVeryLow: true } });
// } else if (waterLevelPercentage <= thresholds.low && !notificationSentStatus.lowWater) {
// eventEmitter.emit('sendLowWaterNotification', fcmTokens, tank);
// notificationSentStatus.lowWater = true;
// await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentLow: true } });
// }
// // if (waterLevelPercentage <= thresholds.criticallyLow) {
// // eventEmitter.emit('sendCriticalLowWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentCritical: true } });
// // } else if (waterLevelPercentage <= thresholds.veryLow) {
// // eventEmitter.emit('sendVeryLowWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentVeryLow: true } });
// // } else if (waterLevelPercentage <= thresholds.low) {
// // eventEmitter.emit('sendLowWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentLow: true } });
// // }
// // else if (waterLevelPercentage >= thresholds.criticallyHigh) {
// // eventEmitter.emit('sendCriticalHighWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentCriticalHigh: true } });
// // } else if (waterLevelPercentage >= thresholds.veryHigh) {
// // eventEmitter.emit('sendVeryHighWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentVeryHigh: true } });
// // } else if (waterLevelPercentage >= thresholds.high) {
// // eventEmitter.emit('sendHighWaterNotification', fcmTokens, tank);
// // await Tank.updateOne({ customerId, tankName: tank.tankName }, { $set: { notificationSentHigh: true } });
// // }
// } catch (error) {
// console.error(`Error checking water levels for tank ${tankName}:`, error);
// }
// };
exports.getPumpsAndUsers = async (req, reply) => {
try {
const { customerId } = req.params;
// Fetch motor_id from inputConnections of all tanks for the customer
const tanks = await Tank.find({ customerId }, { "connections.inputConnections.motor_id": 1 });
const motorIds = tanks.flatMap((tank) =>
tank.connections?.inputConnections?.map((conn) => conn.motor_id).filter(Boolean) || []
);
// Fetch username and staff names from User collection
const user = await User.findOne({ customerId }, { username: 1, "staff.staff.name": 1 });
const staffNames = user?.staff?.staff?.map((s) => s.name) || [];
const username = user?.username || "";
// Include username at the beginning of staffNames and add "manual" at the end
const updatedStaffNames = ["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 monitorWaterLevels = async () => {
try {
const tanks = await Tank.find({});
// Iterate through each tank
for (const tank of tanks) {
// Fetch users associated with the customerId of the tank
const users = await User.find({ customerId: tank.customerId });
const fcmTokens = users
.map(user => user.fcmIds)
.filter(fcmIds => fcmIds)
.flat(); // Flatten if there are multiple fcmIds for each user
// Ensure that fcmTokens exist before proceeding
if (fcmTokens.length > 0) {
const customerId = tank.customerId;
const tankName = tank.tankName; // Assuming tank has a 'name' field
const tankLocation = tank.tankLocation; // Assuming tank has a 'location' field
// Call the function to check water levels and send notifications
//await checkWaterLevelsAndNotify(customerId, tankName, tankLocation, fcmTokens);
} else {
//console.log(`No FCM tokens found for customerId ${tank.customerId}`);
}
}
} catch (error) {
console.error('Error monitoring water levels:', error);
}
};
// Schedule the task to run every 30 minutes
setInterval(monitorWaterLevels, 30 * 60 * 1000);
const motorIntervals = {};
async function calculateTotalPumpedWater(customerId, motorId, start_instance_id) {
const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id });
if (motorData) {
const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() });
const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10);
const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10);
const waterPumpedTillNow = parseInt(receiverTank.total_water_added_from_midnight, 10);
return quantityDelivered + waterPumpedTillNow; // Total water pumped
}
return 0; // Return 0 if no data found
}
exports.motorAction = async (req, reply) => {
try {
const customerId = req.params.customerId;
const action = req.body.action;
const motorId = req.body.motor_id;
const start_instance_id = req.body.start_instance_id;
// Define thresholds for water levels
const lowWaterThreshold = 5; // Low water level percentage threshold
//const highWaterThreshold = 90; // High water level percentage threshold
const highWaterThreshold = 70; // High water level percentage threshold
const veryHighWaterThreshold = 80; // Very High water level percentage threshold
const criticalHighWaterThreshold = 85;
// Ensure motor_id is provided
if (!motorId) {
throw new Error("Motor ID is required.");
}
// Get user FCM tokens
const users = await User.findOne({ customerId });
console.log("users",users)
let loggedInUser = null;
if (users) {
if (users.phone === req.body.phone) {
loggedInUser = { role: "Customer", name: users.username, phone: users.phone };
} else if (users.staff && users.staff.staff) {
const staffMember = users.staff.staff.find(staff => staff.phone === req.body.phone);
if (staffMember) {
loggedInUser = { role: "Staff", name: staffMember.name, phone: staffMember.phone };
}
}
}
if (!loggedInUser) {
console.log("User not found. Cannot proceed with motorStart event.");
return reply.status(404).send({ error: "User not found" }); // ✅ FIX: Ensure a response is returned
}
const fcmToken = users.fcmIds ? users.fcmIds.filter(fcmIds => fcmIds) : [];
// const fcmToken = users.map(user => user.fcmIds).filter(fcmIds => fcmIds);
console.log(fcmToken)
const receiverTank = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() });
console.log(receiverTank)
const currentWaterLevel = parseInt(receiverTank.waterlevel, 10);
const waterLevelThresholds = { low: 30, veryLow: 20, criticallyLow: 10 };
const typeOfWater = receiverTank.typeOfWater;
console.log(typeOfWater,"typeOfWater")
// Determine the motor stop status based on the action
let motorStopStatus;
const blockName = req.body.from || "Unknown Block"; // Provide a fallback if `from` is missing
const tankName = req.body.to || "Unknown Tank"; // Provide a fallback if `to` is missing
const stopTime = req.body.stopTime
const motorOnType = "manual";
const manual_threshold_time = req.body.manual_threshold_time;
let hasNotifiedStart = false;
let hasNotifiedStop = false;
if (action === "start") {
motorStopStatus = "2";
const startTime = req.body.startTime;
await Tank.updateOne(
{ customerId, "connections.inputConnections.motor_id": motorId },
{ $set: { "connections.inputConnections.$.motor_stop_status": motorStopStatus } }
);
const thresholdTimeMs = req.body.manual_threshold_time * 60 * 1000; // Convert minutes to milliseconds
const stopCriteria =
motorOnType === "time"
? `${req.body.manual_threshold_time} minutes`
: `${req.body.manual_threshold_litres} litres`;
// await checkWaterLevelsAndNotify(customerId, tankName, receiverTank.tankLocation, fcmToken);
try {
// eventEmitter.emit("motorStart", customerId, fcmToken, tankName, blockName, startTime, "Mobile APP", manual_threshold_time, typeOfWater);
eventEmitter.emit(
"motorStart",
customerId,
fcmToken,
tankName,
blockName,
startTime,
"Mobile APP",
manual_threshold_time,
typeOfWater,
motorId,
loggedInUser.phone,
);
reply.code(200).send({ message: "Motor started successfully." });
} catch (error) {
console.error("Error in handleMotorStart:", error);
reply.code(500).send({ error: "Internal Server Error" });
}
// Start checking water level every 30 minutes
if (!waterLevelCheckInterval) {
waterLevelCheckInterval = setInterval(async () => {
await checkWaterLevel(customerId, motorId, fcmToken, receiverTank);
}, 30 * 60 * 1000); // 30 minutes
}
await Tank.updateOne(
{ customerId, "connections.inputConnections.motor_id": motorId },
{ $set: { "connections.inputConnections.$.motor_stop_status": "2",
"connections.inputConnections.$.manual_threshold_time": manual_threshold_time,
"connections.inputConnections.$.threshold_type": "time",
"connections.inputConnections.$.motor_on_type": "manual" } }
);
reply.code(200).send({ message: "Motor started successfully." });
const lowWaterThreshold = 5; // Adjust as needed
const thresholdTime = new Date(manual_threshold_time); // Convert threshold time
if (new Date() >= thresholdTime || currentWaterPercentage <= lowWaterThreshold) {
console.log("Motor stopping because it entered this condition");
eventEmitter.emit(
"sendThresholdTimeNotification",
customerId,
fcmToken,
manual_threshold_time,
motorId
);
}
console.log("Motor stopped");
} else if (action === "stop") {
motorStopStatus = "1"; // If action is stop, set stop status to "1"
try {
const totalWaterPumped = await calculateTotalPumpedWater(customerId, motorId, start_instance_id);
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" });
}
await Tank.updateOne(
{ customerId, "connections.inputConnections.motor_id": motorId },
{
$set: {
"connections.inputConnections.$.motor_stop_status": "1",
"connections.inputConnections.$.motor_on_type": motorOnType }
}
);
// Clear the interval when the motor is stopped
if (waterLevelCheckInterval) {
clearInterval(waterLevelCheckInterval);
waterLevelCheckInterval = null; // Reset the interval ID
}
} else {
throw new Error("Invalid action provided.");
}
// If action is stop, immediately update motor status and perform stop operations
if (action === "stop") {
console.log("enterted stop")
await Tank.updateOne(
{ customerId, "connections.inputConnections.motor_id": motorId },
{
$set: {
"connections.inputConnections.$.motor_stop_status": "1",
"connections.inputConnections.$.motor_on_type": "manual",
"connections.inputConnections.$.stopTime": req.body.stopTime,
"connections.inputConnections.$.threshold_type": null,
"connections.inputConnections.$.manual_threshold_time": null,
"connections.inputConnections.$.manual_threshold_percentage": null
}
}
);
if (motorIntervals[motorId]) {
console.log(motorIntervals[motorId],"deleted")
clearInterval(motorIntervals[motorId]); // Clear the interval
delete motorIntervals[motorId]; // Remove the interval from the object
}
this.publishMotorStopStatus(motorId, motorStopStatus);
// Send immediate response to the client
reply.code(200).send({ message: "Motor stopped successfully." });
// Perform stop operations in the background
(async () => {
console.log(start_instance_id,"start_instance_id",customerId,"customerId",motorId,"motorId")
const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id });
if (motorData) {
console.log("entered if in stop")
const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() });
const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10);
const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10);
const water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10);
const totalwaterpumped = quantityDelivered + water_pumped_till_now;
await Tank.findOneAndUpdate(
{ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() },
{ $set: { total_water_added_from_midnight: totalwaterpumped } }
);
await MotorData.updateOne(
{ customerId, motor_id: motorId, start_instance_id: start_instance_id },
{
$set: {
stopTime: req.body.stopTime,
receiverfinalwaterlevel: receiverFinalWaterLevel.toString(),
quantity_delivered: quantityDelivered.toString()
}
}
);
}
})();
return; // Return early to avoid executing the start logic
} else {
await Tank.updateOne(
{ customerId, "connections.inputConnections.motor_id": motorId },
{ $set: { "connections.inputConnections.$.motor_stop_status": "2" } }
);
}
// Check threshold settings if action is start
if (action === "start") {
if (req.body.threshold_type === "time") {
// Create a new MotorData entry
const receiverTank = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() });
const newMotorData = new MotorData({
customerId,
motor_id: motorId,
start_instance_id: start_instance_id,
supplierTank: req.body.from,
receiverTank: req.body.to,
supplier_type: req.body.from_type,
receiver_type: req.body.to_type,
startTime: req.body.startTime,
receiverInitialwaterlevel: parseInt(receiverTank.waterlevel, 10)
});
await newMotorData.save();
// Update the tank connections with start time and threshold time
for await (const tank of Tank.find({ "connections.inputConnections.motor_id": motorId })) {
this.publishMotorStopStatus(motorId, motorStopStatus);
for await (const tank of Tank.find({ "connections.inputConnections.motor_id": motorId })) {
const index = tank.connections.inputConnections.findIndex(connection => connection.motor_id === motorId);
if (index !== -1) {
await Tank.updateOne(
{ customerId, "connections.inputConnections.motor_id": motorId },
{
$set: {
[`connections.inputConnections.${index}.manual_threshold_time`]: req.body.manual_threshold_time,
[`connections.inputConnections.${index}.threshold_type`]: "time",
[`connections.inputConnections.${index}.startTime`]: req.body.startTime,
[`connections.inputConnections.${index}.start_instance_id`]: start_instance_id
}
}
);
}
}
const thresholdTime = new Date(new Date().getTime() + req.body.manual_threshold_time * 60000);
motorIntervals[motorId] = setInterval(async () => {
const supplierTank = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() });
const currentWaterLevel = parseInt(supplierTank.waterlevel, 10);
const currentWaterPercentage = (currentWaterLevel / parseInt(supplierTank.capacity.replace(/,/g, ''), 10)) * 100;
if (new Date() >= thresholdTime || currentWaterPercentage <= lowWaterThreshold) {
console.log(new Date(),"new date")
console.log(thresholdTime,"thresholdTime")
console.log("motor stopping because it entered this condition")
// Emit the threshold time notification
// eventEmitter.emit(
// "sendThresholdTimeNotification",
// fcmToken,
// `Motor has reached its time threshold of ${req.body.manual_threshold_time} minutes and will stop.`
// );
const currentTime = moment().tz('Asia/Kolkata').format('DD-MMM-YYYY - HH:mm');
await Tank.updateOne(
{ customerId, "connections.inputConnections.motor_id": motorId },
{
$set: {
"connections.inputConnections.$.motor_stop_status": "1",
"connections.inputConnections.$.threshold_type": null,
"connections.inputConnections.$.manual_threshold_time": null,
"connections.inputConnections.$.manual_threshold_percentage": null,
"connections.inputConnections.$.stopTime": currentTime,
}
}
);
// eventEmitter.emit('sendLowWaterNotification', fcmToken, receiverTank);
// console.log(motorIntervals[motorId],"deleted automatically") // Emit low water level notification
// clearInterval(motorIntervals[motorId]); // Clear interval
// delete motorIntervals[motorId];
// await checkWaterLevelsAndNotify(customerId, tankName, supplierTank.tankLocation, fcmToken);
// if (currentWaterPercentage >= highWaterThreshold && !notificationSentStatus.highWater) {
// eventEmitter.emit('sendHighWaterNotification', fcmToken, `Water level has reached high levels.`);
// notificationSentStatus.highWater = true; // Set flag to true to prevent duplicate notifications
// }
// if (currentWaterPercentage >= veryHighWaterThreshold && !notificationSentStatus.veryHighWater) {
// eventEmitter.emit('sendVeryHighWaterNotification', fcmToken, `Water level has reached very high levels.`);
// notificationSentStatus.veryHighWater = true; // Set flag to true to prevent duplicate notifications
// }
// if (currentWaterPercentage >= criticalHighWaterThreshold && !notificationSentStatus.criticallyHighWater) {
// eventEmitter.emit('sendCriticalHighWaterNotification', fcmToken, `Water level has reached critically high levels.`);
// notificationSentStatus.criticallyHighWater = true; // Set flag to true to prevent duplicate notifications
// }
clearInterval(motorIntervals[motorId]); // Stop the motor if condition met
delete motorIntervals[motorId]; // Remove from interval object
this.publishMotorStopStatus(motorId, "1");
console.log(start_instance_id,"start_instance_id",customerId,"customerId",motorId,"motorId")
const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id });
console.log(motorData,"motorData")
if (motorData) {
console.log("got into if")
const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() });
const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10);
const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10);
const water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10);
const totalwaterpumped = quantityDelivered + water_pumped_till_now;
await Tank.findOneAndUpdate(
{ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() },
{ $set: { total_water_added_from_midnight: totalwaterpumped } }
);
await MotorData.updateOne(
{ customerId, motor_id: motorId, start_instance_id: start_instance_id },
{
$set: {
stopTime: currentTime,
receiverfinalwaterlevel: receiverFinalWaterLevel.toString(),
quantity_delivered: quantityDelivered.toString()
}
}
);
}
}
// Check for high water level and send notification
// if (currentWaterPercentage >= highWaterThreshold) {
// // eventEmitter.emit('sendHighWaterNotification', fcmToken, receiverTank);
// await checkWaterLevelsAndNotify(customerId, tankName, supplierTank.tankLocation, fcmToken);
// }
}, 30000); // Check every minute
}
}else if (req.body.threshold_type === "litres") {
console.log("entered litres")
const receiver_tank_info7 = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() });
const supplier_tank_info7 = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() });
const newMotorData = new MotorData({
customerId: customerId,
motor_id: motorId,
start_instance_id: start_instance_id,
supplierTank: req.body.from,
receiverTank: req.body.to,
supplier_type: req.body.from_type,
receiver_type: req.body.to_type,
startTime: req.body.startTime,
receiverInitialwaterlevel:parseInt(receiver_tank_info7.waterlevel, 10),
supplierInitialwaterlevel:parseInt(supplier_tank_info7.waterlevel, 10)
});
await newMotorData.save();
// If threshold type is percentage, calculate percentage threshold
const receiver_tank_info = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() });
const supplier_tank_info = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() });
if (!receiver_tank_info) {
throw new Error("Receiver tank not found.");
}
if (!supplier_tank_info) {
throw new Error("Supplierr tank not found.");
}
const supplier_capacity = parseInt(supplier_tank_info.capacity, 10);
const supplier_waterLevel = parseInt(supplier_tank_info.waterlevel, 10);
const capacity = parseInt(receiver_tank_info.capacity, 10);
const waterLevel = parseInt(receiver_tank_info.waterlevel, 10);
const desired_percentage = parseInt(req.body.manual_threshold_litres.replace(/,/g, ''), 10);
console.log(desired_percentage)
const threshold_water_level = waterLevel+desired_percentage;
const supplier_threshold = supplier_waterLevel-desired_percentage
console.log(supplier_threshold,"supplier_threshold")
for await (const tank of Tank.find({ "connections.inputConnections.motor_id": motorId })) {
this.publishMotorStopStatus(motorId, motorStopStatus);
for await (const tank of Tank.find({ "connections.inputConnections.motor_id": motorId })) {
const index = tank.connections.inputConnections.findIndex(connection => connection.motor_id === motorId);
if (index !== -1) {
await Tank.updateOne(
{ customerId, "connections.inputConnections.motor_id": motorId },
{ $set: { [`connections.inputConnections.${index}.manual_threshold_percentage`]: supplier_threshold.toString(), [`connections.inputConnections.${index}.startTime`]: req.body.startTime } }
);
}
}
// Update water level threshold
// Start monitoring water level based on threshold percentage
motorIntervals[motorId] = setInterval(async () => {
// Check if water level has reached the threshold percentage
const supplier_tank_info1 = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() });
const current_water_level = parseInt(supplier_tank_info1.waterlevel, 10);
if (current_water_level <= supplier_threshold) {
// Stop the motor pump
await Tank.updateOne(
{ customerId, "connections.inputConnections.motor_id": motorId },
{
$set: {
"connections.inputConnections.$.motor_stop_status": "1",
"connections.inputConnections.$.threshold_type": null,
"connections.inputConnections.$.manual_threshold_time": null,
"connections.inputConnections.$.manual_threshold_percentage": null
}
}
);
clearInterval(motorIntervals[motorId]); // Clear interval
delete motorIntervals[motorId];
this.publishMotorStopStatus(motorId, "1");
await delay(300000);
const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id });
if (motorData) {
const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() });
const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10);
const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10);
const stopTime = formatDate(new Date());
await MotorData.updateOne(
{ customerId, motor_id: motorId, start_instance_id: start_instance_id },
{
$set: {
stopTime:stopTime,
receiverfinalwaterlevel: receiverFinalWaterLevel.toString(),
quantity_delivered: quantityDelivered.toString()
}
}
);
}
}
}, 20000);
}
}
}
// Respond with success message
reply.code(200).send({ message: `Motor ${action === "start" ? "started" : "stopped"} successfully.` });
} catch (err) {
throw boom.boomify(err);
}
};
// exports.motorAction = async (req, reply) => {
// try {
// const customerId = req.params.customerId;
// const action = req.body.action;
// const motorId = req.body.motor_id;
// const start_instance_id = req.body.start_instance_id
// console.log(req.body.startTime)
// // Ensure motor_id is provided
// if (!motorId) {
// throw new Error("Motor ID is required.");
// }
// // Determine the motor stop status based on the action
// let motorStopStatus;
// if (action === "start") {
// motorStopStatus = "2"; // If action is start, set stop status to "2"
// } else if (action === "stop") {
// motorStopStatus = "1"; // If action is stop, set stop status to "1"
// } else {
// throw new Error("Invalid action provided.");
// }
// // Update the motor stop status immediately if action is stop
// if (action === "stop") {
// // Update the motor stop status and other fields
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// {
// $set: {
// "connections.inputConnections.$.motor_stop_status": "1",
// "connections.inputConnections.$.stopTime": req.body.stopTime,
// "connections.inputConnections.$.threshold_type": null,
// "connections.inputConnections.$.manual_threshold_time": null,
// "connections.inputConnections.$.manual_threshold_percentage": null
// }
// }
// );
// // Send immediate response to the client
// reply.code(200).send({ message: "Motor stopped successfully." });
// // Perform stop operations in the background
// (async () => {
// await delay(300000);
// // Update the existing motor data entry with stop details
// const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id });
// if (motorData) {
// const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() });
// const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10);
// const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10);
// const water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10);
// const totalwaterpumped = quantityDelivered + water_pumped_till_now;
// await Tank.findOneAndUpdate(
// { customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() },
// { $set: { total_water_added_from_midnight: totalwaterpumped } }
// );
// await MotorData.updateOne(
// { customerId, motor_id: motorId, start_instance_id: start_instance_id },
// {
// $set: {
// stopTime: req.body.stopTime,
// receiverfinalwaterlevel: receiverFinalWaterLevel.toString(),
// quantity_delivered: quantityDelivered.toString()
// }
// }
// );
// }
// })();
// // Return here to ensure the rest of the code is not executed for the stop action
// return;
// } else {
// // Update the motor stop status to "2" for start action
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// { $set: { "connections.inputConnections.$.motor_stop_status": "2" } }
// );
// }
// // Check threshold settings if action is start
// if (action === "start") {
// if (req.body.threshold_type === "time") {
// // If threshold type is time, update threshold time
// // await Tank.updateOne(
// // { customerId, "connections.inputConnections.motor_id": motorId },
// // { $set: { "connections.inputConnections.$.manual_threshold_time": req.body.manual_threshold_time,startTime:req.body.startTime } }
// // );
// const receiver_tank_info7 = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() });
// const newMotorData = new MotorData({
// customerId: customerId,
// motor_id: motorId,
// start_instance_id: start_instance_id,
// supplierTank: req.body.from,
// receiverTank: req.body.to,
// supplier_type: req.body.from_type,
// receiver_type: req.body.to_type,
// startTime: req.body.startTime,
// receiverInitialwaterlevel:parseInt(receiver_tank_info7.waterlevel, 10)
// });
// await newMotorData.save();
// for await (const tank of Tank.find({ "connections.inputConnections.motor_id": motorId })) {
// const index = tank.connections.inputConnections.findIndex(connection => connection.motor_id === motorId);
// if (index !== -1) {
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// { $set: { [`connections.inputConnections.${index}.manual_threshold_time`]: req.body.manual_threshold_time, [`connections.inputConnections.${index}.startTime`]: req.body.startTime,[`connections.inputConnections.${index}.start_instance_id`]: start_instance_id } }
// );
// }
// }
// // Start monitoring water level based on threshold time
// const thresholdTime = moment().add(req.body.manual_threshold_time, 'minutes').toDate();
// const intervalId = setInterval(async () => {
// const splr_tank_info3 = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() });
// const splr_tank_info3_waterlevel = parseInt(splr_tank_info3.waterlevel, 10);
// //console.log(splr_tank_info3_waterlevel,"splr_tank_info3_waterlevel")
// const splr_tank_info3_capacity = parseInt(splr_tank_info3.capacity.replace(/,/g, ''), 10);
// // const splr_tank_info3_capacity = parseInt(splr_tank_info3.capacity, 10);
// // console.log(splr_tank_info3.capacity,splr_tank_info3_capacity,"splr_tank_info3_capacity")
// const splr_tank_info3_percentage = (splr_tank_info3_waterlevel / splr_tank_info3_capacity) * 100;
// // console.log(splr_tank_info3_percentage, "percentage for less than 20");
// if (new Date() >= thresholdTime || splr_tank_info3_percentage <= 20) {
// console.log(splr_tank_info3_percentage,)
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// {
// $set: {
// "connections.inputConnections.$.motor_stop_status": "1",
// "connections.inputConnections.$.threshold_type": null,
// "connections.inputConnections.$.manual_threshold_time": null,
// "connections.inputConnections.$.manual_threshold_percentage": null
// }
// }
// );
// clearInterval(intervalId);
// await delay(300000);
// const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id });
// if (motorData) {
// const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() });
// const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10);
// const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10);
// const water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10);
// const totalwaterpumped = quantityDelivered + water_pumped_till_now
// await Tank.findOneAndUpdate({customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase()}, { $set: { total_water_added_from_midnight: totalwaterpumped } })
// const stopTime = formatDate(new Date());
// await MotorData.updateOne(
// { customerId, motor_id: motorId, start_instance_id: start_instance_id },
// {
// $set: {
// stopTime:stopTime,
// receiverfinalwaterlevel: receiverFinalWaterLevel.toString(),
// quantity_delivered: quantityDelivered.toString()
// }
// }
// );
// }
// }
// }, 60000);
// } else if (req.body.threshold_type === "litres") {
// console.log("entered litres")
// const receiver_tank_info7 = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() });
// const newMotorData = new MotorData({
// customerId: customerId,
// motor_id: motorId,
// start_instance_id: start_instance_id,
// supplierTank: req.body.from,
// receiverTank: req.body.to,
// supplier_type: req.body.from_type,
// receiver_type: req.body.to_type,
// startTime: req.body.startTime,
// receiverInitialwaterlevel:parseInt(receiver_tank_info7.waterlevel, 10)
// });
// await newMotorData.save();
// // If threshold type is percentage, calculate percentage threshold
// const receiver_tank_info = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() });
// const supplier_tank_info = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() });
// if (!receiver_tank_info) {
// throw new Error("Receiver tank not found.");
// }
// if (!supplier_tank_info) {
// throw new Error("Supplierr tank not found.");
// }
// const supplier_capacity = parseInt(supplier_tank_info.capacity, 10);
// const supplier_waterLevel = parseInt(supplier_tank_info.waterlevel, 10);
// const capacity = parseInt(receiver_tank_info.capacity, 10);
// const waterLevel = parseInt(receiver_tank_info.waterlevel, 10);
// const desired_percentage = parseInt(req.body.manual_threshold_litres.replace(/,/g, ''), 10);
// console.log(desired_percentage)
// const threshold_water_level = waterLevel+desired_percentage;
// const supplier_threshold = supplier_waterLevel-desired_percentage
// console.log(supplier_threshold,"supplier_threshold")
// for await (const tank of Tank.find({ "connections.inputConnections.motor_id": motorId })) {
// const index = tank.connections.inputConnections.findIndex(connection => connection.motor_id === motorId);
// if (index !== -1) {
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// { $set: { [`connections.inputConnections.${index}.manual_threshold_percentage`]: supplier_threshold.toString(), [`connections.inputConnections.${index}.startTime`]: req.body.startTime } }
// );
// }
// }
// // Update water level threshold
// // Start monitoring water level based on threshold percentage
// const intervalId = setInterval(async () => {
// // Check if water level has reached the threshold percentage
// const supplier_tank_info1 = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() });
// const current_water_level = parseInt(supplier_tank_info1.waterlevel, 10);
// if (current_water_level <= supplier_threshold) {
// // Stop the motor pump
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// {
// $set: {
// "connections.inputConnections.$.motor_stop_status": "1",
// "connections.inputConnections.$.threshold_type": null,
// "connections.inputConnections.$.manual_threshold_time": null,
// "connections.inputConnections.$.manual_threshold_percentage": null
// }
// }
// );
// clearInterval(intervalId); // Stop monitoring water level
// await delay(300000);
// const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id });
// if (motorData) {
// const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() });
// const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10);
// const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10);
// const stopTime = formatDate(new Date());
// await MotorData.updateOne(
// { customerId, motor_id: motorId, start_instance_id: start_instance_id },
// {
// $set: {
// stopTime:stopTime,
// receiverfinalwaterlevel: receiverFinalWaterLevel.toString(),
// quantity_delivered: quantityDelivered.toString()
// }
// }
// );
// }
// }
// }, 20000); // Check water level every minute
// }
// }
// // Respond with success message
// reply.code(200).send({ message: `Motor ${action === "start" ? "started" : "stopped"} successfully.` });
// } catch (err) {
// // Handle errors
// throw boom.boomify(err);
// }
// };
// exports.motorAction = async (req, reply) => {
// try {
// const customerId = req.params.customerId;
// const action = req.body.action;
// const motorId = req.body.motor_id;
// const start_instance_id = req.body.start_instance_id;
// //const fcmIds = req.body.fcmIds; // Assume this is provided in the request to notify users
// // Ensure motor_id is provided
// if (!motorId) {
// throw new Error("Motor ID is required.");
// }
// // Determine the motor stop status based on the action
// let motorStopStatus;
// if (action === "start") {
// motorStopStatus = "2"; // If action is start, set stop status to "2"
// } else if (action === "stop") {
// motorStopStatus = "1"; // If action is stop, set stop status to "1"
// } else {
// throw new Error("Invalid action provided.");
// }
// const users = await User.find({ customerId: customerId });
// const fcmIds = users.map(user => user.fcmId).filter(fcmId => fcmId);
// // Handle motor stop action
// if (action === "stop") {
// // Update the motor stop status and other fields
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// {
// $set: {
// "connections.inputConnections.$.motor_stop_status": "1",
// "connections.inputConnections.$.stopTime": req.body.stopTime,
// "connections.inputConnections.$.threshold_type": null,
// "connections.inputConnections.$.manual_threshold_time": null,
// "connections.inputConnections.$.manual_threshold_percentage": null
// }
// }
// );
// // Send immediate response to the client
// reply.code(200).send({ message: "Motor stopped successfully." });
// // Send notification for motor stop
// for (const fcmId of fcmIds) {
// try {
// const response = await sendPushNotification(fcmId, 'Motor Stopped', `Motor has stopped at ${req.body.stopTime}.`);
// console.log('Notification sent successfully:', response);
// if (response.results[0].error === 'NotRegistered') {
// await User.updateOne({ fcmId: fcmId }, { $unset: { fcmId: "" } });
// console.log(`Removed unregistered FCM ID: ${fcmId}`);
// }
// } catch (error) {
// console.error('Error sending notification:', error);
// }
// }
// // Perform stop operations in the background
// (async () => {
// await delay(300000);
// // Update the existing motor data entry with stop details
// const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id });
// if (motorData) {
// const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() });
// const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10);
// const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10);
// const water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10);
// const totalwaterpumped = quantityDelivered + water_pumped_till_now;
// await Tank.findOneAndUpdate(
// { customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() },
// { $set: { total_water_added_from_midnight: totalwaterpumped } }
// );
// await MotorData.updateOne(
// { customerId, motor_id: motorId, start_instance_id: start_instance_id },
// {
// $set: {
// stopTime: req.body.stopTime,
// receiverfinalwaterlevel: receiverFinalWaterLevel.toString(),
// quantity_delivered: quantityDelivered.toString()
// }
// }
// );
// }
// })();
// // Return here to ensure the rest of the code is not executed for the stop action
// return;
// } else {
// // Update the motor stop status to "2" for start action
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// { $set: { "connections.inputConnections.$.motor_stop_status": "2" } }
// );
// // Send notification for motor start
// for (const fcmId of fcmIds) {
// try {
// const response = await sendPushNotification(fcmId, 'Motor Started', `Motor has started at ${req.body.startTime}.`);
// console.log('Notification sent successfully:', response);
// if (response.results[0].error === 'NotRegistered') {
// await User.updateOne({ fcmId: fcmId }, { $unset: { fcmId: "" } });
// console.log(`Removed unregistered FCM ID: ${fcmId}`);
// }
// } catch (error) {
// console.error('Error sending notification:', error);
// }
// }
// }
// // Check threshold settings if action is start
// if (action === "start") {
// if (req.body.threshold_type === "time") {
// const receiver_tank_info7 = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() });
// const newMotorData = new MotorData({
// customerId: customerId,
// motor_id: motorId,
// start_instance_id: start_instance_id,
// supplierTank: req.body.from,
// receiverTank: req.body.to,
// supplier_type: req.body.from_type,
// receiver_type: req.body.to_type,
// startTime: req.body.startTime,
// receiverInitialwaterlevel: parseInt(receiver_tank_info7.waterlevel, 10)
// });
// await newMotorData.save();
// for await (const tank of Tank.find({ "connections.inputConnections.motor_id": motorId })) {
// const index = tank.connections.inputConnections.findIndex(connection => connection.motor_id === motorId);
// if (index !== -1) {
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// { $set: { [`connections.inputConnections.${index}.manual_threshold_time`]: req.body.manual_threshold_time, [`connections.inputConnections.${index}.startTime`]: req.body.startTime, [`connections.inputConnections.${index}.start_instance_id`]: start_instance_id } }
// );
// }
// }
// // Start monitoring water level based on threshold time
// const thresholdTime = moment().add(req.body.manual_threshold_time, 'minutes').toDate();
// const intervalId = setInterval(async () => {
// const splr_tank_info3 = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() });
// const splr_tank_info3_waterlevel = parseInt(splr_tank_info3.waterlevel, 10);
// const splr_tank_info3_capacity = parseInt(splr_tank_info3.capacity.replace(/,/g, ''), 10);
// const splr_tank_info3_percentage = (splr_tank_info3_waterlevel / splr_tank_info3_capacity) * 100;
// if (new Date() >= thresholdTime || splr_tank_info3_percentage <= 20) {
// // Send notification for low supplier tank percentage
// for (const fcmId of fcmIds) {
// try {
// const response = await sendPushNotification(fcmId, 'Low Water Level Alert', `Supplier tank water level is below 20% (${splr_tank_info3_percentage.toFixed(2)}%).`);
// console.log('Notification sent successfully:', response);
// if (response.results[0].error === 'NotRegistered') {
// await User.updateOne({ fcmId: fcmId }, { $unset: { fcmId: "" } });
// console.log(`Removed unregistered FCM ID: ${fcmId}`);
// }
// } catch (error) {
// console.error('Error sending notification:', error);
// }
// }
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// {
// $set: {
// "connections.inputConnections.$.motor_stop_status": "1",
// "connections.inputConnections.$.threshold_type": null,
// "connections.inputConnections.$.manual_threshold_time": null,
// "connections.inputConnections.$.manual_threshold_percentage": null
// }
// }
// );
// clearInterval(intervalId);
// await delay(300000);
// const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id });
// if (motorData) {
// const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() });
// const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10);
// const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10);
// const water_pumped_till_now = parseInt(receiverTank.total_water_added_from_midnight, 10);
// const totalwaterpumped = quantityDelivered + water_pumped_till_now;
// await Tank.findOneAndUpdate(
// { customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() },
// { $set: { total_water_added_from_midnight: totalwaterpumped } }
// );
// await MotorData.updateOne(
// { customerId, motor_id: motorId, start_instance_id: start_instance_id },
// {
// $set: {
// stopTime: req.body.stopTime,
// receiverfinalwaterlevel: receiverFinalWaterLevel.toString(),
// quantity_delivered: quantityDelivered.toString()
// }
// }
// );
// }
// }
// }, 60000); // Check every minute
// } else if (req.body.threshold_type === "litres") {
// console.log("entered litres")
// const receiver_tank_info7 = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() });
// const newMotorData = new MotorData({
// customerId: customerId,
// motor_id: motorId,
// start_instance_id: start_instance_id,
// supplierTank: req.body.from,
// receiverTank: req.body.to,
// supplier_type: req.body.from_type,
// receiver_type: req.body.to_type,
// startTime: req.body.startTime,
// receiverInitialwaterlevel:parseInt(receiver_tank_info7.waterlevel, 10)
// });
// await newMotorData.save();
// // If threshold type is percentage, calculate percentage threshold
// const receiver_tank_info = await Tank.findOne({ customerId, tankName: req.body.to, tankLocation: req.body.to_type.toLowerCase() });
// const supplier_tank_info = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() });
// if (!receiver_tank_info) {
// throw new Error("Receiver tank not found.");
// }
// if (!supplier_tank_info) {
// throw new Error("Supplierr tank not found.");
// }
// const supplier_capacity = parseInt(supplier_tank_info.capacity, 10);
// const supplier_waterLevel = parseInt(supplier_tank_info.waterlevel, 10);
// const capacity = parseInt(receiver_tank_info.capacity, 10);
// const waterLevel = parseInt(receiver_tank_info.waterlevel, 10);
// const desired_percentage = parseInt(req.body.manual_threshold_litres.replace(/,/g, ''), 10);
// console.log(desired_percentage)
// const threshold_water_level = waterLevel+desired_percentage;
// const supplier_threshold = supplier_waterLevel-desired_percentage
// console.log(supplier_threshold,"supplier_threshold")
// for await (const tank of Tank.find({ "connections.inputConnections.motor_id": motorId })) {
// const index = tank.connections.inputConnections.findIndex(connection => connection.motor_id === motorId);
// if (index !== -1) {
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// { $set: { [`connections.inputConnections.${index}.manual_threshold_percentage`]: supplier_threshold.toString(), [`connections.inputConnections.${index}.startTime`]: req.body.startTime } }
// );
// }
// }
// // Start monitoring water level based on threshold percentage
// const intervalId = setInterval(async () => {
// // Check if water level has reached the threshold percentage
// const supplier_tank_info1 = await Tank.findOne({ customerId, tankName: req.body.from, tankLocation: req.body.from_type.toLowerCase() });
// const current_water_level = parseInt(supplier_tank_info1.waterlevel, 10);
// if (current_water_level <= supplier_threshold) {
// // Stop the motor pump
// await Tank.updateOne(
// { customerId, "connections.inputConnections.motor_id": motorId },
// {
// $set: {
// "connections.inputConnections.$.motor_stop_status": "1",
// "connections.inputConnections.$.threshold_type": null,
// "connections.inputConnections.$.manual_threshold_time": null,
// "connections.inputConnections.$.manual_threshold_percentage": null
// }
// }
// );
// clearInterval(intervalId); // Stop monitoring water level
// await delay(300000);
// const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id });
// if (motorData) {
// const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() });
// const receiverFinalWaterLevel = parseInt(receiverTank.waterlevel, 10);
// const quantityDelivered = receiverFinalWaterLevel - parseInt(motorData.receiverInitialwaterlevel, 10);
// const stopTime = formatDate(new Date());
// await MotorData.updateOne(
// { customerId, motor_id: motorId, start_instance_id: start_instance_id },
// {
// $set: {
// stopTime:stopTime,
// receiverfinalwaterlevel: receiverFinalWaterLevel.toString(),
// quantity_delivered: quantityDelivered.toString()
// }
// }
// );
// }
// }
// }, 20000);
// }
// }
// reply.code(200).send({ message: `Motor ${action === "start" ? "started" : "stopped"} successfully.` });
// } catch (err) {
// // Handle errors
// throw boom.boomify(err);
// }
// };
const motorActionAuto = async (req, reply) => {
try {
const customerId = req.params.customerId;
const action = req.body.action;
const motorId = req.body.motor_id;
const motor_on_type = req.body.motor_on_type
const startTime = req.body.startTime;
const stopTime = req.body.stopTime;
const threshold = req.body.threshold || "unknown";
if (!motorId) {
throw new Error("Motor ID is required.");
}
let motorStopStatus;
const tank = await Tank.findOne({ customerId, "connections.inputConnections.motor_id": motorId });
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;
// Find the tank that contains the specified motor_id in its inputConnections
const tank = await Tank.findOne({ "connections.inputConnections.motor_id": hardwareId });
if (!tank) {
return reply.status(404).send({
status_code: 404,
message: 'Motor not found for the specified motor_id'
});
}
console.log(hardwareId,"hardwareId")
console.log(status,"status")
// Find the inputConnection with the specified motor_id
const inputConnection = tank.connections.inputConnections.find(conn => conn.motor_id === hardwareId);
if (inputConnection) {
// Update the motor_status of the inputConnection
inputConnection.motor_status = status;
console.log(inputConnection)
// Check if motor_stop_status is "1" and status is "2"
if (inputConnection.motor_stop_status === "1" && status === "2") {
console.log("got into forced manual")
console.log(inputConnection.motor_on_type,"before if motor on type")
// Check if motor_on_type is not already "forced_manual"
if (inputConnection.motor_on_type !== "forced_manual") {
inputConnection.motor_on_type = "forced_manual";
console.log("entered forced manual of if")
inputConnection.motor_stop_status = "2";
// Update startTime to the current time in the specified format
const currentTime = new Date();
const formattedTime = currentTime.toLocaleString('en-GB', {
day: '2-digit',
month: 'short',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
hour12: false,
}).replace(',', '');
inputConnection.startTime = formattedTime;
}
}
// Check if motor_stop_status is "1" and status is "2"
if (inputConnection.motor_stop_status === "2" && status === "1") {
console.log("got into forced manual stop")
console.log(inputConnection.motor_on_type,"before if motor on type stop")
// Check if motor_on_type is not already "forced_manual"
if (inputConnection.motor_on_type = "forced_manual") {
inputConnection.motor_on_type = "manual";
console.log("entered forced manual of if of stop")
// Update startTime to the current time in the specified format
inputConnection.motor_stop_status = "1";
}
}
}
// Save the updated tank
await tank.save();
// Send the latest three documents
const latestOttanks = await IotData.find({ hardwareId })
.sort({ date: -1, time: -1 });
reply.code(200).send({ latestOttanks });
} catch (err) {
// send an error response
reply.code(500).send({ error: err.message });
}
};
// exports.IotDevice3 = async (req, reply) => {
// try {
// const { hardwareId, mode, tanks } = req.body;
// // create a new tank document with the current date and time
// const currentDate = new Date();
// const date = currentDate.toISOString(); // save the date as an ISO string
// const time = currentDate.toLocaleTimeString('en-IN', { hour12: false, timeZone: 'Asia/Kolkata' });
// // Create an array of tank documents
// const tankDocuments = tanks.map(tank => ({
// tankhardwareId: tank.tankhardwareId,
// tankHeight: tank.tankHeight,
// maxLevel: tank.maxLevel,
// minLevel: tank.minLevel,
// date: date,
// time: time
// }));
// // create a new IotData document with the provided data
// const ottank = new IotData({ hardwareId, mode, tanks: tankDocuments, date, time });
// // save the document to MongoDB
// await ottank.save();
// // Delete excess records (keep only the latest three records)
// const recordsToKeep = 3;
// const recordsToDelete = await IotData.find({ hardwareId })
// .sort({ date: -1, time: -1 })
// .skip(recordsToKeep);
// for (const record of recordsToDelete) {
// await record.remove();
// }
// // Update waterlevel in tanksSchema for each tank
// for (const tank of tanks) {
// const { tankhardwareId, tankHeight } = tank;
// // Find the corresponding tank in tanksSchema
// const existingTank = await Tank.findOne({ hardwareId, tankhardwareId });
// if (existingTank) {
// // Update the waterlevel using the tankHeight value
// const tank_height1 = (parseInt(existingTank.height.replace(/,/g, ''), 10)) * 30.48;
// console.log(tank_height1, 25);
// // The value of tank_height1 is a number, not a string, so you cannot use replace on it.
// // If you want to format it with commas, you can create a function to add commas to a number.
// function numberWithCommas(x) {
// return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
// }
// // Now you can use the function to format the tank_height1 value with commas.
// const formatted_tank_height1 = numberWithCommas(tank_height1);
// console.log(formatted_tank_height1, 25);
// const tank_height = parseInt(formatted_tank_height1.replace(/,/g, ''), 10);
// console.log(tank_height);
// // console.log(tank_height,1)
// const water_level_height = tank_height - tankHeight
// console.log(water_level_height,2)
// const waterCapacityPerCm = parseInt(existingTank.waterCapacityPerCm.replace(/,/g, ''), 10)
// console.log(waterCapacityPerCm,3)
// const water_level = water_level_height * waterCapacityPerCm;
// console.log(water_level, 4);
// // Function to add commas to a number
// function numberWithCommas(x) {
// return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
// }
// const formatted_water_level = numberWithCommas(water_level);
// console.log(formatted_water_level, 4);
// existingTank.waterlevel = parseInt(formatted_water_level.replace(/,/g, ''), 10);
// console.log(existingTank.waterlevel);
// // Save the updated tank document
// await existingTank.save();
// for (const outputConnection of existingTank.connections.outputConnections) {
// const linkedTank = await Tank.findOne({ customerId: customerId, tankName: outputConnection.outputConnections, tankLocation: outputConnection.output_type });
// if (linkedTank) {
// // linkedTank.waterlevel = existingTank.waterlevel;
// //await linkedTank.save();
// // Update water level of tanks linked through input connections of the linked tank
// for (const inputConnection of linkedTank.connections.inputConnections) {
// if (inputConnection.inputConnections === tank_name) {
// inputConnection.water_level = water_level.toString();
// await linkedTank.save();
// }
// }
// }
// }
// }
// }
// // Send the latest three documents
// const latestOttanks = await IotData.find({ hardwareId })
// .sort({ date: -1, time: -1 });
// reply.code(200).send({ latestOttanks });
// } catch (err) {
// // send an error response
// reply.code(500).send({ error: err.message });
// }
// };
// exports.IotDevice1 = async (req, reply) => {
// try {
// const { hardwareId, mode, tanks } = req.body;
// // create a new tank document with the current date and time
// const currentDate = new Date();
// const date = currentDate.toISOString(); // save the date as an ISO string
// const time = currentDate.toLocaleTimeString('en-IN', { hour12: false, timeZone: 'Asia/Kolkata' });
// // Create an array of tank documents
// const tankDocuments = tanks.map(tank => ({
// tankhardwareId: tank.tankhardwareId,
// tankHeight: tank.tankHeight,
// maxLevel: tank.maxLevel,
// minLevel: tank.minLevel,
// date: date,
// time: time
// }));
// // create a new IotData document with the provided data
// const ottank = new IotData({ hardwareId, mode, tanks: tankDocuments, date, time });
// // save the document to MongoDB
// await ottank.save();
// // Delete excess records (keep only the latest three records)
// const recordsToKeep = 3;
// const recordsToDelete = await IotData.find({ hardwareId })
// .sort({ date: -1, time: -1 })
// .skip(recordsToKeep);
// for (const record of recordsToDelete) {
// await record.remove();
// }
// console.log(tanks)
// // Update waterlevel in tanksSchema for each tank
// for (const tank of tanks) {
// console.log(tank)
// const { tankhardwareId, tankHeight } = tank;
// console.log(hardwareId,tankhardwareId)
// // Find the corresponding tank in tanksSchema
// const existingTank = await Tank.findOne({ hardwareId, tankhardwareId });
// if (!existingTank) {
// console.log(`No tank found for tankhardwareId '${tankhardwareId}'. Skipping.`);
// continue; // Skip to the next iteration
// }
// console.log(existingTank,"existing tank")
// if (existingTank) {
// // Update the waterlevel using the tankHeight value
// const tank_height1 = (parseInt(existingTank.height.replace(/,/g, ''), 10)) * 30.48;
// console.log(tank_height1, 25);
// // The value of tank_height1 is a number, not a string, so you cannot use replace on it.
// // If you want to format it with commas, you can create a function to add commas to a number.
// function numberWithCommas(x) {
// return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
// }
// // Now you can use the function to format the tank_height1 value with commas.
// const formatted_tank_height1 = numberWithCommas(tank_height1);
// console.log(formatted_tank_height1, 25);
// const tank_height = parseInt(formatted_tank_height1.replace(/,/g, ''), 10);
// console.log(tank_height);
// // console.log(tank_height,1)
// const water_level_height = tank_height - tankHeight
// console.log(water_level_height,2)
// const waterCapacityPerCm = parseInt(existingTank.waterCapacityPerCm.replace(/,/g, ''), 10)
// console.log(waterCapacityPerCm,3)
// const water_level = water_level_height * waterCapacityPerCm;
// console.log(water_level, 4);
// // Function to add commas to a number
// function numberWithCommas(x) {
// return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
// }
// const formatted_water_level = numberWithCommas(water_level);
// console.log(formatted_water_level, 4);
// existingTank.waterlevel = parseInt(formatted_water_level.replace(/,/g, ''), 10);
// console.log(existingTank.waterlevel);
// // Save the updated tank document
// await existingTank.save();
// for (const outputConnection of existingTank.connections.outputConnections) {
// const linkedTank = await Tank.findOne({ customerId: customerId, tankName: outputConnection.outputConnections, tankLocation: outputConnection.output_type });
// if (linkedTank) {
// // linkedTank.waterlevel = existingTank.waterlevel;
// //await linkedTank.save();
// // Update water level of tanks linked through input connections of the linked tank
// for (const inputConnection of linkedTank.connections.inputConnections) {
// if (inputConnection.inputConnections === tank_name) {
// inputConnection.water_level = water_level.toString();
// await linkedTank.save();
// }
// }
// }
// }
// }
// }
// // Send the latest three documents
// const latestOttanks = await IotData.find({ hardwareId })
// .sort({ date: -1, time: -1 });
// reply.code(200).send({ latestOttanks });
// } catch (err) {
// // send an error response
// reply.code(500).send({ error: err.message });
// }
// };
// exports.IotDevice1 = async (req, reply) => {
// try {
// const { hardwareId, mode, tanks } = req.body;
// // create a new tank document with the current date and time
// const currentDate = new Date();
// const date = currentDate.toISOString(); // save the date as an ISO string
// const time = currentDate.toLocaleTimeString('en-IN', { hour12: false, timeZone: 'Asia/Kolkata' });
// // Create an array of tank documents
// const tankDocuments = tanks.map(tank => ({
// tankhardwareId: tank.tankhardwareId,
// tankHeight: tank.tankHeight,
// maxLevel: tank.maxLevel,
// minLevel: tank.minLevel,
// date: date,
// time: time
// }));
// // create a new IotData document with the provided data
// const ottank = new IotData({ hardwareId, mode, tanks: tankDocuments, date, time });
// // save the document to MongoDB
// await ottank.save();
// // Delete excess records (keep only the latest three records)
// const recordsToKeep = 3;
// const recordsToDelete = await IotData.find({ hardwareId })
// .sort({ date: -1, time: -1 })
// .skip(recordsToKeep);
// for (const record of recordsToDelete) {
// await record.remove();
// }
// // Update waterlevel in tanksSchema for each tank
// for (const tank of tanks) {
// const { tankhardwareId, tankHeight } = tank;
// if (tankHeight === null || tankHeight === undefined) {
// continue; // Skip this iteration and move to the next tank
// }
// // Find the corresponding tank in tanksSchema
// const existingTank = await Tank.findOne({ hardwareId, tankhardwareId });
// if (existingTank) {
// // Update the waterlevel using the tankHeight value
// const tank_height = parseInt(existingTank.height.replace(/,/g, ''), 10) * 30.48;
// const water_level_height = tank_height - tankHeight;
// const customerId = existingTank.customerId;
// const waterCapacityPerCm = parseInt(existingTank.waterCapacityPerCm.replace(/,/g, ''), 10);
// let water_level = water_level_height * waterCapacityPerCm;
// water_level = Math.round(water_level); // Round to nearest whole number
// existingTank.waterlevel = water_level.toString(); // Convert to string as per schema definition
// const tank_name = existingTank.tankName;
// // Save the updated tank document
// await existingTank.save();
// // Update water level of tanks linked through output connections
// for (const outputConnection of existingTank.connections.outputConnections) {
// const linkedTank = await Tank.findOne({ customerId: customerId, tankName: outputConnection.outputConnections, tankLocation: outputConnection.output_type });
// if (linkedTank) {
// // linkedTank.waterlevel = existingTank.waterlevel;
// //await linkedTank.save();
// // Update water level of tanks linked through input connections of the linked tank
// for (const inputConnection of linkedTank.connections.inputConnections) {
// if (inputConnection.inputConnections === tank_name) {
// inputConnection.water_level = water_level.toString();
// await linkedTank.save();
// }
// }
// }
// }
// }
// }
// // Send the latest three documents
// const latestOttanks = await IotData.find({ hardwareId })
// .sort({ date: -1, time: -1 });
// reply.code(200).send({ latestOttanks });
// } catch (err) {
// // send an error response
// reply.code(500).send({ error: err.message });
// }
// };
// exports.getIotD = async(req, reply) => {
// try {
// await IotData.find({hardwareId: req.query.hardwareId})
// .exec()
// .then((docs) => {
// reply.send({ status_code: 200, data: docs, count: docs.length });
// })
// .catch((err) => {
// console.log(err);
// reply.send({ error: err });
// });
// } catch (err) {
// throw boom.boomify(err);
// }
// }
exports.getIotD = async (req, reply) => {
try {
const latestRecords = await IotData.find({ hardwareId: req.query.hardwareId })
.sort({ date: -1, time: -1 }) // Sort by date and time in descending order
.limit(3) // Limit the result to 3 records
.exec();
reply.send({ status_code: 200, data: latestRecords, count: latestRecords.length });
} catch (err) {
console.error(err);
throw boom.boomify(err);
}
};
exports.getLatestData = async (req, reply) => {
try {
const hardwareId = req.params.hardwareId;
// get the latest two tank documents for the current hardwareId sorted in descending order of date and time
const latestTanks = await IotData.find({ hardwareId }).sort({ date: -1, time: -1 }).limit(2);
// if the number of documents for the current hardwareId is less than two, return an error response
if (latestTanks.length < 2) {
return reply.code(404).send({ error: 'Not enough data' });
}
// calculate the time difference between the latest and previous documents
const latestDate = new Date(latestTanks[0].date);
const previousDate = new Date(latestTanks[1].date);
const latestTime = latestTanks[0].time.split('.')[0]; // remove milliseconds
const previousTime = latestTanks[1].time.split('.')[0]; // remove milliseconds
latestDate.setHours(parseInt(latestTime.substring(0, 2)), parseInt(latestTime.substring(3, 5)), parseInt(latestTime.substring(6, 8)));
previousDate.setHours(parseInt(previousTime.substring(0, 2)), parseInt(previousTime.substring(3, 5)), parseInt(previousTime.substring(6, 8)));
const timeDiff = (latestDate.getTime() - previousDate.getTime()) / 1000; // convert from milliseconds to seconds
console.log(latestDate,previousDate,latestTime,previousTime,timeDiff)
reply.code(200).send({ timeDiff });
} catch (err) {
// send an error response
reply.code(500).send({ error: err.message });
}
};
exports.changesurveystatus = async (req, reply) => {
try {
const customerId = req.params.customerId;
const result = await User.findOneAndUpdate(
{ customerId: customerId },
{ $set: { survey_status: req.body.survey_status } },
{ new: true }
);
reply.code(200).send({ result });
} catch (err) {
// send an error response
reply.code(500).send({ error: err.message });
}
};
exports.checkStatusofIot = async (req, reply) => {
try {
// get a list of unique hardware IDs in the collection
const hardwareIds = await IotData.distinct('hardwareId');
// create an empty object to store the time differences for each hardware ID
const timeDiffs = {};
// loop over each hardware ID and calculate the time difference between the latest two records
for (const hardwareId of hardwareIds) {
// get the latest two records for the current hardware ID
const latestTanks = await IotData.find({ hardwareId }).sort({ date: -1, time: -1 }).limit(2);
// if the number of records for the current hardware ID is less than two, skip to the next ID
if (latestTanks.length < 2) {
continue;
}
// calculate the time difference between the latest and previous records for the current hardware ID
const latestDate = new Date(latestTanks[0].date);
const previousDate = new Date(latestTanks[1].date);
const latestTime = latestTanks[0].time.split('.')[0]; // remove milliseconds
const previousTime = latestTanks[1].time.split('.')[0]; // remove milliseconds
latestDate.setHours(parseInt(latestTime.substring(0, 2)), parseInt(latestTime.substring(3, 5)), parseInt(latestTime.substring(6, 8)));
previousDate.setHours(parseInt(previousTime.substring(0, 2)), parseInt(previousTime.substring(3, 5)), parseInt(previousTime.substring(6, 8)));
const timeDiff = (latestDate.getTime() - previousDate.getTime()) / 1000; // convert from milliseconds to seconds
// store the time difference for the current hardware ID
timeDiffs[hardwareId] = timeDiff;
}
// send the time differences for all hardware IDs
reply.code(200).send({ timeDiffs });
} catch (err) {
// send an error response
reply.code(500).send({ error: err.message });
}
};
exports.totalwaterLevelSum = async (request, reply) => {
const { tankLocation, typeOfWater } = request.query;
const waterlevelSum = await Tank.aggregate([
{
$match: { tankLocation, typeOfWater }
},
{
$group: {
_id: null,
totalWaterlevel: { $sum: { $toInt: '$waterlevel' } }
}
}
]);
const result = waterlevelSum[0]?totalWaterlevel : 0;
reply.send({ waterlevelSum: result });
}
exports.startUpdateLoop = async (request, reply) => {
const updateInterval = 5000;
setInterval(async () => {
try {
const iotTank = await IotData.findOne({ hardwareId: request.body.hardwareId });
if (!iotTank) {
console.log(`IOTtank not found for hardwareId ${request.body.hardwareId}`);
return;
}
const currentWaterlevel = Number(iotTank.tankHeight) * 200;
const tank = await Tank.findOne({ hardwareId: iotTank.hardwareId });
let combinedWaterlevel;
if (tank) {
combinedWaterlevel = currentWaterlevel + Number(tank.waterlevel);
} else {
combinedWaterlevel = currentWaterlevel;
}
await Tank.updateOne({ hardwareId: iotTank.hardwareId }, { $set: { waterlevel: combinedWaterlevel } });
console.log(`Waterlevel updated successfully for hardwareId ${iotTank.hardwareId}`);
console.log(`Previous waterlevel: ${tank ? tank.waterlevel : 0}`);
console.log(`Current waterlevel: ${currentWaterlevel}`);
console.log(`Combined waterlevel: ${combinedWaterlevel}`);
} catch (err) {
console.error(err);
}
}, updateInterval);
};
const updatewaterlevelsatmidnight = async () => {
console.log('Cron job triggered at:', moment().tz('Asia/Kolkata').format());
try {
const tanks = await Tank.find({});
for (const tank of tanks) {
tank.waterlevel_at_midnight = tank.waterlevel;
tank.total_water_added_from_midnight = "0";
await tank.save();
console.log(`Updated tank ${tank._id} waterlevel_at_midnight to ${tank.waterlevel}`);
}
console.log('Waterlevel noted in waterlevel_at_midnight');
} catch (error) {
console.error('Error occurred:', error);
}
};
// Schedule the task to run every day at 13:49 IST (1:49 PM IST)
cron.schedule('0 0 * * *', updatewaterlevelsatmidnight, {
timezone: "Asia/Kolkata"
});
let consumptionTask;
// Function to clear the specific scheduled task
const clearConsumptionSchedule = () => {
if (consumptionTask) {
consumptionTask.stop(); // Stop the existing task if it exists
consumptionTask = null; // Clear the reference
}
};
// Function to update total consumption till midnight
const updatetotalConsumptiontillmidnight = async () => {
console.log('Cron job triggered at:', moment().tz('Asia/Kolkata').format());
try {
const tanks = await Tank.find({});
for (const tank of tanks) {
const waterlevel_at_midnight = parseInt((tank.waterlevel_at_midnight).replace(/,/g, ''), 10);
const total_water_added_from_midnight = parseInt((tank.total_water_added_from_midnight).replace(/,/g, ''), 10);
const waterlevel = parseInt((tank.waterlevel).replace(/,/g, ''), 10);
const capacity = parseInt((tank.capacity).replace(/,/g, ''), 10);
console.log(waterlevel_at_midnight,total_water_added_from_midnight,waterlevel)
const totalconsumption = (waterlevel_at_midnight + total_water_added_from_midnight) - waterlevel;
// const available_capacity = total_water_added_from_midnight + waterlevel;
const consumed_percentage = ((totalconsumption / capacity) * 100).toFixed(2);
console.log(totalconsumption,tank.tankName)
// Format the date in the desired format
const formattedDate = moment().tz('Asia/Kolkata').format('DD-MMM-YYYY - HH:mm');
// Check if the record already exists
const existingRecord = await TankConsumptionOriginalSchema.findOne({
customerId: tank.customerId,
tankName: tank.tankName,
tankLocation: tank.tankLocation,
time: formattedDate
});
if (!existingRecord) {
// Create and save the new document if it doesn't exist
const newTankConsumption = new TankConsumptionOriginalSchema({
customerId: tank.customerId,
tankName: tank.tankName,
tankLocation: tank.tankLocation,
available_capacity: (tank.capacity).toString(),
consumption: totalconsumption.toString(),
consumed_percentage: consumed_percentage.toString(),
time: formattedDate, // Save the formatted date
block:tank.blockName,
typeofwater:tank.typeOfWater
});
await newTankConsumption.save();
console.log(`Created new record for tank ${tank.tankName} at ${formattedDate}`);
} else {
console.log(`Record already exists for tank ${tank.tankName} at ${formattedDate}`);
}
}
console.log('Waterlevel noted in waterlevel_at_midnight');
} catch (error) {
console.error('Error occurred:', error);
}
};
// Clear the existing schedule for this task before creating a new one
clearConsumptionSchedule();
// Schedule the task to run every day at 12:49 PM IST and store the reference
consumptionTask = cron.schedule('50 23 * * *', updatetotalConsumptiontillmidnight, {
timezone: "Asia/Kolkata"
});
console.log('Scheduled task to update total consumption till midnight.');
exports.deletemotordatarecordsbefore7days = async (req, reply) => {
try {
// Schedule the task to run every day at 10 seconds past the minute
cron.schedule('0 0 * * *', async () => {
try {
// Run the deletion task once a day
setInterval(async () => {
await deleteOldRecords();
}, 24 * 60 * 60 * 1000); // 24 hours in milliseconds
} catch (error) {
console.error('Error occurred:', error);
}
});
} catch (err) {
throw boom.boomify(err);
}
};
exports.motorstatus = async (req, reply) => {
try {
const motor_id = req.params.motor_id;
console.log(motor_id)
const motorInfo = await Tank.findOne({ motor_id: motor_id });
console.log(motorInfo)
//return update;
reply.send({ status_code: 200,status:motorInfo.motor_status});
}
catch (err) {
throw boom.boomify(err);
}
};
exports.readMotorStatus = async (req, reply) => {
try {
const motor_id = req.query.motor_id;
console.log("entered read api for iot")
// Perform any necessary logic based on action (1: Start, 2: Stop)
// For example, you can update a database or trigger an action
const tanks = await Tank.find({});
let motor_stop_status = null;
for (let tank of tanks) {
const inputConnections = tank.connections.inputConnections;
const motorConnection = inputConnections.find(conn => conn.motor_id === motor_id);
if (motorConnection) {
// Check if motor_on_type is "forced_manual" and motor_stop_status is "1"
if (motorConnection.motor_on_type === "forced_manual" && motorConnection.motor_stop_status === "1") {
motor_stop_status = "2"; // Send motor_stop_status as "2"
} else {
motor_stop_status = motorConnection.motor_stop_status; // Otherwise, assign its original value
}
break;
}
}
if (!motor_stop_status) {
return reply.status(404).send({
status_code: 404,
message: 'Motor not found for the specified motor_id'
});
}
reply.send({
status_code: 200,
motor_stop_status: motor_stop_status
});
} catch (err) {
throw boom.boomify(err);
}
};
exports.readMotorStatusFromIot = async (req, reply) => {
try {
const motor_id = req.query.motor_id;
console.log(motor_id)
// Find the tank that contains the specified motor_id in its inputConnections
const tank = await Tank.findOne({ "connections.inputConnections.motor_id": motor_id });
if (!tank) {
return reply.status(404).send({
status_code: 404,
message: 'Motor not found for the specified motor_id'
});
}
// Find the inputConnection with the specified motor_id
const inputConnection = tank.connections.inputConnections.find(conn => conn.motor_id === motor_id);
// Extract motor_status and motor_stop_status from the inputConnection
const motor_status = inputConnection.motor_status;
const motor_stop_status = inputConnection.motor_stop_status;
// Send the response with motor_status and motor_stop_status
reply.send({
status_code: 200,
motor_status: motor_status,
motor_stop_status: motor_stop_status
});
} catch (err) {
throw boom.boomify(err);
}
};
exports.writeMotorStatus = async (req, reply) => {
try {
const motor_id = req.body.motor_id;
const status = req.body.status;
// Find the tank that contains the specified motor_id in its inputConnections
const tank = await Tank.findOne({ "connections.inputConnections.motor_id": motor_id });
if (!tank) {
return reply.status(404).send({
status_code: 404,
message: 'Motor not found for the specified motor_id'
});
}
// Find the inputConnection with the specified motor_id
const inputConnection = tank.connections.inputConnections.find(conn => conn.motor_id === motor_id);
// Update the motor_status of the inputConnection
inputConnection.motor_status = status;
// Save the updated tank
await tank.save();
// Send the response with the updated motor_status
reply.send({
status_code: 200,
motor_status: status
});
} catch (err) {
throw boom.boomify(err);
}
};
exports.changeMotorStatus = async (req, reply) => {
try {
const motor_id = req.body.motor_id;
const action = req.body.action;
// Perform any necessary logic to handle motor status update from the device
// For example, update a database with the new status, current, and temp values
await Tank.updateOne(
{ "connections.inputConnections.motor_id": motor_id },
{
$set: {
"connections.inputConnections.$.motor_stop_status":action ,
}
}
);
// Send immediat
// Fetch the motor_status for the given motor_id
// Send the response with motor_stop_status and motor_status
reply.send({
status_code: 200,
motor_stop_status: action,
// motor_status: updatedMotor.motor_status // Assuming motor_status is a field in your Tank model
});
} catch (err) {
throw boom.boomify(err);
}
};
exports.motortemperature = async (req, reply) => {
try {
const motor_id = req.params.motor_id;
console.log(motor_id)
const motorInfo = await Tank.findOne({ motor_id: motor_id });
console.log(motorInfo)
//return update;
reply.send({ status_code: 200,temperature:motorInfo.motor_temperfature});
}
catch (err) {
throw boom.boomify(err);
}
};
exports.update_auto_mode = async (req, reply) => {
try {
const customerId = req.params.customerId;
const { motor_id, auto_mode } = req.body;
// Update inputConnections' auto_mode
await Tank.updateOne(
{ customerId: customerId, "connections.inputConnections.motor_id": motor_id },
{ $set: { "connections.inputConnections.$.auto_mode": auto_mode } }
);
reply.send({ status_code: 200, message: "Auto mode and percentages updated successfully." });
} catch (error) {
throw boom.boomify(error);
}
};
exports.update_auto_percentage = async (req, reply) => {
try {
const customerId = req.params.customerId;
let { tankName, tankLocation, auto_min_percentage, auto_max_percentage, auto_mode_type } = req.body;
// Handle the optional parameters
tankName = tankName ? tankName : null;
tankLocation = tankLocation ? tankLocation.toLowerCase() : null;
const filter = { customerId };
// If tankName is not 'all', add it to the filter
if (tankName && tankName !== "all") {
filter.tankName = tankName;
}
// Only add tankLocation to the filter if tankName is not 'all'
if (tankLocation && tankName !== "all") {
filter.tankLocation = tankLocation;
}
console.log("Update filter:", JSON.stringify(filter, null, 2));
// Check if tanks exist
const matchingTanks = await Tank.find(filter);
console.log("Matching tanks:", matchingTanks);
if (matchingTanks.length === 0) {
return reply.send({ status_code: 400, message: "No matching records found." });
}
// Define the update fields
const updateData = {
auto_min_percentage: String(auto_min_percentage || "20"),
auto_max_percentage: String(auto_max_percentage || "80"),
auto_mode_type: auto_mode_type || "default",
};
let result;
if (tankName && tankName !== "all") {
// Update only one tank if tankName is specified and not "all"
result = await Tank.updateOne(filter, { $set: updateData });
} else {
// Update all tanks of the particular customer if tankName is "all"
result = await Tank.updateMany(filter, { $set: updateData });
// If auto_mode_type is default and tankName is "all", save or update the data in CustomerAutoPercentages
if (auto_mode_type === "default") {
const currentDate = new Date().toLocaleString("en-GB", { timeZone: "UTC" }); // Get current date in UTC
const formattedDate = currentDate.split(",").join(" -"); // Format it like '17-Dec-2024 - 15:56'
// Use findOneAndUpdate to either update the existing record or create a new one if it doesn't exist
const updateOrCreate = await CustomerAutoPercentages.findOneAndUpdate(
{ customerId }, // Search for the record with the customerId
{
$set: {
auto_min_percentage: String(auto_min_percentage || "20"),
auto_max_percentage: String(auto_max_percentage || "80"),
date: formattedDate,
},
},
{ upsert: true, new: true } // If no record found, create a new one; return the updated record
);
console.log("CustomerAutoPercentages updated/created:", updateOrCreate);
}
}
console.log("Update result:", result);
reply.send({ status_code: 200, message: "Auto mode and percentages updated successfully." });
} catch (error) {
console.error(error);
reply.send({ status_code: 500, message: "Internal server error." });
}
};
// Controller function to get CustomerAutoPercentages by customerId
exports.getCustomerAutoPercentages = async (req, reply) => {
try {
const { customerId } = req.params; // Extract customerId from the params
// Find the record in CustomerAutoPercentages based on customerId
const customerData = await CustomerAutoPercentages.findOne({ customerId });
if (!customerData) {
return reply.send({
status_code: 404,
message: "No data found for the provided customerId."
});
}
reply.send({
status_code: 200,
message: "Customer data retrieved successfully.",
data: customerData
});
} catch (error) {
console.error(error);
reply.send({
status_code: 500,
message: "Internal server error."
});
}
};
// exports.update_auto_percentage = async (req, reply) => {
// try {
// const customerId = req.params.customerId;
// let { tankName, tankLocation, auto_min_percentage, auto_max_percentage, auto_mode_type } = req.body;
// // Handle the optional parameters
// tankName = tankName ? tankName : null;
// tankLocation = tankLocation ? tankLocation.toLowerCase() : null;
// const filter = { customerId };
// // If tankName is not 'all', add it to the filter
// if (tankName && tankName !== "all") {
// filter.tankName = tankName;
// }
// // Only add tankLocation to the filter if tankName is not 'all'
// if (tankLocation && tankName !== "all") {
// filter.tankLocation = tankLocation;
// }
// console.log("Update filter:", JSON.stringify(filter, null, 2));
// // Check if tanks exist
// const matchingTanks = await Tank.find(filter);
// console.log("Matching tanks:", matchingTanks);
// if (matchingTanks.length === 0) {
// return reply.send({ status_code: 400, message: "No matching records found." });
// }
// // Define the update fields
// const updateData = {
// auto_min_percentage: String(auto_min_percentage || "20"),
// auto_max_percentage: String(auto_max_percentage || "80"),
// auto_mode_type: auto_mode_type || "default",
// };
// let result;
// if (tankName && tankName !== "all") {
// // Update only one tank if tankName is specified and not "all"
// result = await Tank.updateOne(filter, { $set: updateData });
// } else {
// // Update all tanks of the particular customer if tankName is "all"
// result = await Tank.updateMany(filter, { $set: updateData });
// }
// console.log("Update result:", result);
// reply.send({ status_code: 200, message: "Auto mode and percentages updated successfully." });
// } catch (error) {
// console.error(error);
// reply.send({ status_code: 500, message: "Internal server error." });
// }
// };
//storing water level for every 15 minutes
const getFormattedISTTime = () => {
return moment().tz('Asia/Kolkata').format('DD-MM-YYYY hh:mm:ss A');
};
const storeWaterLevels = async () => {
try {
const tanks = await Tank.find({});
const currentTime = getFormattedISTTime();
const waterLevelRecords = tanks.map(tank => ({
customerId: tank.customerId,
tankName: tank.tankName,
tankLocation: tank.tankLocation,
waterlevel: tank.waterlevel,
time: currentTime
}));
await TankWaterLevel.insertMany(waterLevelRecords);
console.log('Water levels stored successfully');
} catch (error) {
console.error('Error storing water levels:', error);
}
};
setInterval(storeWaterLevels, 15 * 60 * 1000);
console.log('Cron job scheduled to update water levels at midnight');
exports.getBlockData = async (req, reply) => {
try {
const customerId = req.params.customerId;
// Get all tank documents for the current customerId
const tanks = await Tank.find({ customerId });
// Extract the blockName from each tank
const blockNames = tanks.map(tank => tank.blockName);
// Remove duplicates by converting the array to a Set and then back to an array
const uniqueBlockNames = [...new Set(blockNames)];
// Add "all" and "nduku sneha antha kopam" to the block names
uniqueBlockNames.unshift("All");
// Send the unique blockNames in the response
reply.code(200).send({ blockNames: uniqueBlockNames });
} catch (err) {
// Log the error for debugging purposes
console.error(err);
// Send an error response
reply.code(500).send({ error: err.message });
}
};
// const mqtt = require('mqtt');
// // const moment = require('moment-timezone');
// // const IotData = require('./models/IotData'); // Replace with your actual model
// // const Tank = require('./models/Tank'); // Replace with your actual model
// // A map to keep track of MQTT clients by hw_Id
// const mqttClients = new Map();
// // Function to create a new MQTT client for a specific hw_Id
// function createMqttClient(hw_Id) {
// const client = mqtt.connect('mqtt://35.207.198.4:1883'); // Connect to the MQTT broker
// client.on('connect', () => {
// console.log(`Client for hw_Id ${hw_Id} connected to MQTT broker`);
// client.subscribe('water/iot-data', (err) => {
// if (err) {
// console.error(`Error subscribing to topic for hw_Id ${hw_Id}:`, err);
// } else {
// console.log(`Client for hw_Id ${hw_Id} subscribed to water/iot-data topic`);
// }
// });
// });
// client.on('message', async (topic, message) => {
// if (topic === 'water/iot-data') {
// try {
// const data = JSON.parse(message.toString());
// const { hw_Id: receivedHwId, Motor_status, tanks } = data.objects;
// // Ensure we process data only for the current client
// if (receivedHwId !== hw_Id) return;
// // Get the current date and time
// const currentDate = new Date();
// const date = currentDate.toISOString(); // ISO string for date
// const time = currentDate.toLocaleTimeString('en-IN', { hour12: false, timeZone: 'Asia/Kolkata' }); // Time in 'HH:MM:SS'
// // Create tank documents for the received tanks
// const tankDocuments = tanks.map(tank => ({
// tankhardwareId: tank.Id,
// tankHeight: tank.level,
// date,
// time
// }));
// // Save IoT data
// const iotTankData = new IotData({
// hardwareId: receivedHwId,
// Motor_status,
// tanks: tankDocuments,
// date,
// time
// });
// await iotTankData.save();
// // Delete excess records (keep only the latest three)
// const recordsToKeep = 3;
// const recordsToDelete = await IotData.find({ hardwareId: receivedHwId })
// .sort({ date: -1, time: -1 })
// .skip(recordsToKeep);
// for (const record of recordsToDelete) {
// await record.remove();
// }
// // Process tanks
// for (const tank of tanks) {
// const { Id: tankhardwareId, level: tankHeight } = tank;
// const existingTank = await Tank.findOne({ hardwareId: receivedHwId, tankhardwareId });
// if (!existingTank) continue;
// const customerId = existingTank.customerId;
// const tank_name = existingTank.tankName;
// const tankHeightInCm = (parseInt(existingTank.height.replace(/,/g, ''), 10)) * 30.48;
// const tank_height = parseInt(tankHeightInCm.toFixed(0), 10);
// const waterLevelHeight = tank_height - tankHeight;
// const waterCapacityPerCm = parseInt(existingTank.waterCapacityPerCm.replace(/,/g, ''), 10);
// const waterLevel = parseInt(waterLevelHeight * waterCapacityPerCm, 10);
// if (tankHeight > 0 && waterLevel >= 0) {
// existingTank.waterlevel = waterLevel;
// await existingTank.save();
// for (const outputConnection of existingTank.connections.outputConnections) {
// const linkedTank = await Tank.findOne({
// customerId,
// tankName: outputConnection.outputConnections,
// tankLocation: outputConnection.output_type
// });
// if (linkedTank) {
// for (const inputConnection of linkedTank.connections.inputConnections) {
// if (inputConnection.inputConnections === tank_name) {
// inputConnection.water_level = waterLevel;
// await linkedTank.save();
// }
// }
// }
// }
// }
// }
// // Update motor status
// const status = Motor_status;
// const motorTank = await Tank.findOne({ "connections.inputConnections.motor_id": receivedHwId });
// if (motorTank) {
// const inputConnection = motorTank.connections.inputConnections.find(conn => conn.motor_id === receivedHwId);
// if (inputConnection) {
// inputConnection.motor_status = status;
// if (inputConnection.motor_stop_status === "1" && status === 2 && inputConnection.motor_on_type !== "forced_manual") {
// const currentTime = moment().tz('Asia/Kolkata').format('DD-MMM-YYYY - HH:mm');
// inputConnection.motor_stop_status = "2";
// inputConnection.motor_on_type = "forced_manual";
// inputConnection.startTime = currentTime;
// }
// if (inputConnection.motor_stop_status === "2" && status === 1) {
// inputConnection.motor_stop_status = "1";
// }
// await motorTank.save();
// }
// }
// console.log(`Data processed successfully for hw_Id: ${receivedHwId}`);
// } catch (err) {
// console.error(`Error processing message for hw_Id ${hw_Id}:`, err.message);
// }
// }
// });
// return client;
// }
// // Handle incoming MQTT messages for water/iot-data topic
// const mainClient = mqtt.connect('mqtt://35.207.198.4:1883');
// mainClient.on('connect', () => {
// console.log('Main client connected to MQTT broker');
// mainClient.subscribe('water/iot-data', (err) => {
// if (err) {
// console.error('Error subscribing to water/iot-data topic:', err);
// }
// });
// });
// mainClient.on('message', (topic, message) => {
// if (topic === 'water/iot-data') {
// try {
// const data = JSON.parse(message.toString());
// const { hw_Id } = data.objects;
// if (!mqttClients.has(hw_Id)) {
// const client = createMqttClient(hw_Id);
// mqttClients.set(hw_Id, client);
// }
// } catch (err) {
// console.error('Error handling message in main client:', err.message);
// }
// }
// });
const mqtt = require('mqtt');
const client = mqtt.connect('mqtt://35.207.198.4:1883'); // Connect to MQTT broker
client.on('connect', () => {
console.log('Connected to MQTT broker');
client.subscribe('water/iot-data', (err) => {
if (err) {
console.error('Error subscribing to topic:', err);
} else {
console.log('Subscribed to water/iot-data topic');
}
});
});
// client.on("message", async (topic, message) => {
// console.log(`📩 Message received on topic ${topic}:`, message.toString());
// if (topic === "water/iot-data") {
// try {
// const data = JSON.parse(message.toString());
// const { hw_Id, Motor_status, tanks } = data.objects;
// const currentDate = new Date();
// const time = currentDate.toLocaleTimeString("en-IN", { hour12: false, timeZone: "Asia/Kolkata" });
// 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 tankName = existingTank.tankName;
// console.log(`🔍 Checking FCM tokens for Customer ID: ${customerId}`);
// const users = await User.find({ customerId }).select("fcmIds");
// let fcmTokens = users.flatMap(user => user.fcmIds).filter(token => token);
// console.log(`📡 Found ${fcmTokens.length} FCM tokens for Customer ID: ${customerId}`);
// if (!Array.isArray(fcmTokens) || fcmTokens.length === 0) {
// console.warn(`⚠️ No valid FCM tokens found for Customer ID: ${customerId}`);
// continue;
// }
// const motorTank = await Tank.findOne({ "connections.inputConnections.motor_id": hw_Id });
// if (!motorTank) {
// console.warn(`⚠️ Motor not found for motor_id: ${hw_Id}`);
// return;
// }
// const inputConnection = motorTank.connections.inputConnections.find(conn => conn.motor_id === hw_Id);
// console.log(`📢 Emitting 'sendMotorStartNotification' for hw_Id: ${hw_Id}`);
// if (inputConnection) {
// const blockName = motorTank.blockName || "N/A";
// console.log(`🚀 blockName`, blockName);
// console.log("🔍 Debugging Condition Check:");
// console.log("🛠️ inputConnection.motor_stop_status:", inputConnection.motor_stop_status);
// console.log("🛠️ Motor_status:", Motor_status);
// console.log("🛠️ inputConnection.motor_on_type:", inputConnection.motor_on_type);
// if (inputConnection.motor_stop_status == 1 && Motor_status == 2) { // Removed forced_manual check
// inputConnection.motor_stop_status = "2";
// inputConnection.motor_on_type = "forced_manual";
// inputConnection.startTime = new Date().toISOString();
// console.log("🚀 Motor started in FORCED_MANUAL mode.");
// console.log("📢 Emitting sendMotorStartNotification event...");
// eventEmitter.emit(
// "sendMotorStartNotification",
// hw_Id,
// customerId,
// fcmTokens,
// inputConnection.water_level || 0,
// blockName,
// tankName,
// "forced_manual",
// inputConnection.stop_criteria,
// inputConnection.typeOfWater,
// inputConnection.manual_threshold_time
// );
// await motorTank.markModified("connections.inputConnections");
// await motorTank.save(); // Ensure the change is saved
// console.log("💾 motorTank saved successfully.");
// }
// console.log("🛠️ Debugging Motor Stop Condition:");
// console.log("🛠️ inputConnection.motor_stop_status:", inputConnection.motor_stop_status);
// console.log("🛠️ Motor_status:", Motor_status);
// if (inputConnection.motor_stop_status == 2 && Motor_status == 1) {
// console.log("🛑 Motor stopping... Updating motor_stop_status.");
// inputConnection.motor_stop_status = 1;
// inputConnection.stopTime = new Date().toISOString();
// console.log("📢 Emitting sendMotorStopNotification event...");
// eventEmitter.emit(
// "sendMotorStopNotification",
// hw_Id,
// customerId,
// fcmTokens,
// inputConnection.water_level || 0,
// blockName,
// tankName,
// "forced_manual",
// inputConnection.typeOfWater
// );
// await motorTank.markModified("connections.inputConnections");
// await motorTank.save();
// console.log("💾 motorTank saved successfully.");
// } else {
// console.log("❌ Stop condition not met. No notification sent.");
// }
// }
// }
// console.log(`✅ Data processed successfully for hardwareId: ${hw_Id}`);
// } catch (err) {
// console.error(`❌ Error processing message: ${err.message}`);
// }
// }
// });
// client.on("message", async (topic, message) => {
// console.log(`📩 Message received on topic ${topic}:`, message.toString());
// if (topic === "water/iot-data") {
// try {
// const data = JSON.parse(message.toString());
// const { hw_Id, Motor_status, tanks } = data.objects;
// for (const tank of tanks) {
// const { Id: tankhardwareId } = tank;
// const existingTank = await Tank.findOne({ hardwareId: hw_Id, tankhardwareId });
// if (!existingTank) continue;
// const customerId = existingTank.customerId;
// const tankName = existingTank.tankName;
// console.log(`🔍 Checking FCM tokens for Customer ID: ${customerId}`);
// const users = await User.find({ customerId }).select("fcmIds");
// let fcmTokens = users.flatMap(user => user.fcmIds).filter(token => token);
// console.log(`📡 Found ${fcmTokens.length} FCM tokens for Customer ID: ${customerId}`);
// if (!Array.isArray(fcmTokens) || fcmTokens.length === 0) {
// console.warn(`⚠️ No valid FCM tokens found for Customer ID: ${customerId}`);
// continue;
// }
// const motorTank = await Tank.findOne({ "connections.inputConnections.motor_id": hw_Id });
// if (!motorTank) {
// console.warn(`⚠️ Motor not found for motor_id: ${hw_Id}`);
// return;
// }
// const inputConnection = motorTank.connections.inputConnections.find(conn => conn.motor_id === hw_Id);
// if (!inputConnection) {
// console.warn(`⚠️ No inputConnection found for motor_id: ${hw_Id}`);
// return;
// }
// console.log(`📢 Processing motor logic for hw_Id: ${hw_Id}`);
// const blockName = motorTank.blockName || "N/A";
// console.log("🔍 Debugging Condition Check:");
// console.log("🛠️ inputConnection.motor_stop_status:", inputConnection.motor_stop_status);
// console.log("🛠️ Motor_status:", Motor_status);
// console.log("🛠️ inputConnection.motor_on_type:", inputConnection.motor_on_type);
// /** 🔥 MOTOR START LOGIC */
// if (Motor_status === 2 && inputConnection.motor_stop_status === 1) {
// // Only update if motor_stop_status is still 1 (motor was previously OFF)
// inputConnection.motor_stop_status = 2;
// inputConnection.motor_on_type = "forced_manual";
// inputConnection.startTime = new Date().toISOString();
// console.log("🚀 Motor started. Updating motor_stop_status to 2.");
// console.log("📢 Emitting sendMotorStartNotification event...");
// eventEmitter.emit(
// "sendMotorStartNotification",
// hw_Id,
// customerId,
// fcmTokens,
// inputConnection.water_level || 0,
// blockName,
// tankName,
// "forced_manual",
// inputConnection.stop_criteria,
// inputConnection.typeOfWater,
// inputConnection.manual_threshold_time
// );
// await motorTank.markModified("connections.inputConnections");
// await motorTank.save();
// console.log("💾 motorTank saved successfully after start.");
// }
// /** 🔥 MOTOR STOP LOGIC */
// console.log("🛠️ Debugging Motor Stop Condition:");
// console.log("🛠️ inputConnection.motor_stop_status:", inputConnection.motor_stop_status);
// console.log("🛠️ Motor_status:", Motor_status);
// if (Motor_status === 1 && inputConnection.motor_stop_status === 2) {
// // Only update if motor_stop_status was previously 2 (motor was ON)
// console.log("🛑 Motor stopping... Updating motor_stop_status to 1.");
// inputConnection.motor_stop_status = 1;
// inputConnection.stopTime = new Date().toISOString();
// console.log("📢 Emitting sendMotorStopNotification event...");
// eventEmitter.emit(
// "sendMotorStopNotification",
// hw_Id,
// customerId,
// fcmTokens,
// inputConnection.water_level || 0,
// blockName,
// tankName,
// "forced_manual",
// inputConnection.typeOfWater
// );
// await motorTank.markModified("connections.inputConnections");
// await motorTank.save();
// console.log("💾 motorTank saved successfully after stop.");
// } else {
// console.log("⚠️ Stop condition not met. No notification sent.");
// }
// }
// console.log(`✅ Data processed successfully for hardwareId: ${hw_Id}`);
// } catch (err) {
// console.error(`❌ Error processing message: ${err.message}`);
// }
// }
// });
// Handling incoming MQTT messages important
// client.on('message', async (topic, message) => {
// console.log(`Message received on topic ${topic}:`, message.toString());
// if (topic === 'water/iot-data') {
// try {
// const data = JSON.parse(message.toString());
// const { hw_Id, Motor_status, tanks } = data.objects; // Updated variable names according to new format
// // Get the current date and time in the required format
// const currentDate = new Date();
// const date = currentDate.toISOString(); // ISO string for date
// const time = currentDate.toLocaleTimeString('en-IN', { hour12: false, timeZone: 'Asia/Kolkata' }); // Time in 'HH:MM:SS'
// // Create array of tank documents with current date and time
// const tankDocuments = tanks.map(tank => ({
// tankhardwareId: tank.Id, // Updated to match the new format
// tankHeight: tank.level, // Updated to match the new format
// date,
// time
// }));
// // Save IoT data for the received tanks
// const iotTankData = new IotData({
// hardwareId: hw_Id, // Updated variable name
// Motor_status,
// tanks: tankDocuments,
// date,
// time
// });
// await iotTankData.save();
// // Delete excess records (keep only the latest three records)
// const recordsToKeep = 3;
// const recordsToDelete = await IotData.find({ hardwareId: hw_Id }) // Updated variable name
// .sort({ date: -1, time: -1 })
// .skip(recordsToKeep);
// for (const record of recordsToDelete) {
// await record.remove();
// }
// // Process each tank to update water level and connections
// for (const tank of tanks) {
// const { Id: tankhardwareId, level: tankHeight } = tank; // Updated to match the new format
// // Find the corresponding tank in the Tank schema using hardwareId and tankhardwareId
// const existingTank = await Tank.findOne({ hardwareId: hw_Id, tankhardwareId }); // Updated variable name
// if (!existingTank) continue;
// const customerId = existingTank.customerId;
// const tank_name = existingTank.tankName;
// // Calculate water level using tank height and capacity
// const tankHeightInCm = (parseInt(existingTank.height.replace(/,/g, ''), 10)) * 30.48; // Convert height to cm
// const tank_height = parseInt(tankHeightInCm.toFixed(0), 10);
// const waterLevelHeight = tank_height - tankHeight;
// const waterCapacityPerCm = parseInt(existingTank.waterCapacityPerCm.replace(/,/g, ''), 10);
// const waterLevel = parseInt(waterLevelHeight * waterCapacityPerCm, 10); // Calculated water level
// // Update water level in the existing tank
// console.log(tankHeight,"this is located in tank controllers at iot-data mqtt sub ")
// if (tankHeight>0 && waterLevel >= 0) {
// existingTank.waterlevel = waterLevel;
// await existingTank.save();
// // Update linked tanks (input/output connections)
// for (const outputConnection of existingTank.connections.outputConnections) {
// const linkedTank = await Tank.findOne({ customerId, tankName: outputConnection.outputConnections, tankLocation: outputConnection.output_type });
// if (linkedTank) {
// for (const inputConnection of linkedTank.connections.inputConnections) {
// if (inputConnection.inputConnections === tank_name) {
// inputConnection.water_level = waterLevel; // Update water level for linked tank
// await linkedTank.save(); // Save updated linked tank
// }
// }
// }
// }
// }
// }
// // Update motor status
// const status = Motor_status;
// const motorTank = await Tank.findOne({ "connections.inputConnections.motor_id": hw_Id }); // Updated variable name
// if (!motorTank) {
// console.log('Motor not found for the specified motor_id');
// return;
// }
// // Find the inputConnection for the motor and update motor status
// const inputConnection = motorTank.connections.inputConnections.find(conn => conn.motor_id === hw_Id); // Updated variable name
// const user = await User.findOne({ customerId: motorTank.customerId }); // Fetch user by customerId
// const allowNotifications = user?.manualStartAndStopNotify ?? true; // Default to true if not set
// if (!motorTank) {
// console.warn(`⚠️ Motor not found for motor_id: ${hw_Id}`);
// return;
// }
// if (!inputConnection) {
// console.warn(`⚠️ No inputConnection found for motor_id: ${hw_Id}`);
// return;
// }
// if (inputConnection) {
// inputConnection.motor_status = status; // Update motor status
// const tankName = motorTank.tankName;
// const customerId = motorTank.customerId;
// console.log("tankName",tankName)
// console.log("customerId", customerId)
// console.log("status", status)
// // Ensure fcmTokens are fetched before emitting
// // const user = await User.findOne({ customerId: motorTank.customerId }).select("fcmIds manualStartAndStopNotify");
// // const fcmTokens = user?.fcmIds || []; // Ensure fcmTokens is an array
// // console.log("fcmTokens", fcmTokens)
// const users = await User.findOne({ customerId : motorTank.customerId}).select("fcmIds");
// let fcmTokens = users.fcmIds.filter(token => token);
// console.log(`📡 Found ${fcmTokens.length} FCM tokens for Customer ID: ${customerId}`);
// if (!Array.isArray(fcmTokens) || fcmTokens.length === 0) {
// console.warn(`⚠️ No valid FCM tokens found for Customer ID: ${customerId}`);
// }
// console.log(`📢 Processing motor logic for hw_Id: ${hw_Id}`);
// const blockName = motorTank.blockName || "N/A";
// console.log("🔍 Debugging Condition Check:");
// console.log("🛠️ inputConnection.motor_stop_status:", inputConnection.motor_stop_status);
// console.log("🛠️ Motor_status:", status);
// console.log("🛠inputConnection.motor_status:", inputConnection.motor_status);
// console.log("🛠️ inputConnection.motor_on_type:", inputConnection.motor_on_type);
// // if (status === 2 && inputConnection.motor_stop_status === "1" && inputConnection.motor_on_type !== "forced_manual") {
// // // Only update if motor_stop_status is still 1 (motor was previously OFF)
// // inputConnection.motor_stop_status ="2";
// // inputConnection.motor_on_type = "forced_manual";
// // inputConnection.startTime = new Date().toISOString();
// // // status = 1;
// // // inputConnection.motor_status = "1";
// // console.log("🛠️ IN inputConnection.motor_stop_status:", inputConnection.motor_stop_status);
// // console.log("🛠In Motor_status:", status);
// // console.log("🛠In inputConnection.motor_status:", inputConnection.motor_status);
// // console.log("🚀 Motor started. Updating motor_stop_status to 2.");
// // console.log("📢 Emitting sendMotorStartNotification event...");
// // await motorTank.markModified("connections.inputConnections");
// // await motorTank.save();
// // console.log("💾 motorTank saved successfully after start.");
// // eventEmitter.emit(
// // "sendMotorStartNotification",
// // hw_Id,
// // customerId,
// // fcmTokens,
// // inputConnection.water_level || 0,
// // blockName,
// // tankName,
// // "forced_manual",
// // inputConnection.stop_criteria,
// // inputConnection.typeOfWater,
// // inputConnection.manual_threshold_time
// // );
// // }
// // console.log(`🔍 Checking stop condition: status=${status}, motor_stop_status=${inputConnection.motor_stop_status}`);
// // if (status === 1 && inputConnection.motor_stop_status === "2") {
// // console.log("🛑 Motor stopping... Updating motor_stop_status to 1.");
// // inputConnection.motor_stop_status = "1";
// // inputConnection.stopTime = new Date().toISOString();
// // await motorTank.markModified("connections.inputConnections");
// // await motorTank.save(); // Ensure data is saved before emitting
// // console.log("📢 Emitting sendMotorStopNotification event...");
// // eventEmitter.emit(
// // "sendMotorStopNotification",
// // hw_Id,
// // customerId,
// // fcmTokens,
// // inputConnection.water_level || 0,
// // blockName,
// // tankName,
// // "forced_manual",
// // inputConnection.typeOfWater
// // );
// // }
// // if (status === 2 && inputConnection.motor_stop_status === "1" && inputConnection.motor_on_type !== "forced_manual") {
// // // Motor is starting (only execute this block)
// // inputConnection.motor_stop_status = "2"; // Motor is now running
// // inputConnection.motor_on_type = "forced_manual";
// // inputConnection.startTime = new Date().toISOString();
// // console.log("🚀 Motor started. Updating motor_stop_status to 2.");
// // console.log("📢 Emitting sendMotorStartNotification event...");
// // await motorTank.markModified("connections.inputConnections");
// // await motorTank.save();
// // console.log("💾 motorTank saved successfully after start.");
// // eventEmitter.emit(
// // "sendMotorStartNotification",
// // hw_Id,
// // customerId,
// // fcmTokens,
// // inputConnection.water_level || 0,
// // blockName,
// // tankName,
// // "forced_manual",
// // inputConnection.stop_criteria,
// // inputConnection.typeOfWater,
// // inputConnection.manual_threshold_time
// // );
// // } else if (status === 1 && inputConnection.motor_stop_status === "2") {
// // // Motor is stopping (only execute this block)
// // console.log("🛑 Motor stopping... Updating motor_stop_status to 1.");
// // inputConnection.motor_stop_status = "1"; // Motor is now OFF
// // inputConnection.stopTime = new Date().toISOString();
// // await motorTank.markModified("connections.inputConnections");
// // await motorTank.save(); // Ensure data is saved before emitting
// // console.log("📢 Emitting sendMotorStopNotification event...");
// // eventEmitter.emit(
// // "sendMotorStopNotification",
// // hw_Id,
// // customerId,
// // fcmTokens,
// // inputConnection.water_level || 0,
// // blockName,
// // tankName,
// // "forced_manual",
// // inputConnection.typeOfWater
// // );
// // }
// console.log(`🔍 Final condition: status=${status}, motor_stop_status=${inputConnection.motor_stop_status}`);
// await motorTank.save(); // Save the updated tank
// }
// console.log('Data processed successfully for hardwareId:', hw_Id); // Updated variable name
// } catch (err) {
// console.error('Error processing message:', err.message);
// }
// }
// });
client.on('message', async (topic, message) => {
console.log(`Message received on topic ${topic}:`, message.toString());
if (topic === 'water/iot-data') {
try {
const data = JSON.parse(message.toString());
const { hw_Id, Motor_status, tanks } = data.objects; // Updated variable names according to new format
// Get the current date and time in the required format
const currentDate = new Date();
const date = currentDate.toISOString(); // ISO string for date
const time = currentDate.toLocaleTimeString('en-IN', { hour12: false, timeZone: 'Asia/Kolkata' }); // Time in 'HH:MM:SS'
// Create array of tank documents with current date and time
const tankDocuments = tanks.map(tank => ({
tankhardwareId: tank.Id, // Updated to match the new format
tankHeight: tank.level, // Updated to match the new format
date,
time
}));
// Save IoT data for the received tanks
const iotTankData = new IotData({
hardwareId: hw_Id, // Updated variable name
Motor_status,
tanks: tankDocuments,
date,
time
});
await iotTankData.save();
// Delete excess records (keep only the latest three records)
const recordsToKeep = 3;
const recordsToDelete = await IotData.find({ hardwareId: hw_Id }) // Updated variable name
.sort({ date: -1, time: -1 })
.skip(recordsToKeep);
for (const record of recordsToDelete) {
await record.remove();
}
// Process each tank to update water level and connections
for (const tank of tanks) {
const { Id: tankhardwareId, level: tankHeight } = tank; // Updated to match the new format
// Find the corresponding tank in the Tank schema using hardwareId and tankhardwareId
const existingTank = await Tank.findOne({ hardwareId: hw_Id, tankhardwareId }); // Updated variable name
if (!existingTank) continue;
const customerId = existingTank.customerId;
const tank_name = existingTank.tankName;
// Calculate water level using tank height and capacity
const tankHeightInCm = (parseInt(existingTank.height.replace(/,/g, ''), 10)) * 30.48; // Convert height to cm
const tank_height = parseInt(tankHeightInCm.toFixed(0), 10);
const waterLevelHeight = tank_height - tankHeight;
const waterCapacityPerCm = parseInt(existingTank.waterCapacityPerCm.replace(/,/g, ''), 10);
const waterLevel = parseInt(waterLevelHeight * waterCapacityPerCm, 10); // Calculated water level
// Update water level in the existing tank
console.log(tankHeight,"this is located in tank controllers at iot-data mqtt sub ")
if (tankHeight>0 && waterLevel >= 0) {
existingTank.waterlevel = waterLevel;
await existingTank.save();
// Update linked tanks (input/output connections)
for (const outputConnection of existingTank.connections.outputConnections) {
const linkedTank = await Tank.findOne({ customerId, tankName: outputConnection.outputConnections, tankLocation: outputConnection.output_type });
if (linkedTank) {
for (const inputConnection of linkedTank.connections.inputConnections) {
if (inputConnection.inputConnections === tank_name) {
inputConnection.water_level = waterLevel; // Update water level for linked tank
await linkedTank.save(); // Save updated linked tank
}
}
}
}
}
}
// Update motor status
const status = Motor_status;
const motorTank = await Tank.findOne({ "connections.inputConnections.motor_id": hw_Id }); // Updated variable name
if (!motorTank) {
console.log('Motor not found for the specified motor_id');
return;
}
// Find the inputConnection for the motor and update motor status
const inputConnection = motorTank.connections.inputConnections.find(conn => conn.motor_id === hw_Id); // Updated variable name
if (inputConnection) {
inputConnection.motor_status = status; // Update motor status
if (inputConnection.motor_stop_status === "1" && status === 2 && inputConnection.motor_on_type !== "forced_manual") {
const currentTime = moment().tz('Asia/Kolkata').format('DD-MMM-YYYY - HH:mm');
inputConnection.motor_stop_status = "2";
inputConnection.motor_on_type = "forced_manual";
inputConnection.startTime = currentTime;
}
if (inputConnection.motor_stop_status === "2" && status === 1) {
const currentTime = moment().tz('Asia/Kolkata').format('DD-MMM-YYYY - HH:mm');
inputConnection.motor_stop_status = "1";
inputConnection.stopTime = currentTime;
}
await motorTank.save(); // Save the updated tank
}
console.log('Data processed successfully for hardwareId:', hw_Id); // Updated variable name
} catch (err) {
console.error('Error processing message:', err.message);
}
}
});
exports.getPendingAndCompletedsurveyOfparticularInstaller = async (request, reply) => {
try {
const { installationId } = request.params;
const survey_status = request.body;
const surveydata = await User.find({
installationId,
survey_status,
});
// Send the response, including both total consumption and filtered consumption records
reply.send({
status_code: 200,
surveydata,
});
} catch (err) {
throw boom.boomify(err);
}
};
exports.getPendingAndCompletedsurveyOfparticularInstaller = async (request, reply) => {
try {
const { installationId } = request.params;
const survey_status = request.body;
const surveydata = await User.find({
installationId,
survey_status,
});
// Send the response, including both total consumption and filtered consumption records
reply.send({
status_code: 200,
surveydata,
});
} catch (err) {
throw boom.boomify(err);
}
};
exports.consumptionofparticulartank = async (request, reply) => {
try {
const { customerId } = request.params;
const { startDate, stopDate, tankName, tankLocation, block } = request.body;
// Convert input dates into proper JavaScript Date objects for comparison
const start = moment(startDate, "DD-MMM-YYYY - HH:mm").toDate();
const end = moment(stopDate, "DD-MMM-YYYY - HH:mm").toDate();
// Find the tank by customerId, tankLocation, and tankName
const tank = await Tank.findOne({
customerId,
tankLocation: tankLocation || "overhead", // Default to "overhead" if not provided
tankName,
});
if (!tank) {
return reply.status(404).send({
status_code: 404,
message: "Tank not found",
});
}
const waterlevel_at_midnight = parseInt(tank.waterlevel_at_midnight.replace(/,/g, ""), 10);
const total_water_added_from_midnight = parseInt(tank.total_water_added_from_midnight.replace(/,/g, ""), 10);
const waterlevel = parseInt(tank.waterlevel.replace(/,/g, ""), 10);
// Fetch all records for the tank (no date filtering yet)
const tankConsumptions = await TankConsumptionOriginalSchema.find({
customerId,
tankName,
tankLocation: tankLocation,
});
// Filter records in JavaScript by comparing the 'time' field after converting to Date
const filteredConsumptions = tankConsumptions.filter((record) => {
const recordTime = moment(record.time, "DD-MMM-YYYY - HH:mm").toDate();
return recordTime >= start && recordTime <= end;
});
// Sort filtered records by date (ascending)
filteredConsumptions.sort((a, b) => {
const dateA = moment(a.time, "DD-MMM-YYYY - HH:mm").toDate();
const dateB = moment(b.time, "DD-MMM-YYYY - HH:mm").toDate();
return dateA - dateB; // Sort in ascending order
});
// Calculate total consumption from filtered records
const total_consumption_from_records = filteredConsumptions.reduce((acc, record) => {
return acc + parseInt(record.consumption, 10);
}, 0);
// Calculate final consumption
const consumption = (waterlevel_at_midnight + total_water_added_from_midnight) - waterlevel + total_consumption_from_records;
// Prepare response data
const tankData = {
tankname: tank.tankName,
totalConsumption: consumption,
block: tank.blockName,
TypeofWater: tank.typeOfWater,
location: tank.tankLocation,
capacity: tank.capacity,
waterlevel: tank.waterlevel,
};
// Send the response, including both total consumption and filtered consumption records
reply.send({
status_code: 200,
tankData,
totalConsumption: consumption,
consumptionRecords: filteredConsumptions,
});
} catch (err) {
throw boom.boomify(err);
}
};
// // Set start and end dates
// const startDate = new Date("2024-08-20T00:00:00Z");
// const endDate = new Date("2024-11-04T00:00:00Z");
// // Tank names array with respective blocks
// const tanks = [
// { tankName: "REAL TANK OH", block: "A" },
// { tankName: "DUMMY TANK OH1", block: "BLOCK C" },
// { tankName: "DUMMY TANK OH2", block: "BLOCK D" },
// { tankName: "DUMMY TANK OH3", block: "BLOCK C" },
// { tankName: "DUMMY TANK OH4", block: "BLOCK C" },
// { tankName: "DUMMY TANK OH5", block: "BLOCK C" },
// { tankName: "DUMMY TANK OH6", block: "BLOCK C" }
// ];
// const customerId = "AWSUSKY4";
// const tankLocation = "overhead";
// const typeofwater = "Bore Water";
// // Function to format date to "DD-MMM-YYYY - HH:mm"
// function formatDateCustom(date) {
// const options = { day: '2-digit', month: 'short', year: 'numeric' };
// return date.toLocaleDateString('en-GB', options).replace(/ /g, '-') + " - 23:55";
// }
// // Main function to generate data
// async function generateData() {
// for (let date = new Date(startDate); date <= endDate; date.setDate(date.getDate() + 1)) {
// const formattedDate = formatDateCustom(date); // Format date to "DD-MMM-YYYY - 23:55"
// for (const { tankName, block } of tanks) {
// try {
// const existingRecord = await TankConsumptionOriginalSchema.findOne({
// customerId: customerId,
// tankName: tankName,
// tankLocation: tankLocation,
// time: formattedDate
// }).exec();
// console.log(`Checking record for ${tankName} on ${formattedDate}: ${existingRecord ? 'Exists' : 'Does not exist'}`);
// if (!existingRecord) {
// // Random consumption between 7000 and 8000
// const randomConsumption = Math.floor(Math.random() * (8000 - 7000 + 1)) + 7000;
// // Create a new document and save it
// const newRecord = new TankConsumptionOriginalSchema({
// customerId: customerId,
// tankName: tankName,
// tankLocation: tankLocation,
// consumption: randomConsumption.toString(),
// time: formattedDate,
// block: block,
// typeofwater: typeofwater,
// __v: 0
// });
// await newRecord.save(); // Use .save() method to insert the record
// console.log(`Inserted record for ${tankName} on ${formattedDate}`);
// }
// } catch (error) {
// console.error(`Failed to check or insert record for ${tankName} on ${formattedDate}:`, error);
// }
// }
// }
// console.log("Data generation complete.");
// }
// // Run the data generation function
// generateData();
async function removeDuplicates () {
try {
// Step 1: Find duplicates, considering time and ignoring case for typeofwater
const duplicates = await TankConsumptionOriginalSchema.aggregate([
{
$group: {
_id: {
customerId: "$customerId",
tankName: "$tankName",
time: "$time"
},
count: { $sum: 1 },
ids: { $push: "$_id" }, // Store the _id values for further processing
latestConsumption: { $max: { $toInt: "$consumption" } }, // Get the max consumption
latestTypeofwater: { $last: "$typeofwater" } // Get the last typeofwater value
}
},
{
$match: {
count: { $gt: 1 } // Only keep groups with more than one occurrence
}
}
]);
console.log(`Found ${duplicates.length} groups of duplicates.`);
// Step 2: Prepare delete operations
for (const duplicateGroup of duplicates) {
// Filter the ids based on the maximum time to keep the latest entry
const idsToDelete = duplicateGroup.ids.filter(id => {
return id !== duplicateGroup.ids[0]; // Keep the first, delete the rest
});
for (const id of idsToDelete) {
try {
await TankConsumptionOriginalSchema.deleteOne({ _id: id });
console.log(`Deleted duplicate record with ID: ${id}`);
} catch (deleteError) {
console.error(`Failed to delete record with ID ${id}:`, deleteError);
}
}
}
console.log("Duplicate removal complete.");
} catch (error) {
console.error("Failed to remove duplicates:", error);
}
}
// Run the remove duplicates function
// removeDuplicates();
console.log("this is for testing autopush,line located in tankscontroller")
// const calculateDailyConsumptionAndNotify = async () => {
// try {
// const today = moment().startOf("day");
// const yesterday = moment(today).subtract(1, "days");
// // Fetch all active users
// const activeUsers = await User.find({ });
// for (const user of activeUsers) {
// const { customerId, fcmIds } = user;
// // Fetch daily consumption for the customer
// const consumptions = await TankConsumptionOriginalSchema.find({
// customerId,
// time: {
// $gte: yesterday.format("DD-MMM-YYYY - HH:mm"),
// $lt: today.format("DD-MMM-YYYY - HH:mm"),
// },
// });
// // Calculate total consumption
// const totalConsumption = consumptions.reduce((total, record) => {
// return total + parseInt(record.consumption, 10);
// }, 0);
// // Prepare tank-wise consumption details
// const tankDetails = consumptions.map((record) => ({
// tankName: record.tankName,
// consumption: record.consumption,
// }));
// // Send notification
// const notificationTitle = "Daily Water Consumption Report";
// const notificationBody = `
// Total Consumption: ${totalConsumption} liters
// Tank Details: ${tankDetails
// .map((tank) => `${tank.tankName}: ${tank.consumption} liters`)
// .join(", ")}
// `;
// if (fcmIds && fcmIds.length > 0) {
// await sendNotification(fcmIds, notificationTitle, notificationBody);
// }
// }
// console.log("Daily consumption notifications sent successfully.");
// } catch (err) {
// console.error("Error sending daily consumption notifications:", err);
// }
// };
// cron.schedule("0 11:57 * * *", async () => {
// console.log("Starting daily consumption notification task...");
// await calculateDailyConsumptionAndNotify();
// });
// cron.schedule(
// "0 9 * * *",
// async () => {
// console.log("Starting daily consumption notification task...");
// await calculateDailyConsumptionAndNotify();
// },
// {
// timezone: "Asia/Kolkata", // Specify the timezone
// }
// );
// const calculateDailyConsumptionAndNotify = async () => {
// try {
// const today = moment().startOf("day");
// const yesterday = moment(today).subtract(1, "days");
// // Fetch all active users
// const activeUsers = await User.find({});
// for (const user of activeUsers) {
// const { customerId, fcmIds } = user;
// // Fetch daily consumption for the customer
// const consumptions = await TankConsumptionOriginalSchema.find({
// customerId,
// time: {
// $gte: yesterday.format("DD-MMM-YYYY - HH:mm"),
// $lt: today.format("DD-MMM-YYYY - HH:mm"),
// },
// });
// // Calculate total consumption by type of water and the water level percentage
// const consumptionSummary = consumptions.reduce((acc, record) => {
// const typeOfWater = record.typeOfWater; // Assuming this field exists
// const consumption = parseInt(record.consumption, 10);
// const waterLevel = parseInt(record.waterLevel, 10); // Assuming waterLevel is in percentage
// if (!acc[typeOfWater]) {
// acc[typeOfWater] = {
// totalConsumption: 0,
// tankDetails: [],
// totalWaterLevel: 0,
// count: 0,
// };
// }
// acc[typeOfWater].totalConsumption += consumption;
// acc[typeOfWater].totalWaterLevel += waterLevel;
// acc[typeOfWater].count += 1;
// acc[typeOfWater].tankDetails.push({
// tankName: record.tankName,
// consumption,
// waterLevel,
// });
// return acc;
// }, {});
// // Prepare notification body
// let notificationBody = "Daily Water Consumption Report:\n";
// for (const type in consumptionSummary) {
// const { totalConsumption, tankDetails, totalWaterLevel, count } = consumptionSummary[type];
// const averageWaterLevel = (totalWaterLevel / count).toFixed(2); // Calculate average water level
// console.log("averageWaterLevel",averageWaterLevel)
// console.log("totalConsumption",totalConsumption)
// notificationBody += `
// Type of Water: ${type}
// Total Consumption: ${totalConsumption} liters
// Average Water Level: ${averageWaterLevel}%
// `;
// console.log("noti---" ,notificationBody += `
// Type of Water: ${type}
// Total Consumption: ${totalConsumption} liters
// Average Water Level: ${averageWaterLevel}%
// `)
// }
// if (fcmIds && fcmIds.length > 0) {
// await sendNotification(fcmIds, "Daily Water Consumption Report", notificationBody);
// }
// }
// console.log("Daily consumption notifications sent successfully.");
// } catch (err) {
// console.error("Error sending daily consumption notifications:", err);
// }
// };
const calculateDailyConsumptionAndNotify = async () => {
try {
const today = moment().startOf("day");
const yesterday = moment(today).subtract(1, "days");
// Fetch all active users
const activeUsers = await User.find({});
for (const user of activeUsers) {
const { customerId, fcmIds } = user;
// Fetch daily consumption for the customer
const consumptions = await TankConsumptionOriginalSchema.find({
customerId,
time: {
$gte: yesterday.format("DD-MMM-YYYY - HH:mm"),
$lt: today.format("DD-MMM-YYYY - HH:mm"),
},
});
// Calculate total consumption and capacities based on water type
let totalBoreConsumption = 0;
let totalDrinkingConsumption = 0;
let totalBoreCapacity = 0;
let totalDrinkingCapacity = 0;
for (const record of consumptions) {
const typeOfWater = record.typeOfWater; // Assuming this field exists
const consumption = parseInt(record.consumption, 10);
const capacity = parseInt(record.capacity, 10); // Assuming capacity field exists
if (typeOfWater === "bore" || typeOfWater === "Bore Water") {
totalBoreConsumption += consumption;
totalBoreCapacity += capacity;
} else if (typeOfWater === "drinking" || typeOfWater === "Drinking Water") {
totalDrinkingConsumption += consumption;
totalDrinkingCapacity += capacity;
}
}
// Calculate percentages
const boreConsumptionPercentage = totalBoreCapacity
? ((totalBoreConsumption / totalBoreCapacity) * 100).toFixed(2)
: 0;
const drinkingConsumptionPercentage = totalDrinkingCapacity
? ((totalDrinkingConsumption / totalDrinkingCapacity) * 100).toFixed(2)
: 0;
// Prepare notification body
const reportDate = yesterday.format("DD-MMM-YYYY");
let notificationBody = `Daily Water Consumption Report for ${reportDate}:\n`;
notificationBody += `Total Bore Consumption: ${totalBoreConsumption} liters\n`;
notificationBody += `Bore Water Consumption Percentage: ${boreConsumptionPercentage}%\n`;
notificationBody += `Total Drinking Consumption: ${totalDrinkingConsumption} liters\n`;
notificationBody += `Drinking Water Consumption Percentage: ${drinkingConsumptionPercentage}%\n`;
// Send notification if FCM IDs are present
if (fcmIds && fcmIds.length > 0) {
await sendNotification(fcmIds, "Daily Water Consumption Report", notificationBody);
}
}
console.log("Daily consumption notifications sent successfully.");
} catch (err) {
console.error("Error sending daily consumption notifications:", err);
}
};
// Schedule the cron job to run daily at 9 AM
// cron.schedule(
// "0 9 * * *",
// async () => {
// console.log("Starting daily consumption notification task...");
// await calculateDailyConsumptionAndNotify();
// },
// {
// timezone: "Asia/Kolkata", // Specify the timezone
// }
// );
const calculateConsumptionAndNotify = async () => {
try {
const now = moment(); // Current time
const sixHoursAgo = moment(now).subtract(6, 'hours').startOf('hour'); // 6 hours ago
// Fetch all active users
const activeUsers = await User.find({});
for (const user of activeUsers) {
const { customerId, fcmIds } = user;
// Fetch consumption records for the last 6 hours
const consumptions = await TankConsumptionOriginalSchema.find({
customerId,
time: {
$gte: sixHoursAgo.format("DD-MMM-YYYY - HH:mm"),
$lt: now.format("DD-MMM-YYYY - HH:mm"),
},
});
// Prepare notification body
let notificationBody = `Water Consumption Report (From ${sixHoursAgo.format(
"hh:mm A"
)} to ${now.format("hh:mm A")}):\n`;
const tankDetails = {};
// Aggregate consumption data by tank
for (const record of consumptions) {
const tankName = record.tankName; // Assuming this field exists
const tankLocation = record.tankLocation; // Assuming this field exists
const consumption = parseInt(record.consumption, 10); // Liters consumed
const typeOfWater = record.typeOfWater; // Type of water (e.g., bore, drinking)
const tankCapacity = parseInt(record.capacity, 10); // Tank capacity in liters
if (!tankDetails[tankName]) {
tankDetails[tankName] = {
tankLocation,
totalConsumption: 0,
typeOfWater,
tankCapacity,
};
}
tankDetails[tankName].totalConsumption += consumption;
}
// Format tank details for the notification
for (const tankName in tankDetails) {
const {
tankLocation,
totalConsumption,
typeOfWater,
tankCapacity,
} = tankDetails[tankName];
const consumptionPercentage = tankCapacity
? ((totalConsumption / tankCapacity) * 100).toFixed(2)
: 0;
notificationBody +=
`Tank Name: ${tankName} \n`+
`Location: ${tankLocation} \n`+
`Total Consumption: ${totalConsumption} liters ${consumptionPercentage}% \n`+
`Type of Water: ${typeOfWater}`;
}
// Send notification if FCM IDs are present
if (fcmIds && fcmIds.length > 0) {
await sendNotification(fcmIds, "Water Consumption Report", notificationBody);
}
}
console.log("Consumption notifications sent successfully.");
} catch (err) {
console.error("Error sending consumption notifications:", err);
}
};
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" });
}