From 63adb9b9a36ff9c6e4aed0c06a3f22b1fc755c48 Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Sun, 20 Jan 2019 20:04:43 -0700 Subject: [PATCH] Don't log duplicate COMM errors, remove sent log records --- firmware/firmware.ino | 106 +++++++++++++++++++++++++++++++----------- 1 file changed, 78 insertions(+), 28 deletions(-) diff --git a/firmware/firmware.ino b/firmware/firmware.ino index 26ddfa8..934244b 100644 --- a/firmware/firmware.ino +++ b/firmware/firmware.ino @@ -23,12 +23,12 @@ char cardBuffer[CARD_BUFFER_LENGTH]; #define CARD_CHECK_LENGTH 2 #define CARD_HEAD_BYTE 0x2 #define CARD_TAIL_BYTE 0x3 -typedef struct __attribute__((packed)) cardData { +struct __attribute__((packed)) cardData { char head; char data[CARD_DATA_LENGTH]; char checksum[CARD_CHECK_LENGTH]; char tail; -} cardData_t; +}; #define RELAY_PIN D1 #define GREEN_BUTTON_PIN D3 @@ -90,7 +90,8 @@ enum commStates #define SERIAL_LOGGING true -#define LOG_SIZE 100 +#define LOG_SIZE 90 // 100 blew up the stack +#define LOG_DATA_LENGTH CARD_DATA_LENGTH enum eventCodes { @@ -98,6 +99,8 @@ enum eventCodes LOG_INIT_COMPLETE, LOG_WIFI_CONNECTED, LOG_WIFI_DISCONNECTED, + LOG_COMM_LOCK_ARM, + LOG_COMM_LOCK_DISARM, LOG_COMM_LOCK_FAIL, LOG_COMM_CARD_FAIL, LOG_COMM_INFO_FAIL, @@ -105,31 +108,33 @@ enum eventCodes LOG_LOCK_ARMED, LOG_LOCK_TIMEOUT, LOG_LOCK_ON, - LOG_LOCK_CANCEL, + LOG_LOCK_DISARM, LOG_LOCK_ERROR, LOG_CARD_GOOD_READ, LOG_CARD_ACCEPTED, LOG_CARD_DENIED, }; -typedef struct __attribute__((packed)) logData { +struct __attribute__((packed)) logData { uint32_t unixTime; uint8_t eventCode; - char data[CARD_DATA_LENGTH]; -} logData_t; + char data[LOG_DATA_LENGTH]; +}; -logData_t eventLog[LOG_SIZE]; +struct logData eventLog[LOG_SIZE]; uint16_t logPosition = 0; void logEvent(uint8_t eventCode, const char *data = nullptr, size_t num = 0) { - logData_t event; + struct logData event; noInterrupts(); event.unixTime = time(nullptr); event.eventCode = eventCode; - for (uint8_t i = 0; i < CARD_DATA_LENGTH; i++) { + + memset(event.data, 0, LOG_DATA_LENGTH); + for (uint8_t i = 0; i < LOG_DATA_LENGTH; i++) { if (i >= num) break; event.data[i] = data[i]; } @@ -141,6 +146,22 @@ void logEvent(uint8_t eventCode, const char *data = nullptr, size_t num = 0) interrupts(); } +void removeLogRecords(uint8_t num) { + // shift records down by num because they've been sent + + if (num > logPosition) return; + + noInterrupts(); + + for (int i = 0; i < num; i++) { + eventLog[i] = eventLog[i + num]; + } + logPosition -= num; + + interrupts(); +} + + void setup() { Serial.begin(9600); @@ -217,7 +238,7 @@ int8_t charToNum(char input) return String("0123456789ABCDEF").indexOf(input); } -bool checksum(cardData_t *cardData) +bool checksum(struct cardData *cardData) { // checksum is each hex data byte xord'd together. // each char is a hex nibble, so we have to work in pairs. @@ -244,7 +265,7 @@ bool checksum(cardData_t *cardData) void checkCard() { - cardData_t *cardData = (cardData_t *) cardBuffer; + struct cardData *cardData = (struct cardData *) cardBuffer; if (cardData->head == CARD_HEAD_BYTE && cardData->tail == CARD_TAIL_BYTE && @@ -357,7 +378,7 @@ void processLockState() if (redButton()) { if (SERIAL_LOGGING) Serial.println("[INFO] Unarming interlock."); - logEvent(LOG_LOCK_CANCEL); + logEvent(LOG_LOCK_DISARM); lockState = LOCK_OFF; } else if (greenButton()) { if (SERIAL_LOGGING) Serial.println("[INFO] On button pressed."); @@ -485,24 +506,29 @@ String deserializeLockJson(String input) } String serializeLog() { - size_t logLengthBytes = logPosition * sizeof(logData_t); - return base64::encode((uint8_t *) eventLog, logLengthBytes, false); + size_t logLengthBytes = logPosition * sizeof(struct logData); + return "{\"log\": \"" + base64::encode((uint8_t *) eventLog, logLengthBytes, false) + "\"}"; } -uint32_t deserializeInfoJson(String input) +void deserializeInfoJson(String input, uint8_t *processed, uint32_t *unixTime) { // Generated with: https://arduinojson.org/assistant/ - const size_t bufferSize = JSON_OBJECT_SIZE(1) + 50; + const size_t bufferSize = JSON_OBJECT_SIZE(2) + 50; StaticJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.parseObject(input); - uint32_t unixTime = root["unixTime"]; - - return unixTime; + *processed = root["processed"]; + *unixTime = root["unixTime"]; } + +//TODO: abstract http functions + void postState() { + // Don't log more than one error at a time + static bool logErrors = true; + HTTPClient lockHTTP; //lockHTTP.begin("https://url", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS @@ -521,27 +547,33 @@ void postState() if (SERIAL_LOGGING) Serial.printf("[INFO] POST success, code: %d\n", lockHTTPCode); if (lockHTTPCode == HTTP_CODE_OK) { + logErrors = true; + if (SERIAL_LOGGING) Serial.print("[INFO] Resource found, parsing response: "); String lockPayload = lockHTTP.getString(); if (SERIAL_LOGGING) Serial.println(lockPayload); String action = deserializeLockJson(lockPayload); if (action == "arm" && lockState == LOCK_OFF && LEDState == LED_OFF) { + logEvent(LOG_COMM_LOCK_ARM); lockState = LOCK_PREARM; } else if (action == "disarm" && lockState != LOCK_ON) { + logEvent(LOG_COMM_LOCK_DISARM); if (SERIAL_LOGGING) Serial.println("[INFO] Unarming interlock."); - logEvent(LOG_LOCK_CANCEL); + logEvent(LOG_LOCK_DISARM); lockState = LOCK_OFF; } if (SERIAL_LOGGING) Serial.println("[INFO] action: " + action); } else { if (SERIAL_LOGGING) Serial.println("[ERROR] Resource not found."); - logEvent(LOG_COMM_LOCK_FAIL, lockHTTPCodeStr.c_str(), lockHTTPCodeStr.length()); + if (logErrors) logEvent(LOG_COMM_LOCK_FAIL, lockHTTPCodeStr.c_str(), lockHTTPCodeStr.length()); + logErrors = false; } } else { if (SERIAL_LOGGING) Serial.printf("[ERROR] POST failed, error: %s\n", lockHTTP.errorToString(lockHTTPCode).c_str()); - logEvent(LOG_COMM_LOCK_FAIL, lockHTTPCodeStr.c_str(), lockHTTPCodeStr.length()); + if (logErrors) logEvent(LOG_COMM_LOCK_FAIL, lockHTTPCodeStr.c_str(), lockHTTPCodeStr.length()); + logErrors = false; } lockHTTP.end(); @@ -549,6 +581,9 @@ void postState() void getCards() { + // Don't log more than one error at a time + static bool logErrors = true; + HTTPClient cardHTTP; //cardHTTP.begin("https://url", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS @@ -565,6 +600,8 @@ void getCards() if (SERIAL_LOGGING) Serial.printf("[INFO] GET success, code: %d\n", cardHTTPCode); if (cardHTTPCode == HTTP_CODE_OK) { + logErrors = true; + if (SERIAL_LOGGING) Serial.print("[INFO] Resource found, parsing response: "); String cardPayload = cardHTTP.getString(); cardPayload += String(EEPROM_END_MARKER); @@ -581,11 +618,13 @@ void getCards() if (SERIAL_LOGGING) Serial.println("[INFO] Finished getting card data."); } else { if (SERIAL_LOGGING) Serial.println("[ERROR] Resource not found."); - logEvent(LOG_COMM_CARD_FAIL, cardHTTPCodeStr.c_str(), cardHTTPCodeStr.length()); + if (logErrors) logEvent(LOG_COMM_CARD_FAIL, cardHTTPCodeStr.c_str(), cardHTTPCodeStr.length()); + logErrors = false; } } else { if (SERIAL_LOGGING) Serial.printf("[ERROR] POST failed, error: %s\n", cardHTTP.errorToString(cardHTTPCode).c_str()); - logEvent(LOG_COMM_CARD_FAIL, cardHTTPCodeStr.c_str(), cardHTTPCodeStr.length()); + if (logErrors) logEvent(LOG_COMM_CARD_FAIL, cardHTTPCodeStr.c_str(), cardHTTPCodeStr.length()); + logErrors = false; } cardHTTP.end(); @@ -593,6 +632,9 @@ void getCards() void postInfolog() { + // Don't log more than one error at a time + static bool logErrors = true; + HTTPClient infoHTTP; //infoHTTP.begin("https://url", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS @@ -611,24 +653,32 @@ void postInfolog() if (SERIAL_LOGGING) Serial.printf("[INFO] POST success, code: %d\n", infoHTTPCode); if (infoHTTPCode == HTTP_CODE_OK) { + logErrors = true; + if (SERIAL_LOGGING) Serial.print("[INFO] Resource found, parsing response: "); String infoPayload = infoHTTP.getString(); if (SERIAL_LOGGING) Serial.println(infoPayload); - uint32_t unixTime = deserializeInfoJson(infoPayload); + uint8_t processed; + uint32_t unixTime; + deserializeInfoJson(infoPayload, &processed, &unixTime); struct timeval tv = { .tv_sec = unixTime, .tv_usec = 0 }; struct timezone tz = { .tz_minuteswest = 0, .tz_dsttime = 0 }; settimeofday(&tv, &tz); + removeLogRecords(processed); + if (SERIAL_LOGGING) Serial.print("[INFO] Set system time to: "); if (SERIAL_LOGGING) Serial.println(unixTime); } else { if (SERIAL_LOGGING) Serial.println("[ERROR] Resource not found."); - logEvent(LOG_COMM_INFO_FAIL, infoHTTPCodeStr.c_str(), infoHTTPCodeStr.length()); + if (logErrors) logEvent(LOG_COMM_INFO_FAIL, infoHTTPCodeStr.c_str(), infoHTTPCodeStr.length()); + logErrors = false; } } else { if (SERIAL_LOGGING) Serial.printf("[ERROR] POST failed, error: %s\n", infoHTTP.errorToString(infoHTTPCode).c_str()); - logEvent(LOG_COMM_INFO_FAIL, infoHTTPCodeStr.c_str(), infoHTTPCodeStr.length()); + if (logErrors) logEvent(LOG_COMM_INFO_FAIL, infoHTTPCodeStr.c_str(), infoHTTPCodeStr.length()); + logErrors = false; } infoHTTP.end();