Auto detect meter type

This commit is contained in:
Gunnar Skjold 2020-02-11 18:40:38 +01:00
parent 4b9cb27e58
commit f6df84bf9a
4 changed files with 151 additions and 135 deletions

View File

@ -69,19 +69,14 @@ bool configuration::load()
ssid = 0;
ssidPassword = 0;
meterType = (byte)0;
mqttHost = 0;
mqttClientID = 0;
mqttPublishTopic = 0;
mqttSubscribeTopic = 0;
mqttUser = 0;
mqttPass = 0;
mqttPort = 1883;
authSecurity = 0;
authUser = 0;
authPass = 0;
fuseSize = 0;
distSys = 0;
EEPROM.begin(EEPROM_SIZE);
int cs = EEPROM.read(address);

View File

@ -17,7 +17,7 @@ public:
char* ssid;
char* ssidPassword;
char* mqttHost;
int mqttPort;
int mqttPort = 1883;
char* mqttClientID;
char* mqttPublishTopic;
char* mqttSubscribeTopic;

View File

@ -13,6 +13,10 @@
#include "HanReader.h"
#include "HanToJson.h"
#include "Aidon.h"
#include "Kaifa.h"
#include "Kamstrup.h"
// Configuration
configuration config;
@ -68,44 +72,40 @@ void setup() {
led_off();
if (!ap.isActivated)
{
if (!ap.isActivated) {
setupWiFi();
// Configure uart for AMS data
#if defined SOFTWARE_SERIAL
if(config.meterType == 3) {
hanSerial->begin(2400, SWSERIAL_8N1);
} else {
hanSerial->begin(2400, SWSERIAL_8E1);
}
#else
if(config.meterType == 3) {
hanSerial->begin(2400, SERIAL_8N1);
} else {
hanSerial->begin(2400, SERIAL_8E1);
}
#if defined UART2
hanSerial->swap();
#endif
#endif
while (!&hanSerial);
hanReader.setup(hanSerial, debugger);
// Compensate for the known Kaifa bug
hanReader.compensateFor09HeaderBug = (config.meterType == 1);
}
#if defined SOFTWARE_SERIAL
if(config.meterType == 3) {
hanSerial->begin(2400, SWSERIAL_8N1);
} else {
hanSerial->begin(2400, SWSERIAL_8E1);
}
#else
if(config.meterType == 3) {
hanSerial->begin(2400, SERIAL_8N1);
} else {
hanSerial->begin(2400, SERIAL_8E1);
}
#if defined UART2
hanSerial->swap();
#endif
#endif
while (!&hanSerial);
hanReader.setup(hanSerial, debugger);
// Compensate for the known Kaifa bug
hanReader.compensateFor09HeaderBug = (config.meterType == 1);
ws.setup(&config, debugger);
}
// the loop function runs over and over again until power down or reset
void loop()
{
void loop() {
// Only do normal stuff if we're not booted as AP
if (!ap.loop())
{
if (!ap.loop()) {
// Turn off the LED
led_off();
@ -121,15 +121,12 @@ void loop()
}
}
}
readHanPort();
}
else
{
} else {
// Continously flash the LED when AP mode
if (millis() / 1000 % 2 == 0) led_on();
else led_off();
}
readHanPort();
ws.loop();
}
@ -189,57 +186,111 @@ void mqttMessageReceived(String &topic, String &payload)
// Ideas could be to query for values or to initiate OTA firmware update
}
void readHanPort()
{
if (hanReader.read() && config.hasConfig())
{
// Flash LED on, this shows us that data is received
led_on();
bool even = true;
unsigned long lastSuccessfulRead = 0;
void readHanPort() {
if (hanReader.read()) {
lastSuccessfulRead = millis();
// Get the timestamp (as unix time) from the package
time_t time = hanReader.getPackageTime();
if (debugger) debugger->print("Time of the package is: ");
if (debugger) debugger->println(time);
if(config.meterType > 0) {
// Flash LED on, this shows us that data is received
led_on();
// Define a json object to keep the data
StaticJsonDocument<500> json;
// Get the timestamp (as unix time) from the package
time_t time = hanReader.getPackageTime();
if (debugger) debugger->print("Time of the package is: ");
if (debugger) debugger->println(time);
// Any generic useful info here
json["id"] = WiFi.macAddress();
json["up"] = millis();
json["t"] = time;
// Define a json object to keep the data
StaticJsonDocument<500> json;
// Add a sub-structure to the json object,
// to keep the data from the meter itself
JsonObject data = json.createNestedObject("data");
// Any generic useful info here
json["id"] = WiFi.macAddress();
json["up"] = millis();
json["t"] = time;
// Add a sub-structure to the json object,
// to keep the data from the meter itself
JsonObject data = json.createNestedObject("data");
#if defined TEMP_SENSOR_PIN
// Get the temperature too
tempSensor.requestTemperatures();
data["temp"] = tempSensor.getTempCByIndex(0);
// Get the temperature too
tempSensor.requestTemperatures();
data["temp"] = tempSensor.getTempCByIndex(0);
#endif
hanToJson(data, config.meterType, hanReader);
hanToJson(data, config.meterType, hanReader);
if(config.mqttHost != 0 && strlen(config.mqttHost) != 0 && config.mqttPublishTopic != 0 && strlen(config.mqttPublishTopic) != 0) {
// Write the json to the debug port
if (debugger) {
debugger->print("Sending data to MQTT: ");
serializeJsonPretty(json, *debugger);
debugger->println();
if(config.mqttHost != 0 && strlen(config.mqttHost) != 0 && config.mqttPublishTopic != 0 && strlen(config.mqttPublishTopic) != 0) {
// Write the json to the debug port
if (debugger) {
debugger->print("Sending data to MQTT: ");
serializeJsonPretty(json, *debugger);
debugger->println();
}
// Publish the json to the MQTT server
String msg;
serializeJson(json, msg);
mqtt.publish(config.mqttPublishTopic, msg.c_str());
mqtt.loop();
}
ws.setJson(json);
// Publish the json to the MQTT server
String msg;
serializeJson(json, msg);
mqtt.publish(config.mqttPublishTopic, msg.c_str());
mqtt.loop();
// Flash LED off
led_off();
} else {
for(int i = 1; i <= 3; i++) {
String list;
switch(i) {
case 1:
list = hanReader.getString((int) Kaifa_List1Phase::ListVersionIdentifier);
break;
case 2:
list = hanReader.getString((int) Aidon_List1Phase::ListVersionIdentifier);
break;
case 3:
list = hanReader.getString((int) Kamstrup_List1Phase::ListVersionIdentifier);
break;
}
if(!list.isEmpty()) {
list.toLowerCase();
if(list.startsWith("kfm")) {
config.meterType = 1;
if(debugger) debugger->println("Detected Kaifa meter");
break;
} else if(list.startsWith("aidon")) {
config.meterType = 2;
if(debugger) debugger->println("Detected Aidon meter");
break;
} else if(list.startsWith("kamstrup")) {
config.meterType = 3;
if(debugger) debugger->println("Detected Kamstrup meter");
break;
}
}
}
hanReader.compensateFor09HeaderBug = (config.meterType == 1);
}
ws.setJson(json);
}
// Flash LED off
led_off();
if(config.meterType == 0 && millis() - lastSuccessfulRead > 10000) {
lastSuccessfulRead = millis();
#if defined SOFTWARE_SERIAL
if(even) {
hanSerial->begin(2400, SWSERIAL_8N1);
} else {
hanSerial->begin(2400, SWSERIAL_8E1);
}
#else
if(even) {
hanSerial->begin(2400, SERIAL_8N1);
} else {
hanSerial->begin(2400, SERIAL_8E1);
}
#endif
even = !even;
}
}

View File

@ -155,62 +155,32 @@ void AmsWebServer::configurationHtml() {
server.sendHeader("Pragma", "no-cache");
server.sendHeader("Expires", "-1");
if(config->hasConfig()) {
html.replace("${config.ssid}", config->ssid);
html.replace("${config.ssidPassword}", config->ssidPassword);
html.replace("${config.meterType}", String(config->fuseSize));
for(int i = 0; i<4; i++) {
html.replace("${config.meterType" + String(i) + "}", config->meterType == i ? "selected" : "");
}
html.replace("${config.mqtt}", config->mqttHost == 0 ? "" : "checked");
html.replace("${config.mqttHost}", config->mqttHost);
html.replace("${config.mqttPort}", String(config->mqttPort));
html.replace("${config.mqttClientID}", config->mqttClientID);
html.replace("${config.mqttPublishTopic}", config->mqttPublishTopic);
html.replace("${config.mqttSubscribeTopic}", config->mqttSubscribeTopic);
html.replace("${config.mqttUser}", config->mqttUser);
html.replace("${config.mqttPass}", config->mqttPass);
html.replace("${config.authUser}", config->authUser);
html.replace("${config.authSecurity}", String(config->authSecurity));
for(int i = 0; i<3; i++) {
html.replace("${config.authSecurity" + String(i) + "}", config->authSecurity == i ? "selected" : "");
}
html.replace("${config.authPass}", config->authPass);
html.replace("${config.fuseSize}", String(config->fuseSize));
for(int i = 0; i<64; i++) {
html.replace("${config.fuseSize" + String(i) + "}", config->fuseSize == i ? "selected" : "");
}
for(int i = 0; i<3; i++) {
html.replace("${config.distSys" + String(i) + "}", config->distSys == i ? "selected" : "");
}
} else {
html.replace("${config.ssid}", "");
html.replace("${config.ssidPassword}", "");
html.replace("${config.meterType}", "");
for(int i = 0; i<4; i++) {
html.replace("${config.meterType" + String(i) + "}", i == 0 ? "selected" : "");
}
html.replace("${config.mqtt}", "");
html.replace("${config.mqttHost}", "");
html.replace("${config.mqttPort}", "1883");
html.replace("${config.mqttClientID}", "");
html.replace("${config.mqttPublishTopic}", "");
html.replace("${config.mqttSubscribeTopic}", "");
html.replace("${config.mqttUser}", "");
html.replace("${config.mqttPass}", "");
html.replace("${config.authSecurity}", "");
for(int i = 0; i<3; i++) {
html.replace("${config.authSecurity" + String(i) + "}", i == 0 ? "selected" : "");
}
html.replace("${config.authUser}", "");
html.replace("${config.authPass}", "");
html.replace("${config.fuseSize}", "");
for(int i = 0; i<64; i++) {
html.replace("${config.fuseSize" + String(i) + "}", i == 0 ? "selected" : "");
}
for(int i = 0; i<3; i++) {
html.replace("${config.distSys" + String(i) + "}", i == 0 ? "selected" : "");
}
html.replace("${config.ssid}", config->ssid);
html.replace("${config.ssidPassword}", config->ssidPassword);
html.replace("${config.meterType}", String(config->fuseSize));
for(int i = 0; i<4; i++) {
html.replace("${config.meterType" + String(i) + "}", config->meterType == i ? "selected" : "");
}
html.replace("${config.mqtt}", config->mqttHost == 0 ? "" : "checked");
html.replace("${config.mqttHost}", config->mqttHost);
html.replace("${config.mqttPort}", String(config->mqttPort));
html.replace("${config.mqttClientID}", config->mqttClientID);
html.replace("${config.mqttPublishTopic}", config->mqttPublishTopic);
html.replace("${config.mqttSubscribeTopic}", config->mqttSubscribeTopic);
html.replace("${config.mqttUser}", config->mqttUser);
html.replace("${config.mqttPass}", config->mqttPass);
html.replace("${config.authUser}", config->authUser);
html.replace("${config.authSecurity}", String(config->authSecurity));
for(int i = 0; i<3; i++) {
html.replace("${config.authSecurity" + String(i) + "}", config->authSecurity == i ? "selected" : "");
}
html.replace("${config.authPass}", config->authPass);
html.replace("${config.fuseSize}", String(config->fuseSize));
for(int i = 0; i<64; i++) {
html.replace("${config.fuseSize" + String(i) + "}", config->fuseSize == i ? "selected" : "");
}
for(int i = 0; i<3; i++) {
html.replace("${config.distSys" + String(i) + "}", config->distSys == i ? "selected" : "");
}
server.send(200, "text/html", html);
}