Compare commits
17 Commits
2022.1.0b2
...
ble-server
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7401fd42a8 | ||
|
|
737188ae50 | ||
|
|
db21731b14 | ||
|
|
cdb4fa2487 | ||
|
|
514204f0d4 | ||
|
|
45ac577c4d | ||
|
|
09402fdb22 | ||
|
|
89e7448007 | ||
|
|
1ea6f957bc | ||
|
|
f44fca0a4b | ||
|
|
52d2f62a57 | ||
|
|
2a8668ea60 | ||
|
|
cc0d433621 | ||
|
|
1fe89fb364 | ||
|
|
238788365b | ||
|
|
cc85315ce1 | ||
|
|
44b24a54b2 |
@@ -3,4 +3,4 @@ ports:
|
|||||||
onOpen: open-preview
|
onOpen: open-preview
|
||||||
tasks:
|
tasks:
|
||||||
- before: pyenv local $(pyenv version | grep '^3\.' | cut -d ' ' -f 1) && script/setup
|
- before: pyenv local $(pyenv version | grep '^3\.' | cut -d ' ' -f 1) && script/setup
|
||||||
command: python -m esphome config dashboard
|
command: python -m esphome dashboard config
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ esphome/components/ds1307/* @badbadc0ffee
|
|||||||
esphome/components/dsmr/* @glmnet @zuidwijk
|
esphome/components/dsmr/* @glmnet @zuidwijk
|
||||||
esphome/components/esp32/* @esphome/core
|
esphome/components/esp32/* @esphome/core
|
||||||
esphome/components/esp32_ble/* @jesserockz
|
esphome/components/esp32_ble/* @jesserockz
|
||||||
|
esphome/components/esp32_ble_controller/* @jesserockz
|
||||||
esphome/components/esp32_ble_server/* @jesserockz
|
esphome/components/esp32_ble_server/* @jesserockz
|
||||||
esphome/components/esp32_camera_web_server/* @ayufan
|
esphome/components/esp32_camera_web_server/* @ayufan
|
||||||
esphome/components/esp32_can/* @Sympatron
|
esphome/components/esp32_can/* @Sympatron
|
||||||
|
|||||||
@@ -76,8 +76,6 @@ async def to_code(config):
|
|||||||
pos = 0
|
pos = 0
|
||||||
for frameIndex in range(frames):
|
for frameIndex in range(frames):
|
||||||
image.seek(frameIndex)
|
image.seek(frameIndex)
|
||||||
if CONF_RESIZE in config:
|
|
||||||
image.thumbnail(config[CONF_RESIZE])
|
|
||||||
frame = image.convert("RGB")
|
frame = image.convert("RGB")
|
||||||
if CONF_RESIZE in config:
|
if CONF_RESIZE in config:
|
||||||
frame = frame.resize([width, height])
|
frame = frame.resize([width, height])
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "api_frame_helper.h"
|
#include "api_frame_helper.h"
|
||||||
|
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
#include "esphome/core/hal.h"
|
||||||
#include "esphome/core/helpers.h"
|
#include "esphome/core/helpers.h"
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@@ -721,7 +722,12 @@ APIError APINoiseFrameHelper::shutdown(int how) {
|
|||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// declare how noise generates random bytes (here with a good HWRNG based on the RF system)
|
// declare how noise generates random bytes (here with a good HWRNG based on the RF system)
|
||||||
void noise_rand_bytes(void *output, size_t len) { esphome::random_bytes(reinterpret_cast<uint8_t *>(output), len); }
|
void noise_rand_bytes(void *output, size_t len) {
|
||||||
|
if (!esphome::random_bytes(reinterpret_cast<uint8_t *>(output), len)) {
|
||||||
|
ESP_LOGE(TAG, "Failed to acquire random bytes, rebooting!");
|
||||||
|
arch_restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // USE_API_NOISE
|
#endif // USE_API_NOISE
|
||||||
|
|
||||||
|
|||||||
@@ -74,8 +74,10 @@ class BinarySensor : public EntityBase {
|
|||||||
|
|
||||||
// ========== OVERRIDE METHODS ==========
|
// ========== OVERRIDE METHODS ==========
|
||||||
// (You'll only need this when creating your own custom binary sensor)
|
// (You'll only need this when creating your own custom binary sensor)
|
||||||
/// Get the default device class for this sensor, or empty string for no default.
|
/** Override this to set the default device class.
|
||||||
ESPDEPRECATED("device_class() is deprecated, set property during config validation instead.", "2022.01")
|
*
|
||||||
|
* @deprecated This method is deprecated, set the property during config validation instead. (2022.1)
|
||||||
|
*/
|
||||||
virtual std::string device_class();
|
virtual std::string device_class();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -169,7 +169,11 @@ class Cover : public EntityBase {
|
|||||||
friend CoverCall;
|
friend CoverCall;
|
||||||
|
|
||||||
virtual void control(const CoverCall &call) = 0;
|
virtual void control(const CoverCall &call) = 0;
|
||||||
ESPDEPRECATED("device_class() is deprecated, set property during config validation instead.", "2022.01")
|
|
||||||
|
/** Override this to set the default device class.
|
||||||
|
*
|
||||||
|
* @deprecated This method is deprecated, set the property during config validation instead. (2022.1)
|
||||||
|
*/
|
||||||
virtual std::string device_class();
|
virtual std::string device_class();
|
||||||
|
|
||||||
optional<CoverRestoreState> restore_state_();
|
optional<CoverRestoreState> restore_state_();
|
||||||
|
|||||||
@@ -417,7 +417,7 @@ def copy_files():
|
|||||||
)
|
)
|
||||||
|
|
||||||
dir = os.path.dirname(__file__)
|
dir = os.path.dirname(__file__)
|
||||||
post_build_file = os.path.join(dir, "post_build.py")
|
post_build_file = os.path.join(dir, "post_build.py.script")
|
||||||
copy_file_if_changed(
|
copy_file_if_changed(
|
||||||
post_build_file,
|
post_build_file,
|
||||||
CORE.relative_build_path("post_build.py"),
|
CORE.relative_build_path("post_build.py"),
|
||||||
|
|||||||
60
esphome/components/esp32_ble_controller/__init__.py
Normal file
60
esphome/components/esp32_ble_controller/__init__.py
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import esp32_ble_server, logger
|
||||||
|
from esphome.const import (
|
||||||
|
CONF_BLE_SERVER_ID,
|
||||||
|
CONF_ID,
|
||||||
|
CONF_LEVEL,
|
||||||
|
CONF_LOGGER,
|
||||||
|
ESP_PLATFORM_ESP32,
|
||||||
|
)
|
||||||
|
|
||||||
|
AUTO_LOAD = ["esp32_ble_server"]
|
||||||
|
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||||
|
CODEOWNERS = ["@jesserockz"]
|
||||||
|
CONFLICTS_WITH = ["esp32_ble_tracker", "esp32_ble_beacon"]
|
||||||
|
|
||||||
|
CONF_LOG_LEVEL = "log_level"
|
||||||
|
|
||||||
|
esp32_ble_controller_ns = cg.esphome_ns.namespace("esp32_ble_controller")
|
||||||
|
BLEController = esp32_ble_controller_ns.class_(
|
||||||
|
"BLEController",
|
||||||
|
cg.Component,
|
||||||
|
cg.Controller,
|
||||||
|
esp32_ble_server.BLEServiceComponent,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def validate(config, item_config):
|
||||||
|
global_level = config[CONF_LOGGER][CONF_LEVEL]
|
||||||
|
level = item_config.get(CONF_LOG_LEVEL, "DEBUG")
|
||||||
|
if logger.LOG_LEVEL_SEVERITY.index(level) > logger.LOG_LEVEL_SEVERITY.index(
|
||||||
|
global_level
|
||||||
|
):
|
||||||
|
raise ValueError(
|
||||||
|
"The esp32_ble_controller log level {} must be less severe than the "
|
||||||
|
"global log level {}.".format(level, global_level)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(BLEController),
|
||||||
|
cv.GenerateID(CONF_BLE_SERVER_ID): cv.use_id(esp32_ble_server.BLEServer),
|
||||||
|
cv.Optional(CONF_LOG_LEVEL): cv.All(
|
||||||
|
cv.requires_component("logger"),
|
||||||
|
logger.is_log_level,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
).extend(cv.COMPONENT_SCHEMA)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
await cg.register_component(var, config)
|
||||||
|
|
||||||
|
ble_server = await cg.get_variable(config[CONF_BLE_SERVER_ID])
|
||||||
|
cg.add(ble_server.register_service_component(var))
|
||||||
|
|
||||||
|
if CONF_LOG_LEVEL in config:
|
||||||
|
cg.add(var.set_log_level(logger.LOG_LEVELS[config[CONF_LOG_LEVEL]]))
|
||||||
387
esphome/components/esp32_ble_controller/ble_controller.cpp
Normal file
387
esphome/components/esp32_ble_controller/ble_controller.cpp
Normal file
@@ -0,0 +1,387 @@
|
|||||||
|
#include "ble_controller.h"
|
||||||
|
|
||||||
|
#include "esphome/core/application.h"
|
||||||
|
#include "esphome/components/esp32_ble_server/ble_2901.h"
|
||||||
|
#include "esphome/components/esp32_ble_server/ble_2902.h"
|
||||||
|
|
||||||
|
#ifdef USE_LOGGER
|
||||||
|
#include "esphome/components/logger/logger.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace esp32_ble_controller {
|
||||||
|
|
||||||
|
static const char *const ESPHOME_SERVICE_UUID = "03774663-d394-496e-8dcd-000000000000";
|
||||||
|
static const char *const LOGGER_CHARACTERISTIC_UUID = "03774663-d394-496e-8dcd-000000000001";
|
||||||
|
|
||||||
|
static const char *const BINARY_SENSOR_SERVICE_UUID = "03774663-d394-496e-8dcd-000100000000";
|
||||||
|
static const char *const COVER_SERVICE_UUID = "03774663-d394-496e-8dcd-000200000000";
|
||||||
|
static const char *const FAN_SERVICE_UUID = "03774663-d394-496e-8dcd-000300000000";
|
||||||
|
static const char *const LIGHT_SERVICE_UUID = "03774663-d394-496e-8dcd-000400000000";
|
||||||
|
static const char *const SENSOR_SERVICE_UUID = "03774663-d394-496e-8dcd-000500000000";
|
||||||
|
static const char *const SWITCH_SERVICE_UUID = "03774663-d394-496e-8dcd-000600000000";
|
||||||
|
static const char *const TEXT_SENSOR_SERVICE_UUID = "03774663-d394-496e-8dcd-000700000000";
|
||||||
|
static const char *const CLIMATE_SERVICE_UUID = "03774663-d394-496e-8dcd-000800000000";
|
||||||
|
|
||||||
|
static const char *const TAG = "esp32_ble_controller";
|
||||||
|
|
||||||
|
void BLEController::setup() {
|
||||||
|
ESP_LOGD(TAG, "Setting up BLE controller");
|
||||||
|
this->esphome_service_ = global_ble_server->create_service(ESPHOME_SERVICE_UUID);
|
||||||
|
|
||||||
|
#ifdef USE_LOGGER
|
||||||
|
{
|
||||||
|
this->logger_characteristic_ = this->esphome_service_->create_characteristic(
|
||||||
|
LOGGER_CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
|
||||||
|
|
||||||
|
BLEDescriptor *logger_name = new BLE2901("Logger");
|
||||||
|
this->logger_characteristic_->add_descriptor(logger_name);
|
||||||
|
|
||||||
|
BLEDescriptor *descriptor_2902 = new BLE2902();
|
||||||
|
this->logger_characteristic_->add_descriptor(descriptor_2902);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
{
|
||||||
|
auto binary_sensors = App.get_binary_sensors();
|
||||||
|
if (!binary_sensors.empty()) {
|
||||||
|
this->binary_sensor_service_ = global_ble_server->create_service(BINARY_SENSOR_SERVICE_UUID);
|
||||||
|
for (auto *obj : binary_sensors) {
|
||||||
|
std::string uuid = std::string(BINARY_SENSOR_SERVICE_UUID).substr(0, 28);
|
||||||
|
uuid += uint32_to_string(obj->get_object_id_hash());
|
||||||
|
BLECharacteristic *characteristic = this->binary_sensor_service_->create_characteristic(
|
||||||
|
uuid, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
|
||||||
|
|
||||||
|
BLEDescriptor *name = new BLE2901(obj->get_name());
|
||||||
|
characteristic->add_descriptor(name);
|
||||||
|
|
||||||
|
BLEDescriptor *descriptor = new BLE2902();
|
||||||
|
characteristic->add_descriptor(descriptor);
|
||||||
|
|
||||||
|
this->characteristics_.insert(
|
||||||
|
std::pair<uint32_t, BLECharacteristic *>(obj->get_object_id_hash(), characteristic));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_COVER
|
||||||
|
if (!App.get_covers().empty()) {
|
||||||
|
this->cover_service_ = global_ble_server->create_service(COVER_SERVICE_UUID);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_FAN
|
||||||
|
if (!App.get_fans().empty()) {
|
||||||
|
this->fan_service_ = global_ble_server->create_service(FAN_SERVICE_UUID);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_LIGHT
|
||||||
|
if (!App.get_lights().empty()) {
|
||||||
|
this->light_service_ = global_ble_server->create_service(LIGHT_SERVICE_UUID);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
{
|
||||||
|
auto sensors = App.get_sensors();
|
||||||
|
if (!sensors.empty()) {
|
||||||
|
this->sensor_service_ = global_ble_server->create_service(SENSOR_SERVICE_UUID);
|
||||||
|
for (auto *obj : sensors) {
|
||||||
|
std::string uuid = std::string(SENSOR_SERVICE_UUID).substr(0, 28);
|
||||||
|
uuid += uint32_to_string(obj->get_object_id_hash());
|
||||||
|
BLECharacteristic *characteristic = this->sensor_service_->create_characteristic(
|
||||||
|
uuid, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
|
||||||
|
|
||||||
|
BLEDescriptor *name = new BLE2901(obj->get_name());
|
||||||
|
characteristic->add_descriptor(name);
|
||||||
|
|
||||||
|
BLEDescriptor *descriptor = new BLE2902();
|
||||||
|
characteristic->add_descriptor(descriptor);
|
||||||
|
|
||||||
|
this->characteristics_.insert(
|
||||||
|
std::pair<uint32_t, BLECharacteristic *>(obj->get_object_id_hash(), characteristic));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SWITCH
|
||||||
|
{
|
||||||
|
auto switches = App.get_switches();
|
||||||
|
if (!switches.empty()) {
|
||||||
|
this->switch_service_ = global_ble_server->create_service(SWITCH_SERVICE_UUID);
|
||||||
|
for (auto *obj : switches) {
|
||||||
|
std::string uuid = std::string(SWITCH_SERVICE_UUID).substr(0, 28);
|
||||||
|
uuid += uint32_to_string(obj->get_object_id_hash());
|
||||||
|
BLECharacteristic *characteristic = this->switch_service_->create_characteristic(
|
||||||
|
uuid,
|
||||||
|
BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY | BLECharacteristic::PROPERTY_WRITE);
|
||||||
|
|
||||||
|
BLEDescriptor *name = new BLE2901(obj->get_name());
|
||||||
|
characteristic->add_descriptor(name);
|
||||||
|
|
||||||
|
BLEDescriptor *descriptor = new BLE2902();
|
||||||
|
characteristic->add_descriptor(descriptor);
|
||||||
|
|
||||||
|
this->characteristics_.insert(
|
||||||
|
std::pair<uint32_t, BLECharacteristic *>(obj->get_object_id_hash(), characteristic));
|
||||||
|
|
||||||
|
characteristic->on_write([obj](std::vector<uint8_t> data) {
|
||||||
|
if (data[0])
|
||||||
|
obj->turn_on();
|
||||||
|
else
|
||||||
|
obj->turn_off();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TEXT_SENSOR
|
||||||
|
{
|
||||||
|
auto text_sensors = App.get_text_sensors();
|
||||||
|
if (!text_sensors.empty()) {
|
||||||
|
this->text_sensor_service_ = global_ble_server->create_service(TEXT_SENSOR_SERVICE_UUID);
|
||||||
|
for (auto *obj : text_sensors) {
|
||||||
|
std::string uuid = std::string(TEXT_SENSOR_SERVICE_UUID).substr(0, 28);
|
||||||
|
uuid += uint32_to_string(obj->get_object_id_hash());
|
||||||
|
BLECharacteristic *characteristic = this->text_sensor_service_->create_characteristic(
|
||||||
|
uuid, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
|
||||||
|
|
||||||
|
BLEDescriptor *name = new BLE2901(obj->get_name());
|
||||||
|
characteristic->add_descriptor(name);
|
||||||
|
|
||||||
|
BLEDescriptor *descriptor = new BLE2902();
|
||||||
|
characteristic->add_descriptor(descriptor);
|
||||||
|
|
||||||
|
this->characteristics_.insert(
|
||||||
|
std::pair<uint32_t, BLECharacteristic *>(obj->get_object_id_hash(), characteristic));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_CLIMATE
|
||||||
|
if (!App.get_climates().empty()) {
|
||||||
|
this->cover_service_ = global_ble_server->create_service(COVER_SERVICE_UUID);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
this->state_ = CREATING;
|
||||||
|
this->setup_controller();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BLEController::loop() {
|
||||||
|
switch (this->state_) {
|
||||||
|
case CREATING: {
|
||||||
|
bool all_created = true;
|
||||||
|
all_created &= this->esphome_service_->is_created();
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
all_created &= this->binary_sensor_service_ == nullptr || this->binary_sensor_service_->is_created();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_COVER
|
||||||
|
all_created &= this->cover_service_ == nullptr || this->cover_service_->is_created();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_FAN
|
||||||
|
all_created &= this->fan_service_ == nullptr || this->fan_service_->is_created();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_LIGHT
|
||||||
|
all_created &= this->light_service_ == nullptr || this->light_service_->is_created();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
all_created &= this->sensor_service_ == nullptr || this->sensor_service_->is_created();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SWITCH
|
||||||
|
all_created &= this->switch_service_ == nullptr || this->switch_service_->is_created();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TEXT_SENSOR
|
||||||
|
all_created &= this->text_sensor_service_ == nullptr || this->text_sensor_service_->is_created();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_CLIMATE
|
||||||
|
all_created &= this->climate_service_ == nullptr || this->climate_service_->is_created();
|
||||||
|
#endif
|
||||||
|
if (all_created) {
|
||||||
|
ESP_LOGI(TAG, "All services created");
|
||||||
|
this->state_ = STARTING;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STARTING: {
|
||||||
|
bool all_running = true;
|
||||||
|
|
||||||
|
all_running &= this->esphome_service_->is_running();
|
||||||
|
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
all_running &= this->binary_sensor_service_ == nullptr || this->binary_sensor_service_->is_running();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_COVER
|
||||||
|
all_running &= this->cover_service_ == nullptr || this->cover_service_->is_running();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_FAN
|
||||||
|
all_running &= this->fan_service_ == nullptr || this->fan_service_->is_running();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_LIGHT
|
||||||
|
all_running &= this->light_service_ == nullptr || this->light_service_->is_running();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
all_running &= this->sensor_service_ == nullptr || this->sensor_service_->is_running();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SWITCH
|
||||||
|
all_running &= this->switch_service_ == nullptr || this->switch_service_->is_running();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TEXT_SENSOR
|
||||||
|
all_running &= this->text_sensor_service_ == nullptr || this->text_sensor_service_->is_running();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_CLIMATE
|
||||||
|
all_running &= this->climate_service_ == nullptr || this->climate_service_->is_running();
|
||||||
|
#endif
|
||||||
|
if (all_running) {
|
||||||
|
ESP_LOGD(TAG, "BLE Controller started");
|
||||||
|
this->state_ = RUNNING;
|
||||||
|
#ifdef USE_LOGGER
|
||||||
|
logger::global_logger->add_on_log_callback([this](int level, const char *tag, const char *message) {
|
||||||
|
if (level > this->log_level_)
|
||||||
|
return;
|
||||||
|
std::string log;
|
||||||
|
log += "[";
|
||||||
|
log += tag;
|
||||||
|
log += "] ";
|
||||||
|
log += message;
|
||||||
|
this->logger_characteristic_->set_value(log);
|
||||||
|
this->logger_characteristic_->notify();
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
this->esphome_service_->start();
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
this->binary_sensor_service_->start();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_COVER
|
||||||
|
this->cover_service_->start();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_FAN
|
||||||
|
this->fan_service_->start();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_LIGHT
|
||||||
|
this->light_service_->start();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
this->sensor_service_->start();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SWITCH
|
||||||
|
this->switch_service_->start();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TEXT_SENSOR
|
||||||
|
this->text_sensor_service_->start();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_CLIMATE
|
||||||
|
this->climate_service_->start();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case RUNNING:
|
||||||
|
case INIT:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BLEController::start() {
|
||||||
|
if (this->state_ == RUNNING)
|
||||||
|
return;
|
||||||
|
this->state_ = STARTING;
|
||||||
|
}
|
||||||
|
void BLEController::stop() {
|
||||||
|
this->esphome_service_->stop();
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
this->binary_sensor_service_->stop();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_COVER
|
||||||
|
this->cover_service_->stop();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_FAN
|
||||||
|
this->fan_service_->stop();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_LIGHT
|
||||||
|
this->light_service_->stop();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
this->sensor_service_->stop();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SWITCH
|
||||||
|
this->switch_service_->stop();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TEXT_SENSOR
|
||||||
|
this->text_sensor_service_->stop();
|
||||||
|
#endif
|
||||||
|
#ifdef USE_CLIMATE
|
||||||
|
this->climate_service_->stop();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
float BLEController::get_setup_priority() const { return setup_priority::AFTER_BLUETOOTH; }
|
||||||
|
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
void BLEController::on_binary_sensor_update(binary_sensor::BinarySensor *obj, bool state) {
|
||||||
|
if (obj->is_internal())
|
||||||
|
return;
|
||||||
|
auto *characteristic = this->characteristics_[obj->get_object_id_hash()];
|
||||||
|
characteristic->set_value(state);
|
||||||
|
characteristic->notify();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_COVER
|
||||||
|
void BLEController::on_cover_update(cover::Cover *obj) {
|
||||||
|
if (obj->is_internal())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_FAN
|
||||||
|
void BLEController::on_fan_update(fan::FanState *obj) {
|
||||||
|
if (obj->is_internal())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_LIGHT
|
||||||
|
void BLEController::on_light_update(light::LightState *obj) {
|
||||||
|
if (obj->is_internal())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
void BLEController::on_sensor_update(sensor::Sensor *obj, float state) {
|
||||||
|
if (obj->is_internal())
|
||||||
|
return;
|
||||||
|
auto *characteristic = this->characteristics_[obj->get_object_id_hash()];
|
||||||
|
characteristic->set_value(state);
|
||||||
|
characteristic->notify();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SWITCH
|
||||||
|
void BLEController::on_switch_update(switch_::Switch *obj, bool state) {
|
||||||
|
if (obj->is_internal())
|
||||||
|
return;
|
||||||
|
auto *characteristic = this->characteristics_[obj->get_object_id_hash()];
|
||||||
|
characteristic->set_value(state);
|
||||||
|
characteristic->notify();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TEXT_SENSOR
|
||||||
|
void BLEController::on_text_sensor_update(text_sensor::TextSensor *obj, const std::string &state) {
|
||||||
|
if (obj->is_internal())
|
||||||
|
return;
|
||||||
|
auto *characteristic = this->characteristics_[obj->get_object_id_hash()];
|
||||||
|
characteristic->set_value(state);
|
||||||
|
characteristic->notify();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_CLIMATE
|
||||||
|
void BLEController::on_climate_update(climate::Climate *obj) {
|
||||||
|
if (obj->is_internal())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace esp32_ble_controller
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif
|
||||||
106
esphome/components/esp32_ble_controller/ble_controller.h
Normal file
106
esphome/components/esp32_ble_controller/ble_controller.h
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/core/controller.h"
|
||||||
|
#include "esphome/components/esp32_ble_server/ble_2901.h"
|
||||||
|
#include "esphome/components/esp32_ble_server/ble_2902.h"
|
||||||
|
#include "esphome/components/esp32_ble_server/ble_characteristic.h"
|
||||||
|
#include "esphome/components/esp32_ble_server/ble_server.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#ifdef USE_LOGGER
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace esp32_ble_controller {
|
||||||
|
|
||||||
|
using namespace esp32_ble_server;
|
||||||
|
|
||||||
|
class BLEController : public Component, public Controller, public esp32_ble_server::BLEServiceComponent {
|
||||||
|
public:
|
||||||
|
void loop() override;
|
||||||
|
void setup() override;
|
||||||
|
void start() override;
|
||||||
|
void stop() override;
|
||||||
|
|
||||||
|
float get_setup_priority() const override;
|
||||||
|
|
||||||
|
#ifdef USE_LOGGER
|
||||||
|
void set_log_level(int level) { this->log_level_ = level; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
void on_binary_sensor_update(binary_sensor::BinarySensor *obj, bool state) override;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_COVER
|
||||||
|
void on_cover_update(cover::Cover *obj) override;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_FAN
|
||||||
|
void on_fan_update(fan::FanState *obj) override;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_LIGHT
|
||||||
|
void on_light_update(light::LightState *obj) override;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
void on_sensor_update(sensor::Sensor *obj, float state) override;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SWITCH
|
||||||
|
void on_switch_update(switch_::Switch *obj, bool state) override;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TEXT_SENSOR
|
||||||
|
void on_text_sensor_update(text_sensor::TextSensor *obj, const std::string &state) override;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_CLIMATE
|
||||||
|
void on_climate_update(climate::Climate *obj) override;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
enum State : uint8_t {
|
||||||
|
FAILED = 0x00,
|
||||||
|
INIT,
|
||||||
|
CREATING,
|
||||||
|
STARTING,
|
||||||
|
RUNNING,
|
||||||
|
} state_{INIT};
|
||||||
|
|
||||||
|
std::map<uint32_t, BLECharacteristic *> characteristics_;
|
||||||
|
|
||||||
|
BLEService *esphome_service_;
|
||||||
|
#ifdef USE_LOGGER
|
||||||
|
BLECharacteristic *logger_characteristic_;
|
||||||
|
int log_level_{ESPHOME_LOG_LEVEL_DEBUG};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
BLEService *binary_sensor_service_;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_COVER
|
||||||
|
BLEService *cover_service_;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_FAN
|
||||||
|
BLEService *fan_service_;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_LIGHT
|
||||||
|
BLEService *light_service_;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
BLEService *sensor_service_;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SWITCH
|
||||||
|
BLEService *switch_service_;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TEXT_SENSOR
|
||||||
|
BLEService *text_sensor_service_;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_CLIMATE
|
||||||
|
BLEService *climate_service_;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace esp32_ble_controller
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -61,14 +61,11 @@ void BLEServer::loop() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case STARTING_SERVICE: {
|
case STARTING_SERVICE: {
|
||||||
if (!this->device_information_service_->is_created()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (this->device_information_service_->is_running()) {
|
if (this->device_information_service_->is_running()) {
|
||||||
this->state_ = RUNNING;
|
this->state_ = RUNNING;
|
||||||
this->can_proceed_ = true;
|
this->can_proceed_ = true;
|
||||||
ESP_LOGD(TAG, "BLE server setup successfully");
|
ESP_LOGD(TAG, "BLE server setup successfully");
|
||||||
} else if (!this->device_information_service_->is_starting()) {
|
} else if (this->device_information_service_->is_created() && !this->device_information_service_->is_starting()) {
|
||||||
this->device_information_service_->start();
|
this->device_information_service_->start();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -72,9 +72,14 @@ bool BLEService::do_create_characteristics_() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BLEService::start() {
|
void BLEService::start() {
|
||||||
|
if (this->running_state_ == RUNNING)
|
||||||
|
return;
|
||||||
|
|
||||||
if (this->do_create_characteristics_())
|
if (this->do_create_characteristics_())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Starting BLE service %s", this->uuid_.to_string().c_str());
|
||||||
|
|
||||||
esp_err_t err = esp_ble_gatts_start_service(this->handle_);
|
esp_err_t err = esp_ble_gatts_start_service(this->handle_);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "esp_ble_gatts_start_service failed: %d", err);
|
ESP_LOGE(TAG, "esp_ble_gatts_start_service failed: %d", err);
|
||||||
@@ -112,12 +117,14 @@ void BLEService::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t g
|
|||||||
if (this->uuid_ == ESPBTUUID::from_uuid(param->create.service_id.id.uuid) &&
|
if (this->uuid_ == ESPBTUUID::from_uuid(param->create.service_id.id.uuid) &&
|
||||||
this->inst_id_ == param->create.service_id.id.inst_id) {
|
this->inst_id_ == param->create.service_id.id.inst_id) {
|
||||||
this->handle_ = param->create.service_handle;
|
this->handle_ = param->create.service_handle;
|
||||||
|
ESP_LOGI(TAG, "Service %s created", this->uuid_.to_string().c_str());
|
||||||
this->init_state_ = CREATED;
|
this->init_state_ = CREATED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ESP_GATTS_START_EVT: {
|
case ESP_GATTS_START_EVT: {
|
||||||
if (param->start.service_handle == this->handle_) {
|
if (param->start.service_handle == this->handle_) {
|
||||||
|
ESP_LOGI(TAG, "Service %s started", this->uuid_.to_string().c_str());
|
||||||
this->running_state_ = RUNNING;
|
this->running_state_ = RUNNING;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.components import binary_sensor, output, esp32_ble_server
|
from esphome.components import binary_sensor, output, esp32_ble_server
|
||||||
from esphome.const import CONF_ID
|
from esphome.const import CONF_BLE_SERVER_ID, CONF_ID
|
||||||
|
|
||||||
|
|
||||||
AUTO_LOAD = ["binary_sensor", "output", "esp32_ble_server"]
|
AUTO_LOAD = ["binary_sensor", "output", "esp32_ble_server"]
|
||||||
@@ -11,7 +11,6 @@ DEPENDENCIES = ["wifi", "esp32"]
|
|||||||
|
|
||||||
CONF_AUTHORIZED_DURATION = "authorized_duration"
|
CONF_AUTHORIZED_DURATION = "authorized_duration"
|
||||||
CONF_AUTHORIZER = "authorizer"
|
CONF_AUTHORIZER = "authorizer"
|
||||||
CONF_BLE_SERVER_ID = "ble_server_id"
|
|
||||||
CONF_IDENTIFY_DURATION = "identify_duration"
|
CONF_IDENTIFY_DURATION = "identify_duration"
|
||||||
CONF_STATUS_INDICATOR = "status_indicator"
|
CONF_STATUS_INDICATOR = "status_indicator"
|
||||||
CONF_WIFI_TIMEOUT = "wifi_timeout"
|
CONF_WIFI_TIMEOUT = "wifi_timeout"
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ async def to_code(config):
|
|||||||
def copy_files():
|
def copy_files():
|
||||||
|
|
||||||
dir = os.path.dirname(__file__)
|
dir = os.path.dirname(__file__)
|
||||||
post_build_file = os.path.join(dir, "post_build.py")
|
post_build_file = os.path.join(dir, "post_build.py.script")
|
||||||
copy_file_if_changed(
|
copy_file_if_changed(
|
||||||
post_build_file,
|
post_build_file,
|
||||||
CORE.relative_build_path("post_build.py"),
|
CORE.relative_build_path("post_build.py"),
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ from ..const import (
|
|||||||
CONF_FORCE_NEW_RANGE,
|
CONF_FORCE_NEW_RANGE,
|
||||||
CONF_MODBUS_CONTROLLER_ID,
|
CONF_MODBUS_CONTROLLER_ID,
|
||||||
CONF_REGISTER_TYPE,
|
CONF_REGISTER_TYPE,
|
||||||
|
CONF_SKIP_UPDATES,
|
||||||
CONF_USE_WRITE_MULTIPLE,
|
CONF_USE_WRITE_MULTIPLE,
|
||||||
CONF_WRITE_LAMBDA,
|
CONF_WRITE_LAMBDA,
|
||||||
)
|
)
|
||||||
@@ -53,6 +54,7 @@ async def to_code(config):
|
|||||||
config[CONF_ADDRESS],
|
config[CONF_ADDRESS],
|
||||||
byte_offset,
|
byte_offset,
|
||||||
config[CONF_BITMASK],
|
config[CONF_BITMASK],
|
||||||
|
config[CONF_SKIP_UPDATES],
|
||||||
config[CONF_FORCE_NEW_RANGE],
|
config[CONF_FORCE_NEW_RANGE],
|
||||||
)
|
)
|
||||||
await cg.register_component(var, config)
|
await cg.register_component(var, config)
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ namespace modbus_controller {
|
|||||||
class ModbusSwitch : public Component, public switch_::Switch, public SensorItem {
|
class ModbusSwitch : public Component, public switch_::Switch, public SensorItem {
|
||||||
public:
|
public:
|
||||||
ModbusSwitch(ModbusRegisterType register_type, uint16_t start_address, uint8_t offset, uint32_t bitmask,
|
ModbusSwitch(ModbusRegisterType register_type, uint16_t start_address, uint8_t offset, uint32_t bitmask,
|
||||||
bool force_new_range)
|
uint8_t skip_updates, bool force_new_range)
|
||||||
: Component(), switch_::Switch() {
|
: Component(), switch_::Switch() {
|
||||||
this->register_type = register_type;
|
this->register_type = register_type;
|
||||||
this->start_address = start_address;
|
this->start_address = start_address;
|
||||||
this->offset = offset;
|
this->offset = offset;
|
||||||
this->bitmask = bitmask;
|
this->bitmask = bitmask;
|
||||||
this->sensor_value_type = SensorValueType::BIT;
|
this->sensor_value_type = SensorValueType::BIT;
|
||||||
this->skip_updates = 0;
|
this->skip_updates = skip_updates;
|
||||||
this->register_count = 1;
|
this->register_count = 1;
|
||||||
if (register_type == ModbusRegisterType::HOLDING || register_type == ModbusRegisterType::COIL) {
|
if (register_type == ModbusRegisterType::HOLDING || register_type == ModbusRegisterType::COIL) {
|
||||||
this->start_address += offset;
|
this->start_address += offset;
|
||||||
|
|||||||
@@ -150,20 +150,28 @@ class Sensor : public EntityBase {
|
|||||||
void internal_send_state_to_frontend(float state);
|
void internal_send_state_to_frontend(float state);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Override this to set the default unit of measurement.
|
/** Override this to set the default unit of measurement.
|
||||||
ESPDEPRECATED("unit_of_measurement() is deprecated, set property during config validation instead.", "2022.01")
|
*
|
||||||
|
* @deprecated This method is deprecated, set the property during config validation instead. (2022.1)
|
||||||
|
*/
|
||||||
virtual std::string unit_of_measurement(); // NOLINT
|
virtual std::string unit_of_measurement(); // NOLINT
|
||||||
|
|
||||||
/// Override this to set the default accuracy in decimals.
|
/** Override this to set the default accuracy in decimals.
|
||||||
ESPDEPRECATED("accuracy_decimals() is deprecated, set property during config validation instead.", "2022.01")
|
*
|
||||||
|
* @deprecated This method is deprecated, set the property during config validation instead. (2022.1)
|
||||||
|
*/
|
||||||
virtual int8_t accuracy_decimals(); // NOLINT
|
virtual int8_t accuracy_decimals(); // NOLINT
|
||||||
|
|
||||||
/// Override this to set the default device class.
|
/** Override this to set the default device class.
|
||||||
ESPDEPRECATED("device_class() is deprecated, set property during config validation instead.", "2022.01")
|
*
|
||||||
|
* @deprecated This method is deprecated, set the property during config validation instead. (2022.1)
|
||||||
|
*/
|
||||||
virtual std::string device_class(); // NOLINT
|
virtual std::string device_class(); // NOLINT
|
||||||
|
|
||||||
/// Override this to set the default state class.
|
/** Override this to set the default state class.
|
||||||
ESPDEPRECATED("state_class() is deprecated, set property during config validation instead.", "2022.01")
|
*
|
||||||
|
* @deprecated This method is deprecated, set the property during config validation instead. (2022.1)
|
||||||
|
*/
|
||||||
virtual StateClass state_class(); // NOLINT
|
virtual StateClass state_class(); // NOLINT
|
||||||
|
|
||||||
uint32_t hash_base() override;
|
uint32_t hash_base() override;
|
||||||
|
|||||||
@@ -236,7 +236,18 @@ void WebServer::handle_index_request(AsyncWebServerRequest *request) {
|
|||||||
#ifdef USE_NUMBER
|
#ifdef USE_NUMBER
|
||||||
for (auto *obj : App.get_numbers())
|
for (auto *obj : App.get_numbers())
|
||||||
if (this->include_internal_ || !obj->is_internal())
|
if (this->include_internal_ || !obj->is_internal())
|
||||||
write_row(stream, obj, "number", "");
|
write_row(stream, obj, "number", "", [](AsyncResponseStream &stream, EntityBase *obj) {
|
||||||
|
number::Number *number = (number::Number *) obj;
|
||||||
|
stream.print(R"(<input type="number" min=")");
|
||||||
|
stream.print(number->traits.get_min_value());
|
||||||
|
stream.print(R"(" max=")");
|
||||||
|
stream.print(number->traits.get_max_value());
|
||||||
|
stream.print(R"(" step=")");
|
||||||
|
stream.print(number->traits.get_step());
|
||||||
|
stream.print(R"(" value=")");
|
||||||
|
stream.print(number->state);
|
||||||
|
stream.print(R"("/>)");
|
||||||
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SELECT
|
#ifdef USE_SELECT
|
||||||
@@ -652,8 +663,29 @@ void WebServer::handle_number_request(AsyncWebServerRequest *request, const UrlM
|
|||||||
for (auto *obj : App.get_numbers()) {
|
for (auto *obj : App.get_numbers()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (obj->get_object_id() != match.id)
|
||||||
continue;
|
continue;
|
||||||
std::string data = this->number_json(obj, obj->state);
|
|
||||||
request->send(200, "text/json", data.c_str());
|
if (request->method() == HTTP_GET) {
|
||||||
|
std::string data = this->number_json(obj, obj->state);
|
||||||
|
request->send(200, "text/json", data.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match.method != "set") {
|
||||||
|
request->send(404);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto call = obj->make_call();
|
||||||
|
|
||||||
|
if (request->hasParam("value")) {
|
||||||
|
String value = request->getParam("value")->value();
|
||||||
|
optional<float> value_f = parse_number<float>(value.c_str());
|
||||||
|
if (value_f.has_value())
|
||||||
|
call.set_value(*value_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->defer([call]() mutable { call.perform(); });
|
||||||
|
request->send(200);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
request->send(404);
|
request->send(404);
|
||||||
@@ -661,9 +693,8 @@ void WebServer::handle_number_request(AsyncWebServerRequest *request, const UrlM
|
|||||||
std::string WebServer::number_json(number::Number *obj, float value) {
|
std::string WebServer::number_json(number::Number *obj, float value) {
|
||||||
return json::build_json([obj, value](JsonObject root) {
|
return json::build_json([obj, value](JsonObject root) {
|
||||||
root["id"] = "number-" + obj->get_object_id();
|
root["id"] = "number-" + obj->get_object_id();
|
||||||
char buffer[64];
|
std::string state = str_sprintf("%f", value);
|
||||||
snprintf(buffer, sizeof(buffer), "%f", value);
|
root["state"] = state;
|
||||||
root["state"] = buffer;
|
|
||||||
root["value"] = value;
|
root["value"] = value;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -769,7 +800,7 @@ bool WebServer::canHandle(AsyncWebServerRequest *request) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_NUMBER
|
#ifdef USE_NUMBER
|
||||||
if (request->method() == HTTP_GET && match.domain == "number")
|
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "number")
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"""Constants used by esphome."""
|
"""Constants used by esphome."""
|
||||||
|
|
||||||
__version__ = "2022.1.0b2"
|
__version__ = "2022.2.0-dev"
|
||||||
|
|
||||||
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||||
|
|
||||||
@@ -62,6 +62,7 @@ CONF_BINARY_SENSORS = "binary_sensors"
|
|||||||
CONF_BINDKEY = "bindkey"
|
CONF_BINDKEY = "bindkey"
|
||||||
CONF_BIRTH_MESSAGE = "birth_message"
|
CONF_BIRTH_MESSAGE = "birth_message"
|
||||||
CONF_BIT_DEPTH = "bit_depth"
|
CONF_BIT_DEPTH = "bit_depth"
|
||||||
|
CONF_BLE_SERVER_ID = "ble_server_id"
|
||||||
CONF_BLUE = "blue"
|
CONF_BLUE = "blue"
|
||||||
CONF_BOARD = "board"
|
CONF_BOARD = "board"
|
||||||
CONF_BOARD_FLASH_MODE = "board_flash_mode"
|
CONF_BOARD_FLASH_MODE = "board_flash_mode"
|
||||||
|
|||||||
@@ -287,13 +287,12 @@ uint32_t random_uint32() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
float random_float() { return static_cast<float>(random_uint32()) / static_cast<float>(UINT32_MAX); }
|
float random_float() { return static_cast<float>(random_uint32()) / static_cast<float>(UINT32_MAX); }
|
||||||
void random_bytes(uint8_t *data, size_t len) {
|
bool random_bytes(uint8_t *data, size_t len) {
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
esp_fill_random(data, len);
|
esp_fill_random(data, len);
|
||||||
|
return true;
|
||||||
#elif defined(USE_ESP8266)
|
#elif defined(USE_ESP8266)
|
||||||
if (os_get_random(data, len) != 0) {
|
return os_get_random(data, len) == 0;
|
||||||
ESP_LOGE(TAG, "Failed to generate random bytes!");
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
#error "No random source available for this configuration."
|
#error "No random source available for this configuration."
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -311,7 +311,7 @@ uint32_t random_uint32();
|
|||||||
/// Return a random float between 0 and 1.
|
/// Return a random float between 0 and 1.
|
||||||
float random_float();
|
float random_float();
|
||||||
/// Generate \p len number of random bytes.
|
/// Generate \p len number of random bytes.
|
||||||
void random_bytes(uint8_t *data, size_t len);
|
bool random_bytes(uint8_t *data, size_t len);
|
||||||
|
|
||||||
///@}
|
///@}
|
||||||
|
|
||||||
|
|||||||
@@ -445,6 +445,7 @@ class DownloadBinaryRequestHandler(BaseHandler):
|
|||||||
|
|
||||||
self.set_header("Content-Type", "application/octet-stream")
|
self.set_header("Content-Type", "application/octet-stream")
|
||||||
self.set_header("Content-Disposition", f'attachment; filename="{filename}"')
|
self.set_header("Content-Disposition", f'attachment; filename="{filename}"')
|
||||||
|
self.set_header("Cache-Control", "no-cache")
|
||||||
if not Path(path).is_file():
|
if not Path(path).is_file():
|
||||||
self.send_error(404)
|
self.send_error(404)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ pyserial==3.5
|
|||||||
platformio==5.2.4 # When updating platformio, also update Dockerfile
|
platformio==5.2.4 # When updating platformio, also update Dockerfile
|
||||||
esptool==3.2
|
esptool==3.2
|
||||||
click==8.0.3
|
click==8.0.3
|
||||||
esphome-dashboard==20220113.2
|
esphome-dashboard==20220116.0
|
||||||
aioesphomeapi==10.6.0
|
aioesphomeapi==10.6.0
|
||||||
zeroconf==0.37.0
|
zeroconf==0.37.0
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,6 @@ pre-commit
|
|||||||
pytest==6.2.5
|
pytest==6.2.5
|
||||||
pytest-cov==3.0.0
|
pytest-cov==3.0.0
|
||||||
pytest-mock==3.6.1
|
pytest-mock==3.6.1
|
||||||
pytest-asyncio==0.16.0
|
pytest-asyncio==0.17.2
|
||||||
asyncmock==0.4.2
|
asyncmock==0.4.2
|
||||||
hypothesis==5.49.0
|
hypothesis==5.49.0
|
||||||
|
|||||||
Reference in New Issue
Block a user