diff --git a/Code/Arduino/AmsToMqttBridge/AmsToMqttBridge.ino b/Code/Arduino/AmsToMqttBridge/AmsToMqttBridge.ino index ce276d1d..b20d2b75 100644 --- a/Code/Arduino/AmsToMqttBridge/AmsToMqttBridge.ino +++ b/Code/Arduino/AmsToMqttBridge/AmsToMqttBridge.ino @@ -5,20 +5,40 @@ */ +#include +#include +#include +#include #include "configuration.h" #include "accesspoint.h" #include +#include +#include + +#define WIFI_CONNECTION_TIMEOUT 30000; +#define TEMP_SENSOR_PIN 5 // Temperature sensor connected to GPIO5 + +OneWire oneWire(TEMP_SENSOR_PIN); +DallasTemperature tempSensor(&oneWire); +long lastTempDebug = 0; accesspoint ap; +WiFiClient *client; +PubSubClient mqtt; +HardwareSerial* debugger; +// The HAN Port reader +HanReader hanReader; // the setup function runs once when you press reset or power the board void setup() { + debugger = &Serial; + // Setup serial port for debugging - Serial.begin(115200); - while (!Serial); - Serial.println("Started..."); + debugger->begin(2400, SERIAL_8E1); + while (!&debugger); + debugger->println("Started..."); // Assign pin for boot as AP delay(1000); @@ -33,13 +53,376 @@ void setup() // Turn off the blue LED digitalWrite(2, HIGH); + + if (!ap.isActivated) + { + setupWiFi(); + hanReader.setup(&Serial, 2400, SERIAL_8E1, debugger); + hanReader.compensateFor09HeaderBug = (ap.config.meterType == 1); // To compensate for the known Kaifa bug + } +} + +void setupWiFi() +{ + if (ap.config.isSecure()) + client = new WiFiClientSecure(); + else + client = new WiFiClient(); + + mqtt = PubSubClient(*client); + + WiFi.enableAP(false); + WiFi.begin(ap.config.ssid, ap.config.ssidPassword); + mqtt.setServer(ap.config.mqtt, ap.config.mqttPort); + + //std::function vCallback = MakeDelegate(this, xnsClientClass::mqttMessageReceived); + mqtt.setCallback(mqttMessageReceived); + MQTT_connect(); + + sendMqttData("Connected!"); +} + +void mqttMessageReceived(char* topic, unsigned char* payload, unsigned int length) +{ + // make it a null-terminated string + char message[1000]; + for (int i = 0; i < length; i++) + message[i] = payload[i]; + message[length] = 0; + + debugger->println("Incoming MQTT message:"); + debugger->print("["); + debugger->print(topic); + debugger->print("] "); + debugger->println(message); } // the loop function runs over and over again until power down or reset void loop() { + // Only do normal stupp if we're not booted as AP if (!ap.loop()) { - // Only do normal stupp if we're not booted as AP + mqtt.loop(); + delay(10); // <- fixes some issues with WiFi stability + + if (!mqtt.connected()) { + MQTT_connect(); + } + else + { + debugTemperature(); + readHanPort(); + } } } +void debugTemperature() +{ + if (lastTempDebug + 5000 < millis()) + { + lastTempDebug = millis(); + tempSensor.requestTemperatures(); + float temperature = tempSensor.getTempCByIndex(0); + debugger->print("Temperature is "); + debugger->print(temperature); + debugger->println(" degrees"); + } +} +void readHanPort() +{ + switch (ap.config.meterType) + { + case 1: // Kaifa + readHanPort_Kaifa(); + break; + case 2: // Kamstrup + readHanPort_Kamstrup(); + break; + case 3: // Aidon + readHanPort_Aidon(); + break; + default: + debugger->print("Meter type "); + debugger->print(ap.config.meterType, HEX); + debugger->println(" is unknown"); + delay(10000); + break; + } +} + +void readHanPort_Aidon() +{ + debugger->println("Meter type Aidon is not yet implemented"); + delay(10000); +} + +void readHanPort_Kamstrup() +{ + if (hanReader.read()) + { + // Get the list identifier + int listSize = hanReader.getListSize(); + + // Only care for the ACtive Power Imported, which is found in the first list + if (listSize == (int)Kamstrup::List1 || listSize == (int)Kamstrup::List2) + { + if (listSize == (int)Kamstrup::List1) + { + String id = hanReader.getString((int)Kamstrup_List1::ListVersionIdentifier); + if (debugger) debugger->println(id); + } + else if (listSize == (int)Kamstrup::List2) + { + String id = hanReader.getString((int)Kamstrup_List2::ListVersionIdentifier); + if (debugger) debugger->println(id); + } + + // Get the timestamp (as unix time) from the package + time_t time = hanReader.getPackageTime(); + if (debugger) debugger->print("Time of the package is: "); + if (debugger) debugger->println(time); + + // Define a json object to keep the data + StaticJsonBuffer<500> jsonBuffer; + JsonObject& root = jsonBuffer.createObject(); + + // Any generic useful info here + root["id"] = WiFi.macAddress(); + root["up"] = millis(); + root["t"] = time; + + // Add a sub-structure to the json object, + // to keep the data from the meter itself + JsonObject& data = root.createNestedObject("data"); + + // Get the temperature too + tempSensor.requestTemperatures(); + float temperature = tempSensor.getTempCByIndex(0); + data["temp"] = temperature; + + // Based on the list number, get all details + // according to OBIS specifications for the meter + if (listSize == (int)Kamstrup::List1) + { + data["lv"] = hanReader.getString((int)Kamstrup_List1::ListVersionIdentifier); + data["id"] = hanReader.getString((int)Kamstrup_List1::MeterID); + data["type"] = hanReader.getString((int)Kamstrup_List1::MeterType); + data["P"] = hanReader.getInt((int)Kamstrup_List1::ActiveImportPower); + data["Q"] = hanReader.getInt((int)Kamstrup_List1::ReactiveImportPower); + data["I1"] = hanReader.getInt((int)Kamstrup_List1::CurrentL1); + data["I2"] = hanReader.getInt((int)Kamstrup_List1::CurrentL2); + data["I3"] = hanReader.getInt((int)Kamstrup_List1::CurrentL3); + data["U1"] = hanReader.getInt((int)Kamstrup_List1::VoltageL1); + data["U2"] = hanReader.getInt((int)Kamstrup_List1::VoltageL2); + data["U3"] = hanReader.getInt((int)Kamstrup_List1::VoltageL3); + } + else if (listSize == (int)Kamstrup::List2) + { + data["lv"] = hanReader.getString((int)Kamstrup_List2::ListVersionIdentifier);; + data["id"] = hanReader.getString((int)Kamstrup_List2::MeterID); + data["type"] = hanReader.getString((int)Kamstrup_List2::MeterType); + data["P"] = hanReader.getInt((int)Kamstrup_List2::ActiveImportPower); + data["Q"] = hanReader.getInt((int)Kamstrup_List2::ReactiveImportPower); + data["I1"] = hanReader.getInt((int)Kamstrup_List2::CurrentL1); + data["I2"] = hanReader.getInt((int)Kamstrup_List2::CurrentL2); + data["I3"] = hanReader.getInt((int)Kamstrup_List2::CurrentL3); + data["U1"] = hanReader.getInt((int)Kamstrup_List2::VoltageL1); + data["U2"] = hanReader.getInt((int)Kamstrup_List2::VoltageL2); + data["U3"] = hanReader.getInt((int)Kamstrup_List2::VoltageL3); + data["tPI"] = hanReader.getInt((int)Kamstrup_List2::CumulativeActiveImportEnergy); + data["tPO"] = hanReader.getInt((int)Kamstrup_List2::CumulativeActiveExportEnergy); + data["tQI"] = hanReader.getInt((int)Kamstrup_List2::CumulativeReactiveImportEnergy); + data["tQO"] = hanReader.getInt((int)Kamstrup_List2::CumulativeReactiveExportEnergy); + } + + // Write the json to the debug port + root.printTo(Serial1); + Serial1.println(); + + // Publish the json to the MQTT server + char msg[1024]; + root.printTo(msg, 1024); + mqtt.publish(ap.config.mqttPublishTopic, msg); + } + } +} + + +void readHanPort_Kaifa() { + if (hanReader.read()) + { + // Get the list identifier + int listSize = hanReader.getListSize(); + + // Only care for the ACtive Power Imported, which is found in the first list + if (listSize == (int)Kaifa::List1 || listSize == (int)Kaifa::List2 || listSize == (int)Kaifa::List3) + { + if (listSize == (int)Kaifa::List1) + { + if (debugger) debugger->println(" (list #1 has no ID)"); + } + else + { + String id = hanReader.getString((int)Kaifa_List2::ListVersionIdentifier); + if (debugger) debugger->println(id); + } + + // Get the timestamp (as unix time) from the package + time_t time = hanReader.getPackageTime(); + if (debugger) debugger->print("Time of the package is: "); + if (debugger) debugger->println(time); + + // Define a json object to keep the data + StaticJsonBuffer<500> jsonBuffer; + JsonObject& root = jsonBuffer.createObject(); + + // Any generic useful info here + root["id"] = WiFi.macAddress(); + root["up"] = millis(); + root["t"] = time; + + // Add a sub-structure to the json object, + // to keep the data from the meter itself + JsonObject& data = root.createNestedObject("data"); + + // Get the temperature too + tempSensor.requestTemperatures(); + float temperature = tempSensor.getTempCByIndex(0); + data["temp"] = temperature; + + // Based on the list number, get all details + // according to OBIS specifications for the meter + if (listSize == (int)Kaifa::List1) + { + data["P"] = hanReader.getInt((int)Kaifa_List1::ActivePowerImported); + } + else if (listSize == (int)Kaifa::List2) + { + data["lv"] = hanReader.getString((int)Kaifa_List2::ListVersionIdentifier); + data["id"] = hanReader.getString((int)Kaifa_List2::MeterID); + data["type"] = hanReader.getString((int)Kaifa_List2::MeterType); + data["P"] = hanReader.getInt((int)Kaifa_List2::ActiveImportPower); + data["Q"] = hanReader.getInt((int)Kaifa_List2::ReactiveImportPower); + data["I1"] = hanReader.getInt((int)Kaifa_List2::CurrentL1); + data["I2"] = hanReader.getInt((int)Kaifa_List2::CurrentL2); + data["I3"] = hanReader.getInt((int)Kaifa_List2::CurrentL3); + data["U1"] = hanReader.getInt((int)Kaifa_List2::VoltageL1); + data["U2"] = hanReader.getInt((int)Kaifa_List2::VoltageL2); + data["U3"] = hanReader.getInt((int)Kaifa_List2::VoltageL3); + } + else if (listSize == (int)Kaifa::List3) + { + data["lv"] = hanReader.getString((int)Kaifa_List3::ListVersionIdentifier);; + data["id"] = hanReader.getString((int)Kaifa_List3::MeterID); + data["type"] = hanReader.getString((int)Kaifa_List3::MeterType); + data["P"] = hanReader.getInt((int)Kaifa_List3::ActiveImportPower); + data["Q"] = hanReader.getInt((int)Kaifa_List3::ReactiveImportPower); + data["I1"] = hanReader.getInt((int)Kaifa_List3::CurrentL1); + data["I2"] = hanReader.getInt((int)Kaifa_List3::CurrentL2); + data["I3"] = hanReader.getInt((int)Kaifa_List3::CurrentL3); + data["U1"] = hanReader.getInt((int)Kaifa_List3::VoltageL1); + data["U2"] = hanReader.getInt((int)Kaifa_List3::VoltageL2); + data["U3"] = hanReader.getInt((int)Kaifa_List3::VoltageL3); + data["tPI"] = hanReader.getInt((int)Kaifa_List3::CumulativeActiveImportEnergy); + data["tPO"] = hanReader.getInt((int)Kaifa_List3::CumulativeActiveExportEnergy); + data["tQI"] = hanReader.getInt((int)Kaifa_List3::CumulativeReactiveImportEnergy); + data["tQO"] = hanReader.getInt((int)Kaifa_List3::CumulativeReactiveExportEnergy); + } + + // Write the json to the debug port + root.printTo(Serial1); + Serial1.println(); + + // Publish the json to the MQTT server + char msg[1024]; + root.printTo(msg, 1024); + mqtt.publish("sensors/out/espdebugger", msg); + } + } +} + + + + +// Function to connect and reconnect as necessary to the MQTT server. +// Should be called in the loop function and it will take care if connecting. +void MQTT_connect() { + // Connect to WiFi access point. + if (debugger) debugger->println(); if (debugger) debugger->println(); + if (debugger) debugger->print("Connecting to WiFi network "); + if (debugger) debugger->println(ap.config.ssid); + + long vTimeout = millis() + WIFI_CONNECTION_TIMEOUT; + while (WiFi.status() != WL_CONNECTED) { + delay(50); + if (debugger) debugger->print("."); + if (vTimeout < millis()) + { + if (debugger) + { + debugger->print("Timout during connect. WiFi status is: "); + debugger->println(WiFi.status()); + } + WiFi.disconnect(); + WiFi.begin(ap.config.ssid, ap.config.ssidPassword); + vTimeout = millis() + WIFI_CONNECTION_TIMEOUT; + } + yield(); + } + + if (debugger) { + debugger->println(); + debugger->println("WiFi connected"); + debugger->println("IP address: "); + debugger->println(WiFi.localIP()); + debugger->print("\nconnecting to MQTT: "); + debugger->print(ap.config.mqtt); + debugger->print(", port: "); + debugger->print(ap.config.mqttPort); + debugger->println(); + } + while (!mqtt.connected()) { + if ((ap.config.mqttUser == 0 && mqtt.connect(ap.config.mqttClientID)) || + (ap.config.mqttUser != 0 && mqtt.connect(ap.config.mqttClientID, ap.config.mqttUser, ap.config.mqttPass))) + { + if (debugger) debugger->println("\nSuccessfully connected to MQTT!"); + if (ap.config.mqttSubscribeTopic != 0 && strlen(ap.config.mqttSubscribeTopic) > 0) + { + mqtt.subscribe(ap.config.mqttSubscribeTopic); + if (debugger) debugger->printf(" Subscribing to [%s]\r\n", ap.config.mqttSubscribeTopic); + } + } + else + { + if (debugger) debugger->print("."); + if (debugger) debugger->print("failed, mqtt.state() = "); + if (debugger) debugger->print(mqtt.state()); + if (debugger) debugger->println(" trying again in 5 seconds"); + // Wait 2 seconds before retrying + mqtt.disconnect(); + delay(2000); + } + yield(); + } +} + +void sendMqttData(String data) +{ + if (ap.config.mqttPublishTopic == 0 || strlen(ap.config.mqttPublishTopic) == 0) + return; + + if (!client->connected() || !mqtt.connected()) { + MQTT_connect(); + } + + StaticJsonBuffer<500> jsonBuffer; + JsonObject& json = jsonBuffer.createObject(); + json["id"] = WiFi.macAddress(); + json["up"] = millis() / 1000; + json["data"] = data; + + String msg; + json.printTo(msg); + + mqtt.publish(ap.config.mqttPublishTopic, msg.c_str()); +} \ No newline at end of file diff --git a/Code/Arduino/AmsToMqttBridge/accesspoint.cpp b/Code/Arduino/AmsToMqttBridge/accesspoint.cpp index 81f1dd89..a1488402 100644 --- a/Code/Arduino/AmsToMqttBridge/accesspoint.cpp +++ b/Code/Arduino/AmsToMqttBridge/accesspoint.cpp @@ -5,6 +5,11 @@ #include "accesspoint.h" ESP8266WebServer accesspoint::server(80); +Stream* accesspoint::debugger; + +bool accesspoint::hasConfig() { + return config.hasConfig(); +} void accesspoint::setup(int accessPointButtonPin, Stream& debugger) { @@ -13,22 +18,27 @@ void accesspoint::setup(int accessPointButtonPin, Stream& debugger) // Test if we're missing configuration if (!config.hasConfig()) { - this->print("No config. We're booting as AP. Look for SSID "); - this->println(this->AP_SSID); + print("No config. We're booting as AP. Look for SSID "); + println(this->AP_SSID); isActivated = true; } else { + // Load the configuration + config.load(); + if (this->debugger) config.print(debugger); + // Test if we're holding down the AP pin, over 5 seconds int time = millis() + 5000; - this->print("Press the AP button now to boot as access point"); + print("Press the AP button now to boot as access point"); while (millis() < time) { - this->print("."); + print("."); if (digitalRead(accessPointButtonPin) == LOW) { - this->println(""); - this->println("AP button was pressed. Booting as access point now"); + println(""); + print("AP button was pressed. Booting as access point now. Look for SSID "); + println(this->AP_SSID); isActivated = true; break; } @@ -38,6 +48,7 @@ void accesspoint::setup(int accessPointButtonPin, Stream& debugger) if (isActivated) { + // Setup AP WiFi.disconnect(true); WiFi.softAPdisconnect(true); WiFi.mode(WIFI_OFF); @@ -51,34 +62,89 @@ void accesspoint::setup(int accessPointButtonPin, Stream& debugger) dnsServer.start(DNS_PORT, "*", WiFi.softAPIP()); server.on("/", handleRoot); + server.on("/save", handleSave); server.begin(); // Web server start - this->print("Web server is ready for config at http://"); - this->print(WiFi.softAPIP()); - this->println("/"); + print("Web server is ready for config at http://"); + print(WiFi.softAPIP()); + println("/"); } } /** Handle root or redirect to captive portal */ void accesspoint::handleRoot() { - Serial.println("Serving / over http..."); + println("Serving / over http..."); server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); server.sendHeader("Pragma", "no-cache"); server.sendHeader("Expires", "-1"); server.setContentLength(CONTENT_LENGTH_UNKNOWN); server.send(200, "text/html", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves. - server.sendContent( - "" - "

HELLO WORLD!!

" - ); - server.sendContent( - "

You may want to config the wifi connection.

" - "" - ); + String html = String("\r\n\r\n\r\n\t\r\n\r\n\r\n\r\n\t
\r\n\t\t
\r\n\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t

WiFi

\r\n\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t
\r\n\t\t\t
\r\n\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t

AMS Meter

\r\n\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t
\r\n\t\t\t
\r\n\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t

MQTT

\r\n\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t
\r\n\t\t\t
\r\n\t\t
\r\n\t
\r\n\r\n\t\r\n\r\n"); + server.sendContent(html); server.client().stop(); // Stop is needed because we sent no content length } + +void accesspoint::handleSave() { + configuration *config = new configuration(); + + String temp; + + temp = server.arg("ssid"); + config->ssid = new char[temp.length() + 1]; + temp.toCharArray(config->ssid, temp.length() + 1, 0); + + temp = server.arg("ssidPassword"); + config->ssidPassword = new char[temp.length() + 1]; + temp.toCharArray(config->ssidPassword, temp.length() + 1, 0); + + config->meterType = (byte)server.arg("meterType").toInt(); + + temp = server.arg("mqtt"); + config->mqtt = new char[temp.length() + 1]; + temp.toCharArray(config->mqtt, temp.length() + 1, 0); + + config->mqttPort = (int)server.arg("mqttPort").toInt(); + + temp = server.arg("mqttClientID"); + config->mqttClientID = new char[temp.length() + 1]; + temp.toCharArray(config->mqttClientID, temp.length() + 1, 0); + + temp = server.arg("mqttPublishTopic"); + config->mqttPublishTopic = new char[temp.length() + 1]; + temp.toCharArray(config->mqttPublishTopic, temp.length() + 1, 0); + + temp = server.arg("mqttSubscribeTopic"); + config->mqttSubscribeTopic = new char[temp.length() + 1]; + temp.toCharArray(config->mqttSubscribeTopic, temp.length() + 1, 0); + + temp = server.arg("mqttUser"); + config->mqttUser = new char[temp.length() + 1]; + temp.toCharArray(config->mqttUser, temp.length() + 1, 0); + + temp = server.arg("mqttPass"); + config->mqttPass = new char[temp.length() + 1]; + temp.toCharArray(config->mqttPass, temp.length() + 1, 0); + + println("Saving configuration now..."); + + if (accesspoint::debugger) config->print(*accesspoint::debugger); + if (config->save()) + { + println("Successfully saved. Will roboot now."); + String html = "

Successfully Saved!

Device is restarting now...

"; + server.send(200, "text/html", html); + ESP.reset(); + } + else + { + println("Error saving configuration"); + String html = "

Error saving configuration!

"; + server.send(500, "text/html", html); + } +} + bool accesspoint::loop() { if (isActivated) { @@ -97,17 +163,17 @@ bool accesspoint::loop() { size_t accesspoint::print(const char* text) { - if (this->debugger) this->debugger->print(text); + if (debugger) debugger->print(text); } size_t accesspoint::println(const char* text) { - if (this->debugger) this->debugger->println(text); + if (debugger) debugger->println(text); } size_t accesspoint::print(const Printable& data) { - if (this->debugger) this->debugger->print(data); + if (debugger) debugger->print(data); } size_t accesspoint::println(const Printable& data) { - if (this->debugger) this->debugger->println(data); + if (debugger) debugger->println(data); } diff --git a/Code/Arduino/AmsToMqttBridge/accesspoint.h b/Code/Arduino/AmsToMqttBridge/accesspoint.h index 0a4c18f5..527a90d6 100644 --- a/Code/Arduino/AmsToMqttBridge/accesspoint.h +++ b/Code/Arduino/AmsToMqttBridge/accesspoint.h @@ -18,26 +18,28 @@ class accesspoint { public: void setup(int accessPointButtonPin, Stream& debugger); bool loop(); + bool hasConfig(); + configuration config; + bool isActivated = false; private: const char* AP_SSID = "AMS2MQTT"; - configuration config; - bool isActivated = false; - Stream* debugger = NULL; - // DNS server const byte DNS_PORT = 53; DNSServer dnsServer; - size_t print(const char* text); - size_t println(const char* text); - size_t print(const Printable& data); - size_t println(const Printable& data); + static size_t print(const char* text); + static size_t println(const char* text); + static size_t print(const Printable& data); + static size_t println(const Printable& data); // Web server static void handleRoot(); + static void handleSave(); static ESP8266WebServer server; + + static Stream* debugger; }; #endif diff --git a/Code/Arduino/AmsToMqttBridge/configuration.cpp b/Code/Arduino/AmsToMqttBridge/configuration.cpp index 9ea14acd..6f0013ef 100644 --- a/Code/Arduino/AmsToMqttBridge/configuration.cpp +++ b/Code/Arduino/AmsToMqttBridge/configuration.cpp @@ -6,11 +6,11 @@ bool configuration::hasConfig() { - bool has = false; + bool hasConfig = false; EEPROM.begin(EEPROM_SIZE); - has = EEPROM.read(EEPROM_CONFIG_ADDRESS) == EEPROM_CHECK_SUM; + hasConfig = EEPROM.read(EEPROM_CONFIG_ADDRESS) == EEPROM_CHECK_SUM; EEPROM.end(); - return has; + return hasConfig; } bool configuration::save() @@ -23,6 +23,7 @@ bool configuration::save() address += saveString(address, ssid); address += saveString(address, ssidPassword); + address += saveByte(address, meterType); address += saveString(address, mqtt); address += saveInt(address, mqttPort); address += saveString(address, mqttClientID); @@ -37,10 +38,10 @@ bool configuration::save() else address += saveBool(address, false); - bool vRet = EEPROM.commit(); + bool success = EEPROM.commit(); EEPROM.end(); - return vRet; + return success; } @@ -56,6 +57,7 @@ bool configuration::load() address += readString(address, &ssid); address += readString(address, &ssidPassword); + address += readByte(address, &meterType); address += readString(address, &mqtt); address += readInt(address, &mqttPort); address += readString(address, &mqttClientID); @@ -82,6 +84,7 @@ bool configuration::load() { ssid = (char*)String("").c_str(); ssidPassword = (char*)String("").c_str(); + meterType = (byte)0; mqtt = (char*)String("").c_str(); mqttClientID = (char*)String("").c_str(); mqttPublishTopic = (char*)String("").c_str(); @@ -99,45 +102,55 @@ bool configuration::isSecure() return (mqttUser != 0) && (String(mqttUser).length() > 0); } -int configuration::readInt(int pAddress, int *pValue) +int configuration::readInt(int address, int *value) { - int lower = EEPROM.read(pAddress); - int higher = EEPROM.read(pAddress + 1); - *pValue = lower + (higher << 8); + int lower = EEPROM.read(address); + int higher = EEPROM.read(address + 1); + *value = lower + (higher << 8); return 2; } -int configuration::saveInt(int pAddress, int pValue) +int configuration::saveInt(int address, int value) { - byte lowByte = pValue & 0xFF; - byte highByte = ((pValue >> 8) & 0xFF); + byte lowByte = value & 0xFF; + byte highByte = ((value >> 8) & 0xFF); - EEPROM.write(pAddress, lowByte); - EEPROM.write(pAddress + 1, highByte); + EEPROM.write(address, lowByte); + EEPROM.write(address + 1, highByte); return 2; } -int configuration::readBool(int pAddress, bool *pValue) +int configuration::readBool(int address, bool *value) { - byte y = EEPROM.read(pAddress); - *pValue = (bool)y; - //Serial.printf("Read bool as %#x [%s]\r\n", y, (*pValue ? "true" : "false")); + byte y = EEPROM.read(address); + *value = (bool)y; return 1; } -int configuration::saveBool(int pAddress, bool pValue) +int configuration::saveBool(int address, bool value) { - byte y = (byte)pValue; - //Serial.printf("Writing bool as %#x [%s]\r\n", y, (pValue ? "true" : "false")); - EEPROM.write(pAddress, y); + byte y = (byte)value; + EEPROM.write(address, y); + return 1; +} + +int configuration::readByte(int address, byte *value) +{ + *value = EEPROM.read(address); + return 1; +} + +int configuration::saveByte(int address, byte value) +{ + EEPROM.write(address, value); return 1; } void configuration::print(Stream& serial) { - /* char* ssid; char* ssidPassword; + byte meterType; char* mqtt; int mqttPort; char* mqttClientID; @@ -152,6 +165,7 @@ void configuration::print(Stream& serial) serial.println("-----------------------------------------------"); serial.printf("ssid: %s\r\n", this->ssid); serial.printf("ssidPassword: %s\r\n", this->ssidPassword); + serial.printf("meterType: %i\r\n", this->meterType); serial.printf("mqtt: %s\r\n", this->mqtt); serial.printf("mqttPort: %i\r\n", this->mqttPort); serial.printf("mqttClientID: %s\r\n", this->mqttClientID); @@ -167,8 +181,6 @@ void configuration::print(Stream& serial) serial.println("-----------------------------------------------"); } - - template int configuration::writeAnything(int ee, const T& value) { const byte* p = (const byte*)(const void*)&value; @@ -190,38 +202,25 @@ template int configuration::readAnything(int ee, T& value) int configuration::readString(int pAddress, char* pString[]) { int address = 0; - - byte vLength = EEPROM.read(pAddress + address); + byte length = EEPROM.read(pAddress + address); address++; - //Serial.print("Found length of string: "); - //Serial.println(vLength); - - char* buffer = new char[vLength]; - for (int i = 0; i int writeAnything(int ee, const T& value); diff --git a/Code/Arduino/HanReader/src/HanReader.cpp b/Code/Arduino/HanReader/src/HanReader.cpp index 298f984f..de3be461 100644 --- a/Code/Arduino/HanReader/src/HanReader.cpp +++ b/Code/Arduino/HanReader/src/HanReader.cpp @@ -81,6 +81,8 @@ void HanReader::debugPrint(byte *buffer, int start, int length) debug->println(""); else if ((i - start + 1) % 4 == 0) debug->print(" "); + + yield(); // Let other get some resources too } debug->println(""); }