structs, better error checking, number conversion

main
xad1 3 years ago
parent 9c40400d26
commit 427aab95ea

@ -0,0 +1,52 @@
{
"files.associations": {
"stdexcept": "cpp",
"array": "cpp",
"atomic": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"map": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"istream": "cpp",
"limits": "cpp",
"new": "cpp",
"ostream": "cpp",
"sstream": "cpp",
"streambuf": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp"
}
}

@ -4,6 +4,8 @@
extern String selectedNode;
extern int selectedItem;
extern int selectedLXC;
extern int selectedVM;
// TODO remove later
#endif

@ -2,8 +2,41 @@
#define JSON_RETRIEVE_H
#include <ArduinoJson.h>
JsonArray getNodeInfo();
JsonArray getContainerInfo(String node);
JsonArray getVMInfo(String node);
typedef struct {
String name;
int cpu;
int threads;
String onlineStatus;
long long mem;
long long maxmem;
long long disk;
long long maxdisk;
long long uptime;
} Node;
typedef struct {
String name;
int id;
String onlineStatus;
long long maxmem;
long long maxdisk;
long long uptime;
} Container;
typedef struct {
String name;
int id;
String onlineStatus;
long long maxmem;
long long maxdisk;
long long uptime;
long long netin;
long long netout;
} VM;
Node *getNodeInfo(int *numNodes);
Container *getContainerInfo(int *numContainers, String node);
VM *getVMInfo(int *numVMs, String node);
#endif /* JSON_RETRIEVE_H */

@ -1,8 +1,10 @@
#ifndef JSON_UTILS_H
#define JSON_UTILS_H
#include <ArduinoJson.h>
JsonObject getNode(String name, JsonArray nodes);
JsonObject getContainer(int id, JsonArray containers);
#include <json/retrieve.h>
//JsonObject getNode(String name, JsonArray nodes);
Node getNode(String name);
Container getContainer(int id, String node);
VM getVM(int id, String node);
#endif /* JSON_UTILS_H */

@ -2,14 +2,16 @@
#define MENU_H_
#include <ArduinoJson.h>
#include <Arduino.h>
#include <json/retrieve.h>
// Struct for static menu items such as on the main menu. Has the name of the menu item and a function to run when it is selected.
typedef struct {
String name;
void (*function)();
} MenuItem;
void listNodes(JsonArray nodes);
int listContainers(JsonArray containers);
void listNodes(Node* nodes, int numItems);
void listContainers(Container* containers, int numItems);
void listVMs(VM* vms, int numItems);
void mainMenu();
extern int selectedItem;

@ -2,14 +2,11 @@
#include <HTTPClient.h>
#include <server.h>
#include <utils.h>
#include <json/retrieve.h>
#include <stdexcept>
// todo make the bottom part of these into one function
// ######################################
// ######################################
// ######################################
// ######################################
// ######################################
JsonArray getNodeInfo() {
Node *getNodeInfo(int *numNodes)
{
HTTPClient http;
String apiAddress = PROXMOX_ADDRESS + "/api2/json/nodes/";
String auth = "PVEAPIToken=" + PROXMOX_TOKEN_USER + "!" + PROXMOX_TOKEN_NAME + "=" + PROXMOX_TOKEN_SECRET;
@ -19,19 +16,36 @@ JsonArray getNodeInfo() {
http.setAuthorization(authc);
int httpCode = http.GET();
if (httpCode > 0) {
if (httpCode > 0)
{
String json = http.getString();
DynamicJsonDocument doc(1024);
DynamicJsonDocument doc(6144);
deserializeJson(doc, json);
JsonArray nodes = doc["data"].as<JsonArray>();
return nodes;
}
Node *nodeArray = new Node[nodes.size()];
for (int i = 0; i < nodes.size(); i++)
{
nodeArray[i].name = nodes[i]["node"].as<String>();
nodeArray[i].cpu = nodes[i]["cpu"].as<int>();
nodeArray[i].threads = nodes[i]["maxcpu"].as<int>();
nodeArray[i].onlineStatus = nodes[i]["status"].as<String>();
nodeArray[i].mem = nodes[i]["mem"].as<long long>();
nodeArray[i].maxmem = nodes[i]["maxmem"].as<long long>();
nodeArray[i].disk = nodes[i]["disk"].as<long long>();
nodeArray[i].maxdisk = nodes[i]["maxdisk"].as<long long>();
nodeArray[i].uptime = nodes[i]["uptime"].as<long long>();
}
displayError("Error getting data.");
return getNodeInfo();
*numNodes = nodes.size();
return nodeArray;
}
throw std::runtime_error("Can't get node info: HTTP request failed with code: " + httpCode);
}
JsonArray getContainerInfo(String node) {
Container *getContainerInfo(int *numContainers, String node)
{
HTTPClient http;
String apiAddress = PROXMOX_ADDRESS + "/api2/json/nodes/" + node + "/lxc";
String auth = "PVEAPIToken=" + PROXMOX_TOKEN_USER + "!" + PROXMOX_TOKEN_NAME + "=" + PROXMOX_TOKEN_SECRET;
@ -41,19 +55,33 @@ JsonArray getContainerInfo(String node) {
http.setAuthorization(authc);
int httpCode = http.GET();
if (httpCode > 0) {
if (httpCode > 0)
{
String json = http.getString();
DynamicJsonDocument doc(1024);
deserializeJson(doc, json);
JsonArray nodes = doc["data"].as<JsonArray>();
return nodes;
JsonArray containers = doc["data"].as<JsonArray>();
Container *containerArray = new Container[containers.size()];
for (int i = 0; i < containers.size(); i++)
{
containerArray[i].name = containers[i]["name"].as<String>();
containerArray[i].id = containers[i]["vmid"].as<int>();
containerArray[i].onlineStatus = containers[i]["status"].as<String>();
containerArray[i].maxmem = containers[i]["maxmem"].as<long long>();
containerArray[i].maxdisk = containers[i]["maxdisk"].as<long long>();
containerArray[i].uptime = containers[i]["uptime"].as<long long>();
}
*numContainers = containers.size();
return containerArray;
}
displayError("Error getting data.");
return getNodeInfo();
throw std::runtime_error("Can't get container info: HTTP request failed with code: " + httpCode);
}
JsonArray getVMInfo(String node) {
VM *getVMInfo(int *numVMs, String node)
{
HTTPClient http;
String apiAddress = PROXMOX_ADDRESS + "/api2/json/nodes/" + node + "/qemu";
String auth = "PVEAPIToken=" + PROXMOX_TOKEN_USER + "!" + PROXMOX_TOKEN_NAME + "=" + PROXMOX_TOKEN_SECRET;
@ -63,14 +91,28 @@ JsonArray getVMInfo(String node) {
http.setAuthorization(authc);
int httpCode = http.GET();
if (httpCode > 0) {
if (httpCode > 0)
{
String json = http.getString();
DynamicJsonDocument doc(1024);
deserializeJson(doc, json);
JsonArray nodes = doc["data"].as<JsonArray>();
return nodes;
}
JsonArray vms = doc["data"].as<JsonArray>();
VM *vmArray = new VM[vms.size()];
displayError("Error getting data.");
return getNodeInfo();
}
for (int i = 0; i < vms.size(); i++)
{
vmArray[i].name = vms[i]["name"].as<String>();
vmArray[i].id = vms[i]["vmid"].as<int>();
vmArray[i].onlineStatus = vms[i]["status"].as<String>();
vmArray[i].maxmem = vms[i]["maxmem"].as<long long>();
vmArray[i].maxdisk = vms[i]["maxdisk"].as<long long>();
vmArray[i].uptime = vms[i]["uptime"].as<long long>();
vmArray[i].netin = vms[i]["netin"].as<long long>();
vmArray[i].netout = vms[i]["netout"].as<long long>();
}
*numVMs = vms.size();
return vmArray;
}
throw std::runtime_error("Can't get VM info: HTTP request failed with code: " + httpCode);
}

@ -1,27 +1,52 @@
#include <ArduinoJson.h>
#include <json/utils.h>
#include <utils.h>
#include <stdexcept>
/**
Get a specific node from an array of nodes
*/
JsonObject getNode(String name, JsonArray nodes) {
for (JsonObject node : nodes) {
if (node["node"] == name) {
return node;
Node getNode(String name)
{
int numNodes;
Node *nodes = getNodeInfo(&numNodes);
for (int i = 0; i < numNodes; i++)
{
if (nodes[i].name == name)
{
return nodes[i];
}
}
throw std::runtime_error("Can't find the requested node in the array");
}
Container getContainer(int id, String node)
{
int numContainers;
Container *containers = getContainerInfo(&numContainers, node);
for (int i = 0; i < numContainers; i++)
{
if (containers[i].id == id)
{
return containers[i];
}
}
displayError("Node not found!");
throw std::runtime_error("Can't find the requested container in the array");
}
JsonObject getContainer(int id, JsonArray containers) {
for (JsonObject container : containers) {
Serial.println(id);
Serial.println(container["vmid"].as<int>());
if (container["vmid"].as<int>() == id) {
return container;
VM getVM(int id, String node)
{
int numVMs;
VM *vms = getVMInfo(&numVMs, node);
for (int i = 0; i < numVMs; i++)
{
if (vms[i].id == id)
{
return vms[i];
}
}
displayError("Machine not found!");
throw std::runtime_error("Can't find the requested vm in the array");
}

@ -7,22 +7,34 @@
#include <menu.h>
#include <json/retrieve.h>
void setup() {
void setup()
{
Serial.begin(115200);
GO.begin();
connectWiFi();
}
void loop()
{
void loop() {
if (WiFi.status() != WL_CONNECTED) {
if (WiFi.status() != WL_CONNECTED)
{
displayError("WiFi Connection Lost");
connectWiFi();
}
listNodes(getNodeInfo());
selectedItem = 0;
mainMenu();
try
{
int numNodes;
Node *nodes = getNodeInfo(&numNodes);
listNodes(nodes, numNodes);
selectedItem = 0;
mainMenu();
}
catch (const std::exception &e)
{
Serial.println(e.what());
displayError(e.what());
}
}

@ -2,11 +2,19 @@
#include <Arduino.h>
#include <odroid_go.h>
#include <ArduinoJson.h>
#include <global.h>
#include <statistics.h>
#include <global.h>
const int MAIN_TEXT_COLOR = WHITE;
const int MAIN_TEXT_SIZE = 2;
int selectedItem = 0;
String selectedNode = "";
int selectedLXC = 0;
int selectedVM = 0;
@ -24,10 +32,12 @@ int buttonListener(int numItems) {
GO.update();
if (GO.JOY_Y.isAxisPressed() == 1 && selectedItem < (numItems - 1)) {
selectedItem++;
Serial.println(selectedItem);
break;
}
if (GO.JOY_Y.isAxisPressed() == 2 && selectedItem > 0) {
selectedItem--;
Serial.println(selectedItem);
break;
}
if (GO.BtnA.isPressed() == 1) {
@ -46,6 +56,8 @@ int buttonListener(int numItems) {
void drawMenu(MenuItem menuItems[], int numItems) {
GO.lcd.clearDisplay();
GO.lcd.setCursor(0, 0);
GO.lcd.setTextColor(MAIN_TEXT_COLOR);
GO.lcd.setTextSize(MAIN_TEXT_SIZE);
for (int i = 0; i < numItems; i++) {
@ -65,6 +77,7 @@ void drawMenu(MenuItem menuItems[], int numItems) {
break;
default:
drawMenu(menuItems, numItems);
break;
}
}
@ -74,56 +87,84 @@ void mainMenu(){
drawMenu(mainMenuItems, numItems);
}
void listNodes(JsonArray nodes) {
void listNodes(Node* nodes, int numItems) {
GO.lcd.clearDisplay();
GO.lcd.setTextColor(MAIN_TEXT_COLOR);
GO.lcd.setTextSize(MAIN_TEXT_SIZE);
GO.lcd.setCursor(0, 0);
int numItems = nodes.size();
for (int i = 0; i < numItems; i++) {
if (selectedItem == i) {
GO.lcd.print("> ");
}
GO.lcd.println(nodes[i]["node"].as<String>());
GO.lcd.println(nodes[i].name);
}
switch (buttonListener(numItems)) {
case 1:
Serial.println("selected " + selectedItem);
selectedNode = nodes[selectedItem]["node"].as<String>();
selectedNode = nodes[selectedItem].name;
break;
case 2:
Serial.println("back");
break;
default:
listNodes(nodes);
listNodes(nodes, numItems);
break;
}
}
int listContainers(JsonArray containers) {
void listContainers(Container* containers, int numItems) {
GO.lcd.clearDisplay();
GO.lcd.setCursor(0, 0);
int numItems = containers.size();
int selectedLXC = 0;
GO.lcd.setTextColor(MAIN_TEXT_COLOR);
GO.lcd.setTextSize(MAIN_TEXT_SIZE);
for (int i = 0; i < numItems; i++) {
if (selectedItem == i) {
GO.lcd.print("> ");
}
GO.lcd.println(containers[i]["vmid"].as<String>() + ": " + containers[i]["name"].as<String>());
GO.lcd.println(String(containers[i].id) + ": " + containers[i].name);
}
switch (buttonListener(numItems)) {
case 1:
selectedLXC = containers[selectedItem]["vmid"].as<int>();
Serial.println(selectedLXC);
selectedLXC = containers[selectedItem].id;
break;
case 2:
Serial.println("back");
break;
default:
listContainers(containers);
listContainers(containers, numItems);
break;
}
}
void listVMs(VM* vms, int numItems) {
GO.lcd.clearDisplay();
GO.lcd.setCursor(0, 0);
GO.lcd.setTextColor(MAIN_TEXT_COLOR);
GO.lcd.setTextSize(MAIN_TEXT_SIZE);
for (int i = 0; i < numItems; i++) {
if (selectedItem == i) {
GO.lcd.print("> ");
}
GO.lcd.println(String(vms[i].id) + ": " + vms[i].name);
}
switch (buttonListener(numItems)) {
case 1:
selectedVM = vms[selectedItem].id;
break;
case 2:
Serial.println("back");
break;
default:
listVMs(vms, numItems);
break;
}
Serial.println(selectedLXC);
Serial.println("end");
return selectedLXC;
}

@ -3,139 +3,131 @@
#include <global.h>
#include <menu.h>
#include <odroid_go.h>
#include <utils.h>
String convertBytes(long long value) {
if (value > 1099511627776) {
return String(value / 1099511627776) + " TB";
}
if (value > 1073741824) {
return String(value / 1073741824) + " GB";
}
if (value > 1048576) {
return String(value / 1048576) + " MB";
}
if (value > 1024) {
return String(value / 1024) + " KB";
}
return String(value) + " Bytes";
}
void printNodeStats(JsonObject node) {
String name = node["node"].as<String>();
int cpu = round(node["cpu"].as<float>() * 100);
int threads = node["maxcpu"].as<int>();
String onlineStatus = node["status"].as<String>();
String mem = node["mem"].as<String>();
String maxmem = node["maxmem"].as<String>();
String disk = node["disk"].as<String>();
String maxdisk = node["maxdisk"].as<String>();
String uptime = node["uptime"].as<String>();
// these are strings for now because they could be way too big
String convertTime(long long value) {
if (value > 3600) {
return String(value / 3600) + " hrs";
}
if (value > 60) {
return String(value / 60) + " mins";
}
return String(value) + " secs";
}
void printNodeStats(Node node)
{
GO.lcd.fillScreen(WHITE);
GO.lcd.setCursor(0, 0);
GO.lcd.setTextColor(BLACK);
GO.lcd.setTextSize(3);
GO.lcd.println(name);
GO.lcd.println(node.name);
GO.lcd.setTextSize(2);
GO.lcd.println("--------------------------");
GO.lcd.println("Status: " + onlineStatus);
GO.lcd.println("Uptime: " + uptime + "s");
GO.lcd.println("CPU: " + String(cpu) + "%");
GO.lcd.println("Threads: " + String(threads));
GO.lcd.println("RAM: " + mem);
GO.lcd.println("Max RAM: " + maxmem);
GO.lcd.println("Disk: " + disk);
GO.lcd.println("Max Disk: " + maxdisk);
GO.lcd.println("Status: " + node.onlineStatus);
GO.lcd.println("Uptime: " + convertTime(node.uptime));
GO.lcd.println("CPU: " + String(node.cpu) + "%");
GO.lcd.println("Threads: " + String(node.threads));
GO.lcd.println("RAM: " + convertBytes(node.mem));
GO.lcd.println("Max RAM: " + convertBytes(node.maxmem));
GO.lcd.println("Disk: " + convertBytes(node.disk));
GO.lcd.println("Max Disk: " + convertBytes(node.maxdisk));
}
void printContainerStats(JsonObject container) {
String name = container["name"].as<String>();
String id = container["vmid"].as<String>();
String onlineStatus = container["status"].as<String>();
String maxmem = container["maxmem"].as<String>();
String maxdisk = container["maxdisk"].as<String>();
String uptime = container["uptime"].as<String>();
// these are strings for now because they could be way too big
void printContainerStats(Container container)
{
GO.lcd.fillScreen(WHITE);
GO.lcd.setCursor(0, 0);
GO.lcd.setTextColor(BLACK);
GO.lcd.setTextSize(3);
GO.lcd.println(id + ": " + name);
GO.lcd.println(String(container.id) + ": " + container.name);
GO.lcd.setTextSize(2);
GO.lcd.println("--------------------------");
GO.lcd.println("Status: " + onlineStatus);
GO.lcd.println("Uptime: " + uptime + "s");
GO.lcd.println("Max RAM: " + maxmem);
GO.lcd.println("Max Disk: " + maxdisk);
GO.lcd.println("Status: " + container.onlineStatus);
GO.lcd.println("Uptime: " + convertTime(container.uptime));
GO.lcd.println("Max RAM: " + convertBytes(container.maxmem));
GO.lcd.println("Max Disk: " + convertBytes(container.maxdisk));
}
void printVMStats(JsonObject vm) {
String name = vm["name"].as<String>();
String id = vm["vmid"].as<String>();
int cpu = round(vm["cpu"].as<float>() * 100);
int cores = vm["cpus"].as<int>();
String onlineStatus = vm["status"].as<String>();
String mem = vm["mem"].as<String>();
String maxmem = vm["maxmem"].as<String>();
String maxdisk = vm["maxdisk"].as<String>();
String uptime = vm["uptime"].as<String>();
String netin = vm["netin"].as<String>();
String netout = vm["netout"].as<String>();
// these are strings for now because they could be way too big
void printVMStats(VM vm)
{
GO.lcd.fillScreen(WHITE);
GO.lcd.setCursor(0, 0);
GO.lcd.setTextColor(BLACK);
GO.lcd.setTextSize(3);
GO.lcd.println(id + ": " + name);
GO.lcd.println(String(vm.id) + ": " + vm.name);
GO.lcd.setTextSize(2);
GO.lcd.println("--------------------------");
GO.lcd.println("Status: " + onlineStatus);
GO.lcd.println("Uptime: " + uptime + "s");
GO.lcd.println("CPU: " + String(cpu) + "%");
GO.lcd.println("Cores: " + String(cores));
GO.lcd.println("RAM: " + mem);
GO.lcd.println("Max RAM: " + maxmem);
GO.lcd.println("Max Disk: " + maxdisk);
GO.lcd.println("Net In: " + netin);
GO.lcd.println("Net Out: " + netout);
GO.lcd.println("Status: " + vm.onlineStatus);
GO.lcd.println("Uptime: " + convertTime(vm.uptime));
GO.lcd.println("Max RAM: " + convertBytes(vm.maxmem));
GO.lcd.println("Max Disk: " + convertBytes(vm.maxdisk));
}
void nodeInfo() {
void nodeInfo()
{
Serial.println("nodeinfo");
while (true) {
printNodeStats(getNode(selectedNode, getNodeInfo()));
while (true)
{
printNodeStats(getNode(selectedNode));
delay(2000);
}
}
void containerInfo() {
void containerInfo()
{
Serial.println("container info");
JsonArray containerArray = getContainerInfo(selectedNode);
selectedItem = 0;
int selectedLXC = listContainers(containerArray);
JsonObject container = getContainer(selectedLXC, containerArray);
printContainerStats(container);
delay(1000);
// only redraw screen if changed
while (true) {
if (getContainer(selectedLXC, containerArray) != container) {
containerInfo();
}
int numContainers;
Container *containers = getContainerInfo(&numContainers, selectedNode);
listContainers(containers, numContainers);
while (true)
{
printContainerStats(getContainer(selectedLXC, selectedNode));
delay(5000);
}
}
void vmInfo() {
void vmInfo()
{
Serial.println("vm info");
JsonArray vmArray = getVMInfo(selectedNode);
selectedItem = 0;
int selectedVM = listContainers(vmArray);
Serial.println("vm");
Serial.println(selectedVM);
Serial.println(selectedVM);
Serial.println(selectedVM);
Serial.println(selectedVM);
while (true) {
printVMStats(getContainer(selectedVM, vmArray));
delay(2000);
int numVMs;
VM *vms = getVMInfo(&numVMs, selectedNode);
if (vms != NULL)
{
listVMs(vms, numVMs);
while (true)
{
printVMStats(getVM(selectedVM, selectedNode));
delay(5000);
}
}
}
}

Loading…
Cancel
Save