#include 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 callback) { dac_change_callback = callback; } void AnalogIoT::deregisterDACChangeCallback() { dac_change_callback = NULL; } void AnalogIoT::registerADCConversionCallback(std::function 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; }