154 lines
3.9 KiB
JavaScript
154 lines
3.9 KiB
JavaScript
"use strict";
|
|
|
|
import show_help from '../help.mjs';
|
|
import { decode_payload } from '../ttn-app-server/DecodePayload.mjs';
|
|
import path from 'path';
|
|
|
|
import {
|
|
unnormalise_lat,
|
|
unnormalise_lng,
|
|
} from '../../common/Normalisers.mjs'
|
|
|
|
// HACK
|
|
import awilix from 'awilix';
|
|
|
|
export default async function(c) {
|
|
let { ansi: a, log: l, settings, DatasetFetcher } = c.cradle;
|
|
|
|
// 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(c.cradle);
|
|
process.exit();
|
|
break;
|
|
|
|
case "--version":
|
|
case "-v":
|
|
console.log(program.version);
|
|
break;
|
|
|
|
case "--ai-unified":
|
|
settings.ai.mode = "unified";
|
|
break;
|
|
case "--ai-split":
|
|
settings.ai.mode = "split";
|
|
break;
|
|
|
|
// Add more arguments here
|
|
}
|
|
}
|
|
|
|
// 3: Environment Variable Parsing
|
|
|
|
// process.env.XYZ
|
|
|
|
// 4: Run
|
|
if(extras.length < 1) {
|
|
console.error(`${a.fred}${a.hicol}Error: No subcommand specified.${a.reset}`);
|
|
show_help(c.cradle);
|
|
process.exit();
|
|
}
|
|
|
|
l.log_e(`${a.fgreen}${a.hicol}*** LoRaWAN Signal Mapper ***${a.reset}`);
|
|
|
|
switch(extras[0]) {
|
|
case "ttn-app-server":
|
|
l.log(`${a.fgreen}${a.hicol}Starting The Things Network application server${a.reset}`);
|
|
|
|
let app_server = c.resolve("TTNAppServer");
|
|
await app_server.run();
|
|
break;
|
|
|
|
case "decode-test":
|
|
l.log(`${a.fgreen}${a.hicol}Decoding message${a.reset}`);
|
|
if(process.argv.length < 4) {
|
|
l.error("Error: No message specified. Specify the message to decode in single quotes directly after 'decode-test'.");
|
|
process.exit(1);
|
|
}
|
|
l.log("Input: ", process.argv[3]);
|
|
l.log("Output: ", decode_payload(process.argv[3]));
|
|
break;
|
|
|
|
case "process-data":
|
|
l.log(`${a.fgreen}${a.hicol}Processing microSD card data${a.reset}`);
|
|
if(process.argv.length < 4) {
|
|
l.error("Error: No filename specified. Do so by specifying a filename after the 'process-data' subcommand.");
|
|
process.exit(1);
|
|
}
|
|
|
|
let filepath = process.argv[3];
|
|
|
|
let data_processor = c.cradle.DataProcessor;
|
|
await data_processor.process(filepath);
|
|
l.log("Processing complete!");
|
|
|
|
break;
|
|
|
|
case "train-ai":
|
|
// Do ninja dynamic import
|
|
// This avoid loading TensorFlow when it's not needed, as it causes
|
|
// a crash if the AVX2 CPU instruction set isn't available for some
|
|
// reason. Hrm.
|
|
let AITrainer = (await import(path.join(c.cradle.root_dir, "train-ai/AITrainer.mjs"))).default;
|
|
|
|
c.register({
|
|
AITrainer: awilix.asClass(AITrainer)
|
|
});
|
|
|
|
l.log(`${a.fgreen}${a.hicol}Training AIs in ${settings.ai.mode} mode${a.reset}`);
|
|
let ai_trainer = c.cradle.AITrainer;
|
|
switch(settings.ai.mode) {
|
|
case "split":
|
|
await ai_trainer.train_all();
|
|
break;
|
|
case "unified":
|
|
await ai_trainer.train_unified();
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case "geojson-debug":
|
|
let result = [];
|
|
for(let next_item of DatasetFetcher.fetch_all(null, true)) {
|
|
result.push({
|
|
type: "Feature",
|
|
geometry: {
|
|
type: "Point",
|
|
coordinates: [
|
|
unnormalise_lng(next_item.input.longitude),
|
|
unnormalise_lat(next_item.input.latitude)
|
|
]
|
|
},
|
|
properties: {
|
|
"marker-symbol": "circle",
|
|
"marker-color": next_item.output[0] <= 0 ? "#dd0707" : "#04a104",
|
|
gateway: next_item.ext.gateway,
|
|
rssi: next_item.ext.rssi_raw
|
|
}
|
|
})
|
|
}
|
|
console.log(JSON.stringify({
|
|
type: "FeatureCollection",
|
|
features: result
|
|
}, null, "\t"));
|
|
break;
|
|
|
|
default:
|
|
l.error(`Error: Subcommand '${extras[0]}' not recognised.`);
|
|
l.error(`Perhaps you mistyped it, or it hasn't been implemented yet?`);
|
|
l.error(`Try invoking this program with --help to see a list of supported subcommands.`);
|
|
process.exit(1);
|
|
break;
|
|
}
|
|
|
|
}
|