mirror of
https://github.com/lumapu/ahoy.git
synced 2025-07-27 13:17:11 +02:00
Add Tibber
This commit is contained in:
parent
f181e12a29
commit
8785323b30
4 changed files with 103 additions and 21 deletions
|
@ -1,8 +1,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "SML.h"
|
#include "sml.h"
|
||||||
#include "SMLCRCTable.h"
|
#include "smlCrcTable.h"
|
||||||
|
|
||||||
#ifdef SML_DEBUG
|
#ifdef SML_DEBUG
|
||||||
char logBuff[200];
|
char logBuff[200];
|
||||||
|
@ -80,7 +80,7 @@ void pushListBuffer(unsigned char byte)
|
||||||
|
|
||||||
void reduceList()
|
void reduceList()
|
||||||
{
|
{
|
||||||
if (currentLevel <= MAX_TREE_SIZE && nodes[currentLevel] > 0)
|
if (currentLevel >= 0 && nodes[currentLevel] > 0)
|
||||||
nodes[currentLevel]--;
|
nodes[currentLevel]--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ void checkMagicByte(unsigned char &byte)
|
||||||
// Datatype Octet String
|
// Datatype Octet String
|
||||||
setState(SML_HDATA, (byte & 0x0F) << 4);
|
setState(SML_HDATA, (byte & 0x0F) << 4);
|
||||||
}
|
}
|
||||||
else if (byte >= 0xF0 /*&& byte <= 0xFF*/) {
|
else if (byte >= 0xF0 && byte <= 0xFF) {
|
||||||
/* Datatype List of ...*/
|
/* Datatype List of ...*/
|
||||||
setState(SML_LISTEXTENDED, (byte & 0x0F) << 4);
|
setState(SML_LISTEXTENDED, (byte & 0x0F) << 4);
|
||||||
}
|
}
|
||||||
|
@ -403,3 +403,19 @@ void smlOBISAmpere(double &a)
|
||||||
a = val;
|
a = val;
|
||||||
smlPow(a, sc);
|
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);
|
||||||
|
}
|
|
@ -102,5 +102,8 @@ void smlOBISWh(double &wh);
|
||||||
void smlOBISW(double &w);
|
void smlOBISW(double &w);
|
||||||
void smlOBISVolt(double &v);
|
void smlOBISVolt(double &v);
|
||||||
void smlOBISAmpere(double &a);
|
void smlOBISAmpere(double &a);
|
||||||
|
void smlOBISHertz(double &h);
|
||||||
|
void smlOBISDegree(double &d);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -5,14 +5,6 @@
|
||||||
|
|
||||||
#ifdef ARDUINO
|
#ifdef ARDUINO
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 =
|
static const uint16_t smlCrcTable[256] PROGMEM =
|
||||||
#else
|
#else
|
||||||
static const uint16_t smlCrcTable[256] =
|
static const uint16_t smlCrcTable[256] =
|
|
@ -9,8 +9,16 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include "SML.h"
|
#include "SML.h"
|
||||||
|
#include <Base64.h>
|
||||||
#include "config/settings.h"
|
#include "config/settings.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const unsigned char OBIS[6];
|
||||||
|
void (*Fn)(double&);
|
||||||
|
float* Arg;
|
||||||
|
} OBISHandler;
|
||||||
|
|
||||||
|
|
||||||
class powermeter {
|
class powermeter {
|
||||||
public:
|
public:
|
||||||
powermeter() {
|
powermeter() {
|
||||||
|
@ -50,6 +58,11 @@ class powermeter {
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
result = getPowermeterWattsTibber(logObj, group);
|
result = getPowermeterWattsTibber(logObj, group);
|
||||||
|
if (result) {
|
||||||
|
logObj["export"] = String(_powerMeterExport);
|
||||||
|
logObj["import"] = String(_powerMeterImport);
|
||||||
|
logObj["power"] = String(_powerMeter1Power);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
@ -380,25 +393,83 @@ class powermeter {
|
||||||
* @param logObj
|
* @param logObj
|
||||||
* @param group
|
* @param group
|
||||||
* @returns true/false
|
* @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<OBISHandler> 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 getPowermeterWattsTibber(JsonObject logObj, uint8_t group) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
logObj["mod"] = "getPowermeterWattsTibber";
|
|
||||||
|
|
||||||
mCfg->groups[group].pmPower = 0;
|
mCfg->groups[group].pmPower = 0;
|
||||||
mCfg->groups[group].pmPowerL1 = 0;
|
mCfg->groups[group].pmPowerL1 = 0;
|
||||||
mCfg->groups[group].pmPowerL2 = 0;
|
mCfg->groups[group].pmPowerL2 = 0;
|
||||||
mCfg->groups[group].pmPowerL3 = 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;
|
String url = String("http://") + mCfg->groups[group].pm_url + String("/") + String(mCfg->groups[group].pm_jsonPath);
|
||||||
logObj["P1"] = mCfg->groups[group].pmPowerL1;
|
String auth = base64::encode(String(mCfg->groups[group].pm_user) + String(":") + String(mCfg->groups[group].pm_pass));
|
||||||
logObj["P2"] = mCfg->groups[group].pmPowerL2;
|
|
||||||
logObj["P3"] = mCfg->groups[group].pmPowerL3;
|
|
||||||
|
|
||||||
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:
|
private:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue