mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-01-12 00:02:53 +00:00
Merge branch 'master' into dev-v2.2
This commit is contained in:
commit
65a09dcecf
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -33,6 +33,7 @@ If applicable, add screenshots to help explain your problem.
|
||||
**Relevant firmware information:**
|
||||
- Version: [e.g. 2.1.0]
|
||||
- MQTT: [yes/no]
|
||||
- MQTT payload type: [e.g. JSON]
|
||||
- HAN GPIO: [e.g. GPIO5]
|
||||
- HAN baud and parity: [e.g. 2400 8E1]
|
||||
- Temperature sensors [e.g. 3xDS18B20]
|
||||
|
||||
1
.github/ISSUE_TEMPLATE/support.md
vendored
1
.github/ISSUE_TEMPLATE/support.md
vendored
@ -20,6 +20,7 @@ A clear and concise description of what the problem is.
|
||||
**Relevant firmware information:**
|
||||
- Version: [e.g. 2.1.0]
|
||||
- MQTT: [yes/no]
|
||||
- MQTT payload type: [e.g. JSON]
|
||||
- HAN GPIO: [e.g. GPIO5]
|
||||
- HAN baud and parity: [e.g. 2400 8E1]
|
||||
- Temperature sensors [e.g. 3xDS18B20]
|
||||
|
||||
@ -54,7 +54,8 @@ struct WiFiConfig {
|
||||
char hostname[32];
|
||||
bool mdns;
|
||||
uint8_t power;
|
||||
}; // 210
|
||||
uint8_t sleep;
|
||||
}; // 211
|
||||
|
||||
struct MqttConfig86 {
|
||||
char host[128];
|
||||
|
||||
@ -24,6 +24,7 @@ bool AmsConfiguration::getWiFiConfig(WiFiConfig& config) {
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_WIFI_START, config);
|
||||
EEPROM.end();
|
||||
if(config.sleep > 2) config.sleep = 1;
|
||||
return true;
|
||||
} else {
|
||||
clearWifi(config);
|
||||
@ -33,6 +34,7 @@ bool AmsConfiguration::getWiFiConfig(WiFiConfig& config) {
|
||||
|
||||
bool AmsConfiguration::setWiFiConfig(WiFiConfig& config) {
|
||||
WiFiConfig existing;
|
||||
if(config.sleep > 2) config.sleep = 1;
|
||||
if(getWiFiConfig(existing)) {
|
||||
wifiChanged |= strcmp(config.ssid, existing.ssid) != 0;
|
||||
wifiChanged |= strcmp(config.psk, existing.psk) != 0;
|
||||
@ -45,6 +47,7 @@ bool AmsConfiguration::setWiFiConfig(WiFiConfig& config) {
|
||||
}
|
||||
wifiChanged |= strcmp(config.hostname, existing.hostname) != 0;
|
||||
wifiChanged |= config.power != existing.power;
|
||||
wifiChanged |= config.sleep != existing.sleep;
|
||||
} else {
|
||||
wifiChanged = true;
|
||||
}
|
||||
@ -70,6 +73,7 @@ void AmsConfiguration::clearWifi(WiFiConfig& config) {
|
||||
#endif
|
||||
strcpy(config.hostname, (String("ams-") + String(chipId, HEX)).c_str());
|
||||
config.mdns = true;
|
||||
config.sleep = 0xFF;
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearWifiIp(WiFiConfig& config) {
|
||||
@ -510,6 +514,7 @@ bool AmsConfiguration::getEnergyAccountingConfig(EnergyAccountingConfig& config)
|
||||
if(config.thresholds[9] != 255) {
|
||||
clearEnergyAccountingConfig(config);
|
||||
}
|
||||
if(config.hours > 5) config.hours = 5;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -549,6 +554,7 @@ void AmsConfiguration::clearEnergyAccountingConfig(EnergyAccountingConfig& confi
|
||||
config.thresholds[7] = 100;
|
||||
config.thresholds[8] = 150;
|
||||
config.thresholds[9] = 255;
|
||||
config.hours = 3;
|
||||
}
|
||||
|
||||
bool AmsConfiguration::isEnergyAccountingChanged() {
|
||||
|
||||
@ -7,20 +7,20 @@
|
||||
|
||||
struct DayDataPoints {
|
||||
uint8_t version;
|
||||
int16_t hImport[24];
|
||||
uint16_t hImport[24];
|
||||
time_t lastMeterReadTime;
|
||||
uint32_t activeImport;
|
||||
uint32_t activeExport;
|
||||
int16_t hExport[24];
|
||||
uint16_t hExport[24];
|
||||
}; // 112 bytes
|
||||
|
||||
struct MonthDataPoints {
|
||||
uint8_t version;
|
||||
int16_t dImport[31];
|
||||
uint16_t dImport[31];
|
||||
time_t lastMeterReadTime;
|
||||
uint32_t activeImport;
|
||||
uint32_t activeExport;
|
||||
int16_t dExport[31];
|
||||
uint16_t dExport[31];
|
||||
}; // 141 bytes
|
||||
|
||||
class AmsDataStorage {
|
||||
|
||||
@ -657,7 +657,7 @@ var fetch = function() {
|
||||
|
||||
if(ip) {
|
||||
var v = parseInt(json.i);
|
||||
var pct = (v*100)/parseInt(json.im);
|
||||
var pct = Math.min((v*100)/parseInt(json.im), 100);
|
||||
var append = "W";
|
||||
if(v > 1000 && !swatt) {
|
||||
v = (v/1000).toFixed(1);
|
||||
@ -683,7 +683,7 @@ var fetch = function() {
|
||||
$('.rim').hide();
|
||||
if(xp) {
|
||||
var v = parseInt(json.e);
|
||||
var pct = (v*100)/(om*1000);
|
||||
var pct = Math.min((v*100)/(om*1000), 100);
|
||||
var append = "W";
|
||||
if(v > 1000 && !swatt) {
|
||||
v = (v/1000).toFixed(1);
|
||||
@ -723,21 +723,21 @@ var fetch = function() {
|
||||
var u1 = parseFloat(json.u1);
|
||||
t += u1;
|
||||
c++;
|
||||
var pct = (Math.max(parseFloat(json.u1)-195.5, 1)*100/69);
|
||||
var pct = Math.min(Math.max(parseFloat(json.u1)-195.5, 1)*100/69, 100);
|
||||
arr[r++] = [ds == 1 ? 'L1-L2' : 'L1', u1, "color: " + voltcol(pct) + ";opacity: 0.9;", u1 + "V"];
|
||||
}
|
||||
if(json.u2) {
|
||||
var u2 = parseFloat(json.u2);
|
||||
t += u2;
|
||||
c++;
|
||||
var pct = (Math.max(parseFloat(json.u2)-195.5, 1)*100/69);
|
||||
var pct = Math.min(Math.max(parseFloat(json.u2)-195.5, 1)*100/69, 100);
|
||||
arr[r++] = [ds == 1 ? 'L1-L3' : 'L2', u2, "color: " + voltcol(pct) + ";opacity: 0.9;", u2 + "V"];
|
||||
}
|
||||
if(json.u3) {
|
||||
var u3 = parseFloat(json.u3);
|
||||
t += u3;
|
||||
c++;
|
||||
var pct = (Math.max(parseFloat(json.u3)-195.5, 1)*100/69);
|
||||
var pct = Math.min(Math.max(parseFloat(json.u3)-195.5, 1)*100/69, 100);
|
||||
arr[r++] = [ds == 1 ? 'L2-L3' : 'L3', u3, "color: " + voltcol(pct) + ";opacity: 0.9;", u3 + "V"];
|
||||
}
|
||||
v = t/c;
|
||||
@ -762,19 +762,19 @@ var fetch = function() {
|
||||
if(json.i1 || json.u1) {
|
||||
var i1 = parseFloat(json.i1);
|
||||
dA = true;
|
||||
var pct = (parseFloat(json.i1)/parseInt(json.mf))*100;
|
||||
var pct = Math.min((parseFloat(json.i1)/parseInt(json.mf))*100, 100);
|
||||
arr[r++] = ['L1', pct, "color: " + ampcol(pct) + ";opacity: 0.9;", i1 + "A"];
|
||||
}
|
||||
if(json.i2 || json.u2) {
|
||||
var i2 = parseFloat(json.i2);
|
||||
dA = true;
|
||||
var pct = (parseFloat(json.i2)/parseInt(json.mf))*100;
|
||||
var pct = Math.min((parseFloat(json.i2)/parseInt(json.mf))*100, 100);
|
||||
arr[r++] = ['L2', pct, "color: " + ampcol(pct) + ";opacity: 0.9;", i2 + "A"];
|
||||
}
|
||||
if(json.i3 || json.u3) {
|
||||
var i3 = parseFloat(json.i3);
|
||||
dA = true;
|
||||
var pct = (parseFloat(json.i3)/parseInt(json.mf))*100;
|
||||
var pct = Math.min((parseFloat(json.i3)/parseInt(json.mf))*100, 100);
|
||||
arr[r++] = ['L3', pct, "color: " + ampcol(pct) + ";opacity: 0.9;", i3 + "A"];
|
||||
}
|
||||
if(dA) {
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" id="i">
|
||||
<div class="col-xl-3 col-lg-4 form-group">
|
||||
<div class="col-xl-3 col-lg-4 col-md-6 form-group">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">IP</span>
|
||||
@ -45,7 +45,7 @@
|
||||
<input type="text" name="i" class="form-control sip" pattern="\d?\d?\d.\d?\d?\d.\d?\d?\d.\d?\d?\d" value="{i}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-lg-4 form-group">
|
||||
<div class="col-xl-3 col-lg-4 col-md-6 form-group">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Netmask</span>
|
||||
@ -53,7 +53,7 @@
|
||||
<input type="text" name="sn" class="form-control sip" pattern="\d?\d?\d.\d?\d?\d.\d?\d?\d.\d?\d?\d" value="{sn}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-lg-4 form-group">
|
||||
<div class="col-xl-3 col-lg-4 col-md-6 form-group">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Gateway</span>
|
||||
@ -61,7 +61,7 @@
|
||||
<input type="text" name="g" class="form-control sip" pattern="\d?\d?\d.\d?\d?\d.\d?\d?\d.\d?\d?\d" value="{g}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-4 col-lg-5 form-group">
|
||||
<div class="col-xl-4 col-lg-5 col-md-6 form-group">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">DNS 1</span>
|
||||
@ -69,7 +69,7 @@
|
||||
<input type="text" name="d1" class="form-control sip" pattern="\d?\d?\d.\d?\d?\d.\d?\d?\d.\d?\d?\d" value="{d1}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-4 col-lg-5 form-group">
|
||||
<div class="col-xl-4 col-lg-5 col-md-6 form-group">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">DNS 2</span>
|
||||
@ -89,7 +89,21 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-3 col-md-4 col-sm-6 form-group">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Power saving</span>
|
||||
</div>
|
||||
<select name="z" class="form-control">
|
||||
<option value="255">Default</option>
|
||||
<option value="0" {z0}>Off</option>
|
||||
<option value="1" {z1}>Minimum</option>
|
||||
<option value="2" {z2}>Maximum</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row form-group">
|
||||
|
||||
@ -2,6 +2,7 @@ static const char HEADER_CACHE_CONTROL[] PROGMEM = "Cache-Control";
|
||||
static const char HEADER_PRAGMA[] PROGMEM = "Pragma";
|
||||
static const char HEADER_EXPIRES[] PROGMEM = "Expires";
|
||||
static const char HEADER_AUTHENTICATE[] PROGMEM = "WWW-Authenticate";
|
||||
static const char HEADER_LOCATION[] PROGMEM = "Location";
|
||||
|
||||
static const char CACHE_CONTROL_NO_CACHE[] PROGMEM = "no-cache, no-store, must-revalidate";
|
||||
static const char CACHE_1HR[] PROGMEM = "public, max-age=3600";
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -237,7 +237,7 @@ float EnergyAccounting::getMonthMax() {
|
||||
uint32_t maxHour = 0.0;
|
||||
bool included[5] = { false, false, false, false, false };
|
||||
|
||||
while(count < config->hours && count <= 5) {
|
||||
for(uint8_t x = 0;x < min((uint8_t) 5, config->hours); x++) {
|
||||
uint8_t maxIdx = 0;
|
||||
uint16_t maxVal = 0;
|
||||
for(uint8_t i = 0; i < 5; i++) {
|
||||
@ -248,8 +248,10 @@ float EnergyAccounting::getMonthMax() {
|
||||
maxIdx = i;
|
||||
}
|
||||
}
|
||||
included[maxIdx] = true;
|
||||
count++;
|
||||
if(maxVal > 0) {
|
||||
included[maxIdx] = true;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
for(uint8_t i = 0; i < 5; i++) {
|
||||
@ -265,7 +267,7 @@ float EnergyAccounting::getPeak(uint8_t num) {
|
||||
uint8_t count = 0;
|
||||
bool included[5] = { false, false, false, false, false };
|
||||
|
||||
while(count < config->hours && count <= 5) {
|
||||
for(uint8_t x = 0;x < min((uint8_t) 5, config->hours); x++) {
|
||||
uint8_t maxIdx = 0;
|
||||
uint16_t maxVal = 0;
|
||||
for(uint8_t i = 0; i < 5; i++) {
|
||||
@ -275,8 +277,10 @@ float EnergyAccounting::getPeak(uint8_t num) {
|
||||
maxIdx = i;
|
||||
}
|
||||
}
|
||||
included[maxIdx] = true;
|
||||
count++;
|
||||
if(maxVal > 0) {
|
||||
included[maxIdx] = true;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t pos = 0;
|
||||
|
||||
@ -3,5 +3,5 @@
|
||||
"tPO" : %.2f,
|
||||
"tQI" : %.2f,
|
||||
"tQO" : %.2f,
|
||||
"rtc" : %lld
|
||||
"rtc" : %lu
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"id" : "%s",
|
||||
"name" : "%s",
|
||||
"up" : %u,
|
||||
"t" : %lld,
|
||||
"t" : %lu,
|
||||
"vcc" : %.3f,
|
||||
"rssi": %d,
|
||||
"temp": %.2f,
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"id" : "%s",
|
||||
"name" : "%s",
|
||||
"up" : %u,
|
||||
"t" : %lld,
|
||||
"t" : %lu,
|
||||
"vcc" : %.3f,
|
||||
"rssi": %d,
|
||||
"temp": %.2f,
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"id" : "%s",
|
||||
"name" : "%s",
|
||||
"up" : %u,
|
||||
"t" : %lld,
|
||||
"t" : %lu,
|
||||
"vcc" : %.3f,
|
||||
"rssi": %d,
|
||||
"temp": %.2f,
|
||||
@ -24,7 +24,7 @@
|
||||
"tPO" : %.3f,
|
||||
"tQI" : %.3f,
|
||||
"tQO" : %.3f,
|
||||
"rtc" : %lld
|
||||
"rtc" : %lu
|
||||
},
|
||||
"realtime" : {
|
||||
"h" : %.2f,
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"id" : "%s",
|
||||
"name" : "%s",
|
||||
"up" : %u,
|
||||
"t" : %lld,
|
||||
"t" : %lu,
|
||||
"vcc" : %.3f,
|
||||
"rssi": %d,
|
||||
"temp": %.2f,
|
||||
@ -34,7 +34,7 @@
|
||||
"tPO" : %.2f,
|
||||
"tQI" : %.2f,
|
||||
"tQO" : %.2f,
|
||||
"rtc" : %lld
|
||||
"rtc" : %lu
|
||||
},
|
||||
"realtime" : {
|
||||
"h" : %.2f,
|
||||
|
||||
@ -92,7 +92,9 @@ bool RawMqttHandler::publish(AmsData* data, AmsData* meterState, EnergyAccountin
|
||||
}
|
||||
mqtt->publish(topic + "/realtime/import/hour", String(ea->getUseThisHour(), 3));
|
||||
mqtt->publish(topic + "/realtime/import/day", String(ea->getUseToday(), 2));
|
||||
for(uint8_t i = 1; i <= ea->getConfig()->hours; i++) {
|
||||
uint8_t peakCount = ea->getConfig()->hours;
|
||||
if(peakCount > 5) peakCount = 5;
|
||||
for(uint8_t i = 1; i <= peakCount; i++) {
|
||||
mqtt->publish(topic + "/realtime/import/peak/" + String(i, 10), String(ea->getPeak(i), 10), true, 0);
|
||||
}
|
||||
mqtt->publish(topic + "/realtime/import/threshold", String(ea->getCurrentThreshold(), 10), true, 0);
|
||||
|
||||
@ -307,7 +307,7 @@ void setup() {
|
||||
}
|
||||
|
||||
debugI(" flashing");
|
||||
File firmwareFile = LittleFS.open(FILE_FIRMWARE, "r");
|
||||
File firmwareFile = LittleFS.open(FILE_FIRMWARE, (char*) "r");
|
||||
debugD(" firmware size: %d", firmwareFile.size());
|
||||
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
|
||||
debugD(" available: %d", maxSketchSpace);
|
||||
@ -358,7 +358,7 @@ void setup() {
|
||||
|
||||
NtpConfig ntp;
|
||||
if(config.getNtpConfig(ntp)) {
|
||||
configTime(ntp.offset*10, ntp.summerOffset*10, ntp.enable ? strlen(ntp.server) > 0 ? ntp.server : "pool.ntp.org" : ""); // Add NTP server by default if none is configured
|
||||
configTime(ntp.offset*10, ntp.summerOffset*10, ntp.enable ? strlen(ntp.server) > 0 ? ntp.server : (char*) F("pool.ntp.org") : (char*) F("")); // Add NTP server by default if none is configured
|
||||
sntp_servermode_dhcp(ntp.enable && ntp.dhcp ? 1 : 0);
|
||||
ntpEnabled = ntp.enable;
|
||||
TimeChangeRule std = {"STD", Last, Sun, Oct, 3, ntp.offset / 6};
|
||||
@ -473,7 +473,7 @@ void loop() {
|
||||
if(strlen(wifi.hostname) > 0 && wifi.mdns) {
|
||||
debugD("mDNS is enabled, using host: %s", wifi.hostname);
|
||||
if(MDNS.begin(wifi.hostname)) {
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
MDNS.addService(F("http"), F("tcp"), 80);
|
||||
} else {
|
||||
debugE("Failed to set up mDNS!");
|
||||
}
|
||||
@ -607,7 +607,7 @@ void loop() {
|
||||
}
|
||||
|
||||
void setupHanPort(uint8_t pin, uint32_t baud, uint8_t parityOrdinal, bool invert) {
|
||||
if(Debug.isActive(RemoteDebug::INFO)) Debug.printf("(setupHanPort) Setting up HAN on pin %d with baud %d and parity %d\n", pin, baud, parityOrdinal);
|
||||
if(Debug.isActive(RemoteDebug::INFO)) Debug.printf((char*) F("(setupHanPort) Setting up HAN on pin %d with baud %d and parity %d\n"), pin, baud, parityOrdinal);
|
||||
|
||||
HardwareSerial *hwSerial = NULL;
|
||||
if(pin == 3 || pin == 113) {
|
||||
@ -658,14 +658,11 @@ void setupHanPort(uint8_t pin, uint32_t baud, uint8_t parityOrdinal, bool invert
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
hwSerial->begin(baud, serialConfig, -1, -1, invert);
|
||||
hwSerial->setRxBufferSize(768);
|
||||
uart_set_pin(UART_NUM_1, UART_PIN_NO_CHANGE, pin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
||||
#elif defined(ESP32)
|
||||
hwSerial->begin(baud, serialConfig, -1, -1, invert);
|
||||
hwSerial->setRxBufferSize(768);
|
||||
#else
|
||||
hwSerial->begin(baud, serialConfig, SERIAL_FULL, 1, invert);
|
||||
hwSerial->setRxBufferSize(768);
|
||||
#endif
|
||||
|
||||
#if defined(ESP8266)
|
||||
@ -765,14 +762,14 @@ void swapWifiMode() {
|
||||
|
||||
if (mode != WIFI_AP || !config.hasConfig()) {
|
||||
if(Debug.isActive(RemoteDebug::INFO)) debugI("Swapping to AP mode");
|
||||
WiFi.softAP("AMS2MQTT");
|
||||
WiFi.softAP((char*) F("AMS2MQTT"));
|
||||
WiFi.mode(WIFI_AP);
|
||||
|
||||
if(dnsServer == NULL) {
|
||||
dnsServer = new DNSServer();
|
||||
}
|
||||
dnsServer->setErrorReplyCode(DNSReplyCode::NoError);
|
||||
dnsServer->start(53, "*", WiFi.softAPIP());
|
||||
dnsServer->start(53, (char*) F("*"), WiFi.softAPIP());
|
||||
} else {
|
||||
if(Debug.isActive(RemoteDebug::INFO)) debugI("Swapping to STA mode");
|
||||
if(dnsServer != NULL) {
|
||||
@ -813,7 +810,7 @@ bool readHanPort() {
|
||||
hanBuffer[len++] = hanSerial->read();
|
||||
ctx.length = len;
|
||||
pos = unwrapData((uint8_t *) hanBuffer, ctx);
|
||||
if(pos >= 0) {
|
||||
if(ctx.type > 0 && pos >= 0) {
|
||||
if(ctx.type == DATA_TAG_DLMS) {
|
||||
debugV("Received valid DLMS at %d", pos);
|
||||
} else if(ctx.type == DATA_TAG_DSMR) {
|
||||
@ -829,6 +826,7 @@ bool readHanPort() {
|
||||
if(pos == DATA_PARSE_INCOMPLETE) {
|
||||
return false;
|
||||
} else if(pos == DATA_PARSE_UNKNOWN_DATA) {
|
||||
debugV("Unknown data payload:");
|
||||
len = len + hanSerial->readBytes(hanBuffer+len, BUF_SIZE_HAN-len);
|
||||
debugPrint(hanBuffer, 0, len);
|
||||
len = 0;
|
||||
@ -978,13 +976,13 @@ void printHanReadError(int pos) {
|
||||
void debugPrint(byte *buffer, int start, int length) {
|
||||
for (int i = start; i < start + length; i++) {
|
||||
if (buffer[i] < 0x10)
|
||||
Debug.print("0");
|
||||
Debug.print(F("0"));
|
||||
Debug.print(buffer[i], HEX);
|
||||
Debug.print(" ");
|
||||
Debug.print(F(" "));
|
||||
if ((i - start + 1) % 16 == 0)
|
||||
Debug.println("");
|
||||
else if ((i - start + 1) % 4 == 0)
|
||||
Debug.print(" ");
|
||||
Debug.print(F(" "));
|
||||
|
||||
yield(); // Let other get some resources too
|
||||
}
|
||||
@ -1057,7 +1055,6 @@ void WiFi_connect() {
|
||||
}
|
||||
#endif
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.setSleep(WIFI_PS_MAX_MODEM);
|
||||
#if defined(ESP32)
|
||||
if(wifi.power >= 195)
|
||||
WiFi.setTxPower(WIFI_POWER_19_5dBm);
|
||||
@ -1099,7 +1096,7 @@ void WiFi_connect() {
|
||||
if(strlen(wifi.dns2) > 0) {
|
||||
dns2.fromString(wifi.dns2);
|
||||
} else if(dns1.toString().isEmpty()) {
|
||||
dns2.fromString("208.67.220.220"); // Add OpenDNS as second by default if nothing is configured
|
||||
dns2.fromString(F("208.67.220.220")); // Add OpenDNS as second by default if nothing is configured
|
||||
}
|
||||
if(!WiFi.config(ip, gw, sn, dns1, dns2)) {
|
||||
debugE("Static IP configuration is invalid, not using");
|
||||
@ -1118,6 +1115,9 @@ void WiFi_connect() {
|
||||
WiFi.setAutoReconnect(true);
|
||||
WiFi.persistent(true);
|
||||
if(WiFi.begin(wifi.ssid, wifi.psk)) {
|
||||
if(wifi.sleep <= 2) {
|
||||
WiFi.setSleep(wifi.sleep);
|
||||
}
|
||||
yield();
|
||||
} else {
|
||||
if (Debug.isActive(RemoteDebug::ERROR)) debugI("Unable to start WiFi");
|
||||
@ -1176,7 +1176,7 @@ int16_t unwrapData(uint8_t *buf, DataParserContext &context) {
|
||||
if(res >= 0) doRet = true;
|
||||
break;
|
||||
default:
|
||||
debugE("Ended up in default case while unwrapping...");
|
||||
debugE("Ended up in default case while unwrapping...(tag %02X)", tag);
|
||||
return DATA_PARSE_UNKNOWN_DATA;
|
||||
}
|
||||
lastTag = tag;
|
||||
@ -1327,7 +1327,7 @@ void MQTT_connect() {
|
||||
|
||||
if(LittleFS.exists(FILE_MQTT_CA)) {
|
||||
debugI("Found MQTT CA file (%dkb free heap)", ESP.getFreeHeap());
|
||||
file = LittleFS.open(FILE_MQTT_CA, "r");
|
||||
file = LittleFS.open(FILE_MQTT_CA, (char*) "r");
|
||||
#if defined(ESP8266)
|
||||
BearSSL::X509List *serverTrustedCA = new BearSSL::X509List(file);
|
||||
mqttSecureClient->setTrustAnchors(serverTrustedCA);
|
||||
@ -1340,12 +1340,12 @@ void MQTT_connect() {
|
||||
if(LittleFS.exists(FILE_MQTT_CERT) && LittleFS.exists(FILE_MQTT_KEY)) {
|
||||
#if defined(ESP8266)
|
||||
debugI("Found MQTT certificate file (%dkb free heap)", ESP.getFreeHeap());
|
||||
file = LittleFS.open(FILE_MQTT_CERT, "r");
|
||||
file = LittleFS.open(FILE_MQTT_CERT, (char*) "r");
|
||||
BearSSL::X509List *serverCertList = new BearSSL::X509List(file);
|
||||
file.close();
|
||||
|
||||
debugI("Found MQTT key file (%dkb free heap)", ESP.getFreeHeap());
|
||||
file = LittleFS.open(FILE_MQTT_KEY, "r");
|
||||
file = LittleFS.open(FILE_MQTT_KEY, (char*) "r");
|
||||
BearSSL::PrivateKey *serverPrivKey = new BearSSL::PrivateKey(file);
|
||||
file.close();
|
||||
|
||||
@ -1353,12 +1353,12 @@ void MQTT_connect() {
|
||||
mqttSecureClient->setClientRSACert(serverCertList, serverPrivKey);
|
||||
#elif defined(ESP32)
|
||||
debugI("Found MQTT certificate file (%dkb free heap)", ESP.getFreeHeap());
|
||||
file = LittleFS.open(FILE_MQTT_CERT, "r");
|
||||
file = LittleFS.open(FILE_MQTT_CERT, (char*) "r");
|
||||
mqttSecureClient->loadCertificate(file, file.size());
|
||||
file.close();
|
||||
|
||||
debugI("Found MQTT key file (%dkb free heap)", ESP.getFreeHeap());
|
||||
file = LittleFS.open(FILE_MQTT_KEY, "r");
|
||||
file = LittleFS.open(FILE_MQTT_KEY, (char*) "r");
|
||||
mqttSecureClient->loadPrivateKey(file, file.size());
|
||||
file.close();
|
||||
#endif
|
||||
@ -1424,7 +1424,7 @@ void configFileParse() {
|
||||
return;
|
||||
}
|
||||
|
||||
File file = LittleFS.open(FILE_CFG, "r");
|
||||
File file = LittleFS.open(FILE_CFG, (char*) "r");
|
||||
|
||||
bool lSys = false;
|
||||
bool lWiFi = false;
|
||||
@ -1454,195 +1454,196 @@ void configFileParse() {
|
||||
char* buf = (char*) commonBuffer;
|
||||
memset(buf, 0, 1024);
|
||||
while((size = file.readBytesUntil('\n', buf, 1024)) > 0) {
|
||||
if(strncmp(buf, "boardType ", 10) == 0) {
|
||||
if(strncmp_P(buf, PSTR("boardType "), 10) == 0) {
|
||||
if(!lSys) { config.getSystemConfig(sys); lSys = true; };
|
||||
sys.boardType = String(buf+10).toInt();
|
||||
} else if(strncmp(buf, "ssid ", 5) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("ssid "), 5) == 0) {
|
||||
if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; };
|
||||
memcpy(wifi.ssid, buf+5, size-5);
|
||||
} else if(strncmp(buf, "psk ", 4) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("psk "), 4) == 0) {
|
||||
if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; };
|
||||
memcpy(wifi.psk, buf+4, size-4);
|
||||
} else if(strncmp(buf, "ip ", 3) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("ip "), 3) == 0) {
|
||||
if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; };
|
||||
memcpy(wifi.ip, buf+3, size-3);
|
||||
} else if(strncmp(buf, "gateway ", 8) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gateway "), 8) == 0) {
|
||||
if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; };
|
||||
memcpy(wifi.gateway, buf+8, size-8);
|
||||
} else if(strncmp(buf, "subnet ", 7) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("subnet "), 7) == 0) {
|
||||
if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; };
|
||||
memcpy(wifi.subnet, buf+7, size-7);
|
||||
} else if(strncmp(buf, "dns1 ", 5) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("dns1 "), 5) == 0) {
|
||||
if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; };
|
||||
memcpy(wifi.dns1, buf+5, size-5);
|
||||
} else if(strncmp(buf, "dns2 ", 5) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("dns2 "), 5) == 0) {
|
||||
if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; };
|
||||
memcpy(wifi.dns2, buf+5, size-5);
|
||||
} else if(strncmp(buf, "hostname ", 9) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("hostname "), 9) == 0) {
|
||||
if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; };
|
||||
memcpy(wifi.hostname, buf+9, size-9);
|
||||
} else if(strncmp(buf, "mdns ", 5) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("mdns "), 5) == 0) {
|
||||
if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; };
|
||||
wifi.mdns = String(buf+5).toInt() == 1;;
|
||||
} else if(strncmp(buf, "mqttHost ", 9) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("mqttHost "), 9) == 0) {
|
||||
if(!lMqtt) { config.getMqttConfig(mqtt); lMqtt = true; };
|
||||
memcpy(mqtt.host, buf+9, size-9);
|
||||
} else if(strncmp(buf, "mqttPort ", 9) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("mqttPort "), 9) == 0) {
|
||||
if(!lMqtt) { config.getMqttConfig(mqtt); lMqtt = true; };
|
||||
mqtt.port = String(buf+9).toInt();
|
||||
} else if(strncmp(buf, "mqttClientId ", 13) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("mqttClientId "), 13) == 0) {
|
||||
if(!lMqtt) { config.getMqttConfig(mqtt); lMqtt = true; };
|
||||
memcpy(mqtt.clientId, buf+13, size-13);
|
||||
} else if(strncmp(buf, "mqttPublishTopic ", 17) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("mqttPublishTopic "), 17) == 0) {
|
||||
if(!lMqtt) { config.getMqttConfig(mqtt); lMqtt = true; };
|
||||
memcpy(mqtt.publishTopic, buf+17, size-17);
|
||||
} else if(strncmp(buf, "mqttUsername ", 13) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("mqttUsername "), 13) == 0) {
|
||||
if(!lMqtt) { config.getMqttConfig(mqtt); lMqtt = true; };
|
||||
memcpy(mqtt.username, buf+13, size-13);
|
||||
} else if(strncmp(buf, "mqttPassword ", 13) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("mqttPassword "), 13) == 0) {
|
||||
if(!lMqtt) { config.getMqttConfig(mqtt); lMqtt = true; };
|
||||
memcpy(mqtt.password, buf+13, size-13);
|
||||
} else if(strncmp(buf, "mqttPayloadFormat ", 18) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("mqttPayloadFormat "), 18) == 0) {
|
||||
if(!lMqtt) { config.getMqttConfig(mqtt); lMqtt = true; };
|
||||
mqtt.payloadFormat = String(buf+18).toInt();
|
||||
} else if(strncmp(buf, "mqttSsl ", 8) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("mqttSsl "), 8) == 0) {
|
||||
if(!lMqtt) { config.getMqttConfig(mqtt); lMqtt = true; };
|
||||
mqtt.ssl = String(buf+8).toInt() == 1;;
|
||||
} else if(strncmp(buf, "webSecurity ", 12) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("webSecurity "), 12) == 0) {
|
||||
if(!lWeb) { config.getWebConfig(web); lWeb = true; };
|
||||
web.security = String(buf+12).toInt();
|
||||
} else if(strncmp(buf, "webUsername ", 12) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("webUsername "), 12) == 0) {
|
||||
if(!lWeb) { config.getWebConfig(web); lWeb = true; };
|
||||
memcpy(web.username, buf+12, size-12);
|
||||
} else if(strncmp(buf, "webPassword ", 12) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("webPassword "), 12) == 0) {
|
||||
if(!lWeb) { config.getWebConfig(web); lWeb = true; };
|
||||
memcpy(web.username, buf+12, size-12);
|
||||
} else if(strncmp(buf, "meterBaud ", 10) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("meterBaud "), 10) == 0) {
|
||||
if(!lMeter) { config.getMeterConfig(meter); lMeter = true; };
|
||||
meter.baud = String(buf+10).toInt();
|
||||
} else if(strncmp(buf, "meterParity ", 12) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("meterParity "), 12) == 0) {
|
||||
if(!lMeter) { config.getMeterConfig(meter); lMeter = true; };
|
||||
if(strncmp(buf+12, "7N1", 3) == 0) meter.parity = 2;
|
||||
if(strncmp(buf+12, "8N1", 3) == 0) meter.parity = 3;
|
||||
if(strncmp(buf+12, "7E1", 3) == 0) meter.parity = 10;
|
||||
if(strncmp(buf+12, "8E1", 3) == 0) meter.parity = 11;
|
||||
} else if(strncmp(buf, "meterInvert ", 12) == 0) {
|
||||
if(strncmp_P(buf+12, PSTR("7N1"), 3) == 0) meter.parity = 2;
|
||||
if(strncmp_P(buf+12, PSTR("8N1"), 3) == 0) meter.parity = 3;
|
||||
if(strncmp_P(buf+12, PSTR("7E1"), 3) == 0) meter.parity = 10;
|
||||
if(strncmp_P(buf+12, PSTR("8E1"), 3) == 0) meter.parity = 11;
|
||||
} else if(strncmp_P(buf, PSTR("meterInvert "), 12) == 0) {
|
||||
if(!lMeter) { config.getMeterConfig(meter); lMeter = true; };
|
||||
meter.invert = String(buf+12).toInt() == 1;;
|
||||
} else if(strncmp(buf, "meterDistributionSystem ", 24) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("meterDistributionSystem "), 24) == 0) {
|
||||
if(!lMeter) { config.getMeterConfig(meter); lMeter = true; };
|
||||
meter.distributionSystem = String(buf+24).toInt();
|
||||
} else if(strncmp(buf, "meterMainFuse ", 14) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("meterMainFuse "), 14) == 0) {
|
||||
if(!lMeter) { config.getMeterConfig(meter); lMeter = true; };
|
||||
meter.mainFuse = String(buf+14).toInt();
|
||||
} else if(strncmp(buf, "meterProductionCapacity ", 24) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("meterProductionCapacity "), 24) == 0) {
|
||||
if(!lMeter) { config.getMeterConfig(meter); lMeter = true; };
|
||||
meter.productionCapacity = String(buf+24).toInt();
|
||||
} else if(strncmp(buf, "meterEncryptionKey ", 19) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("meterEncryptionKey "), 19) == 0) {
|
||||
if(!lMeter) { config.getMeterConfig(meter); lMeter = true; };
|
||||
fromHex(meter.encryptionKey, String(buf+19), 16);
|
||||
} else if(strncmp(buf, "meterAuthenticationKey ", 23) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("meterAuthenticationKey "), 23) == 0) {
|
||||
if(!lMeter) { config.getMeterConfig(meter); lMeter = true; };
|
||||
fromHex(meter.authenticationKey, String(buf+19), 16);
|
||||
} else if(strncmp(buf, "gpioHanPin ", 11) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gpioHanPin "), 11) == 0) {
|
||||
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
|
||||
gpio.hanPin = String(buf+11).toInt();
|
||||
} else if(strncmp(buf, "gpioApPin ", 10) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gpioApPin "), 10) == 0) {
|
||||
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
|
||||
gpio.apPin = String(buf+10).toInt();
|
||||
} else if(strncmp(buf, "gpioLedPin ", 11) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gpioLedPin "), 11) == 0) {
|
||||
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
|
||||
gpio.ledPin = String(buf+11).toInt();
|
||||
} else if(strncmp(buf, "gpioLedInverted ", 16) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gpioLedInverted "), 16) == 0) {
|
||||
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
|
||||
gpio.ledInverted = String(buf+16).toInt() == 1;
|
||||
} else if(strncmp(buf, "gpioLedPinRed ", 14) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gpioLedPinRed "), 14) == 0) {
|
||||
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
|
||||
gpio.ledPinRed = String(buf+14).toInt();
|
||||
} else if(strncmp(buf, "gpioLedPinGreen ", 16) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gpioLedPinGreen "), 16) == 0) {
|
||||
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
|
||||
gpio.ledPinGreen = String(buf+16).toInt();
|
||||
} else if(strncmp(buf, "gpioLedPinBlue ", 15) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gpioLedPinBlue "), 15) == 0) {
|
||||
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
|
||||
gpio.ledPinBlue = String(buf+15).toInt();
|
||||
} else if(strncmp(buf, "gpioLedRgbInverted ", 19) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gpioLedRgbInverted "), 19) == 0) {
|
||||
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
|
||||
gpio.ledRgbInverted = String(buf+19).toInt() == 1;
|
||||
} else if(strncmp(buf, "gpioTempSensorPin ", 18) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gpioTempSensorPin "), 18) == 0) {
|
||||
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
|
||||
gpio.tempSensorPin = String(buf+18).toInt();
|
||||
} else if(strncmp(buf, "gpioTempAnalogSensorPin ", 24) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gpioTempAnalogSensorPin "), 24) == 0) {
|
||||
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
|
||||
gpio.tempAnalogSensorPin = String(buf+24).toInt();
|
||||
} else if(strncmp(buf, "gpioVccPin ", 11) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gpioVccPin "), 11) == 0) {
|
||||
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
|
||||
gpio.vccPin = String(buf+11).toInt();
|
||||
} else if(strncmp(buf, "gpioVccOffset ", 14) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gpioVccOffset "), 14) == 0) {
|
||||
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
|
||||
gpio.vccOffset = String(buf+14).toDouble() * 100;
|
||||
} else if(strncmp(buf, "gpioVccMultiplier ", 18) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gpioVccMultiplier "), 18) == 0) {
|
||||
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
|
||||
gpio.vccMultiplier = String(buf+18).toDouble() * 1000;
|
||||
} else if(strncmp(buf, "gpioVccBootLimit ", 17) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gpioVccBootLimit "), 17) == 0) {
|
||||
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
|
||||
gpio.vccBootLimit = String(buf+17).toDouble() * 10;
|
||||
} else if(strncmp(buf, "gpioVccResistorGnd ", 19) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gpioVccResistorGnd "), 19) == 0) {
|
||||
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
|
||||
gpio.vccResistorGnd = String(buf+19).toInt();
|
||||
} else if(strncmp(buf, "gpioVccResistorVcc ", 19) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("gpioVccResistorVcc "), 19) == 0) {
|
||||
if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; };
|
||||
gpio.vccResistorVcc = String(buf+19).toInt();
|
||||
} else if(strncmp(buf, "domoticzElidx ", 14) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("domoticzElidx "), 14) == 0) {
|
||||
if(!lDomo) { config.getDomoticzConfig(domo); lDomo = true; };
|
||||
domo.elidx = String(buf+14).toInt();
|
||||
} else if(strncmp(buf, "domoticzVl1idx ", 15) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("domoticzVl1idx "), 15) == 0) {
|
||||
if(!lDomo) { config.getDomoticzConfig(domo); lDomo = true; };
|
||||
domo.vl1idx = String(buf+15).toInt();
|
||||
} else if(strncmp(buf, "domoticzVl2idx ", 15) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("domoticzVl2idx "), 15) == 0) {
|
||||
if(!lDomo) { config.getDomoticzConfig(domo); lDomo = true; };
|
||||
domo.vl2idx = String(buf+15).toInt();
|
||||
} else if(strncmp(buf, "domoticzVl3idx ", 15) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("domoticzVl3idx "), 15) == 0) {
|
||||
if(!lDomo) { config.getDomoticzConfig(domo); lDomo = true; };
|
||||
domo.vl3idx = String(buf+15).toInt();
|
||||
} else if(strncmp(buf, "domoticzCl1idx ", 15) == 0) {
|
||||
} 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(buf, "ntpEnable ", 10) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("ntpEnable "), 10) == 0) {
|
||||
if(!lNtp) { config.getNtpConfig(ntp); lNtp = true; };
|
||||
ntp.enable = String(buf+10).toInt() == 1;
|
||||
} else if(strncmp(buf, "ntpDhcp ", 8) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("ntpDhcp "), 8) == 0) {
|
||||
if(!lNtp) { config.getNtpConfig(ntp); lNtp = true; };
|
||||
ntp.dhcp = String(buf+8).toInt() == 1;
|
||||
} else if(strncmp(buf, "ntpOffset ", 10) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("ntpOffset "), 10) == 0) {
|
||||
if(!lNtp) { config.getNtpConfig(ntp); lNtp = true; };
|
||||
ntp.offset = String(buf+10).toInt() / 10;
|
||||
} else if(strncmp(buf, "ntpSummerOffset ", 16) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("ntpSummerOffset "), 16) == 0) {
|
||||
if(!lNtp) { config.getNtpConfig(ntp); lNtp = true; };
|
||||
ntp.summerOffset = String(buf+16).toInt() / 10;
|
||||
} else if(strncmp(buf, "ntpServer ", 10) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("ntpServer "), 10) == 0) {
|
||||
if(!lNtp) { config.getNtpConfig(ntp); lNtp = true; };
|
||||
memcpy(ntp.server, buf+10, size-10);
|
||||
} else if(strncmp(buf, "entsoeToken ", 12) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("entsoeToken "), 12) == 0) {
|
||||
if(!lEntsoe) { config.getEntsoeConfig(entsoe); lEntsoe = true; };
|
||||
memcpy(entsoe.token, buf+12, size-12);
|
||||
} else if(strncmp(buf, "entsoeArea ", 11) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("entsoeArea "), 11) == 0) {
|
||||
if(!lEntsoe) { config.getEntsoeConfig(entsoe); lEntsoe = true; };
|
||||
memcpy(entsoe.area, buf+11, size-11);
|
||||
} else if(strncmp(buf, "entsoeCurrency ", 15) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("entsoeCurrency "), 15) == 0) {
|
||||
if(!lEntsoe) { config.getEntsoeConfig(entsoe); lEntsoe = true; };
|
||||
memcpy(entsoe.currency, buf+15, size-15);
|
||||
} else if(strncmp(buf, "entsoeMultiplier ", 17) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("entsoeMultiplier "), 17) == 0) {
|
||||
if(!lEntsoe) { config.getEntsoeConfig(entsoe); lEntsoe = true; };
|
||||
entsoe.multiplier = String(buf+17).toDouble() * 1000;
|
||||
} else if(strncmp(buf, "thresholds ", 11) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("thresholds "), 11) == 0) {
|
||||
if(!lEac) { config.getEnergyAccountingConfig(eac); lEac = true; };
|
||||
int i = 0;
|
||||
char * pch = strtok (buf+11," ");
|
||||
while (pch != NULL) {
|
||||
while (pch != NULL && i < 10) {
|
||||
eac.thresholds[i++] = String(pch).toInt();
|
||||
pch = strtok (NULL, " ");
|
||||
}
|
||||
} else if(strncmp(buf, "dayplot ", 8) == 0) {
|
||||
eac.hours = String(pch).toInt();
|
||||
} else if(strncmp_P(buf, PSTR("dayplot "), 8) == 0) {
|
||||
int i = 0;
|
||||
DayDataPoints day = { 4 }; // Use a version we know the multiplier of the data points
|
||||
char * pch = strtok (buf+8," ");
|
||||
@ -1665,7 +1666,7 @@ void configFileParse() {
|
||||
}
|
||||
ds.setDayData(day);
|
||||
sDs = true;
|
||||
} else if(strncmp(buf, "monthplot ", 10) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("monthplot "), 10) == 0) {
|
||||
int i = 0;
|
||||
MonthDataPoints month = { 5 }; // Use a version we know the multiplier of the data points
|
||||
char * pch = strtok (buf+10," ");
|
||||
@ -1688,7 +1689,7 @@ void configFileParse() {
|
||||
}
|
||||
ds.setMonthData(month);
|
||||
sDs = true;
|
||||
} else if(strncmp(buf, "energyaccounting ", 17) == 0) {
|
||||
} else if(strncmp_P(buf, PSTR("energyaccounting "), 17) == 0) {
|
||||
uint8_t i = 0;
|
||||
EnergyAccountingData ead = { 4, 0,
|
||||
0, 0, 0,
|
||||
@ -1753,6 +1754,7 @@ void configFileParse() {
|
||||
if(lDomo) config.setDomoticzConfig(domo);
|
||||
if(lNtp) config.setNtpConfig(ntp);
|
||||
if(lEntsoe) config.setEntsoeConfig(entsoe);
|
||||
if(lEac) config.setEnergyAccountingConfig(eac);
|
||||
if(sDs) ds.save();
|
||||
if(sEa) ea.save();
|
||||
config.save();
|
||||
|
||||
85
src/LNG.cpp
85
src/LNG.cpp
@ -1,6 +1,6 @@
|
||||
#include "LNG.h"
|
||||
#include "lwip/def.h"
|
||||
#include "ams/Cosem.h"
|
||||
#include "ams/ntohll.h"
|
||||
|
||||
LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, RemoteDebug* debugger) {
|
||||
LngHeader* h = (LngHeader*) payload;
|
||||
@ -11,9 +11,10 @@ LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, Da
|
||||
uint8_t* ptr = (uint8_t*) &h[1];
|
||||
uint8_t* data = ptr + (18*h->arrayLength); // Skip descriptors
|
||||
|
||||
uint16_t o170 = 0, o270 = 0;
|
||||
uint16_t o181 = 0, o182 = 0;
|
||||
uint16_t o281 = 0, o282 = 0;
|
||||
uint64_t o170 = 0, o270 = 0;
|
||||
uint64_t o180 = 0, o280 = 0;
|
||||
uint64_t o181 = 0, o182 = 0;
|
||||
uint64_t o281 = 0, o282 = 0;
|
||||
LngObisDescriptor* descriptor = (LngObisDescriptor*) ptr;
|
||||
for(uint8_t x = 0; x < h->arrayLength-1; x++) {
|
||||
ptr = (uint8_t*) &descriptor[1];
|
||||
@ -24,39 +25,41 @@ LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, Da
|
||||
if(descriptor->obis[2] == 1) {
|
||||
if(descriptor->obis[3] == 7) {
|
||||
if(descriptor->obis[4] == 0) {
|
||||
o170 = ntohl(item->dlu.data);
|
||||
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data));
|
||||
o170 = getNumber(item);
|
||||
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o170);
|
||||
}
|
||||
} else if(descriptor->obis[3] == 8) {
|
||||
if(descriptor->obis[4] == 0) {
|
||||
activeImportCounter = ntohl(item->dlu.data) / 1000.0;
|
||||
o180 = getNumber(item);
|
||||
listType = listType >= 3 ? listType : 3;
|
||||
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data));
|
||||
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o180);
|
||||
activeImportCounter = o180 / 1000.0;
|
||||
} else if(descriptor->obis[4] == 1) {
|
||||
o181 = ntohl(item->dlu.data);
|
||||
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data));
|
||||
o181 = getNumber(item);
|
||||
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o181);
|
||||
} else if(descriptor->obis[4] == 2) {
|
||||
o182 = ntohl(item->dlu.data);
|
||||
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data));
|
||||
o182 = getNumber(item);
|
||||
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o182);
|
||||
}
|
||||
}
|
||||
} else if(descriptor->obis[2] == 2) {
|
||||
if(descriptor->obis[3] == 7) {
|
||||
if(descriptor->obis[4] == 0) {
|
||||
o270 = ntohl(item->dlu.data);
|
||||
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data));
|
||||
o270 = getNumber(item);
|
||||
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o270);
|
||||
}
|
||||
} else if(descriptor->obis[3] == 8) {
|
||||
if(descriptor->obis[4] == 0) {
|
||||
activeExportCounter = ntohl(item->dlu.data) / 1000.0;
|
||||
o280 = getNumber(item);
|
||||
listType = listType >= 3 ? listType : 3;
|
||||
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data));
|
||||
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o280);
|
||||
activeExportCounter = o280 / 1000.0;
|
||||
} else if(descriptor->obis[4] == 1) {
|
||||
o281 = ntohl(item->dlu.data);
|
||||
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data));
|
||||
o281 = getNumber(item);
|
||||
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o281);
|
||||
} else if(descriptor->obis[4] == 2) {
|
||||
o282 = ntohl(item->dlu.data);
|
||||
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data));
|
||||
o282 = getNumber(item);
|
||||
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o282);
|
||||
}
|
||||
}
|
||||
} else if(descriptor->obis[2] == 96) {
|
||||
@ -101,11 +104,49 @@ LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, Da
|
||||
|
||||
if((*data) == 0x09) {
|
||||
data += (*(data+1))+2;
|
||||
} else {
|
||||
} else if((*data) == 0x15) {
|
||||
data += 9;
|
||||
} else if((*data) == 0x06) {
|
||||
data += 5;
|
||||
} else if((*data) == 0x12) {
|
||||
data += 3;
|
||||
}
|
||||
|
||||
lastUpdateMillis = millis();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t LNG::getNumber(CosemData* item) {
|
||||
if(item != NULL) {
|
||||
uint64_t ret = 0.0;
|
||||
switch(item->base.type) {
|
||||
case CosemTypeLongSigned: {
|
||||
int16_t i16 = ntohs(item->ls.data);
|
||||
return i16;
|
||||
}
|
||||
case CosemTypeLongUnsigned: {
|
||||
uint16_t u16 = ntohs(item->lu.data);
|
||||
return u16;
|
||||
}
|
||||
case CosemTypeDLongSigned: {
|
||||
int32_t i32 = ntohl(item->dlu.data);
|
||||
return i32;
|
||||
}
|
||||
case CosemTypeDLongUnsigned: {
|
||||
uint32_t u32 = ntohl(item->dlu.data);
|
||||
return u32;
|
||||
}
|
||||
case CosemTypeLong64Signed: {
|
||||
int64_t i64 = ntohll(item->l64s.data);
|
||||
return i64;
|
||||
}
|
||||
case CosemTypeLong64Unsigned: {
|
||||
uint64_t u64 = ntohll(item->l64u.data);
|
||||
return u64;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "AmsData.h"
|
||||
#include "AmsConfiguration.h"
|
||||
#include "ams/DataParser.h"
|
||||
#include "ams/Cosem.h"
|
||||
#include "RemoteDebug.h"
|
||||
|
||||
struct LngHeader {
|
||||
@ -25,6 +26,7 @@ struct LngObisDescriptor {
|
||||
class LNG : public AmsData {
|
||||
public:
|
||||
LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, RemoteDebug* debugger);
|
||||
uint64_t getNumber(CosemData* item);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user