diff --git a/Code/ESPDebugger/ESPDebugger.ino b/Code/ESPDebugger/ESPDebugger.ino index aa44bff2..a96d648e 100644 --- a/Code/ESPDebugger/ESPDebugger.ino +++ b/Code/ESPDebugger/ESPDebugger.ino @@ -11,6 +11,17 @@ * * Created 14. september 2017 by Roar Fredriksen */ +#include +#include +#include + +// WiFi and MQTT endpoints +const char* ssid = "Roar_Etne"; +const char* password = "**********"; +const char* mqtt_server = "192.168.10.203"; + +WiFiClient espClient; +PubSubClient client(espClient); #include "DlmsReader.h" #include "Crc16.h" @@ -30,6 +41,24 @@ void setup() { Serial1.println("Serial1"); Serial1.println("Serial debugging port initialized"); + // Initialize wifi + Serial1.print("Connecting to "); + Serial1.println(ssid); + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial1.print("."); + } + + Serial1.println(""); + Serial1.println("WiFi connected"); + Serial1.println("IP address: "); + Serial1.println(WiFi.localIP()); + + client.setServer(mqtt_server, 1883); + // Initialize H/W serial port for MBus communication Serial.begin(2400, SERIAL_8E1); while (!Serial) {} @@ -39,11 +68,16 @@ void setup() { } void loop() { + if (!client.connected()) { + reconnect(); + } + client.loop(); + if (Serial.available()) { byte newByte = Serial.read(); //if (newByte < 0x10) Serial1.print("0"); - Serial1.print(newByte, HEX); + //Serial1.print(newByte, HEX); if (reader.Read(newByte)) { @@ -53,33 +87,88 @@ void loop() { Serial1.println(""); Serial1.print("List #"); Serial1.print(list, HEX); - - time_t time = kaifa.GetPackageTime(buffer, 0, bytesRead); - Serial1.print(" (time is "); - Serial1.print(time); - Serial1.print(")"); + Serial1.print(": "); - if (list == 0x01) + time_t time = kaifa.GetPackageTime(buffer, 0, bytesRead); + + StaticJsonBuffer<500> jsonBuffer; + JsonObject& root = jsonBuffer.createObject(); + root["id"] = "espdebugger"; + root["up"] = millis(); + root["t"] = time; + + JsonObject& data = root.createNestedObject("data"); + + if (list == (byte)List::List1) { - int consumption = kaifa.GetInt(0, buffer, 0, bytesRead); - Serial1.print(" consumption is "); - Serial1.print(consumption); - Serial1.println(" Watts"); + data["P"] = kaifa.GetInt((int)List1_ObisObjects::ActivePowerImported, buffer, 0, bytesRead); } - writeAndEmptyBuffer(); + else if (list == (byte)List::List2) + { + data["lv"] = kaifa.GetString((int)List2_ObisObjects::ObisListVersionIdentifier, buffer, 0, bytesRead); + data["id"] = kaifa.GetString((int)List2_ObisObjects::MeterID, buffer, 0, bytesRead); + data["type"] = kaifa.GetString((int)List2_ObisObjects::MeterType, buffer, 0, bytesRead); + data["P"] = kaifa.GetInt((int)List2_ObisObjects::ActivePowerImported, buffer, 0, bytesRead); + data["Q"] = kaifa.GetInt((int)List2_ObisObjects::ReactivePowerImported, buffer, 0, bytesRead); + data["I1"] = kaifa.GetInt((int)List2_ObisObjects::CurrentPhaseL1, buffer, 0, bytesRead); + data["I2"] = kaifa.GetInt((int)List2_ObisObjects::CurrentPhaseL2, buffer, 0, bytesRead); + data["I3"] = kaifa.GetInt((int)List2_ObisObjects::CurrentPhaseL3, buffer, 0, bytesRead); + data["U1"] = kaifa.GetInt((int)List2_ObisObjects::VoltagePhaseL1, buffer, 0, bytesRead); + data["U2"] = kaifa.GetInt((int)List2_ObisObjects::VoltagePhaseL1, buffer, 0, bytesRead); + data["U3"] = kaifa.GetInt((int)List2_ObisObjects::VoltagePhaseL1, buffer, 0, bytesRead); + } + else if (list == (byte)List::List3) + { + data["lv"] = kaifa.GetString((int)List3_ObisObjects::ObisListVersionIdentifier, buffer, 0, bytesRead); + data["id"] = kaifa.GetString((int)List3_ObisObjects::MeterID, buffer, 0, bytesRead); + data["type"] = kaifa.GetString((int)List3_ObisObjects::MeterType, buffer, 0, bytesRead); + data["P"] = kaifa.GetInt((int)List3_ObisObjects::ActivePowerImported, buffer, 0, bytesRead); + data["Q"] = kaifa.GetInt((int)List3_ObisObjects::ReactivePowerImported, buffer, 0, bytesRead); + data["I1"] = kaifa.GetInt((int)List3_ObisObjects::CurrentPhaseL1, buffer, 0, bytesRead); + data["I2"] = kaifa.GetInt((int)List3_ObisObjects::CurrentPhaseL2, buffer, 0, bytesRead); + data["I3"] = kaifa.GetInt((int)List3_ObisObjects::CurrentPhaseL3, buffer, 0, bytesRead); + data["U1"] = kaifa.GetInt((int)List3_ObisObjects::VoltagePhaseL1, buffer, 0, bytesRead); + data["U2"] = kaifa.GetInt((int)List3_ObisObjects::VoltagePhaseL1, buffer, 0, bytesRead); + data["U3"] = kaifa.GetInt((int)List3_ObisObjects::VoltagePhaseL1, buffer, 0, bytesRead); + data["tPI"] = kaifa.GetInt((int)List3_ObisObjects::TotalActiveEnergyImported, buffer, 0, bytesRead); + data["tPO"] = kaifa.GetInt((int)List3_ObisObjects::TotalActiveEnergyExported, buffer, 0, bytesRead); + data["tQI"] = kaifa.GetInt((int)List3_ObisObjects::TotalReactiveEnergyImported, buffer, 0, bytesRead); + data["tQO"] = kaifa.GetInt((int)List3_ObisObjects::TotalReactiveEnergyExported, buffer, 0, bytesRead); + } + else + { + Serial1.println("Invalid list"); + return; + } + + root.printTo(Serial1); + Serial1.println(); + + char msg[1024]; + root.printTo(msg, 1024); + client.publish("sensors/out/espdebugger", msg); } } } -void writeAndEmptyBuffer() -{ - for (int i = 0; i < bytesRead; i++) - { - if (buffer[i] < 0x10) Serial1.print("0"); - Serial1.print(buffer[i], HEX); - Serial1.print(" "); +void reconnect() { + // Loop until we're reconnected + while (!client.connected()) { + Serial1.print("Attempting MQTT connection..."); + // Attempt to connect + if (client.connect("ESP8266Client")) { + Serial1.println("connected"); + // Once connected, publish an announcement... + // client.publish("sensors", "hello world"); + // ... and resubscribe + // client.subscribe("inTopic"); + } else { + Serial1.print("failed, rc="); + Serial1.print(client.state()); + Serial1.println(" try again in 5 seconds"); + // Wait 5 seconds before retrying + delay(5000); + } } - Serial1.println(); - bytesRead = 0; } diff --git a/Code/ESPDebugger/KaifaHan.cpp b/Code/ESPDebugger/KaifaHan.cpp index 476634fe..9eb5727e 100644 --- a/Code/ESPDebugger/KaifaHan.cpp +++ b/Code/ESPDebugger/KaifaHan.cpp @@ -6,11 +6,11 @@ byte KaifaHan::GetListID(byte *buffer, int start, int length) if (length > 23) { byte list = buffer[start + 23]; - if (list == List1) return List1; - if (list == List2) return List2; - if (list == List3) return List3; + if (list == (byte)List::List1) return (byte)List::List1; + if (list == (byte)List::List2) return (byte)List::List2; + if (list == (byte)List::List3) return (byte)List::List3; } - return ListUnknown; + return (byte)List::ListUnknown; } long KaifaHan::GetPackageTime(byte *buffer, int start, int length) @@ -30,27 +30,51 @@ long KaifaHan::GetPackageTime(byte *buffer, int start, int length) int KaifaHan::GetInt(int dataPosition, byte *buffer, int start, int length) { - const int dataStart = 24; - int value = 0; - int foundPosition = 0; - for (int i = start + dataStart; i < start + length; i++) + int valuePosition = findValuePosition(dataPosition, buffer, start, length); + if (valuePosition > 0) { - if (foundPosition == 0) - { - if (buffer[i] == 0x06) - foundPosition = i; - } - else - { - value = value << 8 | - buffer[i]; - if (i == foundPosition + 4) - return value; - } + int value = 0; + for (int i = valuePosition + 1; i < valuePosition + 5; i++) + { + value = value << 8 | buffer[i]; + } + return value; } return 0; } +int KaifaHan::findValuePosition(int dataPosition, byte *buffer, int start, int length) +{ + const int dataStart = 24; + for (int i=start + dataStart; i 0) + { + String value = String(""); + for (int i = valuePosition + 2; i < valuePosition + buffer[valuePosition + 1]; i++) + { + value += String((char)buffer[i]); + } + return value; + } + return String(""); +} + time_t KaifaHan::toUnixTime(int year, int month, int day, int hour, int minute, int second) { byte daysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; diff --git a/Code/ESPDebugger/KaifaHan.h b/Code/ESPDebugger/KaifaHan.h index 89d50e20..02720959 100644 --- a/Code/ESPDebugger/KaifaHan.h +++ b/Code/ESPDebugger/KaifaHan.h @@ -10,19 +10,64 @@ class KaifaHan { public: - const byte ListUnknown = 0x00; - const byte List1 = 0x01; - const byte List2 = 0x0D; - const byte List3 = 0x12; byte GetListID(byte *buffer, int start, int length); long GetPackageTime(byte *buffer, int start, int length); int GetInt(int dataPosition, byte *buffer, int start, int length); + String GetString(int dataPosition, byte *buffer, int start, int length); protected: - private: + int findValuePosition(int dataPosition, byte *buffer, int start, int length); time_t toUnixTime(int year, int month, int day, int hour, int minute, int second); }; +enum class List : byte { + ListUnknown = 0x00, + List1 = 0x01, + List2 = 0x0D, + List3 = 0x12 +}; + + +enum class List1_ObisObjects { + ActivePowerImported +}; + +enum class List2_ObisObjects { + ObisListVersionIdentifier, + MeterID, + MeterType, + ActivePowerImported, + ActivePowerExported, + ReactivePowerImported, + ReactivePowerExported, + CurrentPhaseL1, + CurrentPhaseL2, + CurrentPhaseL3, + VoltagePhaseL1, + VoltagePhaseL2, + VoltagePhaseL3 +}; + +enum class List3_ObisObjects { + ObisListVersionIdentifier, + MeterID, + MeterType, + ActivePowerImported, + ActivePowerExported, + ReactivePowerImported, + ReactivePowerExported, + CurrentPhaseL1, + CurrentPhaseL2, + CurrentPhaseL3, + VoltagePhaseL1, + VoltagePhaseL2, + VoltagePhaseL3, + ClockAndDate, + TotalActiveEnergyImported, + TotalActiveEnergyExported, + TotalReactiveEnergyImported, + TotalReactiveEnergyExported +}; #endif