climate IoT Implementation
This commit is contained in:
parent
b1dd128aa1
commit
4c04a135ac
|
@ -106,7 +106,7 @@ void ClimateCard::setFanSpeed(uint8_t fan_speed)
|
|||
saveStateToFRAM();
|
||||
}
|
||||
|
||||
void ClimateCard::registerCallback(std::function<void(uint8_t, uint8_t, uint8_t)> callback)
|
||||
void ClimateCard::registerChangeCallback(std::function<void(uint8_t, uint8_t, uint8_t)> callback)
|
||||
{
|
||||
callbacks.push_back(callback);
|
||||
}
|
||||
|
@ -118,6 +118,8 @@ uint8_t ClimateCard::getType()
|
|||
|
||||
void ClimateCard::updateSensor()
|
||||
{
|
||||
if (sensor_type == AC_SENSOR_TYPE_NONE)
|
||||
return;
|
||||
// Read sensor data and update variables
|
||||
switch (sensor_type)
|
||||
{
|
||||
|
@ -141,6 +143,10 @@ void ClimateCard::updateSensor()
|
|||
room_temperature = ds18b20->getTempC();
|
||||
break;
|
||||
}
|
||||
for (uint8_t i = 0; i < sensor_callbacks.size(); i++)
|
||||
{
|
||||
sensor_callbacks[i](room_temperature, humidity);
|
||||
}
|
||||
}
|
||||
|
||||
void ClimateCard::updateAirConditioner()
|
||||
|
@ -150,11 +156,16 @@ void ClimateCard::updateAirConditioner()
|
|||
NEC_KHZ);
|
||||
for (uint8_t i = 0; i < callbacks.size(); i++)
|
||||
{
|
||||
callbacks[i](this->state.ac_temperature, this->state.ac_mode, this->state.ac_fan_speed);
|
||||
callbacks[i](this->state.ac_mode, this->state.ac_fan_speed, this->state.ac_temperature);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint8_t ClimateCard::getSensorType()
|
||||
{
|
||||
return sensor_type;
|
||||
}
|
||||
|
||||
float ClimateCard::getRoomTemperature()
|
||||
{
|
||||
return room_temperature;
|
||||
|
@ -179,3 +190,8 @@ uint8_t ClimateCard::getFanSpeed()
|
|||
{
|
||||
return state.ac_fan_speed;
|
||||
}
|
||||
|
||||
void ClimateCard::registerSensorCallback(std::function<void(float, float)> callback)
|
||||
{
|
||||
sensor_callbacks.push_back(callback);
|
||||
}
|
|
@ -52,7 +52,9 @@ class ClimateCard : public ExpansionCard {
|
|||
uint8_t getFanSpeed();
|
||||
float getRoomTemperature();
|
||||
float getHumidity();
|
||||
void registerCallback(std::function<void(uint8_t, uint8_t, uint8_t)> callback);
|
||||
uint8_t getSensorType();
|
||||
void registerChangeCallback(std::function<void(uint8_t, uint8_t, uint8_t)> callback);
|
||||
void registerSensorCallback(std::function<void(float, float)> callback);
|
||||
uint8_t getType();
|
||||
private:
|
||||
// Sensor objects
|
||||
|
@ -61,6 +63,7 @@ class ClimateCard : public ExpansionCard {
|
|||
DS18B20 *ds18b20;
|
||||
// Callbacks
|
||||
std::vector<std::function<void(uint8_t, uint8_t, uint8_t)>> callbacks;
|
||||
std::vector<std::function<void(float, float)>> sensor_callbacks;
|
||||
// Update functions
|
||||
void updateSensor();
|
||||
void updateAirConditioner();
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
#include <ClimateIoT.hpp>
|
||||
|
||||
ClimateIoT::ClimateIoT() {
|
||||
|
||||
}
|
||||
|
||||
ClimateIoT::~ClimateIoT() {
|
||||
// Destructor implementation
|
||||
}
|
||||
|
||||
bool ClimateIoT::begin(uint8_t card_id, ExpansionCard *card, PubSubClient *mqtt, char *base_topic) {
|
||||
this->card = (ClimateCard *)card;
|
||||
// Reister Callbacks
|
||||
auto bindedSensorCallback = std::bind(&ClimateIoT::handleSensorUpdate, this, std::placeholders::_1, std::placeholders::_2);
|
||||
this->card->registerSensorCallback(bindedSensorCallback);
|
||||
auto bindedAirConditionerCallback = std::bind(&ClimateIoT::handleAirConditionerUpdate, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
||||
this->card->registerChangeCallback(bindedAirConditionerCallback);
|
||||
}
|
||||
|
||||
void ClimateIoT::handleMqttMessage(char *topic, char *payload) {
|
||||
uint8_t topic_length = strlen(topic);
|
||||
if (this->processSetTemperatureMessage(topic, payload, topic_length))
|
||||
return;
|
||||
if (this->processSetModeMessage(topic, payload, topic_length))
|
||||
return;
|
||||
if (this->processSetFanSpeedMessage(topic, payload, topic_length))
|
||||
return;
|
||||
if (this->processRequestStateMessage(topic, payload, topic_length))
|
||||
return;
|
||||
}
|
||||
|
||||
void ClimateIoT::publishClimateTemperature() {
|
||||
char payload[5];
|
||||
itoa(this->card->getTemperature(), payload, 10);
|
||||
this->publishRelative(AC_TEMPERATURE_REPORT_TOPIC, payload);
|
||||
}
|
||||
|
||||
void ClimateIoT::publishClimateMode() {
|
||||
char payload[2];
|
||||
itoa(this->card->getMode(), payload, 10);
|
||||
this->publishRelative(AC_MODE_REPORT_TOPIC, payload);
|
||||
}
|
||||
|
||||
void ClimateIoT::publishClimateFanSpeed() {
|
||||
char payload[2];
|
||||
itoa(this->card->getFanSpeed(), payload, 10);
|
||||
this->publishRelative(AC_FAN_SPEED_REPORT_TOPIC, payload);
|
||||
}
|
||||
|
||||
void ClimateIoT::publishSensor() {
|
||||
this->publishRoomTemperature();
|
||||
this->publishHumidity();
|
||||
}
|
||||
|
||||
void ClimateIoT::publishClimate() {
|
||||
this->publishClimateTemperature();
|
||||
this->publishClimateMode();
|
||||
this->publishClimateFanSpeed();
|
||||
}
|
||||
|
||||
void ClimateIoT::publishRoomTemperature() {
|
||||
char payload[5];
|
||||
itoa(this->card->getRoomTemperature(), payload, 10);
|
||||
this->publishRelative(AC_ROOM_TEMPERATURE_REPORT_TOPIC, payload);
|
||||
}
|
||||
|
||||
void ClimateIoT::publishHumidity() {
|
||||
if (this->card->getSensorType() == AC_SENSOR_TYPE_DHT22) {
|
||||
char payload[5];
|
||||
itoa(this->card->getHumidity(), payload, 10);
|
||||
this->publishRelative(AC_HUMIDITY_REPORT_TOPIC, payload);
|
||||
}
|
||||
}
|
||||
|
||||
void ClimateIoT::handleStateChange(uint8_t temperature, uint8_t mode, uint8_t fan_speed) {
|
||||
this->publishClimate();
|
||||
}
|
||||
|
||||
void ClimateIoT::publishReport() {
|
||||
this->publishClimate();
|
||||
this->publishSensor();
|
||||
}
|
||||
|
||||
void ClimateIoT::subscribe() {
|
||||
this->subscribeRelative(AC_TEMPERATURE_SET_TOPIC);
|
||||
this->subscribeRelative(AC_MODE_SET_TOPIC);
|
||||
this->subscribeRelative(AC_FAN_SPEED_SET_TOPIC);
|
||||
}
|
||||
|
||||
void ClimateIoT::loop() {
|
||||
|
||||
}
|
||||
|
||||
uint8_t ClimateIoT::getType() {
|
||||
return CARD_TYPE_CLIMATE;
|
||||
}
|
||||
|
||||
bool ClimateIoT::processSetTemperatureMessage(char *topic, char *payload, uint8_t topic_length) {
|
||||
if (!strcmp(topic, AC_TEMPERATURE_SET_TOPIC)) {
|
||||
uint8_t temperature = atoi(payload);
|
||||
this->card->setTemperature(temperature);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ClimateIoT::processSetModeMessage(char *topic, char *payload, uint8_t topic_length) {
|
||||
if (!strcmp(topic, AC_MODE_SET_TOPIC)) {
|
||||
uint8_t mode = atoi(payload);
|
||||
this->card->setMode(mode);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ClimateIoT::processSetFanSpeedMessage(char *topic, char *payload, uint8_t topic_length) {
|
||||
if (!strcmp(topic, AC_FAN_SPEED_SET_TOPIC)) {
|
||||
uint8_t fan_speed = atoi(payload);
|
||||
this->card->setFanSpeed(fan_speed);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ClimateIoT::processRequestStateMessage(char *topic, char *payload, uint8_t topic_length) {
|
||||
if (!strcmp(topic, AC_REQUEST_STATE_TOPIC)) {
|
||||
this->publishReport();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
#include <IoTComponent.hpp>
|
||||
#include <ExpansionCard.hpp>
|
||||
#include <ClimateCard.hpp>
|
||||
|
||||
#define AC_MODE_REPORT_TOPIC "mode"
|
||||
#define AC_MODE_SET_TOPIC "set/mode"
|
||||
#define AC_TEMPERATURE_REPORT_TOPIC "temperature"
|
||||
#define AC_TEMPERATURE_SET_TOPIC "set/temperature"
|
||||
#define AC_FAN_SPEED_REPORT_TOPIC "fan_speed"
|
||||
#define AC_FAN_SPEED_SET_TOPIC "set/fan_speed"
|
||||
#define AC_ROOM_TEMPERATURE_REPORT_TOPIC "room_temperature"
|
||||
#define AC_HUMIDITY_REPORT_TOPIC "humidity"
|
||||
#define AC_REQUEST_STATE_TOPIC "request_state"
|
||||
|
||||
class ClimateIoT : public IoTComponent {
|
||||
public:
|
||||
ClimateIoT();
|
||||
~ClimateIoT();
|
||||
bool begin(uint8_t card_id, ExpansionCard *card, PubSubClient *mqtt, char *base_topic);
|
||||
void handleMqttMessage(char *topic, char *payload);
|
||||
void publishClimate();
|
||||
void publishClimateTemperature();
|
||||
void publishClimateMode();
|
||||
void publishClimateFanSpeed();
|
||||
void publishSensor();
|
||||
void publishRoomTemperature();
|
||||
void publishHumidity();
|
||||
void handleStateChange(uint8_t temperature, uint8_t mode, uint8_t fan_speed);
|
||||
void handleSensorUpdate(float temperature, float humidity);
|
||||
void handleAirConditionerUpdate(uint8_t mode, uint8_t fan_speed, uint8_t temperature);
|
||||
void publishReport();
|
||||
void subscribe();
|
||||
void loop();
|
||||
uint8_t getType();
|
||||
private:
|
||||
bool processSetTemperatureMessage(char *topic, char *payload, uint8_t topic_length);
|
||||
bool processSetModeMessage(char *topic, char *payload, uint8_t topic_length);
|
||||
bool processSetFanSpeedMessage(char *topic, char *payload, uint8_t topic_length);
|
||||
bool processRequestStateMessage(char *topic, char *payload, uint8_t topic_length);
|
||||
ClimateCard *card;
|
||||
};
|
|
@ -14,6 +14,8 @@
|
|||
#include <MCP4725.h>
|
||||
#endif
|
||||
|
||||
#warning "The procedural ESPMega library does not support installing card. If you want to use the card system, please use the OOP version of the library."
|
||||
|
||||
#define INPUT_BANK_A_ADDRESS 0x21
|
||||
#define INPUT_BANK_B_ADDRESS 0x22
|
||||
#define PWM_BANK_ADDRESS 0x5F
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <ExpansionCard.hpp>
|
||||
#include <DigitalInputCard.hpp>
|
||||
#include <DigitalOutputCard.hpp>
|
||||
#include <ClimateCard.hpp>
|
||||
#include <ESPMegaIoT.hpp>
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
|
|
Loading…
Reference in New Issue