Support older config versions. Fixed css for AP mode. Some cleanup and changes to preserve power

This commit is contained in:
Gunnar Skjold
2020-02-16 20:09:29 +01:00
parent 227eb7b6ff
commit 4786735d4c
11 changed files with 509 additions and 221 deletions

View File

@@ -205,13 +205,19 @@ void AmsConfiguration::setProductionCapacity(int productionCapacity) {
}
bool AmsConfiguration::hasConfig()
{
bool hasConfig = false;
bool AmsConfiguration::hasConfig() {
EEPROM.begin(EEPROM_SIZE);
hasConfig = EEPROM.read(EEPROM_CONFIG_ADDRESS) == EEPROM_CHECK_SUM;
int configVersion = EEPROM.read(EEPROM_CONFIG_ADDRESS);
EEPROM.end();
return hasConfig;
switch(configVersion) {
case 71:
case 72:
case 75:
case 80:
return true;
default:
return false;
}
}
bool AmsConfiguration::load() {
@@ -220,80 +226,209 @@ bool AmsConfiguration::load() {
EEPROM.begin(EEPROM_SIZE);
int cs = EEPROM.read(address);
if (cs == EEPROM_CHECK_SUM)
{
char* temp;
address++;
address += readString(address, &temp);
setWifiSsid(temp);
address += readString(address, &temp);
setWifiPassword(temp);
address += readString(address, &temp);
setWifiIp(temp);
address += readString(address, &temp);
setWifiGw(temp);
address += readString(address, &temp);
setWifiSubnet(temp);
bool mqtt = false;
address += readBool(address, &mqtt);
if(mqtt) {
address += readString(address, &temp);
setMqttHost(temp);
int port;
address += readInt(address, &port);
setMqttPort(port);
address += readString(address, &temp);
setMqttClientId(temp);
address += readString(address, &temp);
setMqttPublishTopic(temp);
address += readString(address, &temp);
setMqttSubscribeTopic(temp);
bool secure = false;
address += readBool(address, &secure);
if (secure)
{
address += readString(address, &temp);
setMqttUser(temp);
address += readString(address, &temp);
setMqttPassword(temp);
} else {
setMqttUser("");
setMqttPassword("");
}
} else {
clearMqtt();
}
address += readByte(address, &authSecurity);
if (authSecurity > 0) {
address += readString(address, &temp);
setAuthUser(temp);
address += readString(address, &temp);
setAuthPassword(temp);
} else {
clearAuth();
}
int i;
address += readInt(address, &i);
setMeterType(i);
address += readInt(address, &i);
setDistributionSystem(i);
address += readInt(address, &i);
setMainFuse(i);
address += readInt(address, &i);
setProductionCapacity(i);
ackWifiChange();
success = true;
}
address++;
switch(cs) {
case 71: // Same as 72
case 72:
success = loadConfig72(address);
break;
case 75:
success = loadConfig75(address);
break;
case 80:
success = loadConfig80(address);
break;
}
EEPROM.end();
return success;
}
bool AmsConfiguration::loadConfig72(int address) {
char* temp;
address += readString(address, &temp);
setWifiSsid(temp);
address += readString(address, &temp);
setWifiPassword(temp);
byte b;
address += readByte(address, &b);
setMeterType(b);
address += readString(address, &temp);
setMqttHost(temp);
int port;
address += readInt(address, &port);
setMqttPort(port);
address += readString(address, &temp);
setMqttClientId(temp);
address += readString(address, &temp);
setMqttPublishTopic(temp);
address += readString(address, &temp);
setMqttSubscribeTopic(temp);
bool secure = false;
address += readBool(address, &secure);
if (secure) {
address += readString(address, &temp);
setMqttUser(temp);
address += readString(address, &temp);
setMqttPassword(temp);
} else {
setMqttUser("");
setMqttPassword("");
}
clearAuth();
setWifiIp("");
setWifiGw("");
setWifiSubnet("");
setMainFuse(0);
setProductionCapacity(0);
setDistributionSystem(0);
ackWifiChange();
return true;
}
bool AmsConfiguration::loadConfig75(int address) {
char* temp;
address += readString(address, &temp);
setWifiSsid(temp);
address += readString(address, &temp);
setWifiPassword(temp);
byte b;
address += readByte(address, &b);
setMeterType(b);
bool mqtt = false;
address += readBool(address, &mqtt);
if(mqtt) {
address += readString(address, &temp);
setMqttHost(temp);
int port;
address += readInt(address, &port);
setMqttPort(port);
address += readString(address, &temp);
setMqttClientId(temp);
address += readString(address, &temp);
setMqttPublishTopic(temp);
address += readString(address, &temp);
setMqttSubscribeTopic(temp);
}
bool secure = false;
address += readBool(address, &secure);
if (secure) {
address += readString(address, &temp);
setMqttUser(temp);
address += readString(address, &temp);
setMqttPassword(temp);
} else {
setMqttUser("");
setMqttPassword("");
}
address += readByte(address, &authSecurity);
if (authSecurity > 0) {
address += readString(address, &temp);
setAuthUser(temp);
address += readString(address, &temp);
setAuthPassword(temp);
} else {
clearAuth();
}
int i;
address += readInt(address, &i);
setMainFuse(i);
address += readByte(address, &b);
setDistributionSystem(b);
setWifiIp("");
setWifiGw("");
setWifiSubnet("");
setProductionCapacity(0);
ackWifiChange();
return true;
}
bool AmsConfiguration::loadConfig80(int address) {
char* temp;
address += readString(address, &temp);
setWifiSsid(temp);
address += readString(address, &temp);
setWifiPassword(temp);
address += readString(address, &temp);
setWifiIp(temp);
address += readString(address, &temp);
setWifiGw(temp);
address += readString(address, &temp);
setWifiSubnet(temp);
bool mqtt = false;
address += readBool(address, &mqtt);
if(mqtt) {
address += readString(address, &temp);
setMqttHost(temp);
int port;
address += readInt(address, &port);
setMqttPort(port);
address += readString(address, &temp);
setMqttClientId(temp);
address += readString(address, &temp);
setMqttPublishTopic(temp);
address += readString(address, &temp);
setMqttSubscribeTopic(temp);
bool secure = false;
address += readBool(address, &secure);
if (secure)
{
address += readString(address, &temp);
setMqttUser(temp);
address += readString(address, &temp);
setMqttPassword(temp);
} else {
setMqttUser("");
setMqttPassword("");
}
} else {
clearMqtt();
}
address += readByte(address, &authSecurity);
if (authSecurity > 0) {
address += readString(address, &temp);
setAuthUser(temp);
address += readString(address, &temp);
setAuthPassword(temp);
} else {
clearAuth();
}
int i;
address += readInt(address, &i);
setMeterType(i);
address += readInt(address, &i);
setDistributionSystem(i);
address += readInt(address, &i);
setMainFuse(i);
address += readInt(address, &i);
setProductionCapacity(i);
ackWifiChange();
return true;
}
bool AmsConfiguration::save() {
int address = EEPROM_CONFIG_ADDRESS;

View File

@@ -88,9 +88,13 @@ private:
int meterType, distributionSystem, mainFuse, productionCapacity;
const int EEPROM_SIZE = 512;
const byte EEPROM_CHECK_SUM = 80; // Used to check if config is stored. Change if structure changes
const int EEPROM_CHECK_SUM = 80; // Used to check if config is stored. Change if structure changes
const int EEPROM_CONFIG_ADDRESS = 0;
bool loadConfig72(int address);
bool loadConfig75(int address);
bool loadConfig80(int address);
int saveString(int pAddress, const char* pString);
int readString(int pAddress, char* pString[]);
int saveInt(int pAddress, int pValue);

View File

@@ -19,12 +19,15 @@
#define AP_BUTTON_PIN 0
#if DEBUG_MODE
#define SOFTWARE_SERIAL 1
#if SOFTWARE_SERIAL
#include <SoftwareSerial.h>
SoftwareSerial *hanSerial = new SoftwareSerial(3);
#else
HardwareSerial *hanSerial = &Serial;
#endif
#else
HardwareSerial *hanSerial = &Serial;
#endif
// Build settings for Wemos Lolin D32
#elif defined(ARDUINO_LOLIN_D32)

View File

@@ -44,8 +44,6 @@ Stream* debugger = NULL;
// The HAN Port reader, used to read serial data and decode DLMS
HanReader hanReader;
boolean hasTempSensor = false;
// the setup function runs once when you press reset or power the board
void setup() {
if(config.hasConfig()) {
@@ -54,9 +52,18 @@ void setup() {
#if DEBUG_MODE
#if HW_ROARFRED
#if SOFTWARE_SERIAL
SoftwareSerial *ser = new SoftwareSerial(-1, 1);
ser->begin(115200, SWSERIAL_8N1);
debugger = ser;
#else
HardwareSerial *ser = &Serial;
if(config.getMeterType() == 3) {
ser->begin(2400, SERIAL_8N1);
} else {
ser->begin(2400, SERIAL_8E1);
}
#endif
#else
HardwareSerial *ser = &Serial;
ser->begin(115200, SERIAL_8N1);
@@ -76,9 +83,7 @@ void setup() {
if (vcc > 0 && vcc < 3.1) {
if(debugger) {
debugger->print("Voltage is too low: ");
debugger->print(vcc);
debugger->println("mV");
debugger->println("Voltage is too low, sleeping");
debugger->flush();
}
ESP.deepSleep(10000000); //Deep sleep to allow output cap to charge up
@@ -88,20 +93,15 @@ void setup() {
pinMode(LED_PIN, OUTPUT);
pinMode(AP_BUTTON_PIN, INPUT_PULLUP);
led_off();
WiFi.disconnect(true);
WiFi.softAPdisconnect(true);
WiFi.mode(WIFI_OFF);
if(debugger) {
if(hasTempSensor) {
debugger->println("Has temp sensor");
} else {
debugger->println("No temp sensor found");
}
}
if(config.hasConfig()) {
if(debugger) config.print(debugger);
WiFi_connect();
client = new WiFiClient();
} else {
if(debugger) {
@@ -116,7 +116,6 @@ void setup() {
} else {
hanSerial->begin(2400, SWSERIAL_8E1);
}
#elif defined DEBUG_MODE
#else
if(config.getMeterType() == 3) {
hanSerial->begin(2400, SERIAL_8N1);
@@ -143,14 +142,18 @@ bool longPressActive = false;
bool wifiConnected = false;
unsigned long lastTemperatureRead = 0;
double temperature = -127;
void loop() {
unsigned long now = millis();
if (digitalRead(AP_BUTTON_PIN) == LOW) {
if (buttonActive == false) {
buttonActive = true;
buttonTimer = millis();
buttonTimer = now;
}
if ((millis() - buttonTimer > longPressTime) && (longPressActive == false)) {
if ((now - buttonTimer > longPressTime) && (longPressActive == false)) {
longPressActive = true;
swapWifiMode();
}
@@ -165,6 +168,11 @@ void loop() {
}
}
if(now - lastTemperatureRead > 10000) {
temperature = hw.getTemperature();
lastTemperatureRead = now;
}
// Only do normal stuff if we're not booted as AP
if (WiFi.getMode() != WIFI_AP) {
// Turn off the LED
@@ -181,29 +189,20 @@ void loop() {
}
if (!config.getMqttHost().isEmpty()) {
mqtt.loop();
yield();
delay(10);
if(!mqtt.connected() || config.isMqttChanged()) {
MQTT_connect();
}
} else if(mqtt.connected()) {
mqtt.disconnect();
yield();
}
}
} else {
dnsServer.processNextRequest();
// Continously flash the LED when AP mode
if (millis() / 50 % 64 == 0) led_on();
if (now / 50 % 64 == 0) led_on();
else led_off();
// Make sure there is enough power to run
double vcc = hw.getVcc();
if(vcc > 0) {
delay(max(10, 3500-(int)(vcc*1000)));
} else {
delay(10);
}
}
readHanPort();
ws.loop();
@@ -239,7 +238,7 @@ void swapWifiMode() {
WiFi.mode(WIFI_OFF);
yield();
if (mode != WIFI_AP) {
if (mode != WIFI_AP || !config.hasConfig()) {
if(debugger) debugger->println("Swapping to AP mode");
WiFi.softAP("AMS2MQTT");
WiFi.mode(WIFI_AP);
@@ -298,9 +297,8 @@ void readHanPort() {
float rssi = WiFi.RSSI();
rssi = isnan(rssi) ? -100.0 : rssi;
json["rssi"] = rssi;
double temp = hw.getTemperature();
if(temp != -127) {
json["temp"] = temp;
if(temperature != -127) {
json["temp"] = temperature;
}
// Add a sub-structure to the json object,
@@ -406,6 +404,7 @@ void WiFi_connect() {
WiFi.enableAP(false);
WiFi.mode(WIFI_STA);
// WiFi.setOutputPower(0);
if(!config.getWifiIp().isEmpty()) {
IPAddress ip, gw, sn(255,255,255,0);
ip.fromString(config.getWifiIp());

View File

@@ -23,10 +23,10 @@ void AmsWebServer::setup(AmsConfiguration* config, Stream* debugger, MQTTClient*
this->mqtt = mqtt;
server.on("/", std::bind(&AmsWebServer::indexHtml, this));
server.on("/config/meter", std::bind(&AmsWebServer::configMeterHtml, this));
server.on("/config/wifi", std::bind(&AmsWebServer::configWifiHtml, this));
server.on("/config/mqtt", std::bind(&AmsWebServer::configMqttHtml, this));
server.on("/config/web", std::bind(&AmsWebServer::configWebHtml, this));
server.on("/config-meter", std::bind(&AmsWebServer::configMeterHtml, this));
server.on("/config-wifi", std::bind(&AmsWebServer::configWifiHtml, this));
server.on("/config-mqtt", std::bind(&AmsWebServer::configMqttHtml, this));
server.on("/config-web", std::bind(&AmsWebServer::configWebHtml, this));
server.on("/boot.css", std::bind(&AmsWebServer::bootCss, this));
server.on("/gaugemeter.js", std::bind(&AmsWebServer::gaugemeterJs, this));
server.on("/data.json", std::bind(&AmsWebServer::dataJson, this));
@@ -57,14 +57,15 @@ void AmsWebServer::setJson(StaticJsonDocument<1024> json) {
u3 = json["data"]["U3"].as<double>();
i3 = json["data"]["I3"].as<double>();
}
}
if(maxPwr == 0 && config->hasConfig() && config->getMainFuse() > 0 && config->getDistributionSystem() > 0) {
int volt = config->getDistributionSystem() == 2 ? 400 : 230;
if(u2 > 0) {
maxPwr = config->getMainFuse() * sqrt(3) * volt;
} else {
maxPwr = config->getMainFuse() * 230;
// Only way to determine if you have more than one phase is to run this code here
if(maxPwr == 0 && config->hasConfig() && config->getMainFuse() > 0 && config->getDistributionSystem() > 0) {
int volt = config->getDistributionSystem() == 2 ? 400 : 230;
if(u2 > 0) {
maxPwr = config->getMainFuse() * sqrt(3) * volt;
} else {
maxPwr = config->getMainFuse() * 230;
}
}
}
@@ -302,8 +303,6 @@ void AmsWebServer::dataJson() {
String jsonStr;
if(!this->json.isNull() && this->json.containsKey("data")) {
println(" json has data");
int maxPwr = this->maxPwr;
if(maxPwr == 0) {
if(u2 > 0) {
@@ -312,18 +311,20 @@ void AmsWebServer::dataJson() {
maxPwr = 10000;
}
}
int maxPrd = config->getProductionCapacity() * 1000;
json["up"] = this->json["up"];
json["t"] = this->json["t"];
json["data"] = this->json["data"];
json["p_pct"] = min(p*100/maxPwr, 100);
json["po_pct"] = min(po*100/maxPrd, 100);
json["p_pct"] = min(p*100/maxPwr, 100);
if(config->getProductionCapacity() > 0) {
int maxPrd = config->getProductionCapacity() * 1000;
json["po_pct"] = min(po*100/maxPrd, 100);
}
} else {
json["p_pct"] = -1;
json["po_pct"] = -1;
println(" json is empty");
json["p_pct"] = -1;
json["po_pct"] = -1;
}
unsigned long now = millis();