pms-analysis-reports-mcp-server
Version:
PMS analysis reports server handling maintenance reports, equipment analysis, compliance tracking, and performance metrics with ERP access for data extraction
306 lines • 14.6 kB
JavaScript
import { getTypesenseClient } from "../../utils/typesense.js";
import { getDataLink, getArtifact, fetchQADetails } from "../../utils/helper_functions.js";
import { DatabaseManager } from "../../utils/mongodb.js";
import { logger } from "../../index.js";
// Helper function to get engine data database
async function getEngineDataDatabase() {
const enginePerformanceDbName = process.env.ENGINE_PERFORMANCE_DB_NAME;
const enginePerformanceMongoUri = process.env.ENGINE_PERFORMANCE_MONGO_URI;
if (!enginePerformanceDbName) {
throw new Error("ENGINE_PERFORMANCE_DB_NAME environment variable is required");
}
if (!enginePerformanceMongoUri) {
throw new Error("ENGINE_PERFORMANCE_MONGO_URI environment variable is required");
}
const dbManager = new DatabaseManager();
await dbManager.initializeDatabase(enginePerformanceDbName, enginePerformanceMongoUri);
return dbManager;
}
// Engine names mapping
const ENGINE_NAMES_MAPPING = {
"AE1": "Auxillary Engine 1",
"AE2": "Auxillary Engine 2",
"AE3": "Auxillary Engine 3",
"AE4": "Auxillary Engine 4",
"AE5": "Auxillary Engine 5",
"ME": "Main Engine"
};
export class PerformanceToolHandler {
constructor() {
this.typesenseClient = getTypesenseClient();
}
async getLatestEnginePerformance(args) {
logger.info("getLatestEnginePerformance called", args);
const imo = args.imo;
const engineName = args.engine_name;
if (!imo) {
throw new Error("imo is required. Only the following properties are allowed: imo, engine_name. Please check the tool schema for getLatestEnginePerformance for the allowed properties.");
}
const dbManager = await getEngineDataDatabase();
try {
const db = dbManager.getDb();
const collection = db.collection("bluegem_performance_data");
// Build query
const query = { imo: parseInt(imo.toString()) };
// Engine names mapping
const engineNamesMapping = {
"AE1": "Auxillary Engine 1",
"AE2": "Auxillary Engine 2",
"AE3": "Auxillary Engine 3",
"AE4": "Auxillary Engine 4",
"AE5": "Auxillary Engine 5",
"ME": "Main Engine"
};
if (engineName) {
const mappedEngineName = engineNamesMapping[engineName];
if (mappedEngineName) {
query.ENGINENAME = mappedEngineName;
}
}
// Get all documents sorted by performance date
const documents = await collection
.find(query)
.project({ _id: 0 })
.toArray();
if (!documents || documents.length === 0) {
const noDataResponse = {
type: "text",
text: JSON.stringify({
message: `No engine performance data found for ${engineName || 'any engine'}`
})
};
return [noDataResponse];
}
// Process the documents based on whether engineName is specified
let processedDocuments;
if (engineName) {
// Get latest document for specific engine
processedDocuments = [documents
.sort((a, b) => new Date(b.PERFORMANCEDATE).getTime() - new Date(a.PERFORMANCEDATE).getTime())[0]
];
}
else {
// Group by engine name and get latest for each
const engineGroups = documents.reduce((groups, doc) => {
const name = doc.ENGINENAME;
if (!groups[name]) {
groups[name] = [];
}
groups[name].push(doc);
return groups;
}, {});
processedDocuments = Object.values(engineGroups)
.map((group) => group.sort((a, b) => new Date(b.PERFORMANCEDATE).getTime() - new Date(a.PERFORMANCEDATE).getTime())[0]);
}
// Get vessel name if available
const vesselName = processedDocuments[0]?.vesselName || "";
// Generate data link and store in MongoDB
const dataLink = await getDataLink(processedDocuments);
const mongodbEtlDevDataDbName = process.env.MONGODB_ETL_DEV_DATA_DB_NAME || process.env.mongodbEtlDevDataDbName || 'syia-etl-dev';
const mongodbEtlDevDataUri = process.env.MONGODB_ETL_DEV_DATA_URI || process.env.mongodbEtlDevDataUri || '';
// await insertDataLinkToMongoDB(
// dataLink,
// "Latest engine performance",
// sessionId,
// imo.toString(),
// vesselName,
// mongodbEtlDevDataDbName,
// mongodbEtlDevDataUri
// );
// Create artifact
const artifactData = getArtifact("get_latest_engine_performance", dataLink);
const content = {
type: "text",
text: JSON.stringify(processedDocuments, null, 2)
};
const artifact = {
type: "text",
text: JSON.stringify(artifactData, null, 2)
};
return [content, artifact];
}
catch (error) {
logger.error("Error in getLatestEnginePerformance", { error });
throw new Error(`Error retrieving engine performance data: ${error instanceof Error ? error.message : String(error)}`);
}
finally {
await dbManager.closeDatabase();
}
}
async getHistoricalEnginePerformance(args) {
logger.info("getHistoricalEnginePerformance called", args);
const imo = args.imo;
const engineName = args.engine_name;
const startDate = args.start_date;
const endDate = args.end_date;
const limit = args.limit || 12;
if (!imo) {
throw new Error("imo is required. Only the following properties are allowed: imo, engine_name, start_date, end_date, limit. Please check the tool schema for getHistoricalEnginePerformance for the allowed properties.");
}
if (!engineName) {
throw new Error("engine_name is required. Only the following properties are allowed: imo, engine_name, start_date, end_date, limit. Please check the tool schema for getHistoricalEnginePerformance for the allowed properties.");
}
if (!startDate || !endDate) {
throw new Error("start_date and end_date are required. Only the following properties are allowed: imo, engine_name, start_date, end_date, limit. Please check the tool schema for getHistoricalEnginePerformance for the allowed properties.");
}
const dbManager = await getEngineDataDatabase();
try {
const db = dbManager.getDb();
const collection = db.collection("bluegem_performance_data");
// Get full engine name
const fullEngineName = ENGINE_NAMES_MAPPING[engineName];
if (!fullEngineName) {
throw new Error(`Invalid engine name: ${engineName}`);
}
// Convert string dates to Date objects and adjust end date to be inclusive
const startDateTime = new Date(startDate);
const endDateTime = new Date(endDate);
endDateTime.setDate(endDateTime.getDate() + 1);
// Build query
const query = {
imo: parseInt(imo.toString()),
ENGINENAME: fullEngineName,
PERFORMANCEDATE: {
$gte: startDateTime,
$lt: endDateTime
}
};
// Fetch and sort documents
const documents = await collection
.find(query)
.sort("PERFORMANCEDATE", 1)
.limit(limit)
.toArray();
if (!documents || documents.length === 0) {
const noDataResponse = {
type: "text",
text: JSON.stringify({
message: `No historical engine performance data found for ${fullEngineName} between ${startDate} and ${endDate}`
})
};
return [noDataResponse];
}
// Sort documents by engine name and performance date
const sortedDocuments = documents.sort((a, b) => {
const engineCompare = a.ENGINENAME.localeCompare(b.ENGINENAME);
if (engineCompare !== 0)
return engineCompare;
return new Date(a.PERFORMANCEDATE).getTime() - new Date(b.PERFORMANCEDATE).getTime();
});
// Get vessel name if available
const vesselName = sortedDocuments[0]?.vesselName || "";
// Generate data link and store in MongoDB
const dataLink = await getDataLink(sortedDocuments);
const mongodbEtlDevDataDbName = process.env.MONGODB_ETL_DEV_DATA_DB_NAME || process.env.mongodbEtlDevDataDbName || 'syia-etl-dev';
const mongodbEtlDevDataUri = process.env.MONGODB_ETL_DEV_DATA_URI || process.env.mongodbEtlDevDataUri || '';
// await insertDataLinkToMongoDB(
// dataLink,
// "Historical engine performance",
// sessionId,
// imo.toString(),
// vesselName,
// mongodbEtlDevDataDbName,
// mongodbEtlDevDataUri
// );
// Generate artifact data
const artifactData = getArtifact("get_historical_engine_performance", dataLink);
const content = {
type: "text",
text: JSON.stringify(sortedDocuments, null, 2)
};
const artifact = {
type: "text",
text: JSON.stringify(artifactData, null, 2)
};
return [content, artifact];
}
catch (error) {
logger.error("Error getting historical engine performance:", error);
throw new Error(`Error getting historical engine performance: ${error instanceof Error ? error.message : String(error)}`);
}
finally {
await dbManager.closeDatabase();
}
}
async getMainEnginePerformanceReview(args) {
logger.info("getMainEnginePerformanceReview called", args);
const imo = args.imo;
if (!imo) {
throw new Error("imo is required. Only the following properties are allowed: imo. Please check the tool schema for getMainEnginePerformanceReview for the allowed properties.");
}
const mongodbEtlDevDataDbName = process.env.MONGODB_ETL_DEV_DATA_DB_NAME || process.env.mongodbEtlDevDataDbName || 'syia-etl-dev';
const mongodbEtlDevDataUri = process.env.MONGODB_ETL_DEV_DATA_URI || process.env.mongodbEtlDevDataUri || '';
try {
// Get data from QnA - Q No.67 for ME Performance Review
const result = await fetchQADetails(imo, 67, mongodbEtlDevDataDbName, mongodbEtlDevDataUri);
// // Insert data link to MongoDB if available
// if (result.link) {
// await insertDataLinkToMongoDB(
// result.link,
// "main engine performance review",
// sessionId,
// imo.toString(),
// result.vesselName || "",
// mongodbEtlDevDataDbName,
// mongodbEtlDevDataUri
// );
// }
// Generate artifact data
const artifactData = getArtifact("get_main_engine_performance_review", result.link || "");
const content = {
type: "text",
text: JSON.stringify(result, null, 2)
};
const artifact = {
type: "text",
text: JSON.stringify(artifactData, null, 2)
};
return [content, artifact];
}
catch (error) {
logger.error("Error getting main engine performance review:", error);
throw new Error(`Error getting main engine performance review: ${error instanceof Error ? error.message : String(error)}`);
}
}
async getAuxiliaryEnginePerformanceReview(args) {
logger.info("getAuxiliaryEnginePerformanceReview called", args);
const imo = args.imo;
if (!imo) {
throw new Error("imo is required. Only the following properties are allowed: imo. Please check the tool schema for getAuxiliaryEnginePerformanceReview for the allowed properties.");
}
const mongodbEtlDevDataDbName = process.env.MONGODB_ETL_DEV_DATA_DB_NAME || process.env.mongodbEtlDevDataDbName || 'syia-etl-dev';
const mongodbEtlDevDataUri = process.env.MONGODB_ETL_DEV_DATA_URI || process.env.mongodbEtlDevDataUri || '';
try {
// Get data from QnA - Q No.71 for AE Performance Review
const result = await fetchQADetails(imo, 71, mongodbEtlDevDataDbName, mongodbEtlDevDataUri);
// // Insert data link to MongoDB if available
// if (result.link) {
// await insertDataLinkToMongoDB(
// result.link,
// "auxiliary engine performance review",
// sessionId,
// imo.toString(),
// result.vesselName || "",
// mongodbEtlDevDataDbName,
// mongodbEtlDevDataUri
// );
// }
// Generate artifact data
const artifactData = getArtifact("get_auxiliary_engine_performance_review", result.link || "");
const content = {
type: "text",
text: JSON.stringify(result, null, 2)
};
const artifact = {
type: "text",
text: JSON.stringify(artifactData, null, 2)
};
return [content, artifact];
}
catch (error) {
logger.error("Error getting auxiliary engine performance review:", error);
throw new Error(`Error getting auxiliary engine performance review: ${error instanceof Error ? error.message : String(error)}`);
}
}
}
//# sourceMappingURL=performanceTools.js.map