wifi, ota, time, mqtt, MySerial, TSL2561
This commit is contained in:
commit
a2cf20a189
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/.pio/
|
||||||
12
platformio.ini
Normal file
12
platformio.ini
Normal 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
16
src/main.cpp
Normal 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
42
src/mqtt.cpp
Normal 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
73
src/mqtt.h
Normal 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
39
src/tsl2561.cpp
Normal 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
8
src/tsl2561.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef TSL2561_H
|
||||||
|
#define TSL2561_H
|
||||||
|
|
||||||
|
void sensorSetup();
|
||||||
|
|
||||||
|
void sensorLoop();
|
||||||
|
|
||||||
|
#endif
|
||||||
76
src/wifi.cpp
Normal file
76
src/wifi.cpp
Normal 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
16
src/wifi.h
Normal 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
|
||||||
Loading…
Reference in New Issue
Block a user