#include 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); return true; } // Protocol for digital output card // Note that pin is always 2 characters long and padded with 0 if necessary // Set pin state topic: /set/state payload: 0/1 // Set pin pwm topic: /set/value payload: 0-4095 // Publish pin state topic: /state payload: 0/1 // Publish pin pwm topic: /value payload: 0-4095 // Publish all topic: requeststate payload: N/A // Enable/disable publish topic: publish_enable payload: 0/1 void DigitalOutputIoT::handleMqttMessage(char *topic, char *payload) { uint8_t topic_length = strlen(topic); if(this-> processSetStateMessage(topic, payload, topic_length)) return; if(this-> processSetValueMessage(topic, payload, topic_length)) return; if(this-> processRequestStateMessage(topic, payload, topic_length)) return; } bool DigitalOutputIoT::processSetStateMessage(char *topic, char *payload, uint8_t topic_length) { // Check if the topic is a set state topic // The correct format is /set/state // This mean that the topic must end with /set/state // Check if the 3rd character is / if(topic[2] != '/') { return false; } // The topic must be set_state_length + 2 characters long if(topic_length != set_state_length + 2) { return false; } // Check if the topic ends with /set/state if (!strncmp(topic+2, SET_STATE_TOPIC, set_state_length)) { // Get the pin number uint8_t pin = (topic[0] - '0')*10 + (topic[1] - '0'); // Get the state bool state = false; char state_char = payload[0]; if (state_char == '0') { bool state = false; } else if (state_char == '1') { bool state = true; } else { return false; } // Set the state card->digitalWrite(pin, state); return true; } return false; } bool DigitalOutputIoT::processSetValueMessage(char *topic, char *payload, uint8_t topic_length) { // Check if the topic is a set value topic // The correct format is /set/value // This mean that the topic must end with /set/value // Check if the 3rd character is / if(topic[2] != '/') { return false; } // The topic must be set_value_length + 2 characters long if(topic_length != set_value_length + 2) { return false; } // Check if the topic ends with /set/value if (!strncmp(topic+2, SET_VALUE_TOPIC, set_value_length)) { // Get the pin number uint8_t pin = (topic[0] - '0')*10 + (topic[1] - '0'); // Get the value uint16_t value = atoi(payload); // Set the value card->analogWrite(pin, value); return true; } return false; } bool DigitalOutputIoT::processRequestStateMessage(char *topic, char *payload, uint8_t topic_length) { // Check if the topic is a request state topic // The correct format is requeststate // This mean that the topic must be request_state_length characters long // The topic must be request_state_length characters long if(topic_length != request_state_length) { return false; } // Check if the topic is requeststate if (!strncmp(topic, REQUEST_STATE_TOPIC, request_state_length)) { // Publish the state of all pins publishDigitalOutputs(); return true; } return false; } void DigitalOutputIoT::publishDigitalOutputs() { } void DigitalOutputIoT::publishDigitalOutput(uint8_t pin) { char ]; } 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::registerValueChangeCallback(void (*callback)(uint8_t, bool, uint16_t)) { card->registerDigitalOutputValueChangeCallback(callback); }