Skip to content

Commit

Permalink
Merge pull request #125 from flybywiresim/revert-124-fix-ivao
Browse files Browse the repository at this point in the history
Revert "fix: decommissioned whazzup being used causing error"
  • Loading branch information
Benjozork authored Apr 23, 2022
2 parents 9243d99 + 85ace2c commit 5867193
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 256 deletions.
76 changes: 52 additions & 24 deletions src/atc/atc.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { IvaoService } from '../utilities/ivao.service';
@Injectable()
export class AtcService {
constructor(private readonly vatsimService: VatsimService,
private readonly ivaoService: IvaoService) { }
private readonly ivaoService: IvaoService) {}

public async getVatsimControllers(): Promise<ATCInfo[]> {
const data = await this.vatsimService.fetchVatsimData();
Expand Down Expand Up @@ -46,36 +46,64 @@ export class AtcService {
}

public async getIvaoControllers(): Promise<ATCInfo[]> {
const { clients: { atcs } } = await this.ivaoService.fetchIvaoData();

return atcs.map((atc) => ({
callsign: atc.callsign,
frequency: atc.atcSession.frequency.toString(),
textAtis: atc.atis?.lines,
latitude: atc.lastTrack.latitude,
longitude: atc.lastTrack.longitude,
type: this.callSignToAtcType(atc.callsign),
// TODO FIXME: visual range is not currently available in the new IVAO Whazzup v2 data
visualRange: 100,
}));
const data = await this.ivaoService.fetchIvaoData();

const arr: ATCInfo[] = [];
for (const c of data) {
if (c.indexOf(':ATC:') > -1) {
const split = c.split(':');
if (split[0].indexOf('_') > -1) {
const atisLine = data.find((x) => x.startsWith(`${split[0].split('_')[0]}_TWR`));
const atis = atisLine?.split(':')[35]
.split('^§')
.slice(1)
.join(' ')
.toUpperCase();

arr.push({
callsign: split[0],
frequency: split[4],
textAtis: atis ? [atis] : null,
visualRange: parseInt(split[19]),
type: this.callSignToAtcType(split[0]),
latitude: parseFloat(split[5]),
longitude: parseFloat(split[6]),
});
}
}
}

return arr.filter((c) => c.type !== AtcType.UNKNOWN);
}

public callSignToAtcType(callsign: string): AtcType {
switch (callsign.split('_').reverse()[0]) {
case 'CTR': return AtcType.RADAR;
case 'DEL': return AtcType.DELIVERY;
case 'GND': return AtcType.GROUND;
case 'DEP': return AtcType.DEPARTURE;
case 'TWR': return AtcType.TOWER;
case 'APP': return AtcType.APPROACH;
case 'ATIS': return AtcType.ATIS;
default: return AtcType.UNKNOWN;
if (callsign.indexOf('_CTR') > -1) {
return AtcType.RADAR;
}
if (callsign.indexOf('_DEL') > -1) {
return AtcType.DELIVERY;
}
if (callsign.indexOf('_GND') > -1) {
return AtcType.GROUND;
}
if (callsign.indexOf('_DEP') > -1) {
return AtcType.DEPARTURE;
}
if (callsign.indexOf('_APP') > -1) {
return AtcType.APPROACH;
}
if (callsign.indexOf('_TWR') > -1) {
return AtcType.TOWER;
}
if (callsign.indexOf('_ATIS') > -1) {
return AtcType.ATIS;
}
return AtcType.UNKNOWN;
}

public getFrequency(array: any[]): string {
public getFrequency(array:any[]):string {
if (array && array.length > 0 && array[0].frequency) {
let freqInString: string = array[0].frequency.toString();
let freqInString : string = array[0].frequency.toString();
freqInString = `${freqInString.substr(0, 3)}.${freqInString.substr(3)}`;
return parseFloat(freqInString).toFixed(3);
}
Expand Down
216 changes: 104 additions & 112 deletions src/atis/atis.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,128 +8,120 @@ import { IvaoService } from '../utilities/ivao.service';

@Injectable()
export class AtisService {
private readonly logger = new Logger(AtisService.name);
private readonly logger = new Logger(AtisService.name);

constructor(
private http: HttpService,
private readonly cache: CacheService,
private readonly vatsim: VatsimService,
private readonly ivao: IvaoService,
) {}
constructor(private http: HttpService,
private readonly cache: CacheService,
private readonly vatsim: VatsimService,
private readonly ivao : IvaoService) {
}

getForICAO(icao: string, source?: string): Promise<Atis> {
const icaoCode = icao.toUpperCase();
this.logger.debug(
`Searching for ICAO ${icaoCode} from source ${source}`,
);
getForICAO(icao: string, source?: string): Promise<Atis> {
const icaoCode = icao.toUpperCase();
this.logger.debug(`Searching for ICAO ${icaoCode} from source ${source}`);

switch (source?.toLowerCase()) {
case 'faa':
default:
return this.handleFaa(icaoCode).toPromise();
case 'vatsim':
return this.handleVatsim(icaoCode);
case 'ivao':
return this.handleIvao(icaoCode);
case 'pilotedge':
return this.handlePilotEdge(icaoCode).toPromise();
}
}
switch (source?.toLowerCase()) {
case 'faa':
default:
return this.handleFaa(icaoCode).toPromise();
case 'vatsim':
return this.handleVatsim(icaoCode);
case 'ivao':
return this.handleIvao(icaoCode);
case 'pilotedge':
return this.handlePilotEdge(icaoCode).toPromise();
}
}

// FAA
private handleFaa(icao: string): Observable<Atis> {
return this.http.get<any>(`https://datis.clowd.io/api/${icao}`).pipe(
tap((response) => this.logger.debug(
`Response status ${response.status} for FAA ATIS request`,
)),
map((response) => {
if (response.data.error) {
throw this.generateNotAvailableException(
response.data,
icao,
);
}
// FAA
private handleFaa(icao: string): Observable<Atis> {
return this.http.get<any>(`https://datis.clowd.io/api/${icao}`)
.pipe(
tap((response) => this.logger.debug(`Response status ${response.status} for FAA ATIS request`)),
map((response) => {
if (response.data.error) {
throw this.generateNotAvailableException(response.data, icao);
}

const atis: Atis = {
icao,
source: 'FAA',
};
const atis: Atis = {
icao,
source: 'FAA',
};

response.data.forEach((x) => {
atis[x.type] = x.datis;
});
response.data.forEach((x) => {
atis[x.type] = x.datis;
});

atis.dep?.toUpperCase();
atis.arr?.toUpperCase();
atis.combined?.toUpperCase();
atis.dep?.toUpperCase();
atis.arr?.toUpperCase();
atis.combined?.toUpperCase();

return atis;
}),
catchError((err) => {
throw this.generateNotAvailableException(err, icao);
}),
);
}
return atis;
}),
catchError(
(err) => {
throw this.generateNotAvailableException(err, icao);
},
),
);
}

private handleVatsim(icao: string): Promise<Atis> {
return this.vatsim
.fetchVatsimData()
.then((response) => ({
icao,
source: 'Vatsim',
combined: response.atis
.find((x) => x.callsign === `${icao}_ATIS`)
.text_atis.join(' ')
.toUpperCase(),
}))
.catch((e) => {
throw this.generateNotAvailableException(e, icao);
});
}
private handleVatsim(icao: string): Promise<Atis> {
return this.vatsim.fetchVatsimData()
.then((response) => ({
icao,
source: 'Vatsim',
combined: response.atis
.find((x) => x.callsign === `${icao}_ATIS`)
.text_atis
.join(' ')
.toUpperCase(),
}))
.catch((e) => {
throw this.generateNotAvailableException(e, icao);
});
}

private handleIvao(icao: string): Promise<Atis> {
return this.ivao
.fetchIvaoData()
.then((response) => ({
icao,
source: 'IVAO',
combined: response.clients.atcs
.find((atc) => atc.callsign.includes(icao.toUpperCase()))
?.atis?.lines.join(' '),
}))
.catch((e) => {
throw this.generateNotAvailableException(e, icao);
});
}
private handleIvao(icao: string): Promise<Atis> {
return this.ivao.fetchIvaoData()
.then((response) => ({
icao,
source: 'IVAO',
combined: response
.find((x) => x.startsWith(`${icao}_TWR`))
.split(':')[35]
.split('^§')
.slice(1)
.join(' ')
.toUpperCase(),
}))
.catch((e) => {
throw this.generateNotAvailableException(e, icao);
});
}

// PilotEdge
private handlePilotEdge(icao: string): Observable<Atis> {
return this.http
.get<any>(`https://www.pilotedge.net/atis/${icao}.json`)
.pipe(
tap((response) => this.logger.debug(
`Response status ${response.status} for PilotEdge ATIS request`,
)),
map((response) => ({
icao,
source: 'FAA',
combined: response.data.text
.replace('\n\n', ' ')
.toUpperCase(),
})),
catchError((err) => {
throw this.generateNotAvailableException(err, icao);
}),
);
}
// PilotEdge
private handlePilotEdge(icao: string): Observable<Atis> {
return this.http.get<any>(`https://www.pilotedge.net/atis/${icao}.json`)
.pipe(
tap((response) => this.logger.debug(`Response status ${response.status} for PilotEdge ATIS request`)),
map((response) => ({
icao,
source: 'FAA',
combined: response.data.text.replace('\n\n', ' ').toUpperCase(),
})),
catchError(
(err) => {
throw this.generateNotAvailableException(err, icao);
},
),
);
}

private generateNotAvailableException(err: any, icao: string) {
const exception = new HttpException(
`ATIS not available for ICAO: ${icao}`,
404,
);
this.logger.error(err);
this.logger.error(exception);
return exception;
}
private generateNotAvailableException(err: any, icao: string) {
const exception = new HttpException(`ATIS not available for ICAO: ${icao}`, 404);
this.logger.error(err);
this.logger.error(exception);
return exception;
}
}
Loading

0 comments on commit 5867193

Please sign in to comment.