iot-agent/services/aiAgentService.js
2025-08-03 23:07:33 +05:30

551 lines
18 KiB
JavaScript

const logger = require('../utils/logger');
const database = require('../config/database');
const redis = require('../config/redis');
const healingService = require('./healingService');
const alertService = require('./alertService');
class AIAgentService {
constructor() {
this.learningRate = parseFloat(process.env.AI_LEARNING_RATE) || 0.1;
this.anomalyThreshold = parseFloat(process.env.AI_THRESHOLD_ANOMALY) || 0.8;
this.healingEnabled = process.env.AI_HEALING_ENABLED === 'true';
this.deviceModels = new Map();
this.isInitialized = false;
}
async initialize() {
try {
await this.loadDeviceModels();
await this.setupPeriodicAnalysis();
this.isInitialized = true;
logger.info('AI Agent service initialized successfully');
} catch (error) {
logger.error('Failed to initialize AI Agent service:', error);
throw error;
}
}
async loadDeviceModels() {
try {
// Load device-specific AI models from database
const devices = await database.query('SELECT id, device_type, ai_model_config FROM devices WHERE ai_model_config IS NOT NULL');
for (const device of devices) {
if (device.ai_model_config) {
const config = JSON.parse(device.ai_model_config);
this.deviceModels.set(device.id, {
deviceType: device.device_type,
config: config,
lastUpdated: new Date()
});
}
}
logger.info(`Loaded AI models for ${devices.length} devices`);
} catch (error) {
logger.error('Failed to load device models:', error);
}
}
async setupPeriodicAnalysis() {
// Run periodic analysis every 5 minutes
setInterval(async () => {
await this.runPeriodicAnalysis();
}, 5 * 60 * 1000);
}
async processDeviceData(deviceId, data, timestamp) {
try {
const startTime = Date.now();
// Analyze data for anomalies
const anomalyScore = await this.detectAnomalies(deviceId, data);
// Generate insights
const insights = await this.generateInsights(deviceId, data, timestamp);
// Check for optimization opportunities
const optimizations = await this.findOptimizations(deviceId, data);
// Update device model
await this.updateDeviceModel(deviceId, data, anomalyScore);
// Generate suggestions
const suggestions = await this.generateSuggestions(deviceId, data, insights, optimizations);
// Store analysis results
await this.storeAnalysisResults(deviceId, {
anomalyScore,
insights,
optimizations,
suggestions,
timestamp
});
const processingTime = Date.now() - startTime;
logger.logAIAction('device_data_analysis', {
deviceId,
anomalyScore,
insightsCount: insights.length,
optimizationsCount: optimizations.length,
suggestionsCount: suggestions.length
}, anomalyScore);
logger.logPerformance('ai_data_processing', processingTime, {
deviceId,
dataSize: JSON.stringify(data).length
});
} catch (error) {
logger.error('Error processing device data with AI:', error);
}
}
async detectAnomalies(deviceId, data) {
try {
// Get historical data for comparison
const historicalData = await this.getHistoricalData(deviceId, 100);
if (historicalData.length < 10) {
return 0.5; // Neutral score if insufficient data
}
// Calculate statistical measures
const values = historicalData.map(d => this.extractNumericValues(d.raw_data)).flat();
const mean = values.reduce((a, b) => a + b, 0) / values.length;
const variance = values.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / values.length;
const stdDev = Math.sqrt(variance);
// Calculate anomaly score for current data
const currentValues = this.extractNumericValues(data);
const anomalyScores = currentValues.map(value => {
const zScore = Math.abs((value - mean) / stdDev);
return Math.min(zScore / 3, 1); // Normalize to 0-1
});
const avgAnomalyScore = anomalyScores.reduce((a, b) => a + b, 0) / anomalyScores.length;
// Trigger alert if anomaly score is high
if (avgAnomalyScore > this.anomalyThreshold) {
await alertService.createAlert({
deviceId,
type: 'anomaly_detected',
severity: avgAnomalyScore > 0.9 ? 'critical' : 'warning',
message: `Anomaly detected in device ${deviceId} with score ${avgAnomalyScore.toFixed(3)}`,
data: { anomalyScore: avgAnomalyScore, values: currentValues }
});
}
return avgAnomalyScore;
} catch (error) {
logger.error('Error detecting anomalies:', error);
return 0.5;
}
}
async generateInsights(deviceId, data, timestamp) {
try {
const insights = [];
// Analyze data patterns
const patterns = await this.analyzePatterns(deviceId, data);
if (patterns.length > 0) {
insights.push({
type: 'pattern_detected',
description: `Detected ${patterns.length} new patterns in device behavior`,
patterns: patterns
});
}
// Analyze performance trends
const trends = await this.analyzeTrends(deviceId, data);
if (trends.length > 0) {
insights.push({
type: 'trend_detected',
description: `Identified ${trends.length} performance trends`,
trends: trends
});
}
// Analyze efficiency
const efficiency = await this.analyzeEfficiency(deviceId, data);
if (efficiency.score < 0.7) {
insights.push({
type: 'efficiency_issue',
description: `Device efficiency is ${(efficiency.score * 100).toFixed(1)}%`,
recommendations: efficiency.recommendations
});
}
return insights;
} catch (error) {
logger.error('Error generating insights:', error);
return [];
}
}
async findOptimizations(deviceId, data) {
try {
const optimizations = [];
// Check for energy optimization opportunities
const energyOpt = await this.checkEnergyOptimization(deviceId, data);
if (energyOpt.opportunity) {
optimizations.push({
type: 'energy_optimization',
description: energyOpt.description,
potentialSavings: energyOpt.savings,
action: energyOpt.action
});
}
// Check for performance optimization
const perfOpt = await this.checkPerformanceOptimization(deviceId, data);
if (perfOpt.opportunity) {
optimizations.push({
type: 'performance_optimization',
description: perfOpt.description,
improvement: perfOpt.improvement,
action: perfOpt.action
});
}
// Check for maintenance optimization
const maintOpt = await this.checkMaintenanceOptimization(deviceId, data);
if (maintOpt.opportunity) {
optimizations.push({
type: 'maintenance_optimization',
description: maintOpt.description,
benefit: maintOpt.benefit,
action: maintOpt.action
});
}
return optimizations;
} catch (error) {
logger.error('Error finding optimizations:', error);
return [];
}
}
async generateSuggestions(deviceId, data, insights, optimizations) {
try {
const suggestions = [];
// Generate suggestions based on insights
for (const insight of insights) {
const suggestion = await this.createSuggestionFromInsight(deviceId, insight);
if (suggestion) {
suggestions.push(suggestion);
}
}
// Generate suggestions based on optimizations
for (const optimization of optimizations) {
const suggestion = await this.createSuggestionFromOptimization(deviceId, optimization);
if (suggestion) {
suggestions.push(suggestion);
}
}
// Generate proactive suggestions
const proactiveSuggestions = await this.generateProactiveSuggestions(deviceId, data);
suggestions.push(...proactiveSuggestions);
// Store suggestions in database
for (const suggestion of suggestions) {
await this.storeSuggestion(deviceId, suggestion);
}
return suggestions;
} catch (error) {
logger.error('Error generating suggestions:', error);
return [];
}
}
async createSuggestionFromInsight(deviceId, insight) {
try {
const suggestion = {
deviceId,
type: 'ai_insight',
title: `Action based on ${insight.type}`,
description: insight.description,
priority: insight.type === 'efficiency_issue' ? 'high' : 'medium',
category: 'optimization',
confidence: 0.8,
actions: [],
created_at: new Date()
};
// Add specific actions based on insight type
switch (insight.type) {
case 'efficiency_issue':
suggestion.actions = insight.recommendations;
break;
case 'pattern_detected':
suggestion.actions = ['Monitor pattern evolution', 'Adjust thresholds if needed'];
break;
case 'trend_detected':
suggestion.actions = ['Review trend direction', 'Plan preventive measures'];
break;
}
return suggestion;
} catch (error) {
logger.error('Error creating suggestion from insight:', error);
return null;
}
}
async createSuggestionFromOptimization(deviceId, optimization) {
try {
const suggestion = {
deviceId,
type: 'ai_optimization',
title: optimization.description,
description: `AI detected optimization opportunity: ${optimization.description}`,
priority: 'medium',
category: 'optimization',
confidence: 0.7,
actions: [optimization.action],
metadata: {
optimizationType: optimization.type,
potentialBenefit: optimization.potentialSavings || optimization.improvement || optimization.benefit
},
created_at: new Date()
};
return suggestion;
} catch (error) {
logger.error('Error creating suggestion from optimization:', error);
return null;
}
}
async generateProactiveSuggestions(deviceId, data) {
try {
const suggestions = [];
// Check device health
const health = await this.assessDeviceHealth(deviceId, data);
if (health.score < 0.6) {
suggestions.push({
deviceId,
type: 'health_warning',
title: 'Device Health Alert',
description: `Device health is at ${(health.score * 100).toFixed(1)}%. Consider maintenance.`,
priority: 'high',
category: 'maintenance',
confidence: 0.9,
actions: ['Schedule maintenance', 'Check device logs', 'Review recent alerts'],
created_at: new Date()
});
}
// Check for predictive maintenance
const maintenance = await this.predictMaintenance(deviceId, data);
if (maintenance.needed) {
suggestions.push({
deviceId,
type: 'predictive_maintenance',
title: 'Predictive Maintenance Recommended',
description: `Maintenance recommended within ${maintenance.timeframe} days`,
priority: 'medium',
category: 'maintenance',
confidence: maintenance.confidence,
actions: ['Schedule maintenance', 'Order parts if needed'],
metadata: { timeframe: maintenance.timeframe },
created_at: new Date()
});
}
return suggestions;
} catch (error) {
logger.error('Error generating proactive suggestions:', error);
return [];
}
}
async storeSuggestion(deviceId, suggestion) {
try {
await database.query(
`INSERT INTO ai_suggestions
(device_id, type, title, description, priority, category, confidence, actions, metadata, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
[
deviceId,
suggestion.type,
suggestion.title,
suggestion.description,
suggestion.priority,
suggestion.category,
suggestion.confidence,
JSON.stringify(suggestion.actions),
JSON.stringify(suggestion.metadata || {}),
suggestion.created_at
]
);
} catch (error) {
logger.error('Failed to store suggestion:', error);
}
}
async runPeriodicAnalysis() {
try {
logger.info('Running periodic AI analysis...');
// Get all active devices
const devices = await database.query('SELECT id FROM devices WHERE status = "active"');
for (const device of devices) {
// Get recent data for analysis
const recentData = await database.query(
'SELECT * FROM device_data WHERE device_id = ? ORDER BY timestamp DESC LIMIT 10',
[device.id]
);
if (recentData.length > 0) {
// Run comprehensive analysis
await this.runComprehensiveAnalysis(device.id, recentData);
}
}
logger.info('Periodic AI analysis completed');
} catch (error) {
logger.error('Error in periodic analysis:', error);
}
}
async runComprehensiveAnalysis(deviceId, data) {
try {
// Analyze device behavior patterns
const behaviorPatterns = await this.analyzeBehaviorPatterns(deviceId, data);
// Check for system-wide optimizations
const systemOptimizations = await this.findSystemOptimizations(deviceId, data);
// Generate long-term recommendations
const longTermRecommendations = await this.generateLongTermRecommendations(deviceId, data);
// Store comprehensive analysis
await this.storeComprehensiveAnalysis(deviceId, {
behaviorPatterns,
systemOptimizations,
longTermRecommendations,
timestamp: new Date()
});
} catch (error) {
logger.error('Error in comprehensive analysis:', error);
}
}
// Helper methods
extractNumericValues(data) {
const values = [];
const extract = (obj) => {
for (const key in obj) {
if (typeof obj[key] === 'number') {
values.push(obj[key]);
} else if (typeof obj[key] === 'object' && obj[key] !== null) {
extract(obj[key]);
}
}
};
extract(data);
return values;
}
async getHistoricalData(deviceId, limit) {
try {
return await database.query(
'SELECT raw_data FROM device_data WHERE device_id = ? ORDER BY timestamp DESC LIMIT ?',
[deviceId, limit]
);
} catch (error) {
logger.error('Error getting historical data:', error);
return [];
}
}
async updateDeviceModel(deviceId, data, anomalyScore) {
try {
// Update device model with new data
const model = this.deviceModels.get(deviceId) || {
deviceType: 'unknown',
config: {},
lastUpdated: new Date()
};
// Update model parameters based on new data
model.lastUpdated = new Date();
model.lastAnomalyScore = anomalyScore;
this.deviceModels.set(deviceId, model);
// Store updated model in database
await database.query(
'UPDATE devices SET ai_model_config = ?, updated_at = NOW() WHERE id = ?',
[JSON.stringify(model), deviceId]
);
} catch (error) {
logger.error('Error updating device model:', error);
}
}
async storeAnalysisResults(deviceId, results) {
try {
await database.query(
`INSERT INTO ai_analysis_results
(device_id, anomaly_score, insights, optimizations, suggestions, timestamp, created_at)
VALUES (?, ?, ?, ?, ?, ?, NOW())`,
[
deviceId,
results.anomalyScore,
JSON.stringify(results.insights),
JSON.stringify(results.optimizations),
JSON.stringify(results.suggestions),
results.timestamp
]
);
} catch (error) {
logger.error('Failed to store analysis results:', error);
}
}
// Placeholder methods for complex AI operations
async analyzePatterns(deviceId, data) { return []; }
async analyzeTrends(deviceId, data) { return []; }
async analyzeEfficiency(deviceId, data) { return { score: 0.8, recommendations: [] }; }
async checkEnergyOptimization(deviceId, data) { return { opportunity: false }; }
async checkPerformanceOptimization(deviceId, data) { return { opportunity: false }; }
async checkMaintenanceOptimization(deviceId, data) { return { opportunity: false }; }
async assessDeviceHealth(deviceId, data) { return { score: 0.8 }; }
async predictMaintenance(deviceId, data) { return { needed: false }; }
async analyzeBehaviorPatterns(deviceId, data) { return []; }
async findSystemOptimizations(deviceId, data) { return []; }
async generateLongTermRecommendations(deviceId, data) { return []; }
async storeComprehensiveAnalysis(deviceId, analysis) { }
async healthCheck() {
try {
return {
status: this.isInitialized ? 'healthy' : 'not_initialized',
message: this.isInitialized ? 'AI Agent service is healthy' : 'Service not initialized',
deviceModels: this.deviceModels.size,
learningRate: this.learningRate,
anomalyThreshold: this.anomalyThreshold,
healingEnabled: this.healingEnabled
};
} catch (error) {
return {
status: 'unhealthy',
message: 'AI Agent service health check failed',
error: error.message
};
}
}
}
module.exports = new AIAgentService();