climate IoT Implementation
This commit is contained in:
parent
b1dd128aa1
commit
4c04a135ac
|
@ -106,7 +106,7 @@ void ClimateCard::setFanSpeed(uint8_t fan_speed)
|
||||||
saveStateToFRAM();
|
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);
|
callbacks.push_back(callback);
|
||||||
}
|
}
|
||||||
|
@ -118,6 +118,8 @@ uint8_t ClimateCard::getType()
|
||||||
|
|
||||||
void ClimateCard::updateSensor()
|
void ClimateCard::updateSensor()
|
||||||
{
|
{
|
||||||
|
if (sensor_type == AC_SENSOR_TYPE_NONE)
|
||||||
|
return;
|
||||||
// Read sensor data and update variables
|
// Read sensor data and update variables
|
||||||
switch (sensor_type)
|
switch (sensor_type)
|
||||||
{
|
{
|
||||||
|
@ -141,6 +143,10 @@ void ClimateCard::updateSensor()
|
||||||
room_temperature = ds18b20->getTempC();
|
room_temperature = ds18b20->getTempC();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
for (uint8_t i = 0; i < sensor_callbacks.size(); i++)
|
||||||
|
{
|
||||||
|
sensor_callbacks[i](room_temperature, humidity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClimateCard::updateAirConditioner()
|
void ClimateCard::updateAirConditioner()
|
||||||
|
@ -150,11 +156,16 @@ void ClimateCard::updateAirConditioner()
|
||||||
NEC_KHZ);
|
NEC_KHZ);
|
||||||
for (uint8_t i = 0; i < callbacks.size(); i++)
|
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()
|
float ClimateCard::getRoomTemperature()
|
||||||
{
|
{
|
||||||
return room_temperature;
|
return room_temperature;
|
||||||
|
@ -178,4 +189,9 @@ uint8_t ClimateCard::getMode()
|
||||||
uint8_t ClimateCard::getFanSpeed()
|
uint8_t ClimateCard::getFanSpeed()
|
||||||
{
|
{
|
||||||
return state.ac_fan_speed;
|
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();
|
uint8_t getFanSpeed();
|
||||||
float getRoomTemperature();
|
float getRoomTemperature();
|
||||||
float getHumidity();
|
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();
|
uint8_t getType();
|
||||||
private:
|
private:
|
||||||
// Sensor objects
|
// Sensor objects
|
||||||
|
@ -61,6 +63,7 @@ class ClimateCard : public ExpansionCard {
|
||||||
DS18B20 *ds18b20;
|
DS18B20 *ds18b20;
|
||||||
// Callbacks
|
// Callbacks
|
||||||
std::vector<std::function<void(uint8_t, uint8_t, uint8_t)>> callbacks;
|
std::vector<std::function<void(uint8_t, uint8_t, uint8_t)>> callbacks;
|
||||||
|
std::vector<std::function<void(float, float)>> sensor_callbacks;
|
||||||
// Update functions
|
// Update functions
|
||||||
void updateSensor();
|
void updateSensor();
|
||||||
void updateAirConditioner();
|
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>
|
#include <MCP4725.h>
|
||||||
#endif
|
#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_A_ADDRESS 0x21
|
||||||
#define INPUT_BANK_B_ADDRESS 0x22
|
#define INPUT_BANK_B_ADDRESS 0x22
|
||||||
#define PWM_BANK_ADDRESS 0x5F
|
#define PWM_BANK_ADDRESS 0x5F
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <ExpansionCard.hpp>
|
#include <ExpansionCard.hpp>
|
||||||
#include <DigitalInputCard.hpp>
|
#include <DigitalInputCard.hpp>
|
||||||
#include <DigitalOutputCard.hpp>
|
#include <DigitalOutputCard.hpp>
|
||||||
|
#include <ClimateCard.hpp>
|
||||||
#include <ESPMegaIoT.hpp>
|
#include <ESPMegaIoT.hpp>
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
|
|
Loading…
Reference in New Issue