160 lines
4.0 KiB
C++
160 lines
4.0 KiB
C++
#include <Adafruit_seesaw.h>
|
|
#include <ArduinoJson.h>
|
|
#include <PubSubClient.h>
|
|
#include <WiFiClientSecure.h>
|
|
#include <incbin.h>
|
|
|
|
#include "config.h"
|
|
#include "constants.h"
|
|
#include "mqtt_discovery.hpp"
|
|
#include "values.hpp"
|
|
|
|
INCTXT(RootCA, "isrgrootx1.pem");
|
|
|
|
WiFiClientSecure sock;
|
|
PubSubClient mqtt(sock);
|
|
|
|
Values values;
|
|
Adafruit_seesaw ss;
|
|
|
|
void setup() {
|
|
delay(1000); // VSCode is slow to open the serial console after upload
|
|
|
|
Serial.begin(115200);
|
|
pinMode(13, OUTPUT);
|
|
digitalWrite(13, 1);
|
|
|
|
if (!wifi_connect()) {
|
|
Serial.printf("Failed to connect to WiFi, status %s\n", WiFi.status());
|
|
reboot();
|
|
}
|
|
if (!mqtt_connect()) {
|
|
Serial.println("Could not connect to MQTT");
|
|
reboot();
|
|
}
|
|
|
|
if (!publish_all_config(&mqtt, WiFi.macAddress().c_str())) {
|
|
Serial.println("Failed to publish device configuration!");
|
|
Serial.println(mqtt.state());
|
|
}
|
|
|
|
if (!ss.begin(0x36)) {
|
|
auto msg = "Seesaw not found";
|
|
Serial.println(msg);
|
|
mqtt_send_error(msg);
|
|
reboot();
|
|
}
|
|
|
|
if (!values.read(&ss)) {
|
|
auto msg = "Failed to get sensor values";
|
|
Serial.println(msg);
|
|
mqtt_send_error(msg);
|
|
reboot();
|
|
} else {
|
|
Serial.println("Got Values:");
|
|
Serial.printf(" Moisture: %d\n", values.moisture);
|
|
Serial.printf(" Temperature: %.02f\n", values.temperature);
|
|
Serial.printf(" Battery: %.02f\n", values.battery);
|
|
Serial.printf(" RSSI: %d\n", values.rssi);
|
|
if (!values.send(&mqtt, TOPIC_STATE)) {
|
|
Serial.println("Failed to send sensor values");
|
|
}
|
|
}
|
|
|
|
Serial.println("Disconnecting from MQTT broker ...");
|
|
mqtt.disconnect();
|
|
delay(1000);
|
|
|
|
Serial.println("Entering deep sleep ...");
|
|
Serial.flush();
|
|
esp_sleep_enable_timer_wakeup((SLEEP_MILLIS - millis()) * 1000);
|
|
esp_deep_sleep_start();
|
|
}
|
|
|
|
void loop() {
|
|
digitalWrite(13, 0);
|
|
while (1) delay(1471228928);
|
|
}
|
|
|
|
void error_led_blink() {
|
|
while (1) {
|
|
digitalWrite(13, 1);
|
|
delay(500);
|
|
digitalWrite(13, 0);
|
|
delay(500);
|
|
}
|
|
}
|
|
|
|
boolean wifi_connect() {
|
|
Serial.printf("Connecting to WiFi (%s) ", CFG_WIFI_SSID);
|
|
WiFi.begin(CFG_WIFI_SSID, CFG_WIFI_PSK);
|
|
while (WiFi.status() != WL_CONNECTED) {
|
|
delay(500);
|
|
if (millis() >= 5000) {
|
|
break;
|
|
}
|
|
Serial.print(".");
|
|
Serial.flush();
|
|
}
|
|
Serial.println();
|
|
if (WiFi.status() != WL_CONNECTED) {
|
|
return false;
|
|
}
|
|
|
|
Serial.println("WiFi connected");
|
|
Serial.printf(" IP address: %s\n", WiFi.localIP().toString());
|
|
Serial.printf(" DNS server: %s\n", WiFi.dnsIP().toString());
|
|
Serial.printf(" Default gateway: %s\n", WiFi.gatewayIP().toString());
|
|
|
|
return true;
|
|
}
|
|
|
|
boolean mqtt_connect() {
|
|
sock.setCACert(gRootCAData);
|
|
int retries = 3;
|
|
mqtt.setServer(CFG_MQTT_SERVER, CFG_MQTT_PORT);
|
|
for (;;) {
|
|
Serial.print("Connecting to MQTT ... ");
|
|
Serial.flush();
|
|
if (!mqtt.connect(CFG_MQTT_CLIENTID, CFG_MQTT_USERNAME,
|
|
CFG_MQTT_PASSWORD)) {
|
|
Serial.println(mqtt.state());
|
|
mqtt.disconnect();
|
|
delay(1000);
|
|
retries--;
|
|
if (retries < 1) {
|
|
return false;
|
|
}
|
|
} else {
|
|
Serial.println("OK");
|
|
break;
|
|
}
|
|
}
|
|
if (!mqtt.setBufferSize(512)) {
|
|
Serial.println("Failed to set MQTT client buffer size!");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void mqtt_send_error(const __FlashStringHelper* msg) {
|
|
mqtt_send_error((const char*)msg);
|
|
}
|
|
|
|
void mqtt_send_error(const char* msg) {
|
|
if (!mqtt.connected()) {
|
|
Serial.println("MQTT client not connected, cannot send error message");
|
|
return;
|
|
}
|
|
mqtt.publish(TOPIC_ERRORS, msg);
|
|
}
|
|
|
|
void reboot() {
|
|
if (mqtt.connected()) {
|
|
mqtt.disconnect();
|
|
}
|
|
Serial.println("Rebooting in 2 seconds");
|
|
delay(2000);
|
|
ESP.restart();
|
|
}
|