Merge pull request #33 from gskjold/dev-v1.0.1

Dev v1.0.1
This commit is contained in:
Gunnar Skjold 2020-02-16 14:49:36 +01:00 committed by GitHub
commit fc42fb22d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 105 additions and 106 deletions

View File

@ -27,7 +27,7 @@ You can also use a ESP based development board and combine this with a M-Bus mod
- Jump GPIO4 to GND to force AP mode during boot
[Adafruit HUZZAH32](https://www.adafruit.com/product/3405)
- M-Bus connected to RX
- M-Bus connected to GPIO16
Combine one of above board with an M-Bus module. Connect 3.3v and GND together between the boards and connect the TX pin from the M-Bus board to the dedicated M-Bus pin on the ESP board.

View File

@ -10,9 +10,11 @@ static void hanToJsonKaifa3phase(int listSize, JsonObject& data, HanReader& hanR
{
data["lv"] = hanReader.getString( (int)Kaifa_List3Phase::ListVersionIdentifier);
data["id"] = hanReader.getString( (int)Kaifa_List3Phase::MeterID);
data["type"] = hanReader.getString( (int)Kaifa_List3Phase::MeterType);
data["type"] = hanReader.getString( (int)Kaifa_List3Phase::MeterType);
data["P"] = hanReader.getInt( (int)Kaifa_List3Phase::ActiveImportPower);
data["Q"] = hanReader.getInt( (int)Kaifa_List3Phase::ReactiveImportPower);
data["PO"] = hanReader.getInt( (int)Kaifa_List3Phase::ActiveExportPower);
data["QO"] = hanReader.getInt( (int)Kaifa_List3Phase::ReactiveExportPower);
data["I1"] = ((double) hanReader.getInt((int)Kaifa_List3Phase::CurrentL1)) / 1000;
data["I2"] = ((double) hanReader.getInt((int)Kaifa_List3Phase::CurrentL2)) / 1000;
data["I3"] = ((double) hanReader.getInt((int)Kaifa_List3Phase::CurrentL3)) / 1000;
@ -23,6 +25,7 @@ static void hanToJsonKaifa3phase(int listSize, JsonObject& data, HanReader& hanR
if (listSize >= (int)Kaifa::List3PhaseLong)
{
data["rtc"] = hanReader.getTime( (int)Kaifa_List3Phase::MeterClock);
data["tPI"] = hanReader.getInt( (int)Kaifa_List3Phase::CumulativeActiveImportEnergy);
data["tPO"] = hanReader.getInt( (int)Kaifa_List3Phase::CumulativeActiveExportEnergy);
data["tQI"] = hanReader.getInt( (int)Kaifa_List3Phase::CumulativeReactiveImportEnergy);
@ -39,12 +42,15 @@ static void hanToJsonKaifa1phase(int listSize, JsonObject& data, HanReader& hanR
data["type"] = hanReader.getString( (int)Kaifa_List1Phase::MeterType);
data["P"] = hanReader.getInt( (int)Kaifa_List1Phase::ActiveImportPower);
data["Q"] = hanReader.getInt( (int)Kaifa_List1Phase::ReactiveImportPower);
data["PO"] = hanReader.getInt( (int)Kaifa_List1Phase::ActiveExportPower);
data["QO"] = hanReader.getInt( (int)Kaifa_List1Phase::ReactiveExportPower);
data["I1"] = ((double) hanReader.getInt((int)Kaifa_List1Phase::CurrentL1)) / 1000;
data["U1"] = ((double) hanReader.getInt((int)Kaifa_List1Phase::VoltageL1)) / 10;
}
if (listSize >= (int)Kaifa::List1PhaseLong)
{
data["rtc"] = hanReader.getTime( (int)Kaifa_List1Phase::MeterClock);
data["tPI"] = hanReader.getInt( (int)Kaifa_List1Phase::CumulativeActiveImportEnergy);
data["tPO"] = hanReader.getInt( (int)Kaifa_List1Phase::CumulativeActiveExportEnergy);
data["tQI"] = hanReader.getInt( (int)Kaifa_List1Phase::CumulativeReactiveImportEnergy);
@ -77,15 +83,15 @@ static void hanToJsonKaifa(JsonObject& data, HanReader& hanReader, Stream *debug
}
static void hanToJsonAidon3phase(int listSize, JsonObject& data, HanReader& hanReader, Stream *debugger)
{
if (listSize >= (int)Aidon::List3PhaseShort)
{
static void hanToJsonAidon3phase(int listSize, JsonObject& data, HanReader& hanReader, Stream *debugger) {
if (listSize >= (int)Aidon::List3PhaseShort) {
data["lv"] = hanReader.getString( (int)Aidon_List3Phase::ListVersionIdentifier);
data["id"] = hanReader.getString( (int)Aidon_List3Phase::MeterID);
data["type"] = hanReader.getString( (int)Aidon_List3Phase::MeterType);
data["P"] = hanReader.getInt( (int)Aidon_List3Phase::ActiveImportPower);
data["Q"] = hanReader.getInt( (int)Aidon_List3Phase::ReactiveExportPower);
data["Q"] = hanReader.getInt( (int)Aidon_List3Phase::ReactiveImportPower);
data["PO"] = hanReader.getInt( (int)Aidon_List3Phase::ActiveExportPower);
data["QO"] = hanReader.getInt( (int)Aidon_List3Phase::ReactiveExportPower);
data["I1"] = ((double) hanReader.getInt( (int)Aidon_List3Phase::CurrentL1)) / 10;
data["I2"] = ((double) hanReader.getInt( (int)Aidon_List3Phase::CurrentL2)) / 10;
data["I3"] = ((double) hanReader.getInt( (int)Aidon_List3Phase::CurrentL3)) / 10;
@ -94,8 +100,8 @@ static void hanToJsonAidon3phase(int listSize, JsonObject& data, HanReader& hanR
data["U3"] = ((double) hanReader.getInt( (int)Aidon_List3Phase::VoltageL3)) / 10;
}
if (listSize >= (int)Aidon::List3PhaseLong)
{
if (listSize >= (int)Aidon::List3PhaseLong) {
data["rtc"] = hanReader.getTime( (int)Aidon_List3Phase::Timestamp);
data["tPI"] = hanReader.getInt( (int)Aidon_List3Phase::CumulativeActiveImportEnergy);
data["tPO"] = hanReader.getInt( (int)Aidon_List3Phase::CumulativeActiveExportEnergy);
data["tQI"] = hanReader.getInt( (int)Aidon_List3Phase::CumulativeReactiveImportEnergy);
@ -111,13 +117,16 @@ static void hanToJsonAidon1phase(int listSize, JsonObject& data, HanReader& hanR
data["id"] = hanReader.getString( (int)Aidon_List1Phase::MeterID);
data["type"] = hanReader.getString( (int)Aidon_List1Phase::MeterType);
data["P"] = hanReader.getInt( (int)Aidon_List1Phase::ActiveImportPower);
data["Q"] = hanReader.getInt( (int)Aidon_List1Phase::ReactiveExportPower);
data["Q"] = hanReader.getInt( (int)Aidon_List1Phase::ReactiveImportPower);
data["PO"] = hanReader.getInt( (int)Aidon_List1Phase::ActiveExportPower);
data["QO"] = hanReader.getInt( (int)Aidon_List1Phase::ReactiveExportPower);
data["I1"] = ((double) hanReader.getInt( (int)Aidon_List1Phase::CurrentL1)) / 10;
data["U1"] = ((double) hanReader.getInt( (int)Aidon_List1Phase::VoltageL1)) / 10;
}
if (listSize >= (int)Aidon::List1PhaseLong)
{
data["rtc"] = hanReader.getTime( (int)Aidon_List1Phase::Timestamp);
data["tPI"] = hanReader.getInt( (int)Aidon_List1Phase::CumulativeActiveImportEnergy);
data["tPO"] = hanReader.getInt( (int)Aidon_List1Phase::CumulativeActiveExportEnergy);
data["tQI"] = hanReader.getInt( (int)Aidon_List1Phase::CumulativeReactiveImportEnergy);
@ -132,25 +141,21 @@ static void hanToJsonAidon3phaseIT(int listSize, JsonObject& data, HanReader& ha
data["lv"] = hanReader.getString( (int)Aidon_List3PhaseIT::ListVersionIdentifier);
data["id"] = hanReader.getString( (int)Aidon_List3PhaseIT::MeterID);
data["type"] = hanReader.getString( (int)Aidon_List3PhaseIT::MeterType);
int p = hanReader.getInt( (int)Aidon_List3PhaseIT::ActiveImportPower);
data["P"] = p;
data["Q"] = hanReader.getInt( (int)Aidon_List3PhaseIT::ReactiveExportPower);
double i1 = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CurrentL1)) / 10;
double i3 = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CurrentL3)) / 10;
double u1 = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::VoltageL1)) / 10;
double u2 = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::VoltageL2)) / 10;
double u3 = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::VoltageL3)) / 10;
double i2 = 0.00;
data["I1"] = i1;
data["I2"] = i2;
data["I3"] = i3;
data["U1"] = u1;
data["U2"] = u2;
data["U3"] = u3;
data["P"] = hanReader.getInt( (int)Aidon_List3PhaseIT::ActiveImportPower);
data["Q"] = hanReader.getInt( (int)Aidon_List3PhaseIT::ReactiveImportPower);
data["PO"] = hanReader.getInt( (int)Aidon_List3PhaseIT::ActiveExportPower);
data["QO"] = hanReader.getInt( (int)Aidon_List3PhaseIT::ReactiveExportPower);
data["I1"] = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CurrentL1)) / 10;
data["I1"] = 0;
data["I3"] = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CurrentL3)) / 10;
data["U1"] = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::VoltageL1)) / 10;
data["U2"] = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::VoltageL2)) / 10;
data["U3"] = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::VoltageL3)) / 10;
}
if (listSize >= (int)Aidon::List3PhaseITLong)
{
data["rtc"] = hanReader.getTime( (int)Aidon_List3PhaseIT::Timestamp);
data["tPI"] = hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeActiveImportEnergy);
data["tPO"] = hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeActiveExportEnergy);
data["tQI"] = hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeReactiveImportEnergy);
@ -187,15 +192,15 @@ static void hanToJsonAidon(JsonObject& data, HanReader& hanReader, Stream *debug
}
}
static void hanToJsonKamstrup3phase(int listSize, JsonObject& data, HanReader& hanReader, Stream *debugger)
{
if (listSize >= (int)Kamstrup::List3PhaseShort)
{
static void hanToJsonKamstrup3phase(int listSize, JsonObject& data, HanReader& hanReader, Stream *debugger) {
if (listSize >= (int)Kamstrup::List3PhaseShort) {
data["lv"] = hanReader.getString( (int)Kamstrup_List3Phase::ListVersionIdentifier);
data["id"] = hanReader.getString( (int)Kamstrup_List3Phase::MeterID);
data["type"] = hanReader.getString( (int)Kamstrup_List3Phase::MeterType);
data["P"] = hanReader.getInt( (int)Kamstrup_List3Phase::ActiveImportPower);
data["Q"] = hanReader.getInt( (int)Kamstrup_List3Phase::ReactiveImportPower);
data["PO"] = hanReader.getInt( (int)Kamstrup_List3Phase::ActiveExportPower);
data["QO"] = hanReader.getInt( (int)Kamstrup_List3Phase::ReactiveExportPower);
data["I1"] = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CurrentL1)) / 100;
data["I2"] = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CurrentL2)) / 100;
data["I3"] = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CurrentL3)) / 100;
@ -204,8 +209,8 @@ static void hanToJsonKamstrup3phase(int listSize, JsonObject& data, HanReader& h
data["U3"] = hanReader.getInt( (int)Kamstrup_List3Phase::VoltageL3);
}
if (listSize >= (int)Kamstrup::List3PhaseLong)
{
if (listSize >= (int)Kamstrup::List3PhaseLong) {
data["rtc"] = hanReader.getTime( (int)Kamstrup_List3Phase::MeterClock);
data["tPI"] = hanReader.getInt( (int)Kamstrup_List3Phase::CumulativeActiveImportEnergy);
data["tPO"] = hanReader.getInt( (int)Kamstrup_List3Phase::CumulativeActiveExportEnergy);
data["tQI"] = hanReader.getInt( (int)Kamstrup_List3Phase::CumulativeReactiveImportEnergy);
@ -213,21 +218,21 @@ static void hanToJsonKamstrup3phase(int listSize, JsonObject& data, HanReader& h
}
}
static void hanToJsonKamstrup1phase(int listSize, JsonObject& data, HanReader& hanReader, Stream *debugger)
{
if (listSize >= (int)Kamstrup::List1PhaseShort)
{
static void hanToJsonKamstrup1phase(int listSize, JsonObject& data, HanReader& hanReader, Stream *debugger) {
if (listSize >= (int)Kamstrup::List1PhaseShort) {
data["lv"] = hanReader.getString( (int)Kamstrup_List1Phase::ListVersionIdentifier);
data["id"] = hanReader.getString( (int)Kamstrup_List1Phase::MeterID);
data["type"] = hanReader.getString( (int)Kamstrup_List1Phase::MeterType);
data["P"] = hanReader.getInt( (int)Kamstrup_List1Phase::ActiveImportPower);
data["Q"] = hanReader.getInt( (int)Kamstrup_List1Phase::ReactiveImportPower);
data["PO"] = hanReader.getInt( (int)Kamstrup_List1Phase::ActiveExportPower);
data["QO"] = hanReader.getInt( (int)Kamstrup_List1Phase::ReactiveExportPower);
data["I1"] = ((double) hanReader.getInt((int)Kamstrup_List1Phase::CurrentL1)) / 100;
data["U1"] = hanReader.getInt( (int)Kamstrup_List1Phase::VoltageL1);
}
if (listSize >= (int)Kamstrup::List1PhaseLong)
{
if (listSize >= (int)Kamstrup::List1PhaseLong) {
data["rtc"] = hanReader.getTime( (int)Kamstrup_List1Phase::MeterClock);
data["tPI"] = hanReader.getInt( (int)Kamstrup_List1Phase::CumulativeActiveImportEnergy);
data["tPO"] = hanReader.getInt( (int)Kamstrup_List1Phase::CumulativeActiveExportEnergy);
data["tQI"] = hanReader.getInt( (int)Kamstrup_List1Phase::CumulativeReactiveImportEnergy);
@ -235,8 +240,7 @@ static void hanToJsonKamstrup1phase(int listSize, JsonObject& data, HanReader& h
}
}
static void hanToJsonKamstrup(JsonObject& data, HanReader& hanReader, Stream *debugger)
{
static void hanToJsonKamstrup(JsonObject& data, HanReader& hanReader, Stream *debugger) {
int listSize = hanReader.getListSize();
switch (listSize) {

View File

@ -17,7 +17,13 @@
#include <OneWire.h>
#define TEMP_SENSOR_PIN 5 // Temperature sensor connected to GPIO5
#if DEBUG_MODE
#define SOFTWARE_SERIAL 1
#include <SoftwareSerial.h>
SoftwareSerial *hanSerial = new SoftwareSerial(3);
#else
HardwareSerial *hanSerial = &Serial;
#endif
// Build settings for Wemos Lolin D32
#elif defined(ARDUINO_LOLIN_D32)
@ -45,7 +51,7 @@ SoftwareSerial *hanSerial = new SoftwareSerial(D1);
#define LED_ACTIVE_HIGH 1
#define AP_BUTTON_PIN INVALID_BUTTON_PIN
HardwareSerial *hanSerial = &Serial;
HardwareSerial *hanSerial = &Serial2;
// Default build settings
#else

View File

@ -24,10 +24,10 @@ AmsWebServer ws;
// WiFi client and MQTT client
WiFiClient *client;
MQTTClient mqtt(384);
MQTTClient mqtt(512);
// Object used for debugging
HardwareSerial* debugger = NULL;
Stream* debugger = NULL;
// The HAN Port reader, used to read serial data and decode DLMS
HanReader hanReader;
@ -39,17 +39,15 @@ void setup() {
}
#if DEBUG_MODE
debugger = &Serial;
#if SOFTWARE_SERIAL
debugger->begin(115200, SERIAL_8N1);
#else
if(config.meterType == 3) {
hanSerial->begin(2400, SERIAL_8N1);
} else {
hanSerial->begin(2400, SERIAL_8E1);
}
#endif
while (!&debugger);
#if HW_ROARFRED
SoftwareSerial *ser = new SoftwareSerial(-1, 1);
ser->begin(115200, SWSERIAL_8N1);
debugger = ser;
#else
HardwareSerial *ser = &Serial;
ser->begin(115200, SERIAL_8N1);
#endif
debugger = ser;
#endif
if (debugger) {
@ -72,12 +70,6 @@ void setup() {
{
setupWiFi();
if(config.mqttHost) {
mqtt.begin(config.mqttHost, *client);
// Notify everyone we're here!
sendMqttData("Connected!");
}
// Configure uart for AMS data
#if defined SOFTWARE_SERIAL
if(config.meterType == 3) {
@ -118,15 +110,16 @@ void loop()
// Reconnect to WiFi and MQTT as needed
if (WiFi.status() != WL_CONNECTED) {
WiFi_connect();
}
if (config.mqttHost) {
mqtt.loop();
delay(10); // <- fixes some issues with WiFi stability
if(!mqtt.connected()) {
MQTT_connect();
} else {
if (config.mqttHost) {
mqtt.loop();
yield();
if(!mqtt.connected()) {
MQTT_connect();
}
}
}
readHanPort();
}
else
@ -136,6 +129,7 @@ void loop()
else led_off();
}
ws.loop();
delay(1); // Needed for auto modem sleep
}
@ -207,7 +201,7 @@ void readHanPort()
if (debugger) debugger->println(time);
// Define a json object to keep the data
StaticJsonDocument<500> json;
StaticJsonDocument<1024> json;
// Any generic useful info here
json["id"] = WiFi.macAddress();
@ -297,8 +291,18 @@ void WiFi_connect() {
// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect()
{
unsigned long lastMqttRetry = -10000;
void MQTT_connect() {
if(!config.mqttHost) {
if(debugger) debugger->println("No MQTT config");
return;
}
if(millis() - lastMqttRetry < 5000) {
yield();
return;
}
lastMqttRetry = millis();
if(debugger) {
debugger->print("Connecting to MQTT: ");
debugger->print(config.mqttHost);
@ -306,40 +310,30 @@ void MQTT_connect()
debugger->print(config.mqttPort);
debugger->println();
}
// Wait for the MQTT connection to complete
while (!mqtt.connected()) {
// Connect to a unsecure or secure MQTT server
if ((config.mqttUser == 0 && mqtt.connect(config.mqttClientID)) ||
(config.mqttUser != 0 && mqtt.connect(config.mqttClientID, config.mqttUser, config.mqttPass)))
{
if (debugger) debugger->println("\nSuccessfully connected to MQTT!");
// Subscribe to the chosen MQTT topic, if set in configuration
if (config.mqttSubscribeTopic != 0 && strlen(config.mqttSubscribeTopic) > 0)
{
mqtt.subscribe(config.mqttSubscribeTopic);
if (debugger) debugger->printf(" Subscribing to [%s]\r\n", config.mqttSubscribeTopic);
}
}
else
{
if (debugger)
{
debugger->print(".");
debugger->print("failed, ");
debugger->println(" trying again in 5 seconds");
}
mqtt.disconnect();
// Wait 2 seconds before retrying
mqtt.disconnect();
mqtt.begin(config.mqttHost, config.mqttPort, *client);
delay(2000);
// Connect to a unsecure or secure MQTT server
if ((config.mqttUser == 0 && mqtt.connect(config.mqttClientID)) ||
(config.mqttUser != 0 && mqtt.connect(config.mqttClientID, config.mqttUser, config.mqttPass))) {
if (debugger) debugger->println("\nSuccessfully connected to MQTT!");
// Subscribe to the chosen MQTT topic, if set in configuration
if (config.mqttSubscribeTopic != 0 && strlen(config.mqttSubscribeTopic) > 0) {
mqtt.subscribe(config.mqttSubscribeTopic);
if (debugger) debugger->printf(" Subscribing to [%s]\r\n", config.mqttSubscribeTopic);
}
// Allow some resources for the WiFi connection
yield();
delay(2000);
sendMqttData("Connected!");
} else {
if (debugger) {
debugger->print(" failed, ");
debugger->println(" trying again in 5 seconds");
}
}
yield();
}
// Send a simple string embedded in json over MQTT
@ -349,11 +343,6 @@ void sendMqttData(String data)
if (config.mqttPublishTopic == 0 || strlen(config.mqttPublishTopic) == 0)
return;
// Make sure we're connected
if (!client->connected() || !mqtt.connected()) {
MQTT_connect();
}
// Build a json with the message in a "data" attribute
StaticJsonDocument<500> json;
json["id"] = WiFi.macAddress();

View File

@ -41,7 +41,7 @@ void AmsWebServer::loop() {
server.handleClient();
}
void AmsWebServer::setJson(StaticJsonDocument<500> json) {
void AmsWebServer::setJson(StaticJsonDocument<1024> json) {
if(!json.isNull()) {
p = json["data"]["P"].as<int>();
@ -87,7 +87,7 @@ void AmsWebServer::setJson(StaticJsonDocument<500> json) {
}
bool AmsWebServer::checkSecurity(byte level) {
bool access = !config->hasConfig() || config->authSecurity < level;
bool access = WiFi.getMode() == WIFI_AP || !config->hasConfig() || config->authSecurity < level;
if(!access && config->authSecurity >= level && server.hasHeader("Authorization")) {
println(" forcing web security");
String expectedAuth = String(config->authUser) + ":" + String(config->authPass);

View File

@ -24,12 +24,12 @@ class AmsWebServer {
public:
void setup(configuration* config, Stream* debugger);
void loop();
void setJson(StaticJsonDocument<500> json);
void setJson(StaticJsonDocument<1024> json);
private:
configuration* config;
Stream* debugger;
StaticJsonDocument<500> json;
StaticJsonDocument<1024> json;
int maxPwr;
int p;
double u1, u2, u3, i1, i2, i3;