mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-01-14 07:49:01 +00:00
HAN serial autodetect
This commit is contained in:
parent
c4eaf8184b
commit
7ea4fe881c
@ -218,8 +218,8 @@ bool AmsConfiguration::setMeterConfig(MeterConfig& config) {
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearMeter(MeterConfig& config) {
|
||||
config.baud = 2400;
|
||||
config.parity = 11; // 8E1
|
||||
config.baud = 0;
|
||||
config.parity = 0;
|
||||
config.invert = false;
|
||||
config.distributionSystem = 0;
|
||||
config.mainFuse = 0;
|
||||
|
||||
@ -225,6 +225,7 @@
|
||||
<span>Serial configuration</span>
|
||||
<div class="flex">
|
||||
<select name="mb" bind:value={configuration.m.b} class="in-f">
|
||||
<option value={0} disabled={configuration.m.b != 0}>Autodetect</option>
|
||||
<option value={2400}>2400</option>
|
||||
<option value={4800}>4800</option>
|
||||
<option value={9600}>9600</option>
|
||||
@ -233,7 +234,8 @@
|
||||
<option value={57600}>57600</option>
|
||||
<option value={115200}>115200</option>
|
||||
</select>
|
||||
<select name="mp" bind:value={configuration.m.p} class="in-l">
|
||||
<select name="mp" bind:value={configuration.m.p} class="in-l" disabled={configuration.m.b == 0}>
|
||||
<option value={0} disabled={configuration.m.b != 0}>-</option>
|
||||
<option value={2}>7N1</option>
|
||||
<option value={3}>8N1</option>
|
||||
<option value={10}>7E1</option>
|
||||
|
||||
@ -104,6 +104,9 @@ export function hanError(err) {
|
||||
case -51: return "Authentication failed";
|
||||
case -52: return "Decryption failed";
|
||||
case -53: return "Encryption key invalid";
|
||||
case 90: return "No HAN data received last 30s";
|
||||
case 98: return "Exception in code, debugging necessary";
|
||||
case 99: return "Autodetection failed";
|
||||
}
|
||||
if(err < 0) return "Unspecified error "+err;
|
||||
return "";
|
||||
|
||||
@ -60,7 +60,7 @@ private:
|
||||
bool performRestart = false;
|
||||
bool performUpgrade = false;
|
||||
bool rebootForUpgrade = false;
|
||||
String priceRegion;
|
||||
String priceRegion = "";
|
||||
|
||||
static const uint16_t BufferSize = 2048;
|
||||
char* buf;
|
||||
|
||||
@ -273,16 +273,6 @@ void AmsWebServer::sysinfoJson() {
|
||||
ESP.restart();
|
||||
#endif
|
||||
performRestart = false;
|
||||
} else {
|
||||
time_t now = time(nullptr);
|
||||
if(now < BUILD_EPOCH && server.hasArg(F("t"))) {
|
||||
time_t clientTime = server.arg(F("t")).toInt();
|
||||
if(clientTime > BUILD_EPOCH) {
|
||||
timeval tv { clientTime, 0};
|
||||
settimeofday(&tv, nullptr);
|
||||
if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("Internal clock synchronized with client\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,7 +280,7 @@ void AmsWebServer::dataJson() {
|
||||
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /data.json over http...\n");
|
||||
uint64_t millis = millis64();
|
||||
|
||||
if(!checkSecurity(2))
|
||||
if(!checkSecurity(2, true))
|
||||
return;
|
||||
|
||||
float vcc = hw->getVcc();
|
||||
@ -1322,6 +1312,9 @@ void AmsWebServer::handleSave() {
|
||||
void AmsWebServer::reboot() {
|
||||
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /reboot over http...\n");
|
||||
|
||||
if(!checkSecurity(1))
|
||||
return;
|
||||
|
||||
server.send(200, MIME_JSON, "{\"reboot\":true}");
|
||||
|
||||
server.handleClient();
|
||||
@ -1407,13 +1400,13 @@ void AmsWebServer::upgrade() {
|
||||
void AmsWebServer::firmwareHtml() {
|
||||
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Serving /firmware.html over http..."));
|
||||
|
||||
if(!checkSecurity(1))
|
||||
return;
|
||||
|
||||
server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE);
|
||||
server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE);
|
||||
server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF);
|
||||
|
||||
if(!checkSecurity(1))
|
||||
return;
|
||||
|
||||
server.setContentLength(FIRMWARE_HTML_LEN);
|
||||
server.send_P(200, MIME_HTML, FIRMWARE_HTML);
|
||||
}
|
||||
@ -1979,15 +1972,15 @@ void AmsWebServer::configFileDownload() {
|
||||
EnergyAccountingConfig eac;
|
||||
config->getEnergyAccountingConfig(eac);
|
||||
EnergyAccountingData ead = ea->getData();
|
||||
server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("energyaccounting %d %d %.2f %.2f %.2f %.2f %d %.2f %d %.2f %d %.2f %d %.2f %d %.2f"),
|
||||
server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("energyaccounting %d %d %.2f %d %d %.2f %d %d %d %.2f %d %.2f %d %.2f %d %.2f %d %.2f"),
|
||||
ead.version,
|
||||
ead.month,
|
||||
ead.costYesterday / 10.0,
|
||||
ead.costThisMonth / 1.0,
|
||||
ead.costLastMonth / 1.0,
|
||||
ead.costThisMonth,
|
||||
ead.costLastMonth,
|
||||
ead.incomeYesterday / 10.0,
|
||||
ead.incomeThisMonth / 1.0,
|
||||
ead.incomeLastMonth / 1.0,
|
||||
ead.incomeThisMonth,
|
||||
ead.incomeLastMonth,
|
||||
ead.peaks[0].day,
|
||||
ead.peaks[0].value / 100.0,
|
||||
ead.peaks[1].day,
|
||||
|
||||
@ -233,9 +233,9 @@ void setup() {
|
||||
break;
|
||||
}
|
||||
#if defined(ESP32)
|
||||
Serial.begin(meterConfig.baud, serialConfig, -1, -1, meterConfig.invert);
|
||||
Serial.begin(meterConfig.baud == 0 ? 2400 : meterConfig.baud: , serialConfig, -1, -1, meterConfig.invert);
|
||||
#else
|
||||
Serial.begin(meterConfig.baud, serialConfig, SERIAL_FULL, 1, meterConfig.invert);
|
||||
Serial.begin(meterConfig.baud == 0 ? 2400 : meterConfig.baud, serialConfig, SERIAL_FULL, 1, meterConfig.invert);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -404,6 +404,13 @@ unsigned long lastSysupdate = 0;
|
||||
unsigned long lastErrorBlink = 0;
|
||||
int lastError = 0;
|
||||
|
||||
bool meterAutodetect = false;
|
||||
unsigned long meterAutodetectLastChange = 0;
|
||||
uint8_t meterAutoIndex = 0;
|
||||
uint32_t bauds[] = { 2400, 2400, 115200, 115200 };
|
||||
uint8_t parities[] = { 11, 3, 3, 3 };
|
||||
bool inverts[] = { false, false, false, true };
|
||||
|
||||
void loop() {
|
||||
Debug.handle();
|
||||
unsigned long now = millis();
|
||||
@ -593,6 +600,31 @@ void loop() {
|
||||
}
|
||||
} catch(const std::exception& e) {
|
||||
debugE("Exception in readHanPort (%s)", e.what());
|
||||
meterState.setLastError(98);
|
||||
}
|
||||
try {
|
||||
if(meterState.getLastError() > 0) {
|
||||
if(now - meterAutodetectLastChange > 15000 && (meterConfig.baud == 0 || meterConfig.parity == 0)) {
|
||||
meterAutodetect = true;
|
||||
meterAutoIndex++; // Default is to try the first one in setup()
|
||||
debugI("Meter serial autodetect, swapping to: %d, %d, %s", bauds[meterAutoIndex], parities[meterAutoIndex], inverts[meterAutoIndex] ? "true" : "false");
|
||||
if(meterAutoIndex >= 4) meterAutoIndex = 0;
|
||||
setupHanPort(gpioConfig.hanPin, bauds[meterAutoIndex], parities[meterAutoIndex], inverts[meterAutoIndex]);
|
||||
meterAutodetectLastChange = now;
|
||||
}
|
||||
} else if(meterAutodetect) {
|
||||
meterAutoIndex--; // Last one worked, so lets use that
|
||||
debugI("Meter serial autodetected, saving: %d, %d, %s", bauds[meterAutoIndex], parities[meterAutoIndex], inverts[meterAutoIndex] ? "true" : "false");
|
||||
meterAutodetect = false;
|
||||
meterConfig.baud = bauds[meterAutoIndex];
|
||||
meterConfig.parity = parities[meterAutoIndex];
|
||||
meterConfig.invert = inverts[meterAutoIndex];
|
||||
config.setMeterConfig(meterConfig);
|
||||
setupHanPort(gpioConfig.hanPin, meterConfig.baud, meterConfig.parity, meterConfig.invert);
|
||||
}
|
||||
} catch(const std::exception& e) {
|
||||
debugE("Exception in meter autodetect (%s)", e.what());
|
||||
meterState.setLastError(99);
|
||||
}
|
||||
|
||||
delay(1); // Needed for auto modem sleep
|
||||
@ -606,6 +638,15 @@ void loop() {
|
||||
void setupHanPort(uint8_t pin, uint32_t baud, uint8_t parityOrdinal, bool invert) {
|
||||
if(Debug.isActive(RemoteDebug::INFO)) Debug.printf((char*) F("(setupHanPort) Setting up HAN on pin %d with baud %d and parity %d\n"), pin, baud, parityOrdinal);
|
||||
|
||||
if(baud == 0) {
|
||||
baud = bauds[meterAutoIndex];
|
||||
parityOrdinal = parities[meterAutoIndex];
|
||||
invert = inverts[meterAutoIndex];
|
||||
}
|
||||
if(parityOrdinal == 0) {
|
||||
parityOrdinal = 3; // 8N1
|
||||
}
|
||||
|
||||
HardwareSerial *hwSerial = NULL;
|
||||
if(pin == 3 || pin == 113) {
|
||||
hwSerial = &Serial;
|
||||
@ -723,6 +764,7 @@ void errorBlink() {
|
||||
if(lastErrorBlink - meterState.getLastUpdateMillis() > 30000) {
|
||||
debugW("No HAN data received last 30s, single blink");
|
||||
hw.ledBlink(LED_RED, 1); // If no message received from AMS in 30 sec, blink once
|
||||
if(meterState.getLastError() == 0) meterState.setLastError(90);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user