mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-03-09 20:38:56 +00:00
Finalized new configuration menu and moved AP button trigger from setup to loop
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
name=HanConfigAp
|
||||
version=1.0.0
|
||||
author=roarfred
|
||||
maintainer=roarfred <not@important.com>
|
||||
sentence=HAN Configuraiton accesspoint
|
||||
paragraph=HAN Configuraiton accesspoint
|
||||
category=Sensors
|
||||
url=https://github.com/roarfred/AmsToMqttBridge
|
||||
architectures=*
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2016 Arturo Guadalupi. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "Base64.h"
|
||||
#include <Arduino.h>
|
||||
#if (defined(__AVR__))
|
||||
#include <avr\pgmspace.h>
|
||||
#else
|
||||
#include <pgmspace.h>
|
||||
#endif
|
||||
const char PROGMEM _Base64AlphabetTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
int Base64Class::encode(char *output, char *input, int inputLength) {
|
||||
int i = 0, j = 0;
|
||||
int encodedLength = 0;
|
||||
unsigned char A3[3];
|
||||
unsigned char A4[4];
|
||||
|
||||
while(inputLength--) {
|
||||
A3[i++] = *(input++);
|
||||
if(i == 3) {
|
||||
fromA3ToA4(A4, A3);
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
output[encodedLength++] = pgm_read_byte(&_Base64AlphabetTable[A4[i]]);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(i) {
|
||||
for(j = i; j < 3; j++) {
|
||||
A3[j] = '\0';
|
||||
}
|
||||
|
||||
fromA3ToA4(A4, A3);
|
||||
|
||||
for(j = 0; j < i + 1; j++) {
|
||||
output[encodedLength++] = pgm_read_byte(&_Base64AlphabetTable[A4[j]]);
|
||||
}
|
||||
|
||||
while((i++ < 3)) {
|
||||
output[encodedLength++] = '=';
|
||||
}
|
||||
}
|
||||
output[encodedLength] = '\0';
|
||||
return encodedLength;
|
||||
}
|
||||
|
||||
int Base64Class::decode(char * output, char * input, int inputLength) {
|
||||
int i = 0, j = 0;
|
||||
int decodedLength = 0;
|
||||
unsigned char A3[3];
|
||||
unsigned char A4[4];
|
||||
|
||||
|
||||
while (inputLength--) {
|
||||
if(*input == '=') {
|
||||
break;
|
||||
}
|
||||
|
||||
A4[i++] = *(input++);
|
||||
if (i == 4) {
|
||||
for (i = 0; i <4; i++) {
|
||||
A4[i] = lookupTable(A4[i]);
|
||||
}
|
||||
|
||||
fromA4ToA3(A3,A4);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
output[decodedLength++] = A3[i];
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j < 4; j++) {
|
||||
A4[j] = '\0';
|
||||
}
|
||||
|
||||
for (j = 0; j <4; j++) {
|
||||
A4[j] = lookupTable(A4[j]);
|
||||
}
|
||||
|
||||
fromA4ToA3(A3,A4);
|
||||
|
||||
for (j = 0; j < i - 1; j++) {
|
||||
output[decodedLength++] = A3[j];
|
||||
}
|
||||
}
|
||||
output[decodedLength] = '\0';
|
||||
return decodedLength;
|
||||
}
|
||||
|
||||
int Base64Class::encodedLength(int plainLength) {
|
||||
int n = plainLength;
|
||||
return (n + 2 - ((n + 2) % 3)) / 3 * 4;
|
||||
}
|
||||
|
||||
int Base64Class::decodedLength(char * input, int inputLength) {
|
||||
int i = 0;
|
||||
int numEq = 0;
|
||||
for(i = inputLength - 1; input[i] == '='; i--) {
|
||||
numEq++;
|
||||
}
|
||||
|
||||
return ((6 * inputLength) / 8) - numEq;
|
||||
}
|
||||
|
||||
//Private utility functions
|
||||
inline void Base64Class::fromA3ToA4(unsigned char * A4, unsigned char * A3) {
|
||||
A4[0] = (A3[0] & 0xfc) >> 2;
|
||||
A4[1] = ((A3[0] & 0x03) << 4) + ((A3[1] & 0xf0) >> 4);
|
||||
A4[2] = ((A3[1] & 0x0f) << 2) + ((A3[2] & 0xc0) >> 6);
|
||||
A4[3] = (A3[2] & 0x3f);
|
||||
}
|
||||
|
||||
inline void Base64Class::fromA4ToA3(unsigned char * A3, unsigned char * A4) {
|
||||
A3[0] = (A4[0] << 2) + ((A4[1] & 0x30) >> 4);
|
||||
A3[1] = ((A4[1] & 0xf) << 4) + ((A4[2] & 0x3c) >> 2);
|
||||
A3[2] = ((A4[2] & 0x3) << 6) + A4[3];
|
||||
}
|
||||
|
||||
inline unsigned char Base64Class::lookupTable(char c) {
|
||||
if(c >='A' && c <='Z') return c - 'A';
|
||||
if(c >='a' && c <='z') return c - 71;
|
||||
if(c >='0' && c <='9') return c + 4;
|
||||
if(c == '+') return 62;
|
||||
if(c == '/') return 63;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Base64Class Base64;
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2016 Arturo Guadalupi. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _BASE64_H
|
||||
#define _BASE64_H
|
||||
|
||||
class Base64Class{
|
||||
public:
|
||||
int encode(char *output, char *input, int inputLength);
|
||||
int decode(char * output, char * input, int inputLength);
|
||||
int encodedLength(int plainLength);
|
||||
int decodedLength(char * input, int inputLength);
|
||||
|
||||
private:
|
||||
inline void fromA3ToA4(unsigned char * A4, unsigned char * A3);
|
||||
inline void fromA4ToA3(unsigned char * A3, unsigned char * A4);
|
||||
inline unsigned char lookupTable(char c);
|
||||
};
|
||||
extern Base64Class Base64;
|
||||
|
||||
#endif // _BASE64_H
|
||||
@@ -1,91 +0,0 @@
|
||||
#include "HanConfigAp.h"
|
||||
|
||||
Stream* HanConfigAp::debugger;
|
||||
|
||||
bool HanConfigAp::hasConfig() {
|
||||
return config->hasConfig();
|
||||
}
|
||||
|
||||
void HanConfigAp::setup(int accessPointButtonPin, configuration* config, Stream* debugger)
|
||||
{
|
||||
this->debugger = debugger;
|
||||
this->config = config;
|
||||
|
||||
// Test if we're missing configuration
|
||||
if (!config->hasConfig())
|
||||
{
|
||||
print("No config. We're booting as AP. Look for SSID ");
|
||||
println(this->AP_SSID);
|
||||
isActivated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load the configuration
|
||||
if (this->debugger) config->print(this->debugger);
|
||||
|
||||
if (accessPointButtonPin != INVALID_BUTTON_PIN)
|
||||
{
|
||||
// Assign pin for boot as AP
|
||||
pinMode(accessPointButtonPin, INPUT_PULLUP);
|
||||
|
||||
// Test if we're holding down the AP pin, over 1 second
|
||||
int time = millis() + 1000;
|
||||
print("Press the AP button now to boot as access point");
|
||||
while (millis() < time)
|
||||
{
|
||||
print(".");
|
||||
if (digitalRead(accessPointButtonPin) == LOW)
|
||||
{
|
||||
print("AP button was pressed. Booting as access point now. Look for SSID ");
|
||||
println(this->AP_SSID);
|
||||
isActivated = true;
|
||||
break;
|
||||
}
|
||||
delay(100);
|
||||
}
|
||||
println("");
|
||||
}
|
||||
}
|
||||
|
||||
if (isActivated)
|
||||
{
|
||||
// Setup AP
|
||||
WiFi.disconnect(true);
|
||||
WiFi.softAPdisconnect(true);
|
||||
WiFi.mode(WIFI_OFF);
|
||||
delay(2000);
|
||||
|
||||
WiFi.mode(WIFI_AP);
|
||||
WiFi.softAP(AP_SSID);
|
||||
|
||||
/* Setup the DNS server redirecting all the domains to this IP */
|
||||
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
|
||||
dnsServer.start(DNS_PORT, "*", WiFi.softAPIP());
|
||||
}
|
||||
}
|
||||
|
||||
bool HanConfigAp::loop() {
|
||||
if(isActivated) {
|
||||
//DNS
|
||||
dnsServer.processNextRequest();
|
||||
}
|
||||
|
||||
return isActivated;
|
||||
}
|
||||
|
||||
size_t HanConfigAp::print(const char* text)
|
||||
{
|
||||
if (debugger) debugger->print(text);
|
||||
}
|
||||
size_t HanConfigAp::println(const char* text)
|
||||
{
|
||||
if (debugger) debugger->println(text);
|
||||
}
|
||||
size_t HanConfigAp::print(const Printable& data)
|
||||
{
|
||||
if (debugger) debugger->print(data);
|
||||
}
|
||||
size_t HanConfigAp::println(const Printable& data)
|
||||
{
|
||||
if (debugger) debugger->println(data);
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
// ap.h
|
||||
|
||||
#ifndef _ACCESSPOINT_h
|
||||
#define _ACCESSPOINT_h
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#if defined(ESP8266)
|
||||
#include <ESP8266WiFi.h>
|
||||
#elif defined(ESP32) // ARDUINO_ARCH_ESP32
|
||||
#include <WiFi.h>
|
||||
#else
|
||||
#warning "Unsupported board type"
|
||||
#endif
|
||||
|
||||
#include <DNSServer.h>
|
||||
#include "configuration.h"
|
||||
|
||||
#define INVALID_BUTTON_PIN 0xFFFFFFFF
|
||||
|
||||
class HanConfigAp {
|
||||
public:
|
||||
void setup(int accessPointButtonPin, configuration* config, Stream* debugger);
|
||||
bool loop();
|
||||
bool hasConfig();
|
||||
bool isActivated = false;
|
||||
|
||||
private:
|
||||
const char* AP_SSID = "AMS2MQTT";
|
||||
|
||||
configuration* config;
|
||||
|
||||
// DNS server
|
||||
const byte DNS_PORT = 53;
|
||||
DNSServer dnsServer;
|
||||
|
||||
static size_t print(const char* text);
|
||||
static size_t println(const char* text);
|
||||
static size_t print(const Printable& data);
|
||||
static size_t println(const Printable& data);
|
||||
|
||||
static Stream* debugger;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,260 +0,0 @@
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include "configuration.h"
|
||||
|
||||
bool configuration::hasConfig()
|
||||
{
|
||||
bool hasConfig = false;
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
hasConfig = EEPROM.read(EEPROM_CONFIG_ADDRESS) == EEPROM_CHECK_SUM;
|
||||
EEPROM.end();
|
||||
return hasConfig;
|
||||
}
|
||||
|
||||
bool configuration::save()
|
||||
{
|
||||
int address = EEPROM_CONFIG_ADDRESS;
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(address, EEPROM_CHECK_SUM);
|
||||
address++;
|
||||
|
||||
address += saveString(address, ssid);
|
||||
address += saveString(address, ssidPassword);
|
||||
address += saveByte(address, meterType);
|
||||
|
||||
|
||||
if(mqttHost) {
|
||||
address += saveBool(address, true);
|
||||
address += saveString(address, mqttHost);
|
||||
address += saveInt(address, mqttPort);
|
||||
address += saveString(address, mqttClientID);
|
||||
address += saveString(address, mqttPublishTopic);
|
||||
address += saveString(address, mqttSubscribeTopic);
|
||||
} else {
|
||||
address += saveBool(address, false);
|
||||
}
|
||||
|
||||
if (isSecure()) {
|
||||
address += saveBool(address, true);
|
||||
address += saveString(address, mqttUser);
|
||||
address += saveString(address, mqttPass);
|
||||
}
|
||||
else
|
||||
address += saveBool(address, false);
|
||||
|
||||
|
||||
address += saveByte(address, authSecurity);
|
||||
if (authSecurity > 0) {
|
||||
address += saveString(address, authUser);
|
||||
address += saveString(address, authPass);
|
||||
}
|
||||
|
||||
address += saveInt(address, fuseSize);
|
||||
address += saveInt(address, distSys);
|
||||
|
||||
bool success = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
bool configuration::load()
|
||||
{
|
||||
int address = EEPROM_CONFIG_ADDRESS;
|
||||
bool success = false;
|
||||
|
||||
ssid = 0;
|
||||
ssidPassword = 0;
|
||||
mqttHost = 0;
|
||||
mqttClientID = 0;
|
||||
mqttPublishTopic = 0;
|
||||
mqttSubscribeTopic = 0;
|
||||
mqttUser = 0;
|
||||
mqttPass = 0;
|
||||
authUser = 0;
|
||||
authPass = 0;
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
int cs = EEPROM.read(address);
|
||||
if (cs == EEPROM_CHECK_SUM)
|
||||
{
|
||||
address++;
|
||||
|
||||
address += readString(address, &ssid);
|
||||
address += readString(address, &ssidPassword);
|
||||
address += readByte(address, &meterType);
|
||||
|
||||
bool mqtt = false;
|
||||
address += readBool(address, &mqtt);
|
||||
if(mqtt) {
|
||||
address += readString(address, &mqttHost);
|
||||
address += readInt(address, &mqttPort);
|
||||
address += readString(address, &mqttClientID);
|
||||
address += readString(address, &mqttPublishTopic);
|
||||
address += readString(address, &mqttSubscribeTopic);
|
||||
}
|
||||
|
||||
bool secure = false;
|
||||
address += readBool(address, &secure);
|
||||
if (secure)
|
||||
{
|
||||
address += readString(address, &mqttUser);
|
||||
address += readString(address, &mqttPass);
|
||||
}
|
||||
else
|
||||
{
|
||||
mqttUser = 0;
|
||||
mqttPass = 0;
|
||||
}
|
||||
|
||||
address += readByte(address, &authSecurity);
|
||||
if (authSecurity > 0) {
|
||||
address += readString(address, &authUser);
|
||||
address += readString(address, &authPass);
|
||||
} else {
|
||||
authUser = 0;
|
||||
authPass = 0;
|
||||
}
|
||||
|
||||
address += readInt(address, &fuseSize);
|
||||
address += readByte(address, &distSys);
|
||||
|
||||
success = true;
|
||||
}
|
||||
EEPROM.end();
|
||||
return success;
|
||||
}
|
||||
|
||||
bool configuration::isSecure()
|
||||
{
|
||||
return (mqttUser != 0) && (String(mqttUser).length() > 0);
|
||||
}
|
||||
|
||||
int configuration::readInt(int address, int *value)
|
||||
{
|
||||
int lower = EEPROM.read(address);
|
||||
int higher = EEPROM.read(address + 1);
|
||||
*value = lower + (higher << 8);
|
||||
return 2;
|
||||
}
|
||||
int configuration::saveInt(int address, int value)
|
||||
{
|
||||
byte lowByte = value & 0xFF;
|
||||
byte highByte = ((value >> 8) & 0xFF);
|
||||
|
||||
EEPROM.write(address, lowByte);
|
||||
EEPROM.write(address + 1, highByte);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
int configuration::readBool(int address, bool *value)
|
||||
{
|
||||
byte y = EEPROM.read(address);
|
||||
*value = (bool)y;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int configuration::saveBool(int address, bool value)
|
||||
{
|
||||
byte y = (byte)value;
|
||||
EEPROM.write(address, y);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int configuration::readByte(int address, byte *value)
|
||||
{
|
||||
*value = EEPROM.read(address);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int configuration::saveByte(int address, byte value)
|
||||
{
|
||||
EEPROM.write(address, value);
|
||||
return 1;
|
||||
}
|
||||
void configuration::print(Stream* debugger)
|
||||
{
|
||||
debugger->println("Configuration:");
|
||||
debugger->println("-----------------------------------------------");
|
||||
debugger->printf("ssid: %s\r\n", this->ssid);
|
||||
debugger->printf("ssidPassword: %s\r\n", this->ssidPassword);
|
||||
debugger->printf("meterType: %i\r\n", this->meterType);
|
||||
if(this->mqttHost) {
|
||||
debugger->printf("mqttHost: %s\r\n", this->mqttHost);
|
||||
debugger->printf("mqttPort: %i\r\n", this->mqttPort);
|
||||
debugger->printf("mqttClientID: %s\r\n", this->mqttClientID);
|
||||
debugger->printf("mqttPublishTopic: %s\r\n", this->mqttPublishTopic);
|
||||
debugger->printf("mqttSubscribeTopic: %s\r\n", this->mqttSubscribeTopic);
|
||||
}
|
||||
|
||||
if (this->isSecure())
|
||||
{
|
||||
debugger->printf("SECURE MQTT CONNECTION:\r\n");
|
||||
debugger->printf("mqttUser: %s\r\n", this->mqttUser);
|
||||
debugger->printf("mqttPass: %s\r\n", this->mqttPass);
|
||||
}
|
||||
|
||||
if (this->authSecurity > 0) {
|
||||
debugger->printf("WEB AUTH:\r\n");
|
||||
debugger->printf("authSecurity: %i\r\n", this->authSecurity);
|
||||
debugger->printf("authUser: %s\r\n", this->authUser);
|
||||
debugger->printf("authPass: %s\r\n", this->authPass);
|
||||
}
|
||||
debugger->printf("fuseSize: %i\r\n", this->fuseSize);
|
||||
debugger->printf("distSys: %i\r\n", this->distSys);
|
||||
|
||||
debugger->println("-----------------------------------------------");
|
||||
}
|
||||
|
||||
template <class T> int configuration::writeAnything(int ee, const T& value)
|
||||
{
|
||||
const byte* p = (const byte*)(const void*)&value;
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(value); i++)
|
||||
EEPROM.write(ee++, *p++);
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class T> int configuration::readAnything(int ee, T& value)
|
||||
{
|
||||
byte* p = (byte*)(void*)&value;
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(value); i++)
|
||||
*p++ = EEPROM.read(ee++);
|
||||
return i;
|
||||
}
|
||||
|
||||
int configuration::readString(int pAddress, char* pString[])
|
||||
{
|
||||
int address = 0;
|
||||
byte length = EEPROM.read(pAddress + address);
|
||||
address++;
|
||||
|
||||
char* buffer = new char[length];
|
||||
for (int i = 0; i<length; i++)
|
||||
{
|
||||
buffer[i] = EEPROM.read(pAddress + address++);
|
||||
}
|
||||
*pString = buffer;
|
||||
return address;
|
||||
}
|
||||
int configuration::saveString(int pAddress, char* pString)
|
||||
{
|
||||
int address = 0;
|
||||
int length = pString ? strlen(pString) + 1 : 0;
|
||||
EEPROM.put(pAddress + address, length);
|
||||
address++;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
EEPROM.put(pAddress + address, pString[i]);
|
||||
address++;
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
// config.h
|
||||
|
||||
#ifndef _CONFIGURATION_h
|
||||
#define _CONFIGURATION_h
|
||||
|
||||
#include <EEPROM.h>
|
||||
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
class configuration {
|
||||
public:
|
||||
char* ssid;
|
||||
char* ssidPassword;
|
||||
char* mqttHost;
|
||||
int mqttPort = 1883;
|
||||
char* mqttClientID;
|
||||
char* mqttPublishTopic;
|
||||
char* mqttSubscribeTopic;
|
||||
char* mqttUser;
|
||||
char* mqttPass;
|
||||
byte meterType;
|
||||
|
||||
byte authSecurity;
|
||||
char* authUser;
|
||||
char* authPass;
|
||||
|
||||
int fuseSize;
|
||||
byte distSys;
|
||||
|
||||
bool hasConfig();
|
||||
bool isSecure();
|
||||
bool save();
|
||||
bool load();
|
||||
|
||||
void print(Stream* debugger);
|
||||
protected:
|
||||
|
||||
private:
|
||||
const int EEPROM_SIZE = 512;
|
||||
const byte EEPROM_CHECK_SUM = 75; // Used to check if config is stored. Change if structure changes
|
||||
const int EEPROM_CONFIG_ADDRESS = 0;
|
||||
|
||||
int saveString(int pAddress, char* pString);
|
||||
int readString(int pAddress, char* pString[]);
|
||||
int saveInt(int pAddress, int pValue);
|
||||
int readInt(int pAddress, int *pValue);
|
||||
int saveBool(int pAddress, bool pValue);
|
||||
int readBool(int pAddress, bool *pValue);
|
||||
int saveByte(int pAddress, byte pValue);
|
||||
int readByte(int pAddress, byte *pValue);
|
||||
|
||||
|
||||
template <class T> int writeAnything(int ee, const T& value);
|
||||
template <class T> int readAnything(int ee, T& value);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,7 @@ extra_configs = platformio-user.ini
|
||||
|
||||
[common]
|
||||
framework = arduino
|
||||
lib_deps = HanConfigAp@1.0.0, HanReader@1.0.0, HanToJson@1.0.0, ArduinoJson@^6.0.0, MQTT@^2.4.0, DallasTemperature@^3.8.0, EspSoftwareSerial@^6.7.1
|
||||
lib_deps = HanReader@1.0.0, HanToJson@1.0.0, ArduinoJson@^6.0.0, MQTT@^2.4.0, DallasTemperature@^3.8.0, EspSoftwareSerial@^6.7.1
|
||||
|
||||
[env:hw1esp12e]
|
||||
platform = espressif8266
|
||||
|
||||
467
src/AmsConfiguration.cpp
Normal file
467
src/AmsConfiguration.cpp
Normal file
@@ -0,0 +1,467 @@
|
||||
#include "AmsConfiguration.h"
|
||||
|
||||
String AmsConfiguration::getWifiSsid() {
|
||||
return wifiSsid;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setWifiSsid(String wifiSsid) {
|
||||
wifiChanged |= this->wifiSsid != wifiSsid;
|
||||
this->wifiSsid = String(wifiSsid);
|
||||
}
|
||||
|
||||
String AmsConfiguration::getWifiPassword() {
|
||||
return wifiPassword;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setWifiPassword(String wifiPassword) {
|
||||
wifiChanged |= this->wifiPassword != wifiPassword;
|
||||
this->wifiPassword = String(wifiPassword);
|
||||
}
|
||||
|
||||
String AmsConfiguration::getWifiIp() {
|
||||
return wifiIp;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setWifiIp(String wifiIp) {
|
||||
wifiChanged |= this->wifiIp != wifiIp;
|
||||
this->wifiIp = String(wifiIp);
|
||||
}
|
||||
|
||||
String AmsConfiguration::getWifiGw() {
|
||||
return wifiGw;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setWifiGw(String wifiGw) {
|
||||
wifiChanged |= this->wifiGw != wifiGw;
|
||||
this->wifiGw = String(wifiGw);
|
||||
}
|
||||
|
||||
String AmsConfiguration::getWifiSubnet() {
|
||||
return wifiSubnet;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setWifiSubnet(String wifiSubnet) {
|
||||
wifiChanged |= this->wifiSubnet != wifiSubnet;
|
||||
this->wifiSubnet = String(wifiSubnet);
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearWifiIp() {
|
||||
setWifiIp("");
|
||||
setWifiGw("");
|
||||
setWifiSubnet("");
|
||||
}
|
||||
|
||||
bool AmsConfiguration::isWifiChanged() {
|
||||
return wifiChanged;
|
||||
}
|
||||
|
||||
void AmsConfiguration::ackWifiChange() {
|
||||
wifiChanged = false;
|
||||
}
|
||||
|
||||
|
||||
String AmsConfiguration::getMqttHost() {
|
||||
return mqttHost;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setMqttHost(String mqttHost) {
|
||||
mqttChanged |= this->mqttHost != mqttHost;
|
||||
this->mqttHost = String(mqttHost);
|
||||
}
|
||||
|
||||
int AmsConfiguration::getMqttPort() {
|
||||
return mqttPort;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setMqttPort(int mqttPort) {
|
||||
mqttChanged |= this->mqttPort != mqttPort;
|
||||
this->mqttPort = mqttPort;
|
||||
}
|
||||
|
||||
String AmsConfiguration::getMqttClientId() {
|
||||
return mqttClientId;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setMqttClientId(String mqttClientId) {
|
||||
mqttChanged |= this->mqttClientId != mqttClientId;
|
||||
this->mqttClientId = String(mqttClientId);
|
||||
}
|
||||
|
||||
String AmsConfiguration::getMqttPublishTopic() {
|
||||
return mqttPublishTopic;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setMqttPublishTopic(String mqttPublishTopic) {
|
||||
mqttChanged |= this->mqttPublishTopic != mqttPublishTopic;
|
||||
this->mqttPublishTopic = String(mqttPublishTopic);
|
||||
}
|
||||
|
||||
String AmsConfiguration::getMqttSubscribeTopic() {
|
||||
return mqttSubscribeTopic;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setMqttSubscribeTopic(String mqttSubscribeTopic) {
|
||||
mqttChanged |= this->mqttSubscribeTopic != mqttSubscribeTopic;
|
||||
this->mqttSubscribeTopic = String(mqttSubscribeTopic);
|
||||
}
|
||||
|
||||
String AmsConfiguration::getMqttUser() {
|
||||
return mqttUser;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setMqttUser(String mqttUser) {
|
||||
mqttChanged |= this->mqttUser != mqttUser;
|
||||
this->mqttUser = String(mqttUser);
|
||||
}
|
||||
|
||||
String AmsConfiguration::getMqttPassword() {
|
||||
return mqttPassword;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setMqttPassword(String mqttPassword) {
|
||||
mqttChanged |= this->mqttPassword != mqttPassword;
|
||||
this->mqttPassword = String(mqttPassword);
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearMqtt() {
|
||||
setMqttHost("");
|
||||
setMqttPort(1883);
|
||||
setMqttClientId("");
|
||||
setMqttPublishTopic("");
|
||||
setMqttSubscribeTopic("");
|
||||
setMqttUser("");
|
||||
setMqttPassword("");
|
||||
}
|
||||
|
||||
bool AmsConfiguration::isMqttChanged() {
|
||||
return mqttChanged;
|
||||
}
|
||||
|
||||
void AmsConfiguration::ackMqttChange() {
|
||||
mqttChanged = false;
|
||||
}
|
||||
|
||||
|
||||
byte AmsConfiguration::getAuthSecurity() {
|
||||
return authSecurity;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setAuthSecurity(byte authSecurity) {
|
||||
this->authSecurity = authSecurity;
|
||||
}
|
||||
|
||||
String AmsConfiguration::getAuthUser() {
|
||||
return authUser;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setAuthUser(String authUser) {
|
||||
this->authUser = String(authUser);
|
||||
}
|
||||
|
||||
String AmsConfiguration::getAuthPassword() {
|
||||
return authPassword;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setAuthPassword(String authPassword) {
|
||||
this->authPassword = String(authPassword);
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearAuth() {
|
||||
setAuthSecurity(0);
|
||||
setAuthUser("");
|
||||
setAuthPassword("");
|
||||
}
|
||||
|
||||
int AmsConfiguration::getMeterType() {
|
||||
return this->meterType;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setMeterType(int meterType) {
|
||||
this->meterType = meterType;
|
||||
}
|
||||
|
||||
int AmsConfiguration::getDistributionSystem() {
|
||||
return this->distributionSystem;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setDistributionSystem(int distributionSystem) {
|
||||
this->distributionSystem = distributionSystem;
|
||||
}
|
||||
|
||||
int AmsConfiguration::getMainFuse() {
|
||||
return this->mainFuse;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setMainFuse(int mainFuse) {
|
||||
this->mainFuse = mainFuse;
|
||||
}
|
||||
|
||||
int AmsConfiguration::getProductionCapacity() {
|
||||
return this->productionCapacity;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setProductionCapacity(int productionCapacity) {
|
||||
this->productionCapacity = productionCapacity;
|
||||
}
|
||||
|
||||
|
||||
bool AmsConfiguration::hasConfig()
|
||||
{
|
||||
bool hasConfig = false;
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
hasConfig = EEPROM.read(EEPROM_CONFIG_ADDRESS) == EEPROM_CHECK_SUM;
|
||||
EEPROM.end();
|
||||
return hasConfig;
|
||||
}
|
||||
|
||||
bool AmsConfiguration::load() {
|
||||
int address = EEPROM_CONFIG_ADDRESS;
|
||||
bool success = false;
|
||||
|
||||
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;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool AmsConfiguration::save() {
|
||||
int address = EEPROM_CONFIG_ADDRESS;
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(address, EEPROM_CHECK_SUM);
|
||||
address++;
|
||||
|
||||
address += saveString(address, wifiSsid.c_str());
|
||||
address += saveString(address, wifiPassword.c_str());
|
||||
address += saveString(address, wifiIp.c_str());
|
||||
address += saveString(address, wifiGw.c_str());
|
||||
address += saveString(address, wifiSubnet.c_str());
|
||||
if(mqttHost) {
|
||||
address += saveBool(address, true);
|
||||
address += saveString(address, mqttHost.c_str());
|
||||
address += saveInt(address, mqttPort);
|
||||
address += saveString(address, mqttClientId.c_str());
|
||||
address += saveString(address, mqttPublishTopic.c_str());
|
||||
address += saveString(address, mqttSubscribeTopic.c_str());
|
||||
if (mqttUser) {
|
||||
address += saveBool(address, true);
|
||||
address += saveString(address, mqttUser.c_str());
|
||||
address += saveString(address, mqttPassword.c_str());
|
||||
} else {
|
||||
address += saveBool(address, false);
|
||||
}
|
||||
} else {
|
||||
address += saveBool(address, false);
|
||||
}
|
||||
|
||||
address += saveByte(address, authSecurity);
|
||||
if (authSecurity > 0) {
|
||||
address += saveString(address, authUser.c_str());
|
||||
address += saveString(address, authPassword.c_str());
|
||||
}
|
||||
|
||||
address += saveInt(address, meterType);
|
||||
address += saveInt(address, distributionSystem);
|
||||
address += saveInt(address, mainFuse);
|
||||
address += saveInt(address, productionCapacity);
|
||||
|
||||
bool success = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
int AmsConfiguration::readString(int pAddress, char* pString[]) {
|
||||
int address = 0;
|
||||
byte length = EEPROM.read(pAddress + address);
|
||||
address++;
|
||||
|
||||
char* buffer = new char[length];
|
||||
for (int i = 0; i<length; i++)
|
||||
{
|
||||
buffer[i] = EEPROM.read(pAddress + address++);
|
||||
}
|
||||
*pString = buffer;
|
||||
return address;
|
||||
}
|
||||
|
||||
int AmsConfiguration::saveString(int pAddress, const char* pString) {
|
||||
int address = 0;
|
||||
int length = pString ? strlen(pString) + 1 : 0;
|
||||
EEPROM.put(pAddress + address, length);
|
||||
address++;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
EEPROM.put(pAddress + address, pString[i]);
|
||||
address++;
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
int AmsConfiguration::readInt(int address, int *value) {
|
||||
int lower = EEPROM.read(address);
|
||||
int higher = EEPROM.read(address + 1);
|
||||
*value = lower + (higher << 8);
|
||||
return 2;
|
||||
}
|
||||
|
||||
int AmsConfiguration::saveInt(int address, int value) {
|
||||
byte lowByte = value & 0xFF;
|
||||
byte highByte = ((value >> 8) & 0xFF);
|
||||
|
||||
EEPROM.write(address, lowByte);
|
||||
EEPROM.write(address + 1, highByte);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
int AmsConfiguration::readBool(int address, bool *value) {
|
||||
byte y = EEPROM.read(address);
|
||||
*value = (bool)y;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int AmsConfiguration::saveBool(int address, bool value) {
|
||||
byte y = (byte)value;
|
||||
EEPROM.write(address, y);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int AmsConfiguration::readByte(int address, byte *value) {
|
||||
*value = EEPROM.read(address);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int AmsConfiguration::saveByte(int address, byte value) {
|
||||
EEPROM.write(address, value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <class T> int AmsConfiguration::writeAnything(int ee, const T& value) {
|
||||
const byte* p = (const byte*)(const void*)&value;
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(value); i++)
|
||||
EEPROM.write(ee++, *p++);
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class T> int AmsConfiguration::readAnything(int ee, T& value) {
|
||||
byte* p = (byte*)(void*)&value;
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(value); i++)
|
||||
*p++ = EEPROM.read(ee++);
|
||||
return i;
|
||||
}
|
||||
|
||||
void AmsConfiguration::print(Stream* debugger)
|
||||
{
|
||||
debugger->println("Configuration:");
|
||||
debugger->println("-----------------------------------------------");
|
||||
debugger->printf("WiFi SSID: %s\r\n", this->getWifiSsid().c_str());
|
||||
debugger->printf("WiFi Psk: %s\r\n", this->getWifiPassword().c_str());
|
||||
|
||||
if(getWifiIp()) {
|
||||
debugger->printf("IP: %s\r\n", this->getWifiIp().c_str());
|
||||
debugger->printf("Gateway: %s\r\n", this->getWifiGw().c_str());
|
||||
debugger->printf("Subnet: %s\r\n", this->getWifiSubnet().c_str());
|
||||
}
|
||||
|
||||
if(getMqttHost()) {
|
||||
debugger->printf("mqttHost: %s\r\n", this->getMqttHost().c_str());
|
||||
debugger->printf("mqttPort: %i\r\n", this->getMqttPort());
|
||||
debugger->printf("mqttClientID: %s\r\n", this->getMqttClientId().c_str());
|
||||
debugger->printf("mqttPublishTopic: %s\r\n", this->getMqttPublishTopic().c_str());
|
||||
debugger->printf("mqttSubscribeTopic: %s\r\n", this->getMqttSubscribeTopic().c_str());
|
||||
if (this->getMqttUser()) {
|
||||
debugger->printf("SECURE MQTT CONNECTION:\r\n");
|
||||
debugger->printf("mqttUser: %s\r\n", this->getMqttUser().c_str());
|
||||
debugger->printf("mqttPass: %s\r\n", this->getMqttPassword().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (this->getAuthSecurity()) {
|
||||
debugger->printf("WEB AUTH:\r\n");
|
||||
debugger->printf("authSecurity: %i\r\n", this->getAuthSecurity());
|
||||
debugger->printf("authUser: %s\r\n", this->getAuthUser().c_str());
|
||||
debugger->printf("authPass: %s\r\n", this->getAuthPassword().c_str());
|
||||
}
|
||||
|
||||
debugger->printf("meterType: %i\r\n", this->getMeterType());
|
||||
debugger->printf("distSys: %i\r\n", this->getDistributionSystem());
|
||||
debugger->printf("fuseSize: %i\r\n", this->getMainFuse());
|
||||
debugger->printf("productionCapacity: %i\r\n", this->getProductionCapacity());
|
||||
|
||||
debugger->println("-----------------------------------------------");
|
||||
}
|
||||
106
src/AmsConfiguration.h
Normal file
106
src/AmsConfiguration.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#ifndef _AMSCONFIGURATION_h
|
||||
#define _AMSCONFIGURATION_h
|
||||
#include <EEPROM.h>
|
||||
#include "Arduino.h"
|
||||
|
||||
class AmsConfiguration {
|
||||
public:
|
||||
bool hasConfig();
|
||||
bool load();
|
||||
bool save();
|
||||
|
||||
String getWifiSsid();
|
||||
void setWifiSsid(String wifiSsid);
|
||||
String getWifiPassword();
|
||||
void setWifiPassword(String wifiPassword);
|
||||
String getWifiIp();
|
||||
void setWifiIp(String wifiIp);
|
||||
String getWifiGw();
|
||||
void setWifiGw(String wifiGw);
|
||||
String getWifiSubnet();
|
||||
void setWifiSubnet(String wifiSubnet);
|
||||
void clearWifiIp();
|
||||
|
||||
bool isWifiChanged();
|
||||
void ackWifiChange();
|
||||
|
||||
String getMqttHost();
|
||||
void setMqttHost(String mqttHost);
|
||||
int getMqttPort();
|
||||
void setMqttPort(int mqttPort);
|
||||
String getMqttClientId();
|
||||
void setMqttClientId(String mqttClientId);
|
||||
String getMqttPublishTopic();
|
||||
void setMqttPublishTopic(String mqttPublishTopic);
|
||||
String getMqttSubscribeTopic();
|
||||
void setMqttSubscribeTopic(String mqttSubscribeTopic);
|
||||
String getMqttUser();
|
||||
void setMqttUser(String mqttUser);
|
||||
String getMqttPassword();
|
||||
void setMqttPassword(String mqttPassword);
|
||||
void clearMqtt();
|
||||
|
||||
bool isMqttChanged();
|
||||
void ackMqttChange();
|
||||
|
||||
byte getAuthSecurity();
|
||||
void setAuthSecurity(byte authSecurity);
|
||||
String getAuthUser();
|
||||
void setAuthUser(String authUser);
|
||||
String getAuthPassword();
|
||||
void setAuthPassword(String authPassword);
|
||||
void clearAuth();
|
||||
|
||||
int getMeterType();
|
||||
void setMeterType(int meterType);
|
||||
int getDistributionSystem();
|
||||
void setDistributionSystem(int distributionSystem);
|
||||
int getMainFuse();
|
||||
void setMainFuse(int mainFuse);
|
||||
int getProductionCapacity();
|
||||
void setProductionCapacity(int productionCapacity);
|
||||
|
||||
void print(Stream* debugger);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
String wifiSsid;
|
||||
String wifiPassword;
|
||||
String wifiIp;
|
||||
String wifiGw;
|
||||
String wifiSubnet;
|
||||
bool wifiChanged;
|
||||
|
||||
String mqttHost;
|
||||
int mqttPort;
|
||||
String mqttClientId;
|
||||
String mqttPublishTopic;
|
||||
String mqttSubscribeTopic;
|
||||
String mqttUser;
|
||||
String mqttPassword;
|
||||
bool mqttChanged;
|
||||
|
||||
byte authSecurity;
|
||||
String authUser;
|
||||
String authPassword;
|
||||
|
||||
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_CONFIG_ADDRESS = 0;
|
||||
|
||||
int saveString(int pAddress, const char* pString);
|
||||
int readString(int pAddress, char* pString[]);
|
||||
int saveInt(int pAddress, int pValue);
|
||||
int readInt(int pAddress, int *pValue);
|
||||
int saveBool(int pAddress, bool pValue);
|
||||
int readBool(int pAddress, bool *pValue);
|
||||
int saveByte(int pAddress, byte pValue);
|
||||
int readByte(int pAddress, byte *pValue);
|
||||
|
||||
template <class T> int writeAnything(int ee, const T& value);
|
||||
template <class T> int readAnything(int ee, T& value);
|
||||
};
|
||||
#endif
|
||||
@@ -1,5 +1,7 @@
|
||||
#define WIFI_CONNECTION_TIMEOUT 30000;
|
||||
|
||||
#define INVALID_BUTTON_PIN 0xFFFFFFFF
|
||||
|
||||
|
||||
#if defined(ESP8266)
|
||||
#include <ESP8266WiFi.h>
|
||||
|
||||
@@ -6,14 +6,15 @@
|
||||
|
||||
#if defined(ESP8266)
|
||||
ADC_MODE(ADC_VCC);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "AmsToMqttBridge.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include <MQTT.h>
|
||||
#include <DNSServer.h>
|
||||
|
||||
#include "web/AmsWebServer.h"
|
||||
#include "HanConfigAp.h"
|
||||
#include "AmsConfiguration.h"
|
||||
#include "HanReader.h"
|
||||
#include "HanToJson.h"
|
||||
|
||||
@@ -21,11 +22,10 @@ ADC_MODE(ADC_VCC);
|
||||
#include "Kaifa.h"
|
||||
#include "Kamstrup.h"
|
||||
|
||||
// Configuration
|
||||
configuration config;
|
||||
DNSServer dnsServer;
|
||||
|
||||
// Object used to boot as Access Point
|
||||
HanConfigAp ap;
|
||||
// Configuration
|
||||
AmsConfiguration config;
|
||||
|
||||
// Web server
|
||||
AmsWebServer ws;
|
||||
@@ -51,7 +51,7 @@ void setup() {
|
||||
#if SOFTWARE_SERIAL
|
||||
debugger->begin(115200, SERIAL_8N1);
|
||||
#else
|
||||
if(config.meterType == 3) {
|
||||
if(config.getMeterType() == 3) {
|
||||
hanSerial->begin(2400, SERIAL_8N1);
|
||||
} else {
|
||||
hanSerial->begin(2400, SERIAL_8E1);
|
||||
@@ -84,27 +84,31 @@ void setup() {
|
||||
|
||||
// Flash the LED, to indicate we can boot as AP now
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
led_on();
|
||||
pinMode(AP_BUTTON_PIN, INPUT_PULLUP);
|
||||
|
||||
delay(1000);
|
||||
WiFi.disconnect(true);
|
||||
WiFi.softAPdisconnect(true);
|
||||
WiFi.mode(WIFI_OFF);
|
||||
|
||||
// Initialize the AP
|
||||
ap.setup(AP_BUTTON_PIN, &config, debugger);
|
||||
|
||||
led_off();
|
||||
|
||||
if (!ap.isActivated) {
|
||||
setupWiFi();
|
||||
if(config.hasConfig()) {
|
||||
if(debugger) config.print(debugger);
|
||||
client = new WiFiClient();
|
||||
} else {
|
||||
if(debugger) {
|
||||
debugger->println("No configuration, booting AP");
|
||||
}
|
||||
swapWifiMode();
|
||||
}
|
||||
|
||||
#if defined SOFTWARE_SERIAL
|
||||
if(config.meterType == 3) {
|
||||
if(config.getMeterType() == 3) {
|
||||
hanSerial->begin(2400, SWSERIAL_8N1);
|
||||
} else {
|
||||
hanSerial->begin(2400, SWSERIAL_8E1);
|
||||
}
|
||||
#elif defined DEBUG_MODE
|
||||
#else
|
||||
if(config.meterType == 3) {
|
||||
if(config.getMeterType() == 3) {
|
||||
hanSerial->begin(2400, SERIAL_8N1);
|
||||
} else {
|
||||
hanSerial->begin(2400, SERIAL_8E1);
|
||||
@@ -113,20 +117,44 @@ void setup() {
|
||||
hanSerial->swap();
|
||||
#endif
|
||||
#endif
|
||||
while (!&hanSerial);
|
||||
|
||||
hanReader.setup(hanSerial, debugger);
|
||||
hanReader.setup(hanSerial, 0);
|
||||
|
||||
// Compensate for the known Kaifa bug
|
||||
hanReader.compensateFor09HeaderBug = (config.meterType == 1);
|
||||
hanReader.compensateFor09HeaderBug = (config.getMeterType() == 1);
|
||||
|
||||
ws.setup(&config, debugger, &mqtt);
|
||||
}
|
||||
|
||||
// the loop function runs over and over again until power down or reset
|
||||
int buttonTimer = 0;
|
||||
bool buttonActive = false;
|
||||
unsigned long longPressTime = 5000;
|
||||
bool longPressActive = false;
|
||||
|
||||
void loop() {
|
||||
if (digitalRead(AP_BUTTON_PIN) == LOW) {
|
||||
if (buttonActive == false) {
|
||||
buttonActive = true;
|
||||
buttonTimer = millis();
|
||||
}
|
||||
|
||||
if ((millis() - buttonTimer > longPressTime) && (longPressActive == false)) {
|
||||
longPressActive = true;
|
||||
swapWifiMode();
|
||||
}
|
||||
} else {
|
||||
if (buttonActive == true) {
|
||||
if (longPressActive == true) {
|
||||
longPressActive = false;
|
||||
} else {
|
||||
// Single press action
|
||||
}
|
||||
buttonActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Only do normal stuff if we're not booted as AP
|
||||
if (!ap.loop()) {
|
||||
if (WiFi.getMode() != WIFI_AP) {
|
||||
// Turn off the LED
|
||||
led_off();
|
||||
|
||||
@@ -134,15 +162,19 @@ void loop() {
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
WiFi_connect();
|
||||
} else {
|
||||
if (config.mqttHost) {
|
||||
if (!config.getMqttHost().isEmpty()) {
|
||||
mqtt.loop();
|
||||
yield();
|
||||
if(!mqtt.connected()) {
|
||||
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();
|
||||
else led_off();
|
||||
@@ -157,6 +189,7 @@ void loop() {
|
||||
}
|
||||
readHanPort();
|
||||
ws.loop();
|
||||
delay(1); // Needed for auto modem sleep
|
||||
}
|
||||
|
||||
|
||||
@@ -179,25 +212,28 @@ void led_off()
|
||||
#endif
|
||||
}
|
||||
|
||||
void swapWifiMode() {
|
||||
led_on();
|
||||
WiFiMode_t mode = WiFi.getMode();
|
||||
dnsServer.stop();
|
||||
WiFi.disconnect(true);
|
||||
WiFi.softAPdisconnect(true);
|
||||
WiFi.mode(WIFI_OFF);
|
||||
yield();
|
||||
|
||||
void setupWiFi()
|
||||
{
|
||||
// Turn off AP
|
||||
WiFi.enableAP(false);
|
||||
if (mode != WIFI_AP) {
|
||||
if(debugger) debugger->println("Swapping to AP mode");
|
||||
WiFi.softAP("AMS2MQTT");
|
||||
WiFi.mode(WIFI_AP);
|
||||
|
||||
// Connect to WiFi
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(config.ssid, config.ssidPassword);
|
||||
|
||||
// Wait for WiFi connection
|
||||
if (debugger) debugger->print("\nWaiting for WiFi to connect...");
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
if (debugger) debugger->print(".");
|
||||
delay(500);
|
||||
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
|
||||
dnsServer.start(53, "*", WiFi.softAPIP());
|
||||
} else {
|
||||
if(debugger) debugger->println("Swapping to STA mode");
|
||||
WiFi_connect();
|
||||
}
|
||||
if (debugger) debugger->println(" connected");
|
||||
|
||||
client = new WiFiClient();
|
||||
delay(500);
|
||||
led_off();
|
||||
}
|
||||
|
||||
void mqttMessageReceived(String &topic, String &payload)
|
||||
@@ -221,7 +257,7 @@ void readHanPort() {
|
||||
if (hanReader.read()) {
|
||||
lastSuccessfulRead = millis();
|
||||
|
||||
if(config.meterType > 0) {
|
||||
if(config.getMeterType() > 0) {
|
||||
// Flash LED on, this shows us that data is received
|
||||
led_on();
|
||||
|
||||
@@ -254,9 +290,9 @@ void readHanPort() {
|
||||
data["temp"] = tempSensor.getTempCByIndex(0);
|
||||
#endif
|
||||
|
||||
hanToJson(data, config.meterType, hanReader);
|
||||
hanToJson(data, config.getMeterType(), hanReader);
|
||||
|
||||
if(config.mqttHost != 0 && strlen(config.mqttHost) != 0 && config.mqttPublishTopic != 0 && strlen(config.mqttPublishTopic) != 0) {
|
||||
if(!config.getMqttHost().isEmpty() && !config.getMqttPublishTopic().isEmpty()) {
|
||||
// Write the json to the debug port
|
||||
if (debugger) {
|
||||
debugger->print("Sending data to MQTT: ");
|
||||
@@ -268,7 +304,7 @@ void readHanPort() {
|
||||
String msg;
|
||||
serializeJson(json, msg);
|
||||
|
||||
mqtt.publish(config.mqttPublishTopic, msg.c_str());
|
||||
mqtt.publish(config.getMqttPublishTopic(), msg.c_str());
|
||||
mqtt.loop();
|
||||
}
|
||||
ws.setJson(json);
|
||||
@@ -292,26 +328,27 @@ void readHanPort() {
|
||||
if(!list.isEmpty()) {
|
||||
list.toLowerCase();
|
||||
if(list.startsWith("kfm")) {
|
||||
config.meterType = 1;
|
||||
config.setMeterType(1);
|
||||
if(debugger) debugger->println("Detected Kaifa meter");
|
||||
break;
|
||||
} else if(list.startsWith("aidon")) {
|
||||
config.meterType = 2;
|
||||
config.setMeterType(2);
|
||||
if(debugger) debugger->println("Detected Aidon meter");
|
||||
break;
|
||||
} else if(list.startsWith("kamstrup")) {
|
||||
config.meterType = 3;
|
||||
config.setMeterType(3);
|
||||
if(debugger) debugger->println("Detected Kamstrup meter");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
hanReader.compensateFor09HeaderBug = (config.meterType == 1);
|
||||
hanReader.compensateFor09HeaderBug = (config.getMeterType() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(config.meterType == 0 && millis() - lastSuccessfulRead > 10000) {
|
||||
if(config.getMeterType() == 0 && millis() - lastSuccessfulRead > 10000) {
|
||||
lastSuccessfulRead = millis();
|
||||
if(debugger) debugger->println("No data for current setting, switching parity");
|
||||
#if defined SOFTWARE_SERIAL
|
||||
if(even) {
|
||||
hanSerial->begin(2400, SWSERIAL_8N1);
|
||||
@@ -329,59 +366,45 @@ void readHanPort() {
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long wifiTimeout = WIFI_CONNECTION_TIMEOUT;
|
||||
unsigned long lastWifiRetry = -WIFI_CONNECTION_TIMEOUT;
|
||||
void WiFi_connect() {
|
||||
// Connect to WiFi access point.
|
||||
if(millis() - lastWifiRetry < wifiTimeout) {
|
||||
delay(50);
|
||||
return;
|
||||
}
|
||||
lastWifiRetry = millis();
|
||||
|
||||
if (debugger)
|
||||
{
|
||||
debugger->println();
|
||||
debugger->println();
|
||||
debugger->print("Connecting to WiFi network ");
|
||||
debugger->println(config.ssid);
|
||||
debugger->println(config.getWifiSsid());
|
||||
}
|
||||
|
||||
if (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
// Make one first attempt at connect, this seems to considerably speed up the first connection
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
WiFi.disconnect();
|
||||
WiFi.begin(config.ssid, config.ssidPassword);
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
// Wait for the WiFi connection to complete
|
||||
long vTimeout = millis() + WIFI_CONNECTION_TIMEOUT;
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(50);
|
||||
if (debugger) debugger->print(".");
|
||||
|
||||
// If we timed out, disconnect and try again
|
||||
if (vTimeout < millis())
|
||||
{
|
||||
if (debugger)
|
||||
{
|
||||
debugger->print("Timout during connect. WiFi status is: ");
|
||||
debugger->println(WiFi.status());
|
||||
}
|
||||
WiFi.disconnect();
|
||||
WiFi.begin(config.ssid, config.ssidPassword);
|
||||
vTimeout = millis() + WIFI_CONNECTION_TIMEOUT;
|
||||
}
|
||||
yield();
|
||||
}
|
||||
|
||||
if (debugger) {
|
||||
debugger->println();
|
||||
debugger->println("WiFi connected");
|
||||
debugger->println("IP address: ");
|
||||
debugger->println(WiFi.localIP());
|
||||
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());
|
||||
gw.fromString(config.getWifiGw());
|
||||
sn.fromString(config.getWifiSubnet());
|
||||
WiFi.config(ip, gw, sn);
|
||||
}
|
||||
WiFi.begin(config.getWifiSsid().c_str(), config.getWifiPassword().c_str());
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
||||
unsigned long lastMqttRetry = -10000;
|
||||
void MQTT_connect() {
|
||||
if(!config.mqttHost) {
|
||||
if(config.getMqttHost().isEmpty()) {
|
||||
if(debugger) debugger->println("No MQTT config");
|
||||
return;
|
||||
}
|
||||
@@ -392,25 +415,27 @@ void MQTT_connect() {
|
||||
lastMqttRetry = millis();
|
||||
if(debugger) {
|
||||
debugger->print("Connecting to MQTT: ");
|
||||
debugger->print(config.mqttHost);
|
||||
debugger->print(config.getMqttHost());
|
||||
debugger->print(", port: ");
|
||||
debugger->print(config.mqttPort);
|
||||
debugger->print(config.getMqttPort());
|
||||
debugger->println();
|
||||
}
|
||||
|
||||
mqtt.disconnect();
|
||||
yield();
|
||||
|
||||
mqtt.begin(config.mqttHost, config.mqttPort, *client);
|
||||
mqtt.begin(config.getMqttHost().c_str(), config.getMqttPort(), *client);
|
||||
|
||||
// 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 ((config.getMqttUser().isEmpty() && mqtt.connect(config.getMqttClientId().c_str())) ||
|
||||
(!config.getMqttUser().isEmpty() && mqtt.connect(config.getMqttClientId().c_str(), config.getMqttUser().c_str(), config.getMqttPassword().c_str()))) {
|
||||
if (debugger) debugger->println("\nSuccessfully connected to MQTT!");
|
||||
config.ackMqttChange();
|
||||
|
||||
// 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);
|
||||
if (!config.getMqttSubscribeTopic().isEmpty()) {
|
||||
mqtt.subscribe(config.getMqttSubscribeTopic());
|
||||
if (debugger) debugger->printf(" Subscribing to [%s]\r\n", config.getMqttSubscribeTopic().c_str());
|
||||
}
|
||||
|
||||
sendMqttData("Connected!");
|
||||
@@ -427,7 +452,7 @@ void MQTT_connect() {
|
||||
void sendMqttData(String data)
|
||||
{
|
||||
// Make sure we have configured a publish topic
|
||||
if (config.mqttPublishTopic == 0 || strlen(config.mqttPublishTopic) == 0)
|
||||
if (config.getMqttPublishTopic().isEmpty())
|
||||
return;
|
||||
|
||||
// Build a json with the message in a "data" attribute
|
||||
@@ -438,13 +463,16 @@ void sendMqttData(String data)
|
||||
#if defined(ESP8266)
|
||||
json["vcc"] = ((double) ESP.getVcc()) / 1000;
|
||||
#endif
|
||||
float rssi = WiFi.RSSI();
|
||||
rssi = isnan(rssi) ? -100.0 : rssi;
|
||||
json["rssi"] = rssi;
|
||||
|
||||
// Stringify the json
|
||||
String msg;
|
||||
serializeJson(json, msg);
|
||||
|
||||
// Send the json over MQTT
|
||||
mqtt.publish(config.mqttPublishTopic, msg.c_str());
|
||||
mqtt.publish(config.getMqttPublishTopic(), msg.c_str());
|
||||
|
||||
if (debugger) debugger->print("sendMqttData: ");
|
||||
if (debugger) debugger->println(data);
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
#include "version.h"
|
||||
|
||||
#include "root/index_html.h"
|
||||
#include "root/configuration_html.h"
|
||||
#include "root/configmeter_html.h"
|
||||
#include "root/configwifi_html.h"
|
||||
#include "root/configmqtt_html.h"
|
||||
#include "root/configweb_html.h"
|
||||
#include "root/boot_css.h"
|
||||
#include "root/gaugemeter_js.h"
|
||||
|
||||
@@ -14,13 +17,16 @@ ESP8266WebServer server(80);
|
||||
WebServer server(80);
|
||||
#endif
|
||||
|
||||
void AmsWebServer::setup(configuration* config, Stream* debugger, MQTTClient* mqtt) {
|
||||
void AmsWebServer::setup(AmsConfiguration* config, Stream* debugger, MQTTClient* mqtt) {
|
||||
this->config = config;
|
||||
this->debugger = debugger;
|
||||
this->mqtt = mqtt;
|
||||
|
||||
server.on("/", std::bind(&AmsWebServer::indexHtml, this));
|
||||
server.on("/configuration", std::bind(&AmsWebServer::configurationHtml, 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));
|
||||
@@ -28,14 +34,6 @@ void AmsWebServer::setup(configuration* config, Stream* debugger, MQTTClient* mq
|
||||
server.on("/save", std::bind(&AmsWebServer::handleSave, this));
|
||||
|
||||
server.begin(); // Web server start
|
||||
|
||||
print("Web server is ready for config at http://");
|
||||
if(WiFi.getMode() == WIFI_AP) {
|
||||
print(WiFi.softAPIP());
|
||||
} else {
|
||||
print(WiFi.localIP());
|
||||
}
|
||||
println("/");
|
||||
}
|
||||
|
||||
void AmsWebServer::loop() {
|
||||
@@ -60,12 +58,12 @@ void AmsWebServer::setJson(StaticJsonDocument<1024> json) {
|
||||
}
|
||||
}
|
||||
|
||||
if(maxPwr == 0 && config->hasConfig() && config->fuseSize > 0 && config->distSys > 0) {
|
||||
int volt = config->distSys == 2 ? 400 : 230;
|
||||
if(maxPwr == 0 && config->hasConfig() && config->getMainFuse() > 0 && config->getDistributionSystem() > 0) {
|
||||
int volt = config->getDistributionSystem() == 2 ? 400 : 230;
|
||||
if(u2 > 0) {
|
||||
maxPwr = config->fuseSize * sqrt(3) * volt;
|
||||
maxPwr = config->getMainFuse() * sqrt(3) * volt;
|
||||
} else {
|
||||
maxPwr = config->fuseSize * 230;
|
||||
maxPwr = config->getMainFuse() * 230;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,10 +98,10 @@ void AmsWebServer::setJson(StaticJsonDocument<1024> json) {
|
||||
}
|
||||
|
||||
bool AmsWebServer::checkSecurity(byte level) {
|
||||
bool access = WiFi.getMode() == WIFI_AP || !config->hasConfig() || config->authSecurity < level;
|
||||
if(!access && config->authSecurity >= level && server.hasHeader("Authorization")) {
|
||||
bool access = WiFi.getMode() == WIFI_AP || !config->hasConfig() || config->getAuthSecurity() < level;
|
||||
if(!access && config->getAuthSecurity() >= level && server.hasHeader("Authorization")) {
|
||||
println(" forcing web security");
|
||||
String expectedAuth = String(config->authUser) + ":" + String(config->authPass);
|
||||
String expectedAuth = String(config->getAuthUser()) + ":" + String(config->getAuthPassword());
|
||||
|
||||
String providedPwd = server.header("Authorization");
|
||||
providedPwd.replace("Basic ", "");
|
||||
@@ -173,46 +171,99 @@ void AmsWebServer::indexHtml() {
|
||||
server.send(200, "text/html", html);
|
||||
}
|
||||
|
||||
void AmsWebServer::configurationHtml() {
|
||||
println("Serving /configuration.html over http...");
|
||||
void AmsWebServer::configMeterHtml() {
|
||||
println("Serving /config/meter.html over http...");
|
||||
|
||||
if(!checkSecurity(1))
|
||||
return;
|
||||
|
||||
String html = String((const __FlashStringHelper*) CONFIGURATION_HTML);
|
||||
String html = String((const __FlashStringHelper*) CONFIGMETER_HTML);
|
||||
html.replace("${version}", VERSION);
|
||||
|
||||
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
server.sendHeader("Pragma", "no-cache");
|
||||
server.sendHeader("Expires", "-1");
|
||||
|
||||
html.replace("${config.ssid}", config->ssid);
|
||||
html.replace("${config.ssidPassword}", config->ssidPassword);
|
||||
html.replace("${config.meterType}", String(config->fuseSize));
|
||||
html.replace("${config.meterType}", String(config->getMainFuse()));
|
||||
for(int i = 0; i<4; i++) {
|
||||
html.replace("${config.meterType" + String(i) + "}", config->meterType == i ? "selected" : "");
|
||||
html.replace("${config.meterType" + String(i) + "}", config->getMeterType() == 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));
|
||||
html.replace("${config.distributionSystem}", String(config->getDistributionSystem()));
|
||||
for(int i = 0; i<3; i++) {
|
||||
html.replace("${config.authSecurity" + String(i) + "}", config->authSecurity == i ? "selected" : "");
|
||||
html.replace("${config.distributionSystem" + String(i) + "}", config->getDistributionSystem() == i ? "selected" : "");
|
||||
}
|
||||
html.replace("${config.authPass}", config->authPass);
|
||||
html.replace("${config.fuseSize}", String(config->fuseSize));
|
||||
html.replace("${config.mainFuse}", String(config->getMainFuse()));
|
||||
for(int i = 0; i<64; i++) {
|
||||
html.replace("${config.fuseSize" + String(i) + "}", config->fuseSize == i ? "selected" : "");
|
||||
html.replace("${config.mainFuse" + String(i) + "}", config->getMainFuse() == i ? "selected" : "");
|
||||
}
|
||||
html.replace("${config.productionCapacity}", String(config->getProductionCapacity()));
|
||||
server.send(200, "text/html", html);
|
||||
}
|
||||
|
||||
void AmsWebServer::configWifiHtml() {
|
||||
println("Serving /config/wifi.html over http...");
|
||||
|
||||
if(!checkSecurity(1))
|
||||
return;
|
||||
|
||||
String html = String((const __FlashStringHelper*) CONFIGWIFI_HTML);
|
||||
html.replace("${version}", VERSION);
|
||||
|
||||
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
server.sendHeader("Pragma", "no-cache");
|
||||
|
||||
html.replace("${config.wifiSsid}", config->getWifiSsid());
|
||||
html.replace("${config.wifiPassword}", config->getWifiPassword());
|
||||
html.replace("${config.wifiIpType1}", config->getWifiIp().isEmpty() ? "" : "selected");
|
||||
html.replace("${config.wifiIp}", config->getWifiIp());
|
||||
html.replace("${config.wifiGw}", config->getWifiGw());
|
||||
html.replace("${config.wifiSubnet}", config->getWifiSubnet());
|
||||
|
||||
server.send(200, "text/html", html);
|
||||
}
|
||||
|
||||
void AmsWebServer::configMqttHtml() {
|
||||
println("Serving /config/mqtt.html over http...");
|
||||
|
||||
if(!checkSecurity(1))
|
||||
return;
|
||||
|
||||
String html = String((const __FlashStringHelper*) CONFIGMQTT_HTML);
|
||||
html.replace("${version}", VERSION);
|
||||
|
||||
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
server.sendHeader("Pragma", "no-cache");
|
||||
|
||||
html.replace("${config.mqtt}", config->getMqttHost() == 0 ? "" : "checked");
|
||||
html.replace("${config.mqttHost}", config->getMqttHost());
|
||||
html.replace("${config.mqttPort}", String(config->getMqttPort()));
|
||||
html.replace("${config.mqttClientId}", config->getMqttClientId());
|
||||
html.replace("${config.mqttPublishTopic}", config->getMqttPublishTopic());
|
||||
html.replace("${config.mqttSubscribeTopic}", config->getMqttSubscribeTopic());
|
||||
html.replace("${config.mqttUser}", config->getMqttUser());
|
||||
html.replace("${config.mqttPassword}", config->getMqttPassword());
|
||||
|
||||
server.send(200, "text/html", html);
|
||||
}
|
||||
|
||||
void AmsWebServer::configWebHtml() {
|
||||
println("Serving /config/web.html over http...");
|
||||
|
||||
if(!checkSecurity(1))
|
||||
return;
|
||||
|
||||
String html = String((const __FlashStringHelper*) CONFIGWEB_HTML);
|
||||
html.replace("${version}", VERSION);
|
||||
|
||||
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
server.sendHeader("Pragma", "no-cache");
|
||||
|
||||
html.replace("${config.authSecurity}", String(config->getAuthSecurity()));
|
||||
for(int i = 0; i<3; i++) {
|
||||
html.replace("${config.distSys" + String(i) + "}", config->distSys == i ? "selected" : "");
|
||||
html.replace("${config.authSecurity" + String(i) + "}", config->getAuthSecurity() == i ? "selected" : "");
|
||||
}
|
||||
html.replace("${config.authUser}", config->getAuthUser());
|
||||
html.replace("${config.authPassword}", config->getAuthPassword());
|
||||
|
||||
server.send(200, "text/html", html);
|
||||
}
|
||||
|
||||
@@ -268,7 +319,7 @@ void AmsWebServer::dataJson() {
|
||||
unsigned long now = millis();
|
||||
json["id"] = WiFi.macAddress();
|
||||
json["maxPower"] = maxPwr;
|
||||
json["meterType"] = config->meterType;
|
||||
json["meterType"] = config->getMeterType();
|
||||
json["currentMillis"] = now;
|
||||
|
||||
double vcc = 0;
|
||||
@@ -300,7 +351,7 @@ void AmsWebServer::dataJson() {
|
||||
|
||||
unsigned long lastHan = json.isNull() ? 0 : json["up"].as<unsigned long>();
|
||||
String hanStatus;
|
||||
if(config->meterType == 0) {
|
||||
if(config->getMeterType() == 0) {
|
||||
hanStatus = "secondary";
|
||||
} else if(now - lastHan < 15000) {
|
||||
hanStatus = "success";
|
||||
@@ -312,7 +363,7 @@ void AmsWebServer::dataJson() {
|
||||
json["status"]["han"] = hanStatus;
|
||||
|
||||
String wifiStatus;
|
||||
if(!config->ssid) {
|
||||
if(config->getWifiSsid().isEmpty()) {
|
||||
wifiStatus = "secondary";
|
||||
} else if(rssi > -75) {
|
||||
wifiStatus = "success";
|
||||
@@ -324,7 +375,7 @@ void AmsWebServer::dataJson() {
|
||||
json["status"]["wifi"] = wifiStatus;
|
||||
|
||||
String mqttStatus;
|
||||
if(!config->mqttHost) {
|
||||
if(config->getMqttHost().isEmpty()) {
|
||||
mqttStatus = "secondary";
|
||||
} else if(mqtt->connected()) {
|
||||
mqttStatus = "success";
|
||||
@@ -349,84 +400,72 @@ void AmsWebServer::dataJson() {
|
||||
void AmsWebServer::handleSave() {
|
||||
String temp;
|
||||
|
||||
temp = server.arg("ssid");
|
||||
config->ssid = new char[temp.length() + 1];
|
||||
temp.toCharArray(config->ssid, temp.length() + 1, 0);
|
||||
|
||||
temp = server.arg("ssidPassword");
|
||||
config->ssidPassword = new char[temp.length() + 1];
|
||||
temp.toCharArray(config->ssidPassword, temp.length() + 1, 0);
|
||||
|
||||
config->meterType = (byte)server.arg("meterType").toInt();
|
||||
|
||||
if(server.hasArg("mqtt") && server.arg("mqtt") == "true") {
|
||||
println("MQTT enabled");
|
||||
temp = server.arg("mqttHost");
|
||||
config->mqttHost = new char[temp.length() + 1];
|
||||
temp.toCharArray(config->mqttHost, temp.length() + 1, 0);
|
||||
|
||||
config->mqttPort = (int)server.arg("mqttPort").toInt();
|
||||
|
||||
temp = server.arg("mqttClientID");
|
||||
config->mqttClientID = new char[temp.length() + 1];
|
||||
temp.toCharArray(config->mqttClientID, temp.length() + 1, 0);
|
||||
|
||||
temp = server.arg("mqttPublishTopic");
|
||||
config->mqttPublishTopic = new char[temp.length() + 1];
|
||||
temp.toCharArray(config->mqttPublishTopic, temp.length() + 1, 0);
|
||||
|
||||
temp = server.arg("mqttSubscribeTopic");
|
||||
config->mqttSubscribeTopic = new char[temp.length() + 1];
|
||||
temp.toCharArray(config->mqttSubscribeTopic, temp.length() + 1, 0);
|
||||
|
||||
temp = server.arg("mqttUser");
|
||||
config->mqttUser = new char[temp.length() + 1];
|
||||
temp.toCharArray(config->mqttUser, temp.length() + 1, 0);
|
||||
|
||||
temp = server.arg("mqttPass");
|
||||
config->mqttPass = new char[temp.length() + 1];
|
||||
temp.toCharArray(config->mqttPass, temp.length() + 1, 0);
|
||||
} else {
|
||||
println("MQTT disabled");
|
||||
config->mqttHost = NULL;
|
||||
config->mqttUser = NULL;
|
||||
config->mqttPass = NULL;
|
||||
if(server.hasArg("meterConfig") && server.arg("meterConfig") == "true") {
|
||||
config->setMeterType(server.arg("meterType").toInt());
|
||||
config->setDistributionSystem(server.arg("distributionSystem").toInt());
|
||||
config->setMainFuse(server.arg("mainFuse").toInt());
|
||||
config->setProductionCapacity(server.arg("productionCapacity").toInt());
|
||||
}
|
||||
|
||||
config->authSecurity = (byte)server.arg("authSecurity").toInt();
|
||||
|
||||
if(config->authSecurity > 0) {
|
||||
temp = server.arg("authUser");
|
||||
config->authUser = new char[temp.length() + 1];
|
||||
temp.toCharArray(config->authUser, temp.length() + 1, 0);
|
||||
|
||||
temp = server.arg("authPass");
|
||||
config->authPass = new char[temp.length() + 1];
|
||||
temp.toCharArray(config->authPass, temp.length() + 1, 0);
|
||||
if(server.hasArg("wifiConfig") && server.arg("wifiConfig") == "true") {
|
||||
config->setWifiSsid(server.arg("wifiSsid"));
|
||||
config->setWifiPassword(server.arg("wifiPassword"));
|
||||
if(server.hasArg("wifiIpType") && server.arg("wifiIpType").toInt() == 1) {
|
||||
config->setWifiIp(server.arg("wifiIp"));
|
||||
config->setWifiGw(server.arg("wifiGw"));
|
||||
config->setWifiSubnet(server.arg("wifiSubnet"));
|
||||
} else {
|
||||
config->clearWifiIp();
|
||||
}
|
||||
}
|
||||
|
||||
config->fuseSize = (int)server.arg("fuseSize").toInt();
|
||||
if(server.hasArg("mqttConfig") && server.arg("mqttConfig") == "true") {
|
||||
if(server.hasArg("mqtt") && server.arg("mqtt") == "true") {
|
||||
config->setMqttHost(server.arg("mqttHost"));
|
||||
config->setMqttPort(server.arg("mqttPort").toInt());
|
||||
config->setMqttClientId(server.arg("mqttClientId"));
|
||||
config->setMqttPublishTopic(server.arg("mqttPublishTopic"));
|
||||
config->setMqttSubscribeTopic(server.arg("mqttSubscribeTopic"));
|
||||
config->setMqttUser(server.arg("mqttUser"));
|
||||
config->setMqttPassword(server.arg("mqttPassword"));
|
||||
config->setAuthUser(server.arg("authUser"));
|
||||
config->setAuthPassword(server.arg("authPassword"));
|
||||
} else {
|
||||
config->clearMqtt();
|
||||
}
|
||||
}
|
||||
|
||||
config->distSys = (byte)server.arg("distSys").toInt();
|
||||
if(server.hasArg("authConfig") && server.arg("authConfig") == "true") {
|
||||
config->setAuthSecurity((byte)server.arg("authSecurity").toInt());
|
||||
if(config->getAuthSecurity() > 0) {
|
||||
config->setAuthUser(server.arg("authUser"));
|
||||
config->setAuthPassword(server.arg("authPassword"));
|
||||
} else {
|
||||
config->clearAuth();
|
||||
}
|
||||
}
|
||||
|
||||
println("Saving configuration now...");
|
||||
|
||||
if (debugger) config->print(debugger);
|
||||
if (config->save())
|
||||
{
|
||||
println("Successfully saved. Will reboot now.");
|
||||
String html = "<html><body><h1>Successfully Saved!</h1><h3>Device is restarting now...</h3><a href=\"/\">Go to index</a></form>";
|
||||
server.send(200, "text/html", html);
|
||||
yield();
|
||||
delay(1000);
|
||||
if (config->save()) {
|
||||
println("Successfully saved.");
|
||||
if(config->isWifiChanged()) {
|
||||
String html = "<html><body><h1>Successfully Saved!</h1><a href=\"/\">Go to index</a></form>";
|
||||
server.send(200, "text/html", html);
|
||||
yield();
|
||||
println("Wifi config changed, rebooting");
|
||||
delay(1000);
|
||||
#if defined(ESP8266)
|
||||
ESP.reset();
|
||||
ESP.reset();
|
||||
#elif defined(ESP32)
|
||||
ESP.restart();
|
||||
ESP.restart();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
server.sendHeader("Location", String("/"), true);
|
||||
server.send ( 302, "text/plain", "");
|
||||
}
|
||||
} else {
|
||||
println("Error saving configuration");
|
||||
String html = "<html><body><h1>Error saving configuration!</h1></form>";
|
||||
server.send(500, "text/html", html);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <MQTT.h>
|
||||
#include "configuration.h"
|
||||
#include "AmsConfiguration.h"
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
@@ -23,12 +23,12 @@
|
||||
|
||||
class AmsWebServer {
|
||||
public:
|
||||
void setup(configuration* config, Stream* debugger, MQTTClient* mqtt);
|
||||
void setup(AmsConfiguration* config, Stream* debugger, MQTTClient* mqtt);
|
||||
void loop();
|
||||
void setJson(StaticJsonDocument<1024> json);
|
||||
|
||||
private:
|
||||
configuration* config;
|
||||
AmsConfiguration* config;
|
||||
Stream* debugger;
|
||||
MQTTClient* mqtt;
|
||||
StaticJsonDocument<1024> json;
|
||||
@@ -45,7 +45,10 @@ private:
|
||||
bool checkSecurity(byte level);
|
||||
|
||||
void indexHtml();
|
||||
void configurationHtml();
|
||||
void configMeterHtml();
|
||||
void configWifiHtml();
|
||||
void configMqttHtml();
|
||||
void configWebHtml();
|
||||
void bootCss();
|
||||
void gaugemeterJs();
|
||||
void dataJson();
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
</ul>
|
||||
</header>
|
||||
<form method="post" action="/save">
|
||||
<input type="hidden" name="meterConfig" value="true"/>
|
||||
<div class="my-3 p-3 bg-white rounded shadow">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
@@ -63,10 +64,10 @@
|
||||
<div class="row form-group">
|
||||
<label class="col-6">Distribution system</label>
|
||||
<div class="col-6">
|
||||
<select class="form-control" name="distSys">
|
||||
<option value="0" ${config.distSys0}></option>
|
||||
<option value="1" ${config.distSys1}>IT (230V)</option>
|
||||
<option value="2" ${config.distSys2}>TN (400V)</option>
|
||||
<select class="form-control" name="distributionSystem">
|
||||
<option value="0" ${config.distributionSystem0}></option>
|
||||
<option value="1" ${config.distributionSystem1}>IT (230V)</option>
|
||||
<option value="2" ${config.distributionSystem2}>TN (400V)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -75,23 +76,23 @@
|
||||
<div class="row form-group">
|
||||
<label class="col-6">Main fuse</label>
|
||||
<div class="col-6">
|
||||
<select class="form-control" name="fuseSize">
|
||||
<option value="0" ${config.fuseSize0}></option>
|
||||
<option value="25" ${config.fuseSize25}>25A</option>
|
||||
<option value="32" ${config.fuseSize32}>32A</option>
|
||||
<option value="35" ${config.fuseSize32}>35A</option>
|
||||
<option value="40" ${config.fuseSize40}>40A</option>
|
||||
<option value="50" ${config.fuseSize50}>50A</option>
|
||||
<option value="63" ${config.fuseSize63}>63A</option>
|
||||
<select class="form-control" name="mainFuse">
|
||||
<option value="0" ${config.mainFuse0}></option>
|
||||
<option value="25" ${config.mainFuse25}>25A</option>
|
||||
<option value="32" ${config.mainFuse32}>32A</option>
|
||||
<option value="35" ${config.mainFuse32}>35A</option>
|
||||
<option value="40" ${config.mainFuse40}>40A</option>
|
||||
<option value="50" ${config.mainFuse50}>50A</option>
|
||||
<option value="63" ${config.mainFuse63}>63A</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-6">Export capacity</label>
|
||||
<label class="col-6">Production capacity</label>
|
||||
<div class="col-6">
|
||||
<div class="input-group">
|
||||
<input class="form-control" name="exportCapacity" type="number" min="0" max="50" value="${config.exportCapacity}"/>
|
||||
<div class="input-group-append"><span class="input-group-text">kW</span></div>
|
||||
<input class="form-control" name="productionCapacity" type="number" min="0" max="50" value="${config.productionCapacity}"/>
|
||||
<div class="input-group-append"><span class="input-group-text">kWp</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
129
web/configmqtt.html
Normal file
129
web/configmqtt.html
Normal file
@@ -0,0 +1,129 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>AMS reader - WiFi configuration</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<link rel="stylesheet" type="text/css" href="boot.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css"/>
|
||||
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
|
||||
<style>
|
||||
.bg-purple {
|
||||
background-color: var(--purple);
|
||||
}
|
||||
|
||||
.navbar .navbar-nav-svg {
|
||||
display: inline-block;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
vertical-align: text-top;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-light">
|
||||
<main role="main" class="container">
|
||||
<header class="navbar navbar-expand navbar-dark flex-column flex-md-row bg-purple rounded mt-2 mb-4">
|
||||
<a href="/" class=""><h6 class="navbar-brand">AMS reader <small>${version}</small></h6></a>
|
||||
<div class="navbar-nav-scroll">
|
||||
<ul class="navbar-nav bd-navbar-nav flex-row">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link " href="/config/meter">Meter</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link " href="/config/wifi">WiFi</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="/config/mqtt">MQTT</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link " href="/config/web">Web</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link p-2" href="https://github.com/gskjold/AmsToMqttBridge" target="_blank" rel="noopener" aria-label="GitHub"><svg class="navbar-nav-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 499.36" focusable="false"><title>GitHub</title><path d="M256 0C114.64 0 0 114.61 0 256c0 113.09 73.34 209 175.08 242.9 12.8 2.35 17.47-5.56 17.47-12.34 0-6.08-.22-22.18-.35-43.54-71.2 15.49-86.2-34.34-86.2-34.34-11.64-29.57-28.42-37.45-28.42-37.45-23.27-15.84 1.73-15.55 1.73-15.55 25.69 1.81 39.21 26.38 39.21 26.38 22.84 39.12 59.92 27.82 74.5 21.27 2.33-16.54 8.94-27.82 16.25-34.22-56.84-6.43-116.6-28.43-116.6-126.49 0-27.95 10-50.8 26.35-68.69-2.63-6.48-11.42-32.5 2.51-67.75 0 0 21.49-6.88 70.4 26.24a242.65 242.65 0 0 1 128.18 0c48.87-33.13 70.33-26.24 70.33-26.24 14 35.25 5.18 61.27 2.55 67.75 16.41 17.9 26.31 40.75 26.31 68.69 0 98.35-59.85 120-116.88 126.32 9.19 7.9 17.38 23.53 17.38 47.41 0 34.22-.31 61.83-.31 70.23 0 6.85 4.61 14.81 17.6 12.31C438.72 464.97 512 369.08 512 256.02 512 114.62 397.37 0 256 0z" fill="currentColor" fill-rule="evenodd"></path></svg></a>
|
||||
</li>
|
||||
</ul>
|
||||
</header>
|
||||
<form method="post" action="/save">
|
||||
<input type="hidden" name="mqttConfig" value="true"/>
|
||||
<div class="my-3 p-3 bg-white rounded shadow">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Enable</label>
|
||||
<div class="col-8">
|
||||
<input id="mqttEnable" type="checkbox" name="mqtt" value="true" ${config.mqtt}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Hostname</label>
|
||||
<div class="col-8">
|
||||
<input type="text" class="form-control mqtt-config" name="mqttHost" value="${config.mqttHost}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Port</label>
|
||||
<div class="col-8">
|
||||
<input type="text" class="form-control mqtt-config" name="mqttPort" value="${config.mqttPort}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Client ID</label>
|
||||
<div class="col-8">
|
||||
<input type="text" class="form-control mqtt-config" name="mqttClientId" value="${config.mqttClientId}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Topic</label>
|
||||
<div class="col-8">
|
||||
<input type="text" class="form-control mqtt-config" name="mqttPublishTopic" value="${config.mqttPublishTopic}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Username</label>
|
||||
<div class="col-8">
|
||||
<input type="text" class="form-control mqtt-config" name="mqttUser" value="${config.mqttUser}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Password</label>
|
||||
<div class="col-8">
|
||||
<input type="password" class="form-control mqtt-config" name="mqttPassword" value="${config.mqttPassword}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row form-group">
|
||||
<div class="col-6">
|
||||
<a href="/" class="btn btn-outline-secondary">Back</a>
|
||||
</div>
|
||||
<div class="col-6 text-right">
|
||||
<button class="btn btn-primary">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
<script>
|
||||
$('#mqttEnable').on('change', function() {
|
||||
var inputs = $('.mqtt-config');
|
||||
inputs.prop('disabled', !$(this).is(':checked'));
|
||||
});
|
||||
|
||||
$(function() {
|
||||
$('#mqttEnable').trigger('change');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,184 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>AMS reader - configuration</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<link rel="stylesheet" type="text/css" href="boot.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css"/>
|
||||
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
|
||||
<style>
|
||||
.bg-purple {
|
||||
background-color: var(--purple);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-light">
|
||||
<main role="main" class="container">
|
||||
<div class="d-flex align-items-center p-3 my-2 text-white-50 bg-purple rounded shadow">
|
||||
<div class="lh-100">
|
||||
<h6 class="mb-0 text-white lh-100">AMS reader - configuration</h6>
|
||||
<small>${version}</small>
|
||||
</div>
|
||||
</div>
|
||||
<form method="post" action="/save">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<div class="my-2 p-3 bg-white rounded shadow">
|
||||
<h6 class="border-bottom border-gray pb-2 mb-4">WiFi</h6>
|
||||
<div class="row form-group">
|
||||
<label class="col-3">SSID</label>
|
||||
<div class="col-9">
|
||||
<input type="text" class="form-control" name="ssid" value="${config.ssid}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-3">Password</label>
|
||||
<div class="col-9">
|
||||
<input type="password" class="form-control" name="ssidPassword" value="${config.ssidPassword}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-3 p-3 bg-white rounded shadow">
|
||||
<h6 class="border-bottom border-gray pb-2 mb-4">AMS meter</h6>
|
||||
<div class="row form-group">
|
||||
<label class="col-6">Distribution system</label>
|
||||
<div class="col-6">
|
||||
<select class="form-control" name="distSys">
|
||||
<option value="" ${config.distSys0}></option>
|
||||
<option value="1" ${config.distSys1}>IT (230V)</option>
|
||||
<option value="2" ${config.distSys2}>TN (400V)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-6">Meter type</label>
|
||||
<div class="col-6">
|
||||
<select class="form-control" name="meterType">
|
||||
<option value="0" ${config.meterType0} disabled></option>
|
||||
<option value="1" ${config.meterType1}>Kaifa</option>
|
||||
<option value="2" ${config.meterType2}>Aidon</option>
|
||||
<option value="3" ${config.meterType3}>Kamstrup</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-6">Main fuse</label>
|
||||
<div class="col-6">
|
||||
<select class="form-control" name="fuseSize">
|
||||
<option value="" ${config.fuseSize0}></option>
|
||||
<option value="25" ${config.fuseSize25}>25A</option>
|
||||
<option value="32" ${config.fuseSize32}>32A</option>
|
||||
<option value="35" ${config.fuseSize32}>35A</option>
|
||||
<option value="40" ${config.fuseSize40}>40A</option>
|
||||
<option value="50" ${config.fuseSize50}>50A</option>
|
||||
<option value="63" ${config.fuseSize63}>63A</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<div class="my-2 p-3 bg-white rounded shadow">
|
||||
<h6 class="border-bottom border-gray pb-2 mb-4">MQTT</h6>
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Enable</label>
|
||||
<div class="col-8">
|
||||
<input id="mqttEnable" type="checkbox" name="mqtt" value="true" ${config.mqtt}/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Hostname</label>
|
||||
<div class="col-8">
|
||||
<input type="text" class="form-control mqtt-config" name="mqttHost" value="${config.mqttHost}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Port</label>
|
||||
<div class="col-8">
|
||||
<input type="text" class="form-control mqtt-config" name="mqttPort" value="${config.mqttPort}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Client ID</label>
|
||||
<div class="col-8">
|
||||
<input type="text" class="form-control mqtt-config" name="mqttClientID" value="${config.mqttClientID}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Topic</label>
|
||||
<div class="col-8">
|
||||
<input type="text" class="form-control mqtt-config" name="mqttPublishTopic" value="${config.mqttPublishTopic}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Username</label>
|
||||
<div class="col-8">
|
||||
<input type="text" class="form-control mqtt-config" name="mqttUser" value="${config.mqttUser}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Password</label>
|
||||
<div class="col-8">
|
||||
<input type="password" class="form-control mqtt-config" name="mqttPass" value="${config.mqttPass}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<div class="my-2 p-3 bg-white rounded shadow">
|
||||
<h6 class="border-bottom border-gray pb-2 mb-4">Web server</h6>
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Security</label>
|
||||
<div class="col-8">
|
||||
<select id="authSecurity" class="form-control" name="authSecurity">
|
||||
<option value="0" ${config.authSecurity0}>None</option>
|
||||
<option value="1" ${config.authSecurity1}>Only configuration</option>
|
||||
<option value="2" ${config.authSecurity2}>Everything</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Username</label>
|
||||
<div class="col-8">
|
||||
<input type="text" class="form-control auth-config" name="authUser" value="${config.authUser}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Password</label>
|
||||
<div class="col-8">
|
||||
<input type="password" class="form-control auth-config" name="authPass" value="${config.authPass}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row form-group">
|
||||
<div class="col-6">
|
||||
<a href="/" class="btn btn-outline-secondary">Back</a>
|
||||
</div>
|
||||
<div class="col-6 text-right">
|
||||
<button class="btn btn-primary">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
<script>
|
||||
$('#mqttEnable').on('change', function() {
|
||||
var inputs = $('.mqtt-config');
|
||||
inputs.prop('disabled', !$(this).is(':checked'));
|
||||
});
|
||||
|
||||
$('#authSecurity').on('change', function() {
|
||||
var inputs = $('.auth-config');
|
||||
inputs.prop('disabled', $(this).val() == 0);
|
||||
});
|
||||
|
||||
$(function() {
|
||||
$('#mqttEnable').trigger('change');
|
||||
$('#authSecurity').trigger('change');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
105
web/configweb.html
Normal file
105
web/configweb.html
Normal file
@@ -0,0 +1,105 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>AMS reader - Meter configuration</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<link rel="stylesheet" type="text/css" href="boot.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css"/>
|
||||
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
|
||||
<style>
|
||||
.bg-purple {
|
||||
background-color: var(--purple);
|
||||
}
|
||||
|
||||
.navbar .navbar-nav-svg {
|
||||
display: inline-block;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
vertical-align: text-top;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-light">
|
||||
<main role="main" class="container">
|
||||
<header class="navbar navbar-expand navbar-dark flex-column flex-md-row bg-purple rounded mt-2 mb-4">
|
||||
<a href="/" class=""><h6 class="navbar-brand">AMS reader <small>${version}</small></h6></a>
|
||||
<div class="navbar-nav-scroll">
|
||||
<ul class="navbar-nav bd-navbar-nav flex-row">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/config/meter">Meter</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link " href="/config/wifi">WiFi</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link " href="/config/mqtt">MQTT</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="/config/web">Web</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link p-2" href="https://github.com/gskjold/AmsToMqttBridge" target="_blank" rel="noopener" aria-label="GitHub"><svg class="navbar-nav-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 499.36" focusable="false"><title>GitHub</title><path d="M256 0C114.64 0 0 114.61 0 256c0 113.09 73.34 209 175.08 242.9 12.8 2.35 17.47-5.56 17.47-12.34 0-6.08-.22-22.18-.35-43.54-71.2 15.49-86.2-34.34-86.2-34.34-11.64-29.57-28.42-37.45-28.42-37.45-23.27-15.84 1.73-15.55 1.73-15.55 25.69 1.81 39.21 26.38 39.21 26.38 22.84 39.12 59.92 27.82 74.5 21.27 2.33-16.54 8.94-27.82 16.25-34.22-56.84-6.43-116.6-28.43-116.6-126.49 0-27.95 10-50.8 26.35-68.69-2.63-6.48-11.42-32.5 2.51-67.75 0 0 21.49-6.88 70.4 26.24a242.65 242.65 0 0 1 128.18 0c48.87-33.13 70.33-26.24 70.33-26.24 14 35.25 5.18 61.27 2.55 67.75 16.41 17.9 26.31 40.75 26.31 68.69 0 98.35-59.85 120-116.88 126.32 9.19 7.9 17.38 23.53 17.38 47.41 0 34.22-.31 61.83-.31 70.23 0 6.85 4.61 14.81 17.6 12.31C438.72 464.97 512 369.08 512 256.02 512 114.62 397.37 0 256 0z" fill="currentColor" fill-rule="evenodd"></path></svg></a>
|
||||
</li>
|
||||
</ul>
|
||||
</header>
|
||||
<form method="post" action="/save">
|
||||
<input type="hidden" name="authConfig" value="true"/>
|
||||
<div class="my-3 p-3 bg-white rounded shadow">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Security</label>
|
||||
<div class="col-8">
|
||||
<select id="authSecurity" class="form-control" name="authSecurity">
|
||||
<option value="0" ${config.authSecurity0}>None</option>
|
||||
<option value="1" ${config.authSecurity1}>Only configuration</option>
|
||||
<option value="2" ${config.authSecurity2}>Everything</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Username</label>
|
||||
<div class="col-8">
|
||||
<input type="text" class="form-control auth-config" name="authUser" value="${config.authUser}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Password</label>
|
||||
<div class="col-8">
|
||||
<input type="password" class="form-control auth-config" name="authPassword" value="${config.authPassword}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row form-group">
|
||||
<div class="col-6">
|
||||
<a href="/" class="btn btn-outline-secondary">Back</a>
|
||||
</div>
|
||||
<div class="col-6 text-right">
|
||||
<button class="btn btn-primary">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
<script>
|
||||
$('#authSecurity').on('change', function() {
|
||||
var inputs = $('.auth-config');
|
||||
inputs.prop('disabled', $(this).val() == 0);
|
||||
});
|
||||
|
||||
$(function() {
|
||||
$('#authSecurity').trigger('change');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -6,6 +6,7 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<link rel="stylesheet" type="text/css" href="boot.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css"/>
|
||||
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
|
||||
<style>
|
||||
.bg-purple {
|
||||
background-color: var(--purple);
|
||||
@@ -46,6 +47,7 @@
|
||||
</ul>
|
||||
</header>
|
||||
<form method="post" action="/save">
|
||||
<input type="hidden" name="wifiConfig" value="true"/>
|
||||
<div class="my-3 p-3 bg-white rounded shadow">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
@@ -66,7 +68,7 @@
|
||||
<div class="row form-group">
|
||||
<label class="col-6">IP configuration</label>
|
||||
<div class="col-6">
|
||||
<select class="form-control" name="wifiIpType">
|
||||
<select id="wifiIpType" class="form-control" name="wifiIpType">
|
||||
<option value="0" ${config.wifiIpType0}>DHCP</option>
|
||||
<option value="1" ${config.wifiIpType1}>Static</option>
|
||||
</select>
|
||||
@@ -75,7 +77,7 @@
|
||||
<div class="row form-group">
|
||||
<label class="col-3">IP</label>
|
||||
<div class="col-9">
|
||||
<input type="text" class="form-control" name="wifiIp" value="${config.wifiIp}"/>
|
||||
<input type="text" class="form-control wifiip-config" name="wifiIp" value="${config.wifiIp}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -83,13 +85,13 @@
|
||||
<div class="row form-group">
|
||||
<label class="col-3">Subnet</label>
|
||||
<div class="col-9">
|
||||
<input type="text" class="form-control" name="wifiSubnet" value="${config.wifiSubnet}"/>
|
||||
<input type="text" class="form-control wifiip-config" name="wifiSubnet" value="${config.wifiSubnet}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-3">Gateway</label>
|
||||
<div class="col-9">
|
||||
<input type="text" class="form-control" name="wifiGw" value="${config.wifiGw}"/>
|
||||
<input type="text" class="form-control wifiip-config" name="wifiGw" value="${config.wifiGw}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -106,5 +108,15 @@
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
<script>
|
||||
$('#wifiIpType').on('change', function() {
|
||||
var inputs = $('.wifiip-config');
|
||||
inputs.prop('disabled', $(this).val() != 1);
|
||||
});
|
||||
|
||||
$(function() {
|
||||
$('#wifiIpType').trigger('change');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user