Skip to content

Commit a38bfa6

Browse files
committed
feat: entities now inherit a common HAPEntity
a first attempt to a more cohesive entity implementation
1 parent 5b5085d commit a38bfa6

11 files changed

Lines changed: 482 additions & 422 deletions

File tree

components/homekit/climate.hpp

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,18 @@
77
#include <hap_apple_servs.h>
88
#include <hap_apple_chars.h>
99
#include "const.h"
10+
#include "hap_entity.h"
11+
1012
namespace esphome
1113
{
1214
namespace homekit
1315
{
14-
class ClimateEntity
16+
class ClimateEntity : public HAPEntity
1517
{
1618
private:
1719
static constexpr const char* TAG = "ClimateEntity";
18-
void on_climate_update(climate::Climate& obj) {
20+
climate::Climate* climatePtr;
21+
static void on_climate_update(climate::Climate& obj) {
1922
ESP_LOGI(TAG, "%s Mode: %d Action: %d CTemp: %.2f TTemp: %.2f CHum: %.2f THum: %.2f", obj.get_name().c_str(), obj.mode, obj.action, obj.current_temperature, obj.target_temperature, obj.current_humidity, obj.target_humidity);
2023
hap_acc_t* acc = hap_acc_get_by_aid(hap_get_unique_aid(std::to_string(obj.get_object_id_hash()).c_str()));
2124
if (acc) {
@@ -122,8 +125,8 @@ namespace esphome
122125
return HAP_SUCCESS;
123126
}
124127
public:
125-
ClimateEntity() {}
126-
void setup(climate::Climate* climatePtr, TemperatureUnits units = CELSIUS) {
128+
ClimateEntity(climate::Climate* climatePtr) : HAPEntity({{MODEL, "HAP-CLIMATE"}}), climatePtr(climatePtr) {}
129+
void setup(TemperatureUnits units = CELSIUS) {
127130
hap_acc_cfg_t acc_cfg = {
128131
.model = "ESP-CLIMATE",
129132
.manufacturer = "rednblkx",
@@ -136,12 +139,12 @@ namespace esphome
136139
hap_acc_t* accessory = nullptr;
137140
hap_serv_t* service = nullptr;
138141
hap_serv_t* service_fan = nullptr;
139-
std::string accessory_name = climatePtr->get_name();
142+
std::string accessory_name = this->climatePtr->get_name();
140143
acc_cfg.name = accessory_name.data();
141-
acc_cfg.serial_num = std::to_string(climatePtr->get_object_id_hash()).data();
142-
climate::ClimateTraits climateTraits = climatePtr->get_traits();
143-
climate::ClimateMode climateMode = climatePtr->mode;
144-
climate::ClimateAction climateAction = climatePtr->action;
144+
acc_cfg.serial_num = std::to_string(this->climatePtr->get_object_id_hash()).data();
145+
climate::ClimateTraits climateTraits = this->climatePtr->get_traits();
146+
climate::ClimateMode climateMode = this->climatePtr->mode;
147+
climate::ClimateAction climateAction = this->climatePtr->action;
145148
uint8_t current_mode = 0;
146149
uint8_t target_mode = 0;
147150
switch (climateAction) {
@@ -181,22 +184,22 @@ namespace esphome
181184
default:
182185
break;
183186
}
184-
ESP_LOGI(TAG, "CTemp: %.2f TTemp: %.2f CHum: %.2f THum: %.2f", climatePtr->current_temperature, climatePtr->target_temperature, climatePtr->current_humidity, climatePtr->target_humidity);
185-
service = hap_serv_thermostat_create(current_mode, target_mode, climatePtr->current_temperature, climatePtr->target_temperature, units);
187+
ESP_LOGI(TAG, "CTemp: %.2f TTemp: %.2f CHum: %.2f THum: %.2f", this->climatePtr->current_temperature, this->climatePtr->target_temperature, this->climatePtr->current_humidity, this->climatePtr->target_humidity);
188+
service = hap_serv_thermostat_create(current_mode, target_mode, this->climatePtr->current_temperature, this->climatePtr->target_temperature, units);
186189
if (climateTraits.get_supports_current_humidity()) {
187-
hap_serv_add_char(service, hap_char_current_relative_humidity_create(climatePtr->current_humidity));
190+
hap_serv_add_char(service, hap_char_current_relative_humidity_create(this->climatePtr->current_humidity));
188191
}
189192
if (climateTraits.get_supports_target_humidity()) {
190-
hap_serv_add_char(service, hap_char_target_relative_humidity_create(climatePtr->target_humidity));
193+
hap_serv_add_char(service, hap_char_target_relative_humidity_create(this->climatePtr->target_humidity));
191194
}
192-
// service_fan = hap_serv_fan_v2_create(!climatePtr->fan_mode ? 1 : 0);
195+
// service_fan = hap_serv_fan_v2_create(!this->climatePtr->fan_mode ? 1 : 0);
193196
// hap_char_swing_mode_create();
194197
// hap_serv_link_serv()
195198
if (service) {
196199
/* Create accessory object */
197200
accessory = hap_acc_create(&acc_cfg);
198-
ESP_LOGI(TAG, "ID HASH: %lu", climatePtr->get_object_id_hash());
199-
hap_serv_set_priv(service, strdup(std::to_string(climatePtr->get_object_id_hash()).c_str()));
201+
ESP_LOGI(TAG, "ID HASH: %lu", this->climatePtr->get_object_id_hash());
202+
hap_serv_set_priv(service, strdup(std::to_string(this->climatePtr->get_object_id_hash()).c_str()));
200203

201204
/* Set the write callback for the service */
202205
hap_serv_set_write_cb(service, climate_write);
@@ -207,7 +210,7 @@ namespace esphome
207210

208211

209212
/* Add the Accessory to the HomeKit Database */
210-
hap_add_bridged_accessory(accessory, hap_get_unique_aid(std::to_string(climatePtr->get_object_id_hash()).c_str()));
213+
hap_add_bridged_accessory(accessory, hap_get_unique_aid(std::to_string(this->climatePtr->get_object_id_hash()).c_str()));
211214
}
212215
}
213216
};

components/homekit/fan.hpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,16 @@
55
#include <hap.h>
66
#include <hap_apple_servs.h>
77
#include <hap_apple_chars.h>
8-
#include <map>
8+
#include "hap_entity.h"
99

1010
namespace esphome
1111
{
1212
namespace homekit
1313
{
14-
class FanEntity
14+
class FanEntity : public HAPEntity
1515
{
1616
private:
1717
static constexpr const char* TAG = "FanEntity";
18-
std::map<AInfo, const char*> accessory_info = {{NAME, NULL}, {MODEL, "HAP-FAN"}, {SN, NULL}, {MANUFACTURER, "rednblkx"}, {FW_REV, "0.1"}};
1918
fan::Fan* fanPtr;
2019
static int fanwrite(hap_write_data_t write_data[], int count, void* serv_priv, void* write_priv) {
2120
fan::Fan* fanPtr = (fan::Fan*)serv_priv;
@@ -37,7 +36,7 @@ namespace esphome
3736
}
3837
return ret;
3938
}
40-
void on_fanupdate(fan::Fan* obj) {
39+
static void on_fanupdate(fan::Fan* obj) {
4140
ESP_LOGD(TAG, "%s state: %s", obj->get_name().c_str(), ONOFF(obj->state));
4241
hap_acc_t* acc = hap_acc_get_by_aid(hap_get_unique_aid(std::to_string(obj->get_object_id_hash()).c_str()));
4342
if (acc) {
@@ -53,13 +52,7 @@ namespace esphome
5352
return HAP_SUCCESS;
5453
}
5554
public:
56-
FanEntity(fan::Fan* fanPtr) : fanPtr(fanPtr) {}
57-
void setInfo(std::map<AInfo, const char*> info) {
58-
std::map<AInfo, const char*> merged_info;
59-
merged_info.merge(info);
60-
merged_info.merge(this->accessory_info);
61-
this->accessory_info.swap(merged_info);
62-
}
55+
FanEntity(fan::Fan* fanPtr) : HAPEntity({{MODEL, "HAP-FAN"}}), fanPtr(fanPtr) {}
6356
void setup() {
6457
hap_acc_cfg_t acc_cfg = {
6558
.model = strdup(accessory_info[MODEL]),
@@ -102,7 +95,7 @@ namespace esphome
10295
/* Add the Accessory to the HomeKit Database */
10396
hap_add_bridged_accessory(accessory, hap_get_unique_aid(std::to_string(fanPtr->get_object_id_hash()).c_str()));
10497
if (!fanPtr->is_internal())
105-
fanPtr->add_on_state_callback([this]() { this->on_fanupdate(fanPtr); });
98+
fanPtr->add_on_state_callback([this]() { FanEntity::on_fanupdate(fanPtr); });
10699
ESP_LOGI(TAG, "Fan '%s' linked to HomeKit", accessory_name.c_str());
107100
}
108101
};

components/homekit/hap_entity.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#pragma once
2+
#include "const.h"
3+
#include "esphome/core/entity_base.h"
4+
#include <esp_log.h>
5+
#include <map>
6+
7+
namespace esphome
8+
{
9+
namespace homekit
10+
{
11+
class HAPEntity
12+
{
13+
private:
14+
static constexpr const char* TAG = "HAPEntity";
15+
protected:
16+
std::map<AInfo, const char*> accessory_info = { {NAME, NULL}, {MODEL, "HAP-GENERIC"}, {SN, NULL}, {MANUFACTURER, "rednblkx"}, {FW_REV, "0.1"} };
17+
public:
18+
HAPEntity(){ }
19+
HAPEntity(std::map<AInfo, const char*> accessory_info) { setInfo(accessory_info); }
20+
void setInfo(std::map<AInfo, const char*> info) {
21+
for (const auto& pair : info) {
22+
if (this->accessory_info.find(pair.first) != this->accessory_info.end()) {
23+
this->accessory_info[pair.first] = pair.second;
24+
}
25+
}
26+
}
27+
void virtual setup() { ESP_LOGI(TAG, "Uninmplemented!"); }
28+
};
29+
}
30+
}

components/homekit/light.hpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,16 @@
55
#include <hap.h>
66
#include <hap_apple_servs.h>
77
#include <hap_apple_chars.h>
8-
#include <map>
8+
#include "hap_entity.h"
99

1010
namespace esphome
1111
{
1212
namespace homekit
1313
{
14-
class LightEntity
14+
class LightEntity : public HAPEntity
1515
{
1616
private:
1717
static constexpr const char* TAG = "LightEntity";
18-
std::map<AInfo, const char*> accessory_info = {{NAME, NULL}, {MODEL, "HAP-LIGHT"}, {SN, NULL}, {MANUFACTURER, "rednblkx"}, {FW_REV, "0.1"}};
1918
light::LightState* lightPtr;
2019
static int light_write(hap_write_data_t write_data[], int count, void* serv_priv, void* write_priv) {
2120
light::LightState* lightPtr = (light::LightState*)serv_priv;
@@ -87,7 +86,7 @@ namespace esphome
8786
}
8887
return ret;
8988
}
90-
void on_light_update(light::LightState* obj) {
89+
static void on_light_update(light::LightState* obj) {
9190
bool rgb = obj->current_values.get_color_mode() & light::ColorCapability::RGB;
9291
bool level = obj->get_traits().supports_color_capability(light::ColorCapability::BRIGHTNESS);
9392
bool temperature = obj->current_values.get_color_mode() & (light::ColorCapability::COLOR_TEMPERATURE | light::ColorCapability::COLD_WARM_WHITE);
@@ -135,13 +134,7 @@ namespace esphome
135134
return HAP_SUCCESS;
136135
}
137136
public:
138-
LightEntity(light::LightState* lightPtr) : lightPtr(lightPtr) {}
139-
void setInfo(std::map<AInfo, const char*> info) {
140-
std::map<AInfo, const char*> merged_info;
141-
merged_info.merge(info);
142-
merged_info.merge(this->accessory_info);
143-
this->accessory_info.swap(merged_info);
144-
}
137+
LightEntity(light::LightState* lightPtr) : HAPEntity({{MODEL, "HAP-LIGHT"}}), lightPtr(lightPtr) {}
145138
void setup() {
146139
hap_acc_cfg_t acc_cfg = {
147140
.model = strdup(accessory_info[MODEL]),
@@ -197,7 +190,7 @@ namespace esphome
197190
/* Add the Accessory to the HomeKit Database */
198191
hap_add_bridged_accessory(accessory, hap_get_unique_aid(std::to_string(lightPtr->get_object_id_hash()).c_str()));
199192
if (!lightPtr->is_internal())
200-
lightPtr->add_new_target_state_reached_callback([this]() { this->on_light_update(lightPtr); });
193+
lightPtr->add_new_target_state_reached_callback([this]() { LightEntity::on_light_update(lightPtr); });
201194

202195
ESP_LOGI(TAG, "Light '%s' linked to HomeKit", accessory_name.c_str());
203196
}

0 commit comments

Comments
 (0)