mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-01-13 07:29:23 +00:00
Multipliers for HAN data
This commit is contained in:
parent
b9234f6f64
commit
40016f314e
@ -645,6 +645,14 @@ bool AmsConfiguration::hasConfig() {
|
||||
configVersion = 0;
|
||||
return false;
|
||||
}
|
||||
case 93:
|
||||
configVersion = -1; // Prevent loop
|
||||
if(relocateConfig93()) {
|
||||
configVersion = 94;
|
||||
} else {
|
||||
configVersion = 0;
|
||||
return false;
|
||||
}
|
||||
case EEPROM_CHECK_SUM:
|
||||
return true;
|
||||
default:
|
||||
@ -775,8 +783,6 @@ bool AmsConfiguration::relocateConfig91() {
|
||||
}
|
||||
|
||||
bool AmsConfiguration::relocateConfig92() {
|
||||
saveToFs();
|
||||
|
||||
WiFiConfig wifi;
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_WIFI_START, wifi);
|
||||
@ -797,6 +803,21 @@ bool AmsConfiguration::relocateConfig92() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AmsConfiguration::relocateConfig93() {
|
||||
MeterConfig meter;
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_METER_START_93, meter);
|
||||
meter.wattageMultiplier = 0;
|
||||
meter.voltageMultiplier = 0;
|
||||
meter.amperageMultiplier = 0;
|
||||
meter.accumulatedMultiplier = 0;
|
||||
EEPROM.put(CONFIG_METER_START, meter);
|
||||
EEPROM.put(EEPROM_CONFIG_ADDRESS, 94);
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AmsConfiguration::save() {
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(EEPROM_CONFIG_ADDRESS, EEPROM_CHECK_SUM);
|
||||
|
||||
@ -4,12 +4,12 @@
|
||||
#include "Arduino.h"
|
||||
|
||||
#define EEPROM_SIZE 1024*3
|
||||
#define EEPROM_CHECK_SUM 93 // Used to check if config is stored. Change if structure changes
|
||||
#define EEPROM_CHECK_SUM 94 // 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_METER_START 224
|
||||
#define CONFIG_METER_START 32
|
||||
#define CONFIG_GPIO_START 266
|
||||
#define CONFIG_ENTSOE_START 290
|
||||
#define CONFIG_WIFI_START 360
|
||||
@ -24,6 +24,7 @@
|
||||
#define CONFIG_METER_START_87 784
|
||||
#define CONFIG_ENTSOE_START_90 286
|
||||
#define CONFIG_WIFI_START_91 16
|
||||
#define CONFIG_METER_START_93 224
|
||||
|
||||
|
||||
struct SystemConfig {
|
||||
@ -94,7 +95,11 @@ struct MeterConfig {
|
||||
uint8_t productionCapacity;
|
||||
uint8_t encryptionKey[16];
|
||||
uint8_t authenticationKey[16];
|
||||
}; // 41
|
||||
uint16_t wattageMultiplier;
|
||||
uint16_t voltageMultiplier;
|
||||
uint16_t amperageMultiplier;
|
||||
uint16_t accumulatedMultiplier;
|
||||
}; // 49
|
||||
|
||||
struct MeterConfig87 {
|
||||
uint8_t type;
|
||||
@ -259,6 +264,7 @@ private:
|
||||
bool relocateConfig90(); // 2.0.0
|
||||
bool relocateConfig91(); // 2.0.2
|
||||
bool relocateConfig92(); // 2.0.3
|
||||
bool relocateConfig93(); // 2.1 beta
|
||||
|
||||
void saveToFs();
|
||||
bool loadFromFs(uint8_t version);
|
||||
|
||||
@ -832,7 +832,7 @@ bool readHanPort() {
|
||||
len = 0;
|
||||
if(pos > 0) {
|
||||
debugD("Valid data, start at byte %d", pos);
|
||||
data = IEC6205675(((char *) (hanBuffer)) + pos, meterState.getMeterType(), meterConfig.distributionSystem, timestamp, hc);
|
||||
data = IEC6205675(((char *) (hanBuffer)) + pos, meterState.getMeterType(), &meterConfig, timestamp, hc);
|
||||
} else {
|
||||
if(Debug.isActive(RemoteDebug::WARNING)) {
|
||||
switch(pos) {
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
#include "lwip/def.h"
|
||||
#include "Timezone.h"
|
||||
|
||||
IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, uint8_t distributionSystem, CosemDateTime packageTimestamp, HDLCConfig* hc) {
|
||||
IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterConfig, CosemDateTime packageTimestamp, HDLCConfig* hc) {
|
||||
double val;
|
||||
char str[64];
|
||||
|
||||
@ -360,12 +360,35 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, uint8_t distribution
|
||||
lastUpdateMillis = millis();
|
||||
}
|
||||
|
||||
if(meterConfig->wattageMultiplier > 0) {
|
||||
activeImportPower = activeImportPower > 0 ? activeImportPower * (meterConfig->wattageMultiplier / 1000.0) : 0;
|
||||
activeExportPower = activeExportPower > 0 ? activeExportPower * (meterConfig->wattageMultiplier / 1000.0) : 0;
|
||||
reactiveImportPower = reactiveImportPower > 0 ? reactiveImportPower * (meterConfig->wattageMultiplier / 1000.0) : 0;
|
||||
reactiveExportPower = reactiveExportPower > 0 ? reactiveExportPower * (meterConfig->wattageMultiplier / 1000.0) : 0;
|
||||
}
|
||||
if(meterConfig->voltageMultiplier > 0) {
|
||||
l1voltage = l1voltage > 0 ? l1voltage * (meterConfig->voltageMultiplier / 1000.0) : 0;
|
||||
l2voltage = l2voltage > 0 ? l2voltage * (meterConfig->voltageMultiplier / 1000.0) : 0;
|
||||
l3voltage = l3voltage > 0 ? l3voltage * (meterConfig->voltageMultiplier / 1000.0) : 0;
|
||||
}
|
||||
if(meterConfig->amperageMultiplier > 0) {
|
||||
l1current = l1current > 0 ? l1current * (meterConfig->amperageMultiplier / 1000.0) : 0;
|
||||
l2current = l2current > 0 ? l2current * (meterConfig->amperageMultiplier / 1000.0) : 0;
|
||||
l3current = l3current > 0 ? l3current * (meterConfig->amperageMultiplier / 1000.0) : 0;
|
||||
}
|
||||
if(meterConfig->accumulatedMultiplier > 0) {
|
||||
activeImportCounter = activeImportCounter > 0 ? activeImportCounter * (meterConfig->accumulatedMultiplier / 1000.0) : 0;
|
||||
activeExportCounter = activeExportCounter > 0 ? activeExportCounter * (meterConfig->accumulatedMultiplier / 1000.0) : 0;
|
||||
reactiveImportCounter = reactiveImportCounter > 0 ? reactiveImportCounter * (meterConfig->accumulatedMultiplier / 1000.0) : 0;
|
||||
reactiveExportCounter = reactiveExportCounter > 0 ? reactiveExportCounter * (meterConfig->accumulatedMultiplier / 1000.0) : 0;
|
||||
}
|
||||
|
||||
threePhase = l1voltage > 0 && l2voltage > 0 && l3voltage > 0;
|
||||
if(!threePhase)
|
||||
twoPhase = (l1voltage > 0 && l2voltage > 0) || (l2voltage > 0 && l3voltage > 0) || (l3voltage > 0 && l1voltage > 0);
|
||||
|
||||
// Special case for Norwegian IT/TT meters that does not report all values
|
||||
if(distributionSystem == 1) {
|
||||
if(meterConfig->distributionSystem == 1) {
|
||||
if(threePhase) {
|
||||
if(l2current == 0.0 && l1current > 0.0 && l3current > 0.0) {
|
||||
l2current = (((activeImportPower - activeExportPower) * sqrt(3)) - (l1voltage * l1current) - (l3voltage * l3current)) / l2voltage;
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
#include "AmsData.h"
|
||||
#include "ams/hdlc.h"
|
||||
#include "AmsConfiguration.h"
|
||||
|
||||
#define NOVALUE 0xFFFFFFFF
|
||||
|
||||
@ -13,7 +14,7 @@ struct AmsOctetTimestamp {
|
||||
|
||||
class IEC6205675 : public AmsData {
|
||||
public:
|
||||
IEC6205675(const char* payload, uint8_t useMeterType, uint8_t distributionSystem, CosemDateTime packageTimestamp, HDLCConfig* hc);
|
||||
IEC6205675(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, CosemDateTime packageTimestamp, HDLCConfig* hc);
|
||||
|
||||
private:
|
||||
CosemData* getCosemDataAt(uint8_t index, const char* ptr);
|
||||
|
||||
@ -49,6 +49,7 @@
|
||||
#include "root/energyprice_json.h"
|
||||
#include "root/thresholds_html.h"
|
||||
#include "root/configfile_html.h"
|
||||
#include "root/meteradvanced_html.h"
|
||||
|
||||
#include "base64.h"
|
||||
|
||||
@ -75,6 +76,7 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter
|
||||
server.on("/temperature", HTTP_POST, std::bind(&AmsWebServer::temperaturePost, this));
|
||||
server.on("/temperature.json", HTTP_GET, std::bind(&AmsWebServer::temperatureJson, this));
|
||||
server.on("/meter", HTTP_GET, std::bind(&AmsWebServer::configMeterHtml, this));
|
||||
server.on("/meteradvanced", HTTP_GET, std::bind(&AmsWebServer::configMeterAdvancedHtml, this));
|
||||
server.on("/wifi", HTTP_GET, std::bind(&AmsWebServer::configWifiHtml, this));
|
||||
server.on("/mqtt", HTTP_GET, std::bind(&AmsWebServer::configMqttHtml, this));
|
||||
server.on("/web", HTTP_GET, std::bind(&AmsWebServer::configWebHtml, this));
|
||||
@ -388,6 +390,29 @@ void AmsWebServer::configMeterHtml() {
|
||||
server.sendContent_P(FOOT_HTML);
|
||||
}
|
||||
|
||||
void AmsWebServer::configMeterAdvancedHtml() {
|
||||
printD("Serving /meteradvanced.html over http...");
|
||||
|
||||
if(!checkSecurity(1))
|
||||
return;
|
||||
|
||||
snprintf_P(buf, BufferSize, METERADVANCED_HTML,
|
||||
meterConfig->wattageMultiplier / 1000.0,
|
||||
meterConfig->voltageMultiplier / 1000.0,
|
||||
meterConfig->amperageMultiplier / 1000.0,
|
||||
meterConfig->accumulatedMultiplier / 1000.0
|
||||
);
|
||||
|
||||
server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE);
|
||||
server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE);
|
||||
server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF);
|
||||
|
||||
server.setContentLength(strlen(buf) + HEAD_HTML_LEN + FOOT_HTML_LEN);
|
||||
server.send_P(200, MIME_HTML, HEAD_HTML);
|
||||
server.sendContent(buf);
|
||||
server.sendContent_P(FOOT_HTML);
|
||||
}
|
||||
|
||||
void AmsWebServer::configWifiHtml() {
|
||||
printD("Serving /wifi.html over http...");
|
||||
|
||||
@ -1134,6 +1159,7 @@ void AmsWebServer::handleSave() {
|
||||
|
||||
if(server.hasArg("mc") && server.arg("mc") == "true") {
|
||||
printD("Received meter config");
|
||||
config->getMeterConfig(*meterConfig);
|
||||
meterConfig->baud = server.arg("b").toInt();
|
||||
meterConfig->parity = server.arg("c").toInt();
|
||||
meterConfig->invert = server.hasArg("i") && server.arg("i") == "true";
|
||||
@ -1156,6 +1182,16 @@ void AmsWebServer::handleSave() {
|
||||
config->setMeterConfig(*meterConfig);
|
||||
}
|
||||
|
||||
if(server.hasArg("ma") && server.arg("ma") == "true") {
|
||||
printD("Received meter advanced config");
|
||||
config->getMeterConfig(*meterConfig);
|
||||
meterConfig->wattageMultiplier = server.arg("wm").toDouble() * 1000;
|
||||
meterConfig->voltageMultiplier = server.arg("vm").toDouble() * 1000;
|
||||
meterConfig->amperageMultiplier = server.arg("am").toDouble() * 1000;
|
||||
meterConfig->accumulatedMultiplier = server.arg("cm").toDouble() * 1000;
|
||||
config->setMeterConfig(*meterConfig);
|
||||
}
|
||||
|
||||
if(server.hasArg("wc") && server.arg("wc") == "true") {
|
||||
printD("Received WiFi config");
|
||||
WiFiConfig wifi;
|
||||
|
||||
@ -76,6 +76,7 @@ private:
|
||||
void temperaturePost();
|
||||
void temperatureJson();
|
||||
void configMeterHtml();
|
||||
void configMeterAdvancedHtml();
|
||||
void configWifiHtml();
|
||||
void configMqttHtml();
|
||||
void configWebHtml();
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
<hr/>
|
||||
<div class="row form-group">
|
||||
<div class="col-6">
|
||||
<a href="/" class="btn btn-outline-secondary">Back</a>
|
||||
<a href="/mqtt" class="btn btn-outline-secondary">Back</a>
|
||||
</div>
|
||||
<div class="col-6 text-right">
|
||||
<button class="btn btn-primary">Save</button>
|
||||
|
||||
@ -115,9 +115,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-12">
|
||||
<div class="col-sm-6">
|
||||
<a href="/thresholds">Configure tariff thresholds</a>
|
||||
</div>
|
||||
<div class="col-sm-6 text-right">
|
||||
<a href="/meteradvanced">Multipliers</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
|
||||
49
web/meteradvanced.html
Normal file
49
web/meteradvanced.html
Normal file
@ -0,0 +1,49 @@
|
||||
<form method="post" action="/save">
|
||||
<input type="hidden" name="ma" value="true"/>
|
||||
<div class="my-3 p-3 bg-white rounded shadow">
|
||||
<h6>Multipliers</h6>
|
||||
<div class="row">
|
||||
<div class="col-lg-3 col-md-4 col-sm-6">
|
||||
<div class="m-2 input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Instant</span>
|
||||
</div>
|
||||
<input type="number" class="form-control text-right" name="wm" value="%.2f" min="0.00" max="655.35" step="0.01"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-md-4 col-sm-6">
|
||||
<div class="m-2 input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Voltage</span>
|
||||
</div>
|
||||
<input type="number" class="form-control text-right" name="vm" value="%.2f" min="0.00" max="655.35" step="0.01"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-md-4 col-sm-6">
|
||||
<div class="m-2 input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Amperage</span>
|
||||
</div>
|
||||
<input type="number" class="form-control text-right" name="am" value="%.2f" min="0.00" max="655.35" step="0.01"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-md-4 col-sm-6">
|
||||
<div class="m-2 input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Accumulated</span>
|
||||
</div>
|
||||
<input type="number" class="form-control text-right" name="cm" value="%.2f" min="0.00" max="655.35" step="0.01"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row form-group">
|
||||
<div class="col-6">
|
||||
<a href="/meter" class="btn btn-outline-secondary">Back</a>
|
||||
</div>
|
||||
<div class="col-6 text-right">
|
||||
<button class="btn btn-primary">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
Loading…
x
Reference in New Issue
Block a user