diff --git a/geiger_interface.ino b/geiger_interface.ino new file mode 100644 index 0000000..6559cf4 --- /dev/null +++ b/geiger_interface.ino @@ -0,0 +1,293 @@ +#define ESP_DRD_USE_LITTLEFS true +#define DRD_TIMEOUT 10 +#define DRD_ADDRESS 0 +#define JSON_CONFIG_FILE "/config.json" +#define TUBE_NAME "J305" +#define TUBE_FACTOR 0.00812 + +#include +#include +#include +#include +#include +#include +#include + +DoubleResetDetector* drd; + +WiFiClient espClient; // connection for MQTT +WiFiClient espClient2; // connection fot HTTP Client +PubSubClient client(espClient); + +// Initialize LittleFS +void initLittleFS() { + if (!LittleFS.begin(true)) { + Serial.println("An error has occurred while mounting LittleFS"); + } + Serial.println("LittleFS mounted successfully"); +} + +char mqttServer[50] = ""; +char mqttUser[50] = ""; +char mqttPass[50] = ""; +char gmcAccountID[50] = ""; +char gmcDeviceID[50] = ""; +bool shouldSaveConfig = false; + +char buf[10]; +char buf2[10]; + +unsigned long time_now = 0; +unsigned long time_now2 = 0; +unsigned long mold = 0; +unsigned long currentMillis = 0; +unsigned long previousMillis_60s = 0; +const long interval_60s = 60000; + +unsigned long previousMillis_10m = 0; +const long interval_10m = 600000; + +const byte interruptPin = 13; +volatile unsigned long GeigerCounts = 0; +void ICACHE_RAM_ATTR handleInterrupt() { + GeigerCounts++; +} + +String GMCMap_Request_payload = "http://www.GMCmap.com/log2.asp"; +String GMCMap_Request = ""; +String GMCMap_Data = ""; +String GMCMap = "NONE"; + +void saveConfigFile() +{ + Serial.println(F("Saving config")); + StaticJsonDocument<512> json; + json["mqttServer"] = mqttServer; + json["mqttUser"] = mqttUser; + json["mqttPass"] = mqttPass; + json["gmcAccountID"] = gmcAccountID; + json["gmcDeviceID"] = gmcDeviceID; + + File configFile = FileFS.open(JSON_CONFIG_FILE, "w"); + if (!configFile) + { + Serial.println("failed to open config file for writing"); + } + + serializeJsonPretty(json, Serial); + if (serializeJson(json, configFile) == 0) + { + Serial.println(F("Failed to write to file")); + } + configFile.close(); +} + +bool loadConfigFile() +{ + //read configuration from FS json + Serial.println("mounting FS..."); + + if (FileFS.begin(false) || FileFS.begin(true)) + { + Serial.println("mounted file system"); + if (FileFS.exists(JSON_CONFIG_FILE)) + { + //file exists, reading and loading + Serial.println("reading config file"); + File configFile = FileFS.open(JSON_CONFIG_FILE, "r"); + if (configFile) + { + Serial.println("opened config file"); + StaticJsonDocument<512> json; + DeserializationError error = deserializeJson(json, configFile); + serializeJsonPretty(json, Serial); + if (!error) + { + Serial.println("\nparsed json"); + + strcpy(mqttServer, json["mqttServer"]); + strcpy(mqttUser, json["mqttUser"]); + strcpy(mqttPass, json["mqttPass"]); + strcpy(gmcAccountID, json["gmcAccountID"]); + strcpy(gmcDeviceID, json["gmcDeviceID"]); + + + return true; + } + else + { + Serial.println("failed to load json config"); + } + } + } + } + else + { + Serial.println("failed to mount FS"); + } + //end read + return false; +} + +void saveConfigCallback() +{ + Serial.println("Should save config"); + shouldSaveConfig = true; +} + +void reconnect() { + // Loop until we're reconnected + while (!client.connected()) { + Serial.print("Attempting MQTT connection..."); + // Attempt to connect + if (client.connect("GeigerClient")) { + Serial.println("connected"); + } else { + Serial.print("failed, rc="); + Serial.print(client.state()); + Serial.println(" try again in 5 seconds"); + // Wait 5 seconds before retrying + delay(5000); + } + } +} + +void setup() { + // WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP + // it is a good practice to make sure your code sets wifi mode how you want it. + + Serial.begin(115200); + pinMode( interruptPin, INPUT ); + attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING ); + initLittleFS(); + + drd = new DoubleResetDetector(DRD_TIMEOUT, DRD_ADDRESS); + bool forceConfig = false; + if (drd->detectDoubleReset()) { + Serial.println("Double Reset Detected"); + forceConfig = true; + } + + WiFiManager wm; + wm.setSaveConfigCallback(saveConfigCallback); + WiFiManagerParameter custom_mqttServer("mqttServer", "MQTT Server", mqttServer, 50); + WiFiManagerParameter custom_mqttUser("mqttUser", "MQTT User", mqttUser, 50); + WiFiManagerParameter custom_mqttPass("mqttPass", "MQTT Password", mqttPass, 50); + WiFiManagerParameter custom_gmcAccountID("gmcAccountID", "GMC MAP Account ID", gmcAccountID, 50); + WiFiManagerParameter custom_gmcDeviceID("gmcDeviceID", "GMC MAP Device ID", gmcDeviceID, 50); + + + wm.addParameter(&custom_mqttServer); + wm.addParameter(&custom_mqttUser); + wm.addParameter(&custom_mqttPass); + wm.addParameter(&custom_gmcAccountID); + wm.addParameter(&custom_gmcDeviceID); + // wm.resetSettings(); + + bool res; + res = wm.autoConnect(); + + if (!res) { + Serial.println("Failed to connect"); + // ESP.restart(); + } else { + Serial.println("connected...yeey :)"); + + if (forceConfig) + { + if (!wm.startConfigPortal()) + { + Serial.println("failed to connect and hit timeout"); + delay(3000); + ESP.restart(); + delay(5000); + } + } + } + + //tutaj bez sensu + strcpy(mqttServer, custom_mqttServer.getValue()); + strcpy(mqttUser, custom_mqttUser.getValue()); + strcpy(mqttPass, custom_mqttPass.getValue()); + strcpy(gmcAccountID, custom_gmcAccountID.getValue()); + strcpy(gmcDeviceID, custom_gmcDeviceID.getValue()); + Serial.println("The values in the file are: "); + Serial.println("\tmqtt_server : " + String(mqttServer)); + Serial.println("\tmqtt_user : " + String(mqttUser)); + Serial.println("\tmqtt_pass : " + String(mqttPass)); + Serial.println("\tgmc_AccountID : " + String(gmcAccountID)); + Serial.println("\tgmc_DeviceID : " + String(gmcDeviceID)); + + if (shouldSaveConfig) + { + Serial.println("saving config"); + saveConfigFile(); + } + + loadConfigFile(); + + client.setServer(mqttServer, 1883); + +} + +void loop() { + drd->loop(); + + // if MQTT server provided + if (String(mqttServer) != "") { + if (!client.connected()) { + reconnect(); + } + + if(millis() >= time_now + 5000){ + time_now += 5000; + client.publish("esp32/heartbeat", "PING"); + } + + + if (millis() >= mold + 60000) { + ltoa(GeigerCounts, buf, 10); + dtostrf(GeigerCounts*TUBE_FACTOR, -4, 2, buf2); + client.publish("esp32/CPM", buf); + client.publish("esp32/uSv", buf2); + GeigerCounts = 0; + mold += 60000; + } + client.loop(); + } + + // if GMC IDs provided + if (String(gmcAccountID) != "") { + currentMillis = millis(); + if (currentMillis - previousMillis_10m >= interval_10m) { + previousMillis_10m = currentMillis; + Serial.print("[HTTP] begin...\n"); + GMCMap_Request = GMCMap_Request_payload + "?AID=" + gmcAccountID + "&GID=" + gmcDeviceID + "&CPM=" + buf + "&ACPM=" + buf + "&uSV=" + buf2; + Serial.println(GMCMap_Request); + HTTPClient http; + if (http.begin(espClient2, GMCMap_Request)) { // HTTP + Serial.print("[HTTP] GET...\n"); + int httpCode = http.GET(); + if (httpCode > 0) { + Serial.printf("[HTTP] GET... code: %d\n", httpCode); + if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) { + String payload = http.getString(); + Serial.println(payload); + if (payload.indexOf("ERR0") > 0) GMCMap = "OK"; + if (payload.indexOf("ERR1") > 0) GMCMap = "Error! User is not found"; + if (payload.indexOf("ERR2") > 0) GMCMap = "Error! Geiger Counter is not found"; + if (payload.indexOf("Warning") > 0) GMCMap = "Warning! The Geiger Counter location changed, please confirm the location"; + Serial.println(GMCMap); + } + } else { + Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); + GMCMap = http.errorToString(httpCode).c_str(); + } + http.end(); + } else { + Serial.println("[HTTP] Unable to connect"); + GMCMap = "Unable to connect"; + } + } + } +} \ No newline at end of file