IoT Component
This commit is contained in:
parent
908c3f9c0e
commit
d3497b671e
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include <IoTComponent.hpp>
|
||||
#include <AnalogCard.hpp>
|
||||
class AnalogIoT {
|
||||
class AnalogIoT : public IoTComponent {
|
||||
public:
|
||||
bool begin(AnalogCard *card);
|
||||
void handleMqttMessage(char *topic, char *payload);
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <IoTComponent.hpp>
|
||||
#include <DigitalInputCard.hpp>
|
||||
class DigitalInputIoT {
|
||||
|
||||
class DigitalInputIoT : public IoTComponent {
|
||||
public:
|
||||
bool begin(DigitalInputCard *card);
|
||||
void handleMqttMessage(char *topic, char *payload);
|
||||
|
@ -9,7 +12,6 @@ class DigitalInputIoT {
|
|||
void handleValueChange(uint8_t pin, uint8_t value);
|
||||
void registerValueChangeCallback(void (*callback)(uint8_t, uint8_t));
|
||||
private:
|
||||
char *digital_inputs_topic;
|
||||
bool digital_inputs_publish_enabled = false;
|
||||
DigitalInputCard *card;
|
||||
};
|
|
@ -27,6 +27,8 @@ bool DigitalOutputCard::begin() {
|
|||
// Set the output to the specified state
|
||||
void DigitalOutputCard::digitalWrite(uint8_t pin, bool state) {
|
||||
this->pwm.setPin(pin, state ? 4095 : 0);
|
||||
this->state_buffer[pin] = state;
|
||||
this->value_buffer[pin] = state ? 4095 : 0;
|
||||
}
|
||||
// Set the output to the specified pwm value
|
||||
void DigitalOutputCard::analogWrite(uint8_t pin, uint16_t value) {
|
||||
|
@ -34,12 +36,24 @@ void DigitalOutputCard::analogWrite(uint8_t pin, uint16_t value) {
|
|||
if (value > 4095) value = 4095;
|
||||
// Set the pwm value
|
||||
this->pwm.setPin(pin, value);
|
||||
this->state_buffer[pin] = value > 0;
|
||||
this->value_buffer[pin] = value;
|
||||
}
|
||||
|
||||
// Dummy loop function
|
||||
void DigitalOutputCard::loop() {
|
||||
}
|
||||
|
||||
// Get the state of the specified pin
|
||||
bool DigitalOutputCard::getState(uint8_t pin) {
|
||||
return this->state_buffer[pin];
|
||||
}
|
||||
|
||||
// Get the pwm value of the specified pin
|
||||
uint16_t DigitalOutputCard::getValue(uint8_t pin) {
|
||||
return this->value_buffer[pin];
|
||||
}
|
||||
|
||||
// Get type of card
|
||||
uint8_t DigitalOutputCard::getType() {
|
||||
return CARD_TYPE_DIGITAL_OUTPUT;
|
||||
|
|
|
@ -2,6 +2,22 @@
|
|||
#include <ExpansionCard.hpp>
|
||||
#include <Adafruit_PWMServoDriver.h>
|
||||
|
||||
// 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
|
||||
|
||||
#define SET_STATE_TOPIC "/set/state"
|
||||
#define SET_VALUE_TOPIC "/set/value"
|
||||
#define STATE_TOPIC "/state"
|
||||
#define VALUE_TOPIC "/value"
|
||||
#define REQUEST_STATE_TOPIC "requeststate"
|
||||
#define PUBLISH_ENABLE_TOPIC "publish_enable"
|
||||
|
||||
#define CARD_TYPE_DIGITAL_OUTPUT 0x00
|
||||
|
||||
class DigitalOutputCard : public ExpansionCard
|
||||
|
@ -19,9 +35,15 @@ public:
|
|||
void digitalWrite(uint8_t pin, bool state);
|
||||
// Set the output to the specified pwm value
|
||||
void analogWrite(uint8_t pin, uint16_t value);
|
||||
// Get the state of the specified pin
|
||||
bool getState(uint8_t pin);
|
||||
// Get the pwm value of the specified pin
|
||||
uint16_t getValue(uint8_t pin);
|
||||
// Get type of card
|
||||
uint8_t getType();
|
||||
private:
|
||||
Adafruit_PWMServoDriver pwm;
|
||||
uint8_t address;
|
||||
bool state_buffer[16];
|
||||
uint16_t value_buffer[16];
|
||||
};
|
|
@ -0,0 +1,127 @@
|
|||
#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);
|
||||
}
|
|
@ -1,4 +1,27 @@
|
|||
#pragma once
|
||||
#include <IoTComponent.hpp>
|
||||
#include <ExpansionCard.hpp>
|
||||
#include <DigitalOutputCard.hpp>
|
||||
|
||||
class DigitalOutputIoT : p
|
||||
class DigitalOutputIoT : public IoTComponent {
|
||||
public:
|
||||
bool begin(ExpansionCard *card);
|
||||
void handleMqttMessage(char *topic, char *payload);
|
||||
void publishDigitalOutputs();
|
||||
void publishDigitalOutput(uint8_t pin);
|
||||
void setDigitalOutputsPublishEnabled(bool enabled);
|
||||
void handleValueChange(uint8_t pin, uint8_t value);
|
||||
void registerValueChangeCallback(void (*callback)(uint8_t, bool, uint16_t));
|
||||
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);
|
||||
DigitalOutputCard *card;
|
||||
uint8_t set_state_length;
|
||||
uint8_t set_value_length;
|
||||
uint8_t state_length;
|
||||
uint8_t value_length;
|
||||
uint8_t request_state_length;
|
||||
uint8_t publish_enable_length;
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
#include <IoTComponent.hpp>
|
||||
|
||||
void IoTComponent::setMqttClient(PubSubClient *mqtt) {
|
||||
this->mqtt = mqtt;
|
||||
}
|
|
@ -1,2 +1,11 @@
|
|||
|
||||
class
|
||||
#pragma once
|
||||
#include <ExpansionCard.hpp>
|
||||
#include <PubSubClient.h>
|
||||
class IoTComponent {
|
||||
public:
|
||||
virtual bool begin(ExpansionCard *card);
|
||||
virtual void handleMqttMessage(char *topic, char *payload);
|
||||
void setMqttClient(PubSubClient *mqtt);
|
||||
private:
|
||||
PubSubClient *mqtt;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue