From da277e1e4a082f2bba33116c0e352cfd991de8a4 Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Thu, 28 Dec 2023 14:08:10 +0700 Subject: [PATCH] initial mqtt implementation --- Template Project/.vscode/settings.json | 6 +- Template Project/lib/ESPMegaPRO/AnalogIoT.hpp | 2 +- .../lib/ESPMegaPRO/DigitalInputIoT.hpp | 2 +- .../lib/ESPMegaPRO/DigitalOutputIoT.cpp | 5 +- .../lib/ESPMegaPRO/DigitalOutputIoT.hpp | 2 +- .../lib/ESPMegaPRO/ESPMegaIoT.cpp | 99 ++++++++++++++++--- .../lib/ESPMegaPRO/ESPMegaIoT.hpp | 11 +-- .../lib/ESPMegaPRO/IoTComponent.cpp | 6 ++ .../lib/ESPMegaPRO/IoTComponent.hpp | 5 +- 9 files changed, 109 insertions(+), 29 deletions(-) diff --git a/Template Project/.vscode/settings.json b/Template Project/.vscode/settings.json index 9de6690..2da7432 100644 --- a/Template Project/.vscode/settings.json +++ b/Template Project/.vscode/settings.json @@ -1,5 +1,6 @@ { "files.associations": { + "*.cps": "javascript", "array": "cpp", "deque": "cpp", "string": "cpp", @@ -8,7 +9,10 @@ "vector": "cpp", "string_view": "cpp", "initializer_list": "cpp", - "adafruit_ads1x15.h": "c" + "adafruit_ads1x15.h": "c", + "*.tcc": "cpp", + "memory": "cpp", + "random": "cpp" }, "cmake.configureOnOpen": true, "cmake.sourceDirectory": "D:/Git/ESPMegaPRO-v3-SDK/Template Project/.pio/libdeps/wt32-eth01/Adafruit BusIO" diff --git a/Template Project/lib/ESPMegaPRO/AnalogIoT.hpp b/Template Project/lib/ESPMegaPRO/AnalogIoT.hpp index 40b02c7..6514569 100644 --- a/Template Project/lib/ESPMegaPRO/AnalogIoT.hpp +++ b/Template Project/lib/ESPMegaPRO/AnalogIoT.hpp @@ -5,7 +5,7 @@ class AnalogIoT : public IoTComponent { public: AnalogIoT(); ~AnalogIoT(); - bool begin(AnalogCard *card, void (*publishRelative)(uint8_t, char *, char *), PubSubClient *mqtt, char *base_topic); + bool begin(uint8_t card_id, AnalogCard *card, PubSubClient *mqtt, char *base_topic); void handleMqttMessage(char *topic, char *payload); void publishADCs(); void setADCsPublishInterval(uint32_t interval); diff --git a/Template Project/lib/ESPMegaPRO/DigitalInputIoT.hpp b/Template Project/lib/ESPMegaPRO/DigitalInputIoT.hpp index 38a3071..d84b099 100644 --- a/Template Project/lib/ESPMegaPRO/DigitalInputIoT.hpp +++ b/Template Project/lib/ESPMegaPRO/DigitalInputIoT.hpp @@ -5,7 +5,7 @@ class DigitalInputIoT : public IoTComponent { public: - bool begin(DigitalInputCard *card, void (*publishRelative)(uint8_t, char *, char *), PubSubClient *mqtt, char *base_topic); + bool begin(uint8_t card_id, DigitalInputCard *card, PubSubClient *mqtt, char *base_topic); void handleMqttMessage(char *topic, char *payload); void publishDigitalInputs(); void setDigitalInputsPublishEnabled(bool enabled); diff --git a/Template Project/lib/ESPMegaPRO/DigitalOutputIoT.cpp b/Template Project/lib/ESPMegaPRO/DigitalOutputIoT.cpp index 3d88d77..6535f55 100644 --- a/Template Project/lib/ESPMegaPRO/DigitalOutputIoT.cpp +++ b/Template Project/lib/ESPMegaPRO/DigitalOutputIoT.cpp @@ -10,11 +10,12 @@ DigitalOutputIoT::~DigitalOutputIoT() { delete[] this->value_report_topic; } -bool DigitalOutputIoT::begin(ExpansionCard *card, void (*publishRelative)(uint8_t, char *, char *), PubSubClient *mqtt, char *base_topic) { +bool DigitalOutputIoT::begin(uint8_t card_id, ExpansionCard *card, PubSubClient *mqtt, char *base_topic) { this->mqtt = mqtt; this->base_topic = base_topic; - this->publishRelative = publishRelative; this->card = (DigitalOutputCard *) card; + if(!card->begin()) return false; + this-> card_id = card_id; this->set_state_length = strlen(SET_STATE_TOPIC); this->set_value_length = strlen(SET_VALUE_TOPIC); this->state_length = strlen(STATE_TOPIC); diff --git a/Template Project/lib/ESPMegaPRO/DigitalOutputIoT.hpp b/Template Project/lib/ESPMegaPRO/DigitalOutputIoT.hpp index 7c81da2..1ac761b 100644 --- a/Template Project/lib/ESPMegaPRO/DigitalOutputIoT.hpp +++ b/Template Project/lib/ESPMegaPRO/DigitalOutputIoT.hpp @@ -7,7 +7,7 @@ class DigitalOutputIoT : public IoTComponent { public: DigitalOutputIoT(); ~DigitalOutputIoT(); - bool begin(ExpansionCard *card, void (*publishRelative)(uint8_t, char *, char *), PubSubClient *mqtt, char *base_topic); + bool begin(uint8_t card_id, ExpansionCard *card, PubSubClient *mqtt, char *base_topic); void handleMqttMessage(char *topic, char *payload); void publishDigitalOutputs(); void publishDigitalOutput(uint8_t pin); diff --git a/Template Project/lib/ESPMegaPRO/ESPMegaIoT.cpp b/Template Project/lib/ESPMegaPRO/ESPMegaIoT.cpp index 9891da2..6e3de7e 100644 --- a/Template Project/lib/ESPMegaPRO/ESPMegaIoT.cpp +++ b/Template Project/lib/ESPMegaPRO/ESPMegaIoT.cpp @@ -24,23 +24,92 @@ void ESPMegaIoT::setBaseTopic(char *base_topic) { base_topic_length = strlen(base_topic); } -void ESPMegaIoT::begin() { - +void ESPMegaIoT::begin(ExpansionCard *cards[]) { + this->cards = cards; } void ESPMegaIoT::loop(); -void ESPMegaIoT::registerCard(uint8_t card_id); -void ESPMegaIoT::deregisterCard(uint8_t card_id); -void ESPMegaIoT::publishCard(uint8_t card_id); -void ESPMegaIoT::subscribeToTopic(char *topic); -void ESPMegaIoT::unsubscribeFromTopic(char *topic); -void ESPMegaIoT::connectToEthernet(); -bool ESPMegaIoT::ethernetConnected(); -void ESPMegaIoT::connectToWifi(char *ssid, char *password); -void ESPMegaIoT::connectToWifi(char *ssid); -void ESPMegaIoT::disconnectFromWifi(); -bool ESPMegaIoT::wifiConnected(); -void ESPMegaIoT::connectToMqtt(char *mqtt_server, uint16_t mqtt_port, char *mqtt_user, char *mqtt_password); -void ESPMegaIoT::connectToMqtt(char *mqtt_server, uint16_t mqtt_port); + +// Register Existing Card for use with IoT +void ESPMegaIoT::registerCard(uint8_t card_id) { + // Check if the card is already registered + if (components[card_id] != NULL) { + return; + } + // Get the card type + uint8_t card_type = cards[card_id]->getType(); + // Create the respective IoT component + switch (card_type) { + case CARD_TYPE_ANALOG: + components[card_id] = new AnalogIoT(); + components[card_id]->begin(card_id, cards[card_id], &mqtt, base_topic); + break; + case CARD_TYPE_DIGITAL_INPUT: + components[card_id] = new DigitalInputIoT(); + components[card_id]->begin(card_id, cards[card_id], &mqtt, base_topic); + break; + case CARD_TYPE_DIGITAL_OUTPUT: + components[card_id] = new DigitalOutputIoT(); + components[card_id]->begin(card_id, cards[card_id], &mqtt, base_topic); + break; + default: + return; + } + // Initialize the IoT component + + + // Enable publishing for the card + card_publish_enabled[card_id] = true; +} +void ESPMegaIoT::deregisterCard(uint8_t card_id) { + // Check if the card is registered + if (components[card_id] == NULL) { + return; + } + // Delete the IoT component + delete components[card_id]; + components[card_id] = NULL; + // Disable publishing for the card + card_publish_enabled[card_id] = false; +} +void ESPMegaIoT::publishCard(uint8_t card_id) { + // Check if the card is registered + if (components[card_id] == NULL) { + return; + } + // Publish the card + components[card_id]->publishReport(); +} +void ESPMegaIoT::subscribeToTopic(char *topic) { + mqtt.subscribe(topic); +} +void ESPMegaIoT::unsubscribeFromTopic(char *topic) { + mqtt.unsubscribe(topic); +} +void ESPMegaIoT::connectToEthernet() { + ETH.begin(); +} +bool ESPMegaIoT::ethernetConnected() { + return ETH.linkUp(); +} +void ESPMegaIoT::connectToWifi(char *ssid, char *password) { + WiFi.begin(ssid, password); +} +void ESPMegaIoT::connectToWifi(char *ssid) { + WiFi.begin(ssid); +} +void ESPMegaIoT::disconnectFromWifi() { + WiFi.disconnect(); +} +bool ESPMegaIoT::wifiConnected() { + return WiFi.status() == WL_CONNECTED; +} +void ESPMegaIoT::connectToMqtt(char*client_id, char *mqtt_server, uint16_t mqtt_port, char *mqtt_user, char *mqtt_password) { + mqtt.setServer(mqtt_server, mqtt_port); + mqtt.setCallback(mqttCallback); + mqtt.connect(client_id, mqtt_user, mqtt_password); + sessionKeepAlive(); +} +void ESPMegaIoT::connectToMqtt(char* client_id, char *mqtt_server, uint16_t mqtt_port); void ESPMegaIoT::disconnectFromMqtt(); void ESPMegaIoT::publishToTopic(char *topic, char *payload); void ESPMegaIoT::registerMqttCallback(void (*callback)(char *, char *)); diff --git a/Template Project/lib/ESPMegaPRO/ESPMegaIoT.hpp b/Template Project/lib/ESPMegaPRO/ESPMegaIoT.hpp index 7f5f4cd..8ad4487 100644 --- a/Template Project/lib/ESPMegaPRO/ESPMegaIoT.hpp +++ b/Template Project/lib/ESPMegaPRO/ESPMegaIoT.hpp @@ -12,7 +12,7 @@ class ESPMegaIoT { public: - void begin(); + void begin(ExpansionCard *cards[]); void loop(); void registerCard(uint8_t card_id); void deregisterCard(uint8_t card_id); @@ -25,24 +25,23 @@ class ESPMegaIoT void connectToWifi(char *ssid); void disconnectFromWifi(); bool wifiConnected(); - void connectToMqtt(char *mqtt_server, uint16_t mqtt_port, char *mqtt_user, char *mqtt_password); - void connectToMqtt(char *mqtt_server, uint16_t mqtt_port); + void connectToMqtt(char *client_id, char *mqtt_server, uint16_t mqtt_port, char *mqtt_user, char *mqtt_password); + void connectToMqtt(char* client_id, char *mqtt_server, uint16_t mqtt_port); void disconnectFromMqtt(); void publishToTopic(char *topic, char *payload); void registerMqttCallback(void (*callback)(char *, char *)); void setBaseTopic(char *base_topic); - - private: void sessionKeepAlive(); void mqttReconnect(); void wifiReconnect(); void mqttCallback(char *topic, byte *payload, unsigned int length); - void publishRelative(char *topic, char *payload); + void publishRelative(uint8_t card_id, char *topic, char *payload); PubSubClient mqtt; IoTComponent *components[255]; bool card_publish_enabled[255]; char payload_buffer[200]; char base_topic[100]; uint8_t base_topic_length; + ExpansionCard **cards; // Points to card array in ESPMegaPRO Core }; \ No newline at end of file diff --git a/Template Project/lib/ESPMegaPRO/IoTComponent.cpp b/Template Project/lib/ESPMegaPRO/IoTComponent.cpp index e347523..ac7882f 100644 --- a/Template Project/lib/ESPMegaPRO/IoTComponent.cpp +++ b/Template Project/lib/ESPMegaPRO/IoTComponent.cpp @@ -2,4 +2,10 @@ void IoTComponent::setMqttClient(PubSubClient *mqtt) { this->mqtt = mqtt; +} + +void IoTComponent::publishRelative(char *topic, char *payload) { + char absolute_topic[100]; + sprintf(absolute_topic, "%s/%d/%s", base_topic, card_id, topic); + mqtt->publish(absolute_topic, payload); } \ No newline at end of file diff --git a/Template Project/lib/ESPMegaPRO/IoTComponent.hpp b/Template Project/lib/ESPMegaPRO/IoTComponent.hpp index 8211aac..7e9fc09 100644 --- a/Template Project/lib/ESPMegaPRO/IoTComponent.hpp +++ b/Template Project/lib/ESPMegaPRO/IoTComponent.hpp @@ -3,13 +3,14 @@ #include class IoTComponent { public: - virtual bool begin(ExpansionCard *card, void (*publishRelative)(uint8_t, char *, char *), PubSubClient *mqtt, char *base_topic); + virtual bool begin(uint8_t card_id, ExpansionCard *card, PubSubClient *mqtt, char *base_topic); virtual void handleMqttMessage(char *topic, char *payload); void setMqttClient(PubSubClient *mqtt); virtual void publishReport(); virtual uint8_t getType(); protected: char *base_topic; - void (*publishRelative)(uint8_t, char *, char *); + void publishRelative(char *topic, char *payload); PubSubClient *mqtt; + uint8_t card_id; };