Compare commits

...
13 Commits
7 changed files with 158 additions and 73 deletions

No files matched your search

+18 -2
View File
@@ -1,3 +1,19 @@
# template-mit
# Nomadic Weather
Template with MIT license, protected `main` branch, and available `dev` branch.
See the [wiki](https://git.hyperling.com/me/nomadic-weather/wiki) for more information.
## cli
Programs made while testing with the API endpoint.
## doc
Documentation.
## gui
Flutter project directed at Android and Linux.
## srv
Backend code.
+18
View File
@@ -0,0 +1,18 @@
# Nomadic Weather CLI
Prototype for playing with [Open-Meteo](https://open-meteo.com).
Locations need modified manually since it's still just a prototype.
## prototype.js
Got a little carried away and made it pretty formal.
Still a prototype though since the locations are hardcoded.
Would be made more complete by accepting a list of values, an env file,
or basically just any way of handling the locations as user input.
## install.sh
Allows the script to be installed either in ~/bin/ or /usr/local/bin/.
Also handles removal if it is no longer wanted.
Currently does not remove from /usr/local/src/.
+31 -8
View File
@@ -5,10 +5,12 @@
## Variables ##
DIR="$(cd "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
PROJ="$(cd "$DIR"/.. &>/dev/null && pwd)"
PROG="$(basename -- "${BASH_SOURCE[0]}")"
LOCAL=~/bin
GLOBAL=/usr/local/bin
GLOBAL_SRC=/usr/local/src
GLOBAL="$(npm prefix -g)"
GLOBAL_BIN="$GLOBAL/bin"
GLOBAL_SRC="$GLOBAL/src"
name_local="prototype.js"
name_short="nomad"
@@ -46,6 +48,24 @@ function usage {
exit $1
}
## Validations ##
count=0
while [[ ! -d "$DIR/node_modules" ]]; do
if (( count > 0 )); then
echo "Failed to download libraries, please intervene."
exit 3
fi
if [[ -z "`which npm`" ]]; then
echo "Libraries are missing, please run 'npm install' first."
exit 2
else
echo "Downloading libraries with 'npm install'."
cd $DIR && npm install
fi
count=$(( count++ ))
done
## Parameters ##
while getopts ":gslarh" arg; do
@@ -75,19 +95,19 @@ fi
cmd=""
dir="$LOCAL"
src="$DIR"
src="$PROJ"
if [[ "$global" == "Y" ]]; then
dir="$GLOBAL"
dir="$GLOBAL_BIN"
cmd="sudo"
echo "Requesting sudo privileges... "
sudo echo "Success!"
mkdir -pv /usr/local/src
sudo cp -Rv "$DIR" $GLOBAL_SRC/
src="$GLOBAL_SRC/`basename "$DIR"`"
sudo cp -Rv "$PROJ" "$GLOBAL_SRC"/
src="$GLOBAL_SRC/`basename "$PROJ"`"
fi
if [[ -z "$remove" ]]; then
cmd="$cmd ln -svf $src/$name_local"
cmd="$cmd ln -svf $src/cli/$name_local"
else
cmd="$cmd rm -v"
fi
@@ -100,7 +120,10 @@ fi
#fi
for prog in $name; do
mkdir -pv "$dir"
# fix spaces to tabs
if [[ ! -d "$dir" ]]; then
mkdir -pv "$dir"
fi
$cmd "$dir/$prog"
done
+91 -63
View File
@@ -23,10 +23,25 @@
* - added args, basically took over the program without any incremental commits
* */
/* TODO
* - Add way to manage a DB such as ~/.confg/nomadic-weather/locations.json
* - -c argument for creating locations
* - Should act like "read" to intake data for Season, Nickname, Lat, Long, and Elevation.
* - -d argument for deleting locations
* - Displays the list and asks which index# to delete.
* - -m argument for modifying locations
* - Displays a list and asks which index to open, then goes through create-like process.
* - Tie locations to seasons, as noted for the GUI in the Design, and sort on that rather than elevation.
* */
/* * * Libraries * * */
const yargs = require('yargs/yargs');
const { hideBin } = require('yargs/helpers');
const version = '0.0.1';
/* * * Variables * * */
const version = '0.1.1';
const days_fore_max = 16;
const days_fore_default = 12;
@@ -34,52 +49,22 @@ const days_past_default = 2;
const ft_to_m = 0.3048;
const argv = yargs(hideBin(process.argv))
.option('days_fore', {
alias: 'f',
describe: 'Set forecast days, such as "-f 10". Maximum of 16.',
type: 'number',
requiresArg: true,
})
.option('days_past', {
alias: 'p',
describe: 'Set past days, such as "-p 3"',
type: 'number',
requiresArg: true,
})
.option('calc_elevation', {
alias: 'e',
describe: 'Set to calculate elevation at lat/long.',
type: 'boolean',
})
.check((argv) => {
if (argv.f !== undefined && (isNaN(argv.f) || argv.f < 0)) {
throw new Error('Forecast days must be a non-negative number');
}
if (argv.p !== undefined && (isNaN(argv.p) || argv.p < 0)) {
throw new Error('Past days must be a non-negative number');
}
return true;
})
//.demandOption(['timeout', 'debug']) // Optional: require these arguments
.strict()
.help()
.version(version)
.argv
;
const RED = "\x1b[31m";
const GRN = "\x1b[32m";
const YLW = "\x1b[33m";
const BLU = "\x1b[34m";
const MGN = "\x1b[35m";
const CYN = "\x1b[36m";
const WHT = "\x1b[37m";
const RESET = "\x1b[0m";
function max (value, upper) {
return (value > upper) ? upper : value;
}
const days_fore = max(argv.hasOwnProperty("days_fore") ? argv.days_fore : days_fore_default, days_fore_max);
const days_past = argv.hasOwnProperty("days_past") ? argv.days_past : days_past_default;
const calc_elevation = argv.calc_elevation ? true : false;
const pref_high_upper = 75;
const pref_high_lower = 60;
const pref_low_upper = 55;
const pref_low_lower = 40;
const days = days_fore + days_past;
console.log(`Averaging for ${days} days: ${days_fore} forecasted, ${days_past} past.`);
if (calc_elevation) console.log("Calculating elevation rather than using provided values.");
else console.log("Using user-provided elevations when they exist.");
const tolerance_light = 10;
const tolerance_heavy = 20;
const locations = [
//{ name: "Flagstaff, AZ", lat: 35.1983, lon: -111.6513, elevation: 6903 },
@@ -105,30 +90,22 @@ const locations = [
//{ name: "Ehrenberg, AZ", lat: 33.9897, lon: -114.3550, elevation: 333 },
{ name: "Ehrenberg: ++", lat: 33.9897, lon: -114.3550, elevation: 300 },
{ name: "Quartzsite: ++", lat: 33.6763, lon: -114.2104, elevation: 900 },
{ name: "Kanab: BF", lat: 37.1412, lon: -112.5439, elevation: 5500 },
//{ name: "Kanab: ++", lat: 37.1399, lon: -112.5926, elevation: 5700 },
];
locations.sort((a, b) => a.elevation - b.elevation);
const RED = "\x1b[31m";
const GRN = "\x1b[32m";
const YLW = "\x1b[33m";
const BLU = "\x1b[34m";
const MGN = "\x1b[35m";
const CYN = "\x1b[36m";
const WHT = "\x1b[37m";
const RESET = "\x1b[0m";
/* * * Functions * * */
function highlight(value, min, max) {
const n = parseFloat(value);
return (n >= min && n <= max) ? `${GRN}${value}${RESET}` : value;
}
const pref_high_upper = 75;
const pref_high_lower = 60;
const pref_low_upper = 55;
const pref_low_lower = 40;
const tolerance_light = 10;
const tolerance_heavy = 20;
function pad(str, width) {
const visible = str.replace(/\x1b\[\d+m/g, '').length;
return ' '.repeat(Math.max(0, width - visible)) + str;
}
function check (value, min, max) {
const n = parseFloat(value);
@@ -156,11 +133,60 @@ function check (value, min, max) {
//return (n >= min && n <= max) ? `${GRN}${value}${RESET}` : value;
}
function pad(str, width) {
const visible = str.replace(/\x1b\[\d+m/g, '').length;
return ' '.repeat(Math.max(0, width - visible)) + str;
function max (value, upper) {
return (value > upper) ? upper : value;
}
/* * * Parameters * * */
const argv = yargs(hideBin(process.argv))
.option('days_fore', {
alias: 'f',
describe: 'Future / forecast days, such as "-f 10". Maximum of 16.',
type: 'number',
requiresArg: true,
})
.option('days_past', {
alias: 'p',
describe: 'Past days, such as "-p 3"',
type: 'number',
requiresArg: true,
})
.option('calc_elevation', {
alias: 'e',
describe: 'Set to calculate elevation at lat/long rather than use supplied.',
type: 'boolean',
})
.check((argv) => {
if (argv.f !== undefined && (isNaN(argv.f) || argv.f < 0)) {
throw new Error('Forecast days must be a non-negative number');
}
if (argv.p !== undefined && (isNaN(argv.p) || argv.p < 0)) {
throw new Error('Past days must be a non-negative number');
}
return true;
})
//.demandOption(['timeout', 'debug']) // Optional: require these arguments
.strict()
.help()
.version(version)
.argv
;
/* * * Processing * * */
const days_fore = max(argv.hasOwnProperty("days_fore") ? argv.days_fore : days_fore_default, days_fore_max);
const days_past = argv.hasOwnProperty("days_past") ? argv.days_past : days_past_default;
const calc_elevation = argv.calc_elevation ? true : false;
const days = days_fore + days_past;
console.log(`Averaging for ${days} days: ${days_fore} forecasted, ${days_past} past.`);
if (calc_elevation) console.log("Calculating elevation rather than using provided values.");
else console.log("Using user-provided elevations when they exist.");
/* * * Main * * */
async function getForecast(loc) {
const url = new URL("https://api.open-meteo.com/v1/forecast");
url.searchParams.set("latitude", loc.lat);
@@ -213,3 +239,5 @@ async function getForecast(loc) {
}
}
})();
/* * * Finish * * */
View File
Whitespace-only changes.
View File
Whitespace-only changes.
View File
Whitespace-only changes.