UNPKG

ms-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

266 lines 11.5 kB
import { getTypesenseClient, getDataLink, getArtifact, insertDataLinkToMongoDB, getPmsEtlDatabase, fetchQADetails } from "syia-mcp-utils"; import { logger } from "../../index.js"; // Helper function to get engine data database async function getEngineDataDatabase() { return await getPmsEtlDatabase(); } // 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.ENGINENAME; const sessionId = args.session_id || "testing"; if (!imo) { throw new Error("IMO number is required"); } try { const db = await getEngineDataDatabase(); 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); await insertDataLinkToMongoDB(dataLink, "Latest engine performance", sessionId, imo.toString(), vesselName); // 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 }); const errorResponse = { type: "text", text: `Error retrieving engine performance data: ${error instanceof Error ? error.message : String(error)}` }; return [errorResponse]; } } async getHistoricalEnginePerformance(args) { logger.info("getHistoricalEnginePerformance called", args); const imo = args.imo; const engineName = args.ENGINENAME; const startDate = args.start_date; const endDate = args.end_date; const limit = args.limit || 12; const sessionId = args.session_id || "testing"; if (!imo) { throw new Error("IMO number is required"); } if (!engineName) { throw new Error("Engine name is required"); } if (!startDate || !endDate) { throw new Error("Start date and end date are required"); } try { const db = await getEngineDataDatabase(); 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); await insertDataLinkToMongoDB(dataLink, "Historical engine performance", sessionId, imo.toString(), vesselName); // 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); const errorResponse = { type: "text", text: `Error getting historical engine performance: ${error instanceof Error ? error.message : String(error)}` }; return [errorResponse]; } } async getMainEnginePerformanceReview(args) { logger.info("getMainEnginePerformanceReview called", args); const imo = args.imo; if (!imo) { throw new Error("IMO number is required"); } try { // Get data from QnA - Q No.67 for ME Performance Review const result = await fetchQADetails(imo, 67); const sessionId = args.session_id || "testing"; // Insert data link to MongoDB if available if (result.link) { await insertDataLinkToMongoDB(result.link, "main engine performance review", sessionId, imo.toString(), result.vesselName || ""); } // 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); const errorResponse = { type: "text", text: `Error getting main engine performance review: ${error instanceof Error ? error.message : String(error)}` }; return [errorResponse]; } } async getAuxiliaryEnginePerformanceReview(args) { logger.info("getAuxiliaryEnginePerformanceReview called", args); const imo = args.imo; if (!imo) { throw new Error("IMO number is required"); } try { // Get data from QnA - Q No.71 for AE Performance Review const result = await fetchQADetails(imo, 71); const sessionId = args.session_id || "testing"; // Insert data link to MongoDB if available if (result.link) { await insertDataLinkToMongoDB(result.link, "auxiliary engine performance review", sessionId, imo.toString(), result.vesselName || ""); } // 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); const errorResponse = { type: "text", text: `Error getting auxiliary engine performance review: ${error instanceof Error ? error.message : String(error)}` }; return [errorResponse]; } } } //# sourceMappingURL=performanceTools.js.map