mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-04-10 15:28:55 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e232b875fa | ||
|
|
f18171fecc | ||
|
|
a3c7a09211 | ||
|
|
a6f3bc3f71 | ||
|
|
4e451c51e1 | ||
|
|
43def1c311 |
@@ -32,6 +32,10 @@ ADC_MODE(ADC_VCC);
|
|||||||
#endif
|
#endif
|
||||||
#define WDT_TIMEOUT 60
|
#define WDT_TIMEOUT 60
|
||||||
|
|
||||||
|
#if defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||||
|
#include <driver/uart.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
#include "AmsToMqttBridge.h"
|
#include "AmsToMqttBridge.h"
|
||||||
@@ -619,9 +623,7 @@ void setupHanPort(uint8_t pin, uint32_t baud, uint8_t parityOrdinal, bool invert
|
|||||||
hwSerial = &Serial2;
|
hwSerial = &Serial2;
|
||||||
}
|
}
|
||||||
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||||
if(pin == 18) {
|
hwSerial = &Serial1;
|
||||||
hwSerial = &Serial1;
|
|
||||||
}
|
|
||||||
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
|
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -654,7 +656,11 @@ void setupHanPort(uint8_t pin, uint32_t baud, uint8_t parityOrdinal, bool invert
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ESP32)
|
#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->begin(baud, serialConfig, -1, -1, invert);
|
||||||
hwSerial->setRxBufferSize(768);
|
hwSerial->setRxBufferSize(768);
|
||||||
#else
|
#else
|
||||||
@@ -829,6 +835,7 @@ bool readHanPort() {
|
|||||||
len += hanSerial->readBytes(hanBuffer+len, BUF_SIZE_HAN-len);
|
len += hanSerial->readBytes(hanBuffer+len, BUF_SIZE_HAN-len);
|
||||||
if(mqttEnabled && mqtt != NULL && mqttHandler == NULL) {
|
if(mqttEnabled && mqtt != NULL && mqttHandler == NULL) {
|
||||||
mqtt->publish(topic.c_str(), toHex(hanBuffer+pos, len));
|
mqtt->publish(topic.c_str(), toHex(hanBuffer+pos, len));
|
||||||
|
mqtt->loop();
|
||||||
}
|
}
|
||||||
while(hanSerial->available()) hanSerial->read(); // Make sure it is all empty, in case we overflowed buffer above
|
while(hanSerial->available()) hanSerial->read(); // Make sure it is all empty, in case we overflowed buffer above
|
||||||
len = 0;
|
len = 0;
|
||||||
@@ -845,6 +852,7 @@ bool readHanPort() {
|
|||||||
// If MQTT bytestream payload is selected (mqttHandler == NULL), send the payload to MQTT
|
// If MQTT bytestream payload is selected (mqttHandler == NULL), send the payload to MQTT
|
||||||
if(mqttEnabled && mqtt != NULL && mqttHandler == NULL) {
|
if(mqttEnabled && mqtt != NULL && mqttHandler == NULL) {
|
||||||
mqtt->publish(topic.c_str(), toHex(hanBuffer+pos, ctx.length));
|
mqtt->publish(topic.c_str(), toHex(hanBuffer+pos, ctx.length));
|
||||||
|
mqtt->loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
debugV("Using application data:");
|
debugV("Using application data:");
|
||||||
@@ -1169,6 +1177,7 @@ int16_t unwrapData(uint8_t *buf, DataParserContext &context) {
|
|||||||
// If MQTT bytestream payload is selected (mqttHandler == NULL), send the payload to MQTT
|
// If MQTT bytestream payload is selected (mqttHandler == NULL), send the payload to MQTT
|
||||||
if(mqttEnabled && mqtt != NULL && mqttHandler == NULL) {
|
if(mqttEnabled && mqtt != NULL && mqttHandler == NULL) {
|
||||||
mqtt->publish(topic.c_str(), toHex(buf, curLen));
|
mqtt->publish(topic.c_str(), toHex(buf, curLen));
|
||||||
|
mqtt->loop();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DATA_TAG_MBUS:
|
case DATA_TAG_MBUS:
|
||||||
@@ -1176,6 +1185,7 @@ int16_t unwrapData(uint8_t *buf, DataParserContext &context) {
|
|||||||
// If MQTT bytestream payload is selected (mqttHandler == NULL), send the payload to MQTT
|
// If MQTT bytestream payload is selected (mqttHandler == NULL), send the payload to MQTT
|
||||||
if(mqttEnabled && mqtt != NULL && mqttHandler == NULL) {
|
if(mqttEnabled && mqtt != NULL && mqttHandler == NULL) {
|
||||||
mqtt->publish(topic.c_str(), toHex(buf, curLen));
|
mqtt->publish(topic.c_str(), toHex(buf, curLen));
|
||||||
|
mqtt->loop();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DATA_TAG_GBT:
|
case DATA_TAG_GBT:
|
||||||
@@ -1194,6 +1204,7 @@ int16_t unwrapData(uint8_t *buf, DataParserContext &context) {
|
|||||||
debugV("DSMR frame:");
|
debugV("DSMR frame:");
|
||||||
if(mqttEnabled && mqtt != NULL && mqttHandler == NULL) {
|
if(mqttEnabled && mqtt != NULL && mqttHandler == NULL) {
|
||||||
mqtt->publish(topic.c_str(), (char*) buf);
|
mqtt->publish(topic.c_str(), (char*) buf);
|
||||||
|
mqtt->loop();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -260,6 +260,37 @@ float EnergyAccounting::getMonthMax() {
|
|||||||
return maxHour > 0 ? maxHour / count / 100.0 : 0.0;
|
return maxHour > 0 ? maxHour / count / 100.0 : 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float EnergyAccounting::getPeak(uint8_t num) {
|
||||||
|
if(num < 1 || num > 5) return 0.0;
|
||||||
|
|
||||||
|
uint8_t count = 0;
|
||||||
|
bool included[5] = { false, false, false, false, false };
|
||||||
|
|
||||||
|
while(count < config->hours) {
|
||||||
|
uint8_t maxIdx = 0;
|
||||||
|
uint16_t maxVal = 0;
|
||||||
|
for(uint8_t i = 0; i < 5; i++) {
|
||||||
|
if(included[i]) continue;
|
||||||
|
if(data.peaks[i].value > maxVal) {
|
||||||
|
maxVal = data.peaks[i].value;
|
||||||
|
maxIdx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
included[maxIdx] = true;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t pos = 0;
|
||||||
|
for(uint8_t i = 0; i < 5; i++) {
|
||||||
|
if(!included[i]) continue;
|
||||||
|
pos++;
|
||||||
|
if(pos == num) {
|
||||||
|
return data.peaks[i].value / 100.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
bool EnergyAccounting::load() {
|
bool EnergyAccounting::load() {
|
||||||
if(!LittleFS.begin()) {
|
if(!LittleFS.begin()) {
|
||||||
if(debugger->isActive(RemoteDebug::ERROR)) {
|
if(debugger->isActive(RemoteDebug::ERROR)) {
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ public:
|
|||||||
|
|
||||||
float getMonthMax();
|
float getMonthMax();
|
||||||
uint8_t getCurrentThreshold();
|
uint8_t getCurrentThreshold();
|
||||||
|
float getPeak(uint8_t);
|
||||||
|
|
||||||
EnergyAccountingData getData();
|
EnergyAccountingData getData();
|
||||||
void setData(EnergyAccountingData&);
|
void setData(EnergyAccountingData&);
|
||||||
|
|||||||
@@ -266,7 +266,9 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterCo
|
|||||||
if(meterTs != NULL) {
|
if(meterTs != NULL) {
|
||||||
AmsOctetTimestamp* amst = (AmsOctetTimestamp*) meterTs;
|
AmsOctetTimestamp* amst = (AmsOctetTimestamp*) meterTs;
|
||||||
time_t ts = decodeCosemDateTime(amst->dt);
|
time_t ts = decodeCosemDateTime(amst->dt);
|
||||||
if(meterType == AmsTypeKamstrup || meterType == AmsTypeAidon) {
|
if(meterType == AmsTypeAidon) {
|
||||||
|
meterTimestamp = ts - 3600;
|
||||||
|
} else if(meterType == AmsTypeKamstrup) {
|
||||||
meterTimestamp = tz.toUTC(ts);
|
meterTimestamp = tz.toUTC(ts);
|
||||||
} else {
|
} else {
|
||||||
meterTimestamp = ts;
|
meterTimestamp = ts;
|
||||||
|
|||||||
@@ -203,7 +203,8 @@ bool HomeAssistantMqttHandler::publishSystem(HwTools* hw) {
|
|||||||
(uint32_t) (millis64()/1000),
|
(uint32_t) (millis64()/1000),
|
||||||
hw->getVcc(),
|
hw->getVcc(),
|
||||||
hw->getWifiRssi(),
|
hw->getWifiRssi(),
|
||||||
hw->getTemperature()
|
hw->getTemperature(),
|
||||||
|
VERSION
|
||||||
);
|
);
|
||||||
mqtt->publish(topic + "/state", json);
|
mqtt->publish(topic + "/state", json);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "JsonMqttHandler.h"
|
#include "JsonMqttHandler.h"
|
||||||
|
#include "version.h"
|
||||||
#include "hexutils.h"
|
#include "hexutils.h"
|
||||||
#include "Uptime.h"
|
#include "Uptime.h"
|
||||||
#include "web/root/json1_json.h"
|
#include "web/root/json1_json.h"
|
||||||
@@ -280,7 +281,8 @@ bool JsonMqttHandler::publishSystem(HwTools* hw) {
|
|||||||
(uint32_t) (millis64()/1000),
|
(uint32_t) (millis64()/1000),
|
||||||
hw->getVcc(),
|
hw->getVcc(),
|
||||||
hw->getWifiRssi(),
|
hw->getWifiRssi(),
|
||||||
hw->getTemperature()
|
hw->getTemperature(),
|
||||||
|
VERSION
|
||||||
);
|
);
|
||||||
init = mqtt->publish(topic, json);
|
init = mqtt->publish(topic, json);
|
||||||
return init;
|
return init;
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ bool RawMqttHandler::publish(AmsData* data, AmsData* meterState, EnergyAccountin
|
|||||||
}
|
}
|
||||||
mqtt->publish(topic + "/realtime/import/hour", String(ea->getUseThisHour(), 3));
|
mqtt->publish(topic + "/realtime/import/hour", String(ea->getUseThisHour(), 3));
|
||||||
mqtt->publish(topic + "/realtime/import/day", String(ea->getUseToday(), 2));
|
mqtt->publish(topic + "/realtime/import/day", String(ea->getUseToday(), 2));
|
||||||
|
for(uint8_t i = 1; i <= ea->getConfig()->hours; 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);
|
mqtt->publish(topic + "/realtime/import/threshold", String(ea->getCurrentThreshold(), 10), true, 0);
|
||||||
mqtt->publish(topic + "/realtime/import/monthmax", String(ea->getMonthMax(), 3), true, 0);
|
mqtt->publish(topic + "/realtime/import/monthmax", String(ea->getMonthMax(), 3), true, 0);
|
||||||
mqtt->publish(topic + "/realtime/export/hour", String(ea->getProducedThisHour(), 3));
|
mqtt->publish(topic + "/realtime/export/hour", String(ea->getProducedThisHour(), 3));
|
||||||
|
|||||||
@@ -591,9 +591,9 @@ void AmsWebServer::configThresholdsHtml() {
|
|||||||
|
|
||||||
String html = String((const __FlashStringHelper*) THRESHOLDS_HTML);
|
String html = String((const __FlashStringHelper*) THRESHOLDS_HTML);
|
||||||
for(int i = 0; i < 9; i++) {
|
for(int i = 0; i < 9; i++) {
|
||||||
html.replace("{t" + String(i) + "}", String(config->thresholds[i]));
|
html.replace("{t" + String(i) + "}", String(config->thresholds[i], 10));
|
||||||
}
|
}
|
||||||
html.replace("{h}", String(config->hours));
|
html.replace("{h}", String(config->hours, 10));
|
||||||
|
|
||||||
server.setContentLength(html.length() + HEAD_HTML_LEN + FOOT_HTML_LEN);
|
server.setContentLength(html.length() + HEAD_HTML_LEN + FOOT_HTML_LEN);
|
||||||
server.send_P(200, MIME_HTML, HEAD_HTML);
|
server.send_P(200, MIME_HTML, HEAD_HTML);
|
||||||
@@ -708,6 +708,12 @@ void AmsWebServer::dataJson() {
|
|||||||
if(eapi != NULL && strlen(eapi->getToken()) > 0)
|
if(eapi != NULL && strlen(eapi->getToken()) > 0)
|
||||||
price = eapi->getValueForHour(0);
|
price = eapi->getValueForHour(0);
|
||||||
|
|
||||||
|
String peaks = "";
|
||||||
|
for(uint8_t i = 1; i <= ea->getConfig()->hours; i++) {
|
||||||
|
if(!peaks.isEmpty()) peaks += ",";
|
||||||
|
peaks += String(ea->getPeak(i));
|
||||||
|
}
|
||||||
|
|
||||||
snprintf_P(buf, BufferSize, DATA_JSON,
|
snprintf_P(buf, BufferSize, DATA_JSON,
|
||||||
maxPwr == 0 ? meterState->isThreePhase() ? 20000 : 10000 : maxPwr,
|
maxPwr == 0 ? meterState->isThreePhase() ? 20000 : 10000 : maxPwr,
|
||||||
meterConfig->productionCapacity,
|
meterConfig->productionCapacity,
|
||||||
@@ -744,6 +750,7 @@ void AmsWebServer::dataJson() {
|
|||||||
meterState->getMeterType(),
|
meterState->getMeterType(),
|
||||||
meterConfig->distributionSystem,
|
meterConfig->distributionSystem,
|
||||||
ea->getMonthMax(),
|
ea->getMonthMax(),
|
||||||
|
peaks.c_str(),
|
||||||
ea->getCurrentThreshold(),
|
ea->getCurrentThreshold(),
|
||||||
ea->getUseThisHour(),
|
ea->getUseThisHour(),
|
||||||
ea->getCostThisHour(),
|
ea->getCostThisHour(),
|
||||||
@@ -1044,7 +1051,7 @@ void AmsWebServer::handleSetup() {
|
|||||||
gpioConfig->vccResistorVcc = 33;
|
gpioConfig->vccResistorVcc = 33;
|
||||||
break;
|
break;
|
||||||
case 6: // Pow-P1
|
case 6: // Pow-P1
|
||||||
gpioConfig->hanPin = 18;
|
gpioConfig->hanPin = 16;
|
||||||
gpioConfig->apPin = 0;
|
gpioConfig->apPin = 0;
|
||||||
gpioConfig->ledPinRed = 13;
|
gpioConfig->ledPinRed = 13;
|
||||||
gpioConfig->ledPinGreen = 14;
|
gpioConfig->ledPinGreen = 14;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
"ds" : %d,
|
"ds" : %d,
|
||||||
"ea" : {
|
"ea" : {
|
||||||
"x" : %.1f,
|
"x" : %.1f,
|
||||||
|
"p" : [ %s ],
|
||||||
"t" : %d,
|
"t" : %d,
|
||||||
"h" : {
|
"h" : {
|
||||||
"u" : %.2f,
|
"u" : %.2f,
|
||||||
|
|||||||
@@ -4,5 +4,6 @@
|
|||||||
"up" : %d,
|
"up" : %d,
|
||||||
"vcc" : %.3f,
|
"vcc" : %.3f,
|
||||||
"rssi": %d,
|
"rssi": %d,
|
||||||
"temp": %.2f
|
"temp": %.2f,
|
||||||
|
"version": "%s"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user