mirror of
				https://github.com/esphome/esphome.git
				synced 2025-11-04 09:01:49 +00:00 
			
		
		
		
	Compare commits
	
		
			17 Commits
		
	
	
		
			2022.1.4
			...
			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
 | 
			
		||||
tasks:
 | 
			
		||||
- 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/esp32/* @esphome/core
 | 
			
		||||
esphome/components/esp32_ble/* @jesserockz
 | 
			
		||||
esphome/components/esp32_ble_controller/* @jesserockz
 | 
			
		||||
esphome/components/esp32_ble_server/* @jesserockz
 | 
			
		||||
esphome/components/esp32_camera_web_server/* @ayufan
 | 
			
		||||
esphome/components/esp32_can/* @Sympatron
 | 
			
		||||
 
 | 
			
		||||
@@ -4,5 +4,4 @@ include requirements.txt
 | 
			
		||||
include esphome/dashboard/templates/*.html
 | 
			
		||||
recursive-include esphome/dashboard/static *.ico *.js *.css *.woff* LICENSE
 | 
			
		||||
recursive-include esphome *.cpp *.h *.tcc
 | 
			
		||||
recursive-include esphome *.py.script
 | 
			
		||||
recursive-include esphome LICENSE.txt
 | 
			
		||||
 
 | 
			
		||||
@@ -76,8 +76,6 @@ async def to_code(config):
 | 
			
		||||
        pos = 0
 | 
			
		||||
        for frameIndex in range(frames):
 | 
			
		||||
            image.seek(frameIndex)
 | 
			
		||||
            if CONF_RESIZE in config:
 | 
			
		||||
                image.thumbnail(config[CONF_RESIZE])
 | 
			
		||||
            frame = image.convert("RGB")
 | 
			
		||||
            if CONF_RESIZE in config:
 | 
			
		||||
                frame = frame.resize([width, height])
 | 
			
		||||
 
 | 
			
		||||
@@ -14,14 +14,10 @@ CONF_BIT_RATE = "bit_rate"
 | 
			
		||||
CONF_ON_FRAME = "on_frame"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_id(config):
 | 
			
		||||
    if CONF_CAN_ID in config:
 | 
			
		||||
        id_value = config[CONF_CAN_ID]
 | 
			
		||||
        id_ext = config[CONF_USE_EXTENDED_ID]
 | 
			
		||||
        if not id_ext:
 | 
			
		||||
            if id_value > 0x7FF:
 | 
			
		||||
                raise cv.Invalid("Standard IDs must be 11 Bit (0x000-0x7ff / 0-2047)")
 | 
			
		||||
    return config
 | 
			
		||||
def validate_id(id_value, id_ext):
 | 
			
		||||
    if not id_ext:
 | 
			
		||||
        if id_value > 0x7FF:
 | 
			
		||||
            raise cv.Invalid("Standard IDs must be 11 Bit (0x000-0x7ff / 0-2047)")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_raw_data(value):
 | 
			
		||||
@@ -71,18 +67,23 @@ CANBUS_SCHEMA = cv.Schema(
 | 
			
		||||
        cv.Optional(CONF_ON_FRAME): automation.validate_automation(
 | 
			
		||||
            {
 | 
			
		||||
                cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(CanbusTrigger),
 | 
			
		||||
                cv.Required(CONF_CAN_ID): cv.int_range(min=0, max=0x1FFFFFFF),
 | 
			
		||||
                cv.GenerateID(CONF_CAN_ID): cv.int_range(min=0, max=0x1FFFFFFF),
 | 
			
		||||
                cv.Optional(CONF_USE_EXTENDED_ID, default=False): cv.boolean,
 | 
			
		||||
            },
 | 
			
		||||
            validate_id,
 | 
			
		||||
                cv.Optional(CONF_ON_FRAME): automation.validate_automation(
 | 
			
		||||
                    {
 | 
			
		||||
                        cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(CanbusTrigger),
 | 
			
		||||
                        cv.GenerateID(CONF_CAN_ID): cv.int_range(min=0, max=0x1FFFFFFF),
 | 
			
		||||
                        cv.Optional(CONF_USE_EXTENDED_ID, default=False): cv.boolean,
 | 
			
		||||
                    }
 | 
			
		||||
                ),
 | 
			
		||||
            }
 | 
			
		||||
        ),
 | 
			
		||||
    },
 | 
			
		||||
    }
 | 
			
		||||
).extend(cv.COMPONENT_SCHEMA)
 | 
			
		||||
 | 
			
		||||
CANBUS_SCHEMA.add_extra(validate_id)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def setup_canbus_core_(var, config):
 | 
			
		||||
    validate_id(config[CONF_CAN_ID], config[CONF_USE_EXTENDED_ID])
 | 
			
		||||
    await cg.register_component(var, config)
 | 
			
		||||
    cg.add(var.set_can_id([config[CONF_CAN_ID]]))
 | 
			
		||||
    cg.add(var.set_use_extended_id([config[CONF_USE_EXTENDED_ID]]))
 | 
			
		||||
@@ -91,6 +92,7 @@ async def setup_canbus_core_(var, config):
 | 
			
		||||
    for conf in config.get(CONF_ON_FRAME, []):
 | 
			
		||||
        can_id = conf[CONF_CAN_ID]
 | 
			
		||||
        ext_id = conf[CONF_USE_EXTENDED_ID]
 | 
			
		||||
        validate_id(can_id, ext_id)
 | 
			
		||||
        trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var, can_id, ext_id)
 | 
			
		||||
        await cg.register_component(trigger, conf)
 | 
			
		||||
        await automation.build_automation(
 | 
			
		||||
@@ -115,11 +117,11 @@ async def register_canbus(var, config):
 | 
			
		||||
            cv.Optional(CONF_USE_EXTENDED_ID, default=False): cv.boolean,
 | 
			
		||||
            cv.Required(CONF_DATA): cv.templatable(validate_raw_data),
 | 
			
		||||
        },
 | 
			
		||||
        validate_id,
 | 
			
		||||
        key=CONF_DATA,
 | 
			
		||||
    ),
 | 
			
		||||
)
 | 
			
		||||
async def canbus_action_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    validate_id(config[CONF_CAN_ID], config[CONF_USE_EXTENDED_ID])
 | 
			
		||||
    var = cg.new_Pvariable(action_id, template_arg)
 | 
			
		||||
    await cg.register_parented(var, config[CONF_CANBUS_ID])
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -235,7 +235,7 @@ float DallasTemperatureSensor::get_temp_c() {
 | 
			
		||||
 | 
			
		||||
  return temp / 128.0f;
 | 
			
		||||
}
 | 
			
		||||
std::string DallasTemperatureSensor::unique_id() { return "dallas-" + str_lower_case(format_hex(this->address_)); }
 | 
			
		||||
std::string DallasTemperatureSensor::unique_id() { return "dallas-" + str_upper_case(format_hex(this->address_)); }
 | 
			
		||||
 | 
			
		||||
}  // namespace dallas
 | 
			
		||||
}  // namespace esphome
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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;
 | 
			
		||||
    }
 | 
			
		||||
    case STARTING_SERVICE: {
 | 
			
		||||
      if (!this->device_information_service_->is_created()) {
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      if (this->device_information_service_->is_running()) {
 | 
			
		||||
        this->state_ = RUNNING;
 | 
			
		||||
        this->can_proceed_ = true;
 | 
			
		||||
        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();
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
 
 | 
			
		||||
@@ -72,9 +72,14 @@ bool BLEService::do_create_characteristics_() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BLEService::start() {
 | 
			
		||||
  if (this->running_state_ == RUNNING)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (this->do_create_characteristics_())
 | 
			
		||||
    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_);
 | 
			
		||||
  if (err != ESP_OK) {
 | 
			
		||||
    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) &&
 | 
			
		||||
          this->inst_id_ == param->create.service_id.id.inst_id) {
 | 
			
		||||
        this->handle_ = param->create.service_handle;
 | 
			
		||||
        ESP_LOGI(TAG, "Service %s created", this->uuid_.to_string().c_str());
 | 
			
		||||
        this->init_state_ = CREATED;
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ESP_GATTS_START_EVT: {
 | 
			
		||||
      if (param->start.service_handle == this->handle_) {
 | 
			
		||||
        ESP_LOGI(TAG, "Service %s started", this->uuid_.to_string().c_str());
 | 
			
		||||
        this->running_state_ = RUNNING;
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
import esphome.codegen as cg
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
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"]
 | 
			
		||||
@@ -11,7 +11,6 @@ DEPENDENCIES = ["wifi", "esp32"]
 | 
			
		||||
 | 
			
		||||
CONF_AUTHORIZED_DURATION = "authorized_duration"
 | 
			
		||||
CONF_AUTHORIZER = "authorizer"
 | 
			
		||||
CONF_BLE_SERVER_ID = "ble_server_id"
 | 
			
		||||
CONF_IDENTIFY_DURATION = "identify_duration"
 | 
			
		||||
CONF_STATUS_INDICATOR = "status_indicator"
 | 
			
		||||
CONF_WIFI_TIMEOUT = "wifi_timeout"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
from esphome.const import CONF_ID
 | 
			
		||||
import esphome.codegen as cg
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.core import CORE, coroutine_with_priority
 | 
			
		||||
from esphome.core import CORE
 | 
			
		||||
 | 
			
		||||
CODEOWNERS = ["@esphome/core"]
 | 
			
		||||
DEPENDENCIES = ["network"]
 | 
			
		||||
@@ -29,7 +29,6 @@ CONFIG_SCHEMA = cv.All(
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@coroutine_with_priority(55.0)
 | 
			
		||||
async def to_code(config):
 | 
			
		||||
    if CORE.using_arduino:
 | 
			
		||||
        if CORE.is_esp32:
 | 
			
		||||
 
 | 
			
		||||
@@ -57,11 +57,9 @@ void ModbusNumber::control(float value) {
 | 
			
		||||
  // Create and send the write command
 | 
			
		||||
  ModbusCommandItem write_cmd;
 | 
			
		||||
  if (this->register_count == 1 && !this->use_write_multiple_) {
 | 
			
		||||
    // since offset is in bytes and a register is 16 bits we get the start by adding offset/2
 | 
			
		||||
    write_cmd =
 | 
			
		||||
        ModbusCommandItem::create_write_single_command(parent_, this->start_address + this->offset / 2, data[0]);
 | 
			
		||||
    write_cmd = ModbusCommandItem::create_write_single_command(parent_, this->start_address + this->offset, data[0]);
 | 
			
		||||
  } else {
 | 
			
		||||
    write_cmd = ModbusCommandItem::create_write_multiple_command(parent_, this->start_address + this->offset / 2,
 | 
			
		||||
    write_cmd = ModbusCommandItem::create_write_multiple_command(parent_, this->start_address + this->offset,
 | 
			
		||||
                                                                 this->register_count, data);
 | 
			
		||||
  }
 | 
			
		||||
  // publish new value
 | 
			
		||||
 
 | 
			
		||||
@@ -104,6 +104,7 @@ async def to_code(config):
 | 
			
		||||
            )
 | 
			
		||||
            light_state = cg.new_Pvariable(conf[CONF_LIGHT_ID], "", wrapper)
 | 
			
		||||
            await cg.register_component(light_state, conf)
 | 
			
		||||
            cg.add(cg.App.register_light(light_state))
 | 
			
		||||
            segments.append(AddressableSegment(light_state, 0, 1, False))
 | 
			
		||||
 | 
			
		||||
        else:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
"""Constants used by esphome."""
 | 
			
		||||
 | 
			
		||||
__version__ = "2022.1.4"
 | 
			
		||||
__version__ = "2022.2.0-dev"
 | 
			
		||||
 | 
			
		||||
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
 | 
			
		||||
 | 
			
		||||
@@ -62,6 +62,7 @@ CONF_BINARY_SENSORS = "binary_sensors"
 | 
			
		||||
CONF_BINDKEY = "bindkey"
 | 
			
		||||
CONF_BIRTH_MESSAGE = "birth_message"
 | 
			
		||||
CONF_BIT_DEPTH = "bit_depth"
 | 
			
		||||
CONF_BLE_SERVER_ID = "ble_server_id"
 | 
			
		||||
CONF_BLUE = "blue"
 | 
			
		||||
CONF_BOARD = "board"
 | 
			
		||||
CONF_BOARD_FLASH_MODE = "board_flash_mode"
 | 
			
		||||
 
 | 
			
		||||
@@ -316,8 +316,8 @@ template<int (*fn)(int)> std::string str_ctype_transform(const std::string &str)
 | 
			
		||||
  std::transform(str.begin(), str.end(), result.begin(), [](unsigned char ch) { return fn(ch); });
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
std::string str_lower_case(const std::string &str) { return str_ctype_transform<std::tolower>(str); }
 | 
			
		||||
std::string str_upper_case(const std::string &str) { return str_ctype_transform<std::toupper>(str); }
 | 
			
		||||
std::string str_lower_case(const std::string &str) { return str_ctype_transform<std::toupper>(str); }
 | 
			
		||||
std::string str_upper_case(const std::string &str) { return str_ctype_transform<std::tolower>(str); }
 | 
			
		||||
std::string str_snake_case(const std::string &str) {
 | 
			
		||||
  std::string result;
 | 
			
		||||
  result.resize(str.length());
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,6 @@ pre-commit
 | 
			
		||||
pytest==6.2.5
 | 
			
		||||
pytest-cov==3.0.0
 | 
			
		||||
pytest-mock==3.6.1
 | 
			
		||||
pytest-asyncio==0.16.0
 | 
			
		||||
pytest-asyncio==0.17.2
 | 
			
		||||
asyncmock==0.4.2
 | 
			
		||||
hypothesis==5.49.0
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user