diff --git a/packages/server-api/src/autopilotapi.ts b/packages/server-api/src/autopilotapi.ts index 31c7ae7fe..31ac0dac6 100644 --- a/packages/server-api/src/autopilotapi.ts +++ b/packages/server-api/src/autopilotapi.ts @@ -1,21 +1,39 @@ +import { PathValue } from "./deltas" + export type AutopilotUpdateAttrib = | 'mode' | 'state' | 'target' | 'engaged' | 'options' + | 'alarm' const AUTOPILOTUPDATEATTRIBS: AutopilotUpdateAttrib[] = [ 'mode', 'state', 'target', 'engaged', - 'options' + 'options', + 'alarm' ] export const isAutopilotUpdateAttrib = (s: string) => AUTOPILOTUPDATEATTRIBS.includes(s as AutopilotUpdateAttrib) +export type AutopilotAlarm = + | 'waypointAdvance' + | 'waypointArrival' + | 'routeComplete' + +const AUTOPILOTALARMS: AutopilotAlarm[] = [ + 'waypointAdvance', + 'waypointArrival', + 'routeComplete' +] + +export const isAutopilotAlarm = (s: string) => + AUTOPILOTALARMS.includes(s as AutopilotAlarm) + export type TackGybeDirection = 'port' | 'starboard' export interface AutopilotApi { @@ -29,6 +47,12 @@ export interface AutopilotApi { /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ value: any ): void + apAlarm( + pluginId: string, + deviceId: string, + alarmName: AutopilotAlarm, + value: PathValue + ): void } /** @see {isAutopilotProvider} ts-auto-guard:type-guard */ @@ -76,4 +100,9 @@ export interface AutopilotProviderRegistry { /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ value: any ): void + autopilotAlarm( + deviceId: string, + alarmName: AutopilotAlarm, + value: PathValue + ): void } diff --git a/src/api/autopilot/index.ts b/src/api/autopilot/index.ts index fb60f8554..df4b94927 100644 --- a/src/api/autopilot/index.ts +++ b/src/api/autopilot/index.ts @@ -13,10 +13,13 @@ import { AutopilotInfo, SKVersion, Path, + PathValue, Delta, isAutopilotProvider, AutopilotUpdateAttrib, - isAutopilotUpdateAttrib + isAutopilotUpdateAttrib, + AutopilotAlarm, + isAutopilotAlarm } from '@signalk/server-api' const AUTOPILOT_API_PATH = `/signalk/v2/api/vessels/self/steering/autopilots` @@ -107,6 +110,7 @@ export class AutopilotApi { this.defaultDeviceId = undefined this.defaultProviderId = undefined this.defaultProvider = undefined + this.emitDeltaMsg('defaultPilot', this.defaultDeviceId, 'autopilotApi') } debug( @@ -145,6 +149,30 @@ export class AutopilotApi { } } + // Pass alarm / notification from autopilot. + apAlarm( + pluginId: string, + deviceId: string = pluginId + '.default', + alarmName: AutopilotAlarm, + value: PathValue + ) { + if (isAutopilotAlarm(alarmName)) { + debug(`Alarm -> ${deviceId}:`, value) + this.server.handleMessage(deviceId, { + updates: [ + { + values: [ + { + path: `notifications.steering.autopilot.${alarmName}` as Path, + value: value + } + ] + } + ] + }) + } + } + // ***** /Plugin Interface methods ***** private updateAllowed(request: Request): boolean { @@ -587,6 +615,7 @@ export class AutopilotApi { this.defaultDeviceId ) as string this.defaultProvider = this.autopilotProviders.get(this.defaultProviderId) + this.emitDeltaMsg('defaultPilot', this.defaultDeviceId, 'autopilotApi') debug(`Default Device = ${this.defaultDeviceId}`) debug(`Default Provider = ${this.defaultProviderId}`) return @@ -600,6 +629,7 @@ export class AutopilotApi { this.defaultDeviceId ) as string this.defaultProvider = this.autopilotProviders.get(this.defaultProviderId) + this.emitDeltaMsg('defaultPilot', this.defaultDeviceId, 'autopilotApi') debug(`Default Device = ${this.defaultDeviceId}`) debug(`Default Provider = ${this.defaultProviderId}`) return @@ -628,4 +658,5 @@ export class AutopilotApi { this.server.handleMessage(source, msg, SKVersion.v2) this.server.handleMessage(source, msg, SKVersion.v1) } + } diff --git a/src/interfaces/plugins.ts b/src/interfaces/plugins.ts index 9d4901e47..8c9a71a03 100644 --- a/src/interfaces/plugins.ts +++ b/src/interfaces/plugins.ts @@ -24,7 +24,8 @@ import { ServerAPI, PointDestination, RouteDestination, - AutopilotUpdateAttrib + AutopilotUpdateAttrib, + AutopilotAlarm } from '@signalk/server-api' // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore @@ -541,6 +542,13 @@ module.exports = (theApp: any) => { ) => { autopilotApi.apUpdate(plugin.id, deviceId, attrib, value) } + appCopy.autopilotAlarm = ( + deviceId: string, + alarmName: AutopilotAlarm, + value: any + ) => { + autopilotApi.apAlarm(plugin.id, deviceId, alarmName, value) + } const courseApi: CourseApi = app.courseApi _.omit(appCopy, 'courseApi') // don't expose the actual course api manager