diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index 867fdae126a..1c1980a71de 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -55,6 +55,7 @@ 1. [COND] Add Air Conditioning systems failures - @mjuhe (Miquel Juhe) 1. [COND] Fixed Temp-Indication on CRZ page showing cockpit temperature for fwd and aft cabin - @cptnuss-ops (Lukas) 1. [FMS] Show ILS ident and frequency on ARRIVAL page - @tracernz (Mike) +1. [EFB/ATSU] Use MSFS METAR data rather than FSX cloud data from FBW API - @tracernz (Mike) ## 0.10.0 diff --git a/fbw-a32nx/src/systems/instruments/src/EFB/Dashboard/Widgets/WeatherWidget.tsx b/fbw-a32nx/src/systems/instruments/src/EFB/Dashboard/Widgets/WeatherWidget.tsx index e7841d10411..c34a46a8499 100644 --- a/fbw-a32nx/src/systems/instruments/src/EFB/Dashboard/Widgets/WeatherWidget.tsx +++ b/fbw-a32nx/src/systems/instruments/src/EFB/Dashboard/Widgets/WeatherWidget.tsx @@ -2,9 +2,10 @@ // SPDX-License-Identifier: GPL-3.0 import React, { FC, useEffect, useState } from 'react'; -import { Metar } from '@flybywiresim/api-client'; +import { Metar as FbwApiMetar } from '@flybywiresim/api-client'; import { Droplet, Speedometer2, ThermometerHalf, Wind } from 'react-bootstrap-icons'; import { MetarParserType, parseMetar, useInterval, usePersistentNumberProperty, usePersistentProperty } from '@flybywiresim/fbw-sdk'; +import { Metar as MsfsMetar } from '@microsoft/msfs-sdk'; import { t } from '../../translation'; import { SimpleInput } from '../../UtilComponents/Form/SimpleInput/SimpleInput'; import { ColoredMetar } from './ColorMetar'; @@ -76,7 +77,7 @@ export const WeatherWidget: FC = ({ name, simbriefIcao, user const [metarSource] = usePersistentProperty('CONFIG_METAR_SRC', 'MSFS'); const [metarError, setErrorMetar] = useState(''); const [usingColoredMetar] = usePersistentNumberProperty('EFB_USING_COLOREDMETAR', 1); - const source = metarSource === 'MSFS' ? 'MS' : metarSource; + const source = metarSource; const getBaroTypeForAirport = (icao: string) => (['K', 'C', 'M', 'P', 'RJ', 'RO', 'TI', 'TJ'] .some((r) => icao.toUpperCase().startsWith(r)) ? 'IN HG' : 'HPA'); @@ -120,15 +121,39 @@ export const WeatherWidget: FC = ({ name, simbriefIcao, user } }; - function getMetar(icao: any, source: any) { + async function getMetar(icao: string, source: string): Promise { if (icao.length !== 4 || icao === '----') { - return new Promise(() => { - setErrorMetar(t('Dashboard.ImportantInformation.Weather.NoIcaoProvided')); + setErrorMetar(t('Dashboard.ImportantInformation.Weather.NoIcaoProvided')); + dispatch(setMetar(MetarParserTypeProp)); + return Promise.resolve(); + } + + // Comes from the sim rather than the FBW API + if (source === 'MSFS') { + let metar: MsfsMetar; + // Catch parsing error separately + try { + metar = await Coherent.call('GET_METAR_BY_IDENT', icao); + if (metar.icao !== icao.toUpperCase()) { + throw new Error('No METAR available'); + } + } catch (err) { + console.log(`Error while retrieving Metar: ${err}`); + setErrorMetar(`${err.toString()}`); dispatch(setMetar(MetarParserTypeProp)); - }); + } + try { + const metarParse = parseMetar(metar.metarString); + dispatch(setMetar(metarParse)); + } catch (err) { + console.log(`Error while parsing Metar ("${metar.metarString}"): ${err}`); + setErrorMetar(`${t('Dashboard.ImportantInformation.Weather.MetarParsingError')}: ${err.toString().replace(/^Error: /, '').toUpperCase()}`); + dispatch(setMetar(MetarParserTypeProp)); + } + return Promise.resolve(); } - return Metar.get(icao, source) + return FbwApiMetar.get(icao, source) .then((result) => { // For METAR source Microsoft result.metar is undefined without throwing an error. // For the other METAR sources an error is thrown (Request failed with status code 404) @@ -184,9 +209,9 @@ export const WeatherWidget: FC = ({ name, simbriefIcao, user ?

{t('Dashboard.ImportantInformation.Weather.Loading')}

: ( <> -
+
handleIcao(value)} @@ -208,7 +233,7 @@ export const WeatherWidget: FC = ({ name, simbriefIcao, user ? ( <>
diff --git a/fbw-a32nx/src/systems/instruments/src/EFB/Settings/Pages/AtsuAocPage.tsx b/fbw-a32nx/src/systems/instruments/src/EFB/Settings/Pages/AtsuAocPage.tsx index a1e65e05a83..50ef60052a4 100644 --- a/fbw-a32nx/src/systems/instruments/src/EFB/Settings/Pages/AtsuAocPage.tsx +++ b/fbw-a32nx/src/systems/instruments/src/EFB/Settings/Pages/AtsuAocPage.tsx @@ -84,7 +84,7 @@ export const AtsuAocPage = () => { ]; const metarSourceButtons: ButtonType[] = [ - { name: 'MeteoBlue', setting: 'MSFS' }, + { name: 'MSFS', setting: 'MSFS' }, { name: 'PilotEdge', setting: 'PILOTEDGE' }, { name: 'IVAO', setting: 'IVAO' }, { name: 'VATSIM', setting: 'VATSIM' }, @@ -208,7 +208,7 @@ export const AtsuAocPage = () => { handleHoppieUsernameInput(value.replace(/\s/g, ''))} onChange={(value) => setHoppieUserId(value)} diff --git a/fbw-a32nx/src/systems/instruments/src/EFB/index.tsx b/fbw-a32nx/src/systems/instruments/src/EFB/index.tsx index b66a9a827b3..7ddf15ea65e 100644 --- a/fbw-a32nx/src/systems/instruments/src/EFB/index.tsx +++ b/fbw-a32nx/src/systems/instruments/src/EFB/index.tsx @@ -54,7 +54,7 @@ export const ErrorFallback = ({ resetErrorBoundary }: ErrorFallbackProps) => { const [sentryEnabled] = usePersistentProperty(SENTRY_CONSENT_KEY, SentryConsentState.Refused); return ( -
+
@@ -68,12 +68,12 @@ export const ErrorFallback = ({ resetErrorBoundary }: ErrorFallbackProps) => { You have opted into anonymous error reporting and this issue has been relayed to us. If you want immediate support, please share the following code to a member of staff in the #support channel on the FlyByWire Discord server: -

{sessionId}

+

{sessionId}

)} -
-

Reset Display

+
+

Reset Display

@@ -94,6 +94,11 @@ const setup = () => { readSettingsFromPersistentStorage(); migrateSettings(); setSessionId(); + + // Needed to fetch METARs from the sim + RegisterViewListener('JS_LISTENER_FACILITY', () => { + console.log('JS_LISTENER_FACILITY registered.'); + }, true); }; if (process.env.VITE_BUILD) { diff --git a/fbw-a32nx/src/systems/systems-host/index.ts b/fbw-a32nx/src/systems/systems-host/index.ts index 539e2b8c39e..82cd8b9ea99 100644 --- a/fbw-a32nx/src/systems/systems-host/index.ts +++ b/fbw-a32nx/src/systems/systems-host/index.ts @@ -49,6 +49,11 @@ class SystemsHost extends BaseInstrument { this.powerSupply.connectedCallback(); this.atsu.connectedCallback(); + + // Needed to fetch METARs from the sim + RegisterViewListener('JS_LISTENER_FACILITY', () => { + console.log('JS_LISTENER_FACILITY registered.'); + }, true); } public Update(): void { diff --git a/fbw-common/src/systems/datalink/router/src/Router.ts b/fbw-common/src/systems/datalink/router/src/Router.ts index e1958ed1d96..76d15f64f53 100644 --- a/fbw-common/src/systems/datalink/router/src/Router.ts +++ b/fbw-common/src/systems/datalink/router/src/Router.ts @@ -1,4 +1,4 @@ -// Copyright (c) 2021 FlyByWire Simulations +// Copyright (c) 2021, 2023 FlyByWire Simulations // SPDX-License-Identifier: GPL-3.0 import { @@ -17,6 +17,7 @@ import { } from '@datalink/common'; import { NXDataStore } from '@flybywiresim/fbw-sdk'; import { EventBus } from '@microsoft/msfs-sdk'; +import { MsfsConnector } from './msfs/MsfsConnector'; import { Vdl } from './vhf/VDL'; import { HoppieConnector } from './webinterfaces/HoppieConnector'; import { NXApiConnector } from './webinterfaces/NXApiConnector'; @@ -230,7 +231,13 @@ export class Router { if (index < icaos.length) { if (requestMetar === true) { - retval = await NXApiConnector.receiveMetar(icaos[index], message).then(() => this.receiveWeatherData(requestMetar, icaos, index + 1, message)); + const storedMetarSrc = NXDataStore.get('CONFIG_METAR_SRC', 'MSFS'); + + if (storedMetarSrc === 'MSFS') { + retval = await MsfsConnector.receiveMsfsMetar(icaos[index], message).then(() => this.receiveWeatherData(requestMetar, icaos, index + 1, message)); + } else { + retval = await NXApiConnector.receiveMetar(icaos[index], message).then(() => this.receiveWeatherData(requestMetar, icaos, index + 1, message)); + } } else { retval = await NXApiConnector.receiveTaf(icaos[index], message).then(() => this.receiveWeatherData(requestMetar, icaos, index + 1, message)); } diff --git a/fbw-common/src/systems/datalink/router/src/msfs/MsfsConnector.ts b/fbw-common/src/systems/datalink/router/src/msfs/MsfsConnector.ts new file mode 100644 index 00000000000..5bf2a084dc9 --- /dev/null +++ b/fbw-common/src/systems/datalink/router/src/msfs/MsfsConnector.ts @@ -0,0 +1,22 @@ +// Copyright (c) 2023 FlyByWire Simulations +// SPDX-License-Identifier: GPL-3.0 + +import { AtsuStatusCodes, WeatherMessage } from '@datalink/common'; +import { Metar } from '@microsoft/msfs-sdk'; + +export class MsfsConnector { + public static async receiveMsfsMetar(icao: string, message: WeatherMessage): Promise { + try { + const metar: Metar = await Coherent.call('GET_METAR_BY_IDENT', icao); + let report = metar.metarString; + if (!report || metar.icao !== icao) { + report = 'NO METAR AVAILABLE'; + } + message.Reports.push({ airport: icao, report }); + return AtsuStatusCodes.Ok; + } catch { + message.Reports.push({ airport: icao, report: 'NO METAR AVAILABLE' }); + return AtsuStatusCodes.Ok; + } + } +}