wifi, ota, time, mqtt, MySerial, TSL2561

This commit is contained in:
Patrick Haßel 2025-02-13 23:17:22 +01:00
commit a2cf20a189
9 changed files with 283 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/.pio/

12
platformio.ini Normal file
View File

@ -0,0 +1,12 @@
[env:Helligkeit]
platform = espressif8266
board = esp12e
framework = arduino
lib_deps = https://github.com/adafruit/Adafruit_TSL2561
https://github.com/knolleary/pubsubclient
build_flags = -DHOSTNAME=\"Helligkeit\"
monitor_speed = 115200
upload_protocol = espota
upload_port = 10.0.0.160
;upload_port = /dev/ttyUSB0
;upload_speed = 460800

16
src/main.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "wifi.h"
#include "tsl2561.h"
#include "mqtt.h"
void setup() {
delay(500);
MySerial.printf("\n\n\nStartup\n");
wifiConnect();
sensorSetup();
}
void loop() {
wifiLoop();
sensorLoop();
mqttLoop();
}

42
src/mqtt.cpp Normal file
View File

@ -0,0 +1,42 @@
#include "mqtt.h"
#include "wifi.h"
#include <PubSubClient.h>
#include <WiFiClient.h>
WiFiClient client;
PubSubClient mqtt(client);
MySerialClass MySerial(mqtt);
unsigned long mqttFailureMillis = 0;
void mqttLoop() {
if (!mqtt.loop() && isWifiConnected() && (mqttFailureMillis == 0 || millis() - mqttFailureMillis >= 3000)) {
mqtt.setServer("10.0.0.50", 1883);
if (mqtt.connect(HOSTNAME, HOSTNAME, 0, false, "disconnected\n")) {
yield();
mqttPublish("garten/log", "connected\n");
MySerial.printf("MQTT connected as \"%s\"\n", HOSTNAME);
mqttFailureMillis = 0;
} else {
MySerial.printf("Failed to connect MQTT.\n");
mqttFailureMillis = max(1UL, millis());
}
}
}
void mqttPublish(const char *topic, const float value, const char *unit) {
if (!isTimeSet()) {
return;
}
char buffer[200];
snprintf(buffer, sizeof buffer, R"({"timestamp": %lld, "value": %s, "unit": "%s"})", time(nullptr), isnan(value) ? "null" : String(value).c_str(), unit);
mqttPublish(topic, buffer);
}
void mqttPublish(const char *topic, const char *payload) {
mqtt.publish(topic, payload);
yield();
}

73
src/mqtt.h Normal file
View File

@ -0,0 +1,73 @@
#ifndef MQTT_H
#define MQTT_H
#include <Stream.h>
#include "PubSubClient.h"
#include "wifi.h"
void mqttLoop();
void mqttPublish(const char *topic, float value, const char *unit);
void mqttPublish(const char *topic, const char *payload);
class MySerialClass : public Stream {
PubSubClient& mqtt;
uint8_t buffer[500] = {};
uint8_t *bufferWrite = buffer;
uint8_t *bufferLast = buffer + sizeof(buffer) - 1;
size_t overflow = 0;
bool due = false;
public:
explicit MySerialClass(PubSubClient& mqttClient) : mqtt(mqttClient) {
Serial.begin(115200);
}
size_t write(uint8_t data) override {
Serial.write(data);
if (bufferWrite < bufferLast) {
*bufferWrite++ = data;
*bufferWrite = 0;
} else {
overflow++;
}
if (due || data == '\n' || bufferWrite >= bufferLast) {
due = true;
if (mqtt.connected()) {
if (overflow > 0) {
mqtt.publish(HOSTNAME, "\n### LOG BUFFER OVERFLOW BY %d BYTES ###\n");
overflow = 0;
}
mqtt.publish(HOSTNAME, (const char *) buffer);
bufferWrite = buffer;
*bufferWrite = 0;
due = false;
}
}
return 1;
}
int available() override {
return 0;
}
int read() override {
return -1;
}
int peek() override {
return -1;
}
};
extern MySerialClass MySerial;
#endif

39
src/tsl2561.cpp Normal file
View File

@ -0,0 +1,39 @@
#include "tsl2561.h"
#include "mqtt.h"
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_TSL2561_U.h>
Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 12345);
void sensorSetup() {
if (tsl.begin()) {
MySerial.printf("TSL2561: Initialized.\n");
} else {
MySerial.printf("TSL2561: Failed to initialize.\n");
}
tsl.enableAutoRange(true);
tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_402MS);
}
void sensorRead() {
sensors_event_t event;
if (!tsl.getEvent(&event)) {
MySerial.printf("TSL2561: Failed to read.\n");
sensorSetup();
} else if (event.light == 0) {
MySerial.printf("TSL2561: Too bright.\n");
} else {
mqttPublish("garten/helligkeit", event.light, "lux");
}
}
void sensorLoop() {
unsigned long now = millis();
static unsigned long last = 0;
if (last == 0 || now - last >= 2000) {
last = max(1UL, now);
sensorRead();
}
}

8
src/tsl2561.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef TSL2561_H
#define TSL2561_H
void sensorSetup();
void sensorLoop();
#endif

76
src/wifi.cpp Normal file
View File

@ -0,0 +1,76 @@
#include <TZ.h>
#include <ArduinoOTA.h>
#include "wifi.h"
#include "mqtt.h"
bool wifiConnected = false;
bool timeSet = false;
unsigned long wifiSince = 0;
void wifiConnect() {
wifiSince = max(1UL, millis());
WiFi.setHostname(HOSTNAME);
WiFi.begin("HappyNet", "1Grausame!Sackratte7");
configTime(TZ_Europe_Berlin, "107.189.12.98");
ArduinoOTA.begin();
yield();
}
void timeLoop() {
const time_t now = time(nullptr);
const time_t nowHour = now / 3600;
static unsigned long lastHour = 0;
if (!timeSet) {
if (now > 1700000000) {
timeSet = true;
lastHour = nowHour;
MySerial.printf("Got time: %s\n", getTimeString().c_str());
}
} else {
if (lastHour != nowHour) {
lastHour = nowHour;
MySerial.printf("%s\n", getTimeString().c_str());
}
}
}
void wifiLoop() {
ArduinoOTA.handle();
if (WiFi.localIP() == 0UL) {
if (wifiConnected) {
wifiConnected = false;
MySerial.printf("WiFi disconnected.\n");
wifiConnect();
} else if (wifiSince == 0 || millis() - wifiSince >= 10000) {
WiFi.disconnect();
yield();
wifiConnect();
}
} else {
if (!wifiConnected) {
wifiConnected = true;
MySerial.printf("WiFi connected as \"%s\" (%s)\n", HOSTNAME, WiFi.localIP().toString().c_str());
}
timeLoop();
}
}
String getTimeString() {
time_t now;
time(&now);
tm info{};
localtime_r(&now, &info);
char buffer[32];
strftime(buffer, sizeof buffer, "%F %T %z", &info);
return {buffer};
}
bool isWifiConnected() {
return wifiConnected;
}
bool isTimeSet() {
return timeSet;
}

16
src/wifi.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef WIFI_H
#define WIFI_H
#include <Arduino.h>
void wifiConnect();
void wifiLoop();
String getTimeString();
bool isWifiConnected();
bool isTimeSet();
#endif