|
|
|
@ -2624,91 +2624,109 @@ exports.raiseATicket = async (req, reply) => {
|
|
|
|
|
return reply.code(400).send({ error: "customerId and connected_to are required" });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const sensors = await Insensors.find({ customerId });
|
|
|
|
|
const sensors = await Insensors.find({ customerId }).lean();
|
|
|
|
|
const orders = await Order.find({ customerId }).lean();
|
|
|
|
|
|
|
|
|
|
if (!sensors.length) {
|
|
|
|
|
return reply.code(404).send({ message: "No sensors found for this customer." });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const masterSensor = sensors.find(s => s.hardwareId?.trim() === connected_to.trim() && s.type === "master");
|
|
|
|
|
|
|
|
|
|
if (!masterSensor) {
|
|
|
|
|
return reply.code(404).send({ message: "Master hardwareId not found." });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const orderMap = {};
|
|
|
|
|
orders.forEach(order => {
|
|
|
|
|
order.master_connections.forEach(conn => {
|
|
|
|
|
orderMap[conn.hardwareId] = {
|
|
|
|
|
masterName: conn.master_name || null,
|
|
|
|
|
location: conn.location || null
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const latestMasterRecord = await IotData.findOne({ hardwareId: connected_to }).sort({ date: -1 }).lean();
|
|
|
|
|
const now = moment.tz("Asia/Kolkata");
|
|
|
|
|
|
|
|
|
|
if (!latestMasterRecord) {
|
|
|
|
|
return reply.code(404).send({ message: "No IoT data found for this hardwareId." });
|
|
|
|
|
}
|
|
|
|
|
let masterConnectedStatus = "disconnected";
|
|
|
|
|
let lastDataTime = "No data";
|
|
|
|
|
let diffInMinutes = null;
|
|
|
|
|
|
|
|
|
|
if (latestMasterRecord?.date) {
|
|
|
|
|
const indiaTime = moment.tz(latestMasterRecord.date, "Asia/Kolkata");
|
|
|
|
|
const now = moment.tz("Asia/Kolkata");
|
|
|
|
|
const diffInMinutesMaster = now.diff(indiaTime, "minutes");
|
|
|
|
|
|
|
|
|
|
const masterDisconnected = diffInMinutesMaster > 1 ? [{
|
|
|
|
|
hardwareId: connected_to,
|
|
|
|
|
masterName: masterSensor.tankName || masterSensor.tankName || "Unknown Master",
|
|
|
|
|
// disconnectedAt: now.format("DD-MM-YYYY HH:mm:ss")
|
|
|
|
|
}] : [];
|
|
|
|
|
diffInMinutes = now.diff(indiaTime, "minutes");
|
|
|
|
|
lastDataTime = indiaTime.format("DD-MM-YYYY HH:mm:ss");
|
|
|
|
|
masterConnectedStatus = diffInMinutes <= 1 ? "connected" : "disconnected";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const connectedSlaves = sensors.filter(sensor =>
|
|
|
|
|
sensor.connected_to?.trim() === connected_to.trim() &&
|
|
|
|
|
sensor.type === "slave"
|
|
|
|
|
const connectedSlaves = sensors.filter(s =>
|
|
|
|
|
s.connected_to?.trim() === connected_to.trim() && s.type === "slave"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const formattedSlaves = [];
|
|
|
|
|
const disconnectedSlaves = [];
|
|
|
|
|
|
|
|
|
|
for (const slave of connectedSlaves) {
|
|
|
|
|
const slaveId = slave.hardwareId?.trim();
|
|
|
|
|
const matchedTank = latestMasterRecord.tanks.find(tank => tank.tankhardwareId === slaveId);
|
|
|
|
|
const slaveData = latestMasterRecord?.tanks.find(t => t.tankhardwareId === slave.hardwareId);
|
|
|
|
|
let slaveStatus = "disconnected";
|
|
|
|
|
let lastSlaveDataTime = "No data";
|
|
|
|
|
let slaveDiff = null;
|
|
|
|
|
|
|
|
|
|
if (matchedTank && matchedTank.date) {
|
|
|
|
|
const tankTime = moment.tz(matchedTank.date, "Asia/Kolkata");
|
|
|
|
|
const loraDiffInMinutes = now.diff(tankTime, "minutes");
|
|
|
|
|
if (slaveData?.date) {
|
|
|
|
|
const slaveTime = moment.tz(slaveData.date, "Asia/Kolkata");
|
|
|
|
|
slaveDiff = now.diff(slaveTime, "minutes");
|
|
|
|
|
lastSlaveDataTime = slaveTime.format("DD-MM-YYYY HH:mm:ss");
|
|
|
|
|
slaveStatus = slaveDiff <= 1 ? "connected" : "disconnected";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (loraDiffInMinutes > 1) {
|
|
|
|
|
if (slaveStatus === "disconnected") {
|
|
|
|
|
disconnectedSlaves.push({
|
|
|
|
|
hardwareId: connected_to,
|
|
|
|
|
slaveHardwareId: slaveId,
|
|
|
|
|
slaveHardwareId: slave.hardwareId,
|
|
|
|
|
slaveName: slave.tankName || "Unknown Slave"
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
formattedSlaves.push({
|
|
|
|
|
hardwareId: slave.hardwareId,
|
|
|
|
|
slaveName: slave.tankName || null,
|
|
|
|
|
location: slave.tankLocation || null,
|
|
|
|
|
type: "slave",
|
|
|
|
|
connected_status: slaveStatus,
|
|
|
|
|
last_data_time: lastSlaveDataTime,
|
|
|
|
|
diff_in_minutes: slaveDiff
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Raise tickets if needed
|
|
|
|
|
const issuesToAdd = [];
|
|
|
|
|
|
|
|
|
|
if (masterDisconnected.length > 0) {
|
|
|
|
|
const existingGsmIssue = await Support.findOne({
|
|
|
|
|
if (masterConnectedStatus === "disconnected") {
|
|
|
|
|
const existing = await Support.findOne({
|
|
|
|
|
"issues.hardwareId": connected_to,
|
|
|
|
|
"issues.type": "GSM Disconnected"
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!existingGsmIssue) {
|
|
|
|
|
if (!existing) {
|
|
|
|
|
issuesToAdd.push({
|
|
|
|
|
type: "GSM Disconnected",
|
|
|
|
|
hardwareId: connected_to,
|
|
|
|
|
message: `Master GSM disconnected - ${connected_to}`,
|
|
|
|
|
//disconnectedAt: now.format("DD-MM-YYYY HH:mm:ss")
|
|
|
|
|
message: `Master GSM disconnected - ${connected_to}`
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check for already existing slave issues
|
|
|
|
|
const newHardwareIds = [];
|
|
|
|
|
const newSlaveNames = [];
|
|
|
|
|
|
|
|
|
|
for (const slave of disconnectedSlaves) {
|
|
|
|
|
const existingSlaveIssue = await Support.findOne({
|
|
|
|
|
"issues.hardwareIds": slave.slaveHardwareId,
|
|
|
|
|
for (const s of disconnectedSlaves) {
|
|
|
|
|
const existing = await Support.findOne({
|
|
|
|
|
"issues.hardwareIds": s.slaveHardwareId,
|
|
|
|
|
"issues.masterHardwareId": connected_to,
|
|
|
|
|
"issues.type": "LoRa Disconnected"
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!existingSlaveIssue) {
|
|
|
|
|
newHardwareIds.push(slave.slaveHardwareId);
|
|
|
|
|
newSlaveNames.push(slave.slaveName);
|
|
|
|
|
if (!existing) {
|
|
|
|
|
newHardwareIds.push(s.slaveHardwareId);
|
|
|
|
|
newSlaveNames.push(s.slaveName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -2718,14 +2736,12 @@ exports.raiseATicket = async (req, reply) => {
|
|
|
|
|
masterHardwareId: connected_to,
|
|
|
|
|
hardwareIds: newHardwareIds,
|
|
|
|
|
slaveNames: newSlaveNames,
|
|
|
|
|
message: `Slaves LoRa disconnected under master ${connected_to}`,
|
|
|
|
|
// disconnectedAt: now.format("DD-MM-YYYY HH:mm:ss")
|
|
|
|
|
message: `Slaves LoRa disconnected under master ${connected_to}`
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (issuesToAdd.length > 0) {
|
|
|
|
|
const supportRecord = await Support.findOne({ supportId: "AWHYSU64" });
|
|
|
|
|
|
|
|
|
|
if (supportRecord) {
|
|
|
|
|
await Support.findOneAndUpdate(
|
|
|
|
|
{ _id: supportRecord._id },
|
|
|
|
@ -2734,27 +2750,34 @@ exports.raiseATicket = async (req, reply) => {
|
|
|
|
|
issues: { $each: issuesToAdd }
|
|
|
|
|
},
|
|
|
|
|
updatedAt: new Date()
|
|
|
|
|
},
|
|
|
|
|
{ new: true }
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
console.error("Support record not found for supportId AWHYSU64");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const masterDetails = {
|
|
|
|
|
hardwareId: connected_to,
|
|
|
|
|
masterName: masterSensor.masterName || orderMap[connected_to]?.masterName || null,
|
|
|
|
|
location: masterSensor.location || orderMap[connected_to]?.location || null,
|
|
|
|
|
type: "master",
|
|
|
|
|
connected_status: masterConnectedStatus,
|
|
|
|
|
last_data_time: lastDataTime,
|
|
|
|
|
diff_in_minutes: diffInMinutes
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return reply.send({
|
|
|
|
|
status_code: 200,
|
|
|
|
|
message: "Checked connection and updated support if needed.",
|
|
|
|
|
masterDisconnected,
|
|
|
|
|
disconnectedSlaves
|
|
|
|
|
master: masterDetails,
|
|
|
|
|
connected_slaves: formattedSlaves
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error raising ticket:", error);
|
|
|
|
|
return reply.code(500).send({ error: "Internal server error" });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// exports.raiseATicket = async (req, reply) => {
|
|
|
|
|
// try {
|
|
|
|
|
// const { customerId, connected_to } = req.params;
|
|
|
|
@ -3161,7 +3184,7 @@ exports.getDisconnectedIssuesBySupportId = async (req, reply) => {
|
|
|
|
|
const allIssues = supportRecord.issues || [];
|
|
|
|
|
const hardwareSet = new Set();
|
|
|
|
|
|
|
|
|
|
// Collect all hardware IDs mentioned in issues
|
|
|
|
|
// Collect all hardware IDs from issues
|
|
|
|
|
for (const issue of allIssues) {
|
|
|
|
|
if (issue.hardwareId) hardwareSet.add(issue.hardwareId); // GSM
|
|
|
|
|
if (Array.isArray(issue.hardwareIds)) {
|
|
|
|
@ -3181,14 +3204,14 @@ exports.getDisconnectedIssuesBySupportId = async (req, reply) => {
|
|
|
|
|
|
|
|
|
|
const masterMap = {};
|
|
|
|
|
|
|
|
|
|
// First, add relevant masters from issues
|
|
|
|
|
for (const issue of allIssues) {
|
|
|
|
|
// GSM Disconnected
|
|
|
|
|
if (issue.type === "GSM Disconnected" && issue.hardwareId) {
|
|
|
|
|
const sensor = sensorMap[issue.hardwareId];
|
|
|
|
|
if (sensor && sensor.type === "master") {
|
|
|
|
|
masterMap[sensor.hardwareId] = {
|
|
|
|
|
hardwareId: sensor.hardwareId,
|
|
|
|
|
masterName: sensor.masterName,
|
|
|
|
|
masterName: sensor.masterName || null,
|
|
|
|
|
location: sensor.location || "",
|
|
|
|
|
type: "master",
|
|
|
|
|
connected_status: sensor.connected_status,
|
|
|
|
@ -3205,13 +3228,15 @@ exports.getDisconnectedIssuesBySupportId = async (req, reply) => {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// LoRa Disconnected
|
|
|
|
|
if (issue.type === "LoRa Disconnected" && issue.masterHardwareId) {
|
|
|
|
|
const masterSensor = sensorMap[issue.masterHardwareId];
|
|
|
|
|
if (masterSensor && masterSensor.type === "master") {
|
|
|
|
|
if (!masterSensor || masterSensor.type !== "master") continue;
|
|
|
|
|
|
|
|
|
|
if (!masterMap[masterSensor.hardwareId]) {
|
|
|
|
|
masterMap[masterSensor.hardwareId] = {
|
|
|
|
|
hardwareId: masterSensor.hardwareId,
|
|
|
|
|
masterName: masterSensor.masterName,
|
|
|
|
|
masterName: masterSensor.masterName || null,
|
|
|
|
|
location: masterSensor.location || "",
|
|
|
|
|
type: "master",
|
|
|
|
|
connected_status: masterSensor.connected_status,
|
|
|
|
@ -3227,9 +3252,36 @@ exports.getDisconnectedIssuesBySupportId = async (req, reply) => {
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const master = masterMap[issue.masterHardwareId];
|
|
|
|
|
if (master && Array.isArray(issue.hardwareIds)) {
|
|
|
|
|
for (const slaveId of issue.hardwareIds) {
|
|
|
|
|
const master = masterMap[masterSensor.hardwareId];
|
|
|
|
|
|
|
|
|
|
// First try from issue.hardwareIds
|
|
|
|
|
let slaveIds = Array.isArray(issue.hardwareIds) ? issue.hardwareIds : [];
|
|
|
|
|
|
|
|
|
|
// If empty, fallback to slaves connected to this master
|
|
|
|
|
if (slaveIds.length === 0) {
|
|
|
|
|
const fallbackSlaves = await Insensors.find({ connected_to: masterSensor.hardwareId, type: "slave" }).lean();
|
|
|
|
|
for (const slaveSensor of fallbackSlaves) {
|
|
|
|
|
master.connected_slaves.push({
|
|
|
|
|
hardwareId: slaveSensor.hardwareId,
|
|
|
|
|
tankName: slaveSensor.tankName || "",
|
|
|
|
|
location: slaveSensor.location || "",
|
|
|
|
|
connected_status: slaveSensor.connected_status,
|
|
|
|
|
connected_lora_time: slaveSensor.connected_lora_time,
|
|
|
|
|
connected_lora_date: slaveSensor.connected_lora_date,
|
|
|
|
|
lora_last_check_time: slaveSensor.lora_last_check_time,
|
|
|
|
|
lora_last_disconnect_time: slaveSensor.lora_last_disconnect_time,
|
|
|
|
|
connected_to: slaveSensor.connected_to,
|
|
|
|
|
masterName: master.masterName,
|
|
|
|
|
type: "slave",
|
|
|
|
|
typeOfWater: slaveSensor.typeOfWater,
|
|
|
|
|
tankHeight: slaveSensor.tankHeight,
|
|
|
|
|
support_lora_last_check_time: slaveSensor.support_lora_last_check_time,
|
|
|
|
|
});
|
|
|
|
|
master.connected_slave_count++;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Populate slaves based on provided hardwareIds
|
|
|
|
|
for (const slaveId of slaveIds) {
|
|
|
|
|
const slaveSensor = sensorMap[slaveId];
|
|
|
|
|
if (slaveSensor && slaveSensor.type === "slave") {
|
|
|
|
|
master.connected_slaves.push({
|
|
|
|
@ -3254,7 +3306,6 @@ exports.getDisconnectedIssuesBySupportId = async (req, reply) => {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const finalResponse = Object.values(masterMap);
|
|
|
|
|
|
|
|
|
@ -3271,6 +3322,7 @@ exports.getDisconnectedIssuesBySupportId = async (req, reply) => {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
exports.getDisconnectedCustomerDetails = async (req, reply) => {
|
|
|
|
|
try {
|
|
|
|
|
const { supportId } = req.params;
|
|
|
|
|