128 lines
4.4 KiB
C++
128 lines
4.4 KiB
C++
#include <DigitalOutputIoT.hpp>
|
|
|
|
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: <pin>/set/state payload: 0/1
|
|
// Set pin pwm topic: <pin>/set/value payload: 0-4095
|
|
// Publish pin state topic: <pin>/state payload: 0/1
|
|
// Publish pin pwm topic: <pin>/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 <pin>/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 <pin>/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);
|
|
}
|