iot components callback

This commit is contained in:
Siwat Sirichai 2023-12-28 13:14:18 +07:00
parent d3497b671e
commit 9fa8cbc4b1
10 changed files with 117 additions and 32 deletions

View File

@ -3,11 +3,15 @@
#include <AnalogCard.hpp>
class AnalogIoT : public IoTComponent {
public:
AnalogIoT();
~AnalogIoT();
bool begin(AnalogCard *card);
void handleMqttMessage(char *topic, char *payload);
void publishADCs();
void setADCsPublishInterval(uint32_t interval);
void setADCsPublishEnabled(bool enabled);
void publishReport();
uint8_t getType();
private:
char *adc_topic;
char *dac_topic;

View File

@ -11,7 +11,10 @@ class DigitalInputIoT : public IoTComponent {
void setDigitalInputsPublishEnabled(bool enabled);
void handleValueChange(uint8_t pin, uint8_t value);
void registerValueChangeCallback(void (*callback)(uint8_t, uint8_t));
void publishReport();
uint8_t getType();
private:
bool digital_inputs_publish_enabled = false;
DigitalInputCard *card;
};

View File

@ -1,11 +1,23 @@
#include <DigitalOutputIoT.hpp>
DigitalOutputIoT::DigitalOutputIoT() {
this->state_report_topic = new char[10];
this->value_report_topic = new char[10];
}
DigitalOutputIoT::~DigitalOutputIoT() {
delete[] this->state_report_topic;
delete[] this->value_report_topic;
}
bool DigitalOutputIoT::begin(ExpansionCard *card) {
this->card = (DigitalOutputCard *) card;
this->set_state_length = strlen(SET_STATE_TOPIC);
this->set_value_length = strlen(SET_VALUE_TOPIC);
this->state_length = strlen(STATE_TOPIC);
this->value_length = strlen(VALUE_TOPIC);
strcpy(this->state_report_topic, "00/state");
strcpy(this->value_report_topic, "00/value");
return true;
}
@ -100,28 +112,56 @@ bool DigitalOutputIoT::processRequestStateMessage(char *topic, char *payload, ui
}
void DigitalOutputIoT::publishDigitalOutputs() {
if(!digital_outputs_publish_enabled) return;
for(int i = 1; i <= 16; i++) {
publishDigitalOutput(i);
}
}
void DigitalOutputIoT::publishDigitalOutput(uint8_t pin) {
char ];
publishDigitalOutputState(pin);
publishDigitalOutputValue(pin);
}
void DigitalOutputIoT::publishDigitalOutputState(uint8_t pin) {
if(!digital_outputs_publish_enabled) return;
state_report_topic[0] = pin / 10 + '0';
state_report_topic[1] = pin % 10 + '0';
mqtt->publish(state_report_topic, card->getState(pin) ? "1" : "0");
}
void DigitalOutputIoT::publishDigitalOutputValue(uint8_t pin) {
if(!digital_outputs_publish_enabled) return;
value_report_topic[0] = pin / 10 + '0';
value_report_topic[1] = pin % 10 + '0';
char payload[5];
sprintf(payload, "%d", card->getValue(pin));
mqtt->publish(value_report_topic, payload);
}
void DigitalOutputIoT::setDigitalOutputsPublishEnabled(bool enabled) {
digital_outputs_publish_enabled = enabled;
}
void DigitalOutputIoT::handleValueChange(uint8_t pin, bool value, uint16_t time) {
if (digital_outputs_publish_enabled) {
char payload[17];
for (uint8_t i = 1; i <= 16; i++) {
payload[i - 1] = card->getDigitalOutput(i) ? '1' : '0';
}
payload[16] = '\0';
mqtt->publish(digital_outputs_topic, payload);
void DigitalOutputIoT::handleValueChange(uint8_t pin, bool state, uint16_t value) {
publishDigitalOutput(pin);
if(value_change_callback != NULL) {
value_change_callback(pin, state, value);
}
}
void DigitalOutputIoT::registerValueChangeCallback(void (*callback)(uint8_t, bool, uint16_t)) {
card->registerDigitalOutputValueChangeCallback(callback);
value_change_callback = callback;
}
void DigitalOutputIoT::deregisterValueChangeCallback() {
value_change_callback = NULL;
}
void DigitalOutputIoT::publishReport() {
publishDigitalOutputs();
}
uint8_t DigitalOutputIoT::getType() {
return CARD_TYPE_DIGITAL_OUTPUT;
}

View File

@ -5,19 +5,29 @@
class DigitalOutputIoT : public IoTComponent {
public:
DigitalOutputIoT();
~DigitalOutputIoT();
bool begin(ExpansionCard *card);
void handleMqttMessage(char *topic, char *payload);
void publishDigitalOutputs();
void publishDigitalOutput(uint8_t pin);
void publishDigitalOutputState(uint8_t pin);
void publishDigitalOutputValue(uint8_t pin);
void setDigitalOutputsPublishEnabled(bool enabled);
void handleValueChange(uint8_t pin, uint8_t value);
void handleValueChange(uint8_t pin, bool state, uint16_t value);
void registerValueChangeCallback(void (*callback)(uint8_t, bool, uint16_t));
void deregisterValueChangeCallback();
void publishReport();
uint8_t getType();
private:
bool digital_outputs_publish_enabled = false;
bool processSetStateMessage(char *topic, char *payload, uint8_t topic_length);
bool processSetValueMessage(char *topic, char *payload, uint8_t topic_length);
bool processRequestStateMessage(char *topic, char *payload, uint8_t topic_length);
void (*value_change_callback)(uint8_t, bool, uint16_t);
DigitalOutputCard *card;
char *state_report_topic;
char *value_report_topic;
uint8_t set_state_length;
uint8_t set_value_length;
uint8_t state_length;

View File

@ -13,22 +13,9 @@ void ESPMegaIoT::mqttCallback(char *topic, byte *payload, unsigned int length) {
char *card_id_str = strtok(topic_without_base, "/");
uint8_t card_id = atoi(card_id_str);
// Check if the card is registered
if (expansionCards[card_id] == NULL) {
if (components[card_id] == NULL) {
return;
}
// Get the card type
uint8_t card_type = expansionCards[card_id]->getType();
// Cast the card to the respective type
switch(card_type) {
case CARD_TYPE_ANALOG_INPUT:
((AnalogIoT *)expansionCards[card_id])->mqttCallback(topic_without_base + strlen(card_id_str) + 1, payload_buffer);
break;
case CARD_TYPE_DIGITAL_INPUT:
((DigitalInputIoT *)expansionCards[card_id])->mqttCallback(topic_without_base + strlen(card_id_str) + 1, payload_buffer);
break;
case CARD_TYPE_DIGITAL_OUTPUT:
((DigitalOutputIoT *)expansionCards[card_id])->mqttCallback(topic_without_base + strlen(card_id_str) + 1, payload_buffer);
break;
}
components[card_id]->handleMqttMessage(topic_without_base + 3, payload_buffer);
}

View File

@ -5,6 +5,7 @@
#include <DigitalInputIoT.hpp>
#include <DigitalOutputCard.hpp>
#include <DigitalOutputIoT.hpp>
#include <IoTComponent.hpp>
#include <PubSubClient.h>
#include <ETH.h>
@ -25,10 +26,10 @@ class ESPMegaIoT
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 disconnectFromMqtt();
void publishToTopic(char *topic, char *payload);
void registerMqttCallback(void (*callback)(char *, char *));
void checkCardType(uint8_t card_id);
private:
void sessionKeepAlive();
@ -36,7 +37,7 @@ class ESPMegaIoT
void wifiReconnect();
void mqttCallback(char *topic, byte *payload, unsigned int length);
PubSubClient mqtt;
ExpansionCard *expansionCards[255];
IoTComponent *components[255];
bool card_publish_enabled[255];
char payload_buffer[200];
char base_topic[100];

View File

@ -2,10 +2,9 @@
#include <ExpansionCard.hpp>
#include <DigitalInputCard.hpp>
#include <DigitalOutputCard.hpp>
#include <ESPMegaIoT.hpp>
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include <PCF8574.h>
#include <FRAM.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
@ -38,6 +37,7 @@ class ESPMegaPRO {
FRAM fram;
DigitalInputCard inputs = DigitalInputCard(INPUT_BANK_A_ADDRESS, INPUT_BANK_B_ADDRESS);
DigitalOutputCard outputs = DigitalOutputCard(PWM_BANK_ADDRESS);
ESPMegaIoT iot = ESPMegaIoT();
private:
ExpansionCard* cards[255];
bool cardInstalled[255];

View File

@ -6,6 +6,8 @@ class IoTComponent {
virtual bool begin(ExpansionCard *card);
virtual void handleMqttMessage(char *topic, char *payload);
void setMqttClient(PubSubClient *mqtt);
private:
virtual void publishReport();
virtual uint8_t getType();
protected:
PubSubClient *mqtt;
};

View File

@ -0,0 +1,38 @@
#include <ESPMegaPRO_OOP.hpp>
// Instantiate ESPMega
ESPMegaPRO espmega = ESPMegaPRO();
void setup()
{
// Initialize ESPMega
espmega.begin();
Serial.println("ESPMega 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);
}