mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-02-01 22:51:58 +00:00
Merge branch 'master' into mosquito
This commit is contained in:
@@ -70,6 +70,7 @@ ADC_MODE(ADC_VCC);
|
||||
#include "IEC6205621.h"
|
||||
#include "IEC6205675.h"
|
||||
#include "LNG.h"
|
||||
#include "LNG2.h"
|
||||
|
||||
#include "DataParsers.h"
|
||||
#include "Timezones.h"
|
||||
@@ -933,10 +934,22 @@ bool readHanPort() {
|
||||
debugV("Using application data:");
|
||||
if(Debug.isActive(RemoteDebug::VERBOSE)) debugPrint((byte*) payload, 0, ctx.length);
|
||||
|
||||
// Rudimentary detector for L&G proprietary format
|
||||
// Rudimentary detector for L&G proprietary format, this is terrible code... Fix later
|
||||
if(payload[0] == CosemTypeStructure && payload[2] == CosemTypeArray && payload[1] == payload[3]) {
|
||||
debugV("LNG");
|
||||
data = LNG(payload, meterState.getMeterType(), &meterConfig, ctx, &Debug);
|
||||
} else if(payload[0] == CosemTypeStructure &&
|
||||
payload[2] == CosemTypeLongUnsigned &&
|
||||
payload[5] == CosemTypeLongUnsigned &&
|
||||
payload[8] == CosemTypeLongUnsigned &&
|
||||
payload[11] == CosemTypeLongUnsigned &&
|
||||
payload[14] == CosemTypeLongUnsigned &&
|
||||
payload[17] == CosemTypeLongUnsigned
|
||||
) {
|
||||
debugV("LNG2");
|
||||
data = LNG2(payload, meterState.getMeterType(), &meterConfig, ctx, &Debug);
|
||||
} else {
|
||||
debugV("DLMS");
|
||||
// TODO: Split IEC6205675 into DataParserKaifa and DataParserObis. This way we can add other means of parsing, for those other proprietary formats
|
||||
data = IEC6205675(payload, meterState.getMeterType(), &meterConfig, ctx);
|
||||
}
|
||||
@@ -949,7 +962,7 @@ bool readHanPort() {
|
||||
if(!hw.ledBlink(LED_GREEN, 1))
|
||||
hw.ledBlink(LED_INTERNAL, 1);
|
||||
if(mqttEnabled && mqttHandler != NULL && mqtt != NULL) {
|
||||
if(mqttHandler->publish(&data, &meterState, &ea)) {
|
||||
if(mqttHandler->publish(&data, &meterState, &ea, eapi)) {
|
||||
mqtt->loop();
|
||||
delay(10);
|
||||
}
|
||||
@@ -1363,7 +1376,11 @@ void MQTT_connect() {
|
||||
mqttHandler = new DomoticzMqttHandler(mqtt, (char*) commonBuffer, domo);
|
||||
break;
|
||||
case 4:
|
||||
mqttHandler = new HomeAssistantMqttHandler(mqtt, (char*) commonBuffer, mqttConfig.clientId, mqttConfig.publishTopic, &hw);
|
||||
HomeAssistantConfig haconf;
|
||||
SystemConfig sys;
|
||||
config.getHomeAssistantConfig(haconf);
|
||||
config.getSystemConfig(sys);
|
||||
mqttHandler = new HomeAssistantMqttHandler(mqtt, (char*) commonBuffer, mqttConfig.clientId, mqttConfig.publishTopic, sys.boardType, haconf, &hw);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1495,6 +1512,7 @@ void configFileParse() {
|
||||
bool lMeter = false;
|
||||
bool lGpio = false;
|
||||
bool lDomo = false;
|
||||
bool lHa = false;
|
||||
bool lNtp = false;
|
||||
bool lEntsoe = false;
|
||||
bool lEac = false;
|
||||
@@ -1508,6 +1526,7 @@ void configFileParse() {
|
||||
MeterConfig meter;
|
||||
GpioConfig gpio;
|
||||
DomoticzConfig domo;
|
||||
HomeAssistantConfig haconf;
|
||||
NtpConfig ntp;
|
||||
EntsoeConfig entsoe;
|
||||
EnergyAccountingConfig eac;
|
||||
@@ -1680,6 +1699,15 @@ void configFileParse() {
|
||||
} else if(strncmp_P(buf, PSTR("domoticzCl1idx "), 15) == 0) {
|
||||
if(!lDomo) { config.getDomoticzConfig(domo); lDomo = true; };
|
||||
domo.cl1idx = String(buf+15).toInt();
|
||||
} else if(strncmp_P(buf, PSTR("homeAssistantDiscoveryPrefix "), 28) == 0) {
|
||||
if(!lHa) { config.getHomeAssistantConfig(haconf); lHa = true; };
|
||||
strcpy(haconf.discoveryPrefix, buf+28);
|
||||
} else if(strncmp_P(buf, PSTR("homeAssistantDiscoveryHostname "), 30) == 0) {
|
||||
if(!lHa) { config.getHomeAssistantConfig(haconf); lHa = true; };
|
||||
strcpy(haconf.discoveryHostname, buf+30);
|
||||
} else if(strncmp_P(buf, PSTR("homeAssistantDiscoveryNameTag "), 29) == 0) {
|
||||
if(!lHa) { config.getHomeAssistantConfig(haconf); lHa = true; };
|
||||
strcpy(haconf.discoveryNameTag, buf+29);
|
||||
} else if(strncmp_P(buf, PSTR("ntpEnable "), 10) == 0) {
|
||||
if(!lNtp) { config.getNtpConfig(ntp); lNtp = true; };
|
||||
ntp.enable = String(buf+10).toInt() == 1;
|
||||
@@ -1903,6 +1931,7 @@ void configFileParse() {
|
||||
if(lMeter) config.setMeterConfig(meter);
|
||||
if(lGpio) config.setGpioConfig(gpio);
|
||||
if(lDomo) config.setDomoticzConfig(domo);
|
||||
if(lHa) config.setHomeAssistantConfig(haconf);
|
||||
if(lNtp) config.setNtpConfig(ntp);
|
||||
if(lEntsoe) config.setEntsoeConfig(entsoe);
|
||||
if(lEac) config.setEnergyAccountingConfig(eac);
|
||||
|
||||
@@ -125,17 +125,11 @@ IEC6205621::IEC6205621(const char* p) {
|
||||
if(activeImportCounter > 0 || activeExportCounter > 0 || reactiveImportCounter > 0 || reactiveExportCounter > 0)
|
||||
listType = 3;
|
||||
|
||||
threePhase = l1voltage > 0 && l2voltage > 0 && l3voltage > 0;
|
||||
twoPhase = (l1voltage > 0 && l2voltage > 0) || (l2voltage > 0 && l3voltage > 0) || (l3voltage > 0 && l1voltage > 0);
|
||||
|
||||
if(threePhase) {
|
||||
if(l2current == 0 && l1current != 0 && l3current != 0) {
|
||||
l2current = (((activeImportPower - activeExportPower) * sqrt(3)) - (l1voltage * l1current) - (l3voltage * l3current)) / l2voltage;
|
||||
}
|
||||
}
|
||||
|
||||
if (l1activeImportPower > 0 || l2activeImportPower > 0 || l3activeImportPower > 0 || l1activeExportPower > 0 || l2activeExportPower > 0 || l3activeExportPower > 0)
|
||||
listType = 4;
|
||||
|
||||
threePhase = l1voltage > 0 && l2voltage > 0 && l3voltage > 0;
|
||||
twoPhase = (l1voltage > 0 && l2voltage > 0) || (l2voltage > 0 && l3voltage > 0) || (l3voltage > 0 && l1voltage > 0);
|
||||
}
|
||||
|
||||
String IEC6205621::extract(String payload, String obis) {
|
||||
|
||||
@@ -163,6 +163,8 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterCo
|
||||
if(meterType == AmsTypeUnknown) {
|
||||
if(memcmp(ctx.system_title, "SAGY", 4) == 0) {
|
||||
meterType = AmsTypeSagemcom;
|
||||
} else if(memcmp(ctx.system_title, "KFM", 3) == 0) {
|
||||
meterType = AmsTypeKaifa;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
46
src/LNG2.cpp
Normal file
46
src/LNG2.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#include "LNG2.h"
|
||||
|
||||
LNG2::LNG2(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, RemoteDebug* debugger) {
|
||||
CosemBasic* h = (CosemBasic*) payload;
|
||||
if(h->length == 0x0e) {
|
||||
meterType = AmsTypeLandisGyr;
|
||||
this->packageTimestamp = ctx.timestamp;
|
||||
|
||||
Lng2Data_3p* d = (Lng2Data_3p*) payload;
|
||||
this->l1voltage = ntohs(d->u1.data);
|
||||
this->l2voltage = ntohs(d->u2.data);
|
||||
this->l3voltage = ntohs(d->u3.data);
|
||||
|
||||
this->l1current = ntohs(d->i1.data) / 100.0;
|
||||
this->l2current = ntohs(d->i2.data) / 100.0;
|
||||
this->l3current = ntohs(d->i3.data) / 100.0;
|
||||
|
||||
this->activeImportPower = ntohl(d->activeImport.data);
|
||||
this->activeExportPower = ntohl(d->activeExport.data);
|
||||
this->activeImportCounter = ntohl(d->acumulatedImport.data) / 1000.0;
|
||||
this->activeExportCounter = ntohl(d->accumulatedExport.data) / 1000.0;
|
||||
|
||||
char str[64];
|
||||
uint8_t str_len = getString((CosemData*) &d->meterId, str);
|
||||
if(str_len > 0) {
|
||||
this->meterId = String(str);
|
||||
}
|
||||
listType = 3;
|
||||
lastUpdateMillis = millis();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t LNG2::getString(CosemData* item, char* target) {
|
||||
switch(item->base.type) {
|
||||
case CosemTypeString:
|
||||
memcpy(target, item->str.data, item->str.length);
|
||||
target[item->str.length] = 0;
|
||||
return item->str.length;
|
||||
case CosemTypeOctetString:
|
||||
memcpy(target, item->oct.data, item->oct.length);
|
||||
target[item->oct.length] = 0;
|
||||
return item->oct.length;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
37
src/LNG2.h
Normal file
37
src/LNG2.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef _LNG2_H
|
||||
#define _LNG2_H
|
||||
|
||||
#include "AmsData.h"
|
||||
#include "AmsConfiguration.h"
|
||||
#include "DataParser.h"
|
||||
#include "Cosem.h"
|
||||
#include "RemoteDebug.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(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, RemoteDebug* debugger);
|
||||
|
||||
private:
|
||||
uint8_t getString(CosemData* item, char* target);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user