UNPKG

@sailboat-computer/health-monitoring

Version:

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

302 lines (276 loc) 8.25 kB
/** * GPS Recalibration Recovery Action * Demonstrates a concrete implementation of a recovery action for GPS systems */ import { BaseRecoveryAction, RecoveryActionConfig, RecoveryActionResult, RecoveryActionType, RecoveryPriority, RecoveryStatus } from '../RecoveryAction'; import { HealthCheckResult, OperationalContext, OperationalContextType, MarineSystemType, MarineSystemTypeType, MarineEnvironmentStatus } from '../../types'; /** * GPS recalibration parameters */ export interface GPSRecalibrationParams { /** * Reset satellite tracking */ resetSatelliteTracking: boolean; /** * Clear almanac data */ clearAlmanac: boolean; /** * Reset HDOP thresholds */ resetHDOPThresholds: boolean; /** * Force cold start */ forceColdStart: boolean; /** * Wait time for satellite acquisition in seconds */ satelliteAcquisitionTimeout: number; } /** * GPS Recalibration Action * Attempts to recalibrate a GPS system that is reporting poor quality data */ export class GPSRecalibrationAction extends BaseRecoveryAction { private gpsInterface: { resetSatelliteTracking: () => Promise<boolean>; clearAlmanac: () => Promise<boolean>; resetHDOPThresholds: () => Promise<boolean>; forceColdStart: () => Promise<boolean>; waitForSatellites: (timeout: number) => Promise<number>; }; constructor( config: RecoveryActionConfig, gpsInterface: { resetSatelliteTracking: () => Promise<boolean>; clearAlmanac: () => Promise<boolean>; resetHDOPThresholds: () => Promise<boolean>; forceColdStart: () => Promise<boolean>; waitForSatellites: (timeout: number) => Promise<number>; } ) { super(config); this.gpsInterface = gpsInterface; } /** * Perform GPS recalibration */ protected async performRecovery( triggeringCheck: HealthCheckResult, operationalContext: OperationalContextType, marineEnvironment?: MarineEnvironmentStatus ): Promise<RecoveryActionResult> { const params = this.config.parameters as GPSRecalibrationParams; const startTime = new Date(); const details: Record<string, any> = {}; const steps: string[] = []; try { // Step 1: Reset satellite tracking if configured if (params.resetSatelliteTracking) { steps.push('Resetting satellite tracking'); const resetResult = await this.gpsInterface.resetSatelliteTracking(); details['resetSatelliteTracking'] = resetResult; if (!resetResult) { return this.createRecoveryResult( startTime, new Date(), false, 'Failed to reset satellite tracking', steps, details, operationalContext, marineEnvironment ); } } // Step 2: Clear almanac if configured if (params.clearAlmanac) { steps.push('Clearing almanac data'); const clearResult = await this.gpsInterface.clearAlmanac(); details['clearAlmanac'] = clearResult; if (!clearResult) { return this.createRecoveryResult( startTime, new Date(), false, 'Failed to clear almanac data', steps, details, operationalContext, marineEnvironment ); } } // Step 3: Reset HDOP thresholds if configured if (params.resetHDOPThresholds) { steps.push('Resetting HDOP thresholds'); const resetResult = await this.gpsInterface.resetHDOPThresholds(); details['resetHDOPThresholds'] = resetResult; if (!resetResult) { return this.createRecoveryResult( startTime, new Date(), false, 'Failed to reset HDOP thresholds', steps, details, operationalContext, marineEnvironment ); } } // Step 4: Force cold start if configured if (params.forceColdStart) { steps.push('Forcing cold start'); const coldStartResult = await this.gpsInterface.forceColdStart(); details['forceColdStart'] = coldStartResult; if (!coldStartResult) { return this.createRecoveryResult( startTime, new Date(), false, 'Failed to force cold start', steps, details, operationalContext, marineEnvironment ); } } // Step 5: Wait for satellites steps.push('Waiting for satellite acquisition'); const satelliteCount = await this.gpsInterface.waitForSatellites( params.satelliteAcquisitionTimeout ); details['satelliteCount'] = satelliteCount; // Check if we acquired enough satellites const success = satelliteCount >= 4; // Minimum for 3D fix const message = success ? `GPS recalibration successful, acquired ${satelliteCount} satellites` : `GPS recalibration failed, only acquired ${satelliteCount} satellites`; return this.createRecoveryResult( startTime, new Date(), success, message, steps, details, operationalContext, marineEnvironment ); } catch (error) { return this.createRecoveryResult( startTime, new Date(), false, `GPS recalibration error: ${(error as Error).message}`, steps, details, operationalContext, marineEnvironment ); } } /** * Create a recovery result */ private createRecoveryResult( startTime: Date, endTime: Date, success: boolean, message: string, steps: string[], details: Record<string, any>, operationalContext: OperationalContextType, marineEnvironment?: MarineEnvironmentStatus ): RecoveryActionResult { return { actionId: this.config.actionId, name: this.config.name, type: this.config.type, status: success ? RecoveryStatus.SUCCEEDED : RecoveryStatus.FAILED, message, startTime, endTime, duration: endTime.getTime() - startTime.getTime(), retryCount: this.retryCount, success, error: success ? '' : message, details: { ...details, steps, completedSteps: steps.length }, marineContext: { operationalContext, environmentalConditions: marineEnvironment ? { ...marineEnvironment } : undefined }, triggeringCheck: undefined }; } } /** * Create a GPS recalibration action with default configuration */ export function createGPSRecalibrationAction( gpsInterface: { resetSatelliteTracking: () => Promise<boolean>; clearAlmanac: () => Promise<boolean>; resetHDOPThresholds: () => Promise<boolean>; forceColdStart: () => Promise<boolean>; waitForSatellites: (timeout: number) => Promise<number>; }, customConfig?: Partial<RecoveryActionConfig> ): GPSRecalibrationAction { const defaultConfig: RecoveryActionConfig = { actionId: 'gps-recalibration', name: 'GPS Recalibration', type: RecoveryActionType.RECALIBRATE, marineSystemType: MarineSystemType.NAVIGATION as MarineSystemTypeType, priority: RecoveryPriority.HIGH, timeout: 60000, // 60 seconds maxRetries: 1, retryDelay: 5000, requiresApproval: false, automatedExecution: true, marineSettings: { allowedContexts: [ OperationalContext.DOCKED, OperationalContext.ANCHORED, OperationalContext.SAILING, OperationalContext.MOTORING ] as OperationalContextType[], allowInRoughSeas: false, powerAware: true, safetyImpact: true, powerConsumption: 2 // 2 watts }, parameters: { resetSatelliteTracking: true, clearAlmanac: false, resetHDOPThresholds: true, forceColdStart: false, satelliteAcquisitionTimeout: 30 // 30 seconds } }; return new GPSRecalibrationAction( { ...defaultConfig, ...customConfig }, gpsInterface ); }