-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathClimateIoT.cpp
258 lines (233 loc) · 8.08 KB
/
ClimateIoT.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
#include <ClimateIoT.hpp>
ClimateIoT::ClimateIoT() {
}
/**
* @brief Destructor for the ClimateIoT class.
*/
ClimateIoT::~ClimateIoT() {
// Destructor implementation
}
/**
* @brief Initializes the ClimateIoT component.
*
* This function sets the MQTT client, base topic, card ID, and card pointer.
* It also registers the sensor and air conditioner update callbacks.
*
* @param card_id The ID of the expansion card.
* @param card A pointer to the ExpansionCard object.
* @param mqtt A pointer to the PubSubClient object.
* @param base_topic The base topic for MQTT communication.
* @return True if the initialization is successful, false otherwise.
*/
bool ClimateIoT::begin(uint8_t card_id, ExpansionCard *card, PubSubClient *mqtt, char *base_topic) {
this->mqtt = mqtt;
this->base_topic = base_topic;
this->card_id = card_id;
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);
ESP_LOGD("ClimateIoT", "Climate IoT Component initialized");
return true;
}
/**
* @brief Handles MQTT messages for the ClimateIoT component.
*
* @param topic The trimmed topic of the MQTT message.
* @param payload The null-terminated payload of the MQTT message.
*/
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;
}
/**
* @brief Publishes the temperature of the air conditioner to the MQTT broker.
*/
void ClimateIoT::publishClimateTemperature() {
char payload[5];
itoa(this->card->getTemperature(), payload, 10);
this->publishRelative(AC_TEMPERATURE_REPORT_TOPIC, payload);
}
/**
* @brief Publishes the mode of the air conditioner to the MQTT broker.
*/
void ClimateIoT::publishClimateMode() {
this->publishRelative(AC_MODE_REPORT_TOPIC, this->card->getModeName());
}
/**
* @brief Publishes the fan speed of the air conditioner to the MQTT broker.
*/
void ClimateIoT::publishClimateFanSpeed() {
this->publishRelative(AC_FAN_SPEED_REPORT_TOPIC, this->card->getFanSpeedName());
}
/**
* @brief Publishes the temperature and humidity of the room to the MQTT broker.
*/
void ClimateIoT::publishSensor() {
this->publishRoomTemperature();
this->publishHumidity();
}
/**
* @brief Publishes the climate data (temperature, mode, fan speed) to the MQTT broker.
*/
void ClimateIoT::publishClimate() {
this->publishClimateTemperature();
this->publishClimateMode();
this->publishClimateFanSpeed();
}
/**
* @brief Publishes the room temperature to the MQTT broker.
*/
void ClimateIoT::publishRoomTemperature() {
if (this->card->getSensorType() == AC_SENSOR_TYPE_NONE ) {
return;
}
char payload[5];
itoa(this->card->getRoomTemperature(), payload, 10);
this->publishRelative(AC_ROOM_TEMPERATURE_REPORT_TOPIC, payload);
}
/**
* @brief Publishes the humidity of the room to the MQTT broker.
*/
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);
}
}
/**
* @brief Handle Air Conditioner state change.
*
* @note This function is called by the underlying ClimateCard object and is not meant to be called manually.
*
* @param temperature Temperature of the air conditioner
* @param mode Mode of the air conditioner
* @param fan_speed Fan speed of the air conditioner
*/
void ClimateIoT::handleStateChange(uint8_t temperature, uint8_t mode, uint8_t fan_speed) {
this->publishClimate();
}
/**
* @brief Publishes the climate and sensor data to the MQTT broker.
*/
void ClimateIoT::publishReport() {
this->publishClimate();
this->publishSensor();
}
/**
* @brief Subscribes to MQTT topics.
*/
void ClimateIoT::subscribe() {
ESP_LOGD("ClimateIoT", " topics");
this->subscribeRelative(AC_TEMPERATURE_SET_TOPIC);
this->subscribeRelative(AC_MODE_SET_TOPIC);
this->subscribeRelative(AC_FAN_SPEED_SET_TOPIC);
this->subscribeRelative(AC_REQUEST_STATE_TOPIC);
ESP_LOGD("ClimateIoT", "Subscribed to topics");
}
/**
* @brief The loop function for the ClimateIoT component.
*
* @note This function does nothing.
*/
void ClimateIoT::loop() {
}
/**
* @brief Returns the type of the expansion card.
*
* @return The type of the expansion card.
*/
uint8_t ClimateIoT::getType() {
return CARD_TYPE_CLIMATE;
}
/**
* @brief Processes the set temperature MQTT message.
*
* @param topic The trimmed topic of the MQTT message.
* @param payload The null-terminated payload of the MQTT message.
* @param topic_length The length of the topic.
* @return True if the message is processed, false otherwise.
*/
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;
}
/**
* @brief Processes the set mode MQTT message.
*
* @param topic The trimmed topic of the MQTT message.
* @param payload The null-terminated payload of the MQTT message.
* @param topic_length The length of the topic.
* @return True if the message is processed, false otherwise.
*/
bool ClimateIoT::processSetModeMessage(char *topic, char *payload, uint8_t topic_length) {
if (!strcmp(topic, AC_MODE_SET_TOPIC)) {
this->card->setModeByName(payload);
return true;
}
return false;
}
/**
* @brief Processes the set fan speed MQTT message.
*
* @param topic The trimmed topic of the MQTT message.
* @param payload The null-terminated payload of the MQTT message.
* @param topic_length The length of the topic.
* @return True if the message is processed, false otherwise.
*/
bool ClimateIoT::processSetFanSpeedMessage(char *topic, char *payload, uint8_t topic_length) {
if (!strcmp(topic, AC_FAN_SPEED_SET_TOPIC)) {
this->card->setFanSpeedByName(payload);
}
return false;
}
/**
* @brief Processes the request state MQTT message.
*
* @param topic The trimmed topic of the MQTT message.
* @param payload The null-terminated payload of the MQTT message.
* @param topic_length The length of the topic.
* @return True if the message is processed, false otherwise.
*/
bool ClimateIoT::processRequestStateMessage(char *topic, char *payload, uint8_t topic_length) {
if (!strcmp(topic, AC_REQUEST_STATE_TOPIC)) {
this->publishReport();
return true;
}
return false;
}
/**
* @brief This function is a callback function registered with the Climate card to be called when the sensor data is updated.
*
* @param temperature The room temperature.
* @param humidity The room humidity.
*
* @note The temperature and humidity are not used in this function but are required by the ClimateCard class to match the signature of the callback function.
*/
void ClimateIoT::handleSensorUpdate(float temperature, float humidity) {
this->publishSensor();
}
/**
* @brief This function is a callback function registered with the Climate card to be called when the air conditioner state is updated.
*
* @param mode The mode of the air conditioner.
* @param fan_speed The fan speed of the air conditioner.
* @param temperature The temperature of the air conditioner.
*/
void ClimateIoT::handleAirConditionerUpdate(uint8_t mode, uint8_t fan_speed, uint8_t temperature) {
this->publishClimate();
}