[UNTESTED] Dallas, data-cache, debugLog
This commit is contained in:
parent
e0e80dedad
commit
35af48211e
@ -1,9 +1,10 @@
|
||||
#include <Arduino.h>
|
||||
#include "base.h"
|
||||
#include <Patrix.h>
|
||||
#include <wifi.h>
|
||||
#include <console.h>
|
||||
#include "mqtt.h"
|
||||
#include "log.h"
|
||||
#include "data.h"
|
||||
|
||||
void setup() {
|
||||
delay(500);
|
||||
@ -17,5 +18,6 @@ void setup() {
|
||||
void loop() {
|
||||
consoleLoop();
|
||||
mqttLoop();
|
||||
dataLoop();
|
||||
patrixLoop();
|
||||
}
|
||||
@ -1,6 +1,8 @@
|
||||
#ifndef SENSOR3_PATRIX_H
|
||||
#define SENSOR3_PATRIX_H
|
||||
|
||||
#include "base.h"
|
||||
|
||||
void patrixSetup();
|
||||
|
||||
void patrixLoop();
|
||||
|
||||
6
lib/patrix/base.h
Normal file
6
lib/patrix/base.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef SENSOR3_BASE_H
|
||||
#define SENSOR3_BASE_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#endif
|
||||
@ -50,6 +50,7 @@ void consoleHandle(const char *cmd) {
|
||||
info("CONSOLE", "reboot : reboot system");
|
||||
info("CONSOLE", "wifi : reconnect wifi");
|
||||
info("CONSOLE", "mqtt : reconnect mqtt");
|
||||
info("CONSOLE", "debug : toggle debug log");
|
||||
} else if (strcmp(cmd, "net") == 0) {
|
||||
info("CONSOLE", "MAC: %17s", WiFi.macAddress().c_str());
|
||||
info("CONSOLE", "IP: %17s", WiFi.localIP().toString().c_str());
|
||||
@ -68,6 +69,9 @@ void consoleHandle(const char *cmd) {
|
||||
} else if (strcmp(cmd, "mqtt") == 0) {
|
||||
info("CONSOLE", "Reconnecting MQTT...");
|
||||
mqttDisconnect();
|
||||
} else if (strcmp(cmd, "debug") == 0) {
|
||||
setDebugEnabled(!isDebugEnabled());
|
||||
info("CONSOLE", "DEBUG: %s", isDebugEnabled() ? "ON" : "OFF");
|
||||
} else {
|
||||
info("CONSOLE", "Unknown command: %s", cmd);
|
||||
}
|
||||
|
||||
44
lib/patrix/data.cpp
Normal file
44
lib/patrix/data.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include "data.h"
|
||||
#include "ArduinoJson.h"
|
||||
#include "mqtt.h"
|
||||
|
||||
#define ENTRY_COUNT 1500
|
||||
|
||||
struct Entry {
|
||||
const char *name = "";
|
||||
time_t timestamp = 0;
|
||||
double value = NAN;
|
||||
};
|
||||
|
||||
Entry data[ENTRY_COUNT];
|
||||
|
||||
Entry *dataRead = data;
|
||||
|
||||
Entry *dataWrite = data;
|
||||
|
||||
size_t dataCount = 0;
|
||||
|
||||
bool dataAdd(const char *name, const time_t timestamp, const double value) {
|
||||
if (dataCount >= ENTRY_COUNT) {
|
||||
return false;
|
||||
}
|
||||
dataWrite->name = name;
|
||||
dataWrite->timestamp = timestamp;
|
||||
dataWrite->value = value;
|
||||
dataWrite = (dataWrite - data + 1) % ENTRY_COUNT + data;
|
||||
dataCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
void dataLoop() {
|
||||
if (dataCount == 0) {
|
||||
return;
|
||||
}
|
||||
JsonDocument json;
|
||||
json["timestamp"] = dataRead->timestamp;
|
||||
json["value"] = dataRead->value;
|
||||
if (mqttPublishData(dataRead->name, json)) {
|
||||
dataRead = (dataRead - data + 1) % ENTRY_COUNT + data;
|
||||
dataCount--;
|
||||
}
|
||||
}
|
||||
10
lib/patrix/data.h
Normal file
10
lib/patrix/data.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef SENSOR3_DATA_H
|
||||
#define SENSOR3_DATA_H
|
||||
|
||||
#include "base.h"
|
||||
|
||||
bool dataAdd(const char *name, const time_t timestamp, const double value);
|
||||
|
||||
void dataLoop();
|
||||
|
||||
#endif
|
||||
@ -4,6 +4,8 @@
|
||||
|
||||
#define SEPARATOR " | "
|
||||
|
||||
bool debugEnabled = false;
|
||||
|
||||
void getDateTime(char *buffer, size_t size) {
|
||||
time_t now;
|
||||
time(&now);
|
||||
@ -23,7 +25,17 @@ void log(const char *level, const char *module, const char *format, ...) {
|
||||
va_end(vl);
|
||||
|
||||
const size_t len = Serial.print(datetime) + Serial.print(SEPARATOR) + Serial.print(module) + Serial.print(SEPARATOR) + Serial.print(level) + Serial.print(SEPARATOR) + Serial.print(message) + Serial.println();
|
||||
mqttLog(len, SEPARATOR, datetime, module, level, message);
|
||||
mqttPublishLog(len, SEPARATOR, datetime, module, level, message);
|
||||
}
|
||||
|
||||
void debug(const char *module, const char *format, ...) {
|
||||
if (!debugEnabled) {
|
||||
return;
|
||||
}
|
||||
va_list vl;
|
||||
va_start(vl, format);
|
||||
log("DEBUG", module, format, vl);
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
void info(const char *module, const char *format, ...) {
|
||||
@ -39,3 +51,11 @@ void error(const char *module, const char *format, ...) {
|
||||
log("ERROR", module, format, vl);
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
void setDebugEnabled(const bool enabled) {
|
||||
debugEnabled = enabled;
|
||||
}
|
||||
|
||||
bool isDebugEnabled() {
|
||||
return debugEnabled;
|
||||
}
|
||||
|
||||
@ -1,8 +1,14 @@
|
||||
#ifndef SENSOR3_LOG_H
|
||||
#define SENSOR3_LOG_H
|
||||
|
||||
void debug(const char *module, const char *format, ...);
|
||||
|
||||
void info(const char *module, const char *format, ...);
|
||||
|
||||
void error(const char *module, const char *format, ...);
|
||||
|
||||
void setDebugEnabled(bool enabled);
|
||||
|
||||
bool isDebugEnabled();
|
||||
|
||||
#endif
|
||||
|
||||
@ -8,32 +8,23 @@
|
||||
|
||||
#define CONNECT_TIMEOUT_MILLISECONDS 5000
|
||||
|
||||
#define TOPIC_LOG_FORMAT "log/%s"
|
||||
#define TOPIC_CMD_FORMAT "cmd/%s"
|
||||
#define TOPIC_DATA_FORMAT "data/%s/%s"
|
||||
|
||||
unsigned long mqttLastConnectTry = 0;
|
||||
|
||||
WiFiClient espClient;
|
||||
|
||||
PubSubClient mqtt(espClient);
|
||||
|
||||
char logTopic[32] = "log/UNSET";
|
||||
char logTopic[64] = "log/UNSET";
|
||||
|
||||
char cmdTopic[64] = "cmd/UNSET";
|
||||
|
||||
void mqttSetup() {
|
||||
snprintf(logTopic, sizeof logTopic, "%s/%s", "log", HOSTNAME);
|
||||
snprintf(cmdTopic, sizeof cmdTopic, "%s/%s", "cmd", HOSTNAME);
|
||||
}
|
||||
|
||||
void mqttLog(const size_t len, const char *separator, const char *datetime, const char *module, const char *level, const char *message) {
|
||||
if (mqtt.beginPublish(logTopic, len, false)) {
|
||||
mqtt.print(datetime);
|
||||
mqtt.print(separator);
|
||||
mqtt.print(module);
|
||||
mqtt.print(separator);
|
||||
mqtt.print(level);
|
||||
mqtt.print(separator);
|
||||
mqtt.print(message);
|
||||
mqtt.endPublish();
|
||||
}
|
||||
snprintf(logTopic, sizeof logTopic, TOPIC_LOG_FORMAT, HOSTNAME);
|
||||
snprintf(cmdTopic, sizeof cmdTopic, TOPIC_CMD_FORMAT, HOSTNAME);
|
||||
}
|
||||
|
||||
void mqttDisconnect() {
|
||||
@ -69,11 +60,26 @@ void mqttLoop() {
|
||||
mqtt.loop();
|
||||
}
|
||||
|
||||
bool mqttPublish(const char *topic, const JsonDocument &doc) {
|
||||
if (!mqtt.connected()) {
|
||||
return false;
|
||||
void mqttPublishLog(const size_t len, const char *separator, const char *datetime, const char *module, const char *level, const char *message) {
|
||||
if (mqtt.beginPublish(logTopic, len, false)) {
|
||||
mqtt.print(datetime);
|
||||
mqtt.print(separator);
|
||||
mqtt.print(module);
|
||||
mqtt.print(separator);
|
||||
mqtt.print(level);
|
||||
mqtt.print(separator);
|
||||
mqtt.print(message);
|
||||
mqtt.endPublish();
|
||||
}
|
||||
char buffer[512];
|
||||
const size_t size = serializeJson(doc, buffer);
|
||||
return mqtt.publish(topic, buffer, size);
|
||||
}
|
||||
|
||||
bool mqttPublishData(const char *name, const JsonDocument &doc) {
|
||||
if (mqtt.connected() != 0) {
|
||||
char topic[128];
|
||||
snprintf(topic, sizeof topic, TOPIC_DATA_FORMAT, HOSTNAME, name);
|
||||
char payload[512];
|
||||
const size_t size = serializeJson(doc, payload);
|
||||
return mqtt.publish(topic, payload, size);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -9,8 +9,8 @@ void mqttLoop();
|
||||
|
||||
void mqttDisconnect();
|
||||
|
||||
void mqttLog(size_t len, const char *separator, const char *datetime, const char *module, const char *level, const char *message);
|
||||
void mqttPublishLog(const size_t len, const char *separator, const char *datetime, const char *module, const char *level, const char *message);
|
||||
|
||||
bool mqttPublish(const char *topic, const JsonDocument &doc);
|
||||
bool mqttPublishData(const char *name, const JsonDocument &doc);
|
||||
|
||||
#endif
|
||||
|
||||
90
lib/patrix/sensors/Dallas.h
Normal file
90
lib/patrix/sensors/Dallas.h
Normal file
@ -0,0 +1,90 @@
|
||||
#ifndef SENSOR2_DALLAS_H
|
||||
#define SENSOR2_DALLAS_H
|
||||
|
||||
#include "wifi.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "OneWire.h"
|
||||
|
||||
#include "DallasTemperature.h"
|
||||
|
||||
#define DALLAS_TIMEOUT_MILLISECONDS 3000
|
||||
|
||||
class Dallas {
|
||||
|
||||
|
||||
private:
|
||||
|
||||
OneWire oneWire;
|
||||
|
||||
DallasTemperature sensors;
|
||||
|
||||
time_t timestamp = 0;
|
||||
|
||||
unsigned long lastMillis = 0;
|
||||
|
||||
bool converting = false;
|
||||
|
||||
bool converted = false;
|
||||
|
||||
bool first = true;
|
||||
|
||||
public:
|
||||
|
||||
explicit Dallas(int pin) : oneWire(pin), sensors(&oneWire) {
|
||||
sensors.begin();
|
||||
sensors.setWaitForConversion(false);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (converting) {
|
||||
if (sensors.isConversionComplete()) {
|
||||
if (first) {
|
||||
first = false;
|
||||
uint8_t count = sensors.getDeviceCount();
|
||||
if (count == 0) {
|
||||
error("DALLAS", "No devices found!");
|
||||
} else {
|
||||
debug("DALLAS", "Found %d devices:", count);
|
||||
uint64_t address;
|
||||
for (int index = 0; index < count; ++index) {
|
||||
sensors.getAddress((uint8_t *) &address, index);
|
||||
debug("DALLAS", " - 0x%016llX = %5.1f C", address, sensors.getTempC((uint8_t *) &address));
|
||||
}
|
||||
}
|
||||
}
|
||||
converting = false;
|
||||
converted = true;
|
||||
} else if (millis() - lastMillis > DALLAS_TIMEOUT_MILLISECONDS) {
|
||||
error("DALLAS", "Timeout!");
|
||||
converting = false;
|
||||
converted = false;
|
||||
}
|
||||
} else {
|
||||
sensors.requestTemperatures();
|
||||
timestamp = getTime();
|
||||
lastMillis = millis();
|
||||
converting = true;
|
||||
converted = false;
|
||||
}
|
||||
}
|
||||
|
||||
double read(uint64_t address) {
|
||||
float value = sensors.getTempC((uint8_t *) &address);
|
||||
if (value <= DEVICE_DISCONNECTED_C) {
|
||||
return NAN;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
time_t getTimestamp() const {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
bool isConverted() const {
|
||||
return converted;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
90
lib/patrix/sensors/DallasSensor.h
Normal file
90
lib/patrix/sensors/DallasSensor.h
Normal file
@ -0,0 +1,90 @@
|
||||
#ifndef SENSOR2_DALLAS_SENSOR_H
|
||||
#define SENSOR2_DALLAS_SENSOR_H
|
||||
|
||||
#include "base.h"
|
||||
#include "Dallas.h"
|
||||
#include "wifi.h"
|
||||
#include "mqtt.h"
|
||||
#include "data.h"
|
||||
|
||||
class DallasSensor {
|
||||
|
||||
private:
|
||||
|
||||
Dallas &sensors;
|
||||
|
||||
uint64_t address;
|
||||
|
||||
const char *name;
|
||||
|
||||
const double valueThreshold;
|
||||
|
||||
const time_t timeoutSec;
|
||||
|
||||
const time_t minIntervalSec;
|
||||
|
||||
double lastValue = NAN;
|
||||
|
||||
time_t lastTimestamp = 0;
|
||||
|
||||
double lastValidValue = NAN;
|
||||
|
||||
time_t lastValidTimestamp = 0;
|
||||
|
||||
public:
|
||||
|
||||
DallasSensor(Dallas &sensors, const uint64_t address, const char *name, const double valueThreshold, const time_t timeoutSec, const time_t minIntervalSec) :
|
||||
sensors(sensors),
|
||||
name(name),
|
||||
address(address),
|
||||
valueThreshold(valueThreshold),
|
||||
timeoutSec(timeoutSec),
|
||||
minIntervalSec(minIntervalSec) {
|
||||
// -
|
||||
}
|
||||
|
||||
void loop() {
|
||||
const time_t now = getTime();
|
||||
if (now - lastTimestamp > timeoutSec) {
|
||||
lastTimestamp = 0;
|
||||
lastValue = NAN;
|
||||
}
|
||||
if (sensors.isConverted()) {
|
||||
const double value = sensors.read(address);
|
||||
const time_t timestamp = sensors.getTimestamp();
|
||||
const bool doPublish = !isnan(value) && (abs(lastValue - value) >= valueThreshold || now - lastTimestamp >= minIntervalSec);
|
||||
if (doPublish) {
|
||||
dataAdd(name, timestamp, value);
|
||||
}
|
||||
lastValue = value;
|
||||
lastTimestamp = timestamp;
|
||||
if (!isnan(value)) {
|
||||
lastValidValue = value;
|
||||
lastValidTimestamp = timestamp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *getName() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
double getLastValue() const {
|
||||
return lastValue;
|
||||
}
|
||||
|
||||
time_t getLastTimestamp() const {
|
||||
return lastTimestamp;
|
||||
}
|
||||
|
||||
double getLastValidValue() const {
|
||||
return lastValidValue;
|
||||
}
|
||||
|
||||
time_t getLastValidTimestamp() const {
|
||||
return lastValidTimestamp;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,7 +1,7 @@
|
||||
#ifndef GAERBOX_WIFI_H
|
||||
#define GAERBOX_WIFI_H
|
||||
|
||||
#include <ctime>
|
||||
#include "base.h"
|
||||
|
||||
void wifiSetup();
|
||||
|
||||
|
||||
@ -11,5 +11,7 @@ monitor_port = /dev/ttyUSB0
|
||||
monitor_speed = 115200
|
||||
monitor_filters = esp32_exception_decoder
|
||||
build_flags = -D HOSTNAME=\"Fermenter\" -D WIFI_SSID=\"HappyNet\" -D WIFI_PKEY=\"1Grausame!Sackratte7\" -D OTA_PASSWORD=\"OtaAuthPatrixFermenter\" -D BOOT_DELAY=true
|
||||
lib_deps = knolleary/PubSubClient
|
||||
lib_deps = milesburton/DallasTemperature
|
||||
knolleary/PubSubClient
|
||||
bblanchon/ArduinoJson
|
||||
paulstoffregen/OneWire
|
||||
@ -1,9 +1,16 @@
|
||||
#include <Patrix.h>
|
||||
#include "sensors/Dallas.h"
|
||||
#include "sensors/DallasSensor.h"
|
||||
|
||||
Dallas dallas(2);
|
||||
|
||||
DallasSensor temperatur(dallas, 0xAA0121125E4A7528, "temperatur", 0.5, 5, 60); // TODO wrong address
|
||||
|
||||
void patrixSetup() {
|
||||
|
||||
}
|
||||
|
||||
void patrixLoop() {
|
||||
|
||||
dallas.loop();
|
||||
temperatur.loop();
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user