diff --git a/src/plugins/zeroExport/SML.cpp b/src/plugins/zeroExport/lib/sml.cpp similarity index 96% rename from src/plugins/zeroExport/SML.cpp rename to src/plugins/zeroExport/lib/sml.cpp index 128a56e2..17dbd631 100644 --- a/src/plugins/zeroExport/SML.cpp +++ b/src/plugins/zeroExport/lib/sml.cpp @@ -1,8 +1,8 @@ #include #include -#include "SML.h" -#include "SMLCRCTable.h" +#include "sml.h" +#include "smlCrcTable.h" #ifdef SML_DEBUG char logBuff[200]; @@ -80,7 +80,7 @@ void pushListBuffer(unsigned char byte) void reduceList() { - if (currentLevel <= MAX_TREE_SIZE && nodes[currentLevel] > 0) + if (currentLevel >= 0 && nodes[currentLevel] > 0) nodes[currentLevel]--; } @@ -171,7 +171,7 @@ void checkMagicByte(unsigned char &byte) // Datatype Octet String setState(SML_HDATA, (byte & 0x0F) << 4); } - else if (byte >= 0xF0 /*&& byte <= 0xFF*/) { + else if (byte >= 0xF0 && byte <= 0xFF) { /* Datatype List of ...*/ setState(SML_LISTEXTENDED, (byte & 0x0F) << 4); } @@ -403,3 +403,19 @@ void smlOBISAmpere(double &a) a = val; smlPow(a, sc); } + +void smlOBISHertz(double &h) +{ + long long int val; + smlOBISByUnit(val, sc, SML_HERTZ); + h = val; + smlPow(h, sc); +} + +void smlOBISDegree(double &d) +{ + long long int val; + smlOBISByUnit(val, sc, SML_DEGREE); + d = val; + smlPow(d, sc); +} diff --git a/src/plugins/zeroExport/SML.h b/src/plugins/zeroExport/lib/sml.h similarity index 97% rename from src/plugins/zeroExport/SML.h rename to src/plugins/zeroExport/lib/sml.h index ac6405df..3f774dc8 100644 --- a/src/plugins/zeroExport/SML.h +++ b/src/plugins/zeroExport/lib/sml.h @@ -102,5 +102,8 @@ void smlOBISWh(double &wh); void smlOBISW(double &w); void smlOBISVolt(double &v); void smlOBISAmpere(double &a); +void smlOBISHertz(double &h); +void smlOBISDegree(double &d); + #endif diff --git a/src/plugins/zeroExport/SMLCRCTable.h b/src/plugins/zeroExport/lib/smlCrcTable.h similarity index 89% rename from src/plugins/zeroExport/SMLCRCTable.h rename to src/plugins/zeroExport/lib/smlCrcTable.h index 9aee2987..8f6c1c19 100644 --- a/src/plugins/zeroExport/SMLCRCTable.h +++ b/src/plugins/zeroExport/lib/smlCrcTable.h @@ -5,14 +5,6 @@ #ifdef ARDUINO #include - - -/* - * This mysterious table is just the CRC of each possible byte. It can be - * computed using the standard bit-at-a-time methods. The polynomial can - * be seen in entry 128, 0x8408. This corresponds to x^0 + x^5 + x^12. - * Add the implicit x^16, and you have the standard CRC-CCITT. - */ static const uint16_t smlCrcTable[256] PROGMEM = #else static const uint16_t smlCrcTable[256] = diff --git a/src/plugins/zeroExport/powermeter.h b/src/plugins/zeroExport/powermeter.h index f11ef1c4..8761ae64 100644 --- a/src/plugins/zeroExport/powermeter.h +++ b/src/plugins/zeroExport/powermeter.h @@ -9,8 +9,16 @@ #include #include "SML.h" +#include #include "config/settings.h" +typedef struct { + const unsigned char OBIS[6]; + void (*Fn)(double&); + float* Arg; +} OBISHandler; + + class powermeter { public: powermeter() { @@ -50,6 +58,11 @@ class powermeter { break; case 5: result = getPowermeterWattsTibber(logObj, group); + if (result) { + logObj["export"] = String(_powerMeterExport); + logObj["import"] = String(_powerMeterImport); + logObj["power"] = String(_powerMeter1Power); + } break; } if (!result) { @@ -380,25 +393,83 @@ class powermeter { * @param logObj * @param group * @returns true/false + * @TODO: Username & Passwort wird mittels base64 verschlüsselt. Dies wird für die Authentizierung benötigt. Wichtig diese im WebUI unkenntlich zu machen und base64 im eeprom zu speichern, statt klartext. */ + + sml_states_t currentState; + + float _powerMeter1Power = 0.0; + float _powerMeter2Power = 0.0; + float _powerMeter3Power = 0.0; + + float _powerMeterImport = 0.0; + float _powerMeterExport = 0.0; + + const std::list smlHandlerList{ + {{0x01, 0x00, 0x10, 0x07, 0x00, 0xff}, &smlOBISW, &_powerMeter1Power}, + {{0x01, 0x00, 0x01, 0x08, 0x00, 0xff}, &smlOBISWh, &_powerMeterImport}, + {{0x01, 0x00, 0x02, 0x08, 0x00, 0xff}, &smlOBISWh, &_powerMeterExport} + }; + + bool getPowermeterWattsTibber(JsonObject logObj, uint8_t group) { bool result = false; - logObj["mod"] = "getPowermeterWattsTibber"; - - mCfg->groups[group].pmPower = 0; + mCfg->groups[group].pmPower = 0; mCfg->groups[group].pmPowerL1 = 0; mCfg->groups[group].pmPowerL2 = 0; mCfg->groups[group].pmPowerL3 = 0; - result = true; + HTTPClient http; + http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); + http.setUserAgent("Ahoy-Agent"); + http.setConnectTimeout(500); + http.setTimeout(500); + http.addHeader("Content-Type", "application/json"); + http.addHeader("Accept", "application/json"); - logObj["P"] = mCfg->groups[group].pmPower; - logObj["P1"] = mCfg->groups[group].pmPowerL1; - logObj["P2"] = mCfg->groups[group].pmPowerL2; - logObj["P3"] = mCfg->groups[group].pmPowerL3; + String url = String("http://") + mCfg->groups[group].pm_url + String("/") + String(mCfg->groups[group].pm_jsonPath); + String auth = base64::encode(String(mCfg->groups[group].pm_user) + String(":") + String(mCfg->groups[group].pm_pass)); - return result; + http.begin(url); + http.addHeader("Authorization", "Basic " + auth); + + if (http.GET() == HTTP_CODE_OK) + { + String myString = http.getString(); + + char floatBuffer[20]; + double readVal = 0; + + unsigned char c; + for (int i = 0; i < http.getSize(); ++i) + { + c = myString[i]; + sml_states_t smlCurrentState = smlState(c); + + switch(smlCurrentState) + { + case SML_FINAL: + mCfg->groups[group].pmPower = _powerMeter1Power; + /*mCfg->groups[group].pmPower = _powerMeterImport; + mCfg->groups[group].pmPower = _powerMeterExport;*/ + return true; + break; + case SML_LISTEND: + // check handlers on last received list + for (auto &handler: smlHandlerList) + { + if (smlOBISCheck(handler.OBIS)) { + handler.Fn(readVal); + *handler.Arg = readVal; + } + } + break; + } + } + } + http.end(); + return false; } private: