Compare commits

...

2 Commits

Author SHA1 Message Date
Siwat Sirichai 4c77474a94 fixed climate card mqtt crash bug 2023-12-31 23:29:40 +07:00
Siwat Sirichai 9cd5b7132b mqtt_dbg 2023-12-31 20:49:22 +07:00
8 changed files with 147 additions and 50 deletions

View File

@ -9,12 +9,16 @@ ClimateIoT::~ClimateIoT() {
} }
bool ClimateIoT::begin(uint8_t card_id, ExpansionCard *card, PubSubClient *mqtt, char *base_topic) { bool ClimateIoT::begin(uint8_t card_id, ExpansionCard *card, PubSubClient *mqtt, char *base_topic) {
this->mqtt = mqtt;
this->base_topic = base_topic;
this->card_id = card_id;
this->card = (ClimateCard *)card; this->card = (ClimateCard *)card;
// Reister Callbacks // Reister Callbacks
auto bindedSensorCallback = std::bind(&ClimateIoT::handleSensorUpdate, this, std::placeholders::_1, std::placeholders::_2); auto bindedSensorCallback = std::bind(&ClimateIoT::handleSensorUpdate, this, std::placeholders::_1, std::placeholders::_2);
this->card->registerSensorCallback(bindedSensorCallback); this->card->registerSensorCallback(bindedSensorCallback);
auto bindedAirConditionerCallback = std::bind(&ClimateIoT::handleAirConditionerUpdate, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); auto bindedAirConditionerCallback = std::bind(&ClimateIoT::handleAirConditionerUpdate, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
this->card->registerChangeCallback(bindedAirConditionerCallback); this->card->registerChangeCallback(bindedAirConditionerCallback);
ESP_LOGD("ClimateIoT", "Climate IoT Component initialized");
return true; return true;
} }
@ -83,9 +87,11 @@ void ClimateIoT::publishReport() {
} }
void ClimateIoT::subscribe() { void ClimateIoT::subscribe() {
ESP_LOGD("ClimateIoT", " topics");
this->subscribeRelative(AC_TEMPERATURE_SET_TOPIC); this->subscribeRelative(AC_TEMPERATURE_SET_TOPIC);
this->subscribeRelative(AC_MODE_SET_TOPIC); this->subscribeRelative(AC_MODE_SET_TOPIC);
this->subscribeRelative(AC_FAN_SPEED_SET_TOPIC); this->subscribeRelative(AC_FAN_SPEED_SET_TOPIC);
ESP_LOGD("ClimateIoT", "Subscribed to topics");
} }
void ClimateIoT::loop() { void ClimateIoT::loop() {

View File

@ -13,9 +13,7 @@ bool DigitalInputIoT::begin(uint8_t card_id, ExpansionCard *card, PubSubClient *
} }
void DigitalInputIoT::subscribe() { void DigitalInputIoT::subscribe() {
char topic[64]; this->subscribeRelative(PUBLISH_ENABLE_TOPIC);
sprintf(topic, "%s/%d/%s", this->base_topic, this->card_id, PUBLISH_ENABLE_TOPIC);
this->subscribeRelative(topic);
} }
void DigitalInputIoT::handleMqttMessage(char *topic, char *payload) { void DigitalInputIoT::handleMqttMessage(char *topic, char *payload) {

View File

@ -3,7 +3,7 @@
ESPMegaIoT::ESPMegaIoT() : mqtt(tcpClient) ESPMegaIoT::ESPMegaIoT() : mqtt(tcpClient)
{ {
tcpClient.setTimeout(1); tcpClient.setTimeout(TCP_TIMEOUT_SEC);
// Initialize the components array // Initialize the components array
for (int i = 0; i < 255; i++) for (int i = 0; i < 255; i++)
{ {
@ -11,9 +11,6 @@ ESPMegaIoT::ESPMegaIoT() : mqtt(tcpClient)
} }
active = false; active = false;
mqtt_connected = false; mqtt_connected = false;
this->user_mqtt_callback = nullptr;
this->user_relative_mqtt_callback = nullptr;
this->user_subscribe_callback = nullptr;
} }
ESPMegaIoT::~ESPMegaIoT() ESPMegaIoT::~ESPMegaIoT()
@ -26,14 +23,14 @@ void ESPMegaIoT::mqttCallback(char *topic, byte *payload, unsigned int length)
memcpy(payload_buffer, payload, length); memcpy(payload_buffer, payload, length);
payload_buffer[length] = '\0'; payload_buffer[length] = '\0';
// Remove the base topic from the topic // Remove the base topic from the topic
char *topic_without_base = topic + strlen(base_topic) + 1; char *topic_without_base = topic + strlen(this->mqtt_config.base_topic) + 1;
if (user_relative_mqtt_callback != NULL) for (const auto &callback : mqtt_relative_callbacks)
{ {
user_relative_mqtt_callback(topic_without_base + 3, payload_buffer); callback.second(topic_without_base + 3, payload_buffer);
} }
if (user_mqtt_callback != NULL) for (const auto &callback : mqtt_callbacks)
{ {
user_mqtt_callback(topic, payload_buffer); callback.second(topic, payload_buffer);
} }
// Call the respective card's mqtt callback // Call the respective card's mqtt callback
// Note that after the base topic, there should be the card id // Note that after the base topic, there should be the card id
@ -51,8 +48,8 @@ void ESPMegaIoT::mqttCallback(char *topic, byte *payload, unsigned int length)
void ESPMegaIoT::setBaseTopic(char *base_topic) void ESPMegaIoT::setBaseTopic(char *base_topic)
{ {
strcpy(this->base_topic, base_topic); strcpy(this->mqtt_config.base_topic, base_topic);
base_topic_length = strlen(base_topic); base_topic_length = strlen(this->mqtt_config.base_topic);
} }
void ESPMegaIoT::intr_begin(ExpansionCard *cards[]) void ESPMegaIoT::intr_begin(ExpansionCard *cards[])
@ -91,7 +88,7 @@ void ESPMegaIoT::registerCard(uint8_t card_id)
{ {
case CARD_TYPE_ANALOG: case CARD_TYPE_ANALOG:
components[card_id] = new AnalogIoT(); components[card_id] = new AnalogIoT();
components[card_id]->begin(card_id, cards[card_id], &mqtt, base_topic); components[card_id]->begin(card_id, cards[card_id], &mqtt, this->mqtt_config.base_topic);
if (mqtt_connected) if (mqtt_connected)
{ {
components[card_id]->subscribe(); components[card_id]->subscribe();
@ -100,16 +97,22 @@ void ESPMegaIoT::registerCard(uint8_t card_id)
break; break;
case CARD_TYPE_DIGITAL_INPUT: case CARD_TYPE_DIGITAL_INPUT:
components[card_id] = new DigitalInputIoT(); components[card_id] = new DigitalInputIoT();
components[card_id]->begin(card_id, cards[card_id], &mqtt, base_topic); components[card_id]->begin(card_id, cards[card_id], &mqtt, this->mqtt_config.base_topic);
if (mqtt_connected) if (mqtt_connected)
{ {
Serial.println("Subscribing to Input Topics");
components[card_id]->subscribe(); components[card_id]->subscribe();
mqtt.loop();
Serial.println(mqtt.connected()? "MQTT Connected" : "MQTT Not Connected");
Serial.println("Publishing Input report");
components[card_id]->publishReport(); components[card_id]->publishReport();
mqtt.loop();
Serial.println(mqtt.connected()? "MQTT Connected" : "MQTT Not Connected");
} }
break; break;
case CARD_TYPE_DIGITAL_OUTPUT: case CARD_TYPE_DIGITAL_OUTPUT:
components[card_id] = new DigitalOutputIoT(); components[card_id] = new DigitalOutputIoT();
components[card_id]->begin(card_id, cards[card_id], &mqtt, base_topic); components[card_id]->begin(card_id, cards[card_id], &mqtt, this->mqtt_config.base_topic);
if (mqtt_connected) if (mqtt_connected)
{ {
components[card_id]->subscribe(); components[card_id]->subscribe();
@ -118,7 +121,7 @@ void ESPMegaIoT::registerCard(uint8_t card_id)
break; break;
case CARD_TYPE_CLIMATE: case CARD_TYPE_CLIMATE:
components[card_id] = new ClimateIoT(); components[card_id] = new ClimateIoT();
components[card_id]->begin(card_id, cards[card_id], &mqtt, base_topic); components[card_id]->begin(card_id, cards[card_id], &mqtt, this->mqtt_config.base_topic);
if (mqtt_connected) if (mqtt_connected)
{ {
components[card_id]->subscribe(); components[card_id]->subscribe();
@ -238,27 +241,33 @@ void ESPMegaIoT::disconnectFromMqtt()
{ {
mqtt.disconnect(); mqtt.disconnect();
} }
void ESPMegaIoT::publishToTopic(char *topic, char *payload) void ESPMegaIoT::publish(const char *topic, const char *payload)
{ {
mqtt.publish(topic, payload); mqtt.publish(topic, payload);
} }
void ESPMegaIoT::registerMqttCallback(void (*callback)(char *, char *))
uint8_t ESPMegaIoT::registerMqttCallback(std::function<void(char *, char *)> callback)
{ {
user_mqtt_callback = callback; mqtt_callbacks[mqtt_callbacks_handler_index] = callback;
return mqtt_callbacks_handler_index++;
} }
void ESPMegaIoT::unregisterMqttCallback(uint8_t handler)
{
mqtt_callbacks.erase(handler);
}
void ESPMegaIoT::mqttSubscribe() void ESPMegaIoT::mqttSubscribe()
{ {
ESP_LOGD("ESPMegaIoT", "Begin MQTT Subscription"); ESP_LOGD("ESPMegaIoT", "Begin MQTT Subscription");
if (user_subscribe_callback != nullptr) for (const auto &callback : subscribe_callbacks)
{ {
ESP_LOGD("ESPMegaIoT", "Subscribing user callback"); callback.second();
user_subscribe_callback();
mqtt.loop(); mqtt.loop();
} }
// Subscribe to all topics // Subscribe to all topics
for (int i = 0; i < 255; i++) for (int i = 0; i < 255; i++)
{ {
ESP_LOGV("ESPMegaIoT","Scanning component %d", i);
if (components[i] != NULL) if (components[i] != NULL)
{ {
ESP_LOGD("ESPMegaIoT","Subscribing component %d", i); ESP_LOGD("ESPMegaIoT","Subscribing component %d", i);
@ -271,7 +280,7 @@ void ESPMegaIoT::mqttSubscribe()
void ESPMegaIoT::publishRelative(uint8_t card_id, char *topic, char *payload) void ESPMegaIoT::publishRelative(uint8_t card_id, char *topic, char *payload)
{ {
char absolute_topic[100]; char absolute_topic[100];
sprintf(absolute_topic, "%s/%d/%s", base_topic, card_id, topic); sprintf(absolute_topic, "%s/%d/%s", this->mqtt_config.base_topic, card_id, topic);
mqtt.publish(absolute_topic, payload); mqtt.publish(absolute_topic, payload);
} }
@ -289,28 +298,45 @@ bool ESPMegaIoT::mqttReconnect()
void ESPMegaIoT::sessionKeepAlive() void ESPMegaIoT::sessionKeepAlive()
{ {
// This reconnect the MQTT if it disconnect.
// If a disconnect happens, this will reconnect the MQTT within 1 second.
// A connection attempt will be made at most once every MQTT_RECONNECT_INTERVAL
// This have the effect of reconnecting to the server immediately if the connection is lost
// and the connection was previously stable for at least MQTT_RECONNECT_INTERVAL
// But will not reconnect if the connection was unstable and the connection was lost
static unsigned long lastSessionKeepAlive = 0; static unsigned long lastSessionKeepAlive = 0;
if (millis() - lastSessionKeepAlive > 30000) static unsigned long lastConnectionAttempt = 0;
if (millis() - lastSessionKeepAlive > 1000)
{ {
lastSessionKeepAlive = millis(); lastSessionKeepAlive = millis();
// Check if mqtt is connected // Check if mqtt is connected
if (!mqtt.connected()) if (!mqtt.connected())
{ {
// Try to reconnect // Try to reconnect if lastConnectionAttempt exceed MQTT_RECONNECT_INTERVAL
if (millis() - lastConnectionAttempt > MQTT_RECONNECT_INTERVAL)
{
lastConnectionAttempt = millis();
mqtt_connected = mqttReconnect(); mqtt_connected = mqttReconnect();
} }
} }
} }
}
void ESPMegaIoT::registerRelativeMqttCallback(void (*callback)(char *, char *)) uint8_t ESPMegaIoT::registerRelativeMqttCallback(std::function<void(char *, char *)> callback)
{ {
user_relative_mqtt_callback = callback; mqtt_relative_callbacks[mqtt_relative_callbacks_handler_index] = callback;
return mqtt_relative_callbacks_handler_index++;
}
void ESPMegaIoT::unregisterRelativeMqttCallback(uint8_t handler)
{
mqtt_relative_callbacks.erase(handler);
} }
void ESPMegaIoT::publishRelative(char *topic, char *payload) void ESPMegaIoT::publishRelative(char *topic, char *payload)
{ {
char absolute_topic[100]; char absolute_topic[100];
sprintf(absolute_topic, "%s/%s", base_topic, topic); sprintf(absolute_topic, "%s/%s", this->mqtt_config.base_topic, topic);
mqtt.publish(absolute_topic, payload); mqtt.publish(absolute_topic, payload);
mqtt.loop(); mqtt.loop();
} }
@ -318,14 +344,20 @@ void ESPMegaIoT::publishRelative(char *topic, char *payload)
void ESPMegaIoT::subscribeRelative(char *topic) void ESPMegaIoT::subscribeRelative(char *topic)
{ {
char absolute_topic[100]; char absolute_topic[100];
sprintf(absolute_topic, "%s/%s", base_topic, topic); sprintf(absolute_topic, "%s/%s", this->mqtt_config.base_topic, topic);
mqtt.subscribe(absolute_topic); mqtt.subscribe(absolute_topic);
mqtt.loop(); mqtt.loop();
} }
void ESPMegaIoT::registerSubscribeCallback(void (*callback)(void)) uint8_t ESPMegaIoT::registerSubscribeCallback(std::function<void(void)> callback)
{ {
user_subscribe_callback = callback; subscribe_callbacks[subscribe_callbacks_handler_index] = callback;
return subscribe_callbacks_handler_index++;
}
void ESPMegaIoT::unregisterSubscribeCallback(uint8_t handler)
{
subscribe_callbacks.erase(handler);
} }
void ESPMegaIoT::setNetworkConfig(NetworkConfig network_config) void ESPMegaIoT::setNetworkConfig(NetworkConfig network_config)
@ -380,6 +412,7 @@ void ESPMegaIoT::loadMqttConfig()
fram->read(IOT_FRAM_ADDRESS + 194, (uint8_t *)mqtt_config.mqtt_password, 32); fram->read(IOT_FRAM_ADDRESS + 194, (uint8_t *)mqtt_config.mqtt_password, 32);
mqtt_config.mqtt_useauth = fram->read8(IOT_FRAM_ADDRESS + 226); mqtt_config.mqtt_useauth = fram->read8(IOT_FRAM_ADDRESS + 226);
fram->read(IOT_FRAM_ADDRESS + 227, (uint8_t *)mqtt_config.base_topic, 32); fram->read(IOT_FRAM_ADDRESS + 227, (uint8_t *)mqtt_config.base_topic, 32);
this->base_topic_length = strlen(mqtt_config.base_topic);
} }
void ESPMegaIoT::saveMqttConfig() void ESPMegaIoT::saveMqttConfig()
@ -430,6 +463,7 @@ void ESPMegaIoT::connectNetwork()
void ESPMegaIoT::setMqttConfig(MqttConfig mqtt_config) void ESPMegaIoT::setMqttConfig(MqttConfig mqtt_config)
{ {
this->mqtt_config = mqtt_config; this->mqtt_config = mqtt_config;
this->base_topic_length = strlen(mqtt_config.base_topic);
} }
void ESPMegaIoT::bindEthernetInterface(ETHClass *ethernetIface) void ESPMegaIoT::bindEthernetInterface(ETHClass *ethernetIface)
@ -454,7 +488,8 @@ MqttConfig *ESPMegaIoT::getMqttConfig()
bool ESPMegaIoT::mqttConnected() bool ESPMegaIoT::mqttConnected()
{ {
return mqtt_connected; //return mqtt_connected;
return mqtt.connected();
} }
bool ESPMegaIoT::networkConnected() bool ESPMegaIoT::networkConnected()

View File

@ -13,6 +13,10 @@
#include <ETH.h> #include <ETH.h>
#include <WiFi.h> #include <WiFi.h>
#include <FRAM.h> #include <FRAM.h>
#include <map>
#define TCP_TIMEOUT_SEC 5
#define MQTT_RECONNECT_INTERVAL 30000
// FRAM Address for ESPMegaPROIoT // FRAM Address for ESPMegaPROIoT
// Starts from 34 // Starts from 34
@ -80,10 +84,13 @@ public:
bool connectToMqtt(char *client_id, char *mqtt_server, uint16_t mqtt_port); bool connectToMqtt(char *client_id, char *mqtt_server, uint16_t mqtt_port);
bool mqttConnected(); bool mqttConnected();
void disconnectFromMqtt(); void disconnectFromMqtt();
void publishToTopic(char *topic, char *payload); void publish(const char *topic, const char *payload);
void registerMqttCallback(void (*callback)(char *, char *)); uint8_t registerMqttCallback(std::function<void(char *, char *)> callback);
void registerRelativeMqttCallback(void (*callback)(char *, char *)); void unregisterMqttCallback(uint8_t handler);
void registerSubscribeCallback(void (*callback)(void)); uint8_t registerRelativeMqttCallback(std::function<void(char *, char *)> callback);
void unregisterRelativeMqttCallback(uint8_t handler);
uint8_t registerSubscribeCallback(std::function<void(void)> callback);
void unregisterSubscribeCallback(uint8_t handler);
void setBaseTopic(char *base_topic); void setBaseTopic(char *base_topic);
void bindEthernetInterface(ETHClass *ethernetIface); void bindEthernetInterface(ETHClass *ethernetIface);
bool networkConnected(); bool networkConnected();
@ -104,15 +111,17 @@ private:
void wifiReconnect(); void wifiReconnect();
void mqttSubscribe(); void mqttSubscribe();
void mqttCallback(char *topic, byte *payload, unsigned int length); void mqttCallback(char *topic, byte *payload, unsigned int length);
void (*user_mqtt_callback)(char *, char *); uint8_t mqtt_callbacks_handler_index;
void (*user_relative_mqtt_callback)(char *, char *); uint8_t mqtt_relative_callbacks_handler_index;
void (*user_subscribe_callback)(void); uint8_t subscribe_callbacks_handler_index;
std::map<uint8_t, std::function<void(char*, char*)>> mqtt_callbacks;
std::map<uint8_t, std::function<void(char*, char*)>> mqtt_relative_callbacks;
std::map<uint8_t, std::function<void(void)>> subscribe_callbacks;
void publishRelative(uint8_t card_id, char *topic, char *payload); void publishRelative(uint8_t card_id, char *topic, char *payload);
bool active; bool active;
PubSubClient mqtt; PubSubClient mqtt;
IoTComponent *components[255]; IoTComponent *components[255];
char payload_buffer[200]; char payload_buffer[200];
char base_topic[100];
uint8_t base_topic_length; uint8_t base_topic_length;
ExpansionCard **cards; // Points to card array in ESPMegaPRO Core ExpansionCard **cards; // Points to card array in ESPMegaPRO Core
// MQTT Connection Parameters // MQTT Connection Parameters

View File

@ -5,15 +5,19 @@ void IoTComponent::setMqttClient(PubSubClient *mqtt) {
} }
void IoTComponent::publishRelative(const char *topic, const char *payload) { void IoTComponent::publishRelative(const char *topic, const char *payload) {
char absolute_topic[100]; static char absolute_topic[100];
sprintf(absolute_topic, "%s/%02d/%s", base_topic, card_id, topic); sprintf(absolute_topic, "%s/%02d/%s", base_topic, card_id, topic);
mqtt->publish(absolute_topic, payload); mqtt->publish(absolute_topic, payload);
mqtt->loop();
delay(50);
} }
void IoTComponent::subscribeRelative(const char *topic) { void IoTComponent::subscribeRelative(const char *topic) {
char absolute_topic[50]; char absolute_topic[50];
sprintf(absolute_topic, "%s/%02d/%s", base_topic, card_id, topic); sprintf(absolute_topic, "%s/%02d/%s", base_topic, card_id, topic);
ESP_LOGD("IoTComponent", "Subscribing to %s", absolute_topic);
mqtt->subscribe(absolute_topic); mqtt->subscribe(absolute_topic);
mqtt->loop();
} }
void IoTComponent::loop() { void IoTComponent::loop() {

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <ExpansionCard.hpp> #include <ExpansionCard.hpp>
#include <PubSubClient.h> #include <PubSubClient.h>
#include <esp_log.h>
class IoTComponent { class IoTComponent {
public: public:
virtual bool begin(uint8_t card_id, ExpansionCard *card, PubSubClient *mqtt, char *base_topic); virtual bool begin(uint8_t card_id, ExpansionCard *card, PubSubClient *mqtt, char *base_topic);

View File

@ -31,4 +31,4 @@ lib_deps = adafruit/Adafruit PWM Servo Driver Library@^2.4.1
https://github.com/me-no-dev/ESPAsyncWebServer.git https://github.com/me-no-dev/ESPAsyncWebServer.git
#esphome/ESPAsyncWebServer-esphome@^3.1.0 #esphome/ESPAsyncWebServer-esphome@^3.1.0
monitor_speed = 115200 monitor_speed = 115200
build_flags = -DCORE_DEBUG_LEVEL=1 build_flags = -DCORE_DEBUG_LEVEL=5

View File

@ -4,10 +4,18 @@
#include <ClimateCard.hpp> #include <ClimateCard.hpp>
// #define FRAM_DEBUG // #define FRAM_DEBUG
#define MQTT_DEBUG
// #define WRITE_DEFAULT_NETCONF
#define CLIMATE_CARD_ENABLE
#define MQTT_CARD_REGISTER
#define DISPLAY_ENABLE
// Demo PLC firmware using the ESPMegaPRO OOP library // Demo PLC firmware using the ESPMegaPRO OOP library
ESPMegaPRO espmega = ESPMegaPRO(); ESPMegaPRO espmega = ESPMegaPRO();
#ifdef CLIMATE_CARD_ENABLE
// Climate Card
const uint16_t irCode[15][4][4][1] = {0}; const uint16_t irCode[15][4][4][1] = {0};
const char *mode_names[] = {"Off", "Fan-only", "Cool"}; const char *mode_names[] = {"Off", "Fan-only", "Cool"};
const char *fan_speed_names[] = {"Auto", "Low", "Medium", "High"}; const char *fan_speed_names[] = {"Auto", "Low", "Medium", "High"};
@ -29,6 +37,7 @@ AirConditioner ac = {
.getInfraredCode = &getInfraredCode}; .getInfraredCode = &getInfraredCode};
ClimateCard climateCard = ClimateCard(14, ac); ClimateCard climateCard = ClimateCard(14, ac);
#endif
void input_change_callback(uint8_t pin, uint8_t value) void input_change_callback(uint8_t pin, uint8_t value)
{ {
@ -38,14 +47,15 @@ void input_change_callback(uint8_t pin, uint8_t value)
Serial.println(value); Serial.println(value);
} }
#ifdef WRITE_DEFAULT_NETCONF
void setNetworkConfig() void setNetworkConfig()
{ {
NetworkConfig config = { NetworkConfig config = {
.ip = {192, 168, 0, 11}, .ip = {10, 16, 6, 213},
.gateway = {192, 168, 0, 1}, .gateway = {10, 16, 6, 1},
.subnet = {255, 255, 255, 0}, .subnet = {255, 255, 255, 0},
.dns1 = {192, 168, 0, 1}, .dns1 = {10, 192, 1, 1},
.dns2 = {192, 168, 0, 1}, .dns2 = {10, 192, 1, 1},
.useStaticIp = true, .useStaticIp = true,
.useWifi = false, .useWifi = false,
.wifiUseAuth = false, .wifiUseAuth = false,
@ -68,6 +78,7 @@ void setMqttConfig()
espmega.iot->setMqttConfig(config); espmega.iot->setMqttConfig(config);
espmega.iot->saveMqttConfig(); espmega.iot->saveMqttConfig();
} }
#endif
void setup() void setup()
{ {
@ -79,20 +90,31 @@ void setup()
ETH.begin(); ETH.begin();
ESP_LOGI("Initializer", "Binding Ethernet to IOT module"); ESP_LOGI("Initializer", "Binding Ethernet to IOT module");
espmega.iot->bindEthernetInterface(&ETH); espmega.iot->bindEthernetInterface(&ETH);
#ifdef WRITE_DEFAULT_NETCONF
setNetworkConfig();
#else
ESP_LOGI("Initializer", "Loading network config"); ESP_LOGI("Initializer", "Loading network config");
espmega.iot->loadNetworkConfig(); espmega.iot->loadNetworkConfig();
#endif
ESP_LOGI("Initializer", "Connecting to network"); ESP_LOGI("Initializer", "Connecting to network");
espmega.iot->connectNetwork(); espmega.iot->connectNetwork();
#ifdef WRITE_DEFAULT_NETCONF
setMqttConfig();
#else
ESP_LOGI("Initializer", "Loading MQTT config"); ESP_LOGI("Initializer", "Loading MQTT config");
espmega.iot->loadMqttConfig(); espmega.iot->loadMqttConfig();
#endif
ESP_LOGI("Initializer", "Connecting to MQTT"); ESP_LOGI("Initializer", "Connecting to MQTT");
espmega.iot->connectToMqtt(); espmega.iot->connectToMqtt();
#ifdef MQTT_CARD_REGISTER
ESP_LOGI("Initializer", "Registering cards 0"); ESP_LOGI("Initializer", "Registering cards 0");
espmega.iot->registerCard(0); espmega.iot->registerCard(0);
ESP_LOGI("Initializer", "Registering cards 1"); ESP_LOGI("Initializer", "Registering cards 1");
espmega.iot->registerCard(1); espmega.iot->registerCard(1);
#endif
ESP_LOGI("Initializer", "Registering Input change callback"); ESP_LOGI("Initializer", "Registering Input change callback");
espmega.inputs.registerCallback(input_change_callback); espmega.inputs.registerCallback(input_change_callback);
#ifdef CLIMATE_CARD_ENABLE
ESP_LOGI("Initializer", "Installing climate card"); ESP_LOGI("Initializer", "Installing climate card");
espmega.installCard(2, &climateCard); espmega.installCard(2, &climateCard);
ESP_LOGI("Initializer", "Binding climate card to FRAM"); ESP_LOGI("Initializer", "Binding climate card to FRAM");
@ -101,10 +123,15 @@ void setup()
climateCard.loadStateFromFRAM(); climateCard.loadStateFromFRAM();
ESP_LOGI("Initializer", "Enabling climate card FRAM autosave"); ESP_LOGI("Initializer", "Enabling climate card FRAM autosave");
climateCard.setFRAMAutoSave(true); climateCard.setFRAMAutoSave(true);
ESP_LOGI("Initializer", "Registering cards 2");
espmega.iot->registerCard(2);
#endif
#ifdef DISPLAY_ENABLE
ESP_LOGI("Initializer", "Enabling internal display"); ESP_LOGI("Initializer", "Enabling internal display");
espmega.enableInternalDisplay(&Serial); espmega.enableInternalDisplay(&Serial);
ESP_LOGI("Initializer", "Binding climate card to internal display"); ESP_LOGI("Initializer", "Binding climate card to internal display");
espmega.display->bindClimateCard(&climateCard); espmega.display->bindClimateCard(&climateCard);
#endif
} }
void loop() void loop()
@ -122,4 +149,21 @@ void loop()
espmega.dumpFRAMtoSerialASCII(0, 500); espmega.dumpFRAMtoSerialASCII(0, 500);
} }
#endif #endif
// Every 5 seconds, publish "I'm alive" to MQTT
#ifdef MQTT_DEBUG
static uint32_t last_mqtt_publish = 0;
if (millis() - last_mqtt_publish >= 5000)
{
last_mqtt_publish = millis();
espmega.iot->publish("/espmegai/alive", "true");
}
static uint32_t last_mqtt_status = 0;
if (millis() - last_mqtt_status >= 1000)
{
last_mqtt_status = millis();
Serial.print("MQTT Status: ");
Serial.println(espmega.iot->mqttConnected() ? "Connected" : "Disconnected");
}
#endif
} }