add mqtt module #2
7 changed files with 167 additions and 3 deletions
|
@ -42,6 +42,7 @@ lib_deps =
|
||||||
https://github.com/dsbaars/GxEPD2#universal_pin
|
https://github.com/dsbaars/GxEPD2#universal_pin
|
||||||
https://github.com/tzapu/WiFiManager.git#v2.0.17
|
https://github.com/tzapu/WiFiManager.git#v2.0.17
|
||||||
rblb/Nostrduino@1.2.8
|
rblb/Nostrduino@1.2.8
|
||||||
|
elims/PsychicMqttClient@^0.2.0
|
||||||
|
|
||||||
[env:lolin_s3_mini]
|
[env:lolin_s3_mini]
|
||||||
extends = btclock_base
|
extends = btclock_base
|
||||||
|
|
|
@ -100,6 +100,12 @@ void setup()
|
||||||
setupMiningPoolStatsFetchTask();
|
setupMiningPoolStatsFetchTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (preferences.getBool("mqttEnabled", DEFAULT_MQTT_ENABLED))
|
||||||
|
{
|
||||||
|
if (setupMqtt())
|
||||||
|
setupMqttTask();
|
||||||
|
}
|
||||||
|
|
||||||
setupButtonTask();
|
setupButtonTask();
|
||||||
setupOTA();
|
setupOTA();
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "PCA9685.h"
|
#include "PCA9685.h"
|
||||||
#include "BH1750.h"
|
#include "BH1750.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "lib/mqtt.hpp"
|
||||||
|
|
||||||
#define NTP_SERVER "pool.ntp.org"
|
#define NTP_SERVER "pool.ntp.org"
|
||||||
#define DEFAULT_TIME_OFFSET_SECONDS 3600
|
#define DEFAULT_TIME_OFFSET_SECONDS 3600
|
||||||
|
|
|
@ -62,6 +62,10 @@
|
||||||
#define DEFAULT_MINING_POOL_NAME "ocean"
|
#define DEFAULT_MINING_POOL_NAME "ocean"
|
||||||
#define DEFAULT_MINING_POOL_USER "38Qkkei3SuF1Eo45BaYmRHUneRD54yyTFy" // Random actual Ocean hasher
|
#define DEFAULT_MINING_POOL_USER "38Qkkei3SuF1Eo45BaYmRHUneRD54yyTFy" // Random actual Ocean hasher
|
||||||
|
|
||||||
|
#define DEFAULT_MQTT_ENABLED false
|
||||||
|
#define DEFAULT_MQTT_URL ""
|
||||||
|
#define DEFAULT_MQTT_ROOTTOPIC "home/"
|
||||||
|
|
||||||
#define DEFAULT_ZAP_NOTIFY_ENABLED false
|
#define DEFAULT_ZAP_NOTIFY_ENABLED false
|
||||||
#define DEFAULT_ZAP_NOTIFY_PUBKEY "b5127a08cf33616274800a4387881a9f98e04b9c37116e92de5250498635c422"
|
#define DEFAULT_ZAP_NOTIFY_PUBKEY "b5127a08cf33616274800a4387881a9f98e04b9c37116e92de5250498635c422"
|
||||||
#define DEFAULT_LED_FLASH_ON_ZAP true
|
#define DEFAULT_LED_FLASH_ON_ZAP true
|
||||||
|
|
131
src/lib/mqtt.cpp
Normal file
131
src/lib/mqtt.cpp
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
#include "mqtt.hpp"
|
||||||
|
|
||||||
|
TaskHandle_t mqttTaskHandle = NULL;
|
||||||
|
|
||||||
|
// WiFiClient wifiClient;
|
||||||
|
//PubSubClient client(wifiClient);
|
||||||
|
PsychicMqttClient mqttClient;
|
||||||
|
|
||||||
|
// avoid circular deps, just forward declare externs used here.
|
||||||
|
#ifdef HAS_FRONTLIGHT
|
||||||
|
bool hasLightLevel();
|
||||||
|
float getLightLevel();
|
||||||
|
#endif
|
||||||
|
String getMyHostname();
|
||||||
|
|
||||||
|
void onMqttCallback(char* topic, byte* payload, unsigned int length)
|
||||||
|
{
|
||||||
|
Serial.println("MQTT message arrived");
|
||||||
|
}
|
||||||
|
|
||||||
|
const String getDeviceTopic()
|
||||||
|
{
|
||||||
|
const String hostname = getMyHostname();
|
||||||
|
const String rootTopic = preferences.getString("mqttRootTopic", DEFAULT_MQTT_ROOTTOPIC);
|
||||||
|
String fullTopic = rootTopic;
|
||||||
|
if (!rootTopic.endsWith("/") && rootTopic != "")
|
||||||
|
{
|
||||||
|
fullTopic += "/";
|
||||||
|
}
|
||||||
|
fullTopic += hostname + "/";
|
||||||
|
|
||||||
|
return String(fullTopic);
|
||||||
|
}
|
||||||
|
|
||||||
|
// boolean connectMqtt()
|
||||||
|
// {
|
||||||
|
// const String willTopic = getDeviceTopic() + "status";
|
||||||
|
// mqttClient.connect()
|
||||||
|
// boolean result = client.connect("btclockClient", willTopic.c_str(), 0, true, "offline");
|
||||||
|
// if (!result)
|
||||||
|
// {
|
||||||
|
// Serial.println("[MQTT] could not connect");
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
// publish("status", "online", true);
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
boolean setupMqtt()
|
||||||
|
{
|
||||||
|
const String url = preferences.getString("mqttUrl", DEFAULT_MQTT_URL);
|
||||||
|
if (url == "")
|
||||||
|
{
|
||||||
|
Serial.println("[MQTT] url not set");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Serial.print("[MQTT] url: ");
|
||||||
|
Serial.println(url.c_str());
|
||||||
|
|
||||||
|
mqttClient.setClientId(getMyHostname().c_str());
|
||||||
|
mqttClient.setServer(url.c_str());
|
||||||
|
// if (url.startsWith("mqtts:") || url.startsWith("wss:"))
|
||||||
|
// mqttClient.attachArduinoCACertBundle();
|
||||||
|
mqttClient.connect();
|
||||||
|
|
||||||
|
const String willTopic = getDeviceTopic() + "status";
|
||||||
|
mqttClient.setWill(willTopic.c_str(), 0, 1, "offline");
|
||||||
|
publish("status", "online", true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqttTask(void *pvParameters)
|
||||||
|
{
|
||||||
|
int t=0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
// client.loop();
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
if (t++ % 10 == 0)
|
||||||
|
{
|
||||||
|
#ifdef HAS_FRONTLIGHT
|
||||||
|
if (hasLightLevel())
|
||||||
|
{
|
||||||
|
std::string lux_s = std::to_string(static_cast<int>(std::round(getLightLevel())));
|
||||||
|
publish("sensors/lux", lux_s.c_str());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (WiFi.isConnected())
|
||||||
|
{
|
||||||
|
int8_t rssi = WiFi.RSSI();
|
||||||
|
std::string rssi_s = std::to_string(static_cast<int>(rssi));
|
||||||
|
publish("wifi/rssi", rssi_s.c_str());
|
||||||
|
publish("wifi/bssid", WiFi.BSSIDstr().c_str());
|
||||||
|
}
|
||||||
|
std::string heap_free_s = std::to_string(static_cast<int>(ESP.getFreeHeap()));
|
||||||
|
publish("mem/heap_free", heap_free_s.c_str());
|
||||||
|
std::string heap_size_s = std::to_string(static_cast<int>(ESP.getHeapSize()));
|
||||||
|
publish("mem/heap_size", heap_size_s.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupMqttTask()
|
||||||
|
{
|
||||||
|
xTaskCreate(mqttTask, "mqttTask", 8192, NULL, 10, &mqttTaskHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void publishForDevice(const char *topic, const char *payload)
|
||||||
|
{
|
||||||
|
publishForDevice(topic, payload, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void publishForDevice(const char *topic, const char *payload, boolean retain)
|
||||||
|
{
|
||||||
|
const String fullTopic = getDeviceTopic() + topic;
|
||||||
|
publish(fullTopic.c_str(), payload, retain);
|
||||||
|
}
|
||||||
|
|
||||||
|
void publish(const char *topic, const char *payload)
|
||||||
|
{
|
||||||
|
publish(topic, payload, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void publish(const char *topic, const char *payload, boolean retain)
|
||||||
|
{
|
||||||
|
if (!mqttClient.publish(topic, 0, retain, payload))
|
||||||
|
{
|
||||||
|
Serial.println("[MQTT] could not write");
|
||||||
|
}
|
||||||
|
}
|
13
src/lib/mqtt.hpp
Normal file
13
src/lib/mqtt.hpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <WiFiClientSecure.h>
|
||||||
|
#include <PsychicMqttClient.h>
|
||||||
|
#include "lib/shared.hpp"
|
||||||
|
|
||||||
|
boolean setupMqtt();
|
||||||
|
void setupMqttTask();
|
||||||
|
void publishForDevice(const char *topic, const char *payload);
|
||||||
|
void publishForDevice(const char *topic, const char *payload, boolean retain);
|
||||||
|
void publish(const char *topic, const char *payload);
|
||||||
|
void publish(const char *topic, const char *payload, boolean retain);
|
|
@ -510,7 +510,10 @@ void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json)
|
||||||
settings["timePerScreen"].as<uint>() * 60);
|
settings["timePerScreen"].as<uint>() * 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
String strSettings[] = {"hostnamePrefix", "mempoolInstance", "nostrPubKey", "nostrRelay", "bitaxeHostname", "miningPoolName", "miningPoolUser", "nostrZapPubkey", "httpAuthUser", "httpAuthPass", "gitReleaseUrl"};
|
String strSettings[] = {"hostnamePrefix", "mempoolInstance", "nostrPubKey",
|
||||||
|
"nostrRelay", "bitaxeHostname", "nostrZapPubkey",
|
||||||
|
"httpAuthUser", "httpAuthPass", "gitReleaseUrl",
|
||||||
|
"mqttUrl", "mqttRootTopic"};
|
||||||
|
|
||||||
for (String setting : strSettings)
|
for (String setting : strSettings)
|
||||||
{
|
{
|
||||||
|
@ -549,7 +552,7 @@ void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json)
|
||||||
"mowMode", "suffixShareDot", "flOffWhenDark",
|
"mowMode", "suffixShareDot", "flOffWhenDark",
|
||||||
"flAlwaysOn", "flDisable", "flFlashOnUpd",
|
"flAlwaysOn", "flDisable", "flFlashOnUpd",
|
||||||
"mempoolSecure", "useNostr", "bitaxeEnabled",
|
"mempoolSecure", "useNostr", "bitaxeEnabled",
|
||||||
"miningPoolStats", "verticalDesc",
|
"miningPoolStats", "verticalDesc", "mqttEnabled",
|
||||||
"nostrZapNotify", "stagingSource", "httpAuthEnabled"};
|
"nostrZapNotify", "stagingSource", "httpAuthEnabled"};
|
||||||
|
|
||||||
for (String setting : boolSettings)
|
for (String setting : boolSettings)
|
||||||
|
@ -718,6 +721,11 @@ void onApiSettingsGet(AsyncWebServerRequest *request)
|
||||||
root["miningPoolName"] = preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME);
|
root["miningPoolName"] = preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME);
|
||||||
root["miningPoolUser"] = preferences.getString("miningPoolUser", DEFAULT_MINING_POOL_USER);
|
root["miningPoolUser"] = preferences.getString("miningPoolUser", DEFAULT_MINING_POOL_USER);
|
||||||
root["availablePools"] = PoolFactory::getAvailablePools();
|
root["availablePools"] = PoolFactory::getAvailablePools();
|
||||||
|
|
||||||
|
root["mqttEnabled"] = preferences.getBool("mqttEnabled", DEFAULT_MQTT_ENABLED);
|
||||||
|
root["mqttUrl"] = preferences.getString("mqttUrl", DEFAULT_MQTT_URL);
|
||||||
|
root["mqttRootTopic"] = preferences.getString("mqttRootTopic", DEFAULT_MQTT_ROOTTOPIC);
|
||||||
|
|
||||||
root["httpAuthEnabled"] = preferences.getBool("httpAuthEnabled", DEFAULT_HTTP_AUTH_ENABLED);
|
root["httpAuthEnabled"] = preferences.getBool("httpAuthEnabled", DEFAULT_HTTP_AUTH_ENABLED);
|
||||||
root["httpAuthUser"] = preferences.getString("httpAuthUser", DEFAULT_HTTP_AUTH_USERNAME);
|
root["httpAuthUser"] = preferences.getString("httpAuthUser", DEFAULT_HTTP_AUTH_USERNAME);
|
||||||
root["httpAuthPass"] = preferences.getString("httpAuthPass", DEFAULT_HTTP_AUTH_PASSWORD);
|
root["httpAuthPass"] = preferences.getString("httpAuthPass", DEFAULT_HTTP_AUTH_PASSWORD);
|
||||||
|
|
Loading…
Reference in a new issue