mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-03-12 05:25:24 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd0b3ebb26 | ||
|
|
895a9bc6b1 | ||
|
|
ff935fc920 | ||
|
|
3833421e5f | ||
|
|
ebdc357a47 |
@@ -1,7 +1,7 @@
|
||||
# AMS MQTT Bridge
|
||||
This code is designed to decode data from electric smart meters installed in many countries in Europe these days. The data is presented in a graphical web interface and can also send the data to a MQTT broker which makes it suitable for home automation project. Originally it was only designed to work with Norwegian meters, but has since been adapter to read any IEC-62056-7-5 or IEC-62056-21 compliant meters.
|
||||
|
||||
Later development have added Energy usage graph for both day and month, as well as future energy price. The code can run on any ESP8266 or ESP32 hardware which you can read more about in the [WiKi](https://github.com/gskjold/AmsToMqttBridge/wiki). If you don't have the knowledge to set up a ESP device yourself, have a look at the shop at [amsleser.no](https://amsleser.no/).
|
||||
Later development have added Energy usage graph for both day and month, as well as future energy price (Prices only available for ESP32). The code can run on any ESP8266 or ESP32 hardware which you can read more about in the [WiKi](https://github.com/gskjold/AmsToMqttBridge/wiki). If you don't have the knowledge to set up a ESP device yourself, have a look at the shop at [amsleser.no](https://amsleser.no/).
|
||||
|
||||
|
||||
<img src="webui.png">
|
||||
|
||||
30
frames/Aidon-Sweden.raw
Normal file
30
frames/Aidon-Sweden.raw
Normal file
@@ -0,0 +1,30 @@
|
||||
7E A2 43 41 08 83 13 85 EB E6 E7 00 0F 40 00 00 00 00
|
||||
01 1B
|
||||
02 02 09 06 00 00 01 00 00 FF 09 0C 07 E5 0C 0A 05 10 39 00 FF 80 00 FF
|
||||
02 03 09 06 01 00 01 07 00 FF 06 00 00 07 E5 02 02 0F 00 16 1B
|
||||
02 03 09 06 01 00 02 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1B
|
||||
02 03 09 06 01 00 03 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1D
|
||||
02 03 09 06 01 00 04 07 00 FF 06 00 00 02 48 02 02 0F 00 16 1D
|
||||
02 03 09 06 01 00 1F 07 00 FF 10 00 09 02 02 0F FF 16 21
|
||||
02 03 09 06 01 00 33 07 00 FF 10 00 25 02 02 0F FF 16 21
|
||||
02 03 09 06 01 00 47 07 00 FF 10 00 2E 02 02 0F FF 16 21
|
||||
02 03 09 06 01 00 20 07 00 FF 12 08 E3 02 02 0F FF 16 23
|
||||
02 03 09 06 01 00 34 07 00 FF 12 08 D8 02 02 0F FF 16 23
|
||||
02 03 09 06 01 00 48 07 00 FF 12 08 DF 02 02 0F FF 16 23
|
||||
02 03 09 06 01 00 15 07 00 FF 06 00 00 00 D5 02 02 0F 00 16 1B
|
||||
02 03 09 06 01 00 16 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1B
|
||||
02 03 09 06 01 00 17 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1D
|
||||
02 03 09 06 01 00 18 07 00 FF 06 00 00 00 36 02 02 0F 00 16 1D
|
||||
02 03 09 06 01 00 29 07 00 FF 06 00 00 03 0C 02 02 0F 00 16 1B
|
||||
02 03 09 06 01 00 2A 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1B
|
||||
02 03 09 06 01 00 2B 07 00 FF 06 00 00 01 21 02 02 0F 00 16 1D
|
||||
02 03 09 06 01 00 2C 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1D
|
||||
02 03 09 06 01 00 3D 07 00 FF 06 00 00 03 F9 02 02 0F 00 16 1B
|
||||
02 03 09 06 01 00 3E 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1B
|
||||
02 03 09 06 01 00 3F 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1D
|
||||
02 03 09 06 01 00 40 07 00 FF 06 00 00 00 E9 02 02 0F 00 16 1D
|
||||
02 03 09 06 01 00 01 08 00 FF 06 03 C2 5A 64 02 02 0F 00 16 1E
|
||||
02 03 09 06 01 00 02 08 00 FF 06 00 00 00 00 02 02 0F 00 16 1E
|
||||
02 03 09 06 01 00 03 08 00 FF 06 00 04 5D 06 02 02 0F 00 16 20
|
||||
02 03 09 06 01 00 04 08 00 FF 06 00 B4 9D 89 02 02 0F 00 16 20
|
||||
1C 90 7E
|
||||
@@ -571,6 +571,14 @@ bool AmsConfiguration::hasConfig() {
|
||||
configVersion = 0;
|
||||
return false;
|
||||
}
|
||||
case 90:
|
||||
configVersion = -1; // Prevent loop
|
||||
if(relocateConfig90()) {
|
||||
configVersion = 91;
|
||||
} else {
|
||||
configVersion = 0;
|
||||
return false;
|
||||
}
|
||||
case EEPROM_CHECK_SUM:
|
||||
return true;
|
||||
default:
|
||||
@@ -831,6 +839,17 @@ bool AmsConfiguration::relocateConfig89() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AmsConfiguration::relocateConfig90() {
|
||||
EntsoeConfig entsoe;
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_ENTSOE_START_90, entsoe);
|
||||
EEPROM.put(CONFIG_ENTSOE_START, entsoe);
|
||||
EEPROM.put(EEPROM_CONFIG_ADDRESS, 91);
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AmsConfiguration::save() {
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(EEPROM_CONFIG_ADDRESS, EEPROM_CHECK_SUM);
|
||||
@@ -1013,13 +1032,13 @@ void AmsConfiguration::print(Print* debugger)
|
||||
debugger->printf("Temp analog pin: %i\r\n", gpio.tempAnalogSensorPin);
|
||||
debugger->printf("Vcc pin: %i\r\n", gpio.vccPin);
|
||||
if(gpio.vccMultiplier > 0) {
|
||||
debugger->printf("Vcc multiplier: %f\r\n", gpio.vccMultiplier / 1000.0);
|
||||
debugger->printf("Vcc multiplier: %f\r\n", gpio.vccMultiplier / 1000.0);
|
||||
}
|
||||
if(gpio.vccOffset > 0) {
|
||||
debugger->printf("Vcc offset: %f\r\n", gpio.vccOffset / 100.0);
|
||||
debugger->printf("Vcc offset: %f\r\n", gpio.vccOffset / 100.0);
|
||||
}
|
||||
if(gpio.vccBootLimit > 0) {
|
||||
debugger->printf("Vcc boot limit: %f\r\n", gpio.vccBootLimit / 10.0);
|
||||
debugger->printf("Vcc boot limit: %f\r\n", gpio.vccBootLimit / 10.0);
|
||||
}
|
||||
debugger->printf("GND resistor: %i\r\n", gpio.vccResistorGnd);
|
||||
debugger->printf("Vcc resistor: %i\r\n", gpio.vccResistorVcc);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "Arduino.h"
|
||||
|
||||
#define EEPROM_SIZE 1024*3
|
||||
#define EEPROM_CHECK_SUM 90 // Used to check if config is stored. Change if structure changes
|
||||
#define EEPROM_CHECK_SUM 91 // Used to check if config is stored. Change if structure changes
|
||||
#define EEPROM_CONFIG_ADDRESS 0
|
||||
#define EEPROM_TEMP_CONFIG_ADDRESS 2048
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#define CONFIG_WIFI_START 16
|
||||
#define CONFIG_METER_START 224
|
||||
#define CONFIG_GPIO_START 266
|
||||
#define CONFIG_ENTSOE_START 286
|
||||
#define CONFIG_ENTSOE_START 290
|
||||
#define CONFIG_WEB_START 648
|
||||
#define CONFIG_DEBUG_START 824
|
||||
#define CONFIG_DOMOTICZ_START 856
|
||||
@@ -23,6 +23,7 @@
|
||||
#define CONFIG_METER_START_87 784
|
||||
#define CONFIG_GPIO_START_88 832
|
||||
#define CONFIG_ENTSOE_START_89 944
|
||||
#define CONFIG_ENTSOE_START_90 286
|
||||
|
||||
|
||||
struct SystemConfig {
|
||||
@@ -325,6 +326,7 @@ private:
|
||||
bool relocateConfig87();
|
||||
bool relocateConfig88(); // dev 1.6
|
||||
bool relocateConfig89(); // dev 1.6
|
||||
bool relocateConfig90(); // 2.0.0
|
||||
|
||||
int readString(int pAddress, char* pString[]);
|
||||
int readInt(int pAddress, int *pValue);
|
||||
|
||||
@@ -8,21 +8,27 @@ void AmsData::apply(AmsData& other) {
|
||||
|
||||
if(ms > 0) {
|
||||
if(other.getActiveImportPower() > 0)
|
||||
activeImportCounter += (((float) ms) * other.getActiveImportPower()) / 3600000000;
|
||||
activeImportCounter += (((float) ms) * other.getActiveImportPower()) / 3600000000.0;
|
||||
|
||||
if(other.getListType() > 1) {
|
||||
ms = this->lastUpdateMillis > other.getLastUpdateMillis() ? 0 : other.getLastUpdateMillis() - this->lastList2;
|
||||
if(other.getActiveExportPower() > 0)
|
||||
activeExportCounter += (((float) ms*2) * other.getActiveExportPower()) / 3600000000;
|
||||
activeExportCounter += (((float) ms) * other.getActiveExportPower()) / 3600000000.0;
|
||||
if(other.getReactiveImportPower() > 0)
|
||||
reactiveImportCounter += (((float) ms*2) * other.getReactiveImportPower()) / 3600000000;
|
||||
reactiveImportCounter += (((float) ms) * other.getReactiveImportPower()) / 3600000000.0;
|
||||
if(other.getReactiveExportPower() > 0)
|
||||
reactiveExportCounter += (((float) ms*2) * other.getReactiveExportPower()) / 3600000000;
|
||||
reactiveExportCounter += (((float) ms) * other.getReactiveExportPower()) / 3600000000.0;
|
||||
}
|
||||
counterEstimated = true;
|
||||
}
|
||||
} else {
|
||||
//Serial.printf("\nDeviation: %.4f\n", other.getActiveImportCounter() - activeImportCounter);
|
||||
}
|
||||
|
||||
this->lastUpdateMillis = other.getLastUpdateMillis();
|
||||
if(other.getListType() > 1) {
|
||||
this->lastList2 = this->lastUpdateMillis;
|
||||
}
|
||||
this->packageTimestamp = other.getPackageTimestamp();
|
||||
if(other.getListType() > this->listType)
|
||||
this->listType = other.getListType();
|
||||
|
||||
@@ -63,6 +63,7 @@ public:
|
||||
|
||||
protected:
|
||||
unsigned long lastUpdateMillis = 0;
|
||||
unsigned long lastList2 = 0;
|
||||
uint8_t listType = 0, meterType = AmsTypeUnknown;
|
||||
time_t packageTimestamp = 0;
|
||||
String listId, meterId, meterModel;
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
#include "Timezone.h"
|
||||
|
||||
IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, CosemDateTime packageTimestamp) {
|
||||
uint32_t u32;
|
||||
int32_t s32;
|
||||
uint32_t ui;
|
||||
double val;
|
||||
char str[64];
|
||||
|
||||
this->packageTimestamp = getTimestamp(packageTimestamp);
|
||||
|
||||
u32 = getUnsignedNumber(AMS_OBIS_ACTIVE_IMPORT, sizeof(AMS_OBIS_ACTIVE_IMPORT), ((char *) (d)));
|
||||
if(u32 == 0xFFFFFFFF) {
|
||||
ui = getNumber(AMS_OBIS_ACTIVE_IMPORT, sizeof(AMS_OBIS_ACTIVE_IMPORT), ((char *) (d)));
|
||||
if(ui == 0xFFFFFFFF) {
|
||||
CosemData* data = getCosemDataAt(1, ((char *) (d)));
|
||||
|
||||
// Kaifa special case...
|
||||
@@ -124,7 +124,7 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, CosemDateTime packag
|
||||
// Kaifa end
|
||||
} else {
|
||||
listType = 1;
|
||||
activeImportPower = u32;
|
||||
activeImportPower = ui;
|
||||
|
||||
meterType = AmsTypeUnknown;
|
||||
CosemData* version = findObis(AMS_OBIS_VERSION, sizeof(AMS_OBIS_VERSION), d);
|
||||
@@ -151,119 +151,95 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, CosemDateTime packag
|
||||
this->packageTimestamp = this->packageTimestamp > 0 ? tz.toUTC(this->packageTimestamp) : 0;
|
||||
}
|
||||
|
||||
u32 = getString(AMS_OBIS_VERSION, sizeof(AMS_OBIS_VERSION), ((char *) (d)), str);
|
||||
if(u32 > 0) {
|
||||
ui = getString(AMS_OBIS_VERSION, sizeof(AMS_OBIS_VERSION), ((char *) (d)), str);
|
||||
if(ui > 0) {
|
||||
listId = String(str);
|
||||
}
|
||||
|
||||
u32 = getUnsignedNumber(AMS_OBIS_ACTIVE_EXPORT, sizeof(AMS_OBIS_ACTIVE_EXPORT), ((char *) (d)));
|
||||
if(u32 != 0xFFFFFFFF) {
|
||||
activeExportPower = u32;
|
||||
ui = getNumber(AMS_OBIS_ACTIVE_EXPORT, sizeof(AMS_OBIS_ACTIVE_EXPORT), ((char *) (d)));
|
||||
if(ui != 0xFFFFFFFF) {
|
||||
activeExportPower = ui;
|
||||
}
|
||||
|
||||
u32 = getUnsignedNumber(AMS_OBIS_REACTIVE_IMPORT, sizeof(AMS_OBIS_REACTIVE_IMPORT), ((char *) (d)));
|
||||
if(u32 != 0xFFFFFFFF) {
|
||||
reactiveImportPower = u32;
|
||||
ui = getNumber(AMS_OBIS_REACTIVE_IMPORT, sizeof(AMS_OBIS_REACTIVE_IMPORT), ((char *) (d)));
|
||||
if(ui != 0xFFFFFFFF) {
|
||||
reactiveImportPower = ui;
|
||||
}
|
||||
|
||||
u32 = getUnsignedNumber(AMS_OBIS_REACTIVE_EXPORT, sizeof(AMS_OBIS_REACTIVE_EXPORT), ((char *) (d)));
|
||||
if(u32 != 0xFFFFFFFF) {
|
||||
reactiveExportPower = u32;
|
||||
ui = getNumber(AMS_OBIS_REACTIVE_EXPORT, sizeof(AMS_OBIS_REACTIVE_EXPORT), ((char *) (d)));
|
||||
if(ui != 0xFFFFFFFF) {
|
||||
reactiveExportPower = ui;
|
||||
}
|
||||
|
||||
u32 = getUnsignedNumber(AMS_OBIS_VOLTAGE_L1, sizeof(AMS_OBIS_VOLTAGE_L1), ((char *) (d)));
|
||||
if(u32 != 0xFFFFFFFF) {
|
||||
val = getNumber(AMS_OBIS_VOLTAGE_L1, sizeof(AMS_OBIS_VOLTAGE_L1), ((char *) (d)));
|
||||
if(val != 0xFFFFFFFF) {
|
||||
listType = 2;
|
||||
l1voltage = u32;
|
||||
l1voltage = val;
|
||||
}
|
||||
u32 = getUnsignedNumber(AMS_OBIS_VOLTAGE_L2, sizeof(AMS_OBIS_VOLTAGE_L2), ((char *) (d)));
|
||||
if(u32 != 0xFFFFFFFF) {
|
||||
val = getNumber(AMS_OBIS_VOLTAGE_L2, sizeof(AMS_OBIS_VOLTAGE_L2), ((char *) (d)));
|
||||
if(val != 0xFFFFFFFF) {
|
||||
listType = 2;
|
||||
l2voltage = u32;
|
||||
l2voltage = val;
|
||||
}
|
||||
u32 = getUnsignedNumber(AMS_OBIS_VOLTAGE_L3, sizeof(AMS_OBIS_VOLTAGE_L3), ((char *) (d)));
|
||||
if(u32 != 0xFFFFFFFF) {
|
||||
val = getNumber(AMS_OBIS_VOLTAGE_L3, sizeof(AMS_OBIS_VOLTAGE_L3), ((char *) (d)));
|
||||
if(val != 0xFFFFFFFF) {
|
||||
listType = 2;
|
||||
l3voltage = u32;
|
||||
l3voltage = val;
|
||||
}
|
||||
|
||||
s32 = getSignedNumber(AMS_OBIS_CURRENT_L1, sizeof(AMS_OBIS_CURRENT_L1), ((char *) (d)));
|
||||
if(s32 != 0xFFFFFFFF) {
|
||||
val = getNumber(AMS_OBIS_CURRENT_L1, sizeof(AMS_OBIS_CURRENT_L1), ((char *) (d)));
|
||||
if(val != 0xFFFFFFFF) {
|
||||
listType = 2;
|
||||
l1current = s32;
|
||||
l1current = val;
|
||||
}
|
||||
s32 = getSignedNumber(AMS_OBIS_CURRENT_L2, sizeof(AMS_OBIS_CURRENT_L2), ((char *) (d)));
|
||||
if(s32 != 0xFFFFFFFF) {
|
||||
val = getNumber(AMS_OBIS_CURRENT_L2, sizeof(AMS_OBIS_CURRENT_L2), ((char *) (d)));
|
||||
if(val != 0xFFFFFFFF) {
|
||||
listType = 2;
|
||||
l2current = s32;
|
||||
l2current = val;
|
||||
}
|
||||
s32 = getSignedNumber(AMS_OBIS_CURRENT_L3, sizeof(AMS_OBIS_CURRENT_L3), ((char *) (d)));
|
||||
if(s32 != 0xFFFFFFFF) {
|
||||
val = getNumber(AMS_OBIS_CURRENT_L3, sizeof(AMS_OBIS_CURRENT_L3), ((char *) (d)));
|
||||
if(val != 0xFFFFFFFF) {
|
||||
listType = 2;
|
||||
l3current = s32;
|
||||
l3current = val;
|
||||
}
|
||||
|
||||
if(listType == 2) {
|
||||
int vdiv = 1;
|
||||
int voltage = l1voltage == 0 ? l2voltage == 0 ? l3voltage == 0 ? 0 : l3voltage : l2voltage : l1voltage;
|
||||
while(voltage > 1000) {
|
||||
vdiv *= 10;
|
||||
voltage /= 10;
|
||||
}
|
||||
|
||||
l1voltage = l1voltage != 0 ? l1voltage / vdiv : 0;
|
||||
l2voltage = l2voltage != 0 ? l2voltage / vdiv : 0;
|
||||
l3voltage = l3voltage != 0 ? l3voltage / vdiv : 0;
|
||||
|
||||
int adiv = 1;
|
||||
int watt = (l1voltage * l1current) + (l2voltage * l2current) + (l3voltage * l3current);
|
||||
while(activeImportPower > 0 && watt / activeImportPower > 2) {
|
||||
adiv *= 10;
|
||||
watt /= 10;
|
||||
}
|
||||
|
||||
l1current = l1current != 0 ? l1current / adiv : 0;
|
||||
l2current = l2current != 0 ? l2current / adiv : 0;
|
||||
l3current = l3current != 0 ? l3current / adiv : 0;
|
||||
}
|
||||
|
||||
u32 = getUnsignedNumber(AMS_OBIS_ACTIVE_IMPORT_COUNT, sizeof(AMS_OBIS_ACTIVE_IMPORT_COUNT), ((char *) (d)));
|
||||
if(u32 != 0xFFFFFFFF) {
|
||||
val = getNumber(AMS_OBIS_ACTIVE_IMPORT_COUNT, sizeof(AMS_OBIS_ACTIVE_IMPORT_COUNT), ((char *) (d)));
|
||||
if(val != 0xFFFFFFFF) {
|
||||
listType = 3;
|
||||
activeImportCounter = u32 / 100.0;
|
||||
activeImportCounter = val / 1000.0;
|
||||
}
|
||||
u32 = getUnsignedNumber(AMS_OBIS_ACTIVE_EXPORT_COUNT, sizeof(AMS_OBIS_ACTIVE_EXPORT_COUNT), ((char *) (d)));
|
||||
if(u32 != 0xFFFFFFFF) {
|
||||
val = getNumber(AMS_OBIS_ACTIVE_EXPORT_COUNT, sizeof(AMS_OBIS_ACTIVE_EXPORT_COUNT), ((char *) (d)));
|
||||
if(val != 0xFFFFFFFF) {
|
||||
listType = 3;
|
||||
activeExportCounter = u32 / 100.0;
|
||||
activeExportCounter = val / 1000.0;
|
||||
}
|
||||
u32 = getUnsignedNumber(AMS_OBIS_REACTIVE_IMPORT_COUNT, sizeof(AMS_OBIS_REACTIVE_IMPORT_COUNT), ((char *) (d)));
|
||||
if(u32 != 0xFFFFFFFF) {
|
||||
val = getNumber(AMS_OBIS_REACTIVE_IMPORT_COUNT, sizeof(AMS_OBIS_REACTIVE_IMPORT_COUNT), ((char *) (d)));
|
||||
if(val != 0xFFFFFFFF) {
|
||||
listType = 3;
|
||||
reactiveImportCounter = u32 / 100.0;
|
||||
reactiveImportCounter = val / 1000.0;
|
||||
}
|
||||
u32 = getUnsignedNumber(AMS_OBIS_REACTIVE_EXPORT_COUNT, sizeof(AMS_OBIS_REACTIVE_EXPORT_COUNT), ((char *) (d)));
|
||||
if(u32 != 0xFFFFFFFF) {
|
||||
val = getNumber(AMS_OBIS_REACTIVE_EXPORT_COUNT, sizeof(AMS_OBIS_REACTIVE_EXPORT_COUNT), ((char *) (d)));
|
||||
if(val != 0xFFFFFFFF) {
|
||||
listType = 3;
|
||||
reactiveExportCounter = u32 / 100.0;
|
||||
reactiveExportCounter = val / 1000.0;
|
||||
}
|
||||
|
||||
u32 = getString(AMS_OBIS_METER_MODEL, sizeof(AMS_OBIS_METER_MODEL), ((char *) (d)), str);
|
||||
if(u32 > 0) {
|
||||
ui = getString(AMS_OBIS_METER_MODEL, sizeof(AMS_OBIS_METER_MODEL), ((char *) (d)), str);
|
||||
if(ui > 0) {
|
||||
meterModel = String(str);
|
||||
} else {
|
||||
u32 = getString(AMS_OBIS_METER_MODEL_2, sizeof(AMS_OBIS_METER_MODEL_2), ((char *) (d)), str);
|
||||
if(u32 > 0) {
|
||||
ui = getString(AMS_OBIS_METER_MODEL_2, sizeof(AMS_OBIS_METER_MODEL_2), ((char *) (d)), str);
|
||||
if(ui > 0) {
|
||||
meterModel = String(str);
|
||||
}
|
||||
}
|
||||
|
||||
u32 = getString(AMS_OBIS_METER_ID, sizeof(AMS_OBIS_METER_ID), ((char *) (d)), str);
|
||||
if(u32 > 0) {
|
||||
ui = getString(AMS_OBIS_METER_ID, sizeof(AMS_OBIS_METER_ID), ((char *) (d)), str);
|
||||
if(ui > 0) {
|
||||
meterId = String(str);
|
||||
} else {
|
||||
u32 = getString(AMS_OBIS_METER_ID_2, sizeof(AMS_OBIS_METER_ID_2), ((char *) (d)), str);
|
||||
if(u32 > 0) {
|
||||
ui = getString(AMS_OBIS_METER_ID_2, sizeof(AMS_OBIS_METER_ID_2), ((char *) (d)), str);
|
||||
if(ui > 0) {
|
||||
meterId = String(str);
|
||||
}
|
||||
}
|
||||
@@ -279,21 +255,35 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, CosemDateTime packag
|
||||
}
|
||||
}
|
||||
|
||||
u32 = getUnsignedNumber(AMS_OBIS_POWER_FACTOR, sizeof(AMS_OBIS_POWER_FACTOR), ((char *) (d)));
|
||||
if(u32 != 0xFFFFFFFF) {
|
||||
powerFactor = u32 / 100.0;
|
||||
val = getNumber(AMS_OBIS_POWER_FACTOR, sizeof(AMS_OBIS_POWER_FACTOR), ((char *) (d)));
|
||||
if(val != 0xFFFFFFFF) {
|
||||
powerFactor = val;
|
||||
}
|
||||
u32 = getUnsignedNumber(AMS_OBIS_POWER_FACTOR_L1, sizeof(AMS_OBIS_POWER_FACTOR_L1), ((char *) (d)));
|
||||
if(u32 != 0xFFFFFFFF) {
|
||||
l1PowerFactor = u32 / 100.0;
|
||||
val = getNumber(AMS_OBIS_POWER_FACTOR_L1, sizeof(AMS_OBIS_POWER_FACTOR_L1), ((char *) (d)));
|
||||
if(val != 0xFFFFFFFF) {
|
||||
l1PowerFactor = val;
|
||||
}
|
||||
u32 = getUnsignedNumber(AMS_OBIS_POWER_FACTOR_L2, sizeof(AMS_OBIS_POWER_FACTOR_L2), ((char *) (d)));
|
||||
if(u32 != 0xFFFFFFFF) {
|
||||
l2PowerFactor = u32 / 100.0;
|
||||
val = getNumber(AMS_OBIS_POWER_FACTOR_L2, sizeof(AMS_OBIS_POWER_FACTOR_L2), ((char *) (d)));
|
||||
if(val != 0xFFFFFFFF) {
|
||||
l2PowerFactor = val;
|
||||
}
|
||||
u32 = getUnsignedNumber(AMS_OBIS_POWER_FACTOR_L3, sizeof(AMS_OBIS_POWER_FACTOR_L3), ((char *) (d)));
|
||||
if(u32 != 0xFFFFFFFF) {
|
||||
l3PowerFactor = u32 / 100.0;
|
||||
val = getNumber(AMS_OBIS_POWER_FACTOR_L3, sizeof(AMS_OBIS_POWER_FACTOR_L3), ((char *) (d)));
|
||||
if(val != 0xFFFFFFFF) {
|
||||
l3PowerFactor = val;
|
||||
}
|
||||
|
||||
if(meterType == AmsTypeKamstrup) {
|
||||
activeImportCounter *= 10;
|
||||
activeExportCounter *= 10;
|
||||
reactiveImportCounter *= 10;
|
||||
reactiveExportCounter *= 10;
|
||||
l1current /= 100;
|
||||
l2current /= 100;
|
||||
l3current /= 100;
|
||||
powerFactor /= 100;
|
||||
l1PowerFactor /= 100;
|
||||
l2PowerFactor /= 100;
|
||||
l3PowerFactor /= 100;
|
||||
}
|
||||
|
||||
lastUpdateMillis = millis();
|
||||
@@ -403,32 +393,35 @@ uint8_t IEC6205675::getString(uint8_t* obis, int matchlength, const char* ptr, c
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t IEC6205675::getSignedNumber(uint8_t* obis, int matchlength, const char* ptr) {
|
||||
double IEC6205675::getNumber(uint8_t* obis, int matchlength, const char* ptr) {
|
||||
CosemData* item = findObis(obis, matchlength, ptr);
|
||||
if(item != NULL) {
|
||||
switch(item->base.type) {
|
||||
case CosemTypeLongUnsigned:
|
||||
return ntohs(item->lu.data);
|
||||
case CosemTypeDLongUnsigned:
|
||||
return ntohl(item->dlu.data);
|
||||
case CosemTypeLongSigned:
|
||||
return ntohs(item->lu.data);
|
||||
}
|
||||
}
|
||||
return 0xFFFFFFFF;
|
||||
return getNumber(item);
|
||||
}
|
||||
|
||||
uint32_t IEC6205675::getUnsignedNumber(uint8_t* obis, int matchlength, const char* ptr) {
|
||||
CosemData* item = findObis(obis, matchlength, ptr);
|
||||
double IEC6205675::getNumber(CosemData* item) {
|
||||
double val = 0xFFFFFFFF;
|
||||
if(item != NULL) {
|
||||
char* pos = ((char*) item);
|
||||
switch(item->base.type) {
|
||||
case CosemTypeLongUnsigned:
|
||||
return ntohs(item->lu.data);
|
||||
val = ntohs(item->lu.data);
|
||||
pos += 3;
|
||||
break;
|
||||
case CosemTypeDLongUnsigned:
|
||||
return ntohl(item->dlu.data);
|
||||
val = ntohl(item->dlu.data);
|
||||
pos += 5;
|
||||
break;
|
||||
case CosemTypeLongSigned:
|
||||
val = ntohs(item->lu.data);
|
||||
pos += 3;
|
||||
break;
|
||||
}
|
||||
if(*pos++ == 0x02 && *pos++ == 0x02) {
|
||||
int8_t scale = *++pos;
|
||||
val *= pow(10, scale);
|
||||
}
|
||||
}
|
||||
return 0xFFFFFFFF;
|
||||
return val;
|
||||
}
|
||||
|
||||
time_t IEC6205675::getTimestamp(uint8_t* obis, int matchlength, const char* ptr) {
|
||||
|
||||
@@ -17,8 +17,8 @@ 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);
|
||||
uint32_t getSignedNumber(uint8_t* obis, int matchlength, const char* ptr);
|
||||
uint32_t getUnsignedNumber(uint8_t* obis, int matchlength, const char* ptr);
|
||||
double getNumber(uint8_t* obis, int matchlength, const char* ptr);
|
||||
double getNumber(CosemData*);
|
||||
time_t getTimestamp(uint8_t* obis, int matchlength, const char* ptr);
|
||||
time_t getTimestamp(CosemDateTime timestamp);
|
||||
|
||||
|
||||
@@ -265,9 +265,7 @@ $(function() {
|
||||
url: swv.data('url'),
|
||||
dataType: 'json'
|
||||
}).done(function(releases) {
|
||||
if(!swv.text().match("^v\d{1,2}\.\d{1,2}\.\d{1,2}$")) {
|
||||
nextVersion = releases[0];
|
||||
} else {
|
||||
if(/^v\d{1,2}\.\d{1,2}\.\d{1,2}$/.test(swv.text()) && fwl.length == 0) {
|
||||
releases.reverse();
|
||||
var next_patch;
|
||||
var next_minor;
|
||||
@@ -308,7 +306,8 @@ $(function() {
|
||||
} else if(next_patch) {
|
||||
nextVersion = next_patch;
|
||||
}
|
||||
|
||||
} else {
|
||||
nextVersion = releases[0];
|
||||
}
|
||||
if(nextVersion) {
|
||||
if(fwl.length > 0) {
|
||||
|
||||
Reference in New Issue
Block a user