Compare commits
2 Commits
14767df9ec
...
4c77474a94
Author | SHA1 | Date |
---|---|---|
Siwat Sirichai | 4c77474a94 | |
Siwat Sirichai | 9cd5b7132b |
|
@ -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() {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
|
@ -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(Ð);
|
espmega.iot->bindEthernetInterface(Ð);
|
||||||
|
#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
|
||||||
}
|
}
|
Loading…
Reference in New Issue