#include "comm.h" //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 lockHTTP.begin(SOCKET_URL + wifiMACAddr); lockHTTP.addHeader("Content-Type", "application/json"); if (SERIAL_LOGGING) Serial.println("[INFO] Lock state HTTP begin."); if (SERIAL_LOGGING) Serial.print("[INFO] HTTP POST: "); String postData = serializeLockJson(lockState); if (SERIAL_LOGGING) Serial.println(postData); int16_t lockHTTPCode = lockHTTP.POST(postData); String lockHTTPCodeStr = String(lockHTTPCode); if (lockHTTPCode > 0) { 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_DISARM); lockState = LOCK_OFF; } if (SERIAL_LOGGING) Serial.println("[INFO] action: " + action); } else { if (SERIAL_LOGGING) Serial.println("[ERROR] Resource not found."); 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()); if (logErrors) logEvent(LOG_COMM_LOCK_FAIL, lockHTTPCodeStr.c_str(), lockHTTPCodeStr.length()); logErrors = false; } lockHTTP.end(); } 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 cardHTTP.begin(CARD_URL + wifiMACAddr + "/"); cardHTTP.addHeader("Content-Type", "application/json"); if (SERIAL_LOGGING) Serial.println("[INFO] Card state HTTP begin."); if (SERIAL_LOGGING) Serial.println("[INFO] HTTP GET"); int16_t cardHTTPCode = cardHTTP.GET(); String cardHTTPCodeStr = String(cardHTTPCode); if (cardHTTPCode > 0) { 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); if (SERIAL_LOGGING) Serial.println(cardPayload); noInterrupts(); // commit() disables interrupts, but we want an atomic EEPROM buffer write for (int i = 0; i < cardPayload.length(); i++) { if (i >= EEPROM_SIZE) break; EEPROM.write(i, cardPayload.charAt(i)); } EEPROM.commit(); interrupts(); if (SERIAL_LOGGING) Serial.println("[INFO] Finished getting card data."); } else { if (SERIAL_LOGGING) Serial.println("[ERROR] Resource not found."); 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()); if (logErrors) logEvent(LOG_COMM_CARD_FAIL, cardHTTPCodeStr.c_str(), cardHTTPCodeStr.length()); logErrors = false; } cardHTTP.end(); } 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 infoHTTP.begin(INFOLOG_URL + wifiMACAddr + "/"); infoHTTP.addHeader("Content-Type", "application/json"); if (SERIAL_LOGGING) Serial.println("[INFO] Info state HTTP begin."); if (SERIAL_LOGGING) Serial.println("[INFO] HTTP POST."); String postData = serializeLog(); int16_t infoHTTPCode = infoHTTP.POST(postData); String infoHTTPCodeStr = String(infoHTTPCode); if (infoHTTPCode > 0) { 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); uint8_t processed; uint32_t unixTime; String version = String(); deserializeInfoJson(infoPayload, &processed, &unixTime, &version); struct timeval tv = { .tv_sec = unixTime, .tv_usec = 0 }; struct timezone tz = { .tz_minuteswest = 0, .tz_dsttime = 0 }; settimeofday(&tv, &tz); removeLogRecords(processed); if (version != LOCKOUT_FIRMWARE_VERSION && lockState == LOCK_OFF) { noInterrupts(); if (SERIAL_LOGGING) Serial.println("[INFO] Firmware out of date. Updating..."); WiFiClient client; int16_t update_response = ESPhttpUpdate.update(client, UPDATE_URL + wifiMACAddr + "/"); interrupts(); if (SERIAL_LOGGING) printf("[ERROR] %s\n", ESPhttpUpdate.getLastErrorString().c_str()); String lastErrorNum = String(ESPhttpUpdate.getLastError()); logEvent(LOG_UPDATE_FAILED, lastErrorNum.c_str(), lastErrorNum.length()); } 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."); 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()); if (logErrors) logEvent(LOG_COMM_INFO_FAIL, infoHTTPCodeStr.c_str(), infoHTTPCodeStr.length()); logErrors = false; } infoHTTP.end(); } void processCommState() { static uint16_t commLockIdleCount, commCardIdleCount, commInfoIdleCount; switch (commState) { case COMM_INIT: commLockIdleCount = 0; commCardIdleCount = 0; commInfoIdleCount = 0; commState = COMM_IDLE; break; case COMM_IDLE: commLockIdleCount++; commCardIdleCount++; commInfoIdleCount++; if (commLockIdleCount >= COMM_LOCK_IDLE_TIME) { commState = COMM_LOCK; } else if (commCardIdleCount >= COMM_CARD_IDLE_TIME) { commState = COMM_CARD; } else if (commInfoIdleCount >= COMM_INFO_IDLE_TIME) { commState = COMM_INFO; } break; case COMM_LOCK: { postState(); commLockIdleCount = 0; commState = COMM_IDLE; } break; case COMM_CARD: { getCards(); commCardIdleCount = 0; commState = COMM_IDLE; } break; case COMM_INFO: { postInfolog(); commInfoIdleCount = 0; commState = COMM_IDLE; } break; } }