Memory optimization and bugfix

This commit is contained in:
Gunnar Skjold
2021-01-16 16:02:39 +01:00
parent a830a52863
commit af8f5a7c24
23 changed files with 2041 additions and 2312 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -3,42 +3,74 @@
#include <EEPROM.h>
#include "Arduino.h"
struct ConfigObject {
#define EEPROM_SIZE 1024 * 3
#define EEPROM_CHECK_SUM 86 // Used to check if config is stored. Change if structure changes
#define EEPROM_CONFIG_ADDRESS 0
#define EEPROM_TEMP_CONFIG_ADDRESS 2048
#define CONFIG_SYSTEM_START 8
#define CONFIG_WIFI_START 16
#define CONFIG_MQTT_START 224
#define CONFIG_WEB_START 648
#define CONFIG_METER_START 784
#define CONFIG_DEBUG_START 824
#define CONFIG_GPIO_START 832
#define CONFIG_DOMOTICZ_START 856
#define CONFIG_NTP_START 872
#define CONFIG_ENTSOE_START 944
struct SystemConfig {
uint8_t boardType;
char wifiSsid[32];
char wifiPassword[64];
char wifiIp[15];
char wifiGw[15];
char wifiSubnet[15];
char wifiDns1[15];
char wifiDns2[15];
char wifiHostname[32];
char mqttHost[128];
uint16_t mqttPort;
char mqttClientId[32];
char mqttPublishTopic[64];
char mqttSubscribeTopic[64];
char mqttUser[64];
char mqttPassword[64];
uint8_t mqttPayloadFormat;
bool mqttSsl;
uint8_t authSecurity;
char authUser[64];
char authPassword[64];
uint8_t meterType;
}; // 1
struct WiFiConfig {
char ssid[32];
char psk[64];
char ip[15];
char gateway[15];
char subnet[15];
char dns1[15];
char dns2[15];
char hostname[32];
bool mdns;
}; // 204
struct MqttConfig {
char host[128];
uint16_t port;
char clientId[32];
char publishTopic[64];
char subscribeTopic[64];
char username[64];
char password[64];
uint8_t payloadFormat;
bool ssl;
}; // 420
struct WebConfig {
uint8_t security;
char username[64];
char password[64];
}; // 129
struct MeterConfig {
uint8_t type;
uint8_t distributionSystem;
uint8_t mainFuse;
uint8_t productionCapacity;
uint8_t meterEncryptionKey[16];
uint8_t meterAuthenticationKey[16];
uint8_t encryptionKey[16];
uint8_t authenticationKey[16];
bool substituteMissing;
bool sendUnknown;
}; // 38
bool debugTelnet;
bool debugSerial;
uint8_t debugLevel;
struct DebugConfig {
bool telnet;
bool serial;
uint8_t level;
}; // 3
struct GpioConfig {
uint8_t hanPin;
uint8_t apPin;
uint8_t ledPin;
@@ -53,25 +85,30 @@ struct ConfigObject {
int16_t vccOffset;
uint16_t vccMultiplier;
uint8_t vccBootLimit;
}; // 16
uint16_t domoELIDX;
uint16_t domoVL1IDX;
uint16_t domoVL2IDX;
uint16_t domoVL3IDX;
uint16_t domoCL1IDX;
struct DomoticzConfig {
uint16_t elidx;
uint16_t vl1idx;
uint16_t vl2idx;
uint16_t vl3idx;
uint16_t cl1idx;
}; // 10
bool mDnsEnable;
bool ntpEnable;
bool ntpDhcp;
int16_t ntpOffset;
int16_t ntpSummerOffset;
char ntpServer[64];
struct NtpConfig {
bool enable;
bool dhcp;
int16_t offset;
int16_t summerOffset;
char server[64];
}; // 70
char entsoeApiToken[37];
char entsoeApiArea[17];
char entsoeApiCurrency[4];
double entsoeApiMultiplier;
};
struct EntsoeConfig {
char token[37];
char area[17];
char currency[4];
uint16_t multiplier;
}; // 60
struct ConfigObject83 {
uint8_t boardType;
@@ -204,173 +241,63 @@ public:
bool hasConfig();
int getConfigVersion();
bool load();
bool save();
uint8_t getBoardType();
void setBoardType(uint8_t boardType);
char* getWifiSsid();
void setWifiSsid(const char* wifiSsid);
char* getWifiPassword();
void setWifiPassword(const char* wifiPassword);
char* getWifiIp();
void setWifiIp(const char* wifiIp);
char* getWifiGw();
void setWifiGw(const char* wifiGw);
char* getWifiSubnet();
void setWifiSubnet(const char* wifiSubnet);
char* getWifiDns1();
void setWifiDns1(const char* wifiDns1);
char* getWifiDns2();
void setWifiDns2(const char* wifiDns1);
char* getWifiHostname();
void setWifiHostname(const char* wifiHostname);
void clearWifi();
void clearWifiIp();
bool getSystemConfig(SystemConfig&);
bool setSystemConfig(SystemConfig&);
bool getWiFiConfig(WiFiConfig&);
bool setWiFiConfig(WiFiConfig&);
void clearWifi(WiFiConfig&);
void clearWifiIp(WiFiConfig&);
bool isWifiChanged();
void ackWifiChange();
char* getMqttHost();
void setMqttHost(const char* mqttHost);
uint16_t getMqttPort();
void setMqttPort(uint16_t mqttPort);
char* getMqttClientId();
void setMqttClientId(const char* mqttClientId);
char* getMqttPublishTopic();
void setMqttPublishTopic(const char* mqttPublishTopic);
char* getMqttSubscribeTopic();
void setMqttSubscribeTopic(const char* mqttSubscribeTopic);
char* getMqttUser();
void setMqttUser(const char* mqttUser);
char* getMqttPassword();
void setMqttPassword(const char* mqttPassword);
uint8_t getMqttPayloadFormat();
void setMqttPayloadFormat(uint8_t mqttPayloadFormat);
bool isMqttSsl();
void setMqttSsl(bool mqttSsl);
void clearMqtt();
bool getMqttConfig(MqttConfig&);
bool setMqttConfig(MqttConfig&);
void clearMqtt(MqttConfig&);
void setMqttChanged();
bool isMqttChanged();
void ackMqttChange();
byte getAuthSecurity();
void setAuthSecurity(byte authSecurity);
char* getAuthUser();
void setAuthUser(const char* authUser);
char* getAuthPassword();
void setAuthPassword(const char* authPassword);
void clearAuth();
uint8_t getMeterType();
void setMeterType(uint8_t meterType);
uint8_t getDistributionSystem();
void setDistributionSystem(uint8_t distributionSystem);
uint8_t getMainFuse();
void setMainFuse(uint8_t mainFuse);
uint8_t getProductionCapacity();
void setProductionCapacity(uint8_t productionCapacity);
uint8_t* getMeterEncryptionKey();
void setMeterEncryptionKey(uint8_t* meterEncryptionKey);
uint8_t* getMeterAuthenticationKey();
void setMeterAuthenticationKey(uint8_t* meterAuthenticationKey);
bool isSubstituteMissing();
void setSubstituteMissing(bool substituteMissing);
bool isSendUnknown();
void setSendUnknown(bool sendUnknown);
void clearMeter();
bool getWebConfig(WebConfig&);
bool setWebConfig(WebConfig&);
void clearAuth(WebConfig&);
bool getMeterConfig(MeterConfig&);
bool setMeterConfig(MeterConfig&);
void clearMeter(MeterConfig&);
bool isMeterChanged();
void ackMeterChanged();
bool isDebugTelnet();
void setDebugTelnet(bool debugTelnet);
bool isDebugSerial();
void setDebugSerial(bool debugSerial);
uint8_t getDebugLevel();
void setDebugLevel(uint8_t debugLevel);
bool getDebugConfig(DebugConfig&);
bool setDebugConfig(DebugConfig&);
bool pinUsed(uint8_t pin);
bool pinUsed(uint8_t, GpioConfig&);
uint8_t getHanPin();
void setHanPin(uint8_t hanPin);
uint8_t getApPin();
void setApPin(uint8_t apPin);
uint8_t getLedPin();
void setLedPin(uint8_t ledPin);
bool isLedInverted();
void setLedInverted(bool ledInverted);
uint8_t getLedPinRed();
void setLedPinRed(uint8_t ledPinRed);
uint8_t getLedPinGreen();
void setLedPinGreen(uint8_t ledPinGreen);
uint8_t getLedPinBlue();
void setLedPinBlue(uint8_t ledPinBlue);
bool isLedRgbInverted();
void setLedRgbInverted(bool ledRgbInverted);
uint8_t getTempSensorPin();
void setTempSensorPin(uint8_t tempSensorPin);
uint8_t getTempAnalogSensorPin();
void setTempAnalogSensorPin(uint8_t tempSensorPin);
uint8_t getVccPin();
void setVccPin(uint8_t vccPin);
double getVccOffset();
void setVccOffset(double vccOffset);
double getVccMultiplier();
void setVccMultiplier(double vccMultiplier);
double getVccBootLimit();
void setVccBootLimit(double vccBootLimit);
bool getGpioConfig(GpioConfig&);
bool setGpioConfig(GpioConfig&);
void clearGpio(GpioConfig&);
void print(Print* debugger);
uint16_t getDomoELIDX();
uint16_t getDomoVL1IDX();
uint16_t getDomoVL2IDX();
uint16_t getDomoVL3IDX();
uint16_t getDomoCL1IDX();
void setDomoELIDX(uint16_t domoELIDX);
void setDomoVL1IDX(uint16_t domoVL1IDX);
void setDomoVL2IDX(uint16_t domoVL2IDX);
void setDomoVL3IDX(uint16_t domoVL3IDX);
void setDomoCL1IDX(uint16_t domoCL1IDX);
void clearDomo();
bool getDomoticzConfig(DomoticzConfig&);
bool setDomoticzConfig(DomoticzConfig&);
void clearDomo(DomoticzConfig&);
bool isDomoChanged();
void ackDomoChange();
bool isMdnsEnable();
void setMdnsEnable(bool mdnsEnable);
bool isNtpEnable();
void setNtpEnable(bool ntpEnable);
bool isNtpDhcp();
void setNtpDhcp(bool ntpDhcp);
int32_t getNtpOffset();
void setNtpOffset(uint32_t ntpOffset);
int32_t getNtpSummerOffset();
void setNtpSummerOffset(uint32_t ntpSummerOffset);
char* getNtpServer();
void setNtpServer(const char* ntpServer);
void clearNtp();
bool getNtpConfig(NtpConfig&);
bool setNtpConfig(NtpConfig&);
void clearNtp(NtpConfig&);
bool isNtpChanged();
void ackNtpChange();
char* getEntsoeApiToken();
void setEntsoeApiToken(const char* token);
char* getEntsoeApiArea();
void setEntsoeApiArea(const char* area);
char* getEntsoeApiCurrency();
void setEntsoeApiCurrency(const char* currency);
double getEntsoeApiMultiplier();
void setEntsoeApiMultiplier(double multiplier);
bool getEntsoeConfig(EntsoeConfig&);
bool setEntsoeConfig(EntsoeConfig&);
uint8_t getTempSensorCount();
TempSensorConfig* getTempSensorConfig(uint8_t i);
TempSensorConfig* getTempSensorConfig(uint8_t address[8]);
void updateTempSensorConfig(uint8_t address[8], const char name[32], bool common);
bool isSensorAddressEqual(uint8_t a[8], uint8_t b[8]);
@@ -380,81 +307,12 @@ public:
protected:
private:
int configVersion = 0;
ConfigObject config {
0, // Board type
"", // SSID
"", // PSK
"", // IP
"", // GW
"", // Subnet
"", // DNS 1
"", // DNS 2
"", // Hostname
"", // MQTT host
1883, // Port
"", // Client ID
"", // Publish topic
"", // Subscribe topic
"", // Username
"", // Password
0, // Format
false, // SSL
0, // Web security
"", // Username
"", // Password
0, // Meter type
0, // Distribution system
0, // Main fuse
0, // Production capacity
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Encryption key
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Authentication key
false, // Substitute
false, // Send unknown
false, // Debug telnet
false, // Debug serial
5, // Debug level
0x03, // HAN pin
0xFF, // AP pin
0x02, // LED pin
true, // Inverted
0xFF, // Red
0xFF, // Green
0xFF, // Blue
true, // Inverted
0xFF, // Temp sensor
0xFF, // Analog temp sensor
0xFF, // Vcc
0, // Offset
100, // Multiplier
0, // Boot limit
//Domoticz
0, // ELIDX
0, // VL1IDX
0, // VL2IDX
0, // VL3IDX
0, // CL1IDX
true, // mDNS
true, // NTP
true, // NTP DHCP
360, // Timezone (*10)
360, // Summertime offset (*10)
"pool.ntp.org", // NTP server
"", // Entsoe token
"", // Entsoe area
"", // Entsoe currency
1.00, // Entsoe multiplier
// 960 bytes
};
uint8_t configVersion = 0;
bool wifiChanged, mqttChanged, meterChanged = true, domoChanged, ntpChanged;
uint8_t tempSensorCount = 0;
TempSensorConfig* tempSensors[32];
const int EEPROM_SIZE = 1024 * 3;
const int EEPROM_CHECK_SUM = 84; // Used to check if config is stored. Change if structure changes
const int EEPROM_CONFIG_ADDRESS = 0;
const int EEPROM_TEMP_CONFIG_ADDRESS = 2048;
TempSensorConfig** tempSensors;
void loadTempSensors();
void saveTempSensors();

View File

@@ -6,7 +6,7 @@
AmsData::AmsData() {}
AmsData::AmsData(int meterType, bool substituteMissing, HanReader& hanReader) {
AmsData::AmsData(uint8_t meterType, bool substituteMissing, HanReader& hanReader) {
lastUpdateMillis = millis();
packageTimestamp = hanReader.getPackageTime(true, true);
@@ -27,34 +27,34 @@ AmsData::AmsData(int meterType, bool substituteMissing, HanReader& hanReader) {
}
}
void AmsData::extractFromKaifa(HanReader& hanReader, int listSize) {
void AmsData::extractFromKaifa(HanReader& hanReader, uint8_t listSize) {
switch(listSize) {
case (int)Kaifa::List1:
case (uint8_t)Kaifa::List1:
listType = 1;
break;
case (int)Kaifa::List3PhaseShort:
case (uint8_t)Kaifa::List3PhaseShort:
threePhase = true;
case (int)Kaifa::List1PhaseShort:
case (uint8_t)Kaifa::List1PhaseShort:
listType = 2;
break;
case (int)Kaifa::List3PhaseLong:
case (uint8_t)Kaifa::List3PhaseLong:
threePhase = true;
case (int)Kaifa::List1PhaseLong:
case (uint8_t)Kaifa::List1PhaseLong:
listType = 3;
break;
}
if(listSize == (int)Kaifa::List1) {
if(listSize == (uint8_t)Kaifa::List1) {
activeImportPower = hanReader.getInt((int)Kaifa_List1::ActivePowerImported);
} else {
switch(listSize) {
case (int)Kaifa::List3PhaseLong:
case (uint8_t)Kaifa::List3PhaseLong:
meterTimestamp = hanReader.getTime( (int)Kaifa_List3Phase::MeterClock, false, false);
activeImportCounter = ((double) hanReader.getUint((int)Kaifa_List3Phase::CumulativeActiveImportEnergy)) / 1000;
activeExportCounter = ((double) hanReader.getUint((int)Kaifa_List3Phase::CumulativeActiveExportEnergy)) / 1000;
reactiveImportCounter = ((double) hanReader.getUint((int)Kaifa_List3Phase::CumulativeReactiveImportEnergy)) / 1000;
reactiveExportCounter = ((double) hanReader.getUint((int)Kaifa_List3Phase::CumulativeReactiveExportEnergy)) / 1000;
case (int)Kaifa::List3PhaseShort:
activeImportCounter = ((float) hanReader.getUint((int)Kaifa_List3Phase::CumulativeActiveImportEnergy)) / 1000;
activeExportCounter = ((float) hanReader.getUint((int)Kaifa_List3Phase::CumulativeActiveExportEnergy)) / 1000;
reactiveImportCounter = ((float) hanReader.getUint((int)Kaifa_List3Phase::CumulativeReactiveImportEnergy)) / 1000;
reactiveExportCounter = ((float) hanReader.getUint((int)Kaifa_List3Phase::CumulativeReactiveExportEnergy)) / 1000;
case (uint8_t)Kaifa::List3PhaseShort:
listId = hanReader.getString( (int)Kaifa_List3Phase::ListVersionIdentifier);
meterId = hanReader.getString( (int)Kaifa_List3Phase::MeterID);
meterType = hanReader.getString( (int)Kaifa_List3Phase::MeterType);
@@ -62,20 +62,20 @@ void AmsData::extractFromKaifa(HanReader& hanReader, int listSize) {
reactiveImportPower = hanReader.getUint( (int)Kaifa_List3Phase::ReactiveImportPower);
activeExportPower = hanReader.getUint( (int)Kaifa_List3Phase::ActiveExportPower);
reactiveExportPower = hanReader.getUint( (int)Kaifa_List3Phase::ReactiveExportPower);
l1current = ((double) hanReader.getInt( (int)Kaifa_List3Phase::CurrentL1)) / 1000;
l2current = ((double) hanReader.getInt( (int)Kaifa_List3Phase::CurrentL2)) / 1000;
l3current = ((double) hanReader.getInt( (int)Kaifa_List3Phase::CurrentL3)) / 1000;
l1voltage = ((double) hanReader.getInt( (int)Kaifa_List3Phase::VoltageL1)) / 10;
l2voltage = ((double) hanReader.getInt( (int)Kaifa_List3Phase::VoltageL2)) / 10;
l3voltage = ((double) hanReader.getInt( (int)Kaifa_List3Phase::VoltageL3)) / 10;
l1current = ((float) hanReader.getInt( (int)Kaifa_List3Phase::CurrentL1)) / 1000;
l2current = ((float) hanReader.getInt( (int)Kaifa_List3Phase::CurrentL2)) / 1000;
l3current = ((float) hanReader.getInt( (int)Kaifa_List3Phase::CurrentL3)) / 1000;
l1voltage = ((float) hanReader.getInt( (int)Kaifa_List3Phase::VoltageL1)) / 10;
l2voltage = ((float) hanReader.getInt( (int)Kaifa_List3Phase::VoltageL2)) / 10;
l3voltage = ((float) hanReader.getInt( (int)Kaifa_List3Phase::VoltageL3)) / 10;
break;
case (int)Kaifa::List1PhaseLong:
case (uint8_t)Kaifa::List1PhaseLong:
meterTimestamp = hanReader.getTime( (int)Kaifa_List1Phase::MeterClock, false, false);
activeImportCounter = ((double) hanReader.getUint((int)Kaifa_List1Phase::CumulativeActiveImportEnergy));
activeExportCounter = ((double) hanReader.getUint((int)Kaifa_List1Phase::CumulativeActiveExportEnergy));
reactiveImportCounter = ((double) hanReader.getUint((int)Kaifa_List1Phase::CumulativeReactiveImportEnergy));
reactiveExportCounter = ((double) hanReader.getUint((int)Kaifa_List1Phase::CumulativeReactiveExportEnergy));
case (int)Kaifa::List1PhaseShort:
activeImportCounter = ((float) hanReader.getUint((int)Kaifa_List1Phase::CumulativeActiveImportEnergy));
activeExportCounter = ((float) hanReader.getUint((int)Kaifa_List1Phase::CumulativeActiveExportEnergy));
reactiveImportCounter = ((float) hanReader.getUint((int)Kaifa_List1Phase::CumulativeReactiveImportEnergy));
reactiveExportCounter = ((float) hanReader.getUint((int)Kaifa_List1Phase::CumulativeReactiveExportEnergy));
case (uint8_t)Kaifa::List1PhaseShort:
listId = hanReader.getString( (int)Kaifa_List1Phase::ListVersionIdentifier);
meterId = hanReader.getString( (int)Kaifa_List1Phase::MeterID);
meterType = hanReader.getString( (int)Kaifa_List1Phase::MeterType);
@@ -83,94 +83,94 @@ void AmsData::extractFromKaifa(HanReader& hanReader, int listSize) {
reactiveImportPower = hanReader.getUint( (int)Kaifa_List1Phase::ReactiveImportPower);
activeExportPower = hanReader.getUint( (int)Kaifa_List1Phase::ActiveExportPower);
reactiveExportPower = hanReader.getUint( (int)Kaifa_List1Phase::ReactiveExportPower);
l1current = ((double) hanReader.getInt( (int)Kaifa_List1Phase::CurrentL1)) / 1000;
l1voltage = ((double) hanReader.getInt( (int)Kaifa_List1Phase::VoltageL1)) / 10;
l1current = ((float) hanReader.getInt( (int)Kaifa_List1Phase::CurrentL1)) / 1000;
l1voltage = ((float) hanReader.getInt( (int)Kaifa_List1Phase::VoltageL1)) / 10;
break;
}
}
}
void AmsData::extractFromAidon(HanReader& hanReader, int listSize, bool substituteMissing) {
void AmsData::extractFromAidon(HanReader& hanReader, uint8_t listSize, bool substituteMissing) {
switch(listSize) {
case (int)Aidon::List1:
case (uint8_t)Aidon::List1:
listType = 1;
break;
case (int)Aidon::List3PhaseITShort:
case (int)Aidon::List3PhaseShort:
case (uint8_t)Aidon::List3PhaseITShort:
case (uint8_t)Aidon::List3PhaseShort:
threePhase = true;
case (int)Aidon::List1PhaseShort:
case (uint8_t)Aidon::List1PhaseShort:
listType = 2;
break;
case (int)Aidon::List3PhaseITLong:
case (int)Aidon::List3PhaseLong:
case (uint8_t)Aidon::List3PhaseITLong:
case (uint8_t)Aidon::List3PhaseLong:
threePhase = true;
case (int)Aidon::List1PhaseLong:
case (uint8_t)Aidon::List1PhaseLong:
listType = 3;
break;
}
if(listSize == (int)Aidon::List1) {
activeImportPower = hanReader.getUint((int)Aidon_List1::ActiveImportPower);
if(listSize == (uint8_t)Aidon::List1) {
activeImportPower = hanReader.getUint((uint8_t)Aidon_List1::ActiveImportPower);
} else {
switch(listSize) {
case (int)Aidon::List3PhaseLong:
meterTimestamp = hanReader.getTime( (int)Aidon_List3Phase::Timestamp, false, false);
activeImportCounter = ((double) hanReader.getUint( (int)Aidon_List3Phase::CumulativeActiveImportEnergy)) / 100;
activeExportCounter = ((double) hanReader.getUint( (int)Aidon_List3Phase::CumulativeActiveExportEnergy)) / 100;
reactiveImportCounter = ((double) hanReader.getUint( (int)Aidon_List3Phase::CumulativeReactiveImportEnergy)) / 100;
reactiveExportCounter = ((double) hanReader.getUint( (int)Aidon_List3Phase::CumulativeReactiveExportEnergy)) / 100;
case (int)Aidon::List3PhaseShort:
listId = hanReader.getString( (int)Aidon_List3Phase::ListVersionIdentifier);
meterId = hanReader.getString( (int)Aidon_List3Phase::MeterID);
meterType = hanReader.getString( (int)Aidon_List3Phase::MeterType);
activeImportPower = hanReader.getUint( (int)Aidon_List3Phase::ActiveImportPower);
reactiveImportPower = hanReader.getUint( (int)Aidon_List3Phase::ReactiveImportPower);
activeExportPower = hanReader.getUint( (int)Aidon_List3Phase::ActiveExportPower);
reactiveExportPower = hanReader.getUint( (int)Aidon_List3Phase::ReactiveExportPower);
l1current = ((double) hanReader.getInt( (int)Aidon_List3Phase::CurrentL1)) / 10;
l2current = ((double) hanReader.getInt( (int)Aidon_List3Phase::CurrentL2)) / 10;
l3current = ((double) hanReader.getInt( (int)Aidon_List3Phase::CurrentL3)) / 10;
l1voltage = ((double) hanReader.getInt( (int)Aidon_List3Phase::VoltageL1)) / 10;
l2voltage = ((double) hanReader.getInt( (int)Aidon_List3Phase::VoltageL2)) / 10;
l3voltage = ((double) hanReader.getInt( (int)Aidon_List3Phase::VoltageL3)) / 10;
case (uint8_t)Aidon::List3PhaseLong:
meterTimestamp = hanReader.getTime( (uint8_t)Aidon_List3Phase::Timestamp, false, false);
activeImportCounter = ((float) hanReader.getUint( (uint8_t)Aidon_List3Phase::CumulativeActiveImportEnergy)) / 100;
activeExportCounter = ((float) hanReader.getUint( (uint8_t)Aidon_List3Phase::CumulativeActiveExportEnergy)) / 100;
reactiveImportCounter = ((float) hanReader.getUint( (uint8_t)Aidon_List3Phase::CumulativeReactiveImportEnergy)) / 100;
reactiveExportCounter = ((float) hanReader.getUint( (uint8_t)Aidon_List3Phase::CumulativeReactiveExportEnergy)) / 100;
case (uint8_t)Aidon::List3PhaseShort:
listId = hanReader.getString( (uint8_t)Aidon_List3Phase::ListVersionIdentifier);
meterId = hanReader.getString( (uint8_t)Aidon_List3Phase::MeterID);
meterType = hanReader.getString( (uint8_t)Aidon_List3Phase::MeterType);
activeImportPower = hanReader.getUint( (uint8_t)Aidon_List3Phase::ActiveImportPower);
reactiveImportPower = hanReader.getUint( (uint8_t)Aidon_List3Phase::ReactiveImportPower);
activeExportPower = hanReader.getUint( (uint8_t)Aidon_List3Phase::ActiveExportPower);
reactiveExportPower = hanReader.getUint( (uint8_t)Aidon_List3Phase::ReactiveExportPower);
l1current = ((float) hanReader.getInt( (uint8_t)Aidon_List3Phase::CurrentL1)) / 10;
l2current = ((float) hanReader.getInt( (uint8_t)Aidon_List3Phase::CurrentL2)) / 10;
l3current = ((float) hanReader.getInt( (uint8_t)Aidon_List3Phase::CurrentL3)) / 10;
l1voltage = ((float) hanReader.getInt( (uint8_t)Aidon_List3Phase::VoltageL1)) / 10;
l2voltage = ((float) hanReader.getInt( (uint8_t)Aidon_List3Phase::VoltageL2)) / 10;
l3voltage = ((float) hanReader.getInt( (uint8_t)Aidon_List3Phase::VoltageL3)) / 10;
break;
case (int)Aidon::List1PhaseLong:
meterTimestamp = hanReader.getTime( (int)Aidon_List1Phase::Timestamp, false, false);
activeImportCounter = ((double) hanReader.getUint( (int)Aidon_List1Phase::CumulativeActiveImportEnergy)) / 100;
activeExportCounter = ((double) hanReader.getUint( (int)Aidon_List1Phase::CumulativeActiveExportEnergy)) / 100;
reactiveImportCounter = ((double) hanReader.getUint( (int)Aidon_List1Phase::CumulativeReactiveImportEnergy)) / 100;
reactiveExportCounter = ((double) hanReader.getUint( (int)Aidon_List1Phase::CumulativeReactiveExportEnergy)) / 100;
case (int)Aidon::List1PhaseShort:
listId = hanReader.getString( (int)Aidon_List1Phase::ListVersionIdentifier);
meterId = hanReader.getString( (int)Aidon_List1Phase::MeterID);
meterType = hanReader.getString( (int)Aidon_List1Phase::MeterType);
activeImportPower = hanReader.getUint( (int)Aidon_List1Phase::ActiveImportPower);
reactiveImportPower = hanReader.getUint( (int)Aidon_List1Phase::ReactiveImportPower);
activeExportPower = hanReader.getUint( (int)Aidon_List1Phase::ActiveExportPower);
reactiveExportPower = hanReader.getUint( (int)Aidon_List1Phase::ReactiveExportPower);
l1current = ((double) hanReader.getInt( (int)Aidon_List1Phase::CurrentL1)) / 10;
l1voltage = ((double) hanReader.getInt( (int)Aidon_List1Phase::VoltageL1)) / 10;
case (uint8_t)Aidon::List1PhaseLong:
meterTimestamp = hanReader.getTime( (uint8_t)Aidon_List1Phase::Timestamp, false, false);
activeImportCounter = ((float) hanReader.getUint( (uint8_t)Aidon_List1Phase::CumulativeActiveImportEnergy)) / 100;
activeExportCounter = ((float) hanReader.getUint( (uint8_t)Aidon_List1Phase::CumulativeActiveExportEnergy)) / 100;
reactiveImportCounter = ((float) hanReader.getUint( (uint8_t)Aidon_List1Phase::CumulativeReactiveImportEnergy)) / 100;
reactiveExportCounter = ((float) hanReader.getUint( (uint8_t)Aidon_List1Phase::CumulativeReactiveExportEnergy)) / 100;
case (uint8_t)Aidon::List1PhaseShort:
listId = hanReader.getString( (uint8_t)Aidon_List1Phase::ListVersionIdentifier);
meterId = hanReader.getString( (uint8_t)Aidon_List1Phase::MeterID);
meterType = hanReader.getString( (uint8_t)Aidon_List1Phase::MeterType);
activeImportPower = hanReader.getUint( (uint8_t)Aidon_List1Phase::ActiveImportPower);
reactiveImportPower = hanReader.getUint( (uint8_t)Aidon_List1Phase::ReactiveImportPower);
activeExportPower = hanReader.getUint( (uint8_t)Aidon_List1Phase::ActiveExportPower);
reactiveExportPower = hanReader.getUint( (uint8_t)Aidon_List1Phase::ReactiveExportPower);
l1current = ((float) hanReader.getInt( (uint8_t)Aidon_List1Phase::CurrentL1)) / 10;
l1voltage = ((float) hanReader.getInt( (uint8_t)Aidon_List1Phase::VoltageL1)) / 10;
break;
case (int)Aidon::List3PhaseITLong:
meterTimestamp = hanReader.getTime( (int)Aidon_List3PhaseIT::Timestamp, false, false);
activeImportCounter = ((double) hanReader.getUint( (int)Aidon_List3PhaseIT::CumulativeActiveImportEnergy)) / 100;
activeExportCounter = ((double) hanReader.getUint( (int)Aidon_List3PhaseIT::CumulativeActiveExportEnergy)) / 100;
reactiveImportCounter = ((double) hanReader.getUint( (int)Aidon_List3PhaseIT::CumulativeReactiveImportEnergy)) / 100;
reactiveExportCounter = ((double) hanReader.getUint( (int)Aidon_List3PhaseIT::CumulativeReactiveExportEnergy)) / 100;
case (int)Aidon::List3PhaseITShort:
listId = hanReader.getString( (int)Aidon_List3PhaseIT::ListVersionIdentifier);
meterId = hanReader.getString( (int)Aidon_List3PhaseIT::MeterID);
meterType = hanReader.getString( (int)Aidon_List3PhaseIT::MeterType);
activeImportPower = hanReader.getUint( (int)Aidon_List3PhaseIT::ActiveImportPower);
reactiveImportPower = hanReader.getUint( (int)Aidon_List3PhaseIT::ReactiveImportPower);
activeExportPower = hanReader.getUint( (int)Aidon_List3PhaseIT::ActiveExportPower);
reactiveExportPower = hanReader.getUint( (int)Aidon_List3PhaseIT::ReactiveExportPower);
l1current = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CurrentL1)) / 10;
case (uint8_t)Aidon::List3PhaseITLong:
meterTimestamp = hanReader.getTime( (uint8_t)Aidon_List3PhaseIT::Timestamp, false, false);
activeImportCounter = ((float) hanReader.getUint( (uint8_t)Aidon_List3PhaseIT::CumulativeActiveImportEnergy)) / 100;
activeExportCounter = ((float) hanReader.getUint( (uint8_t)Aidon_List3PhaseIT::CumulativeActiveExportEnergy)) / 100;
reactiveImportCounter = ((float) hanReader.getUint( (uint8_t)Aidon_List3PhaseIT::CumulativeReactiveImportEnergy)) / 100;
reactiveExportCounter = ((float) hanReader.getUint( (uint8_t)Aidon_List3PhaseIT::CumulativeReactiveExportEnergy)) / 100;
case (uint8_t)Aidon::List3PhaseITShort:
listId = hanReader.getString( (uint8_t)Aidon_List3PhaseIT::ListVersionIdentifier);
meterId = hanReader.getString( (uint8_t)Aidon_List3PhaseIT::MeterID);
meterType = hanReader.getString( (uint8_t)Aidon_List3PhaseIT::MeterType);
activeImportPower = hanReader.getUint( (uint8_t)Aidon_List3PhaseIT::ActiveImportPower);
reactiveImportPower = hanReader.getUint( (uint8_t)Aidon_List3PhaseIT::ReactiveImportPower);
activeExportPower = hanReader.getUint( (uint8_t)Aidon_List3PhaseIT::ActiveExportPower);
reactiveExportPower = hanReader.getUint( (uint8_t)Aidon_List3PhaseIT::ReactiveExportPower);
l1current = ((float) hanReader.getInt( (uint8_t)Aidon_List3PhaseIT::CurrentL1)) / 10;
l2current = 0;
l3current = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CurrentL3)) / 10;
l1voltage = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::VoltageL1)) / 10;
l2voltage = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::VoltageL2)) / 10;
l3voltage = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::VoltageL3)) / 10;
l3current = ((float) hanReader.getInt( (uint8_t)Aidon_List3PhaseIT::CurrentL3)) / 10;
l1voltage = ((float) hanReader.getInt( (uint8_t)Aidon_List3PhaseIT::VoltageL1)) / 10;
l2voltage = ((float) hanReader.getInt( (uint8_t)Aidon_List3PhaseIT::VoltageL2)) / 10;
l3voltage = ((float) hanReader.getInt( (uint8_t)Aidon_List3PhaseIT::VoltageL3)) / 10;
if(substituteMissing) {
l2current = (((activeImportPower - activeExportPower) * sqrt(3)) - (l1voltage * l1current) - (l3voltage * l3current)) / l2voltage;
}
@@ -179,81 +179,81 @@ void AmsData::extractFromAidon(HanReader& hanReader, int listSize, bool substitu
}
}
void AmsData::extractFromKamstrup(HanReader& hanReader, int listSize, bool substituteMissing) {
void AmsData::extractFromKamstrup(HanReader& hanReader, uint8_t listSize, bool substituteMissing) {
switch(listSize) {
case (int)Kamstrup::List3PhaseITShort:
case (int)Kamstrup::List3PhaseShort:
case (uint8_t)Kamstrup::List3PhaseITShort:
case (uint8_t)Kamstrup::List3PhaseShort:
threePhase = true;
case (int)Kamstrup::List1PhaseShort:
case (uint8_t)Kamstrup::List1PhaseShort:
listType = 2;
break;
case (int)Kamstrup::List3PhaseITLong:
case (int)Kamstrup::List3PhaseLong:
case (uint8_t)Kamstrup::List3PhaseITLong:
case (uint8_t)Kamstrup::List3PhaseLong:
threePhase = true;
case (int)Kamstrup::List1PhaseLong:
case (uint8_t)Kamstrup::List1PhaseLong:
listType = 3;
break;
}
switch(listSize) {
case (int)Kamstrup::List1PhaseLong:
meterTimestamp = hanReader.getTime( (int)Kamstrup_List1Phase::MeterClock, true, true);
activeImportCounter = ((double) hanReader.getInt((int)Kamstrup_List1Phase::CumulativeActiveImportEnergy)) / 100;
activeExportCounter = ((double) hanReader.getInt((int)Kamstrup_List1Phase::CumulativeActiveExportEnergy)) / 100;
reactiveImportCounter = ((double) hanReader.getInt((int)Kamstrup_List1Phase::CumulativeReactiveImportEnergy)) / 100;
reactiveExportCounter = ((double) hanReader.getInt((int)Kamstrup_List1Phase::CumulativeReactiveExportEnergy)) / 100;
case (int)Kamstrup::List1PhaseShort:
listId = hanReader.getString( (int)Kamstrup_List1Phase::ListVersionIdentifier);
meterId = hanReader.getString( (int)Kamstrup_List1Phase::MeterID);
meterType = hanReader.getString( (int)Kamstrup_List1Phase::MeterType);
activeImportPower = hanReader.getInt( (int)Kamstrup_List1Phase::ActiveImportPower);
reactiveImportPower = hanReader.getInt( (int)Kamstrup_List1Phase::ReactiveImportPower);
activeExportPower = hanReader.getInt( (int)Kamstrup_List1Phase::ActiveExportPower);
reactiveExportPower = hanReader.getInt( (int)Kamstrup_List1Phase::ReactiveExportPower);
l1current = ((double) hanReader.getInt((int)Kamstrup_List1Phase::CurrentL1)) / 100;
l1voltage = hanReader.getInt( (int)Kamstrup_List1Phase::VoltageL1);
case (uint8_t)Kamstrup::List1PhaseLong:
meterTimestamp = hanReader.getTime( (uint8_t)Kamstrup_List1Phase::MeterClock, true, true);
activeImportCounter = ((float) hanReader.getInt((uint8_t)Kamstrup_List1Phase::CumulativeActiveImportEnergy)) / 100;
activeExportCounter = ((float) hanReader.getInt((uint8_t)Kamstrup_List1Phase::CumulativeActiveExportEnergy)) / 100;
reactiveImportCounter = ((float) hanReader.getInt((uint8_t)Kamstrup_List1Phase::CumulativeReactiveImportEnergy)) / 100;
reactiveExportCounter = ((float) hanReader.getInt((uint8_t)Kamstrup_List1Phase::CumulativeReactiveExportEnergy)) / 100;
case (uint8_t)Kamstrup::List1PhaseShort:
listId = hanReader.getString( (uint8_t)Kamstrup_List1Phase::ListVersionIdentifier);
meterId = hanReader.getString( (uint8_t)Kamstrup_List1Phase::MeterID);
meterType = hanReader.getString( (uint8_t)Kamstrup_List1Phase::MeterType);
activeImportPower = hanReader.getInt( (uint8_t)Kamstrup_List1Phase::ActiveImportPower);
reactiveImportPower = hanReader.getInt( (uint8_t)Kamstrup_List1Phase::ReactiveImportPower);
activeExportPower = hanReader.getInt( (uint8_t)Kamstrup_List1Phase::ActiveExportPower);
reactiveExportPower = hanReader.getInt( (uint8_t)Kamstrup_List1Phase::ReactiveExportPower);
l1current = ((float) hanReader.getInt((uint8_t)Kamstrup_List1Phase::CurrentL1)) / 100;
l1voltage = hanReader.getInt( (uint8_t)Kamstrup_List1Phase::VoltageL1);
break;
case (int)Kamstrup::List3PhaseLong:
meterTimestamp = hanReader.getTime( (int)Kamstrup_List3Phase::MeterClock, true, true);
activeImportCounter = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CumulativeActiveImportEnergy)) / 100;
activeExportCounter = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CumulativeActiveExportEnergy)) / 100;
reactiveImportCounter = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CumulativeReactiveImportEnergy)) / 100;
reactiveExportCounter = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CumulativeReactiveExportEnergy)) / 100;
case (int)Kamstrup::List3PhaseShort:
listId = hanReader.getString( (int)Kamstrup_List3Phase::ListVersionIdentifier);
meterId = hanReader.getString( (int)Kamstrup_List3Phase::MeterID);
meterType = hanReader.getString( (int)Kamstrup_List3Phase::MeterType);
activeImportPower = hanReader.getInt( (int)Kamstrup_List3Phase::ActiveImportPower);
reactiveImportPower = hanReader.getInt( (int)Kamstrup_List3Phase::ReactiveImportPower);
activeExportPower = hanReader.getInt( (int)Kamstrup_List3Phase::ActiveExportPower);
reactiveExportPower = hanReader.getInt( (int)Kamstrup_List3Phase::ReactiveExportPower);
l1current = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CurrentL1)) / 100;
l2current = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CurrentL2)) / 100;
l3current = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CurrentL3)) / 100;
l1voltage = hanReader.getInt( (int)Kamstrup_List3Phase::VoltageL1);
l2voltage = hanReader.getInt( (int)Kamstrup_List3Phase::VoltageL2);
l3voltage = hanReader.getInt( (int)Kamstrup_List3Phase::VoltageL3);
case (uint8_t)Kamstrup::List3PhaseLong:
meterTimestamp = hanReader.getTime( (uint8_t)Kamstrup_List3Phase::MeterClock, true, true);
activeImportCounter = ((float) hanReader.getInt((uint8_t)Kamstrup_List3Phase::CumulativeActiveImportEnergy)) / 100;
activeExportCounter = ((float) hanReader.getInt((uint8_t)Kamstrup_List3Phase::CumulativeActiveExportEnergy)) / 100;
reactiveImportCounter = ((float) hanReader.getInt((uint8_t)Kamstrup_List3Phase::CumulativeReactiveImportEnergy)) / 100;
reactiveExportCounter = ((float) hanReader.getInt((uint8_t)Kamstrup_List3Phase::CumulativeReactiveExportEnergy)) / 100;
case (uint8_t)Kamstrup::List3PhaseShort:
listId = hanReader.getString( (uint8_t)Kamstrup_List3Phase::ListVersionIdentifier);
meterId = hanReader.getString( (uint8_t)Kamstrup_List3Phase::MeterID);
meterType = hanReader.getString( (uint8_t)Kamstrup_List3Phase::MeterType);
activeImportPower = hanReader.getInt( (uint8_t)Kamstrup_List3Phase::ActiveImportPower);
reactiveImportPower = hanReader.getInt( (uint8_t)Kamstrup_List3Phase::ReactiveImportPower);
activeExportPower = hanReader.getInt( (uint8_t)Kamstrup_List3Phase::ActiveExportPower);
reactiveExportPower = hanReader.getInt( (uint8_t)Kamstrup_List3Phase::ReactiveExportPower);
l1current = ((float) hanReader.getInt((uint8_t)Kamstrup_List3Phase::CurrentL1)) / 100;
l2current = ((float) hanReader.getInt((uint8_t)Kamstrup_List3Phase::CurrentL2)) / 100;
l3current = ((float) hanReader.getInt((uint8_t)Kamstrup_List3Phase::CurrentL3)) / 100;
l1voltage = hanReader.getInt( (uint8_t)Kamstrup_List3Phase::VoltageL1);
l2voltage = hanReader.getInt( (uint8_t)Kamstrup_List3Phase::VoltageL2);
l3voltage = hanReader.getInt( (uint8_t)Kamstrup_List3Phase::VoltageL3);
break;
case (int)Kamstrup::List3PhaseITLong:
meterTimestamp = hanReader.getTime( (int)Kamstrup_List3Phase::MeterClock, true, true);
activeImportCounter = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CumulativeActiveImportEnergy)) / 100;
activeExportCounter = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CumulativeActiveExportEnergy)) / 100;
reactiveImportCounter = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CumulativeReactiveImportEnergy)) / 100;
reactiveExportCounter = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CumulativeReactiveExportEnergy)) / 100;
case (int)Kamstrup::List3PhaseITShort:
listId = hanReader.getString( (int)Kamstrup_List3Phase::ListVersionIdentifier);
meterId = hanReader.getString( (int)Kamstrup_List3Phase::MeterID);
meterType = hanReader.getString( (int)Kamstrup_List3Phase::MeterType);
activeImportPower = hanReader.getInt( (int)Kamstrup_List3Phase::ActiveImportPower);
reactiveImportPower = hanReader.getInt( (int)Kamstrup_List3Phase::ReactiveImportPower);
activeExportPower = hanReader.getInt( (int)Kamstrup_List3Phase::ActiveExportPower);
reactiveExportPower = hanReader.getInt( (int)Kamstrup_List3Phase::ReactiveExportPower);
l1current = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CurrentL1)) / 100;
case (uint8_t)Kamstrup::List3PhaseITLong:
meterTimestamp = hanReader.getTime( (uint8_t)Kamstrup_List3Phase::MeterClock, true, true);
activeImportCounter = ((float) hanReader.getInt((uint8_t)Kamstrup_List3Phase::CumulativeActiveImportEnergy)) / 100;
activeExportCounter = ((float) hanReader.getInt((uint8_t)Kamstrup_List3Phase::CumulativeActiveExportEnergy)) / 100;
reactiveImportCounter = ((float) hanReader.getInt((uint8_t)Kamstrup_List3Phase::CumulativeReactiveImportEnergy)) / 100;
reactiveExportCounter = ((float) hanReader.getInt((uint8_t)Kamstrup_List3Phase::CumulativeReactiveExportEnergy)) / 100;
case (uint8_t)Kamstrup::List3PhaseITShort:
listId = hanReader.getString( (uint8_t)Kamstrup_List3Phase::ListVersionIdentifier);
meterId = hanReader.getString( (uint8_t)Kamstrup_List3Phase::MeterID);
meterType = hanReader.getString( (uint8_t)Kamstrup_List3Phase::MeterType);
activeImportPower = hanReader.getInt( (uint8_t)Kamstrup_List3Phase::ActiveImportPower);
reactiveImportPower = hanReader.getInt( (uint8_t)Kamstrup_List3Phase::ReactiveImportPower);
activeExportPower = hanReader.getInt( (uint8_t)Kamstrup_List3Phase::ActiveExportPower);
reactiveExportPower = hanReader.getInt( (uint8_t)Kamstrup_List3Phase::ReactiveExportPower);
l1current = ((float) hanReader.getInt((uint8_t)Kamstrup_List3Phase::CurrentL1)) / 100;
l2current = 0;
l3current = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CurrentL3)) / 100;
l1voltage = hanReader.getInt( (int)Kamstrup_List3Phase::VoltageL1);
l2voltage = hanReader.getInt( (int)Kamstrup_List3Phase::VoltageL2);
l3voltage = hanReader.getInt( (int)Kamstrup_List3Phase::VoltageL3);
l3current = ((float) hanReader.getInt((uint8_t)Kamstrup_List3Phase::CurrentL3)) / 100;
l1voltage = hanReader.getInt( (uint8_t)Kamstrup_List3Phase::VoltageL1);
l2voltage = hanReader.getInt( (uint8_t)Kamstrup_List3Phase::VoltageL2);
l3voltage = hanReader.getInt( (uint8_t)Kamstrup_List3Phase::VoltageL3);
if(substituteMissing) {
l2current = (((activeImportPower - activeExportPower) * sqrt(3)) - (l1voltage * l1current) - (l3voltage * l3current)) / l2voltage;
}
@@ -261,25 +261,25 @@ void AmsData::extractFromKamstrup(HanReader& hanReader, int listSize, bool subst
}
}
void AmsData::extractFromOmnipower(HanReader& hanReader, int listSize) {
void AmsData::extractFromOmnipower(HanReader& hanReader, uint8_t listSize) {
switch(listSize) {
case (int)Omnipower::DLMS:
meterTimestamp = hanReader.getTime( (int)Omnipower_DLMS::MeterClock, true, true);
activeImportCounter = ((double) hanReader.getInt((int)Omnipower_DLMS::CumulativeActiveImportEnergy)) / 100;
activeExportCounter = ((double) hanReader.getInt((int)Omnipower_DLMS::CumulativeActiveExportEnergy)) / 100;
reactiveImportCounter = ((double) hanReader.getInt((int)Omnipower_DLMS::CumulativeReactiveImportEnergy)) / 100;
reactiveExportCounter = ((double) hanReader.getInt((int)Omnipower_DLMS::CumulativeReactiveExportEnergy)) / 100;
listId = hanReader.getString( (int)Omnipower_DLMS::ListVersionIdentifier);
activeImportPower = hanReader.getInt( (int)Omnipower_DLMS::ActiveImportPower);
reactiveImportPower = hanReader.getInt( (int)Omnipower_DLMS::ReactiveImportPower);
activeExportPower = hanReader.getInt( (int)Omnipower_DLMS::ActiveExportPower);
reactiveExportPower = hanReader.getInt( (int)Omnipower_DLMS::ReactiveExportPower);
l1current = ((double) hanReader.getInt((int)Omnipower_DLMS::CurrentL1)) / 100;
l2current = ((double) hanReader.getInt((int)Omnipower_DLMS::CurrentL2)) / 100;
l3current = ((double) hanReader.getInt((int)Omnipower_DLMS::CurrentL3)) / 100;
l1voltage = hanReader.getInt( (int)Omnipower_DLMS::VoltageL1);
l2voltage = hanReader.getInt( (int)Omnipower_DLMS::VoltageL2);
l3voltage = hanReader.getInt( (int)Omnipower_DLMS::VoltageL3);
case (uint8_t)Omnipower::DLMS:
meterTimestamp = hanReader.getTime( (uint8_t)Omnipower_DLMS::MeterClock, true, true);
activeImportCounter = ((float) hanReader.getInt((uint8_t)Omnipower_DLMS::CumulativeActiveImportEnergy)) / 100;
activeExportCounter = ((float) hanReader.getInt((uint8_t)Omnipower_DLMS::CumulativeActiveExportEnergy)) / 100;
reactiveImportCounter = ((float) hanReader.getInt((uint8_t)Omnipower_DLMS::CumulativeReactiveImportEnergy)) / 100;
reactiveExportCounter = ((float) hanReader.getInt((uint8_t)Omnipower_DLMS::CumulativeReactiveExportEnergy)) / 100;
listId = hanReader.getString( (uint8_t)Omnipower_DLMS::ListVersionIdentifier);
activeImportPower = hanReader.getInt( (uint8_t)Omnipower_DLMS::ActiveImportPower);
reactiveImportPower = hanReader.getInt( (uint8_t)Omnipower_DLMS::ReactiveImportPower);
activeExportPower = hanReader.getInt( (uint8_t)Omnipower_DLMS::ActiveExportPower);
reactiveExportPower = hanReader.getInt( (uint8_t)Omnipower_DLMS::ReactiveExportPower);
l1current = ((float) hanReader.getInt((uint8_t)Omnipower_DLMS::CurrentL1)) / 100;
l2current = ((float) hanReader.getInt((uint8_t)Omnipower_DLMS::CurrentL2)) / 100;
l3current = ((float) hanReader.getInt((uint8_t)Omnipower_DLMS::CurrentL3)) / 100;
l1voltage = hanReader.getInt( (uint8_t)Omnipower_DLMS::VoltageL1);
l2voltage = hanReader.getInt( (uint8_t)Omnipower_DLMS::VoltageL2);
l3voltage = hanReader.getInt( (uint8_t)Omnipower_DLMS::VoltageL3);
listType = 3;
break;
}
@@ -292,28 +292,24 @@ void AmsData::apply(AmsData& other) {
if(ms > 0) {
if(other.getActiveImportPower() > 0)
activeImportCounter += (((double) ms) * other.getActiveImportPower()) / 3600000000;
counterEstimated = true;
}
activeImportCounter += (((float) ms) * other.getActiveImportPower()) / 3600000000;
if(other.getListType() > 1) {
unsigned long ms2 = this->lastList2UpdateMillis > other.getLastUpdateMillis() ? 0 : other.getLastUpdateMillis() - this->lastList2UpdateMillis;
if(ms2 > 0) {
// Not sure why, but I cannot make these numbers correct. It seems to be double of what it should, so dividing it by two...
if(other.getListType() > 1) {
if(other.getActiveExportPower() > 0)
activeExportCounter += (((double) ms2/2) * other.getActiveExportPower()) / 3600000000;
activeExportCounter += (((float) ms*2) * other.getActiveExportPower()) / 3600000000;
if(other.getReactiveImportPower() > 0)
reactiveImportCounter += (((double) ms2/2) * other.getReactiveImportPower()) / 3600000000;
reactiveImportCounter += (((float) ms*2) * other.getReactiveImportPower()) / 3600000000;
if(other.getReactiveExportPower() > 0)
reactiveExportCounter += (((double) ms2/2) * other.getReactiveExportPower()) / 3600000000;
counterEstimated = true;
reactiveExportCounter += (((float) ms*2) * other.getReactiveExportPower()) / 3600000000;
}
counterEstimated = true;
}
}
this->lastUpdateMillis = other.getLastUpdateMillis();
this->packageTimestamp = other.getPackageTimestamp();
this->listType = max(this->listType, other.getListType());
if(other.getListType() > this->listType)
this->listType = other.getListType();
switch(other.getListType()) {
case 3:
this->meterTimestamp = other.getMeterTimestamp();
@@ -336,7 +332,6 @@ void AmsData::apply(AmsData& other) {
this->l2voltage = other.getL2Voltage();
this->l3voltage = other.getL3Voltage();
this->threePhase = other.isThreePhase();
this->lastList2UpdateMillis = other.getLastUpdateMillis();
case 1:
this->activeImportPower = other.getActiveImportPower();
}
@@ -346,11 +341,11 @@ unsigned long AmsData::getLastUpdateMillis() {
return this->lastUpdateMillis;
}
unsigned long AmsData::getPackageTimestamp() {
time_t AmsData::getPackageTimestamp() {
return this->packageTimestamp;
}
int AmsData::getListType() {
uint8_t AmsData::getListType() {
return this->listType;
}
@@ -366,63 +361,63 @@ String AmsData::getMeterType() {
return this->meterType;
}
unsigned long AmsData::getMeterTimestamp() {
time_t AmsData::getMeterTimestamp() {
return this->meterTimestamp;
}
int AmsData::getActiveImportPower() {
uint16_t AmsData::getActiveImportPower() {
return this->activeImportPower;
}
int AmsData::getReactiveImportPower() {
uint16_t AmsData::getReactiveImportPower() {
return this->reactiveImportPower;
}
int AmsData::getActiveExportPower() {
uint16_t AmsData::getActiveExportPower() {
return this->activeExportPower;
}
int AmsData::getReactiveExportPower() {
uint16_t AmsData::getReactiveExportPower() {
return this->reactiveExportPower;
}
double AmsData::getL1Voltage() {
float AmsData::getL1Voltage() {
return this->l1voltage;
}
double AmsData::getL2Voltage() {
float AmsData::getL2Voltage() {
return this->l2voltage;
}
double AmsData::getL3Voltage() {
float AmsData::getL3Voltage() {
return this->l3voltage;
}
double AmsData::getL1Current() {
float AmsData::getL1Current() {
return this->l1current;
}
double AmsData::getL2Current() {
float AmsData::getL2Current() {
return this->l2current;
}
double AmsData::getL3Current() {
float AmsData::getL3Current() {
return this->l3current;
}
double AmsData::getActiveImportCounter() {
float AmsData::getActiveImportCounter() {
return this->activeImportCounter;
}
double AmsData::getReactiveImportCounter() {
float AmsData::getReactiveImportCounter() {
return this->reactiveImportCounter;
}
double AmsData::getActiveExportCounter() {
float AmsData::getActiveExportCounter() {
return this->activeExportCounter;
}
double AmsData::getReactiveExportCounter() {
float AmsData::getReactiveExportCounter() {
return this->reactiveExportCounter;
}

View File

@@ -13,58 +13,57 @@
class AmsData {
public:
AmsData();
AmsData(int meterType, bool substituteMissing, HanReader& hanReader);
AmsData(uint8_t meterType, bool substituteMissing, HanReader& hanReader);
void apply(AmsData& other);
unsigned long getLastUpdateMillis();
unsigned long getPackageTimestamp();
time_t getPackageTimestamp();
int getListType();
uint8_t getListType();
String getListId();
String getMeterId();
String getMeterType();
unsigned long getMeterTimestamp();
time_t getMeterTimestamp();
int getActiveImportPower();
int getReactiveImportPower();
int getActiveExportPower();
int getReactiveExportPower();
uint16_t getActiveImportPower();
uint16_t getReactiveImportPower();
uint16_t getActiveExportPower();
uint16_t getReactiveExportPower();
double getL1Voltage();
double getL2Voltage();
double getL3Voltage();
float getL1Voltage();
float getL2Voltage();
float getL3Voltage();
double getL1Current();
double getL2Current();
double getL3Current();
float getL1Current();
float getL2Current();
float getL3Current();
double getActiveImportCounter();
double getReactiveImportCounter();
double getActiveExportCounter();
double getReactiveExportCounter();
float getActiveImportCounter();
float getReactiveImportCounter();
float getActiveExportCounter();
float getReactiveExportCounter();
bool isThreePhase();
private:
unsigned long lastUpdateMillis = 0;
unsigned long lastList2UpdateMillis = 0;
int listType = 0;
unsigned long packageTimestamp = 0;
uint8_t listType = 0;
time_t packageTimestamp = 0;
String listId, meterId, meterType;
unsigned long meterTimestamp = 0;
int activeImportPower = 0, reactiveImportPower = 0, activeExportPower = 0, reactiveExportPower = 0;
double l1voltage = 0, l2voltage = 0, l3voltage = 0, l1current = 0, l2current = 0, l3current = 0;
double activeImportCounter = 0, reactiveImportCounter = 0, activeExportCounter = 0, reactiveExportCounter = 0;
time_t meterTimestamp = 0;
uint16_t activeImportPower = 0, reactiveImportPower = 0, activeExportPower = 0, reactiveExportPower = 0;
float l1voltage = 0, l2voltage = 0, l3voltage = 0, l1current = 0, l2current = 0, l3current = 0;
float activeImportCounter = 0, reactiveImportCounter = 0, activeExportCounter = 0, reactiveExportCounter = 0;
bool threePhase = false, counterEstimated = false;
void extractFromKaifa(HanReader& hanReader, int listSize);
void extractFromAidon(HanReader& hanReader, int listSize, bool substituteMissing);
void extractFromKamstrup(HanReader& hanReader, int listSize, bool substituteMissing);
void extractFromOmnipower(HanReader& hanReader, int listSize);
void extractFromKaifa(HanReader& hanReader, uint8_t listSize);
void extractFromAidon(HanReader& hanReader, uint8_t listSize, bool substituteMissing);
void extractFromKamstrup(HanReader& hanReader, uint8_t listSize, bool substituteMissing);
void extractFromOmnipower(HanReader& hanReader, uint8_t listSize);
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,56 +1,69 @@
#include "HwTools.h"
void HwTools::setTempSensorPin(int tempSensorPin) {
if(tempSensorPin != this->tempSensorPin) {
this->tempSensorInit = false;
if(sensorApi)
delete sensorApi;
if(oneWire)
delete oneWire;
if(tempSensorPin > 0 && tempSensorPin < 40) {
this->tempSensorPin = tempSensorPin;
pinMode(tempSensorPin, INPUT);
} else {
this->tempSensorPin = 0xFF;
}
}
}
void HwTools::setTempAnalogSensorPin(int tempAnalogSensorPin) {
if(tempAnalogSensorPin != this->tempAnalogSensorPin) {
if(tempAnalogSensorPin > 0 && tempAnalogSensorPin < 40) {
this->tempAnalogSensorPin = tempAnalogSensorPin;
pinMode(tempAnalogSensorPin, INPUT);
} else {
this->tempAnalogSensorPin = 0xFF;
}
}
}
void HwTools::setVccPin(int vccPin) {
if(vccPin > 0 && vccPin < 40) {
pinMode(vccPin, INPUT);
this->vccPin = vccPin;
void HwTools::setup(GpioConfig* config, AmsConfiguration* amsConf) {
this->config = config;
this->amsConf = amsConf;
this->tempSensorInit = false;
if(this->tempSensors == NULL)
this->tempSensors = new TempSensorData*[32];
if(sensorApi != NULL)
delete sensorApi;
if(oneWire != NULL)
delete oneWire;
if(config->tempSensorPin > 0 && config->tempSensorPin < 40) {
pinMode(config->tempSensorPin, INPUT);
} else {
this->vccPin = 0xFF;
config->tempSensorPin = 0xFF;
}
}
void HwTools::setVccOffset(double vccOffset) {
this->vccOffset = vccOffset;
}
if(config->tempAnalogSensorPin > 0 && config->tempAnalogSensorPin < 40) {
pinMode(config->tempAnalogSensorPin, INPUT);
} else {
config->tempAnalogSensorPin = 0xFF;
}
void HwTools::setVccMultiplier(double vccMultiplier) {
this->vccMultiplier = vccMultiplier;
if(config->vccPin > 0 && config->vccPin < 40) {
pinMode(config->vccPin, INPUT);
} else {
config->vccPin = 0xFF;
}
if(config->ledPin > 0 && config->ledPin < 40) {
pinMode(config->ledPin, OUTPUT);
ledOff(LED_INTERNAL);
} else {
config->ledPin = 0xFF;
}
if(config->ledPinRed > 0 && config->ledPinRed < 40) {
pinMode(config->ledPinRed, OUTPUT);
ledOff(LED_RED);
} else {
config->ledPinRed = 0xFF;
}
if(config->ledPinGreen > 0 && config->ledPinGreen < 40) {
pinMode(config->ledPinGreen, OUTPUT);
ledOff(LED_GREEN);
} else {
config->ledPinGreen = 0xFF;
}
if(config->ledPinBlue > 0 && config->ledPinBlue < 40) {
pinMode(config->ledPinBlue, OUTPUT);
ledOff(LED_BLUE);
} else {
config->ledPinBlue = 0xFF;
}
}
double HwTools::getVcc() {
double volts = 0.0;
if(vccPin != 0xFF) {
if(config->vccPin != 0xFF) {
#if defined(ESP8266)
volts = (analogRead(vccPin) / 1024.0) * 3.3;
volts = (analogRead(config->vccPin) / 1024.0) * 3.3;
#elif defined(ESP32)
volts = (analogRead(vccPin) / 4095.0) * 3.3;
volts = (analogRead(config->vccPin) / 4095.0) * 3.3;
#endif
} else {
#if defined(ESP8266)
@@ -58,31 +71,11 @@ double HwTools::getVcc() {
#endif
}
float vccOffset = config->vccOffset / 100.0;
float vccMultiplier = config->vccMultiplier / 1000.0;
return vccOffset + (volts > 0.0 ? volts * vccMultiplier : 0.0);
}
void HwTools::confTempSensor(uint8_t address[8], const char name[32], bool common) {
bool found = false;
for(int x = 0; x < sensorCount; x++) {
TempSensorData *data = tempSensors[x];
if(isSensorAddressEqual(data->address, address)) {
found = true;
strcpy(data->name, name);
data->common = common;
}
}
if(!found) {
TempSensorData *data = new TempSensorData();
memcpy(data->address, address, 8);
strcpy(data->name, name);
data->common = common;
data->lastRead = DEVICE_DISCONNECTED_C;
data->lastValidRead = DEVICE_DISCONNECTED_C;
tempSensors[sensorCount] = data;
sensorCount++;
}
}
uint8_t HwTools::getTempSensorCount() {
return sensorCount;
}
@@ -92,9 +85,9 @@ TempSensorData* HwTools::getTempSensorData(uint8_t i) {
}
bool HwTools::updateTemperatures() {
if(tempSensorPin != 0xFF) {
if(config->tempSensorPin != 0xFF) {
if(!tempSensorInit) {
oneWire = new OneWire(tempSensorPin);
oneWire = new OneWire(config->tempSensorPin);
sensorApi = new DallasTemperature(this->oneWire);
sensorApi->begin();
delay(100);
@@ -120,14 +113,12 @@ bool HwTools::updateTemperatures() {
if(!found) {
TempSensorData *data = new TempSensorData();
memcpy(data->address, addr, 8);
data->common = true;
data->lastRead = t;
if(t > -85) {
data->lastValidRead = t;
}
tempSensors[sensorCount] = data;
sensorCount++;
tempSensors[sensorCount++] = data;
}
delay(10);
}
@@ -166,7 +157,8 @@ double HwTools::getTemperature() {
}
for(int x = 0; x < sensorCount; x++) {
TempSensorData data = *tempSensors[x];
if(data.common && data.lastValidRead > -85) {
TempSensorConfig* conf = amsConf->getTempSensorConfig(data.address);
if((conf == NULL || conf->common) && data.lastValidRead > -85) {
ret += data.lastValidRead;
c++;
}
@@ -174,13 +166,13 @@ double HwTools::getTemperature() {
return c == 0 ? DEVICE_DISCONNECTED_C : ret/c;
}
double HwTools::getTemperatureAnalog() {
if(tempAnalogSensorPin != 0xFF) {
if(config->tempAnalogSensorPin != 0xFF) {
float adcCalibrationFactor = 1.06587;
int volts;
#if defined(ESP8266)
volts = (analogRead(tempAnalogSensorPin) / 1024.0) * 3.3;
volts = (analogRead(config->tempAnalogSensorPin) / 1024.0) * 3.3;
#elif defined(ESP32)
volts = (analogRead(tempAnalogSensorPin) / 4095.0) * 3.3;
volts = (analogRead(config->tempAnalogSensorPin) / 4095.0) * 3.3;
#endif
return ((volts * adcCalibrationFactor) - 0.4) / 0.0195;
}
@@ -192,55 +184,19 @@ int HwTools::getWifiRssi() {
return isnan(rssi) ? -100.0 : rssi;
}
void HwTools::setLed(uint8_t ledPin, bool ledInverted) {
if(ledPin > 0 && ledPin < 40) {
this->ledPin = ledPin;
this->ledInverted = ledInverted;
pinMode(ledPin, OUTPUT);
ledOff(LED_INTERNAL);
} else {
this->ledPin = 0xFF;
}
}
void HwTools::setLedRgb(uint8_t ledPinRed, uint8_t ledPinGreen, uint8_t ledPinBlue, bool ledRgbInverted) {
this->ledRgbInverted = ledRgbInverted;
if(ledPinRed > 0 && ledPinRed < 40) {
this->ledPinRed = ledPinRed;
pinMode(ledPinRed, OUTPUT);
ledOff(LED_RED);
} else {
this->ledPinRed = 0xFF;
}
if(ledPinGreen > 0 && ledPinGreen < 40) {
this->ledPinGreen = ledPinGreen;
pinMode(ledPinGreen, OUTPUT);
ledOff(LED_GREEN);
} else {
this->ledPinGreen = 0xFF;
}
if(ledPinBlue > 0 && ledPinBlue < 40) {
this->ledPinBlue = ledPinBlue;
pinMode(ledPinBlue, OUTPUT);
ledOff(LED_BLUE);
} else {
this->ledPinBlue = 0xFF;
}
}
bool HwTools::ledOn(uint8_t color) {
if(color == LED_INTERNAL) {
return writeLedPin(color, ledInverted ? LOW : HIGH);
return writeLedPin(color, config->ledInverted ? LOW : HIGH);
} else {
return writeLedPin(color, ledRgbInverted ? LOW : HIGH);
return writeLedPin(color, config->ledRgbInverted ? LOW : HIGH);
}
}
bool HwTools::ledOff(uint8_t color) {
if(color == LED_INTERNAL) {
return writeLedPin(color, ledInverted ? HIGH : LOW);
return writeLedPin(color, config->ledInverted ? HIGH : LOW);
} else {
return writeLedPin(color, ledRgbInverted ? HIGH : LOW);
return writeLedPin(color, config->ledRgbInverted ? HIGH : LOW);
}
}
@@ -256,47 +212,52 @@ bool HwTools::ledBlink(uint8_t color, uint8_t blink) {
bool HwTools::writeLedPin(uint8_t color, uint8_t state) {
switch(color) {
case LED_INTERNAL:
if(ledPin != 0xFF) {
digitalWrite(ledPin, state);
case LED_INTERNAL: {
if(config->ledPin != 0xFF) {
digitalWrite(config->ledPin, state);
return true;
} else {
return false;
}
break;
case LED_RED:
if(ledPinRed != 0xFF) {
digitalWrite(ledPinRed, state);
}
case LED_RED: {
if(config->ledPinRed != 0xFF) {
digitalWrite(config->ledPinRed, state);
return true;
} else {
return false;
}
break;
case LED_GREEN:
if(ledPinGreen != 0xFF) {
digitalWrite(ledPinGreen, state);
}
case LED_GREEN: {
if(config->ledPinGreen != 0xFF) {
digitalWrite(config->ledPinGreen, state);
return true;
} else {
return false;
}
break;
case LED_BLUE:
if(ledPinBlue != 0xFF) {
digitalWrite(ledPinBlue, state);
}
case LED_BLUE: {
if(config->ledPinBlue != 0xFF) {
digitalWrite(config->ledPinBlue, state);
return true;
} else {
return false;
}
break;
case LED_YELLOW:
if(ledPinRed != 0xFF && ledPinGreen != 0xFF) {
digitalWrite(ledPinRed, state);
digitalWrite(ledPinGreen, state);
}
case LED_YELLOW: {
if(config->ledPinRed != 0xFF && config->ledPinGreen != 0xFF) {
digitalWrite(config->ledPinRed, state);
digitalWrite(config->ledPinGreen, state);
return true;
} else {
return false;
}
break;
}
}
return false;
}

View File

@@ -11,6 +11,7 @@
#include <DallasTemperature.h>
#include <OneWire.h>
#include "AmsConfiguration.h"
#define LED_INTERNAL 0
#define LED_RED 1
@@ -20,48 +21,34 @@
struct TempSensorData {
uint8_t address[8];
char name[32];
bool common;
float lastRead;
float lastValidRead;
};
class HwTools {
public:
void setTempSensorPin(int tempSensorPin);
void setTempAnalogSensorPin(int tempAnalogSensorPin);
void setVccPin(int vccPin);
void setVccOffset(double vccOffset);
void setVccMultiplier(double vccMultiplier);
void setup(GpioConfig*, AmsConfiguration*);
double getVcc();
void confTempSensor(uint8_t address[8], const char name[32], bool common);
uint8_t getTempSensorCount();
TempSensorData* getTempSensorData(uint8_t i);
TempSensorData* getTempSensorData(uint8_t);
bool updateTemperatures();
double getTemperature();
double getTemperatureAnalog();
double getTemperature(uint8_t address[8]);
int getWifiRssi();
void setLed(uint8_t ledPin, bool ledInverted);
void setLedRgb(uint8_t ledPinRed, uint8_t ledPinGreen, uint8_t ledPinBlue, bool ledRgbInverted);
bool ledOn(uint8_t color);
bool ledOff(uint8_t color);
bool ledBlink(uint8_t color, uint8_t blink);
HwTools() {};
private:
uint8_t tempSensorPin = 0xFF, tempAnalogSensorPin = 0xFF;
uint8_t vccPin = 0xFF;
uint8_t ledPin = 0xFF, ledPinRed = 0xFF, ledPinGreen = 0xFF, ledPinBlue = 0xFF;
bool ledInverted, ledRgbInverted;
double vccOffset = 0.0;
double vccMultiplier = 1.0;
GpioConfig* config;
AmsConfiguration* amsConf;
bool tempSensorInit;
OneWire *oneWire;
DallasTemperature *sensorApi;
OneWire *oneWire = NULL;
DallasTemperature *sensorApi = NULL;
uint8_t sensorCount = 0;
TempSensorData *tempSensors[32];
TempSensorData** tempSensors = NULL;
bool writeLedPin(uint8_t color, uint8_t state);
bool isSensorAddressEqual(uint8_t a[8], uint8_t b[8]);

View File

@@ -1,7 +1,7 @@
#include "DnbCurrParser.h"
#include "HardwareSerial.h"
double DnbCurrParser::getValue() {
float DnbCurrParser::getValue() {
return value;
}
@@ -49,7 +49,7 @@ size_t DnbCurrParser::write(uint8_t byte) {
break;
}
}
value = String(buf+pos).toDouble();
value = String(buf+pos).toFloat();
}
pos = 0;
} else {

View File

@@ -5,7 +5,7 @@
class DnbCurrParser: public Stream {
public:
double getValue();
float getValue();
int available();
int read();
@@ -15,9 +15,9 @@ public:
size_t write(uint8_t);
private:
double value = 1.0;
float value = 1.0;
char buf[256];
char buf[64];
uint8_t pos = 0;
uint8_t mode = 0;
};

View File

@@ -13,7 +13,7 @@ char* EntsoeA44Parser::getMeasurementUnit() {
return measurementUnit;
}
double EntsoeA44Parser::getPoint(uint8_t position) {
float EntsoeA44Parser::getPoint(uint8_t position) {
return points[position];
}
@@ -69,7 +69,7 @@ size_t EntsoeA44Parser::write(uint8_t byte) {
} else if(docPos == DOCPOS_AMOUNT) {
if(byte == '<') {
buf[pos] = '\0';
points[pointNum] = String(buf).toDouble();
points[pointNum] = String(buf).toFloat();
docPos = DOCPOS_SEEK;
pos = 0;
} else {

View File

@@ -15,7 +15,7 @@ public:
char* getCurrency();
char* getMeasurementUnit();
double getPoint(uint8_t position);
float getPoint(uint8_t position);
int available();
int read();
@@ -27,9 +27,9 @@ public:
private:
char currency[4];
char measurementUnit[4];
double points[24];
float points[24];
char buf[256];
char buf[64];
uint8_t pos = 0;
uint8_t docPos = 0;
uint8_t pointNum = 0;

View File

@@ -21,31 +21,23 @@ EntsoeApi::EntsoeApi(RemoteDebug* Debug) {
tz = new Timezone(CEST, CET);
}
void EntsoeApi::setToken(const char* token) {
strcpy(this->token, token);
void EntsoeApi::setup(EntsoeConfig& config) {
if(this->config == NULL) {
this->config = new EntsoeConfig();
}
memcpy(this->config, &config, sizeof(config));
}
void EntsoeApi::setArea(const char* area) {
strcpy(this->area, area);
char* EntsoeApi::getToken() {
return this->config->token;
}
void EntsoeApi::setCurrency(const char* currency) {
strcpy(this->currency, currency);
}
void EntsoeApi::setMultiplier(double multiplier) {
this->multiplier = multiplier;
}
char* EntsoeApi::getCurrency() {
return currency;
}
double EntsoeApi::getValueForHour(int hour) {
float EntsoeApi::getValueForHour(uint8_t hour) {
time_t cur = time(nullptr);
return getValueForHour(cur, hour);
}
double EntsoeApi::getValueForHour(time_t cur, int hour) {
float EntsoeApi::getValueForHour(time_t cur, uint8_t hour) {
tmElements_t tm;
if(tz != NULL)
cur = tz->toLocal(cur);
@@ -55,7 +47,7 @@ double EntsoeApi::getValueForHour(time_t cur, int hour) {
return ENTSOE_NO_VALUE;
double value = ENTSOE_NO_VALUE;
double multiplier = this->multiplier;
double multiplier = config->multiplier / 1000.0;
if(pos > 23) {
if(tomorrow == NULL)
return ENTSOE_NO_VALUE;
@@ -65,7 +57,7 @@ double EntsoeApi::getValueForHour(time_t cur, int hour) {
} else {
return ENTSOE_NO_VALUE;
}
multiplier *= getCurrencyMultiplier(tomorrow->getCurrency(), currency);
multiplier *= getCurrencyMultiplier(tomorrow->getCurrency(), config->currency);
} else {
if(today == NULL)
return ENTSOE_NO_VALUE;
@@ -75,13 +67,13 @@ double EntsoeApi::getValueForHour(time_t cur, int hour) {
} else {
return ENTSOE_NO_VALUE;
}
multiplier *= getCurrencyMultiplier(today->getCurrency(), currency);
multiplier *= getCurrencyMultiplier(today->getCurrency(), config->currency);
}
return value * multiplier;
}
bool EntsoeApi::loop() {
if(strlen(token) == 0)
if(strlen(config->token) == 0)
return false;
bool ret = false;
@@ -116,10 +108,10 @@ bool EntsoeApi::loop() {
char url[256];
snprintf(url, sizeof(url), "%s?securityToken=%s&documentType=A44&periodStart=%04d%02d%02d%02d%02d&periodEnd=%04d%02d%02d%02d%02d&in_Domain=%s&out_Domain=%s",
"https://transparency.entsoe.eu/api", token,
"https://transparency.entsoe.eu/api", config->token,
d1.Year+1970, d1.Month, d1.Day, 23, 00,
d2.Year+1970, d2.Month, d2.Day, 23, 00,
area, area);
config->area, config->area);
printD("Fetching prices for today");
printD(url);
@@ -146,10 +138,10 @@ bool EntsoeApi::loop() {
char url[256];
snprintf(url, sizeof(url), "%s?securityToken=%s&documentType=A44&periodStart=%04d%02d%02d%02d%02d&periodEnd=%04d%02d%02d%02d%02d&in_Domain=%s&out_Domain=%s",
"https://transparency.entsoe.eu/api", token,
"https://transparency.entsoe.eu/api", config->token,
d1.Year+1970, d1.Month, d1.Day, 23, 00,
d2.Year+1970, d2.Month, d2.Day, 23, 00,
area, area);
config->area, config->area);
printD("Fetching prices for tomorrow");
printD(url);
@@ -169,8 +161,9 @@ bool EntsoeApi::loop() {
bool EntsoeApi::retrieve(const char* url, Stream* doc) {
WiFiClientSecure client;
#if defined(ESP8266)
client.setBufferSizes(512, 512);
client.setBufferSizes(SSL_BUF_SIZE, SSL_BUF_SIZE);
client.setInsecure();
client.setX509Time(time(nullptr));
#endif
HTTPClient https;
@@ -191,8 +184,8 @@ bool EntsoeApi::retrieve(const char* url, Stream* doc) {
printD(https.getString());
#if defined(ESP8266)
char buf[256];
client.getLastSSLError(buf,256);
char buf[64];
client.getLastSSLError(buf,64);
printE(buf);
#endif
@@ -201,53 +194,32 @@ bool EntsoeApi::retrieve(const char* url, Stream* doc) {
}
} else {
#if defined(ESP8266)
char buf[256];
client.getLastSSLError(buf,256);
char buf[64];
client.getLastSSLError(buf,64);
printE(buf);
#endif
return false;
}
client.stop();
}
double EntsoeApi::getCurrencyMultiplier(const char* from, const char* to) {
float EntsoeApi::getCurrencyMultiplier(const char* from, const char* to) {
if(strcmp(from, to) == 0)
return 1.00;
uint64_t now = millis64();
if(lastCurrencyFetch == 0 || now - lastCurrencyFetch > (SECS_PER_HOUR * 1000)) {
WiFiClientSecure client;
#if defined(ESP8266)
client.setBufferSizes(512, 512);
client.setInsecure();
#endif
HTTPClient https;
#if defined(ESP8266)
https.setFollowRedirects(true);
#endif
char url[256];
snprintf(url, sizeof(url), "https://data.norges-bank.no/api/data/EXR/M.%s.%s.SP?lastNObservations=1",
from,
to
);
if(https.begin(client, url)) {
int status = https.GET();
if(status == HTTP_CODE_OK) {
DnbCurrParser p;
https.writeToStream(&p);
currencyMultiplier = p.getValue();
} else {
printE("Communication error: ");
printE(https.errorToString(status));
printI(url);
printD(https.getString());
}
lastCurrencyFetch = now;
https.end();
} else {
return false;
DnbCurrParser p;
if(retrieve(url, &p)) {
currencyMultiplier = p.getValue();
}
lastCurrencyFetch = now;
}
return currencyMultiplier;
}

View File

@@ -5,27 +5,25 @@
#include "Timezone.h"
#include "RemoteDebug.h"
#include "EntsoeA44Parser.h"
#include "AmsConfiguration.h"
#define ENTSOE_NO_VALUE -127
#define ENTSOE_DEFAULT_MULTIPLIER 1.00
#define SSL_BUF_SIZE 512
class EntsoeApi {
public:
EntsoeApi(RemoteDebug* Debug);
EntsoeApi(RemoteDebug*);
void setup(EntsoeConfig&);
bool loop();
double getValueForHour(int hour);
double getValueForHour(time_t now, int hour);
char* getCurrency();
void setToken(const char* token);
void setArea(const char* area);
void setCurrency(const char* currency);
void setMultiplier(double multiplier);
char* getToken();
float getValueForHour(uint8_t);
float getValueForHour(time_t, uint8_t);
private:
RemoteDebug* debugger;
char token[37]; // UUID + null terminator
EntsoeConfig* config = NULL;
uint64_t midnightMillis = 0;
uint64_t lastTodayFetch = 0;
@@ -36,13 +34,10 @@ private:
Timezone* tz = NULL;
char area[32];
char currency[4];
double multiplier = ENTSOE_DEFAULT_MULTIPLIER;
double currencyMultiplier = ENTSOE_DEFAULT_MULTIPLIER;
float currencyMultiplier = ENTSOE_DEFAULT_MULTIPLIER;
bool retrieve(const char* url, Stream* doc);
double getCurrencyMultiplier(const char* from, const char* to);
float getCurrencyMultiplier(const char* from, const char* to);
void printD(String fmt, ...);
void printI(String fmt, ...);

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,7 @@
#define BOOTSTRAP_URL "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css"
#include "Arduino.h"
#include <MQTT.h>
#include <ArduinoJson.h>
#include "AmsConfiguration.h"
@@ -12,12 +13,6 @@
#include "RemoteDebug.h"
#include "entsoe/EntsoeApi.h"
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
@@ -27,7 +22,6 @@
#include <WebServer.h>
#include <HTTPClient.h>
#include "SPIFFS.h"
#include "Update.h"
#else
#warning "Unsupported board type"
#endif
@@ -35,19 +29,22 @@
class AmsWebServer {
public:
AmsWebServer(RemoteDebug* Debug, HwTools* hw, EntsoeApi* eapi);
void setup(AmsConfiguration* config, MQTTClient* mqtt);
void setup(AmsConfiguration*, GpioConfig*, MeterConfig*, AmsData*, MQTTClient*);
void loop();
void setData(AmsData& data);
void setTimezone(Timezone* tz);
private:
RemoteDebug* debugger;
bool mqttEnabled = false;
int maxPwr = 0;
HwTools* hw;
Timezone* tz;
EntsoeApi* eapi;
AmsConfiguration* config;
AmsData data;
AmsConfiguration* config;
GpioConfig* gpioConfig;
MeterConfig* meterConfig;
WebConfig webConfig;
AmsData* meterState;
MQTTClient* mqtt;
bool uploading = false;
File file;