gardensensor/gardensensor.ino

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();
}