knx, wifi, time, mqtt, http
This commit is contained in:
parent
4867d92b62
commit
773b4b297b
@ -4,3 +4,4 @@ board = esp12e
|
||||
framework = arduino
|
||||
lib_deps = https://github.com/thorsten-gehrig/arduino-tpuart-knx-user-forum
|
||||
https://github.com/knolleary/pubsubclient
|
||||
https://github.com/me-no-dev/ESPAsyncWebServer
|
||||
20
src/Group.cpp
Normal file
20
src/Group.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include "Group.h"
|
||||
|
||||
#include <mqtt.h>
|
||||
|
||||
Group groups[500];
|
||||
|
||||
Group *groupCache(KnxTelegram *telegram) {
|
||||
for (auto &&group: groups) {
|
||||
if ((group.main == 0 && group.mid == 0 && group.sub == 0) || (group.main == telegram->getTargetMainGroup() && group.mid == telegram->getTargetMiddleGroup() && group.sub == telegram->getTargetSubGroup())) {
|
||||
group.main = telegram->getTargetMainGroup();
|
||||
group.mid = telegram->getTargetMiddleGroup();
|
||||
group.sub = telegram->getTargetSubGroup();
|
||||
group.timestamp = time(nullptr);
|
||||
group.value = static_cast<double>(telegram->get1ByteIntValue()) + telegram->get2ByteIntValue() + (telegram->get4BitDirectionValue() ? telegram->get4BitStepsValue() : -telegram->get4BitStepsValue()) + telegram->get2ByteFloatValue() + telegram->get4ByteFloatValue();
|
||||
return &group;
|
||||
}
|
||||
}
|
||||
mqttLogError("group cache full");
|
||||
return nullptr;
|
||||
}
|
||||
18
src/Group.h
18
src/Group.h
@ -1,6 +1,8 @@
|
||||
#ifndef GROUP_H
|
||||
#define GROUP_H
|
||||
|
||||
#include <KnxTpUart.h>
|
||||
|
||||
class Group {
|
||||
|
||||
public:
|
||||
@ -11,18 +13,14 @@ public:
|
||||
|
||||
uint8_t sub = 0;
|
||||
|
||||
uint8_t dpt = 0;
|
||||
time_t timestamp = 0;
|
||||
|
||||
static Group groups[500];
|
||||
|
||||
static void write(uint8_t main, uint8_t mid, uint8_t sub) {
|
||||
for (auto group: groups) {
|
||||
if (group.main == main && group.mid == mid && group.sub == sub) {
|
||||
group.
|
||||
}
|
||||
}
|
||||
}
|
||||
double value = 0;
|
||||
|
||||
};
|
||||
|
||||
extern Group groups[];
|
||||
|
||||
Group *groupCache(KnxTelegram *telegram);
|
||||
|
||||
#endif
|
||||
|
||||
9
src/http.cpp
Normal file
9
src/http.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
#include "http.h"
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
|
||||
AsyncWebServer server(80);
|
||||
|
||||
void httpSetup() {
|
||||
server.begin();
|
||||
}
|
||||
6
src/http.h
Normal file
6
src/http.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef HTTP_H
|
||||
#define HTTP_H
|
||||
|
||||
void httpSetup();
|
||||
|
||||
#endif
|
||||
45
src/knx.cpp
Normal file
45
src/knx.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include "knx.h"
|
||||
#include "Group.h"
|
||||
#include "wifi.h"
|
||||
#include "time_.h"
|
||||
#include "mqtt.h"
|
||||
|
||||
#include <KnxTpUart.h>
|
||||
|
||||
KnxTpUart knx(&Serial1, "15.15.20");
|
||||
|
||||
void sendGroup(Group *group);
|
||||
|
||||
void knxSetup() {
|
||||
Serial1.begin(19200, SERIAL_8E1);
|
||||
knx.uartReset();
|
||||
knx.setListenToBroadcasts(true);
|
||||
}
|
||||
|
||||
void knxLoop() {
|
||||
if (knx.serialEvent() != KNX_TELEGRAM) {
|
||||
return;
|
||||
}
|
||||
|
||||
KnxTelegram *telegram = knx.getReceivedTelegram();
|
||||
mqttLogInfo("received: %d/%d/%d", telegram->getTargetMainGroup(), telegram->getTargetMiddleGroup(), telegram->getTargetSubGroup());
|
||||
|
||||
Group *group = groupCache(telegram);
|
||||
sendGroup(group);
|
||||
}
|
||||
|
||||
void sendGroup(Group *group) {
|
||||
if (group == nullptr || !isTimeSet() || !isWiFiConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
correctTime(&group->timestamp);
|
||||
|
||||
char topic[64];
|
||||
snprintf(topic, sizeof topic, "knx/group/%d/%d/%d", group->main, group->mid, group->sub);
|
||||
|
||||
char payload[128];
|
||||
snprintf(payload, sizeof payload, "%d/%d/%d %lld %f", group->main, group->mid, group->sub, group->timestamp, group->value);
|
||||
|
||||
mqttPublish(topic, payload);
|
||||
}
|
||||
8
src/knx.h
Normal file
8
src/knx.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef KNX_H
|
||||
#define KNX_H
|
||||
|
||||
void knxSetup();
|
||||
|
||||
void knxLoop();
|
||||
|
||||
#endif
|
||||
65
src/main.cpp
65
src/main.cpp
@ -1,70 +1,25 @@
|
||||
#include <Arduino.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <KnxTpUart.h>
|
||||
#include <PubSubClient.h>
|
||||
|
||||
KnxTpUart knx(&Serial1, "15.15.20");
|
||||
|
||||
PubSubClient mqtt;
|
||||
|
||||
void knxSetup();
|
||||
|
||||
void knxLoop();
|
||||
|
||||
void mqttLoop();
|
||||
|
||||
void mqttSetup();
|
||||
|
||||
void wifiSetup();
|
||||
#include "knx.h"
|
||||
#include "wifi.h"
|
||||
#include "time_.h"
|
||||
#include "mqtt.h"
|
||||
#include "http.h"
|
||||
|
||||
void setup() {
|
||||
Serial.begin(112500);
|
||||
delay(500);
|
||||
Serial.begin(112500);
|
||||
Serial.print("\n\n\nStartup\n");
|
||||
knxSetup();
|
||||
wifiSetup();
|
||||
configTime("Europe/Berlin", "de.pool.ntp.org");
|
||||
timeSetup();
|
||||
mqttSetup();
|
||||
}
|
||||
|
||||
void wifiSetup() {
|
||||
WiFi.hostname("KnxEsp");
|
||||
WiFi.begin("HappyNet", "1Grausame!Sackratte7");
|
||||
while (WiFi.localIP() == 0UL) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
httpSetup();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
knxLoop();
|
||||
wifiLoop();
|
||||
timeLoop();
|
||||
mqttLoop();
|
||||
}
|
||||
|
||||
void mqttSetup() {
|
||||
mqtt.setServer("10.0.0.50", 1883);
|
||||
mqtt.setBufferSize(512);
|
||||
}
|
||||
|
||||
void mqttLoop() {
|
||||
if (!mqtt.loop()) {
|
||||
if (!mqtt.connect(WiFi.hostname().c_str())) {
|
||||
mqtt.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void knxSetup() {
|
||||
Serial1.begin(19200, SERIAL_8E1);
|
||||
knx.uartReset();
|
||||
knx.setListenToBroadcasts(true);
|
||||
}
|
||||
|
||||
void knxLoop() {
|
||||
auto type = knx.serialEvent();
|
||||
if (type != KNX_TELEGRAM) {
|
||||
return;
|
||||
}
|
||||
KnxTelegram *t = knx.getReceivedTelegram();
|
||||
Serial.printf("%3d / %3d / %3d len=%d, bool=%d\n", t->getTargetMainGroup(), t->getTargetMiddleGroup(), t->getTargetSubGroup(), t->getPayloadLength(), t->getBool());
|
||||
}
|
||||
|
||||
56
src/mqtt.cpp
Normal file
56
src/mqtt.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include "mqtt.h"
|
||||
#include "wifi.h"
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
|
||||
PubSubClient mqtt;
|
||||
|
||||
void mqttSetup() {
|
||||
mqtt.setServer("10.0.0.50", 1883);
|
||||
mqtt.setBufferSize(512);
|
||||
}
|
||||
|
||||
void mqttLoop() {
|
||||
if (!isWiFiConnected()) {
|
||||
mqtt.disconnect();
|
||||
} else if (!mqtt.loop()) {
|
||||
if (!mqtt.connect(WiFi.hostname().c_str())) {
|
||||
mqtt.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mqttPublish(const char *topic, const char *payload) {
|
||||
mqtt.publish(topic, payload);
|
||||
}
|
||||
|
||||
String getLogPrefix(const char *level) {
|
||||
tm info{};
|
||||
getLocalTime(&info);
|
||||
char buffer[20];
|
||||
snprintf(buffer, sizeof buffer, "%04d-%02d-%02d %02d:%02d:%02d %5s ", info.tm_year, info.tm_mon, info.tm_mday, info.tm_hour, info.tm_min, info.tm_sec, level);
|
||||
return {buffer};
|
||||
}
|
||||
|
||||
void mqttLog(const char *level, const char *format, va_list vl) {
|
||||
char message[400];
|
||||
vsnprintf(message, sizeof message, format, vl);
|
||||
const String topic = String("knx/log/") + level;
|
||||
const String payload = getLogPrefix(level) + message;
|
||||
mqttPublish(topic.c_str(), payload.c_str());
|
||||
}
|
||||
|
||||
void mqttLogInfo(const char *message, ...) {
|
||||
va_list vl;
|
||||
va_start(vl, message);
|
||||
mqttLog("info", message, vl);
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
void mqttLogError(const char *message, ...) {
|
||||
va_list vl;
|
||||
va_start(vl, message);
|
||||
mqttLog("og/error", message, vl);
|
||||
va_end(vl);
|
||||
}
|
||||
14
src/mqtt.h
Normal file
14
src/mqtt.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef MQTT_H
|
||||
#define MQTT_H
|
||||
|
||||
void mqttSetup();
|
||||
|
||||
void mqttLoop();
|
||||
|
||||
void mqttPublish(const char *topic, const char *payload);
|
||||
|
||||
void mqttLogInfo(const char *message, ...);
|
||||
|
||||
void mqttLogError(const char *message, ...);
|
||||
|
||||
#endif
|
||||
36
src/time_.cpp
Normal file
36
src/time_.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include "time_.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#define TIME_MIN 1728424800
|
||||
|
||||
bool hasTime = false;
|
||||
|
||||
time_t timeCorrection = 0;
|
||||
|
||||
void timeSetup() {
|
||||
configTime("Europe/Berlin", "de.pool.ntp.org");
|
||||
}
|
||||
|
||||
void timeLoop() {
|
||||
if (hasTime) {
|
||||
return;
|
||||
}
|
||||
const time_t now = time(nullptr);
|
||||
if (now >= TIME_MIN) {
|
||||
hasTime = true;
|
||||
timeCorrection = now - timeCorrection;
|
||||
} else {
|
||||
timeCorrection = now;
|
||||
}
|
||||
}
|
||||
|
||||
bool isTimeSet() {
|
||||
return hasTime;
|
||||
}
|
||||
|
||||
void correctTime(time_t *t) {
|
||||
if (*t > 0 && *t < TIME_MIN) {
|
||||
*t += timeCorrection;
|
||||
}
|
||||
}
|
||||
14
src/time_.h
Normal file
14
src/time_.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef MY_TIME_H
|
||||
#define MY_TIME_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
void timeSetup();
|
||||
|
||||
void timeLoop();
|
||||
|
||||
bool isTimeSet();
|
||||
|
||||
void correctTime(time_t *t);
|
||||
|
||||
#endif
|
||||
45
src/wifi.cpp
Normal file
45
src/wifi.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include "wifi.h"
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
|
||||
#define WIFI_TIMEOUT_MILLIS 20000
|
||||
|
||||
unsigned long wifiConnectBegin = 0;
|
||||
|
||||
bool wifiConnected = false;
|
||||
|
||||
bool isWiFiConnected() {
|
||||
return wifiConnected;
|
||||
}
|
||||
|
||||
void wifiSetup() {
|
||||
wifiConnected = false;
|
||||
WiFi.disconnect();
|
||||
yield();
|
||||
|
||||
wifiConnectBegin = millis();
|
||||
Serial.print("connecting wifi...\n");
|
||||
WiFi.hostname("KnxEsp");
|
||||
WiFi.begin("HappyNet", "1Grausame!Sackratte7");
|
||||
}
|
||||
|
||||
void wifiLoop() {
|
||||
if (!wifiConnected) {
|
||||
if (WiFi.localIP() == 0UL) {
|
||||
if (millis() - wifiConnectBegin > WIFI_TIMEOUT_MILLIS) {
|
||||
if (wifiConnectBegin != 0) {
|
||||
Serial.print("wifi timeout\n");
|
||||
}
|
||||
wifiSetup();
|
||||
}
|
||||
} else {
|
||||
Serial.print("wifi connected\n");
|
||||
wifiConnected = true;
|
||||
}
|
||||
} else {
|
||||
if (WiFi.localIP() == 0UL) {
|
||||
Serial.print("wifi disconnected\n");
|
||||
wifiSetup();
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/wifi.h
Normal file
14
src/wifi.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef WIFI_H
|
||||
#define WIFI_H
|
||||
|
||||
bool isWiFiConnected();
|
||||
|
||||
void wifiSetup();
|
||||
|
||||
void wifiLoop();
|
||||
|
||||
void timeLoop();
|
||||
|
||||
bool isTimeSet();
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user