diff --git a/Code/ESPDebugger/ESPDebugger.ino b/Code/ESPDebugger/ESPDebugger.ino index 45608511..5e025372 100644 --- a/Code/ESPDebugger/ESPDebugger.ino +++ b/Code/ESPDebugger/ESPDebugger.ino @@ -11,9 +11,14 @@ * * Created 14. september 2017 by Roar Fredriksen */ + #include #include #include +#include "HanReader.h" + +// The HAN Port reader +HanReader hanReader; // WiFi and MQTT endpoints const char* ssid = "Roar_Etne"; @@ -23,151 +28,164 @@ const char* mqtt_server = "192.168.10.203"; WiFiClient espClient; PubSubClient client(espClient); -#include "DlmsReader.h" -#include "KaifaHan.h" - -DlmsReader reader; -byte buffer[512]; -int bytesRead; -KaifaHan kaifa; - void setup() { - // Initialize the Serial1 port for debugging - // (This port is fixed to Pin2 of the ESP8266) - Serial1.begin(115200); - while (!Serial1) {} - Serial1.setDebugOutput(true); - 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); + setupDebugPort(); + setupWiFi(); + setupMqtt(); - while (WiFi.status() != WL_CONNECTED) { - delay(500); - Serial1.print("."); - } - - Serial1.println(""); - Serial1.println("WiFi connected"); - Serial1.println("IP address: "); - Serial1.println(WiFi.localIP()); + // initialize the HanReader + // (passing Serial as the HAN port and Serial1 for debugging) + hanReader.setup(&Serial, &Serial1); +} - client.setServer(mqtt_server, 1883); - - // Initialize H/W serial port for MBus communication - Serial.begin(2400, SERIAL_8E1); - while (!Serial) {} - Serial1.println("MBUS serial setup complete"); +void setupMqtt() +{ + client.setServer(mqtt_server, 1883); +} - bytesRead = 0; +void setupDebugPort() +{ + // Initialize the Serial1 port for debugging + // (This port is fixed to Pin2 of the ESP8266) + Serial1.begin(115200); + while (!Serial1) {} + Serial1.setDebugOutput(true); + Serial1.println("Serial1"); + Serial1.println("Serial debugging port initialized"); +} + +void setupWiFi() +{ + // 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()); } 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); + loopMqtt(); - if (reader.Read(newByte)) - { - bytesRead = reader.GetRawData(buffer, 0, 512); + // Read one byt from the port, and see if we got a full package + if (hanReader.read()) + { + // Get the list identifier + List list = hanReader.getList(); + Serial1.println(""); + Serial1.print("List #"); + Serial1.print((byte)list, HEX); + Serial1.print(": "); - byte list = kaifa.GetListID(buffer, 0, bytesRead); - Serial1.println(""); - Serial1.print("List #"); - Serial1.print(list, HEX); - Serial1.print(": "); - - time_t time = kaifa.GetPackageTime(buffer, 0, bytesRead); + // Make sure we got a valid list + if (list == List::ListUnknown) + { + Serial1.println("Invalid list"); + return; + } - 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) - { - data["P"] = kaifa.GetInt((int)List1_ObisObjects::ActivePowerImported, buffer, 0, bytesRead); - } - 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; - } + // Get the timestamp (as unix time) from the package + time_t time = hanReader.getPackageTime(); - root.printTo(Serial1); - Serial1.println(); + // Define a json object to keep the data + StaticJsonBuffer<500> jsonBuffer; + JsonObject& root = jsonBuffer.createObject(); + + // Any generic useful info here + root["id"] = "espdebugger"; + root["up"] = millis(); + root["t"] = time; - char msg[1024]; - root.printTo(msg, 1024); - client.publish("sensors/out/espdebugger", msg); - } - } + // Add a sub-structure to the json object, + // to keep the data from the meter itself + JsonObject& data = root.createNestedObject("data"); + + // Based on the list number, get all details + // according to OBIS specifications for the meter + if (list == List::List1) + { + data["P"] = hanReader.getInt(List1_ObisObjects::ActivePowerImported); + } + else if (list == List::List2) + { + data["lv"] = hanReader.getString(List2_ObisObjects::ObisListVersionIdentifier); + data["id"] = hanReader.getString(List2_ObisObjects::MeterID); + data["type"] = hanReader.getString(List2_ObisObjects::MeterType); + data["P"] = hanReader.getInt(List2_ObisObjects::ActivePowerImported); + data["Q"] = hanReader.getInt(List2_ObisObjects::ReactivePowerImported); + data["I1"] = hanReader.getInt(List2_ObisObjects::CurrentPhaseL1); + data["I2"] = hanReader.getInt(List2_ObisObjects::CurrentPhaseL2); + data["I3"] = hanReader.getInt(List2_ObisObjects::CurrentPhaseL3); + data["U1"] = hanReader.getInt(List2_ObisObjects::VoltagePhaseL1); + data["U2"] = hanReader.getInt(List2_ObisObjects::VoltagePhaseL1); + data["U3"] = hanReader.getInt(List2_ObisObjects::VoltagePhaseL1); + } + else if (list == List::List3) + { + data["lv"] = hanReader.getString(List3_ObisObjects::ObisListVersionIdentifier);; + data["id"] = hanReader.getString(List3_ObisObjects::MeterID); + data["type"] = hanReader.getString(List3_ObisObjects::MeterType); + data["P"] = hanReader.getInt(List3_ObisObjects::ActivePowerImported); + data["Q"] = hanReader.getInt(List3_ObisObjects::ReactivePowerImported); + data["I1"] = hanReader.getInt(List3_ObisObjects::CurrentPhaseL1); + data["I2"] = hanReader.getInt(List3_ObisObjects::CurrentPhaseL2); + data["I3"] = hanReader.getInt(List3_ObisObjects::CurrentPhaseL3); + data["U1"] = hanReader.getInt(List3_ObisObjects::VoltagePhaseL1); + data["U2"] = hanReader.getInt(List3_ObisObjects::VoltagePhaseL1); + data["U3"] = hanReader.getInt(List3_ObisObjects::VoltagePhaseL1); + data["tPI"] = hanReader.getInt(List3_ObisObjects::TotalActiveEnergyImported); + data["tPO"] = hanReader.getInt(List3_ObisObjects::TotalActiveEnergyExported); + data["tQI"] = hanReader.getInt(List3_ObisObjects::TotalReactiveEnergyImported); + data["tQO"] = hanReader.getInt(List3_ObisObjects::TotalReactiveEnergyExported); + } + + // 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); + client.publish("sensors/out/espdebugger", msg); + } } - -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); - } - } +// Ensure the MQTT lirary gets some attention too +void loopMqtt() +{ + if (!client.connected()) { + reconnectMqtt(); + } + client.loop(); +} + +void reconnectMqtt() { + // 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); + } + } } diff --git a/Code/ESPDebugger/ESPDebugger.vcxproj b/Code/ESPDebugger/ESPDebugger.vcxproj new file mode 100644 index 00000000..6cf04934 --- /dev/null +++ b/Code/ESPDebugger/ESPDebugger.vcxproj @@ -0,0 +1,91 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {B9C3E8F6-86B2-4D70-89ED-D6A7B8C7AC8D} + + + ESPDebugger + + + + Application + true + + + MultiByte + + + Application + false + + + true + MultiByte + + + + + + + + + + + + + + + Level3 + Disabled + true + $(ProjectDir)..\..\..\..\..\..\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\Extensions\pabjyzh5.4hi\Micro Platforms\visualmicro\ide\libraries;$(ProjectDir)..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries;$(ProjectDir)..\libraries;$(ProjectDir)..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266;$(ProjectDir)..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\libb64;$(ProjectDir)..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\spiffs;$(ProjectDir)..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc;$(ProjectDir)..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\variants\generic;$(ProjectDir)..\ESPDebugger;$(ProjectDir)..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\tools\sdk\include;$(ProjectDir)..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\tools\sdk\lwip\include;$(ProjectDir)..\..\..\..\AppData\Local\Temp\VMBuilds\test\esp8266_generic\Debug\core;$(ProjectDir)..\..\..\..\AppData\Local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2;$(ProjectDir)..\..\..\..\AppData\Local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2\xtensa-lx106-elf;$(ProjectDir)..\..\..\..\AppData\Local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include;$(ProjectDir)..\..\..\..\AppData\Local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\lib\gcc\xtensa-lx106-elf\4.8.2\include;$(ProjectDir)..\..\..\..\AppData\Local\arduino15\packages\esp8266\hardware\esp8266\2.3.0\tools\sdk\include;%(AdditionalIncludeDirectories) + $(ProjectDir)__vm\.ESPDebugger.vsarduino.h;%(ForcedIncludeFiles) + false + __ESP8266_ESp8266__;__ESP8266_ESP8266__;__ets__;ICACHE_FLASH;F_CPU=80000000L;LWIP_OPEN_SRC;ARDUINO=10801;ARDUINO_ESP8266_ESP01;ARDUINO_ARCH_ESP8266;ESP8266;__cplusplus=201103L;%(PreprocessorDefinitions) + + + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + + + + CppCode + + + + + + + VisualMicroDebugger + + + + + \ No newline at end of file diff --git a/Code/ESPDebugger/ESPDebugger.vcxproj.filters b/Code/ESPDebugger/ESPDebugger.vcxproj.filters new file mode 100644 index 00000000..acb82fcd --- /dev/null +++ b/Code/ESPDebugger/ESPDebugger.vcxproj.filters @@ -0,0 +1,25 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + \ No newline at end of file diff --git a/Code/ESPDebugger/HanReader.cpp b/Code/ESPDebugger/HanReader.cpp new file mode 100644 index 00000000..6b793d1c --- /dev/null +++ b/Code/ESPDebugger/HanReader.cpp @@ -0,0 +1,63 @@ +#include "HanReader.h" + +HanReader::HanReader() +{ + +} + +void HanReader::setup(HardwareSerial *hanPort) +{ + // Initialize H/W serial port for MBus communication + hanPort->begin(2400, SERIAL_8E1); + while (!hanPort) {} + bytesRead = 0; +} + +void HanReader::setup(HardwareSerial *hanPort, Stream *debugPort) +{ + setup(hanPort); + debug = debugPort; + if (debug) debug->println("MBUS serial setup complete"); +} + +bool HanReader::read() +{ + if (han->available()) + { + byte newByte = han->read(); + if (reader.Read(newByte)) + { + bytesRead = reader.GetRawData(buffer, 0, 512); + list = (List)kaifa.GetListID(buffer, 0, bytesRead); + return true; + } + } + + return false; +} + +List HanReader::getList() +{ + return list; +} + +time_t HanReader::getPackageTime() +{ + return kaifa.GetPackageTime(buffer, 0, bytesRead); +} + +int HanReader::getInt(List1_ObisObjects objectId) { return getInt((int)objectId); } +int HanReader::getInt(List2_ObisObjects objectId) { return getInt((int)objectId); } +int HanReader::getInt(List3_ObisObjects objectId) { return getInt((int)objectId); } +int HanReader::getInt(int objectId) +{ + return kaifa.GetInt(objectId, buffer, 0, bytesRead); +} + +String HanReader::getString(List1_ObisObjects objectId) { return getString((int)objectId); } +String HanReader::getString(List2_ObisObjects objectId) { return getString((int)objectId); } +String HanReader::getString(List3_ObisObjects objectId) { return getString((int)objectId); } +String HanReader::getString(int objectId) +{ + return kaifa.GetString(objectId, buffer, 0, bytesRead); +} diff --git a/Code/ESPDebugger/HanReader.h b/Code/ESPDebugger/HanReader.h new file mode 100644 index 00000000..34740bfb --- /dev/null +++ b/Code/ESPDebugger/HanReader.h @@ -0,0 +1,44 @@ +#ifndef _HANREADER_h +#define _HANREADER_h + +#if defined(ARDUINO) && ARDUINO >= 100 + #include "arduino.h" +#else + #include "WProgram.h" +#endif + + +#include "KaifaHan.h" +#include "DlmsReader.h" + + +class HanReader +{ + public: + HanReader(); + void setup(HardwareSerial *hanPort); + void setup(HardwareSerial *hanPort, Stream *debugPort); + bool read(); + List getList(); + time_t getPackageTime(); + int getInt(List1_ObisObjects objectId); + int getInt(List2_ObisObjects objectId); + int getInt(List3_ObisObjects objectId); + int getInt(int objectId); + String getString(List1_ObisObjects objectId); + String getString(List2_ObisObjects objectId); + String getString(List3_ObisObjects objectId); + String getString(int objectId); + + private: + Stream *debug; + Stream *han; + byte buffer[512]; + int bytesRead; + KaifaHan kaifa; + DlmsReader reader; + List list; +}; + + +#endif