complete iot structure
This commit is contained in:
parent
da277e1e4a
commit
0dfb066a74
|
@ -11,6 +11,7 @@ class AnalogIoT : public IoTComponent {
|
|||
void setADCsPublishInterval(uint32_t interval);
|
||||
void setADCsPublishEnabled(bool enabled);
|
||||
void publishReport();
|
||||
void subscribe();
|
||||
uint8_t getType();
|
||||
private:
|
||||
char *adc_topic;
|
||||
|
|
|
@ -169,3 +169,25 @@ void DigitalOutputIoT::publishReport() {
|
|||
uint8_t DigitalOutputIoT::getType() {
|
||||
return CARD_TYPE_DIGITAL_OUTPUT;
|
||||
}
|
||||
|
||||
void DigitalOutputIoT::subscribe() {
|
||||
// Subscribe to all set state topics
|
||||
for(int i = 1; i <= 16; i++) {
|
||||
char topic[10];
|
||||
sprintf(topic, "%02d/set/state", i);
|
||||
subscribeRelative(topic);
|
||||
}
|
||||
// Subscribe to all set value topics
|
||||
for(int i = 1; i <= 16; i++) {
|
||||
char topic[10];
|
||||
sprintf(topic, "%02d/set/value", i);
|
||||
subscribeRelative(topic);
|
||||
}
|
||||
// Subscribe to request state topic
|
||||
subscribeRelative(REQUEST_STATE_TOPIC);
|
||||
// Subscribe to publish enable topic
|
||||
subscribeRelative(PUBLISH_ENABLE_TOPIC);
|
||||
}
|
||||
|
||||
void DigitalOutputIoT::loop() {
|
||||
}
|
|
@ -18,6 +18,8 @@ class DigitalOutputIoT : public IoTComponent {
|
|||
void registerValueChangeCallback(void (*callback)(uint8_t, bool, uint16_t));
|
||||
void deregisterValueChangeCallback();
|
||||
void publishReport();
|
||||
void subscribe();
|
||||
void loop();
|
||||
uint8_t getType();
|
||||
private:
|
||||
bool digital_outputs_publish_enabled = false;
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
#include <ESPMegaIoT.hpp>
|
||||
|
||||
ESPMegaIoT::ESPMegaIoT() {
|
||||
// Initialize the components array
|
||||
for (int i = 0; i < 255; i++) {
|
||||
components[i] = NULL;
|
||||
}
|
||||
active = false;
|
||||
mqtt_connected = false;
|
||||
}
|
||||
|
||||
void ESPMegaIoT::mqttCallback(char *topic, byte *payload, unsigned int length) {
|
||||
// Create a null terminated string from the payload
|
||||
memcpy(payload_buffer, payload, length);
|
||||
|
@ -17,6 +26,12 @@ void ESPMegaIoT::mqttCallback(char *topic, byte *payload, unsigned int length) {
|
|||
return;
|
||||
}
|
||||
components[card_id]->handleMqttMessage(topic_without_base + 3, payload_buffer);
|
||||
if (user_relative_mqtt_callback != NULL) {
|
||||
user_relative_mqtt_callback(topic_without_base + 3, payload_buffer);
|
||||
}
|
||||
if (user_mqtt_callback != NULL) {
|
||||
user_mqtt_callback(topic, payload_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void ESPMegaIoT::setBaseTopic(char *base_topic) {
|
||||
|
@ -24,10 +39,23 @@ void ESPMegaIoT::setBaseTopic(char *base_topic) {
|
|||
base_topic_length = strlen(base_topic);
|
||||
}
|
||||
|
||||
void ESPMegaIoT::begin(ExpansionCard *cards[]) {
|
||||
void ESPMegaIoT::intr_begin(ExpansionCard *cards[]) {
|
||||
this->cards = cards;
|
||||
ETH.begin();
|
||||
active = true;
|
||||
}
|
||||
void ESPMegaIoT::loop() {
|
||||
if(!active)
|
||||
return;
|
||||
// Call each component's loop function
|
||||
for (int i = 0; i < 255; i++) {
|
||||
if (components[i] != NULL) {
|
||||
components[i]->loop();
|
||||
}
|
||||
}
|
||||
mqtt.loop();
|
||||
sessionKeepAlive();
|
||||
}
|
||||
void ESPMegaIoT::loop();
|
||||
|
||||
// Register Existing Card for use with IoT
|
||||
void ESPMegaIoT::registerCard(uint8_t card_id) {
|
||||
|
@ -54,11 +82,6 @@ void ESPMegaIoT::registerCard(uint8_t card_id) {
|
|||
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
|
||||
|
@ -68,8 +91,6 @@ void ESPMegaIoT::deregisterCard(uint8_t card_id) {
|
|||
// 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
|
||||
|
@ -103,13 +124,114 @@ void ESPMegaIoT::disconnectFromWifi() {
|
|||
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) {
|
||||
bool ESPMegaIoT::connectToMqtt(char*client_id, char *mqtt_server, uint16_t mqtt_port, char *mqtt_user, char *mqtt_password) {
|
||||
// Store mqtt connection parameters
|
||||
this->mqtt_server = mqtt_server;
|
||||
this->mqtt_port = mqtt_port;
|
||||
this->mqtt_user = mqtt_user;
|
||||
this->mqtt_password = mqtt_password;
|
||||
this-> mqtt_useauth = true;
|
||||
this->client_id = client_id;
|
||||
mqtt.setServer(mqtt_server, mqtt_port);
|
||||
mqtt.setCallback(mqttCallback);
|
||||
mqtt.connect(client_id, mqtt_user, mqtt_password);
|
||||
auto boundCallback = std::bind(&ESPMegaIoT::mqttCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
||||
mqtt.setCallback(boundCallback);
|
||||
if (mqtt.connect(client_id, mqtt_user, mqtt_password)) {
|
||||
sessionKeepAlive();
|
||||
mqttSubscribe();
|
||||
mqtt_connected = true;
|
||||
return true;
|
||||
}
|
||||
mqtt_connected = false;
|
||||
return false;
|
||||
}
|
||||
bool ESPMegaIoT::connectToMqtt(char* client_id, char *mqtt_server, uint16_t mqtt_port) {
|
||||
// Store mqtt connection parameters
|
||||
this->mqtt_server = mqtt_server;
|
||||
this->mqtt_port = mqtt_port;
|
||||
this->mqtt_useauth = false;
|
||||
this->client_id = client_id;
|
||||
mqtt.setServer(mqtt_server, mqtt_port);
|
||||
auto boundCallback = std::bind(&ESPMegaIoT::mqttCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
||||
mqtt.setCallback(boundCallback);
|
||||
if(mqtt.connect(client_id)) {
|
||||
sessionKeepAlive();
|
||||
mqttSubscribe();
|
||||
mqtt_connected = true;
|
||||
return true;
|
||||
}
|
||||
mqtt_connected = false;
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
void ESPMegaIoT::disconnectFromMqtt() {
|
||||
mqtt.disconnect();
|
||||
}
|
||||
void ESPMegaIoT::publishToTopic(char *topic, char *payload) {
|
||||
mqtt.publish(topic, payload);
|
||||
}
|
||||
void ESPMegaIoT::registerMqttCallback(void (*callback)(char *, char *)) {
|
||||
}
|
||||
void ESPMegaIoT::mqttSubscribe() {
|
||||
// Subscribe to all topics
|
||||
for (int i = 0; i < 255; i++) {
|
||||
if (components[i] != NULL) {
|
||||
components[i]->subscribe();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ESPMegaIoT::publishRelative(uint8_t card_id, char *topic, char *payload) {
|
||||
char absolute_topic[100];
|
||||
sprintf(absolute_topic, "%s/%d/%s", base_topic, card_id, topic);
|
||||
mqtt.publish(absolute_topic, payload);
|
||||
}
|
||||
|
||||
void ESPMegaIoT::setETHStaticIp(IPAddress ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2) {
|
||||
ETH.config(ip, gateway, subnet, dns1, dns2);
|
||||
}
|
||||
void ESPMegaIoT::setETHStaticIp(IPAddress ip, IPAddress gateway, IPAddress subnet, IPAddress dns1) {
|
||||
ETH.config(ip, gateway, subnet, dns1);
|
||||
}
|
||||
void ESPMegaIoT::setETHStaticIp(IPAddress ip, IPAddress gateway, IPAddress subnet) {
|
||||
ETH.config(ip, gateway, subnet);
|
||||
}
|
||||
IPAddress ESPMegaIoT::getETHIp() {
|
||||
return ETH.localIP();
|
||||
}
|
||||
|
||||
bool ESPMegaIoT::mqttReconnect() {
|
||||
if (mqtt_useauth) {
|
||||
return this->connectToMqtt(client_id, mqtt_server, mqtt_port, mqtt_user, mqtt_password);
|
||||
} else {
|
||||
return this->connectToMqtt(client_id, mqtt_server, mqtt_port);
|
||||
}
|
||||
}
|
||||
|
||||
void ESPMegaIoT::sessionKeepAlive() {
|
||||
static unsigned long lastSessionKeepAlive = 0;
|
||||
if (millis() - lastSessionKeepAlive > 30000) {
|
||||
lastSessionKeepAlive = millis();
|
||||
// Check if mqtt is connected
|
||||
if (!mqtt.connected()) {
|
||||
// Try to reconnect
|
||||
mqtt_connected = mqttReconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ESPMegaIoT::registerRelativeMqttCallback(void (*callback)(char *, char *)) {
|
||||
user_relative_mqtt_callback = callback;
|
||||
}
|
||||
|
||||
void ESPMegaIoT::publishRelative(char *topic, char *payload) {
|
||||
char absolute_topic[100];
|
||||
sprintf(absolute_topic, "%s/%s", base_topic, topic);
|
||||
mqtt.publish(absolute_topic, payload);
|
||||
}
|
||||
|
||||
void ESPMegaIoT::subscribeRelative(char *topic) {
|
||||
char absolute_topic[100];
|
||||
sprintf(absolute_topic, "%s/%s", base_topic, topic);
|
||||
mqtt.subscribe(absolute_topic);
|
||||
}
|
||||
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 *));
|
||||
|
|
|
@ -12,11 +12,15 @@
|
|||
class ESPMegaIoT
|
||||
{
|
||||
public:
|
||||
void begin(ExpansionCard *cards[]);
|
||||
void intr_begin(ExpansionCard *cards[]);
|
||||
void loop();
|
||||
void registerCard(uint8_t card_id);
|
||||
void deregisterCard(uint8_t card_id);
|
||||
void publishCard(uint8_t card_id);
|
||||
// Publish topic appended with base topic
|
||||
void publishRelative(char *topic, char *payload);
|
||||
// Subscribe topic appended with base topic
|
||||
void subscribeRelative(char *topic);
|
||||
void subscribeToTopic(char *topic);
|
||||
void unsubscribeFromTopic(char *topic);
|
||||
void connectToEthernet();
|
||||
|
@ -25,23 +29,40 @@ class ESPMegaIoT
|
|||
void connectToWifi(char *ssid);
|
||||
void disconnectFromWifi();
|
||||
bool wifiConnected();
|
||||
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);
|
||||
bool connectToMqtt(char *client_id, char *mqtt_server, uint16_t mqtt_port, char *mqtt_user, char *mqtt_password);
|
||||
bool 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 registerRelativeMqttCallback(void (*callback)(char *, char *));
|
||||
void setBaseTopic(char *base_topic);
|
||||
void setETHStaticIp(IPAddress ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2);
|
||||
void setETHStaticIp(IPAddress ip, IPAddress gateway, IPAddress subnet, IPAddress dns1);
|
||||
void setETHStaticIp(IPAddress ip, IPAddress gateway, IPAddress subnet);
|
||||
IPAddress getETHIp();
|
||||
|
||||
private:
|
||||
void sessionKeepAlive();
|
||||
void mqttReconnect();
|
||||
bool mqttReconnect();
|
||||
void wifiReconnect();
|
||||
void mqttSubscribe();
|
||||
void mqttCallback(char *topic, byte *payload, unsigned int length);
|
||||
void (*user_mqtt_callback)(char *, char *);
|
||||
void (*user_relative_mqtt_callback)(char *, char *);
|
||||
void publishRelative(uint8_t card_id, char *topic, char *payload);
|
||||
bool active;
|
||||
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
|
||||
// MQTT Connection Parameters
|
||||
char *mqtt_server;
|
||||
uint16_t mqtt_port;
|
||||
char *mqtt_user;
|
||||
char *mqtt_password;
|
||||
char *client_id;
|
||||
bool mqtt_useauth;
|
||||
bool mqtt_connected;
|
||||
};
|
|
@ -28,6 +28,7 @@ void ESPMegaPRO::loop() {
|
|||
cards[i]->loop();
|
||||
}
|
||||
}
|
||||
iot.loop();
|
||||
}
|
||||
bool ESPMegaPRO::installCard(uint8_t slot, ExpansionCard* card) {
|
||||
if (slot > 255) return false;
|
||||
|
@ -88,3 +89,6 @@ void ESPMegaPRO::setTime(int hours, int minutes, int seconds, int day, int month
|
|||
RTC.write(timeElement);
|
||||
}
|
||||
|
||||
void ESPMegaPRO::enableIotModule() {
|
||||
iot.intr_begin(cards);
|
||||
}
|
|
@ -32,6 +32,7 @@ class ESPMegaPRO {
|
|||
void loop();
|
||||
bool installCard(uint8_t slot, ExpansionCard* card);
|
||||
bool updateTimeFromNTP();
|
||||
void enableIotModule();
|
||||
rtctime_t getTime();
|
||||
void setTime(int hours, int minutes, int seconds, int day, int month, int year);
|
||||
FRAM fram;
|
||||
|
|
|
@ -9,3 +9,13 @@ void IoTComponent::publishRelative(char *topic, char *payload) {
|
|||
sprintf(absolute_topic, "%s/%d/%s", base_topic, card_id, topic);
|
||||
mqtt->publish(absolute_topic, payload);
|
||||
}
|
||||
|
||||
void IoTComponent::subscribeRelative(char *topic) {
|
||||
char absolute_topic[100];
|
||||
sprintf(absolute_topic, "%s/%d/%s", base_topic, card_id, topic);
|
||||
mqtt->subscribe(absolute_topic);
|
||||
}
|
||||
|
||||
void IoTComponent::loop() {
|
||||
// Placeholder, Do nothing
|
||||
}
|
|
@ -8,9 +8,12 @@ class IoTComponent {
|
|||
void setMqttClient(PubSubClient *mqtt);
|
||||
virtual void publishReport();
|
||||
virtual uint8_t getType();
|
||||
virtual void subscribe();
|
||||
void loop();
|
||||
protected:
|
||||
char *base_topic;
|
||||
void publishRelative(char *topic, char *payload);
|
||||
void subscribeRelative(char *topic);
|
||||
PubSubClient *mqtt;
|
||||
uint8_t card_id;
|
||||
};
|
||||
|
|
|
@ -3,36 +3,35 @@
|
|||
// Instantiate ESPMega
|
||||
ESPMegaPRO espmega = ESPMegaPRO();
|
||||
|
||||
void mqtt_callback(char *topic, char *payload)
|
||||
{
|
||||
Serial.print("MQTT Callback: ");
|
||||
Serial.print(topic);
|
||||
Serial.print(" ");
|
||||
Serial.println(payload);
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Initialize ESPMega
|
||||
espmega.begin();
|
||||
Serial.println("ESPMega initialized");
|
||||
espmega.enableIotModule();
|
||||
espmega.iot.connectToEthernet();
|
||||
IPAddress ip(192, 168, 0, 11);
|
||||
IPAddress gateway(192, 168, 0, 1);
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
espmega.iot.setETHStaticIp(ip, gateway, subnet);
|
||||
espmega.iot.setBaseTopic("/testmegaoop");
|
||||
espmega.iot.connectToMqtt("espmega", "192.168.0.26", 1883);
|
||||
espmega.iot.publishRelative("test", "test");
|
||||
espmega.iot.subscribeRelative("test");
|
||||
espmega.iot.registerMqttCallback(mqtt_callback);
|
||||
Serial.println("ESPMega IoT initialized");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Read all the inputs and print them
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
Serial.print("Input ");
|
||||
Serial.print(i);
|
||||
Serial.print(": ");
|
||||
Serial.print(espmega.inputs.digitalRead(i));
|
||||
Serial.println();
|
||||
}
|
||||
// Turn on all the outputs
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
espmega.outputs.digitalWrite(i, true);
|
||||
}
|
||||
// Wait 1 second
|
||||
delay(1000);
|
||||
// Turn off all the outputs
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
espmega.outputs.digitalWrite(i, false);
|
||||
}
|
||||
// Wait 1 second
|
||||
delay(1000);
|
||||
// Call ESPMega loop
|
||||
espmega.loop();
|
||||
}
|
Loading…
Reference in New Issue