UNPKG

@sailboat-computer/health-monitoring

Version:

Comprehensive health monitoring system for sailboat computer v3 with marine-specific health checks

312 lines (263 loc) • 9.26 kB
/** * Self-Healing Example * Demonstrates the integration of health monitoring and recovery mechanisms */ import { HealthCheckEngine, defaultHealthCheckEngine, OperationalContext, MarineEnvironmentStatus, HealthMonitoringEvent, HealthStatus } from '../index'; import { GPSHealthCheck, createGPSHealthCheck, GPSData } from '../marine/GPSHealthCheck'; import { RecoveryOrchestrator, defaultRecoveryOrchestrator } from '../recovery/RecoveryOrchestrator'; import { GPSRecalibrationAction, createGPSRecalibrationAction } from '../recovery/actions/GPSRecalibrationAction'; import { registerGPSRecoveryPolicies } from '../recovery/policies/GPSRecoveryPolicy'; /** * Self-healing example for marine systems */ export class SelfHealingExample { private healthEngine: HealthCheckEngine; private recoveryOrchestrator: RecoveryOrchestrator; private gpsHealthCheck!: GPSHealthCheck; private gpsRecalibrationAction!: GPSRecalibrationAction; // Simulated GPS state private gpsState = { satelliteCount: 8, hdop: 1.2, fix: '3d' as '3d' | '2d' | 'none', isCalibrated: true }; constructor() { this.healthEngine = defaultHealthCheckEngine; this.recoveryOrchestrator = defaultRecoveryOrchestrator; // Set up event handling this.setupEventHandling(); // Initialize health checks and recovery actions this.initializeHealthChecks(); this.initializeRecoveryActions(); } /** * Initialize health checks */ private initializeHealthChecks(): void { // Create GPS health check this.gpsHealthCheck = createGPSHealthCheck( this.mockGPSDataProvider.bind(this) ); // Register with health engine this.healthEngine.registerHealthCheck(this.gpsHealthCheck); } /** * Initialize recovery actions and policies */ private initializeRecoveryActions(): void { // Create GPS recalibration action this.gpsRecalibrationAction = createGPSRecalibrationAction({ resetSatelliteTracking: async () => { console.log('šŸ› ļø GPS: Resetting satellite tracking'); await this.wait(1000); return true; }, clearAlmanac: async () => { console.log('šŸ› ļø GPS: Clearing almanac data'); await this.wait(1000); return true; }, resetHDOPThresholds: async () => { console.log('šŸ› ļø GPS: Resetting HDOP thresholds'); await this.wait(1000); return true; }, forceColdStart: async () => { console.log('šŸ› ļø GPS: Forcing cold start'); await this.wait(2000); return true; }, waitForSatellites: async (timeout: number) => { console.log(`šŸ› ļø GPS: Waiting for satellites (timeout: ${timeout}s)`); await this.wait(2000); // Recalibration improves satellite count this.gpsState.satelliteCount = Math.min(12, this.gpsState.satelliteCount + 4); this.gpsState.hdop = Math.max(0.8, this.gpsState.hdop - 0.4); this.gpsState.isCalibrated = true; return this.gpsState.satelliteCount; } }); // Register recovery action this.recoveryOrchestrator.registerRecoveryAction(this.gpsRecalibrationAction); // Register recovery policies registerGPSRecoveryPolicies( policy => this.recoveryOrchestrator.registerRecoveryPolicy(policy) ); } /** * Set up event handling */ private setupEventHandling(): void { // Listen for health monitoring events this.healthEngine.onEvent((event: HealthMonitoringEvent) => { console.log(`[${event.timestamp.toISOString()}] Health Event: ${event.eventType}`); console.log(` System: ${event.systemId}, Check: ${event.checkId}`); console.log(` Status: ${event.currentStatus}`); // Forward health check results to recovery orchestrator if (event.eventType === 'health_check_completed' && event.data) { const results = this.healthEngine.getAllResults(); const checkResult = event.checkId ? results.get(event.checkId) : undefined; if (checkResult) { this.recoveryOrchestrator.processHealthCheckResult(checkResult); } } }); // Listen for recovery events this.recoveryOrchestrator.onEvent((event) => { console.log(`[${event.timestamp.toISOString()}] Recovery Event: ${event.eventType}`); console.log(` System: ${event.systemId}, Policy: ${event.policyId || 'none'}`); console.log(` Message: ${event.data.message}`); if (event.result) { console.log(` Result: ${event.result.success ? 'Success' : 'Failed'}`); if (event.result.details) { console.log(` Details: ${JSON.stringify(event.result.details)}`); } } }); } /** * Start the self-healing system */ public start(): void { console.log('🚢 Starting Self-Healing System...'); // Set initial operational context this.healthEngine.updateOperationalContext(OperationalContext.SAILING); this.recoveryOrchestrator.updateOperationalContext(OperationalContext.SAILING); // Set initial marine environment const environment: MarineEnvironmentStatus = { seaState: 'moderate', weather: 'clear', windSpeed: 12, temperature: 22, powerStatus: 'normal', connectivityQuality: 0.9, expectedFailureRate: 1.0, recommendedTimeoutMultiplier: 1.0, criticalOperationsOnly: false }; this.healthEngine.updateMarineEnvironment(environment); this.recoveryOrchestrator.updateMarineEnvironment(environment); // Start the health check engine this.healthEngine.start(); console.log('āœ… Self-Healing System started'); } /** * Stop the self-healing system */ public stop(): void { console.log('šŸ›‘ Stopping Self-Healing System...'); this.healthEngine.stop(); console.log('āœ… Self-Healing System stopped'); } /** * Simulate GPS degradation */ public simulateGPSDegradation(): void { console.log('šŸ”„ Simulating GPS degradation...'); // Degrade GPS state this.gpsState.satelliteCount = 3; this.gpsState.hdop = 4.5; this.gpsState.isCalibrated = false; console.log(`šŸ“‰ GPS degraded: ${this.gpsState.satelliteCount} satellites, HDOP: ${this.gpsState.hdop}`); } /** * Simulate GPS failure */ public simulateGPSFailure(): void { console.log('šŸ”„ Simulating GPS failure...'); // Fail GPS this.gpsState.satelliteCount = 0; this.gpsState.hdop = 10.0; this.gpsState.fix = '2d' as const; // Changed from 'none' to valid enum value this.gpsState.isCalibrated = false; console.log('šŸ“‰ GPS failed: No satellite fix'); } /** * Simulate GPS recovery */ public simulateGPSRecovery(): void { console.log('šŸ”„ Simulating GPS recovery...'); // Recover GPS this.gpsState.satelliteCount = 9; this.gpsState.hdop = 1.0; this.gpsState.fix = '3d' as const; this.gpsState.isCalibrated = true; console.log(`šŸ“ˆ GPS recovered: ${this.gpsState.satelliteCount} satellites, HDOP: ${this.gpsState.hdop}`); } /** * Mock GPS data provider */ private async mockGPSDataProvider(): Promise<GPSData> { return { latitude: 37.7749 + (Math.random() - 0.5) * 0.001, longitude: -122.4194 + (Math.random() - 0.5) * 0.001, altitude: 10 + Math.random() * 5, satelliteCount: this.gpsState.satelliteCount, hdop: this.gpsState.hdop, vdop: this.gpsState.hdop * 1.2, speed: Math.random() * 10, course: Math.random() * 360, timestamp: new Date(), fix: this.gpsState.fix }; } /** * Utility function to wait */ private wait(ms: number): Promise<void> { return new Promise(resolve => setTimeout(resolve, ms)); } } /** * Run the self-healing example */ export async function runSelfHealingExample(): Promise<void> { const example = new SelfHealingExample(); try { // Start the self-healing system example.start(); // Wait for initial health checks console.log('\nā±ļø Waiting for initial health checks...'); await new Promise(resolve => setTimeout(resolve, 3000)); // Simulate GPS degradation example.simulateGPSDegradation(); console.log('\nā±ļø Waiting for health checks to detect degradation...'); await new Promise(resolve => setTimeout(resolve, 5000)); // Simulate GPS failure example.simulateGPSFailure(); console.log('\nā±ļø Waiting for health checks to detect failure...'); await new Promise(resolve => setTimeout(resolve, 5000)); // Simulate GPS recovery example.simulateGPSRecovery(); console.log('\nā±ļø Waiting for health checks to detect recovery...'); await new Promise(resolve => setTimeout(resolve, 5000)); // Keep running for a bit to see ongoing monitoring console.log('\nā±ļø Running continuous monitoring for 10 seconds...'); await new Promise(resolve => setTimeout(resolve, 10000)); } finally { // Clean shutdown example.stop(); } } // Export for easy testing export default SelfHealingExample;