ESPMegaPRO-v3-SDK/Template Project/lib/ESPMegaPRO/AnalogIoT.cpp

173 lines
6.1 KiB
C++

#include <AnalogIoT.hpp>
AnalogIoT::AnalogIoT() {
for (uint8_t i = 0; i < 8; i++) {
adc_publish_enabled[i] = false;
adc_conversion_interval[i] = 1000;
}
}
AnalogIoT::~AnalogIoT() {
}
bool AnalogIoT::begin(uint8_t card_id, ExpansionCard *card, PubSubClient *mqtt, char *base_topic) {
this->mqtt = mqtt;
this->base_topic = base_topic;
this->card = (AnalogCard*)card;
this-> card_id = card_id;
this->dac_set_state_length = strlen(DAC_SET_STATE_TOPIC);
this->dac_set_value_length = strlen(DAC_SET_VALUE_TOPIC);
this->dac_state_length = strlen(DAC_STATE_TOPIC);
this->dac_value_length = strlen(DAC_VALUE_TOPIC);
this->request_state_length = strlen(REQUEST_STATE_TOPIC);
this->dac_publish_enable_length = strlen(DAC_PUBLISH_ENABLE_TOPIC);
// Register callbacks
auto bindedCallback = std::bind(&AnalogIoT::handleDACChange, this, std::placeholders::_1, std::placeholders::_2);
this->card->registerDACChangeCallback(bindedCallback);
return true;
}
void AnalogIoT::handleMqttMessage(char *topic, char *payload){
uint8_t topic_length = strlen(topic);
if(this-> processDACSetStateMessage(topic, payload, topic_length)) return;
if(this-> processDACSetValueMessage(topic, payload, topic_length)) return;
if(this-> processRequestStateMessage(topic, payload, topic_length)) return;
if(this-> processADCSetConversionIntervalMessage(topic, payload, topic_length)) return;
if(this-> processADCSetConversionEnabledMessage(topic, payload, topic_length)) return;
}
void AnalogIoT::publishADCs() {
for (uint8_t i = 0; i < 8; i++) {
this->publishADC(i);
}
}
void AnalogIoT::publishADC(uint8_t pin) {
if (this->adc_publish_enabled[pin]) {
uint16_t value = this->card->analogRead(pin);
char *topic = new char[15];
sprintf(topic, "adc/%02d/value", pin);
char *payload = new char[10];
sprintf(payload, "%d", value);
this->publishRelative(topic, payload);
delete[] topic;
delete[] payload;
}
}
void AnalogIoT::setADCsPublishInterval(uint32_t interval) {
for (uint8_t i = 0; i < 8; i++) {
adc_conversion_interval[i] = interval;
}
}
void AnalogIoT::setADCsPublishEnabled(bool enabled) {
for (uint8_t i = 0; i < 8; i++) {
adc_publish_enabled[i] = enabled;
}
}
void AnalogIoT::registerDACChangeCallback(std::function<void(uint8_t, uint16_t)> callback) {
dac_change_callback = callback;
}
void AnalogIoT::deregisterDACChangeCallback() {
dac_change_callback = NULL;
}
void AnalogIoT::registerADCConversionCallback(std::function<void(uint8_t, uint16_t)> callback) {
adc_conversion_callback = callback;
}
void AnalogIoT::deregisterADCConversionCallback() {
adc_conversion_callback = NULL;
}
void AnalogIoT::setADCConversionInterval(uint8_t pin, uint16_t interval) {
adc_conversion_interval[pin] = interval;
}
void AnalogIoT::setADCConversionEnabled(uint8_t pin, bool enabled) {
adc_publish_enabled[pin] = enabled;
}
bool AnalogIoT::processADCSetConversionIntervalMessage(char *topic, char *payload, uint8_t topic_length) {
// TODO: publish all DACs and ADCs
}
bool AnalogIoT::processADCSetConversionEnabledMessage(char *topic, char *payload, uint8_t topic_length) {
// TODO: publish all DACs and ADCs
}
bool AnalogIoT::processDACSetStateMessage(char *topic, char *payload, uint8_t topic_length) {
// TODO: publish all DACs and ADCs
}
bool AnalogIoT::processDACSetValueMessage(char *topic, char *payload, uint8_t topic_length) {
// TODO: publish all DACs and ADCs
}
bool AnalogIoT::processRequestStateMessage(char *topic, char *payload, uint8_t topic_length) {
// TODO: publish all DACs and ADCs
}
void AnalogIoT::publishReport() {
// TODO: publish all DACs and ADCs
}
void AnalogIoT::subscribe() {
// There are 4 DACs and 8 ADCs
// DACs: dac/<%02d>/set/state, dac/<%02d>/set/value, dac/publish_enable
// ADCs: adc/<%02d>/set/conversion_interval, adc/<%02d>/set/conversion_enabled
// Subscribe to all set state topics
char topic[20];
for (uint8_t i = 0; i < 4; i++) {
sprintf(topic, "dac/%02d/set/state", i);
this->subscribeRelative(topic);
}
// Subscribe to all set value topics
for (uint8_t i = 0; i < 4; i++) {
sprintf(topic, "dac/%02d/set/value", i);
this->subscribeRelative(topic);
}
// Subscribe to all set conversion interval topics
for (uint8_t i = 0; i < 8; i++) {
sprintf(topic, "adc/%02d/set/conversion_interval", i);
this->subscribeRelative(topic);
}
// Subscribe to all set conversion enabled topics
for (uint8_t i = 0; i < 8; i++) {
sprintf(topic, "adc/%02d/set/conversion_enabled", i);
this->subscribeRelative(topic);
}
// Subscribe to publish enable topic
this->subscribeRelative("dac/publish_enable");
}
void AnalogIoT::loop() {
// Iterate over all ADCs and publish if enabled and interval has passed
uint32_t now = millis();
for (uint8_t i = 0; i < 8; i++) {
if (this->adc_publish_enabled[i] && now - this->last_adc_publish > this->adc_conversion_interval[i]) {
this->publishADC(i);
this->last_adc_publish = now;
}
}
}
void AnalogIoT::publishReport() {
publishADCs();
publishDACs();
}
uint8_t AnalogIoT::getType() {
return CARD_TYPE_ANALOG;
}
void AnalogIoT::publishDACs() {
for (uint8_t i = 0; i < 4; i++) {
this->publishDAC(i);
}
}
void AnalogIoT::publishDAC(uint8_t pin) {
this->publishDACState(pin);
this->publishDACValue(pin);
}
void AnalogIoT::publishDACState(uint8_t pin) {
char *topic = new char[15];
sprintf(topic, "dac/%02d/state", pin);
char *payload = new char[2];
sprintf(payload, "%d", this->card->getDACState(pin));
this->publishRelative(topic, payload);
delete[] topic;
delete[] payload;
}
void AnalogIoT::publishDACValue(uint8_t pin) {
char *topic = new char[15];
sprintf(topic, "dac/%02d/value", pin);
char *payload = new char[5];
sprintf(payload, "%d", this->card->getDACValue(pin));
this->publishRelative(topic, payload);
delete[] topic;
delete[] payload;
}