Add Metars with Decoding TODO: add TAFs

This commit is contained in:
Skylar Grant 2024-06-21 18:35:12 -04:00
parent 2a3b53ea08
commit 388bc4d021
5 changed files with 118 additions and 21 deletions

File diff suppressed because one or more lines are too long

26
dot-commands/metar.js Normal file
View File

@ -0,0 +1,26 @@
const fn = require('../functions');
module.exports = {
name: 'metar',
description: 'Lookup METAR for an airport',
usage: 'ICAO.metar',
async execute(message, commandData) {
try {
// Parse the ICAOs into a CSV list by trimming whitespace and converting delimiters
// Also checks for validity of ICAOs
const icaoList = fn.avWx.parseICAOs(commandData);
const metarData = await fn.avWx.metar.getData(icaoList);
const messages = fn.avWx.metar.parseData(metarData);
messages.forEach(messagePayload => {
message.reply(messagePayload);
});
} catch (e) {
try {
message.reply(`Something went wrong while retrieving the METAR: ${e.name}\n\n${e.message}`);
console.error(e);
} catch (e) {
console.error(e);
}
}
}
}

View File

@ -34,6 +34,7 @@ const dotCommandFiles = fs.readdirSync('./dot-commands/').filter(file => file.en
// MySQL database connection // MySQL database connection
const mysql = require('mysql'); const mysql = require('mysql');
const { GifData, PastaData } = require('./CustomModules/NodBot'); const { GifData, PastaData } = require('./CustomModules/NodBot');
const axios = require('axios');
const db = new mysql.createPool({ const db = new mysql.createPool({
connectionLimit: 10, connectionLimit: 10,
host: dbHost, host: dbHost,
@ -384,6 +385,30 @@ const functions = {
.setDescription("Generating a response, please stand by.") .setDescription("Generating a response, please stand by.")
.setFooter({ text: "Ligma balls" }); .setFooter({ text: "Ligma balls" });
return { embeds: [embed] }; return { embeds: [embed] };
},
avWx: {
metar(metarData) {
const wgst = metarData.wgst ? `G${metarData.wgst}` : '';
const clouds = [];
const interAltim = Math.round((metarData.altim * 0.2952998057228486) * 10)
const altim = interAltim / 100;
metarData.clouds.forEach(cloudLayer => {
clouds.push(`${cloudLayer.cover} @ ${cloudLayer.base}`);
});
const embed = new Discord.MessageEmbed()
.setAuthor({ name: `${metarData.icaoId} METAR`, iconURL: "https://aviationweather.gov/img/icons/awc-logo-180.png"})
.setDescription(metarData.rawOb)
.setFooter({ text: "METAR by AviationWeather.gov" })
.addFields(
{ name: 'Observation Time', value: `${metarData.reportTime}Z` },
{ name: 'Temperature', value: `${metarData.temp}ºC/${metarData.dewp}ºC`},
{ name: 'Winds', value: `${metarData.wdir}@${metarData.wspd}${wgst} kts`},
{ name: 'Visibility', value: `${metarData.visib} SM` },
{ name: 'Clouds', value: clouds.join('\n') },
{ name: 'Altimeter', value: `${altim} inHg` }
)
return { embeds: [embed] };
}
} }
}, },
collect: { collect: {
@ -489,16 +514,16 @@ const functions = {
} }
}, },
download: { download: {
requests(client) { async requests(client) {
const query = 'SELECT * FROM requests WHERE status = \'Active\' ORDER BY id DESC'; const query = 'SELECT * FROM requests WHERE status = \'Active\' ORDER BY id DESC';
db.query(query, (err, rows, fields) => { await db.query(query, (err, rows, fields) => {
if (err) throw err; if (err) throw err;
functions.collections.requests(rows, client); functions.collections.requests(rows, client);
}); });
}, },
pastas(client) { async pastas(client) {
const query = 'SELECT * FROM pastas ORDER BY id ASC'; const query = 'SELECT * FROM pastas ORDER BY id ASC';
db.query(query, (err, rows, fields) => { await db.query(query, (err, rows, fields) => {
if (err) throw err; if (err) throw err;
functions.collections.pastas(rows, client); functions.collections.pastas(rows, client);
}); });
@ -510,16 +535,16 @@ const functions = {
functions.collections.gifs(rows, client); functions.collections.gifs(rows, client);
}); });
}, },
joints(client) { async joints(client) {
const query = 'SELECT * FROM joints ORDER BY id ASC'; const query = 'SELECT * FROM joints ORDER BY id ASC';
db.query(query, (err, rows, fields) => { await db.query(query, (err, rows, fields) => {
if (err) throw err; if (err) throw err;
functions.collections.joints(rows, client); functions.collections.joints(rows, client);
}); });
}, },
strain(strainName, interaction) { async strain(strainName, interaction) {
const query = `SELECT id, strain, type, effects, description, flavor, rating FROM strains WHERE strain = ${db.escape(strainName)}`; const query = `SELECT id, strain, type, effects, description, flavor, rating FROM strains WHERE strain = ${db.escape(strainName)}`;
db.query(query, (err, rows, fields) => { await db.query(query, (err, rows, fields) => {
if (rows != undefined) { if (rows != undefined) {
const strainInfo = { const strainInfo = {
id: `${rows[0].id}`, id: `${rows[0].id}`,
@ -534,16 +559,16 @@ const functions = {
} }
}); });
}, },
strains(client) { async strains(client) {
const query = 'SELECT id, strain FROM strains'; const query = 'SELECT id, strain FROM strains';
db.query(query, (err, rows, fields) => { await db.query(query, (err, rows, fields) => {
if (err) throw err; if (err) throw err;
functions.collections.strains(rows, client); functions.collections.strains(rows, client);
}); });
}, },
medicalAdvice(client) { async medicalAdvice(client) {
const query = 'SELECT * FROM medical_advice ORDER BY id ASC'; const query = 'SELECT * FROM medical_advice ORDER BY id ASC';
db.query(query, (err, rows, fields) => { await db.query(query, (err, rows, fields) => {
if (err) throw err; if (err) throw err;
functions.collections.medicalAdvice(rows, client); functions.collections.medicalAdvice(rows, client);
}); });
@ -709,6 +734,49 @@ const functions = {
} }
} }
}, },
avWx: {
parseICAOs(commandData) {
let input = commandData.args.toUpperCase();
// Replace newlines and different delimiters with a comma
let standardizedInput = input.replace(/[\s,;]+/g, ',');
// Split the string by commas
let icaoArray = standardizedInput.split(',');
// Trim each element to remove extra whitespace
icaoArray = icaoArray.map(icao => icao.trim()).filter(icao => icao.length > 0);
icaoArray.forEach(icao => {
if (!(config.icaoIds.includes(icao))) throw new Error(`Invalid ICAO ID Detected: ${icao}`);
});
// Join the array into a comma-separated string
return icaoArray.join(',');
},
metar: {
async getAllICAOs() {
const reqUrl = `https://aviationweather.gov/api/data/metar?format=json`
const response = await axios.get(reqUrl);
let icaoArray = [];
response.data.forEach(e => {
icaoArray.push(e.icaoId)
});
return icaoArray;
},
async getData(icaoList) {
const reqUrl = `https://aviationweather.gov/api/data/metar?ids=${icaoList}&format=json`;
const response = await axios.get(reqUrl);
return response.data;
},
parseData(metarData) {
let messages = [];
metarData.forEach(metar => {
messages.push(functions.embeds.avWx.metar(metar));
})
return messages;
}
}
},
generateErrorId() { generateErrorId() {
const digitCount = 10; const digitCount = 10;
const digits = []; const digits = [];

16
main.js
View File

@ -30,18 +30,20 @@ const strings = require('./strings.json');
const { GifData } = require('./CustomModules/NodBot.js'); const { GifData } = require('./CustomModules/NodBot.js');
const isDev = process.env.isDev; const isDev = process.env.isDev;
client.once('ready', () => { client.once('ready', async () => {
fn.collections.slashCommands(client); fn.collections.slashCommands(client);
fn.collections.dotCommands(client); fn.collections.dotCommands(client);
fn.collections.setvalidCommands(client); fn.collections.setvalidCommands(client);
fn.collections.roaches(client); fn.collections.roaches(client);
fn.download.gifs(client); await fn.download.gifs(client);
fn.download.pastas(client); await fn.download.pastas(client);
fn.download.joints(client); await fn.download.joints(client);
fn.download.requests(client); await fn.download.requests(client);
fn.download.strains(client); await fn.download.strains(client);
fn.download.medicalAdvice(client); await fn.download.medicalAdvice(client);
console.log('Ready!'); console.log('Ready!');
// const icaoArray = await fn.avWx.metar.getAllICAOs();
// console.log(JSON.stringify(icaoArray));
client.channels.fetch(statusChannelId).then(channel => { client.channels.fetch(statusChannelId).then(channel => {
channel.send(`${new Date().toISOString()} -- <@${process.env.ownerId}>\nStartup Sequence Complete`); channel.send(`${new Date().toISOString()} -- <@${process.env.ownerId}>\nStartup Sequence Complete`);
}); });

View File

@ -1,6 +1,6 @@
{ {
"name": "nodbot", "name": "nodbot",
"version": "3.2.3", "version": "3.3.0",
"description": "Nods and Nod Accessories, now with ChatGPT!", "description": "Nods and Nod Accessories, now with ChatGPT!",
"main": "main.js", "main": "main.js",
"dependencies": { "dependencies": {