diff --git a/Helpers/Ansi.mjs b/Helpers/Ansi.mjs new file mode 100644 index 0000000..7fb8d79 --- /dev/null +++ b/Helpers/Ansi.mjs @@ -0,0 +1,78 @@ +"use strict"; + +/** + * Generates various VT100 ANSI escape sequences. + * Ported from C#. + * @licence MPL-2.0 + * @source https://gist.github.com/a4edd3204a03f4eedb79785751efb0f3#file-ansi-cs + * @author Starbeamrainbowlabs + * GitHub: @sbrl | Twitter: @SBRLabs | Reddit: u/Starbeamrainbowlabs + ***** Changelog ***** + * 27th March 2019: + * - Initial public release + */ +class Ansi { + constructor() { + /** + * Whether we should *actually* emit ANSI escape codes or not. + * Useful when we want to output to a log file, for example + * @type {Boolean} + */ + this.enabled = true; + + this.escape_codes(); + } + + escape_codes() { + // Solution on how to output ANSI escape codes in C# from here: + // https://www.jerriepelser.com/blog/using-ansi-color-codes-in-net-console-apps + this.reset = this.enabled ? "\u001b[0m" : ""; + this.hicol = this.enabled ? "\u001b[1m" : ""; + this.locol = this.enabled ? "\u001b[2m" : ""; + this.underline = this.enabled ? "\u001b[4m" : ""; + this.inverse = this.enabled ? "\u001b[7m" : ""; + this.fblack = this.enabled ? "\u001b[30m" : ""; + this.fred = this.enabled ? "\u001b[31m" : ""; + this.fgreen = this.enabled ? "\u001b[32m" : ""; + this.fyellow = this.enabled ? "\u001b[33m" : ""; + this.fblue = this.enabled ? "\u001b[34m" : ""; + this.fmagenta = this.enabled ? "\u001b[35m" : ""; + this.fcyan = this.enabled ? "\u001b[36m" : ""; + this.fwhite = this.enabled ? "\u001b[37m" : ""; + this.bblack = this.enabled ? "\u001b[40m" : ""; + this.bred = this.enabled ? "\u001b[41m" : ""; + this.bgreen = this.enabled ? "\u001b[42m" : ""; + this.byellow = this.enabled ? "\u001b[43m" : ""; + this.bblue = this.enabled ? "\u001b[44m" : ""; + this.bmagenta = this.enabled ? "\u001b[45m" : ""; + this.bcyan = this.enabled ? "\u001b[46m" : ""; + this.bwhite = this.enabled ? "\u001b[47m" : ""; + } + + // Thanks to http://ascii-table.com/ansi-escape-sequences.php for the following ANSI escape sequences + up(lines = 1) { + return this.enabled ? `\u001b[${lines}A` : ""; + } + down(lines = 1) { + return this.enabled ? `\u001b[${lines}B` : ""; + } + right(lines = 1) { + return this.enabled ? `\u001b[${lines}C` : ""; + } + left(lines = 1) { + return this.enabled ? `\u001b[${lines}D` : ""; + } + + jump_to(x, y) { + return this.enabled ? `\u001b[${y};${x}H` : ""; + } + + cursor_pos_save() { + return this.enabled ? `\u001b[s` : ""; + } + cursor_pos_restore() { + return this.enabled ? `\u001b[u` : ""; + } +} + +export default Ansi; diff --git a/help.mjs b/help.mjs new file mode 100644 index 0000000..7848b07 --- /dev/null +++ b/help.mjs @@ -0,0 +1,26 @@ +import path from 'path'; + +export default function(settings) { + let ansi = settings.ansi; + console.log(`${settings.program_name}, ${settings.version} +${ansi.locol}By Starbeamrainbowlabs${ansi.reset} + +${ansi.hicol}This program ${settings.description}.${ansi.reset} + +${ansi.fblue}${ansi.hicol}Usage:${ansi.reset} + node --experimental-modules ${path.relative(process.cwd(), process.argv[1])} {subcommand} {options} + +${ansi.fblue}${ansi.hicol}Subcommands:${ansi.reset} + ${ansi.fyellow}ttn-app-server${ansi.reset} Starts the thing network application server + ${ansi.fyellow}process-data${ansi.reset} Consolidates collected data from the IoT device and the TTN app server + ${ansi.fyellow}train-ai${ansi.reset} Trains the AI on the consolidated data + ${ansi.fyellow}serve-map${ansi.reset} Serves the final output map using the trained AI + +${ansi.fblue}${ansi.hicol}Options:${ansi.reset} + ${ansi.fyellow}-h --help ${ansi.reset}Show this message + ${ansi.fyellow}-v --version ${ansi.reset}Show the version of this program + +${ansi.fblue}${ansi.hicol}Environment Variables:${ansi.reset} + (none yet) +`); +}; diff --git a/index.mjs b/index.mjs new file mode 100755 index 0000000..c037683 --- /dev/null +++ b/index.mjs @@ -0,0 +1,68 @@ +#!/usr/bin/env node + +// Requires Ansi.mjs, which can be found here: https://gist.github.com/8c0bb5e172438b6e62dd48587cfeba84#file-ansi-mjs + +import Ansi from './Helpers/Ansi.mjs'; + +import show_help from './help.mjs'; +import TTNAppServer from './ttn-app-server/TTNAppServer.mjs'; + +// 1: Setup +const ansi = new Ansi(); + +const settings = { + program_name: "LoRaWAN Signal Mapper", + version: "v0.1", + description: "assists in mapping LoRaWAN signal coverage.", + ansi +}; + +// 2: CLI Argument Parsing +let args = process.argv.slice(2); // Slice out the node binary name and the filename +let extras = []; +for(let i = 0; i < args.length; i++) { + if(!args[i].startsWith("-")) { + extras.push(args[i]); + continue; + } + + switch(args[i]) { + case "--help": + case "-h": + show_help(settings); + process.exit(); + break; + + case "--version": + case "-v": + console.log(program.version); + break; + + // Add more arguments here + } +} + +// 3: Environment Variable Parsing + +// process.env.XYZ + +// 4: Run +if(extras.length < 1) { + console.error(`${ansi.fred}${ansi.hicol}Error: No subcommand specified.${ansi.reset}`); + show_help(settings); + process.exit(); +} +switch(extras[0]) { + case "ttn-app-server": + let app_server = new TTNAppServer(settings); + app_server.run(); + break; + + default: + console.error(`${ansi.fred}${ansi.hicol}Error: Subcommand '${extras[0]}' not recognised.${ansi.reset}`); + console.error( `${ansi.fred}Perhaps you mistyped it, or it hasn't been implemented yet?`); + process.exit(1); + break; +} + +// 5: Cleanup diff --git a/package.json b/package.json new file mode 100644 index 0000000..80a2cfc --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "lorawan-signal-mapping", + "version": "0.0.1", + "description": "A LoRaWAN signal mapping system. Comprised of several distinct parts.", + "main": "index.mjs", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://git.starbeamrainbowlabs.com/sbrl/Msc-Summer-Project/" + }, + "keywords": [ + "lora", + "ttn", + "arduino", + "mapping" + ], + "author": "Starbeamrainbowlabs", + "license": "MPL-2.0" +} diff --git a/ttn-app-server/TTNAppServer.mjs b/ttn-app-server/TTNAppServer.mjs new file mode 100644 index 0000000..300c84a --- /dev/null +++ b/ttn-app-server/TTNAppServer.mjs @@ -0,0 +1,14 @@ +"use strict"; + +class TTNAppServer { + constructor(in_settings) { + this.settings = in_settings; + this.ansi = this.settings.ansi; + } + + run() { + + } +} + +export default TTNAppServer;