mirror of
https://github.com/esphome/esphome.git
synced 2025-03-15 07:08:20 +00:00
Merge branch 'dev' into optolink
This commit is contained in:
commit
99e01efdec
60
.github/workflows/sync-device-classes.yml
vendored
Normal file
60
.github/workflows/sync-device-classes.yml
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
name: Synchronise Device Classes from Home Assistant
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: '45 6 * * *'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
sync:
|
||||||
|
name: Sync Device Classes
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Checkout Home Assistant
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
repository: home-assistant/core
|
||||||
|
path: lib/home-assistant
|
||||||
|
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: 3.11
|
||||||
|
|
||||||
|
- name: Install Home Assistant
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install -e lib/home-assistant
|
||||||
|
|
||||||
|
- name: Sync
|
||||||
|
run: |
|
||||||
|
python ./script/sync-device_class.py
|
||||||
|
|
||||||
|
- name: Get PR template
|
||||||
|
id: pr-template-body
|
||||||
|
run: |
|
||||||
|
body=$(cat .github/PULL_REQUEST_TEMPLATE.md)
|
||||||
|
delimiter="$(openssl rand -hex 8)"
|
||||||
|
echo "body<<$delimiter" >> $GITHUB_OUTPUT
|
||||||
|
echo "$body" >> $GITHUB_OUTPUT
|
||||||
|
echo "$delimiter" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Commit changes
|
||||||
|
uses: peter-evans/create-pull-request@v4
|
||||||
|
with:
|
||||||
|
commit-message: "Synchronise Device Classes from Home Assistant"
|
||||||
|
committer: esphomebot <esphome@nabucasa.com>
|
||||||
|
author: esphomebot <esphome@nabucasa.com>
|
||||||
|
branch: sync/device-classes/
|
||||||
|
branch-suffix: timestamp
|
||||||
|
delete-branch: true
|
||||||
|
title: "Synchronise Device Classes from Home Assistant"
|
||||||
|
body: ${{ steps.pr-template-body.outputs.body }}
|
@ -53,6 +53,8 @@ service APIConnection {
|
|||||||
rpc bluetooth_gatt_write_descriptor(BluetoothGATTWriteDescriptorRequest) returns (void) {}
|
rpc bluetooth_gatt_write_descriptor(BluetoothGATTWriteDescriptorRequest) returns (void) {}
|
||||||
rpc bluetooth_gatt_notify(BluetoothGATTNotifyRequest) returns (void) {}
|
rpc bluetooth_gatt_notify(BluetoothGATTNotifyRequest) returns (void) {}
|
||||||
rpc subscribe_bluetooth_connections_free(SubscribeBluetoothConnectionsFreeRequest) returns (BluetoothConnectionsFreeResponse) {}
|
rpc subscribe_bluetooth_connections_free(SubscribeBluetoothConnectionsFreeRequest) returns (BluetoothConnectionsFreeResponse) {}
|
||||||
|
rpc unsubscribe_bluetooth_le_advertisements(UnsubscribeBluetoothLEAdvertisementsRequest) returns (void) {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1125,6 +1127,7 @@ message MediaPlayerCommandRequest {
|
|||||||
message SubscribeBluetoothLEAdvertisementsRequest {
|
message SubscribeBluetoothLEAdvertisementsRequest {
|
||||||
option (id) = 66;
|
option (id) = 66;
|
||||||
option (source) = SOURCE_CLIENT;
|
option (source) = SOURCE_CLIENT;
|
||||||
|
option (ifdef) = "USE_BLUETOOTH_PROXY";
|
||||||
}
|
}
|
||||||
|
|
||||||
message BluetoothServiceData {
|
message BluetoothServiceData {
|
||||||
@ -1361,6 +1364,12 @@ message BluetoothDeviceUnpairingResponse {
|
|||||||
int32 error = 3;
|
int32 error = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message UnsubscribeBluetoothLEAdvertisementsRequest {
|
||||||
|
option (id) = 87;
|
||||||
|
option (source) = SOURCE_CLIENT;
|
||||||
|
option (ifdef) = "USE_BLUETOOTH_PROXY";
|
||||||
|
}
|
||||||
|
|
||||||
message BluetoothDeviceClearCacheResponse {
|
message BluetoothDeviceClearCacheResponse {
|
||||||
option (id) = 88;
|
option (id) = 88;
|
||||||
option (source) = SOURCE_SERVER;
|
option (source) = SOURCE_SERVER;
|
||||||
|
@ -97,6 +97,12 @@ class APIConnection : public APIServerConnection {
|
|||||||
this->send_homeassistant_service_response(call);
|
this->send_homeassistant_service_response(call);
|
||||||
}
|
}
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
|
void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) override {
|
||||||
|
this->bluetooth_le_advertisement_subscription_ = true;
|
||||||
|
}
|
||||||
|
void unsubscribe_bluetooth_le_advertisements(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) override {
|
||||||
|
this->bluetooth_le_advertisement_subscription_ = false;
|
||||||
|
}
|
||||||
bool send_bluetooth_le_advertisement(const BluetoothLEAdvertisementResponse &msg);
|
bool send_bluetooth_le_advertisement(const BluetoothLEAdvertisementResponse &msg);
|
||||||
|
|
||||||
void bluetooth_device_request(const BluetoothDeviceRequest &msg) override;
|
void bluetooth_device_request(const BluetoothDeviceRequest &msg) override;
|
||||||
@ -150,9 +156,7 @@ class APIConnection : public APIServerConnection {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
void execute_service(const ExecuteServiceRequest &msg) override;
|
void execute_service(const ExecuteServiceRequest &msg) override;
|
||||||
void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) override {
|
|
||||||
this->bluetooth_le_advertisement_subscription_ = true;
|
|
||||||
}
|
|
||||||
bool is_authenticated() override { return this->connection_state_ == ConnectionState::AUTHENTICATED; }
|
bool is_authenticated() override { return this->connection_state_ == ConnectionState::AUTHENTICATED; }
|
||||||
bool is_connection_setup() override {
|
bool is_connection_setup() override {
|
||||||
return this->connection_state_ == ConnectionState ::CONNECTED || this->is_authenticated();
|
return this->connection_state_ == ConnectionState ::CONNECTED || this->is_authenticated();
|
||||||
@ -197,7 +201,9 @@ class APIConnection : public APIServerConnection {
|
|||||||
uint32_t last_traffic_;
|
uint32_t last_traffic_;
|
||||||
bool sent_ping_{false};
|
bool sent_ping_{false};
|
||||||
bool service_call_subscription_{false};
|
bool service_call_subscription_{false};
|
||||||
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
bool bluetooth_le_advertisement_subscription_{false};
|
bool bluetooth_le_advertisement_subscription_{false};
|
||||||
|
#endif
|
||||||
bool next_close_ = false;
|
bool next_close_ = false;
|
||||||
APIServer *parent_;
|
APIServer *parent_;
|
||||||
InitialStateIterator initial_state_iterator_;
|
InitialStateIterator initial_state_iterator_;
|
||||||
|
@ -6062,6 +6062,12 @@ void BluetoothDeviceUnpairingResponse::dump_to(std::string &out) const {
|
|||||||
out.append("}");
|
out.append("}");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
void UnsubscribeBluetoothLEAdvertisementsRequest::encode(ProtoWriteBuffer buffer) const {}
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
void UnsubscribeBluetoothLEAdvertisementsRequest::dump_to(std::string &out) const {
|
||||||
|
out.append("UnsubscribeBluetoothLEAdvertisementsRequest {}");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
bool BluetoothDeviceClearCacheResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
|
bool BluetoothDeviceClearCacheResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
|
||||||
switch (field_id) {
|
switch (field_id) {
|
||||||
case 1: {
|
case 1: {
|
||||||
|
@ -1555,6 +1555,15 @@ class BluetoothDeviceUnpairingResponse : public ProtoMessage {
|
|||||||
protected:
|
protected:
|
||||||
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
|
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
|
||||||
};
|
};
|
||||||
|
class UnsubscribeBluetoothLEAdvertisementsRequest : public ProtoMessage {
|
||||||
|
public:
|
||||||
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
void dump_to(std::string &out) const override;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
};
|
||||||
class BluetoothDeviceClearCacheResponse : public ProtoMessage {
|
class BluetoothDeviceClearCacheResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
|
@ -329,6 +329,8 @@ bool APIServerConnectionBase::send_media_player_state_response(const MediaPlayer
|
|||||||
#ifdef USE_MEDIA_PLAYER
|
#ifdef USE_MEDIA_PLAYER
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
|
#endif
|
||||||
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
bool APIServerConnectionBase::send_bluetooth_le_advertisement_response(const BluetoothLEAdvertisementResponse &msg) {
|
bool APIServerConnectionBase::send_bluetooth_le_advertisement_response(const BluetoothLEAdvertisementResponse &msg) {
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_le_advertisement_response: %s", msg.dump().c_str());
|
ESP_LOGVV(TAG, "send_bluetooth_le_advertisement_response: %s", msg.dump().c_str());
|
||||||
@ -442,6 +444,8 @@ bool APIServerConnectionBase::send_bluetooth_device_unpairing_response(const Blu
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
|
#endif
|
||||||
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
bool APIServerConnectionBase::send_bluetooth_device_clear_cache_response(const BluetoothDeviceClearCacheResponse &msg) {
|
bool APIServerConnectionBase::send_bluetooth_device_clear_cache_response(const BluetoothDeviceClearCacheResponse &msg) {
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_device_clear_cache_response: %s", msg.dump().c_str());
|
ESP_LOGVV(TAG, "send_bluetooth_device_clear_cache_response: %s", msg.dump().c_str());
|
||||||
@ -717,12 +721,14 @@ bool APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 66: {
|
case 66: {
|
||||||
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
SubscribeBluetoothLEAdvertisementsRequest msg;
|
SubscribeBluetoothLEAdvertisementsRequest msg;
|
||||||
msg.decode(msg_data, msg_size);
|
msg.decode(msg_data, msg_size);
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
ESP_LOGVV(TAG, "on_subscribe_bluetooth_le_advertisements_request: %s", msg.dump().c_str());
|
ESP_LOGVV(TAG, "on_subscribe_bluetooth_le_advertisements_request: %s", msg.dump().c_str());
|
||||||
#endif
|
#endif
|
||||||
this->on_subscribe_bluetooth_le_advertisements_request(msg);
|
this->on_subscribe_bluetooth_le_advertisements_request(msg);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 68: {
|
case 68: {
|
||||||
@ -810,6 +816,17 @@ bool APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
|||||||
ESP_LOGVV(TAG, "on_subscribe_bluetooth_connections_free_request: %s", msg.dump().c_str());
|
ESP_LOGVV(TAG, "on_subscribe_bluetooth_connections_free_request: %s", msg.dump().c_str());
|
||||||
#endif
|
#endif
|
||||||
this->on_subscribe_bluetooth_connections_free_request(msg);
|
this->on_subscribe_bluetooth_connections_free_request(msg);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 87: {
|
||||||
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
|
UnsubscribeBluetoothLEAdvertisementsRequest msg;
|
||||||
|
msg.decode(msg_data, msg_size);
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
ESP_LOGVV(TAG, "on_unsubscribe_bluetooth_le_advertisements_request: %s", msg.dump().c_str());
|
||||||
|
#endif
|
||||||
|
this->on_unsubscribe_bluetooth_le_advertisements_request(msg);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1073,6 +1090,7 @@ void APIServerConnection::on_media_player_command_request(const MediaPlayerComma
|
|||||||
this->media_player_command(msg);
|
this->media_player_command(msg);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
void APIServerConnection::on_subscribe_bluetooth_le_advertisements_request(
|
void APIServerConnection::on_subscribe_bluetooth_le_advertisements_request(
|
||||||
const SubscribeBluetoothLEAdvertisementsRequest &msg) {
|
const SubscribeBluetoothLEAdvertisementsRequest &msg) {
|
||||||
if (!this->is_connection_setup()) {
|
if (!this->is_connection_setup()) {
|
||||||
@ -1085,6 +1103,7 @@ void APIServerConnection::on_subscribe_bluetooth_le_advertisements_request(
|
|||||||
}
|
}
|
||||||
this->subscribe_bluetooth_le_advertisements(msg);
|
this->subscribe_bluetooth_le_advertisements(msg);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
void APIServerConnection::on_bluetooth_device_request(const BluetoothDeviceRequest &msg) {
|
void APIServerConnection::on_bluetooth_device_request(const BluetoothDeviceRequest &msg) {
|
||||||
if (!this->is_connection_setup()) {
|
if (!this->is_connection_setup()) {
|
||||||
@ -1193,6 +1212,20 @@ void APIServerConnection::on_subscribe_bluetooth_connections_free_request(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
|
void APIServerConnection::on_unsubscribe_bluetooth_le_advertisements_request(
|
||||||
|
const UnsubscribeBluetoothLEAdvertisementsRequest &msg) {
|
||||||
|
if (!this->is_connection_setup()) {
|
||||||
|
this->on_no_setup_connection();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this->is_authenticated()) {
|
||||||
|
this->on_unauthenticated_access();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->unsubscribe_bluetooth_le_advertisements(msg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
@ -154,8 +154,10 @@ class APIServerConnectionBase : public ProtoService {
|
|||||||
#ifdef USE_MEDIA_PLAYER
|
#ifdef USE_MEDIA_PLAYER
|
||||||
virtual void on_media_player_command_request(const MediaPlayerCommandRequest &value){};
|
virtual void on_media_player_command_request(const MediaPlayerCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
virtual void on_subscribe_bluetooth_le_advertisements_request(
|
virtual void on_subscribe_bluetooth_le_advertisements_request(
|
||||||
const SubscribeBluetoothLEAdvertisementsRequest &value){};
|
const SubscribeBluetoothLEAdvertisementsRequest &value){};
|
||||||
|
#endif
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
bool send_bluetooth_le_advertisement_response(const BluetoothLEAdvertisementResponse &msg);
|
bool send_bluetooth_le_advertisement_response(const BluetoothLEAdvertisementResponse &msg);
|
||||||
#endif
|
#endif
|
||||||
@ -216,6 +218,10 @@ class APIServerConnectionBase : public ProtoService {
|
|||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
bool send_bluetooth_device_unpairing_response(const BluetoothDeviceUnpairingResponse &msg);
|
bool send_bluetooth_device_unpairing_response(const BluetoothDeviceUnpairingResponse &msg);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
|
virtual void on_unsubscribe_bluetooth_le_advertisements_request(
|
||||||
|
const UnsubscribeBluetoothLEAdvertisementsRequest &value){};
|
||||||
|
#endif
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
bool send_bluetooth_device_clear_cache_response(const BluetoothDeviceClearCacheResponse &msg);
|
bool send_bluetooth_device_clear_cache_response(const BluetoothDeviceClearCacheResponse &msg);
|
||||||
#endif
|
#endif
|
||||||
@ -270,7 +276,9 @@ class APIServerConnection : public APIServerConnectionBase {
|
|||||||
#ifdef USE_MEDIA_PLAYER
|
#ifdef USE_MEDIA_PLAYER
|
||||||
virtual void media_player_command(const MediaPlayerCommandRequest &msg) = 0;
|
virtual void media_player_command(const MediaPlayerCommandRequest &msg) = 0;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
virtual void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) = 0;
|
virtual void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) = 0;
|
||||||
|
#endif
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
virtual void bluetooth_device_request(const BluetoothDeviceRequest &msg) = 0;
|
virtual void bluetooth_device_request(const BluetoothDeviceRequest &msg) = 0;
|
||||||
#endif
|
#endif
|
||||||
@ -295,6 +303,9 @@ class APIServerConnection : public APIServerConnectionBase {
|
|||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
virtual BluetoothConnectionsFreeResponse subscribe_bluetooth_connections_free(
|
virtual BluetoothConnectionsFreeResponse subscribe_bluetooth_connections_free(
|
||||||
const SubscribeBluetoothConnectionsFreeRequest &msg) = 0;
|
const SubscribeBluetoothConnectionsFreeRequest &msg) = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
|
virtual void unsubscribe_bluetooth_le_advertisements(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) = 0;
|
||||||
#endif
|
#endif
|
||||||
protected:
|
protected:
|
||||||
void on_hello_request(const HelloRequest &msg) override;
|
void on_hello_request(const HelloRequest &msg) override;
|
||||||
@ -342,7 +353,9 @@ class APIServerConnection : public APIServerConnectionBase {
|
|||||||
#ifdef USE_MEDIA_PLAYER
|
#ifdef USE_MEDIA_PLAYER
|
||||||
void on_media_player_command_request(const MediaPlayerCommandRequest &msg) override;
|
void on_media_player_command_request(const MediaPlayerCommandRequest &msg) override;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
void on_subscribe_bluetooth_le_advertisements_request(const SubscribeBluetoothLEAdvertisementsRequest &msg) override;
|
void on_subscribe_bluetooth_le_advertisements_request(const SubscribeBluetoothLEAdvertisementsRequest &msg) override;
|
||||||
|
#endif
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
void on_bluetooth_device_request(const BluetoothDeviceRequest &msg) override;
|
void on_bluetooth_device_request(const BluetoothDeviceRequest &msg) override;
|
||||||
#endif
|
#endif
|
||||||
@ -367,6 +380,10 @@ class APIServerConnection : public APIServerConnectionBase {
|
|||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
void on_subscribe_bluetooth_connections_free_request(const SubscribeBluetoothConnectionsFreeRequest &msg) override;
|
void on_subscribe_bluetooth_connections_free_request(const SubscribeBluetoothConnectionsFreeRequest &msg) override;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
|
void on_unsubscribe_bluetooth_le_advertisements_request(
|
||||||
|
const UnsubscribeBluetoothLEAdvertisementsRequest &msg) override;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
|
@ -12,7 +12,6 @@ from esphome.const import (
|
|||||||
CONF_CAPACITANCE,
|
CONF_CAPACITANCE,
|
||||||
)
|
)
|
||||||
|
|
||||||
AUTO_LOAD = ["sensor", "binary_sensor"]
|
|
||||||
MULTI_CONF = True
|
MULTI_CONF = True
|
||||||
|
|
||||||
CONF_AS3935_ID = "as3935_id"
|
CONF_AS3935_ID = "as3935_id"
|
||||||
|
@ -26,9 +26,13 @@ void AS3935Component::setup() {
|
|||||||
void AS3935Component::dump_config() {
|
void AS3935Component::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, "AS3935:");
|
ESP_LOGCONFIG(TAG, "AS3935:");
|
||||||
LOG_PIN(" Interrupt Pin: ", this->irq_pin_);
|
LOG_PIN(" Interrupt Pin: ", this->irq_pin_);
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
LOG_BINARY_SENSOR(" ", "Thunder alert", this->thunder_alert_binary_sensor_);
|
LOG_BINARY_SENSOR(" ", "Thunder alert", this->thunder_alert_binary_sensor_);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SENSOR
|
||||||
LOG_SENSOR(" ", "Distance", this->distance_sensor_);
|
LOG_SENSOR(" ", "Distance", this->distance_sensor_);
|
||||||
LOG_SENSOR(" ", "Lightning energy", this->energy_sensor_);
|
LOG_SENSOR(" ", "Lightning energy", this->energy_sensor_);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
float AS3935Component::get_setup_priority() const { return setup_priority::DATA; }
|
float AS3935Component::get_setup_priority() const { return setup_priority::DATA; }
|
||||||
@ -44,16 +48,22 @@ void AS3935Component::loop() {
|
|||||||
ESP_LOGI(TAG, "Disturber was detected - try increasing the spike rejection value!");
|
ESP_LOGI(TAG, "Disturber was detected - try increasing the spike rejection value!");
|
||||||
} else if (int_value == LIGHTNING_INT) {
|
} else if (int_value == LIGHTNING_INT) {
|
||||||
ESP_LOGI(TAG, "Lightning has been detected!");
|
ESP_LOGI(TAG, "Lightning has been detected!");
|
||||||
if (this->thunder_alert_binary_sensor_ != nullptr)
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
if (this->thunder_alert_binary_sensor_ != nullptr) {
|
||||||
this->thunder_alert_binary_sensor_->publish_state(true);
|
this->thunder_alert_binary_sensor_->publish_state(true);
|
||||||
|
this->set_timeout(10, [this]() { this->thunder_alert_binary_sensor_->publish_state(false); });
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SENSOR
|
||||||
uint8_t distance = this->get_distance_to_storm_();
|
uint8_t distance = this->get_distance_to_storm_();
|
||||||
if (this->distance_sensor_ != nullptr)
|
if (this->distance_sensor_ != nullptr)
|
||||||
this->distance_sensor_->publish_state(distance);
|
this->distance_sensor_->publish_state(distance);
|
||||||
|
|
||||||
uint32_t energy = this->get_lightning_energy_();
|
uint32_t energy = this->get_lightning_energy_();
|
||||||
if (this->energy_sensor_ != nullptr)
|
if (this->energy_sensor_ != nullptr)
|
||||||
this->energy_sensor_->publish_state(energy);
|
this->energy_sensor_->publish_state(energy);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
this->thunder_alert_binary_sensor_->publish_state(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AS3935Component::write_indoor(bool indoor) {
|
void AS3935Component::write_indoor(bool indoor) {
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/core/defines.h"
|
||||||
#include "esphome/core/hal.h"
|
#include "esphome/core/hal.h"
|
||||||
|
#ifdef USE_SENSOR
|
||||||
#include "esphome/components/sensor/sensor.h"
|
#include "esphome/components/sensor/sensor.h"
|
||||||
|
#endif
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace as3935 {
|
namespace as3935 {
|
||||||
@ -52,6 +57,15 @@ enum AS3935Values {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class AS3935Component : public Component {
|
class AS3935Component : public Component {
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
SUB_SENSOR(distance)
|
||||||
|
SUB_SENSOR(energy)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
SUB_BINARY_SENSOR(thunder_alert)
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setup() override;
|
void setup() override;
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
@ -59,11 +73,7 @@ class AS3935Component : public Component {
|
|||||||
void loop() override;
|
void loop() override;
|
||||||
|
|
||||||
void set_irq_pin(GPIOPin *irq_pin) { irq_pin_ = irq_pin; }
|
void set_irq_pin(GPIOPin *irq_pin) { irq_pin_ = irq_pin; }
|
||||||
void set_distance_sensor(sensor::Sensor *distance_sensor) { distance_sensor_ = distance_sensor; }
|
|
||||||
void set_energy_sensor(sensor::Sensor *energy_sensor) { energy_sensor_ = energy_sensor; }
|
|
||||||
void set_thunder_alert_binary_sensor(binary_sensor::BinarySensor *thunder_alert_binary_sensor) {
|
|
||||||
thunder_alert_binary_sensor_ = thunder_alert_binary_sensor;
|
|
||||||
}
|
|
||||||
void set_indoor(bool indoor) { indoor_ = indoor; }
|
void set_indoor(bool indoor) { indoor_ = indoor; }
|
||||||
void write_indoor(bool indoor);
|
void write_indoor(bool indoor);
|
||||||
void set_noise_level(uint8_t noise_level) { noise_level_ = noise_level; }
|
void set_noise_level(uint8_t noise_level) { noise_level_ = noise_level; }
|
||||||
@ -92,9 +102,6 @@ class AS3935Component : public Component {
|
|||||||
|
|
||||||
virtual void write_register(uint8_t reg, uint8_t mask, uint8_t bits, uint8_t start_position) = 0;
|
virtual void write_register(uint8_t reg, uint8_t mask, uint8_t bits, uint8_t start_position) = 0;
|
||||||
|
|
||||||
sensor::Sensor *distance_sensor_{nullptr};
|
|
||||||
sensor::Sensor *energy_sensor_{nullptr};
|
|
||||||
binary_sensor::BinarySensor *thunder_alert_binary_sensor_{nullptr};
|
|
||||||
GPIOPin *irq_pin_;
|
GPIOPin *irq_pin_;
|
||||||
|
|
||||||
bool indoor_;
|
bool indoor_;
|
||||||
|
@ -30,7 +30,7 @@ void BinarySensorMap::process_group_() {
|
|||||||
if (bs.binary_sensor->state) {
|
if (bs.binary_sensor->state) {
|
||||||
num_active_sensors++;
|
num_active_sensors++;
|
||||||
total_current_value += bs.sensor_value;
|
total_current_value += bs.sensor_value;
|
||||||
mask |= 1 << i;
|
mask |= 1ULL << i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check if the sensor map was touched
|
// check if the sensor map was touched
|
||||||
@ -38,12 +38,11 @@ void BinarySensorMap::process_group_() {
|
|||||||
// did the bit_mask change or is it a new sensor touch
|
// did the bit_mask change or is it a new sensor touch
|
||||||
if (this->last_mask_ != mask) {
|
if (this->last_mask_ != mask) {
|
||||||
float publish_value = total_current_value / num_active_sensors;
|
float publish_value = total_current_value / num_active_sensors;
|
||||||
ESP_LOGD(TAG, "'%s' - Publishing %.2f", this->name_.c_str(), publish_value);
|
|
||||||
this->publish_state(publish_value);
|
this->publish_state(publish_value);
|
||||||
}
|
}
|
||||||
} else if (this->last_mask_ != 0ULL) {
|
} else if (this->last_mask_ != 0ULL) {
|
||||||
// is this a new sensor release
|
// is this a new sensor release
|
||||||
ESP_LOGD(TAG, "'%s' - No binary sensor active, publishing NAN", this->name_.c_str());
|
ESP_LOGV(TAG, "'%s' - No binary sensor active, publishing NAN", this->name_.c_str());
|
||||||
this->publish_state(NAN);
|
this->publish_state(NAN);
|
||||||
}
|
}
|
||||||
this->last_mask_ = mask;
|
this->last_mask_ = mask;
|
||||||
@ -52,28 +51,22 @@ void BinarySensorMap::process_group_() {
|
|||||||
void BinarySensorMap::process_sum_() {
|
void BinarySensorMap::process_sum_() {
|
||||||
float total_current_value = 0.0;
|
float total_current_value = 0.0;
|
||||||
uint64_t mask = 0x00;
|
uint64_t mask = 0x00;
|
||||||
// check all binary_sensors for its state. when active add its value to total_current_value.
|
// - check all binary_sensor states
|
||||||
// create a bitmask for the binary_sensor status on all channels
|
// - if active, add its value to total_current_value
|
||||||
|
// - creates a bitmask for the binary_sensor status on all channels
|
||||||
for (size_t i = 0; i < this->channels_.size(); i++) {
|
for (size_t i = 0; i < this->channels_.size(); i++) {
|
||||||
auto bs = this->channels_[i];
|
auto bs = this->channels_[i];
|
||||||
if (bs.binary_sensor->state) {
|
if (bs.binary_sensor->state) {
|
||||||
total_current_value += bs.sensor_value;
|
total_current_value += bs.sensor_value;
|
||||||
mask |= 1 << i;
|
mask |= 1ULL << i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check if the sensor map was touched
|
|
||||||
if (mask != 0ULL) {
|
// update state only if the binary sensor states have changed or if no state has ever been sent on boot
|
||||||
// did the bit_mask change or is it a new sensor touch
|
if ((this->last_mask_ != mask) || (!this->has_state())) {
|
||||||
if (this->last_mask_ != mask) {
|
this->publish_state(total_current_value);
|
||||||
float publish_value = total_current_value;
|
|
||||||
ESP_LOGD(TAG, "'%s' - Publishing %.2f", this->name_.c_str(), publish_value);
|
|
||||||
this->publish_state(publish_value);
|
|
||||||
}
|
|
||||||
} else if (this->last_mask_ != 0ULL) {
|
|
||||||
// is this a new sensor release
|
|
||||||
ESP_LOGD(TAG, "'%s' - No binary sensor active, publishing 0", this->name_.c_str());
|
|
||||||
this->publish_state(0.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->last_mask_ = mask;
|
this->last_mask_ = mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ CONFIG_SCHEMA = cv.typed_schema(
|
|||||||
).extend(
|
).extend(
|
||||||
{
|
{
|
||||||
cv.Required(CONF_CHANNELS): cv.All(
|
cv.Required(CONF_CHANNELS): cv.All(
|
||||||
cv.ensure_list(entry), cv.Length(min=1)
|
cv.ensure_list(entry), cv.Length(min=1, max=64)
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
@ -50,7 +50,7 @@ CONFIG_SCHEMA = cv.typed_schema(
|
|||||||
).extend(
|
).extend(
|
||||||
{
|
{
|
||||||
cv.Required(CONF_CHANNELS): cv.All(
|
cv.Required(CONF_CHANNELS): cv.All(
|
||||||
cv.ensure_list(entry), cv.Length(min=1)
|
cv.ensure_list(entry), cv.Length(min=1, max=64)
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
@ -6,9 +6,6 @@ namespace button {
|
|||||||
|
|
||||||
static const char *const TAG = "button";
|
static const char *const TAG = "button";
|
||||||
|
|
||||||
Button::Button(const std::string &name) : EntityBase(name) {}
|
|
||||||
Button::Button() : Button("") {}
|
|
||||||
|
|
||||||
void Button::press() {
|
void Button::press() {
|
||||||
ESP_LOGD(TAG, "'%s' Pressed.", this->get_name().c_str());
|
ESP_LOGD(TAG, "'%s' Pressed.", this->get_name().c_str());
|
||||||
this->press_action();
|
this->press_action();
|
||||||
|
@ -28,9 +28,6 @@ namespace button {
|
|||||||
*/
|
*/
|
||||||
class Button : public EntityBase {
|
class Button : public EntityBase {
|
||||||
public:
|
public:
|
||||||
explicit Button();
|
|
||||||
explicit Button(const std::string &name);
|
|
||||||
|
|
||||||
/** Press this button. This is called by the front-end.
|
/** Press this button. This is called by the front-end.
|
||||||
*
|
*
|
||||||
* For implementing buttons, please override press_action.
|
* For implementing buttons, please override press_action.
|
||||||
|
@ -453,12 +453,7 @@ void Climate::set_visual_temperature_step_override(float target, float current)
|
|||||||
this->visual_target_temperature_step_override_ = target;
|
this->visual_target_temperature_step_override_ = target;
|
||||||
this->visual_current_temperature_step_override_ = current;
|
this->visual_current_temperature_step_override_ = current;
|
||||||
}
|
}
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
Climate::Climate(const std::string &name) : EntityBase(name) {}
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
Climate::Climate() : Climate("") {}
|
|
||||||
ClimateCall Climate::make_call() { return ClimateCall(this); }
|
ClimateCall Climate::make_call() { return ClimateCall(this); }
|
||||||
|
|
||||||
ClimateCall ClimateDeviceRestoreState::to_call(Climate *climate) {
|
ClimateCall ClimateDeviceRestoreState::to_call(Climate *climate) {
|
||||||
|
@ -166,11 +166,6 @@ struct ClimateDeviceRestoreState {
|
|||||||
*/
|
*/
|
||||||
class Climate : public EntityBase {
|
class Climate : public EntityBase {
|
||||||
public:
|
public:
|
||||||
/// Construct a climate device with empty name (will be set later).
|
|
||||||
Climate();
|
|
||||||
/// Construct a climate device with a name.
|
|
||||||
Climate(const std::string &name);
|
|
||||||
|
|
||||||
/// The active mode of the climate device.
|
/// The active mode of the climate device.
|
||||||
ClimateMode mode{CLIMATE_MODE_OFF};
|
ClimateMode mode{CLIMATE_MODE_OFF};
|
||||||
/// The active state of the climate device.
|
/// The active state of the climate device.
|
||||||
|
@ -31,7 +31,7 @@ const char *cover_operation_to_str(CoverOperation op) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Cover::Cover(const std::string &name) : EntityBase(name), position{COVER_OPEN} {}
|
Cover::Cover() : position{COVER_OPEN} {}
|
||||||
|
|
||||||
CoverCall::CoverCall(Cover *parent) : parent_(parent) {}
|
CoverCall::CoverCall(Cover *parent) : parent_(parent) {}
|
||||||
CoverCall &CoverCall::set_command(const char *command) {
|
CoverCall &CoverCall::set_command(const char *command) {
|
||||||
@ -204,7 +204,6 @@ optional<CoverRestoreState> Cover::restore_state_() {
|
|||||||
return {};
|
return {};
|
||||||
return recovered;
|
return recovered;
|
||||||
}
|
}
|
||||||
Cover::Cover() : Cover("") {}
|
|
||||||
std::string Cover::get_device_class() {
|
std::string Cover::get_device_class() {
|
||||||
if (this->device_class_override_.has_value())
|
if (this->device_class_override_.has_value())
|
||||||
return *this->device_class_override_;
|
return *this->device_class_override_;
|
||||||
|
@ -111,7 +111,6 @@ const char *cover_operation_to_str(CoverOperation op);
|
|||||||
class Cover : public EntityBase {
|
class Cover : public EntityBase {
|
||||||
public:
|
public:
|
||||||
explicit Cover();
|
explicit Cover();
|
||||||
explicit Cover(const std::string &name);
|
|
||||||
|
|
||||||
/// The current operation of the cover (idle, opening, closing).
|
/// The current operation of the cover (idle, opening, closing).
|
||||||
CoverOperation current_operation{COVER_OPERATION_IDLE};
|
CoverOperation current_operation{COVER_OPERATION_IDLE};
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <esp_bt.h>
|
#include <esp_bt.h>
|
||||||
#include <esp_bt_main.h>
|
#include <esp_bt_main.h>
|
||||||
|
#include <esp_bt_device.h>
|
||||||
#include <esp_gap_ble_api.h>
|
#include <esp_gap_ble_api.h>
|
||||||
#include <freertos/FreeRTOS.h>
|
#include <freertos/FreeRTOS.h>
|
||||||
#include <freertos/FreeRTOSConfig.h>
|
#include <freertos/FreeRTOSConfig.h>
|
||||||
@ -211,7 +212,16 @@ void ESP32BLE::real_gattc_event_handler_(esp_gattc_cb_event_t event, esp_gatt_if
|
|||||||
|
|
||||||
float ESP32BLE::get_setup_priority() const { return setup_priority::BLUETOOTH; }
|
float ESP32BLE::get_setup_priority() const { return setup_priority::BLUETOOTH; }
|
||||||
|
|
||||||
void ESP32BLE::dump_config() { ESP_LOGCONFIG(TAG, "ESP32 BLE:"); }
|
void ESP32BLE::dump_config() {
|
||||||
|
const uint8_t *mac_address = esp_bt_dev_get_address();
|
||||||
|
if (mac_address) {
|
||||||
|
ESP_LOGCONFIG(TAG, "ESP32 BLE:");
|
||||||
|
ESP_LOGCONFIG(TAG, " MAC address: %02X:%02X:%02X:%02X:%02X:%02X", mac_address[0], mac_address[1], mac_address[2],
|
||||||
|
mac_address[3], mac_address[4], mac_address[5]);
|
||||||
|
} else {
|
||||||
|
ESP_LOGCONFIG(TAG, "ESP32 BLE: bluetooth stack is not enabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ESP32BLE *global_ble = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
ESP32BLE *global_ble = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ void ESP32Camera::loop() {
|
|||||||
float ESP32Camera::get_setup_priority() const { return setup_priority::DATA; }
|
float ESP32Camera::get_setup_priority() const { return setup_priority::DATA; }
|
||||||
|
|
||||||
/* ---------------- constructors ---------------- */
|
/* ---------------- constructors ---------------- */
|
||||||
ESP32Camera::ESP32Camera(const std::string &name) : EntityBase(name) {
|
ESP32Camera::ESP32Camera() {
|
||||||
this->config_.pin_pwdn = -1;
|
this->config_.pin_pwdn = -1;
|
||||||
this->config_.pin_reset = -1;
|
this->config_.pin_reset = -1;
|
||||||
this->config_.pin_xclk = -1;
|
this->config_.pin_xclk = -1;
|
||||||
@ -215,7 +215,6 @@ ESP32Camera::ESP32Camera(const std::string &name) : EntityBase(name) {
|
|||||||
|
|
||||||
global_esp32_camera = this;
|
global_esp32_camera = this;
|
||||||
}
|
}
|
||||||
ESP32Camera::ESP32Camera() : ESP32Camera("") {}
|
|
||||||
|
|
||||||
/* ---------------- setters ---------------- */
|
/* ---------------- setters ---------------- */
|
||||||
/* set pin assignment */
|
/* set pin assignment */
|
||||||
|
@ -103,7 +103,6 @@ class CameraImageReader {
|
|||||||
/* ---------------- ESP32Camera class ---------------- */
|
/* ---------------- ESP32Camera class ---------------- */
|
||||||
class ESP32Camera : public Component, public EntityBase {
|
class ESP32Camera : public Component, public EntityBase {
|
||||||
public:
|
public:
|
||||||
ESP32Camera(const std::string &name);
|
|
||||||
ESP32Camera();
|
ESP32Camera();
|
||||||
|
|
||||||
/* setters */
|
/* setters */
|
||||||
|
@ -12,14 +12,14 @@ static const char *const TAG = "ezo.sensor";
|
|||||||
|
|
||||||
enum EzoCommandType : uint8_t {
|
enum EzoCommandType : uint8_t {
|
||||||
EZO_READ = 0,
|
EZO_READ = 0,
|
||||||
EZO_LED = 1,
|
EZO_LED,
|
||||||
EZO_DEVICE_INFORMATION = 2,
|
EZO_DEVICE_INFORMATION,
|
||||||
EZO_SLOPE = 3,
|
EZO_SLOPE,
|
||||||
EZO_CALIBRATION,
|
EZO_CALIBRATION,
|
||||||
EZO_SLEEP = 4,
|
EZO_SLEEP,
|
||||||
EZO_I2C = 5,
|
EZO_I2C,
|
||||||
EZO_T = 6,
|
EZO_T,
|
||||||
EZO_CUSTOM = 7
|
EZO_CUSTOM
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EzoCalibrationType : uint8_t { EZO_CAL_LOW = 0, EZO_CAL_MID = 1, EZO_CAL_HIGH = 2 };
|
enum EzoCalibrationType : uint8_t { EZO_CAL_LOW = 0, EZO_CAL_MID = 1, EZO_CAL_HIGH = 2 };
|
||||||
|
@ -80,9 +80,6 @@ void FanRestoreState::apply(Fan &fan) {
|
|||||||
fan.publish_state();
|
fan.publish_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
Fan::Fan() : EntityBase("") {}
|
|
||||||
Fan::Fan(const std::string &name) : EntityBase(name) {}
|
|
||||||
|
|
||||||
FanCall Fan::turn_on() { return this->make_call().set_state(true); }
|
FanCall Fan::turn_on() { return this->make_call().set_state(true); }
|
||||||
FanCall Fan::turn_off() { return this->make_call().set_state(false); }
|
FanCall Fan::turn_off() { return this->make_call().set_state(false); }
|
||||||
FanCall Fan::toggle() { return this->make_call().set_state(!this->state); }
|
FanCall Fan::toggle() { return this->make_call().set_state(!this->state); }
|
||||||
|
@ -99,10 +99,6 @@ struct FanRestoreState {
|
|||||||
|
|
||||||
class Fan : public EntityBase {
|
class Fan : public EntityBase {
|
||||||
public:
|
public:
|
||||||
Fan();
|
|
||||||
/// Construct the fan with name.
|
|
||||||
explicit Fan(const std::string &name);
|
|
||||||
|
|
||||||
/// The current on/off state of the fan.
|
/// The current on/off state of the fan.
|
||||||
bool state{false};
|
bool state{false};
|
||||||
/// The current oscillation state of the fan.
|
/// The current oscillation state of the fan.
|
||||||
|
@ -15,7 +15,6 @@ enum ESPDEPRECATED("LegacyFanDirection members are deprecated, use FanDirection
|
|||||||
class ESPDEPRECATED("FanState is deprecated, use Fan instead.", "2022.2") FanState : public Fan, public Component {
|
class ESPDEPRECATED("FanState is deprecated, use Fan instead.", "2022.2") FanState : public Fan, public Component {
|
||||||
public:
|
public:
|
||||||
FanState() = default;
|
FanState() = default;
|
||||||
explicit FanState(const std::string &name) : Fan(name) {}
|
|
||||||
|
|
||||||
/// Get the traits of this fan.
|
/// Get the traits of this fan.
|
||||||
FanTraits get_traits() override { return this->traits_; }
|
FanTraits get_traits() override { return this->traits_; }
|
||||||
|
@ -8,7 +8,6 @@ namespace light {
|
|||||||
|
|
||||||
static const char *const TAG = "light";
|
static const char *const TAG = "light";
|
||||||
|
|
||||||
LightState::LightState(const std::string &name, LightOutput *output) : EntityBase(name), output_(output) {}
|
|
||||||
LightState::LightState(LightOutput *output) : output_(output) {}
|
LightState::LightState(LightOutput *output) : output_(output) {}
|
||||||
|
|
||||||
LightTraits LightState::get_traits() { return this->output_->get_traits(); }
|
LightTraits LightState::get_traits() { return this->output_->get_traits(); }
|
||||||
|
@ -33,9 +33,6 @@ enum LightRestoreMode {
|
|||||||
*/
|
*/
|
||||||
class LightState : public EntityBase, public Component {
|
class LightState : public EntityBase, public Component {
|
||||||
public:
|
public:
|
||||||
/// Construct this LightState using the provided traits and name.
|
|
||||||
LightState(const std::string &name, LightOutput *output);
|
|
||||||
|
|
||||||
LightState(LightOutput *output);
|
LightState(LightOutput *output);
|
||||||
|
|
||||||
LightTraits get_traits();
|
LightTraits get_traits();
|
||||||
|
@ -24,8 +24,7 @@ const char *lock_state_to_string(LockState state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Lock::Lock(const std::string &name) : EntityBase(name), state(LOCK_STATE_NONE) {}
|
Lock::Lock() : state(LOCK_STATE_NONE) {}
|
||||||
Lock::Lock() : Lock("") {}
|
|
||||||
LockCall Lock::make_call() { return LockCall(this); }
|
LockCall Lock::make_call() { return LockCall(this); }
|
||||||
|
|
||||||
void Lock::lock() {
|
void Lock::lock() {
|
||||||
|
@ -103,7 +103,6 @@ class LockCall {
|
|||||||
class Lock : public EntityBase {
|
class Lock : public EntityBase {
|
||||||
public:
|
public:
|
||||||
explicit Lock();
|
explicit Lock();
|
||||||
explicit Lock(const std::string &name);
|
|
||||||
|
|
||||||
/** Make a lock device control call, this is used to control the lock device, see the LockCall description
|
/** Make a lock device control call, this is used to control the lock device, see the LockCall description
|
||||||
* for more info.
|
* for more info.
|
||||||
|
@ -31,6 +31,7 @@ from esphome.const import (
|
|||||||
DEVICE_CLASS_DISTANCE,
|
DEVICE_CLASS_DISTANCE,
|
||||||
DEVICE_CLASS_EMPTY,
|
DEVICE_CLASS_EMPTY,
|
||||||
DEVICE_CLASS_ENERGY,
|
DEVICE_CLASS_ENERGY,
|
||||||
|
DEVICE_CLASS_ENERGY_STORAGE,
|
||||||
DEVICE_CLASS_FREQUENCY,
|
DEVICE_CLASS_FREQUENCY,
|
||||||
DEVICE_CLASS_GAS,
|
DEVICE_CLASS_GAS,
|
||||||
DEVICE_CLASS_HUMIDITY,
|
DEVICE_CLASS_HUMIDITY,
|
||||||
@ -59,6 +60,7 @@ from esphome.const import (
|
|||||||
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS,
|
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS,
|
||||||
DEVICE_CLASS_VOLTAGE,
|
DEVICE_CLASS_VOLTAGE,
|
||||||
DEVICE_CLASS_VOLUME,
|
DEVICE_CLASS_VOLUME,
|
||||||
|
DEVICE_CLASS_VOLUME_STORAGE,
|
||||||
DEVICE_CLASS_WATER,
|
DEVICE_CLASS_WATER,
|
||||||
DEVICE_CLASS_WEIGHT,
|
DEVICE_CLASS_WEIGHT,
|
||||||
DEVICE_CLASS_WIND_SPEED,
|
DEVICE_CLASS_WIND_SPEED,
|
||||||
@ -81,6 +83,7 @@ DEVICE_CLASSES = [
|
|||||||
DEVICE_CLASS_DISTANCE,
|
DEVICE_CLASS_DISTANCE,
|
||||||
DEVICE_CLASS_EMPTY,
|
DEVICE_CLASS_EMPTY,
|
||||||
DEVICE_CLASS_ENERGY,
|
DEVICE_CLASS_ENERGY,
|
||||||
|
DEVICE_CLASS_ENERGY_STORAGE,
|
||||||
DEVICE_CLASS_FREQUENCY,
|
DEVICE_CLASS_FREQUENCY,
|
||||||
DEVICE_CLASS_GAS,
|
DEVICE_CLASS_GAS,
|
||||||
DEVICE_CLASS_HUMIDITY,
|
DEVICE_CLASS_HUMIDITY,
|
||||||
@ -109,6 +112,7 @@ DEVICE_CLASSES = [
|
|||||||
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS,
|
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS,
|
||||||
DEVICE_CLASS_VOLTAGE,
|
DEVICE_CLASS_VOLTAGE,
|
||||||
DEVICE_CLASS_VOLUME,
|
DEVICE_CLASS_VOLUME,
|
||||||
|
DEVICE_CLASS_VOLUME_STORAGE,
|
||||||
DEVICE_CLASS_WATER,
|
DEVICE_CLASS_WATER,
|
||||||
DEVICE_CLASS_WEIGHT,
|
DEVICE_CLASS_WEIGHT,
|
||||||
DEVICE_CLASS_WIND_SPEED,
|
DEVICE_CLASS_WIND_SPEED,
|
||||||
|
@ -102,7 +102,7 @@ async def to_code(config):
|
|||||||
conf[CONF_ADDRESSABLE_LIGHT_ID],
|
conf[CONF_ADDRESSABLE_LIGHT_ID],
|
||||||
await cg.get_variable(conf[CONF_SINGLE_LIGHT_ID]),
|
await cg.get_variable(conf[CONF_SINGLE_LIGHT_ID]),
|
||||||
)
|
)
|
||||||
light_state = cg.new_Pvariable(conf[CONF_LIGHT_ID], "", wrapper)
|
light_state = cg.new_Pvariable(conf[CONF_LIGHT_ID], wrapper)
|
||||||
await cg.register_component(light_state, conf)
|
await cg.register_component(light_state, conf)
|
||||||
segments.append(AddressableSegment(light_state, 0, 1, False))
|
segments.append(AddressableSegment(light_state, 0, 1, False))
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ from esphome.const import (
|
|||||||
DEVICE_CLASS_DURATION,
|
DEVICE_CLASS_DURATION,
|
||||||
DEVICE_CLASS_EMPTY,
|
DEVICE_CLASS_EMPTY,
|
||||||
DEVICE_CLASS_ENERGY,
|
DEVICE_CLASS_ENERGY,
|
||||||
|
DEVICE_CLASS_ENERGY_STORAGE,
|
||||||
DEVICE_CLASS_FREQUENCY,
|
DEVICE_CLASS_FREQUENCY,
|
||||||
DEVICE_CLASS_GAS,
|
DEVICE_CLASS_GAS,
|
||||||
DEVICE_CLASS_HUMIDITY,
|
DEVICE_CLASS_HUMIDITY,
|
||||||
@ -72,6 +73,7 @@ from esphome.const import (
|
|||||||
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS,
|
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS,
|
||||||
DEVICE_CLASS_VOLTAGE,
|
DEVICE_CLASS_VOLTAGE,
|
||||||
DEVICE_CLASS_VOLUME,
|
DEVICE_CLASS_VOLUME,
|
||||||
|
DEVICE_CLASS_VOLUME_STORAGE,
|
||||||
DEVICE_CLASS_WATER,
|
DEVICE_CLASS_WATER,
|
||||||
DEVICE_CLASS_WEIGHT,
|
DEVICE_CLASS_WEIGHT,
|
||||||
DEVICE_CLASS_WIND_SPEED,
|
DEVICE_CLASS_WIND_SPEED,
|
||||||
@ -97,6 +99,7 @@ DEVICE_CLASSES = [
|
|||||||
DEVICE_CLASS_DURATION,
|
DEVICE_CLASS_DURATION,
|
||||||
DEVICE_CLASS_EMPTY,
|
DEVICE_CLASS_EMPTY,
|
||||||
DEVICE_CLASS_ENERGY,
|
DEVICE_CLASS_ENERGY,
|
||||||
|
DEVICE_CLASS_ENERGY_STORAGE,
|
||||||
DEVICE_CLASS_FREQUENCY,
|
DEVICE_CLASS_FREQUENCY,
|
||||||
DEVICE_CLASS_GAS,
|
DEVICE_CLASS_GAS,
|
||||||
DEVICE_CLASS_HUMIDITY,
|
DEVICE_CLASS_HUMIDITY,
|
||||||
@ -126,6 +129,7 @@ DEVICE_CLASSES = [
|
|||||||
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS,
|
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS,
|
||||||
DEVICE_CLASS_VOLTAGE,
|
DEVICE_CLASS_VOLTAGE,
|
||||||
DEVICE_CLASS_VOLUME,
|
DEVICE_CLASS_VOLUME,
|
||||||
|
DEVICE_CLASS_VOLUME_STORAGE,
|
||||||
DEVICE_CLASS_WATER,
|
DEVICE_CLASS_WATER,
|
||||||
DEVICE_CLASS_WEIGHT,
|
DEVICE_CLASS_WEIGHT,
|
||||||
DEVICE_CLASS_WIND_SPEED,
|
DEVICE_CLASS_WIND_SPEED,
|
||||||
|
@ -20,8 +20,7 @@ std::string state_class_to_string(StateClass state_class) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Sensor::Sensor(const std::string &name) : EntityBase(name), state(NAN), raw_state(NAN) {}
|
Sensor::Sensor() : state(NAN), raw_state(NAN) {}
|
||||||
Sensor::Sensor() : Sensor("") {}
|
|
||||||
|
|
||||||
std::string Sensor::get_unit_of_measurement() {
|
std::string Sensor::get_unit_of_measurement() {
|
||||||
if (this->unit_of_measurement_.has_value())
|
if (this->unit_of_measurement_.has_value())
|
||||||
|
@ -57,7 +57,6 @@ std::string state_class_to_string(StateClass state_class);
|
|||||||
class Sensor : public EntityBase {
|
class Sensor : public EntityBase {
|
||||||
public:
|
public:
|
||||||
explicit Sensor();
|
explicit Sensor();
|
||||||
explicit Sensor(const std::string &name);
|
|
||||||
|
|
||||||
/// Get the unit of measurement, using the manual override if set.
|
/// Get the unit of measurement, using the manual override if set.
|
||||||
std::string get_unit_of_measurement();
|
std::string get_unit_of_measurement();
|
||||||
@ -162,7 +161,6 @@ class Sensor : public EntityBase {
|
|||||||
CallbackManager<void(float)> raw_callback_; ///< Storage for raw state callbacks.
|
CallbackManager<void(float)> raw_callback_; ///< Storage for raw state callbacks.
|
||||||
CallbackManager<void(float)> callback_; ///< Storage for filtered state callbacks.
|
CallbackManager<void(float)> callback_; ///< Storage for filtered state callbacks.
|
||||||
|
|
||||||
bool has_state_{false};
|
|
||||||
Filter *filter_list_{nullptr}; ///< Store all active filters.
|
Filter *filter_list_{nullptr}; ///< Store all active filters.
|
||||||
|
|
||||||
optional<std::string> unit_of_measurement_; ///< Unit of measurement override
|
optional<std::string> unit_of_measurement_; ///< Unit of measurement override
|
||||||
@ -170,6 +168,7 @@ class Sensor : public EntityBase {
|
|||||||
optional<std::string> device_class_; ///< Device class override
|
optional<std::string> device_class_; ///< Device class override
|
||||||
optional<StateClass> state_class_{STATE_CLASS_NONE}; ///< State class override
|
optional<StateClass> state_class_{STATE_CLASS_NONE}; ///< State class override
|
||||||
bool force_update_{false}; ///< Force update mode
|
bool force_update_{false}; ///< Force update mode
|
||||||
|
bool has_state_{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sensor
|
} // namespace sensor
|
||||||
|
@ -6,8 +6,7 @@ namespace switch_ {
|
|||||||
|
|
||||||
static const char *const TAG = "switch";
|
static const char *const TAG = "switch";
|
||||||
|
|
||||||
Switch::Switch(const std::string &name) : EntityBase(name), state(false) {}
|
Switch::Switch() : state(false) {}
|
||||||
Switch::Switch() : Switch("") {}
|
|
||||||
|
|
||||||
void Switch::turn_on() {
|
void Switch::turn_on() {
|
||||||
ESP_LOGD(TAG, "'%s' Turning ON.", this->get_name().c_str());
|
ESP_LOGD(TAG, "'%s' Turning ON.", this->get_name().c_str());
|
||||||
|
@ -32,7 +32,6 @@ enum SwitchRestoreMode {
|
|||||||
class Switch : public EntityBase {
|
class Switch : public EntityBase {
|
||||||
public:
|
public:
|
||||||
explicit Switch();
|
explicit Switch();
|
||||||
explicit Switch(const std::string &name);
|
|
||||||
|
|
||||||
/** Publish a state to the front-end from the back-end.
|
/** Publish a state to the front-end from the back-end.
|
||||||
*
|
*
|
||||||
|
@ -6,9 +6,6 @@ namespace text_sensor {
|
|||||||
|
|
||||||
static const char *const TAG = "text_sensor";
|
static const char *const TAG = "text_sensor";
|
||||||
|
|
||||||
TextSensor::TextSensor() : TextSensor("") {}
|
|
||||||
TextSensor::TextSensor(const std::string &name) : EntityBase(name) {}
|
|
||||||
|
|
||||||
void TextSensor::publish_state(const std::string &state) {
|
void TextSensor::publish_state(const std::string &state) {
|
||||||
this->raw_state = state;
|
this->raw_state = state;
|
||||||
this->raw_callback_.call(state);
|
this->raw_callback_.call(state);
|
||||||
|
@ -30,9 +30,6 @@ namespace text_sensor {
|
|||||||
|
|
||||||
class TextSensor : public EntityBase {
|
class TextSensor : public EntityBase {
|
||||||
public:
|
public:
|
||||||
explicit TextSensor();
|
|
||||||
explicit TextSensor(const std::string &name);
|
|
||||||
|
|
||||||
/// Getter-syntax for .state.
|
/// Getter-syntax for .state.
|
||||||
std::string get_state() const;
|
std::string get_state() const;
|
||||||
/// Getter-syntax for .raw_state
|
/// Getter-syntax for .raw_state
|
||||||
|
@ -100,8 +100,8 @@ void ESP32ArduinoUARTComponent::setup() {
|
|||||||
invert = true;
|
invert = true;
|
||||||
if (rx_pin_ != nullptr && rx_pin_->is_inverted())
|
if (rx_pin_ != nullptr && rx_pin_->is_inverted())
|
||||||
invert = true;
|
invert = true;
|
||||||
this->hw_serial_->begin(this->baud_rate_, get_config(), rx, tx, invert);
|
|
||||||
this->hw_serial_->setRxBufferSize(this->rx_buffer_size_);
|
this->hw_serial_->setRxBufferSize(this->rx_buffer_size_);
|
||||||
|
this->hw_serial_->begin(this->baud_rate_, get_config(), rx, tx, invert);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESP32ArduinoUARTComponent::dump_config() {
|
void ESP32ArduinoUARTComponent::dump_config() {
|
||||||
|
@ -28,6 +28,9 @@ class ESP32ArduinoUARTComponent : public UARTComponent, public Component {
|
|||||||
|
|
||||||
uint32_t get_config();
|
uint32_t get_config();
|
||||||
|
|
||||||
|
HardwareSerial *get_hw_serial() { return this->hw_serial_; }
|
||||||
|
uint8_t get_hw_serial_number() { return this->number_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void check_logger_conflict() override;
|
void check_logger_conflict() override;
|
||||||
|
|
||||||
|
@ -79,7 +79,12 @@ void IDFUARTComponent::setup() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = uart_driver_install(this->uart_num_, this->rx_buffer_size_, 0, 0, nullptr, 0);
|
err = uart_driver_install(this->uart_num_, /* UART RX ring buffer size. */ this->rx_buffer_size_,
|
||||||
|
/* UART TX ring buffer size. If set to zero, driver will not use TX buffer, TX function will
|
||||||
|
block task until all data have been sent out.*/
|
||||||
|
0,
|
||||||
|
/* UART event queue size/depth. */ 20, &(this->uart_event_queue_),
|
||||||
|
/* Flags used to allocate the interrupt. */ 0);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGW(TAG, "uart_driver_install failed: %s", esp_err_to_name(err));
|
ESP_LOGW(TAG, "uart_driver_install failed: %s", esp_err_to_name(err));
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
|
@ -23,9 +23,13 @@ class IDFUARTComponent : public UARTComponent, public Component {
|
|||||||
int available() override;
|
int available() override;
|
||||||
void flush() override;
|
void flush() override;
|
||||||
|
|
||||||
|
uint8_t get_hw_serial_number() { return this->uart_num_; }
|
||||||
|
QueueHandle_t *get_uart_event_queue() { return &this->uart_event_queue_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void check_logger_conflict() override;
|
void check_logger_conflict() override;
|
||||||
uart_port_t uart_num_;
|
uart_port_t uart_num_;
|
||||||
|
QueueHandle_t uart_event_queue_;
|
||||||
uart_config_t get_config_();
|
uart_config_t get_config_();
|
||||||
SemaphoreHandle_t lock_;
|
SemaphoreHandle_t lock_;
|
||||||
|
|
||||||
|
@ -30,6 +30,9 @@ class RP2040UartComponent : public UARTComponent, public Component {
|
|||||||
|
|
||||||
uint16_t get_config();
|
uint16_t get_config();
|
||||||
|
|
||||||
|
bool is_hw_serial() { return this->hw_serial_; }
|
||||||
|
HardwareSerial *get_hw_serial() { return this->serial_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void check_logger_conflict() override {}
|
void check_logger_conflict() override {}
|
||||||
bool hw_serial_{false};
|
bool hw_serial_{false};
|
||||||
|
@ -946,6 +946,7 @@ DEVICE_CLASS_DOOR = "door"
|
|||||||
DEVICE_CLASS_DURATION = "duration"
|
DEVICE_CLASS_DURATION = "duration"
|
||||||
DEVICE_CLASS_EMPTY = ""
|
DEVICE_CLASS_EMPTY = ""
|
||||||
DEVICE_CLASS_ENERGY = "energy"
|
DEVICE_CLASS_ENERGY = "energy"
|
||||||
|
DEVICE_CLASS_ENERGY_STORAGE = "energy_storage"
|
||||||
DEVICE_CLASS_FREQUENCY = "frequency"
|
DEVICE_CLASS_FREQUENCY = "frequency"
|
||||||
DEVICE_CLASS_GARAGE = "garage"
|
DEVICE_CLASS_GARAGE = "garage"
|
||||||
DEVICE_CLASS_GARAGE_DOOR = "garage_door"
|
DEVICE_CLASS_GARAGE_DOOR = "garage_door"
|
||||||
@ -1000,6 +1001,7 @@ DEVICE_CLASS_VIBRATION = "vibration"
|
|||||||
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS = "volatile_organic_compounds"
|
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS = "volatile_organic_compounds"
|
||||||
DEVICE_CLASS_VOLTAGE = "voltage"
|
DEVICE_CLASS_VOLTAGE = "voltage"
|
||||||
DEVICE_CLASS_VOLUME = "volume"
|
DEVICE_CLASS_VOLUME = "volume"
|
||||||
|
DEVICE_CLASS_VOLUME_STORAGE = "volume_storage"
|
||||||
DEVICE_CLASS_WATER = "water"
|
DEVICE_CLASS_WATER = "water"
|
||||||
DEVICE_CLASS_WEIGHT = "weight"
|
DEVICE_CLASS_WEIGHT = "weight"
|
||||||
DEVICE_CLASS_WINDOW = "window"
|
DEVICE_CLASS_WINDOW = "window"
|
||||||
|
@ -6,19 +6,16 @@ namespace esphome {
|
|||||||
|
|
||||||
static const char *const TAG = "entity_base";
|
static const char *const TAG = "entity_base";
|
||||||
|
|
||||||
EntityBase::EntityBase(std::string name) : name_(std::move(name)) { this->calc_object_id_(); }
|
|
||||||
|
|
||||||
// Entity Name
|
// Entity Name
|
||||||
const std::string &EntityBase::get_name() const { return this->name_; }
|
const StringRef &EntityBase::get_name() const { return this->name_; }
|
||||||
void EntityBase::set_name(const std::string &name) {
|
void EntityBase::set_name(const char *name) {
|
||||||
if (name.empty()) {
|
this->name_ = StringRef(name);
|
||||||
this->name_ = App.get_friendly_name();
|
if (this->name_.empty()) {
|
||||||
|
this->name_ = StringRef(App.get_friendly_name());
|
||||||
this->has_own_name_ = false;
|
this->has_own_name_ = false;
|
||||||
} else {
|
} else {
|
||||||
this->name_ = name;
|
|
||||||
this->has_own_name_ = true;
|
this->has_own_name_ = true;
|
||||||
}
|
}
|
||||||
this->calc_object_id_();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entity Internal
|
// Entity Internal
|
||||||
@ -43,13 +40,37 @@ EntityCategory EntityBase::get_entity_category() const { return this->entity_cat
|
|||||||
void EntityBase::set_entity_category(EntityCategory entity_category) { this->entity_category_ = entity_category; }
|
void EntityBase::set_entity_category(EntityCategory entity_category) { this->entity_category_ = entity_category; }
|
||||||
|
|
||||||
// Entity Object ID
|
// Entity Object ID
|
||||||
const std::string &EntityBase::get_object_id() { return this->object_id_; }
|
std::string EntityBase::get_object_id() const {
|
||||||
|
// Check if `App.get_friendly_name()` is constant or dynamic.
|
||||||
|
if (!this->has_own_name_ && App.is_name_add_mac_suffix_enabled()) {
|
||||||
|
// `App.get_friendly_name()` is dynamic.
|
||||||
|
return str_sanitize(str_snake_case(App.get_friendly_name()));
|
||||||
|
} else {
|
||||||
|
// `App.get_friendly_name()` is constant.
|
||||||
|
if (this->object_id_c_str_ == nullptr) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return this->object_id_c_str_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void EntityBase::set_object_id(const char *object_id) {
|
||||||
|
this->object_id_c_str_ = object_id;
|
||||||
|
this->calc_object_id_();
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate Object ID Hash from Entity Name
|
// Calculate Object ID Hash from Entity Name
|
||||||
void EntityBase::calc_object_id_() {
|
void EntityBase::calc_object_id_() {
|
||||||
this->object_id_ = str_sanitize(str_snake_case(this->name_));
|
// Check if `App.get_friendly_name()` is constant or dynamic.
|
||||||
// FNV-1 hash
|
if (!this->has_own_name_ && App.is_name_add_mac_suffix_enabled()) {
|
||||||
this->object_id_hash_ = fnv1_hash(this->object_id_);
|
// `App.get_friendly_name()` is dynamic.
|
||||||
|
const auto object_id = str_sanitize(str_snake_case(App.get_friendly_name()));
|
||||||
|
// FNV-1 hash
|
||||||
|
this->object_id_hash_ = fnv1_hash(object_id);
|
||||||
|
} else {
|
||||||
|
// `App.get_friendly_name()` is constant.
|
||||||
|
// FNV-1 hash
|
||||||
|
this->object_id_hash_ = fnv1_hash(this->object_id_c_str_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
uint32_t EntityBase::get_object_id_hash() { return this->object_id_hash_; }
|
uint32_t EntityBase::get_object_id_hash() { return this->object_id_hash_; }
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include "string_ref.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
|
|
||||||
@ -14,18 +15,16 @@ enum EntityCategory : uint8_t {
|
|||||||
// The generic Entity base class that provides an interface common to all Entities.
|
// The generic Entity base class that provides an interface common to all Entities.
|
||||||
class EntityBase {
|
class EntityBase {
|
||||||
public:
|
public:
|
||||||
EntityBase() : EntityBase("") {}
|
|
||||||
explicit EntityBase(std::string name);
|
|
||||||
|
|
||||||
// Get/set the name of this Entity
|
// Get/set the name of this Entity
|
||||||
const std::string &get_name() const;
|
const StringRef &get_name() const;
|
||||||
void set_name(const std::string &name);
|
void set_name(const char *name);
|
||||||
|
|
||||||
// Get whether this Entity has its own name or it should use the device friendly_name.
|
// Get whether this Entity has its own name or it should use the device friendly_name.
|
||||||
bool has_own_name() const { return this->has_own_name_; }
|
bool has_own_name() const { return this->has_own_name_; }
|
||||||
|
|
||||||
// Get the sanitized name of this Entity as an ID. Caching it internally.
|
// Get the sanitized name of this Entity as an ID.
|
||||||
const std::string &get_object_id();
|
std::string get_object_id() const;
|
||||||
|
void set_object_id(const char *object_id);
|
||||||
|
|
||||||
// Get the unique Object ID of this Entity
|
// Get the unique Object ID of this Entity
|
||||||
uint32_t get_object_id_hash();
|
uint32_t get_object_id_hash();
|
||||||
@ -54,11 +53,11 @@ class EntityBase {
|
|||||||
virtual uint32_t hash_base() { return 0L; }
|
virtual uint32_t hash_base() { return 0L; }
|
||||||
void calc_object_id_();
|
void calc_object_id_();
|
||||||
|
|
||||||
std::string name_;
|
StringRef name_;
|
||||||
bool has_own_name_{false};
|
const char *object_id_c_str_{nullptr};
|
||||||
std::string object_id_;
|
|
||||||
const char *icon_c_str_{nullptr};
|
const char *icon_c_str_{nullptr};
|
||||||
uint32_t object_id_hash_;
|
uint32_t object_id_hash_;
|
||||||
|
bool has_own_name_{false};
|
||||||
bool internal_{false};
|
bool internal_{false};
|
||||||
bool disabled_by_default_{false};
|
bool disabled_by_default_{false};
|
||||||
EntityCategory entity_category_{ENTITY_CATEGORY_NONE};
|
EntityCategory entity_category_{ENTITY_CATEGORY_NONE};
|
||||||
|
12
esphome/core/string_ref.cpp
Normal file
12
esphome/core/string_ref.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include "string_ref.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
|
||||||
|
#ifdef USE_JSON
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||||
|
void convertToJson(const StringRef &src, JsonVariant dst) { dst.set(src.c_str()); }
|
||||||
|
|
||||||
|
#endif // USE_JSON
|
||||||
|
|
||||||
|
} // namespace esphome
|
134
esphome/core/string_ref.h
Normal file
134
esphome/core/string_ref.h
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iterator>
|
||||||
|
#include <cstring>
|
||||||
|
#include "esphome/core/defines.h"
|
||||||
|
|
||||||
|
#ifdef USE_JSON
|
||||||
|
#include "esphome/components/json/json_util.h"
|
||||||
|
#endif // USE_JSON
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StringRef is a reference to a string owned by something else. So it behaves like simple string, but it does not own
|
||||||
|
* pointer. When it is default constructed, it has empty string. You can freely copy or move around this struct, but
|
||||||
|
* never free its pointer. str() function can be used to export the content as std::string. StringRef is adopted from
|
||||||
|
* <https://github.com/nghttp2/nghttp2/blob/29cbf8b83ff78faf405d1086b16adc09a8772eca/src/template.h#L376>
|
||||||
|
*/
|
||||||
|
class StringRef {
|
||||||
|
public:
|
||||||
|
using traits_type = std::char_traits<char>;
|
||||||
|
using value_type = traits_type::char_type;
|
||||||
|
using allocator_type = std::allocator<char>;
|
||||||
|
using size_type = std::allocator_traits<allocator_type>::size_type;
|
||||||
|
using difference_type = std::allocator_traits<allocator_type>::difference_type;
|
||||||
|
using const_reference = const value_type &;
|
||||||
|
using const_pointer = const value_type *;
|
||||||
|
using const_iterator = const_pointer;
|
||||||
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
|
|
||||||
|
constexpr StringRef() : base_(""), len_(0) {}
|
||||||
|
explicit StringRef(const std::string &s) : base_(s.c_str()), len_(s.size()) {}
|
||||||
|
explicit StringRef(const char *s) : base_(s), len_(strlen(s)) {}
|
||||||
|
constexpr StringRef(const char *s, size_t n) : base_(s), len_(n) {}
|
||||||
|
template<typename CharT>
|
||||||
|
constexpr StringRef(const CharT *s, size_t n) : base_(reinterpret_cast<const char *>(s)), len_(n) {}
|
||||||
|
template<typename InputIt>
|
||||||
|
StringRef(InputIt first, InputIt last)
|
||||||
|
: base_(reinterpret_cast<const char *>(&*first)), len_(std::distance(first, last)) {}
|
||||||
|
template<typename InputIt>
|
||||||
|
StringRef(InputIt *first, InputIt *last)
|
||||||
|
: base_(reinterpret_cast<const char *>(first)), len_(std::distance(first, last)) {}
|
||||||
|
template<typename CharT, size_t N> constexpr static StringRef from_lit(const CharT (&s)[N]) {
|
||||||
|
return StringRef{s, N - 1};
|
||||||
|
}
|
||||||
|
static StringRef from_maybe_nullptr(const char *s) {
|
||||||
|
if (s == nullptr) {
|
||||||
|
return StringRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringRef(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const_iterator begin() const { return base_; };
|
||||||
|
constexpr const_iterator cbegin() const { return base_; };
|
||||||
|
|
||||||
|
constexpr const_iterator end() const { return base_ + len_; };
|
||||||
|
constexpr const_iterator cend() const { return base_ + len_; };
|
||||||
|
|
||||||
|
const_reverse_iterator rbegin() const { return const_reverse_iterator{base_ + len_}; }
|
||||||
|
const_reverse_iterator crbegin() const { return const_reverse_iterator{base_ + len_}; }
|
||||||
|
|
||||||
|
const_reverse_iterator rend() const { return const_reverse_iterator{base_}; }
|
||||||
|
const_reverse_iterator crend() const { return const_reverse_iterator{base_}; }
|
||||||
|
|
||||||
|
constexpr const char *c_str() const { return base_; }
|
||||||
|
constexpr size_type size() const { return len_; }
|
||||||
|
constexpr bool empty() const { return len_ == 0; }
|
||||||
|
constexpr const_reference operator[](size_type pos) const { return *(base_ + pos); }
|
||||||
|
|
||||||
|
std::string str() const { return std::string(base_, len_); }
|
||||||
|
const uint8_t *byte() const { return reinterpret_cast<const uint8_t *>(base_); }
|
||||||
|
|
||||||
|
operator std::string() const { return str(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char *base_;
|
||||||
|
size_type len_;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator==(const StringRef &lhs, const StringRef &rhs) {
|
||||||
|
return lhs.size() == rhs.size() && std::equal(std::begin(lhs), std::end(lhs), std::begin(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const StringRef &lhs, const std::string &rhs) {
|
||||||
|
return lhs.size() == rhs.size() && std::equal(std::begin(lhs), std::end(lhs), std::begin(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const std::string &lhs, const StringRef &rhs) { return rhs == lhs; }
|
||||||
|
|
||||||
|
inline bool operator==(const StringRef &lhs, const char *rhs) {
|
||||||
|
return lhs.size() == strlen(rhs) && std::equal(std::begin(lhs), std::end(lhs), rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const char *lhs, const StringRef &rhs) { return rhs == lhs; }
|
||||||
|
|
||||||
|
inline bool operator!=(const StringRef &lhs, const StringRef &rhs) { return !(lhs == rhs); }
|
||||||
|
|
||||||
|
inline bool operator!=(const StringRef &lhs, const std::string &rhs) { return !(lhs == rhs); }
|
||||||
|
|
||||||
|
inline bool operator!=(const std::string &lhs, const StringRef &rhs) { return !(rhs == lhs); }
|
||||||
|
|
||||||
|
inline bool operator!=(const StringRef &lhs, const char *rhs) { return !(lhs == rhs); }
|
||||||
|
|
||||||
|
inline bool operator!=(const char *lhs, const StringRef &rhs) { return !(rhs == lhs); }
|
||||||
|
|
||||||
|
inline bool operator<(const StringRef &lhs, const StringRef &rhs) {
|
||||||
|
return std::lexicographical_compare(std::begin(lhs), std::end(lhs), std::begin(rhs), std::end(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string &operator+=(std::string &lhs, const StringRef &rhs) {
|
||||||
|
lhs.append(rhs.c_str(), rhs.size());
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string operator+(const char *lhs, const StringRef &rhs) {
|
||||||
|
auto str = std::string(lhs);
|
||||||
|
str.append(rhs.c_str(), rhs.size());
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string operator+(const StringRef &lhs, const char *rhs) {
|
||||||
|
auto str = lhs.str();
|
||||||
|
str.append(rhs);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_JSON
|
||||||
|
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||||
|
void convertToJson(const StringRef &src, JsonVariant dst);
|
||||||
|
#endif // USE_JSON
|
||||||
|
|
||||||
|
} // namespace esphome
|
@ -20,6 +20,7 @@ from esphome.types import ConfigType, ConfigFragmentType
|
|||||||
from esphome.cpp_generator import add, get_variable
|
from esphome.cpp_generator import add, get_variable
|
||||||
from esphome.cpp_types import App
|
from esphome.cpp_types import App
|
||||||
from esphome.util import Registry, RegistryEntry
|
from esphome.util import Registry, RegistryEntry
|
||||||
|
from esphome.helpers import snake_case, sanitize
|
||||||
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -101,6 +102,10 @@ async def register_parented(var, value):
|
|||||||
async def setup_entity(var, config):
|
async def setup_entity(var, config):
|
||||||
"""Set up generic properties of an Entity"""
|
"""Set up generic properties of an Entity"""
|
||||||
add(var.set_name(config[CONF_NAME]))
|
add(var.set_name(config[CONF_NAME]))
|
||||||
|
if not config[CONF_NAME]:
|
||||||
|
add(var.set_object_id(sanitize(snake_case(CORE.friendly_name))))
|
||||||
|
else:
|
||||||
|
add(var.set_object_id(sanitize(snake_case(config[CONF_NAME]))))
|
||||||
add(var.set_disabled_by_default(config[CONF_DISABLED_BY_DEFAULT]))
|
add(var.set_disabled_by_default(config[CONF_DISABLED_BY_DEFAULT]))
|
||||||
if CONF_INTERNAL in config:
|
if CONF_INTERNAL in config:
|
||||||
add(var.set_internal(config[CONF_INTERNAL]))
|
add(var.set_internal(config[CONF_INTERNAL]))
|
||||||
|
@ -7,6 +7,7 @@ from pathlib import Path
|
|||||||
from typing import Union
|
from typing import Union
|
||||||
import tempfile
|
import tempfile
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
import re
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -334,3 +335,13 @@ def add_class_to_obj(value, cls):
|
|||||||
if type(value) is type_: # pylint: disable=unidiomatic-typecheck
|
if type(value) is type_: # pylint: disable=unidiomatic-typecheck
|
||||||
return add_class_to_obj(func(value), cls)
|
return add_class_to_obj(func(value), cls)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
def snake_case(value):
|
||||||
|
"""Same behaviour as `helpers.cpp` method `str_snake_case`."""
|
||||||
|
return value.replace(" ", "_").lower()
|
||||||
|
|
||||||
|
|
||||||
|
def sanitize(value):
|
||||||
|
"""Same behaviour as `helpers.cpp` method `str_sanitize`."""
|
||||||
|
return re.sub("[^-_0-9a-zA-Z]", r"", value)
|
||||||
|
@ -25,9 +25,9 @@ DOMAINS = {
|
|||||||
|
|
||||||
|
|
||||||
def sub(path, pattern, repl):
|
def sub(path, pattern, repl):
|
||||||
with open(path, "r") as handle:
|
with open(path) as handle:
|
||||||
content = handle.read()
|
content = handle.read()
|
||||||
content = re.sub(pattern, repl, content, flags=re.MULTILINE, count=1)
|
content = re.sub(pattern, repl, content, flags=re.MULTILINE)
|
||||||
with open(path, "w") as handle:
|
with open(path, "w") as handle:
|
||||||
handle.write(content)
|
handle.write(content)
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ def main():
|
|||||||
out = ""
|
out = ""
|
||||||
for cls in sorted(classes):
|
for cls in sorted(classes):
|
||||||
out += f'DEVICE_CLASS_{cls.upper()} = "{classes[cls]}"\n'
|
out += f'DEVICE_CLASS_{cls.upper()} = "{classes[cls]}"\n'
|
||||||
sub("esphome/const.py", '(DEVICE_CLASS_\w+ = "\w*"\r?\n)+', out)
|
sub("esphome/const.py", '(DEVICE_CLASS_\\w+ = "\\w*"\r?\n)+', out)
|
||||||
|
|
||||||
for domain in sorted(allowed):
|
for domain in sorted(allowed):
|
||||||
# replace imports
|
# replace imports
|
||||||
@ -58,7 +58,7 @@ def main():
|
|||||||
|
|
||||||
sub(
|
sub(
|
||||||
f"esphome/components/{domain}/__init__.py",
|
f"esphome/components/{domain}/__init__.py",
|
||||||
"( DEVICE_CLASS_\w+,\r?\n)+",
|
"( DEVICE_CLASS_\\w+,\r?\n)+",
|
||||||
out,
|
out,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -229,3 +229,37 @@ def test_file_compare(fixture_path, file1, file2, expected):
|
|||||||
actual = helpers.file_compare(path1, path2)
|
actual = helpers.file_compare(path1, path2)
|
||||||
|
|
||||||
assert actual == expected
|
assert actual == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"text, expected",
|
||||||
|
(
|
||||||
|
("foo", "foo"),
|
||||||
|
("foo bar", "foo_bar"),
|
||||||
|
("foo Bar", "foo_bar"),
|
||||||
|
("foo BAR", "foo_bar"),
|
||||||
|
("foo.bar", "foo.bar"),
|
||||||
|
("fooBAR", "foobar"),
|
||||||
|
("Foo-bar_EEK", "foo-bar_eek"),
|
||||||
|
(" foo", "__foo"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
def test_snake_case(text, expected):
|
||||||
|
actual = helpers.snake_case(text)
|
||||||
|
|
||||||
|
assert actual == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"text, expected",
|
||||||
|
(
|
||||||
|
("foo_bar", "foo_bar"),
|
||||||
|
('!"§$%&/()=?foo_bar', "foo_bar"),
|
||||||
|
('foo_!"§$%&/()=?bar', "foo_bar"),
|
||||||
|
('foo_bar!"§$%&/()=?', "foo_bar"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
def test_sanitize(text, expected):
|
||||||
|
actual = helpers.sanitize(text)
|
||||||
|
|
||||||
|
assert actual == expected
|
||||||
|
Loading…
x
Reference in New Issue
Block a user