fix mqtt ptr init bug

This commit is contained in:
Siwat Sirichai 2023-12-31 17:55:13 +07:00
parent 443a02c319
commit 14767df9ec
4 changed files with 93 additions and 41 deletions

View File

@ -11,6 +11,9 @@ 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()
@ -177,6 +180,12 @@ bool ESPMegaIoT::connectToMqtt(char *client_id, char *mqtt_server, uint16_t mqtt
mqtt.setServer(mqtt_server, mqtt_port); mqtt.setServer(mqtt_server, mqtt_port);
auto boundCallback = std::bind(&ESPMegaIoT::mqttCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); auto boundCallback = std::bind(&ESPMegaIoT::mqttCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
mqtt.setCallback(boundCallback); mqtt.setCallback(boundCallback);
if (mqtt_user == nullptr || mqtt_password == nullptr || strlen(mqtt_user) == 0 || strlen(mqtt_password) == 0)
{
mqtt_connected = false;
ESP_LOGE("ESPMegaIoT", "MQTT Connection failed: Username or password not set but MQTT use_auth is true");
return false;
}
if (mqtt.connect(client_id, mqtt_user, mqtt_password)) if (mqtt.connect(client_id, mqtt_user, mqtt_password))
{ {
sessionKeepAlive(); sessionKeepAlive();
@ -197,13 +206,18 @@ bool ESPMegaIoT::connectToMqtt(char *client_id, char *mqtt_server, uint16_t mqtt
} }
bool ESPMegaIoT::connectToMqtt(char *client_id, char *mqtt_server, uint16_t mqtt_port) bool ESPMegaIoT::connectToMqtt(char *client_id, char *mqtt_server, uint16_t mqtt_port)
{ {
ESP_LOGD("ESPMegaIoT", "Setting MQTT server to %s:%d", mqtt_server, mqtt_port);
mqtt.setServer(mqtt_server, mqtt_port); mqtt.setServer(mqtt_server, mqtt_port);
auto boundCallback = std::bind(&ESPMegaIoT::mqttCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); auto boundCallback = std::bind(&ESPMegaIoT::mqttCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
ESP_LOGD("ESPMegaIoT", "Binding MQTT callback");
mqtt.setCallback(boundCallback); mqtt.setCallback(boundCallback);
if (mqtt.connect(client_id)) if (mqtt.connect(client_id))
{ {
ESP_LOGD("ESPMegaIoT", "MQTT Connected, Calling session keep alive");
sessionKeepAlive(); sessionKeepAlive();
ESP_LOGD("ESPMegaIoT", "Subscribing to topics");
mqttSubscribe(); mqttSubscribe();
ESP_LOGD("ESPMegaIoT", "Publishing reports");
// Publish all cards // Publish all cards
for (int i = 0; i < 255; i++) for (int i = 0; i < 255; i++)
{ {
@ -212,7 +226,7 @@ bool ESPMegaIoT::connectToMqtt(char *client_id, char *mqtt_server, uint16_t mqtt
components[i]->publishReport(); components[i]->publishReport();
} }
} }
ESP_LOGI("ESPMegaIoT", "MQTT Connected"); ESP_LOGI("ESPMegaIoT", "MQTT Connected OK.");
mqtt_connected = true; mqtt_connected = true;
return true; return true;
} }
@ -234,16 +248,22 @@ void ESPMegaIoT::registerMqttCallback(void (*callback)(char *, char *))
} }
void ESPMegaIoT::mqttSubscribe() void ESPMegaIoT::mqttSubscribe()
{ {
if (user_subscribe_callback != NULL) ESP_LOGD("ESPMegaIoT", "Begin MQTT Subscription");
if (user_subscribe_callback != nullptr)
{ {
ESP_LOGD("ESPMegaIoT", "Subscribing user callback");
user_subscribe_callback(); user_subscribe_callback();
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);
components[i]->subscribe(); components[i]->subscribe();
mqtt.loop();
} }
} }
} }
@ -292,6 +312,7 @@ 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", base_topic, topic);
mqtt.publish(absolute_topic, payload); mqtt.publish(absolute_topic, payload);
mqtt.loop();
} }
void ESPMegaIoT::subscribeRelative(char *topic) void ESPMegaIoT::subscribeRelative(char *topic)
@ -299,6 +320,7 @@ 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", base_topic, topic);
mqtt.subscribe(absolute_topic); mqtt.subscribe(absolute_topic);
mqtt.loop();
} }
void ESPMegaIoT::registerSubscribeCallback(void (*callback)(void)) void ESPMegaIoT::registerSubscribeCallback(void (*callback)(void))
@ -319,12 +341,12 @@ void ESPMegaIoT::loadNetworkConfig()
network_config.subnet = fram->read32(IOT_FRAM_ADDRESS + 8); network_config.subnet = fram->read32(IOT_FRAM_ADDRESS + 8);
network_config.dns1 = fram->read32(IOT_FRAM_ADDRESS + 12); network_config.dns1 = fram->read32(IOT_FRAM_ADDRESS + 12);
network_config.dns2 = fram->read32(IOT_FRAM_ADDRESS + 16); network_config.dns2 = fram->read32(IOT_FRAM_ADDRESS + 16);
fram->read(IOT_FRAM_ADDRESS + 20, (uint8_t*)network_config.hostname, 32); fram->read(IOT_FRAM_ADDRESS + 20, (uint8_t *)network_config.hostname, 32);
network_config.useStaticIp = fram->read8(IOT_FRAM_ADDRESS + 52); network_config.useStaticIp = fram->read8(IOT_FRAM_ADDRESS + 52);
network_config.useWifi = fram->read8(IOT_FRAM_ADDRESS + 53); network_config.useWifi = fram->read8(IOT_FRAM_ADDRESS + 53);
network_config.wifiUseAuth = fram->read8(IOT_FRAM_ADDRESS + 54); network_config.wifiUseAuth = fram->read8(IOT_FRAM_ADDRESS + 54);
fram->read(IOT_FRAM_ADDRESS + 55, (uint8_t*)network_config.ssid, 32); fram->read(IOT_FRAM_ADDRESS + 55, (uint8_t *)network_config.ssid, 32);
fram->read(IOT_FRAM_ADDRESS + 87, (uint8_t*)network_config.password, 32); fram->read(IOT_FRAM_ADDRESS + 87, (uint8_t *)network_config.password, 32);
} }
void ESPMegaIoT::saveNetworkConfig() void ESPMegaIoT::saveNetworkConfig()
@ -335,13 +357,12 @@ void ESPMegaIoT::saveNetworkConfig()
fram->write32(IOT_FRAM_ADDRESS + 8, network_config.subnet); fram->write32(IOT_FRAM_ADDRESS + 8, network_config.subnet);
fram->write32(IOT_FRAM_ADDRESS + 12, network_config.dns1); fram->write32(IOT_FRAM_ADDRESS + 12, network_config.dns1);
fram->write32(IOT_FRAM_ADDRESS + 16, network_config.dns2); fram->write32(IOT_FRAM_ADDRESS + 16, network_config.dns2);
fram->write(IOT_FRAM_ADDRESS + 20, (uint8_t*)network_config.hostname, 32); fram->write(IOT_FRAM_ADDRESS + 20, (uint8_t *)network_config.hostname, 32);
fram->write8(IOT_FRAM_ADDRESS + 52, network_config.useStaticIp); fram->write8(IOT_FRAM_ADDRESS + 52, network_config.useStaticIp);
fram->write8(IOT_FRAM_ADDRESS + 53, network_config.useWifi); fram->write8(IOT_FRAM_ADDRESS + 53, network_config.useWifi);
fram->write8(IOT_FRAM_ADDRESS + 54, network_config.wifiUseAuth); fram->write8(IOT_FRAM_ADDRESS + 54, network_config.wifiUseAuth);
fram->write(IOT_FRAM_ADDRESS + 55, (uint8_t*)network_config.ssid, 32); fram->write(IOT_FRAM_ADDRESS + 55, (uint8_t *)network_config.ssid, 32);
fram->write(IOT_FRAM_ADDRESS + 87, (uint8_t*)network_config.password, 32); fram->write(IOT_FRAM_ADDRESS + 87, (uint8_t *)network_config.password, 32);
} }
void ESPMegaIoT::ethernetBegin() void ESPMegaIoT::ethernetBegin()
@ -354,29 +375,35 @@ void ESPMegaIoT::loadMqttConfig()
// Load the mqtt config from FRAM // Load the mqtt config from FRAM
// We skip bytes 119-127 because they are reserved for the network config // We skip bytes 119-127 because they are reserved for the network config
mqtt_config.mqtt_port = fram->read16(IOT_FRAM_ADDRESS + 128); mqtt_config.mqtt_port = fram->read16(IOT_FRAM_ADDRESS + 128);
fram->read(IOT_FRAM_ADDRESS + 130, (uint8_t*)mqtt_config.mqtt_server, 32); fram->read(IOT_FRAM_ADDRESS + 130, (uint8_t *)mqtt_config.mqtt_server, 32);
fram->read(IOT_FRAM_ADDRESS + 162, (uint8_t*)mqtt_config.mqtt_user, 32); fram->read(IOT_FRAM_ADDRESS + 162, (uint8_t *)mqtt_config.mqtt_user, 32);
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);
} }
void ESPMegaIoT::saveMqttConfig() void ESPMegaIoT::saveMqttConfig()
{ {
fram->write16(IOT_FRAM_ADDRESS + 128, mqtt_config.mqtt_port); fram->write16(IOT_FRAM_ADDRESS + 128, mqtt_config.mqtt_port);
fram->write(IOT_FRAM_ADDRESS + 130, (uint8_t*)mqtt_config.mqtt_server, 32); fram->write(IOT_FRAM_ADDRESS + 130, (uint8_t *)mqtt_config.mqtt_server, 32);
fram->write(IOT_FRAM_ADDRESS + 162, (uint8_t*)mqtt_config.mqtt_user, 32); fram->write(IOT_FRAM_ADDRESS + 162, (uint8_t *)mqtt_config.mqtt_user, 32);
fram->write(IOT_FRAM_ADDRESS + 194, (uint8_t*)mqtt_config.mqtt_password, 32); fram->write(IOT_FRAM_ADDRESS + 194, (uint8_t *)mqtt_config.mqtt_password, 32);
fram->write8(IOT_FRAM_ADDRESS + 226, mqtt_config.mqtt_useauth); fram->write8(IOT_FRAM_ADDRESS + 226, mqtt_config.mqtt_useauth);
fram->write(IOT_FRAM_ADDRESS + 227, (uint8_t*)mqtt_config.base_topic, 32); fram->write(IOT_FRAM_ADDRESS + 227, (uint8_t *)mqtt_config.base_topic, 32);
} }
void ESPMegaIoT::connectToMqtt() void ESPMegaIoT::connectToMqtt()
{ {
if (mqtt_config.mqtt_useauth) if (mqtt_config.mqtt_useauth)
{
ESP_LOGD("ESPMegaIoT", "Connecting to MQTT with auth");
this->connectToMqtt(network_config.hostname, mqtt_config.mqtt_server, mqtt_config.mqtt_port, mqtt_config.mqtt_user, mqtt_config.mqtt_password); this->connectToMqtt(network_config.hostname, mqtt_config.mqtt_server, mqtt_config.mqtt_port, mqtt_config.mqtt_user, mqtt_config.mqtt_password);
}
else else
{
ESP_LOGD("ESPMegaIoT", "Connecting to MQTT without auth");
this->connectToMqtt(network_config.hostname, mqtt_config.mqtt_server, mqtt_config.mqtt_port); this->connectToMqtt(network_config.hostname, mqtt_config.mqtt_server, mqtt_config.mqtt_port);
}
} }
void ESPMegaIoT::connectNetwork() void ESPMegaIoT::connectNetwork()
@ -415,12 +442,12 @@ IoTComponent *ESPMegaIoT::getComponent(uint8_t card_id)
return components[card_id]; return components[card_id];
} }
NetworkConfig* ESPMegaIoT::getNetworkConfig() NetworkConfig *ESPMegaIoT::getNetworkConfig()
{ {
return &network_config; return &network_config;
} }
MqttConfig* ESPMegaIoT::getMqttConfig() MqttConfig *ESPMegaIoT::getMqttConfig()
{ {
return &mqtt_config; return &mqtt_config;
} }

View File

@ -163,6 +163,9 @@ void InternalDisplay::saveMQTTConfig()
// password_set -> a text input to set the mqtt password // password_set -> a text input to set the mqtt password
// topic_set -> a text input to set the mqtt base topic // topic_set -> a text input to set the mqtt base topic
// Send the stop bytes to flush the serial buffer
this->sendStopBytes();
// Save the mqtt server // Save the mqtt server
if(!this->getStringToBuffer("mqttsv_set.txt", this->mqttConfig->mqtt_server, 16)) if(!this->getStringToBuffer("mqttsv_set.txt", this->mqttConfig->mqtt_server, 16))
return; return;
@ -183,7 +186,10 @@ void InternalDisplay::saveMQTTConfig()
return; return;
// Save the mqtt use auth // Save the mqtt use auth
this->mqttConfig->mqtt_useauth = this->getNumber("use_auth.val") == 1 ? true : false; uint8_t use_auth = this->getNumber("use_auth.val");
Serial.print("use_auth: ");
Serial.println(use_auth);
this->mqttConfig->mqtt_useauth = use_auth == 1 ? true : false;
this->iot->saveMqttConfig(); this->iot->saveMqttConfig();
ESP.restart(); ESP.restart();
} }

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=3 build_flags = -DCORE_DEBUG_LEVEL=1

View File

@ -3,16 +3,17 @@
#include <ETH.h> #include <ETH.h>
#include <ClimateCard.hpp> #include <ClimateCard.hpp>
// #define FRAM_DEBUG
// Demo PLC firmware using the ESPMegaPRO OOP library // Demo PLC firmware using the ESPMegaPRO OOP library
ESPMegaPRO espmega = ESPMegaPRO(); ESPMegaPRO espmega = ESPMegaPRO();
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"};
size_t getInfraredCode(uint8_t mode, uint8_t fan_speed, uint8_t temperature, const uint16_t** codePtr) { size_t getInfraredCode(uint8_t mode, uint8_t fan_speed, uint8_t temperature, const uint16_t **codePtr)
{
// Change the code pointer to point to the IR timing array // Change the code pointer to point to the IR timing array
*codePtr = &(irCode[mode][fan_speed][temperature][0]); *codePtr = &(irCode[mode][fan_speed][temperature][0]);
return sizeof(irCode[mode][fan_speed][temperature]) / sizeof(uint16_t); return sizeof(irCode[mode][fan_speed][temperature]) / sizeof(uint16_t);
@ -25,19 +26,20 @@ AirConditioner ac = {
.mode_names = mode_names, .mode_names = mode_names,
.fan_speeds = 4, .fan_speeds = 4,
.fan_speed_names = fan_speed_names, .fan_speed_names = fan_speed_names,
.getInfraredCode = &getInfraredCode .getInfraredCode = &getInfraredCode};
};
ClimateCard climateCard = ClimateCard(14, ac); ClimateCard climateCard = ClimateCard(14, ac);
void input_change_callback(uint8_t pin, uint8_t value) { void input_change_callback(uint8_t pin, uint8_t value)
{
Serial.print("Input change callback: "); Serial.print("Input change callback: ");
Serial.print(pin); Serial.print(pin);
Serial.print(" "); Serial.print(" ");
Serial.println(value); Serial.println(value);
} }
void setNetworkConfig() { void setNetworkConfig()
{
NetworkConfig config = { NetworkConfig config = {
.ip = {192, 168, 0, 11}, .ip = {192, 168, 0, 11},
.gateway = {192, 168, 0, 1}, .gateway = {192, 168, 0, 1},
@ -54,53 +56,70 @@ void setNetworkConfig() {
Serial.println("Setting network config"); Serial.println("Setting network config");
espmega.iot->setNetworkConfig(config); espmega.iot->setNetworkConfig(config);
espmega.iot->saveNetworkConfig(); espmega.iot->saveNetworkConfig();
} }
void setMqttConfig() { void setMqttConfig()
{
MqttConfig config = { MqttConfig config = {
.mqtt_port = 1883, .mqtt_port = 1883,
.mqtt_useauth = false .mqtt_useauth = false};
};
strcpy(config.mqtt_server, "192.168.0.26"); strcpy(config.mqtt_server, "192.168.0.26");
strcpy(config.base_topic, "/espmegaoop"); strcpy(config.base_topic, "/espmegaoop");
espmega.iot->setMqttConfig(config); espmega.iot->setMqttConfig(config);
espmega.iot->saveMqttConfig(); espmega.iot->saveMqttConfig();
} }
void setup() { void setup()
{
ESP_LOGI("Initializer", "Starting ESPMegaPRO OOP demo");
espmega.begin(); espmega.begin();
ESP_LOGI("Initializer", "Enabling IOT module");
espmega.enableIotModule(); espmega.enableIotModule();
ESP_LOGI("Initializer", "Enabling Ethernet");
ETH.begin(); ETH.begin();
ESP_LOGI("Initializer", "Binding Ethernet to IOT module");
espmega.iot->bindEthernetInterface(&ETH); espmega.iot->bindEthernetInterface(&ETH);
ESP_LOGI("Initializer", "Loading network config");
espmega.iot->loadNetworkConfig(); espmega.iot->loadNetworkConfig();
ESP_LOGI("Initializer", "Connecting to network");
espmega.iot->connectNetwork(); espmega.iot->connectNetwork();
ESP_LOGI("Initializer", "Loading MQTT config");
espmega.iot->loadMqttConfig(); espmega.iot->loadMqttConfig();
ESP_LOGI("Initializer", "Connecting to MQTT");
espmega.iot->connectToMqtt(); espmega.iot->connectToMqtt();
ESP_LOGI("Initializer", "Registering cards 0");
espmega.iot->registerCard(0); espmega.iot->registerCard(0);
ESP_LOGI("Initializer", "Registering cards 1");
espmega.iot->registerCard(1); espmega.iot->registerCard(1);
ESP_LOGI("Initializer", "Registering Input change callback");
espmega.inputs.registerCallback(input_change_callback); espmega.inputs.registerCallback(input_change_callback);
ESP_LOGI("Initializer", "Installing climate card");
espmega.installCard(2, &climateCard); espmega.installCard(2, &climateCard);
ESP_LOGI("Initializer", "Binding climate card to FRAM");
climateCard.bindFRAM(&espmega.fram, 301); climateCard.bindFRAM(&espmega.fram, 301);
ESP_LOGI("Initializer", "Loading climate card state from FRAM");
climateCard.loadStateFromFRAM(); climateCard.loadStateFromFRAM();
ESP_LOGI("Initializer", "Enabling climate card FRAM autosave");
climateCard.setFRAMAutoSave(true); climateCard.setFRAMAutoSave(true);
ESP_LOGI("Initializer", "Enabling internal display");
espmega.enableInternalDisplay(&Serial); espmega.enableInternalDisplay(&Serial);
ESP_LOGI("Initializer", "Binding climate card to internal display");
espmega.display->bindClimateCard(&climateCard); espmega.display->bindClimateCard(&climateCard);
} }
void loop()
{
// Every 20 seconds, dump FRAM 0-500 to serial
void loop() {
espmega.loop(); espmega.loop();
#ifdef FRAM_DEBUG #ifdef FRAM_DEBUG
// Every 20 seconds, dump FRAM 0-500 to serial
static uint32_t last_fram_dump = 0; static uint32_t last_fram_dump = 0;
if (millis() - last_fram_dump >= 20000) { if (millis() - last_fram_dump >= 20000)
{
last_fram_dump = millis(); last_fram_dump = millis();
Serial.println("Dumping FRAM"); Serial.println("Dumping FRAM");
espmega.dumpFRAMtoSerial(0, 500); espmega.dumpFRAMtoSerial(0, 500);
Serial.println("Dumping FRAM ASCII"); Serial.println("Dumping FRAM ASCII");
espmega.dumpFRAMtoSerialASCII(0, 500); espmega.dumpFRAMtoSerialASCII(0, 500);
} }
#endif #endif
} }