Restructuring to be able to include precompiled kmp lib

This commit is contained in:
Gunnar Skjold
2024-07-11 13:15:22 +02:00
parent 4407526d96
commit 8a4efd0047
32 changed files with 105 additions and 25 deletions

View File

@@ -0,0 +1,24 @@
/**
* @copyright Utilitech AS 2023
* License: Fair Source
*
*/
#ifndef _IEC62056_21_H
#define _IEC62056_21_H
#include "Arduino.h"
#include "AmsData.h"
#include "Timezone.h"
#include "AmsConfiguration.h"
class IEC6205621 : public AmsData {
public:
IEC6205621(const char* payload, Timezone* tz, MeterConfig* meterConfig);
private:
String extract(String payload, String obis);
double extractDouble(String payload, String obis);
float extractFloat(String payload, String obis);
};
#endif

View File

@@ -0,0 +1,74 @@
/**
* @copyright Utilitech AS 2023
* License: Fair Source
*
*/
#ifndef _IEC62056_7_5_H
#define _IEC62056_7_5_H
#include "AmsData.h"
#include "AmsConfiguration.h"
#include "DataParser.h"
#include "Cosem.h"
#define NOVALUE 0xFFFFFFFF
struct AmsOctetTimestamp {
uint8_t type;
CosemDateTime dt;
} __attribute__((packed));
class IEC6205675 : public AmsData {
public:
IEC6205675(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, AmsData &state);
private:
CosemData* getCosemDataAt(uint8_t index, const char* ptr);
CosemData* findObis(uint8_t* obis, int matchlength, const char* ptr);
uint8_t getString(uint8_t* obis, int matchlength, const char* ptr, char* target);
float getNumber(uint8_t* obis, int matchlength, const char* ptr);
float getNumber(CosemData*);
time_t getTimestamp(uint8_t* obis, int matchlength, const char* ptr);
uint8_t AMS_OBIS_UNKNOWN_1[4] = { 25, 9, 0, 255 };
uint8_t AMS_OBIS_VERSION[4] = { 0, 2, 129, 255 };
uint8_t AMS_OBIS_METER_MODEL[4] = { 96, 1, 1, 255 };
uint8_t AMS_OBIS_METER_MODEL_2[4] = { 96, 1, 7, 255 };
uint8_t AMS_OBIS_METER_ID[4] = { 96, 1, 0, 255 };
uint8_t AMS_OBIS_METER_ID_2[4] = { 0, 0, 5, 255 };
uint8_t AMS_OBIS_METER_TIMESTAMP[4] = { 1, 0, 0, 255 };
uint8_t AMS_OBIS_ACTIVE_IMPORT[4] = { 1, 7, 0, 255 };
uint8_t AMS_OBIS_ACTIVE_EXPORT[4] = { 2, 7, 0, 255 };
uint8_t AMS_OBIS_REACTIVE_IMPORT[4] = { 3, 7, 0, 255 };
uint8_t AMS_OBIS_REACTIVE_EXPORT[4] = { 4, 7, 0, 255 };
uint8_t AMS_OBIS_CURRENT_L1[4] = { 31, 7, 0, 255 };
uint8_t AMS_OBIS_CURRENT_L2[4] = { 51, 7, 0, 255 };
uint8_t AMS_OBIS_CURRENT_L3[4] = { 71, 7, 0, 255 };
uint8_t AMS_OBIS_VOLTAGE_L1[4] = { 32, 7, 0, 255 };
uint8_t AMS_OBIS_VOLTAGE_L2[4] = { 52, 7, 0, 255 };
uint8_t AMS_OBIS_VOLTAGE_L3[4] = { 72, 7, 0, 255 };
uint8_t AMS_OBIS_ACTIVE_IMPORT_COUNT[4] = { 1, 8, 0, 255 };
uint8_t AMS_OBIS_ACTIVE_EXPORT_COUNT[4] = { 2, 8, 0, 255 };
uint8_t AMS_OBIS_REACTIVE_IMPORT_COUNT[4] = { 3, 8, 0, 255 };
uint8_t AMS_OBIS_REACTIVE_EXPORT_COUNT[4] = { 4, 8, 0, 255 };
uint8_t AMS_OBIS_POWER_FACTOR[4] = { 13, 7, 0, 255 };
uint8_t AMS_OBIS_POWER_FACTOR_L1[4] = { 33, 7, 0, 255 };
uint8_t AMS_OBIS_POWER_FACTOR_L2[4] = { 53, 7, 0, 255 };
uint8_t AMS_OBIS_POWER_FACTOR_L3[4] = { 73, 7, 0, 255 };
uint8_t AMS_OBIS_ACTIVE_IMPORT_L1[4] = { 21, 7, 0, 255 };
uint8_t AMS_OBIS_ACTIVE_IMPORT_L2[4] = { 41, 7, 0, 255 };
uint8_t AMS_OBIS_ACTIVE_IMPORT_L3[4] = { 61, 7, 0, 255 };
uint8_t AMS_OBIS_ACTIVE_EXPORT_L1[4] = { 22, 7, 0, 255 };
uint8_t AMS_OBIS_ACTIVE_EXPORT_L2[4] = { 42, 7, 0, 255 };
uint8_t AMS_OBIS_ACTIVE_EXPORT_L3[4] = { 62, 7, 0, 255 };
uint8_t AMS_OBIS_ACTIVE_IMPORT_L1_COUNT[4] = { 21, 8, 0, 255 };
uint8_t AMS_OBIS_ACTIVE_IMPORT_L2_COUNT[4] = { 41, 8, 0, 255 };
uint8_t AMS_OBIS_ACTIVE_IMPORT_L3_COUNT[4] = { 61, 8, 0, 255 };
uint8_t AMS_OBIS_ACTIVE_EXPORT_L1_COUNT[4] = { 22, 8, 0, 255 };
uint8_t AMS_OBIS_ACTIVE_EXPORT_L2_COUNT[4] = { 42, 8, 0, 255 };
uint8_t AMS_OBIS_ACTIVE_EXPORT_L3_COUNT[4] = { 62, 8, 0, 255 };
};
#endif

View File

@@ -0,0 +1,12 @@
#ifndef _IMPULSEAMSDATA_H
#define _IMPULSEAMSDATA_H
#include "AmsData.h"
class ImpulseAmsData : public AmsData {
public:
ImpulseAmsData(AmsData &state, uint16_t pulsePerKwh, uint8_t pulses);
ImpulseAmsData(double activeImportCounter);
};
#endif

View File

@@ -0,0 +1,35 @@
/**
* @copyright Utilitech AS 2024
* License: Fair Source
*
*/
#pragma once
#include "PassiveMeterCommunicator.h"
#if defined(AMS_REMOTE_DEBUG)
#include "RemoteDebug.h"
#endif
#include "AmsConfiguration.h"
#include "Timezone.h"
#include "ImpulseAmsData.h"
#if defined(ESP8266)
#include "SoftwareSerial.h"
#endif
#include "KmpTalker.h"
class KmpCommunicator : public PassiveMeterCommunicator {
public:
#if defined(AMS_REMOTE_DEBUG)
KmpCommunicator(RemoteDebug* debugger) : PassiveMeterCommunicator(debugger) {};
#else
KmpCommunicator(Stream* debugger) : PassiveMeterCommunicator(debugger) {};
#endif
void configure(MeterConfig&);
bool loop();
AmsData* getData(AmsData& meterState);
private:
KmpTalker* talker = NULL;
};

View File

@@ -0,0 +1,22 @@
#pragma once
#include <Stream.h>
struct KmpDataHolder {
uint32_t activeImportPower = 0, reactiveImportPower = 0, activeExportPower = 0, reactiveExportPower = 0;
float l1voltage = 0, l2voltage = 0, l3voltage = 0, l1current = 0, l2current = 0, l3current = 0;
uint32_t l1activeImportPower = 0, l2activeImportPower = 0, l3activeImportPower = 0;
uint32_t l1activeExportPower = 0, l2activeExportPower = 0, l3activeExportPower = 0;
double l1activeImportCounter = 0, l2activeImportCounter = 0, l3activeImportCounter = 0;
double l1activeExportCounter = 0, l2activeExportCounter = 0, l3activeExportCounter = 0;
float powerFactor = 0, l1PowerFactor = 0, l2PowerFactor = 0, l3PowerFactor = 0;
double activeImportCounter = 0, reactiveImportCounter = 0, activeExportCounter = 0, reactiveExportCounter = 0;
uint16_t meterId;
};
class KmpTalker {
public:
KmpTalker(Stream *hanSerial);
bool loop();
void getData(KmpDataHolder& data);
};

View File

@@ -0,0 +1,37 @@
/**
* @copyright Utilitech AS 2023
* License: Fair Source
*
*/
#ifndef _LNG_H
#define _LNG_H
#include "AmsData.h"
#include "AmsConfiguration.h"
#include "DataParser.h"
#include "Cosem.h"
struct LngHeader {
uint8_t tag;
uint8_t values;
uint8_t arrayTag;
uint8_t arrayLength;
} __attribute__((packed));
struct LngObisDescriptor {
uint8_t ignore1[5];
uint8_t octetTag;
uint8_t octetLength;
uint8_t obis[6];
uint8_t ignore2[5];
} __attribute__((packed));
class LNG : public AmsData {
public:
LNG(AmsData& meterState, const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx);
uint64_t getNumber(CosemData* item);
};
#endif

View File

@@ -0,0 +1,42 @@
/**
* @copyright Utilitech AS 2023
* License: Fair Source
*
*/
#ifndef _LNG2_H
#define _LNG2_H
#include "AmsData.h"
#include "AmsConfiguration.h"
#include "DataParser.h"
#include "Cosem.h"
struct Lng2Data_3p {
CosemBasic header;
CosemLongUnsigned u1;
CosemLongUnsigned u2;
CosemLongUnsigned u3;
CosemLongUnsigned i1;
CosemLongUnsigned i2;
CosemLongUnsigned i3;
CosemDLongUnsigned activeImport;
CosemDLongUnsigned activeExport;
CosemDLongUnsigned acumulatedImport;
CosemDLongUnsigned accumulatedExport;
CosemLongUnsigned x;
CosemLongUnsigned y;
CosemLongUnsigned z;
CosemString meterId;
} __attribute__((packed));
class LNG2 : public AmsData {
public:
LNG2(AmsData& meterState, const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx);
private:
uint8_t getString(CosemData* item, char* target);
};
#endif

View File

@@ -0,0 +1,28 @@
/**
* @copyright Utilitech AS 2023
* License: Fair Source
*
*/
#ifndef _METERCOMMUNICATOR_H
#define _METERCOMMUNICATOR_H
#include <Arduino.h>
#if defined(AMS_REMOTE_DEBUG)
#include "RemoteDebug.h"
#endif
#include "AmsData.h"
#include "AmsConfiguration.h"
class MeterCommunicator {
public:
virtual ~MeterCommunicator() {};
virtual void configure(MeterConfig&, Timezone*);
virtual bool loop();
virtual AmsData* getData(AmsData& meterState);
virtual int getLastError();
virtual bool isConfigChanged();
virtual void getCurrentConfig(MeterConfig& meterConfig);
};
#endif

View File

@@ -0,0 +1,96 @@
/**
* @copyright Utilitech AS 2023
* License: Fair Source
*
*/
#ifndef _PASSIVEMETERCOMMUNICATOR_H
#define _PASSIVEMETERCOMMUNICATOR_H
#include "MeterCommunicator.h"
#if defined(AMS_REMOTE_DEBUG)
#include "RemoteDebug.h"
#endif
#include "AmsConfiguration.h"
#include "DataParsers.h"
#include "Timezone.h"
#include "PassthroughMqttHandler.h"
#if defined(ESP8266)
#include "SoftwareSerial.h"
#endif
const uint32_t AUTO_BAUD_RATES[] = { 2400, 115200 };
class PassiveMeterCommunicator : public MeterCommunicator {
public:
#if defined(AMS_REMOTE_DEBUG)
PassiveMeterCommunicator(RemoteDebug* debugger);
#else
PassiveMeterCommunicator(Stream* debugger);
#endif
void configure(MeterConfig&, Timezone*);
bool loop();
AmsData* getData(AmsData& meterState);
int getLastError();
bool isConfigChanged();
void getCurrentConfig(MeterConfig& meterConfig);
void setPassthroughMqttHandler(PassthroughMqttHandler*);
HardwareSerial* getHwSerial();
void rxerr(int err);
protected:
#if defined(AMS_REMOTE_DEBUG)
RemoteDebug* debugger = NULL;
#else
Stream* debugger = NULL;
#endif
MeterConfig meterConfig;
bool configChanged = false;
Timezone* tz;
PassthroughMqttHandler* pt = NULL;
uint8_t *hanBuffer = NULL;
uint16_t hanBufferSize = 0;
Stream *hanSerial;
#if defined(ESP8266)
SoftwareSerial *swSerial = NULL;
#endif
HardwareSerial *hwSerial = NULL;
uint8_t rxBufferErrors = 0;
bool autodetect = false, validDataReceived = false;
unsigned long meterAutodetectLastChange = 0;
long rate = 10000;
uint32_t autodetectBaud = 0;
uint8_t autodetectParity = 11;
bool autodetectInvert = false;
uint8_t autodetectCount = 0;
bool dataAvailable = false;
int len = 0;
int pos = DATA_PARSE_INCOMPLETE;
int lastError = DATA_PARSE_OK;
bool serialInit = false;
bool maxDetectPayloadDetectDone = false;
uint8_t maxDetectedPayloadSize = 64;
DataParserContext ctx = {0,0,0,0};
HDLCParser *hdlcParser = NULL;
MBUSParser *mbusParser = NULL;
GBTParser *gbtParser = NULL;
GCMParser *gcmParser = NULL;
LLCParser *llcParser = NULL;
DLMSParser *dlmsParser = NULL;
DSMRParser *dsmrParser = NULL;
void setupHanPort(uint32_t baud, uint8_t parityOrdinal, bool invert, bool passive = true);
int16_t unwrapData(uint8_t *buf, DataParserContext &context);
void debugPrint(byte *buffer, int start, int length);
void printHanReadError(int pos);
void handleAutodetect(unsigned long now);
};
#endif

View File

@@ -0,0 +1,51 @@
/**
* @copyright Utilitech AS 2024
* License: Fair Source
*
*/
#ifndef _PULSEMETERCOMMUNICATOR_H
#define _PULSEMETERCOMMUNICATOR_H
#include "MeterCommunicator.h"
#if defined(AMS_REMOTE_DEBUG)
#include "RemoteDebug.h"
#endif
#include "AmsConfiguration.h"
#include "Timezone.h"
#include "ImpulseAmsData.h"
class PulseMeterCommunicator : public MeterCommunicator {
public:
#if defined(AMS_REMOTE_DEBUG)
PulseMeterCommunicator(RemoteDebug* debugger);
#else
PulseMeterCommunicator(Stream* debugger);
#endif
void configure(MeterConfig& config, Timezone* tz);
bool loop();
AmsData* getData(AmsData& meterState);
int getLastError();
bool isConfigChanged();
void getCurrentConfig(MeterConfig& meterConfig);
void onPulse(uint8_t pulses);
protected:
#if defined(AMS_REMOTE_DEBUG)
RemoteDebug* debugger = NULL;
#else
Stream* debugger = NULL;
#endif
MeterConfig meterConfig;
bool configChanged = false;
Timezone* tz;
bool updated = false;
bool initialized = false;
AmsData state;
uint64_t lastUpdate = 0;
void setupGpio();
};
#endif