esp8266-geigercounter/esp8266-geigercounter.ino

209 lines
6 KiB
Arduino
Raw Normal View History

2020-09-26 17:34:24 +02:00
#include "wifi.h"
2015-12-23 22:49:57 +01:00
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
2020-09-26 17:34:24 +02:00
#include <ArduinoJson.h>
#include <WiFiManager.h>
#include <PubSubClient.h>
#include <SoftwareSerial.h>
2015-12-23 22:49:57 +01:00
#include "settings.h"
2020-09-26 17:34:24 +02:00
uint8_t mqttRetryCounter = 0;
2020-09-26 17:34:24 +02:00
WiFiManager wifiManager;
2015-12-23 22:49:57 +01:00
WiFiClient wifiClient;
PubSubClient mqttClient;
2020-09-26 17:34:24 +02:00
WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, sizeof(mqtt_server));
WiFiManagerParameter custom_mqtt_user("user", "MQTT username", username, sizeof(username));
WiFiManagerParameter custom_mqtt_pass("pass", "MQTT password", password, sizeof(password));
unsigned long lastMqttConnectionAttempt = millis();
const long mqttConnectionInterval = 60000;
unsigned long statusPublishPreviousMillis = millis();
const long statusPublishInterval = 30000;
char identifier[24];
#define FIRMWARE_PREFIX "esp8266-geigercounter"
#define AVAILABILITY_ONLINE "online"
#define AVAILABILITY_OFFLINE "offline"
char MQTT_TOPIC_AVAILABILITY[128];
char MQTT_TOPIC_CPM[128];
char MQTT_TOPIC_USV[128];
char MQTT_TOPIC_AUTOCONF_CPM[128];
char MQTT_TOPIC_AUTOCONF_USV[128];
2015-12-23 22:49:57 +01:00
SoftwareSerial geigerCounterSerial(PIN_UART_RX, PIN_UART_TX);
2020-09-26 17:34:24 +02:00
bool shouldSaveConfig = false;
2015-12-23 22:49:57 +01:00
2020-09-26 17:34:24 +02:00
void saveConfigCallback () {
shouldSaveConfig = true;
}
2016-02-20 22:21:44 +01:00
void setup() {
delay(3000);
2020-09-26 17:34:24 +02:00
Serial.begin(9600);
delay(2000);
Serial.println("\n");
Serial.println("Hello from esp8266-geigercounter");
Serial.printf("Core Version: %s\n", ESP.getCoreVersion().c_str());
Serial.printf("Boot Version: %u\n", ESP.getBootVersion());
Serial.printf("Boot Mode: %u\n", ESP.getBootMode());
Serial.printf("CPU Frequency: %u MHz\n", ESP.getCpuFreqMHz());
Serial.printf("Reset reason: %s\n", ESP.getResetReason().c_str());
2020-09-26 17:34:24 +02:00
geigerCounterSerial.begin(9600);
2020-09-26 17:34:24 +02:00
snprintf(identifier, sizeof(identifier), "GEIGERCTR-%X", ESP.getChipId());
snprintf(MQTT_TOPIC_AVAILABILITY, 127, "%s/%s/status", FIRMWARE_PREFIX, identifier);
snprintf(MQTT_TOPIC_CPM, 127, "%s/%s_cpm/state", FIRMWARE_PREFIX, identifier);
snprintf(MQTT_TOPIC_USV, 127, "%s/%s_usv/state", FIRMWARE_PREFIX, identifier);
2020-09-26 17:34:24 +02:00
snprintf(MQTT_TOPIC_AUTOCONF_CPM, 127, "homeassistant/sensor/%s/%s_cpm/config", FIRMWARE_PREFIX, identifier);
snprintf(MQTT_TOPIC_AUTOCONF_USV, 127, "homeassistant/sensor/%s/%s_usv/config", FIRMWARE_PREFIX, identifier);
2015-12-23 22:49:57 +01:00
2020-09-26 17:34:24 +02:00
WiFi.hostname(identifier);
2020-09-26 17:34:24 +02:00
loadConfig();
setupWifi();
mqttClient.setServer(mqtt_server, 1883);
mqttClient.setKeepAlive(10);
mqttClient.setBufferSize(2048);
2020-09-26 17:34:24 +02:00
Serial.print("Hostname: ");
Serial.println(identifier);
Serial.print("\nIP: ");
Serial.println(WiFi.localIP());
Serial.println("-- Current GPIO Configuration --");
Serial.print("PIN_UART_RX: ");
Serial.println(PIN_UART_RX);
2020-09-26 17:34:24 +02:00
//Disable blue LED
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
mqttReconnect();
2015-12-23 22:49:57 +01:00
}
2020-09-26 17:34:24 +02:00
void loop() {
mqttClient.loop();
2020-09-26 17:34:24 +02:00
handleUart();
if (statusPublishInterval <= (millis() - statusPublishPreviousMillis)) {
statusPublishPreviousMillis = millis();
updateRadiationValues();
}
2020-09-26 17:34:24 +02:00
if (!mqttClient.connected() && (mqttConnectionInterval <= (millis() - lastMqttConnectionAttempt)) ) {
lastMqttConnectionAttempt = millis();
mqttReconnect();
}
}
2020-09-26 17:34:24 +02:00
void setupWifi() {
wifiManager.setDebugOutput(false);
wifiManager.setSaveConfigCallback(saveConfigCallback);
2020-09-26 17:34:24 +02:00
wifiManager.addParameter(&custom_mqtt_server);
wifiManager.addParameter(&custom_mqtt_user);
wifiManager.addParameter(&custom_mqtt_pass);
2020-09-26 17:34:24 +02:00
WiFi.hostname(identifier);
wifiManager.autoConnect(identifier);
mqttClient.setClient(wifiClient);
2020-09-26 17:34:24 +02:00
strcpy(mqtt_server, custom_mqtt_server.getValue());
strcpy(username, custom_mqtt_user.getValue());
strcpy(password, custom_mqtt_pass.getValue());
2015-12-23 22:49:57 +01:00
2020-09-26 17:34:24 +02:00
if (shouldSaveConfig) {
saveConfig();
} else {
2020-09-26 17:34:24 +02:00
//For some reason, the read values get overwritten in this function
//To combat this, we just reload the config
//This is most likely a logic error which could be fixed otherwise
loadConfig();
}
}
2020-09-26 17:34:24 +02:00
void resetWifiSettingsAndReboot() {
wifiManager.resetSettings();
delay(3000);
ESP.restart();
}
2020-09-26 17:34:24 +02:00
void mqttReconnect() {
for (int attempt = 0; attempt < 3; ++attempt) {
if (mqttClient.connect(identifier, username, password, MQTT_TOPIC_AVAILABILITY, 1, true, AVAILABILITY_OFFLINE)) {
mqttClient.publish(MQTT_TOPIC_AVAILABILITY, AVAILABILITY_ONLINE, true);
2020-09-26 17:34:24 +02:00
Serial.println("Connected to MQTT Server");
2015-12-23 22:49:57 +01:00
2020-09-26 17:34:24 +02:00
publishAutoConfig();
break;
} else {
Serial.println("Failed to connect to MQTT Server :(");
delay(5000);
}
}
}
2020-09-26 17:34:24 +02:00
boolean isMqttConnected() {
return mqttClient.connected();
2015-12-23 22:49:57 +01:00
}
2020-09-26 17:34:24 +02:00
void publishAutoConfig() {
char mqttPayload[2048];
DynamicJsonDocument device(256);
StaticJsonDocument<64> identifiersDoc;
JsonArray identifiers = identifiersDoc.to<JsonArray>();
2016-02-20 22:21:44 +01:00
2020-09-26 17:34:24 +02:00
identifiers.add(identifier);
2016-02-20 22:21:44 +01:00
2020-09-26 17:34:24 +02:00
device["identifiers"] = identifiers;
device["manufacturer"] = "MightyOhm LLC";
device["model"] = "Geiger Counter";
device["name"] = identifier;
device["sw_version"] = "2023.08.0";
2016-02-20 22:21:44 +01:00
2020-09-26 17:34:24 +02:00
DynamicJsonDocument cpmSensorPayload(512);
2016-02-20 22:21:44 +01:00
2020-09-26 17:34:24 +02:00
cpmSensorPayload["device"] = device.as<JsonObject>();
cpmSensorPayload["availability_topic"] = MQTT_TOPIC_AVAILABILITY;
cpmSensorPayload["state_topic"] = MQTT_TOPIC_CPM;
cpmSensorPayload["name"] = "CPM";
2020-09-26 17:34:24 +02:00
cpmSensorPayload["unit_of_measurement"] = "CPM";
cpmSensorPayload["state_class"] = "measurement";
2020-09-26 17:34:24 +02:00
cpmSensorPayload["unique_id"] = identifier + String("_cpm");
2016-02-20 22:21:44 +01:00
2020-09-26 17:34:24 +02:00
serializeJson(cpmSensorPayload, mqttPayload);
mqttClient.publish(MQTT_TOPIC_AUTOCONF_CPM, mqttPayload, true);
2016-02-20 22:21:44 +01:00
2020-09-26 17:34:24 +02:00
DynamicJsonDocument usvSensorPayload(512);
2016-02-20 22:21:44 +01:00
2020-09-26 17:34:24 +02:00
usvSensorPayload["device"] = device.as<JsonObject>();
usvSensorPayload["availability_topic"] = MQTT_TOPIC_AVAILABILITY;
usvSensorPayload["state_topic"] = MQTT_TOPIC_USV;
usvSensorPayload["name"] = "uSv";
2020-09-26 17:34:24 +02:00
usvSensorPayload["unit_of_measurement"] = "µSv/h";
usvSensorPayload["state_class"] = "measurement";
2020-09-26 17:34:24 +02:00
usvSensorPayload["unique_id"] = identifier + String("_uSv");
2015-12-23 22:49:57 +01:00
2020-09-26 17:34:24 +02:00
serializeJson(usvSensorPayload, mqttPayload);
mqttClient.publish(MQTT_TOPIC_AUTOCONF_USV, mqttPayload, true);
2016-02-20 22:21:44 +01:00
2020-09-26 17:34:24 +02:00
Serial.println("Published MQTT Autoconf");
}