diff --git a/icbm.ino b/icbm.ino
index d80617367274914c0c68d5fe0cc2acb3d963263c..0bda6e537e51002e359ebc5133bc8166e2fda09a 100644
--- a/icbm.ino
+++ b/icbm.ino
@@ -1,244 +1,16 @@
-#include <WiFiUdp.h>
-#include <SNMP.h>
 #include "esp32_ethernet.hpp"
 #include "rest.hpp"
+//#include "mpod.hpp"
 
-WiFiUDP udp;
-SNMP::Manager snmp;
-
-// Use some SNMP classes
-using SNMP::IntegerBER;
-using SNMP::OctetStringBER;
-using SNMP::OpaqueBER;
-using SNMP::OpaqueFloatBER;
-using SNMP::VarBind;
-using SNMP::VarBindList;
-
-// This class encapsulates the MPOD SNMP interface
-class MPOD {
-public:
-    // Simple helper class to handle OIDs
-    class OID {
-    public:
-        enum {
-            OUTPUTSTATUS,
-            OUTPUTMEASUREMENTSENSEVOLTAGE,
-            OUTPUTMEASUREMENTCURRENT,
-            OUTPUTSWITCH,
-            OUTPUTVOLTAGE,
-            OUTPUTCURRENT,
-            OUTPUTVOLTAGERISERATE,
-            UNKNOWN,
-            COUNT = UNKNOWN,
-        };
-
-        static inline const char *NAMES[] = {
-                "1.3.6.1.4.1.19947.1.3.2.1.4.1",
-                "1.3.6.1.4.1.19947.1.3.2.1.5.1",
-                "1.3.6.1.4.1.19947.1.3.2.1.7.1",
-                "1.3.6.1.4.1.19947.1.3.2.1.9.1",
-                "1.3.6.1.4.1.19947.1.3.2.1.10.1",
-                "1.3.6.1.4.1.19947.1.3.2.1.12.1",
-                "1.3.6.1.4.1.19947.1.3.2.1.13.1",
-        };
-
-        // Returns index of OID equals to name
-        // Returns UNKNOWN if none
-        static unsigned int match(const char *name) {
-            for (unsigned int index = 0; index < COUNT; ++index) {
-                if (strcmp(NAMES[index], name) == 0) {
-                    return index;
-                }
-            }
-            return UNKNOWN;
-        }
-    };
-
-    // Create an SNMP SETREQUEST message to setup MPOD
-    SNMP::Message* setup() {
-        // Use read/write community, not read-only
-        SNMP::Message* message = new SNMP::Message(SNMP::VERSION2C, "guru", SNMP::TYPE_SETREQUEST);
-        // In SETREQUEST, use node type and set the value.
-        // OUTPUT SWITCH, integer type, 0 is OFF and 1 is ON.
-        message->add(OID::NAMES[OID::OUTPUTSWITCH], new IntegerBER(0));
-        // OUTPUT VOLTAGE is an opaque float embedded in an opaque node
-        message->add(OID::NAMES[OID::OUTPUTVOLTAGE], new OpaqueBER(new OpaqueFloatBER(10.0)));
-        // OUTPUT CURRENT is an opaque float embedded in an opaque node
-        message->add(OID::NAMES[OID::OUTPUTCURRENT], new OpaqueBER(new OpaqueFloatBER(0.001)));
-        // OUTPUT VOLTAGE RISE RATE is negative. Don't ask me why...
-        message->add(OID::NAMES[OID::OUTPUTVOLTAGERISERATE], new OpaqueBER(new OpaqueFloatBER(-1.0)));
-        return message;
-    }
-
-    // Create an SNMP GETREQUEST message
-    SNMP::Message* read() {
-        SNMP::Message* message = new SNMP::Message(SNMP::VERSION2C, "public", SNMP::TYPE_GETREQUEST);
-        // In GETREQUEST, values are always of type NULL.
-        message->add(OID::NAMES[OID::OUTPUTSTATUS]);
-        message->add(OID::NAMES[OID::OUTPUTMEASUREMENTSENSEVOLTAGE]);
-        message->add(OID::NAMES[OID::OUTPUTMEASUREMENTCURRENT]);
-        return message;
-    }
-
-    // Create an SNMP SETREQUEST message to switch on or off the MPOD
-    SNMP::Message* output(const bool on) {
-        SNMP::Message* message = new SNMP::Message(SNMP::VERSION2C, "guru", SNMP::TYPE_SETREQUEST);
-        // In SETREQUEST, use node type and set the value.
-        // OUTPUT SWITCH, integer type, 0 is OFF and 1 is ON.
-        message->add(OID::NAMES[OID::OUTPUTSWITCH], new IntegerBER(on ? 1 : 0));
-        return message;
-    }
-
-    // Parse incoming message
-    bool message(const SNMP::Message *message) {
-        unsigned int found = 0;
-        unsigned int index = 0;
-        // Get the variable binding list from the message.
-        VarBindList *varbindlist = message->getVarBindList();
-        for (unsigned int index = 0; index < varbindlist->count(); ++index) {
-            // Each variable binding is a sequence of 2 objects:
-            // - First one is and ObjectIdentifierBER. It holds the OID
-            // - Second is the value of any type
-            VarBind *varbind = (*varbindlist)[index];
-            // There is a convenient function to get the OID as a const char*
-            const char *name = varbind->getName();
-            switch (OID::match(name)) {
-            case OID::OUTPUTSTATUS: {
-                // OUTPUTSTATUS is defined in MIB as BITS but encoded as OCTETSTRING by MPOD
-                OctetStringBER *status = static_cast<OctetStringBER*>(varbind->getValue());
-                _on = status->getBit(0);
-                _up = status->getBit(11);
-                _down = status->getBit(12);
-            }
-                found++;
-                break;
-            case OID::OUTPUTMEASUREMENTSENSEVOLTAGE:
-                // Use private helper function to extract float value
-                _measurementSenseVoltage = getFloatFromVarBind(varbind);
-                found++;
-                break;
-            case OID::OUTPUTMEASUREMENTCURRENT:
-                _measurementCurrent = getFloatFromVarBind(varbind);
-                found++;
-                break;
-            case OID::OUTPUTSWITCH:
-                // Use private helper function to extract integer value
-                _on = getIntegerFromVarBind(varbind);
-                found++;
-                break;
-            case OID::OUTPUTVOLTAGE:
-                _voltage = getFloatFromVarBind(varbind);
-                found++;
-                break;
-            case OID::OUTPUTCURRENT:
-                _current = getFloatFromVarBind(varbind);
-                found++;
-                break;
-            case OID::OUTPUTVOLTAGERISERATE:
-                _voltageRiseRate = getFloatFromVarBind(varbind);
-                found++;
-                break;
-            }
-        }
-        // Return true if nodes found, that means this is a valid response from MPOD
-        return found;
-    }
-
-    // Getters
-    bool isOn() const {
-        return _on;
-    }
-
-    bool isUp() const {
-        return _up;
-    }
-
-    bool isDown() const {
-        return _down;
-    }
-
-    float getMeasurementSenseVoltage() const {
-        return _measurementSenseVoltage;
-    }
-
-    float getMeasurementCurrent() const {
-        return _measurementCurrent;
-    }
-
-    float getVoltage() const {
-        return _voltage;
-    }
-
-    float getCurrent() const {
-        return _current;
-    }
-
-    float getVoltageRiseRate() const {
-        return _voltageRiseRate;
-    }
-
-private:
-    // Use appropriate cast to get integer value
-    unsigned int getIntegerFromVarBind(const VarBind *varbind) {
-        return static_cast<IntegerBER*>(varbind->getValue())->getValue();
-    }
-
-    // Use appropriate casts to get embedded opaque float value
-    float getFloatFromVarBind(const VarBind *varbind) {
-        return static_cast<OpaqueFloatBER*>(static_cast<OpaqueBER*>(varbind->getValue())->getBER())->getValue();
-    }
-
-    bool _on = false;
-    bool _up = false;
-    bool _down = false;
-    float _measurementSenseVoltage = 0;
-    float _measurementCurrent = 0;
-    float _voltage = 0;
-    float _current = 0;
-    float _voltageRiseRate = 0;
-};
-
-MPOD mpod;
-
-// Event handler to process SNMP messages
-void onMessage(const SNMP::Message *message, const IPAddress remote, const uint16_t port) {
-    // Check if message is from MPOD
-    if (mpod.message(message)) {
-        Serial.println();
-        Serial.print("MPOD status");
-        Serial.print(mpod.isOn() ? " on" : " off");
-        if (mpod.isUp()) {
-            Serial.print(" up");
-        }
-        if (mpod.isDown()) {
-            Serial.print(" down");
-        }
-        Serial.println();
-        Serial.print("HV voltage ");
-        Serial.print(mpod.getMeasurementSenseVoltage());
-        Serial.print(" V (");
-        Serial.print(mpod.getVoltage());
-        Serial.print(") current ");
-        Serial.print(mpod.getMeasurementCurrent());
-        Serial.print(" A (");
-        Serial.print(mpod.getCurrent());
-        Serial.print(") rise rate ");
-        Serial.print(mpod.getVoltageRiseRate());
-        Serial.println(" V/s");
-    }
-}
 
 unsigned long start;
 extern bool eth_connected;
+//extern SNMP::Manager snmp;
 
 void setup() {
     Serial.begin(115200);
 
     connectNetwork();
-    // SNMP
-    snmp.begin(&udp);
-    snmp.onMessage(onMessage);
-    // Start
     while (!eth_connected) {
         Serial.print("-");
         delay(100);
@@ -248,12 +20,9 @@ void setup() {
     Serial.println("Started REST server");
 
     start = millis();
-    // MPOD
-    SNMP::Message *message = mpod.setup();
-    snmp.send(message, IPAddress(10, 42, 0, 1), SNMP::PORT::SNMP);
-    delete message;
 }
 
+
 enum {
     NONE,
     ON,
@@ -272,29 +41,18 @@ void serial_loop() {
         } else if (string == "off") {
             output = OFF;
         }
-        Serial.print(string);
-        if (output != NONE) {
-            // If ON or OFF, send SETREQUEST to MPOD
-            SNMP::Message *message = mpod.output(output == ON);
-            Serial.print("Sending message  ");
-            snmp.send(message, IPAddress(10, 42, 0, 1), SNMP::PORT::SNMP);
-            Serial.println("Sent");
-            delete message;
-        }
+        Serial.print(output);
     }
 }
 
 void loop() {
     // Manager loop function must be called to process incoming messages
+    //snmp.loop();
     restServer.handleClient();
     serial_loop();
 
     if (millis() - start  >= 1000) {
         start = millis();
-        // Create message to query MPOD and send it
-        SNMP::Message* message = mpod.read();
-        snmp.send(message, IPAddress(10, 42, 0, 1), SNMP::PORT::SNMP);
-        delete message;
         Serial.print(".");
     }
 }
diff --git a/rest.cpp b/rest.cpp
index 8758637635120a3bb07f6fb24fa884cd186875cd..1cade9c880278c6f4ac0aa36aab1c442b7e3e984 100644
--- a/rest.cpp
+++ b/rest.cpp
@@ -1,9 +1,11 @@
 #include "rest.hpp"
+#include <ETH.h>
 
 WebServer restServer(80);
 
 void initializeRoutes() {
     restServer.on("/idn", identify);
+	restServer.on("/restart", restart);
     restServer.onNotFound(notFound);
 
     restServer.begin();
@@ -19,16 +21,20 @@ void identify() {
 
 	String message = "{\n";
 
+	message += "\"mac\":\"";
+	message += ETH.macAddress();
+	message += "\",\n";
+
 	message += "\"version\":\"";
 	message += "0.1";  // TODO: Get from Git
 	message += "\",\n";
 
 	message += "\"uptime\": \"";
-	message += String(hours);
+	message += hours;
 	message += ":";
-	message += String(minutes);
+	message += minutes;
 	message += ":";
-	message += String(seconds);
+	message += seconds;
 	message += "\"";
 
 	message += "\n}";
@@ -37,16 +43,26 @@ void identify() {
 }
 
 void notFound() {
-    String message = "File Not Found\n\n";
-    message += "URI: ";
+    String message = "{\n";
+    message += "\"uri\":\"";
     message += restServer.uri();
-    message += "\nMethod: ";
+    message += "\",\n\"method\":\"";
     message += (restServer.method() == HTTP_GET) ? "GET" : "POST";
-    message += "\nArguments: ";
-    message += restServer.args();
-    message += "\n";
+
+    message += "\",\n\"arguments\":{";
     for (uint8_t i = 0; i < restServer.args(); i++) {
-        message += " " + restServer.argName(i) + ": " + restServer.arg(i) + "\n";
+        message += "\n\"" + restServer.argName(i) + "\":\"" + restServer.arg(i) + "\",";
     }
-    restServer.send(404, "text/plain", message);
+	if (restServer.args() != 0) {
+		message.remove(message.length()-1);  // remove trailing comma for valid json
+	}
+
+	message += "\n}\n}";
+    restServer.send(404, "text/json", message);
+	Serial.println(message);
+}
+
+void restart() {
+	restServer.send(200);
+	ESP.restart();
 }
diff --git a/rest.hpp b/rest.hpp
index bb098d658c567b3d657001fba6786f2c15759874..d955917369a298df78e12cadcc9eefd278647fb9 100644
--- a/rest.hpp
+++ b/rest.hpp
@@ -6,3 +6,5 @@ extern WebServer restServer;
 void initializeRoutes();
 void identify();
 void notFound();
+void list();
+void restart();