Merge branch 'esphome:dev' into optolink

This commit is contained in:
j0ta29 2023-08-04 11:51:03 +02:00 committed by GitHub
commit bb031decf9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
120 changed files with 1065 additions and 889 deletions

View file

@ -5,9 +5,12 @@ Checks: >-
-altera-*, -altera-*,
-android-*, -android-*,
-boost-*, -boost-*,
-bugprone-easily-swappable-parameters,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-narrowing-conversions, -bugprone-narrowing-conversions,
-bugprone-signed-char-misuse, -bugprone-signed-char-misuse,
-cert-dcl50-cpp, -cert-dcl50-cpp,
-cert-err33-c,
-cert-err58-cpp, -cert-err58-cpp,
-cert-oop57-cpp, -cert-oop57-cpp,
-cert-str34-c, -cert-str34-c,
@ -15,6 +18,7 @@ Checks: >-
-clang-analyzer-osx.*, -clang-analyzer-osx.*,
-clang-diagnostic-delete-abstract-non-virtual-dtor, -clang-diagnostic-delete-abstract-non-virtual-dtor,
-clang-diagnostic-delete-non-abstract-non-virtual-dtor, -clang-diagnostic-delete-non-abstract-non-virtual-dtor,
-clang-diagnostic-ignored-optimization-argument,
-clang-diagnostic-shadow-field, -clang-diagnostic-shadow-field,
-clang-diagnostic-unused-const-variable, -clang-diagnostic-unused-const-variable,
-clang-diagnostic-unused-parameter, -clang-diagnostic-unused-parameter,
@ -25,6 +29,7 @@ Checks: >-
-cppcoreguidelines-macro-usage, -cppcoreguidelines-macro-usage,
-cppcoreguidelines-narrowing-conversions, -cppcoreguidelines-narrowing-conversions,
-cppcoreguidelines-non-private-member-variables-in-classes, -cppcoreguidelines-non-private-member-variables-in-classes,
-cppcoreguidelines-prefer-member-initializer,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay, -cppcoreguidelines-pro-bounds-array-to-pointer-decay,
-cppcoreguidelines-pro-bounds-constant-array-index, -cppcoreguidelines-pro-bounds-constant-array-index,
-cppcoreguidelines-pro-bounds-pointer-arithmetic, -cppcoreguidelines-pro-bounds-pointer-arithmetic,
@ -36,6 +41,7 @@ Checks: >-
-cppcoreguidelines-pro-type-union-access, -cppcoreguidelines-pro-type-union-access,
-cppcoreguidelines-pro-type-vararg, -cppcoreguidelines-pro-type-vararg,
-cppcoreguidelines-special-member-functions, -cppcoreguidelines-special-member-functions,
-cppcoreguidelines-virtual-class-destructor,
-fuchsia-multiple-inheritance, -fuchsia-multiple-inheritance,
-fuchsia-overloaded-operator, -fuchsia-overloaded-operator,
-fuchsia-statically-constructed-objects, -fuchsia-statically-constructed-objects,
@ -68,6 +74,7 @@ Checks: >-
-modernize-use-nodiscard, -modernize-use-nodiscard,
-mpi-*, -mpi-*,
-objc-*, -objc-*,
-readability-container-data-pointer,
-readability-convert-member-functions-to-static, -readability-convert-member-functions-to-static,
-readability-else-after-return, -readability-else-after-return,
-readability-function-cognitive-complexity, -readability-function-cognitive-complexity,
@ -82,8 +89,6 @@ WarningsAsErrors: '*'
AnalyzeTemporaryDtors: false AnalyzeTemporaryDtors: false
FormatStyle: google FormatStyle: google
CheckOptions: CheckOptions:
- key: google-readability-braces-around-statements.ShortStatementLines
value: '1'
- key: google-readability-function-size.StatementThreshold - key: google-readability-function-size.StatementThreshold
value: '800' value: '800'
- key: google-runtime-int.TypeSuffix - key: google-runtime-int.TypeSuffix
@ -158,3 +163,9 @@ CheckOptions:
value: '' value: ''
- key: readability-qualified-auto.AddConstToQualified - key: readability-qualified-auto.AddConstToQualified
value: 0 value: 0
- key: readability-identifier-length.MinimumVariableNameLength
value: 0
- key: readability-identifier-length.MinimumParameterNameLength
value: 0
- key: readability-identifier-length.MinimumLoopCounterNameLength
value: 0

View file

@ -305,7 +305,7 @@ jobs:
key: platformio-${{ matrix.pio_cache_key }}-${{ hashFiles('platformio.ini') }} key: platformio-${{ matrix.pio_cache_key }}-${{ hashFiles('platformio.ini') }}
- name: Install clang-tidy - name: Install clang-tidy
run: sudo apt-get install clang-tidy-11 run: sudo apt-get install clang-tidy-14
- name: Register problem matchers - name: Register problem matchers
run: | run: |

View file

@ -3,7 +3,7 @@
# See https://pre-commit.com/hooks.html for more hooks # See https://pre-commit.com/hooks.html for more hooks
repos: repos:
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 23.3.0 rev: 23.7.0
hooks: hooks:
- id: black - id: black
args: args:
@ -27,7 +27,7 @@ repos:
- --branch=release - --branch=release
- --branch=beta - --branch=beta
- repo: https://github.com/asottile/pyupgrade - repo: https://github.com/asottile/pyupgrade
rev: v3.7.0 rev: v3.9.0
hooks: hooks:
- id: pyupgrade - id: pyupgrade
args: [--py39-plus] args: [--py39-plus]

View file

@ -28,6 +28,6 @@ async def to_code(config):
dir_pin = await cg.gpio_pin_expression(config[CONF_DIR_PIN]) dir_pin = await cg.gpio_pin_expression(config[CONF_DIR_PIN])
cg.add(var.set_dir_pin(dir_pin)) cg.add(var.set_dir_pin(dir_pin))
if CONF_SLEEP_PIN in config: if sleep_pin_config := config.get(CONF_SLEEP_PIN):
sleep_pin = await cg.gpio_pin_expression(config[CONF_SLEEP_PIN]) sleep_pin = await cg.gpio_pin_expression(sleep_pin_config)
cg.add(var.set_sleep_pin(sleep_pin)) cg.add(var.set_sleep_pin(sleep_pin))

View file

@ -32,8 +32,8 @@ static const int32_t SOC_ADC_RTC_MAX_BITWIDTH = 12;
#endif #endif
#endif #endif
static const int32_t ADC_MAX = (1 << SOC_ADC_RTC_MAX_BITWIDTH) - 1; // 4095 (12 bit) or 8191 (13 bit) static const int ADC_MAX = (1 << SOC_ADC_RTC_MAX_BITWIDTH) - 1; // 4095 (12 bit) or 8191 (13 bit)
static const int32_t ADC_HALF = (1 << SOC_ADC_RTC_MAX_BITWIDTH) >> 1; // 2048 (12 bit) or 4096 (13 bit) static const int ADC_HALF = (1 << SOC_ADC_RTC_MAX_BITWIDTH) >> 1; // 2048 (12 bit) or 4096 (13 bit)
#endif #endif
#ifdef USE_RP2040 #ifdef USE_RP2040
@ -59,7 +59,7 @@ extern "C"
} }
// load characteristics for each attenuation // load characteristics for each attenuation
for (int32_t i = 0; i < (int32_t) ADC_ATTEN_MAX; i++) { for (int32_t i = 0; i <= ADC_ATTEN_DB_11; i++) {
auto adc_unit = channel1_ != ADC1_CHANNEL_MAX ? ADC_UNIT_1 : ADC_UNIT_2; auto adc_unit = channel1_ != ADC1_CHANNEL_MAX ? ADC_UNIT_1 : ADC_UNIT_2;
auto cal_value = esp_adc_cal_characterize(adc_unit, (adc_atten_t) i, ADC_WIDTH_MAX_SOC_BITS, auto cal_value = esp_adc_cal_characterize(adc_unit, (adc_atten_t) i, ADC_WIDTH_MAX_SOC_BITS,
1100, // default vref 1100, // default vref
@ -157,7 +157,7 @@ float ADCSensor::sample() {
#ifdef USE_ESP32 #ifdef USE_ESP32
float ADCSensor::sample() { float ADCSensor::sample() {
if (!autorange_) { if (!autorange_) {
int32_t raw = -1; int raw = -1;
if (channel1_ != ADC1_CHANNEL_MAX) { if (channel1_ != ADC1_CHANNEL_MAX) {
raw = adc1_get_raw(channel1_); raw = adc1_get_raw(channel1_);
} else if (channel2_ != ADC2_CHANNEL_MAX) { } else if (channel2_ != ADC2_CHANNEL_MAX) {
@ -174,7 +174,7 @@ float ADCSensor::sample() {
return mv / 1000.0f; return mv / 1000.0f;
} }
int32_t raw11 = ADC_MAX, raw6 = ADC_MAX, raw2 = ADC_MAX, raw0 = ADC_MAX; int raw11 = ADC_MAX, raw6 = ADC_MAX, raw2 = ADC_MAX, raw0 = ADC_MAX;
if (channel1_ != ADC1_CHANNEL_MAX) { if (channel1_ != ADC1_CHANNEL_MAX) {
adc1_config_channel_atten(channel1_, ADC_ATTEN_DB_11); adc1_config_channel_atten(channel1_, ADC_ATTEN_DB_11);

View file

@ -62,7 +62,7 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
adc1_channel_t channel1_{ADC1_CHANNEL_MAX}; adc1_channel_t channel1_{ADC1_CHANNEL_MAX};
adc2_channel_t channel2_{ADC2_CHANNEL_MAX}; adc2_channel_t channel2_{ADC2_CHANNEL_MAX};
bool autorange_{false}; bool autorange_{false};
esp_adc_cal_characteristics_t cal_characteristics_[(int32_t) ADC_ATTEN_MAX] = {}; esp_adc_cal_characteristics_t cal_characteristics_[ADC_ATTEN_MAX] = {};
#endif #endif
}; };

View file

@ -89,14 +89,14 @@ async def to_code(config):
pin = await cg.gpio_pin_expression(config[CONF_PIN]) pin = await cg.gpio_pin_expression(config[CONF_PIN])
cg.add(var.set_pin(pin)) cg.add(var.set_pin(pin))
if CONF_RAW in config: if raw := config.get(CONF_RAW):
cg.add(var.set_output_raw(config[CONF_RAW])) cg.add(var.set_output_raw(raw))
if CONF_ATTENUATION in config: if attenuation := config.get(CONF_ATTENUATION):
if config[CONF_ATTENUATION] == "auto": if attenuation == "auto":
cg.add(var.set_autorange(cg.global_ns.true)) cg.add(var.set_autorange(cg.global_ns.true))
else: else:
cg.add(var.set_attenuation(config[CONF_ATTENUATION])) cg.add(var.set_attenuation(attenuation))
if CORE.is_esp32: if CORE.is_esp32:
variant = get_esp32_variant() variant = get_esp32_variant()

View file

@ -48,16 +48,16 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await display.register_display(var, config) await display.register_display(var, config)
if CONF_PIXEL_MAPPER in config: if pixel_mapper := config.get(CONF_PIXEL_MAPPER):
pixel_mapper_template_ = await cg.process_lambda( pixel_mapper_template_ = await cg.process_lambda(
config[CONF_PIXEL_MAPPER], pixel_mapper,
[(int, "x"), (int, "y")], [(int, "x"), (int, "y")],
return_type=cg.int_, return_type=cg.int_,
) )
cg.add(var.set_pixel_mapper(pixel_mapper_template_)) cg.add(var.set_pixel_mapper(pixel_mapper_template_))
if CONF_LAMBDA in config: if lambda_config := config.get(CONF_LAMBDA):
lambda_ = await cg.process_lambda( lambda_ = await cg.process_lambda(
config[CONF_LAMBDA], [(display.DisplayRef, "it")], return_type=cg.void lambda_config, [(display.DisplayRef, "it")], return_type=cg.void
) )
cg.add(var.set_writer(lambda_)) cg.add(var.set_writer(lambda_))

View file

@ -72,8 +72,8 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await i2c.register_i2c_device(var, config) await i2c.register_i2c_device(var, config)
if CONF_IRQ_PIN in config: if irq_pin_config := config.get(CONF_IRQ_PIN):
irq_pin = await cg.gpio_pin_expression(config[CONF_IRQ_PIN]) irq_pin = await cg.gpio_pin_expression(irq_pin_config)
cg.add(var.set_irq_pin(irq_pin)) cg.add(var.set_irq_pin(irq_pin))
for key in [ for key in [

View file

@ -45,10 +45,10 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await i2c.register_i2c_device(var, config) await i2c.register_i2c_device(var, config)
if CONF_TEMPERATURE in config: if temperature := config.get(CONF_TEMPERATURE):
sens = await sensor.new_sensor(config[CONF_TEMPERATURE]) sens = await sensor.new_sensor(temperature)
cg.add(var.set_temperature_sensor(sens)) cg.add(var.set_temperature_sensor(sens))
if CONF_HUMIDITY in config: if humidity := config.get(CONF_HUMIDITY):
sens = await sensor.new_sensor(config[CONF_HUMIDITY]) sens = await sensor.new_sensor(humidity)
cg.add(var.set_humidity_sensor(sens)) cg.add(var.set_humidity_sensor(sens))

View file

@ -1,5 +1,6 @@
#include "airthings_listener.h" #include "airthings_listener.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include <cinttypes>
#ifdef USE_ESP32 #ifdef USE_ESP32
@ -19,7 +20,7 @@ bool AirthingsListener::parse_device(const esp32_ble_tracker::ESPBTDevice &devic
sn |= ((uint32_t) it.data[2] << 16); sn |= ((uint32_t) it.data[2] << 16);
sn |= ((uint32_t) it.data[3] << 24); sn |= ((uint32_t) it.data[3] << 24);
ESP_LOGD(TAG, "Found AirThings device Serial:%u (MAC: %s)", sn, device.address_str().c_str()); ESP_LOGD(TAG, "Found AirThings device Serial:%" PRIu32 " (MAC: %s)", sn, device.address_str().c_str());
return true; return true;
} }
} }

View file

@ -99,8 +99,8 @@ async def register_alarm_control_panel(var, config):
async def alarm_action_arm_away_to_code(config, action_id, template_arg, args): async def alarm_action_arm_away_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID]) paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren) var = cg.new_Pvariable(action_id, template_arg, paren)
if CONF_CODE in config: if code_config := config.get(CONF_CODE):
templatable_ = await cg.templatable(config[CONF_CODE], args, cg.std_string) templatable_ = await cg.templatable(code_config, args, cg.std_string)
cg.add(var.set_code(templatable_)) cg.add(var.set_code(templatable_))
return var return var
@ -111,8 +111,8 @@ async def alarm_action_arm_away_to_code(config, action_id, template_arg, args):
async def alarm_action_arm_home_to_code(config, action_id, template_arg, args): async def alarm_action_arm_home_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID]) paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren) var = cg.new_Pvariable(action_id, template_arg, paren)
if CONF_CODE in config: if code_config := config.get(CONF_CODE):
templatable_ = await cg.templatable(config[CONF_CODE], args, cg.std_string) templatable_ = await cg.templatable(code_config, args, cg.std_string)
cg.add(var.set_code(templatable_)) cg.add(var.set_code(templatable_))
return var return var
@ -123,8 +123,8 @@ async def alarm_action_arm_home_to_code(config, action_id, template_arg, args):
async def alarm_action_disarm_to_code(config, action_id, template_arg, args): async def alarm_action_disarm_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID]) paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren) var = cg.new_Pvariable(action_id, template_arg, paren)
if CONF_CODE in config: if code_config := config.get(CONF_CODE):
templatable_ = await cg.templatable(config[CONF_CODE], args, cg.std_string) templatable_ = await cg.templatable(code_config, args, cg.std_string)
cg.add(var.set_code(templatable_)) cg.add(var.set_code(templatable_))
return var return var

View file

@ -60,26 +60,26 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await ble_client.register_ble_node(var, config) await ble_client.register_ble_node(var, config)
if CONF_FLOW in config: if flow_config := config.get(CONF_FLOW):
sens = await sensor.new_sensor(config[CONF_FLOW]) sens = await sensor.new_sensor(flow_config)
cg.add(var.set_flow_sensor(sens)) cg.add(var.set_flow_sensor(sens))
if CONF_HEAD in config: if head_config := config.get(CONF_HEAD):
sens = await sensor.new_sensor(config[CONF_HEAD]) sens = await sensor.new_sensor(head_config)
cg.add(var.set_head_sensor(sens)) cg.add(var.set_head_sensor(sens))
if CONF_POWER in config: if power_config := config.get(CONF_POWER):
sens = await sensor.new_sensor(config[CONF_POWER]) sens = await sensor.new_sensor(power_config)
cg.add(var.set_power_sensor(sens)) cg.add(var.set_power_sensor(sens))
if CONF_CURRENT in config: if current_config := config.get(CONF_CURRENT):
sens = await sensor.new_sensor(config[CONF_CURRENT]) sens = await sensor.new_sensor(current_config)
cg.add(var.set_current_sensor(sens)) cg.add(var.set_current_sensor(sens))
if CONF_SPEED in config: if speed_config := config.get(CONF_SPEED):
sens = await sensor.new_sensor(config[CONF_SPEED]) sens = await sensor.new_sensor(speed_config)
cg.add(var.set_speed_sensor(sens)) cg.add(var.set_speed_sensor(sens))
if CONF_VOLTAGE in config: if voltage_config := config.get(CONF_VOLTAGE):
sens = await sensor.new_sensor(config[CONF_VOLTAGE]) sens = await sensor.new_sensor(voltage_config)
cg.add(var.set_voltage_sensor(sens)) cg.add(var.set_voltage_sensor(sens))

View file

@ -47,10 +47,10 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await i2c.register_i2c_device(var, config) await i2c.register_i2c_device(var, config)
if CONF_TEMPERATURE in config: if temperature_config := config.get(CONF_TEMPERATURE):
sens = await sensor.new_sensor(config[CONF_TEMPERATURE]) sens = await sensor.new_sensor(temperature_config)
cg.add(var.set_temperature_sensor(sens)) cg.add(var.set_temperature_sensor(sens))
if CONF_HUMIDITY in config: if humidity_config := config.get(CONF_HUMIDITY):
sens = await sensor.new_sensor(config[CONF_HUMIDITY]) sens = await sensor.new_sensor(humidity_config)
cg.add(var.set_humidity_sensor(sens)) cg.add(var.set_humidity_sensor(sens))

View file

@ -44,10 +44,10 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await ble_client.register_ble_node(var, config) await ble_client.register_ble_node(var, config)
if CONF_BATTERY_LEVEL in config: if battery_level_config := config.get(CONF_BATTERY_LEVEL):
sens = await sensor.new_sensor(config[CONF_BATTERY_LEVEL]) sens = await sensor.new_sensor(battery_level_config)
cg.add(var.set_battery(sens)) cg.add(var.set_battery(sens))
if CONF_ILLUMINANCE in config: if illuminance_config := config.get(CONF_ILLUMINANCE):
sens = await sensor.new_sensor(config[CONF_ILLUMINANCE]) sens = await sensor.new_sensor(illuminance_config)
cg.add(var.set_illuminance(sens)) cg.add(var.set_illuminance(sens))

View file

@ -115,8 +115,8 @@ async def animation_action_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID]) paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren) var = cg.new_Pvariable(action_id, template_arg, paren)
if CONF_FRAME in config: if frame := config.get(CONF_FRAME):
template_ = await cg.templatable(config[CONF_FRAME], args, cg.uint16) template_ = await cg.templatable(frame, args, cg.uint16)
cg.add(var.set_frame(template_)) cg.add(var.set_frame(template_))
return var return var
@ -289,8 +289,8 @@ async def to_code(config):
espImage.IMAGE_TYPE[config[CONF_TYPE]], espImage.IMAGE_TYPE[config[CONF_TYPE]],
) )
cg.add(var.set_transparency(transparent)) cg.add(var.set_transparency(transparent))
if CONF_LOOP in config: if loop_config := config.get(CONF_LOOP):
start = config[CONF_LOOP][CONF_START_FRAME] start = loop_config[CONF_START_FRAME]
end = config[CONF_LOOP].get(CONF_END_FRAME, frames) end = loop_config.get(CONF_END_FRAME, frames)
count = config[CONF_LOOP].get(CONF_REPEAT, -1) count = loop_config.get(CONF_REPEAT, -1)
cg.add(var.set_loop(start, end, count)) cg.add(var.set_loop(start, end, count))

View file

@ -116,9 +116,8 @@ async def to_code(config):
cg.add(var.register_user_service(trigger)) cg.add(var.register_user_service(trigger))
await automation.build_automation(trigger, func_args, conf) await automation.build_automation(trigger, func_args, conf)
if CONF_ENCRYPTION in config: if encryption_config := config.get(CONF_ENCRYPTION):
conf = config[CONF_ENCRYPTION] decoded = base64.b64decode(encryption_config[CONF_KEY])
decoded = base64.b64decode(conf[CONF_KEY])
cg.add(var.set_noise_psk(list(decoded))) cg.add(var.set_noise_psk(list(decoded)))
cg.add_define("USE_API_NOISE") cg.add_define("USE_API_NOISE")
cg.add_library("esphome/noise-c", "0.1.4") cg.add_library("esphome/noise-c", "0.1.4")

View file

@ -31,12 +31,10 @@ CONFIG_SCHEMA = cv.Schema(
async def to_code(config): async def to_code(config):
hub = await cg.get_variable(config[CONF_AS3935_ID]) hub = await cg.get_variable(config[CONF_AS3935_ID])
if CONF_DISTANCE in config: if distance_config := config.get(CONF_DISTANCE):
conf = config[CONF_DISTANCE] sens = await sensor.new_sensor(distance_config)
distance_sensor = await sensor.new_sensor(conf) cg.add(hub.set_distance_sensor(sens))
cg.add(hub.set_distance_sensor(distance_sensor))
if CONF_LIGHTNING_ENERGY in config: if lightning_energy_config := config.get(CONF_LIGHTNING_ENERGY):
conf = config[CONF_LIGHTNING_ENERGY] sens = await sensor.new_sensor(lightning_energy_config)
lightning_energy_sensor = await sensor.new_sensor(conf) cg.add(hub.set_energy_sensor(sens))
cg.add(hub.set_energy_sensor(lightning_energy_sensor))

View file

@ -107,6 +107,6 @@ async def to_code(config):
cg.add(var.set_astep(config[CONF_ASTEP])) cg.add(var.set_astep(config[CONF_ASTEP]))
for conf_id, set_sensor_func in SENSORS.items(): for conf_id, set_sensor_func in SENSORS.items():
if conf_id in config: if sens_config := config.get(conf_id):
sens = await sensor.new_sensor(config[conf_id]) sens = await sensor.new_sensor(sens_config)
cg.add(getattr(var, set_sensor_func)(sens)) cg.add(getattr(var, set_sensor_func)(sens))

View file

@ -83,18 +83,18 @@ async def to_code(config):
cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex)) cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex))
if CONF_TEMPERATURE in config: if temperature_config := config.get(CONF_TEMPERATURE):
sens = await sensor.new_sensor(config[CONF_TEMPERATURE]) sens = await sensor.new_sensor(temperature_config)
cg.add(var.set_temperature(sens)) cg.add(var.set_temperature(sens))
if CONF_HUMIDITY in config: if humidity_config := config.get(CONF_HUMIDITY):
sens = await sensor.new_sensor(config[CONF_HUMIDITY]) sens = await sensor.new_sensor(humidity_config)
cg.add(var.set_humidity(sens)) cg.add(var.set_humidity(sens))
if CONF_BATTERY_LEVEL in config: if battery_level_config := config.get(CONF_BATTERY_LEVEL):
sens = await sensor.new_sensor(config[CONF_BATTERY_LEVEL]) sens = await sensor.new_sensor(battery_level_config)
cg.add(var.set_battery_level(sens)) cg.add(var.set_battery_level(sens))
if CONF_BATTERY_VOLTAGE in config: if battery_voltage_config := config.get(CONF_BATTERY_VOLTAGE):
sens = await sensor.new_sensor(config[CONF_BATTERY_VOLTAGE]) sens = await sensor.new_sensor(battery_voltage_config)
cg.add(var.set_battery_voltage(sens)) cg.add(var.set_battery_voltage(sens))
if CONF_SIGNAL_STRENGTH in config: if signal_strength_config := config.get(CONF_SIGNAL_STRENGTH):
sens = await sensor.new_sensor(config[CONF_SIGNAL_STRENGTH]) sens = await sensor.new_sensor(signal_strength_config)
cg.add(var.set_signal_strength(sens)) cg.add(var.set_signal_strength(sens))

View file

@ -124,29 +124,29 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await spi.register_spi_device(var, config) await spi.register_spi_device(var, config)
if CONF_VOLTAGE in config: if voltage_config := config.get(CONF_VOLTAGE):
sens = await sensor.new_sensor(config[CONF_VOLTAGE]) sens = await sensor.new_sensor(voltage_config)
cg.add(var.set_voltage_sensor(sens)) cg.add(var.set_voltage_sensor(sens))
if CONF_CURRENT in config: if current_config := config.get(CONF_CURRENT):
sens = await sensor.new_sensor(config[CONF_CURRENT]) sens = await sensor.new_sensor(current_config)
cg.add(var.set_current_sensor(sens)) cg.add(var.set_current_sensor(sens))
if CONF_POWER in config: if power_config := config.get(CONF_POWER):
sens = await sensor.new_sensor(config[CONF_POWER]) sens = await sensor.new_sensor(power_config)
cg.add(var.set_power_sensor(sens)) cg.add(var.set_power_sensor(sens))
if CONF_REACTIVE_POWER in config: if reactive_power_config := config.get(CONF_REACTIVE_POWER):
sens = await sensor.new_sensor(config[CONF_REACTIVE_POWER]) sens = await sensor.new_sensor(reactive_power_config)
cg.add(var.set_reactive_power_sensor(sens)) cg.add(var.set_reactive_power_sensor(sens))
if CONF_POWER_FACTOR in config: if power_factor_config := config.get(CONF_POWER_FACTOR):
sens = await sensor.new_sensor(config[CONF_POWER_FACTOR]) sens = await sensor.new_sensor(power_factor_config)
cg.add(var.set_power_factor_sensor(sens)) cg.add(var.set_power_factor_sensor(sens))
if CONF_FORWARD_ACTIVE_ENERGY in config: if forward_active_energy_config := config.get(CONF_FORWARD_ACTIVE_ENERGY):
sens = await sensor.new_sensor(config[CONF_FORWARD_ACTIVE_ENERGY]) sens = await sensor.new_sensor(forward_active_energy_config)
cg.add(var.set_forward_active_energy_sensor(sens)) cg.add(var.set_forward_active_energy_sensor(sens))
if CONF_REVERSE_ACTIVE_ENERGY in config: if reverse_active_energy_config := config.get(CONF_REVERSE_ACTIVE_ENERGY):
sens = await sensor.new_sensor(config[CONF_REVERSE_ACTIVE_ENERGY]) sens = await sensor.new_sensor(reverse_active_energy_config)
cg.add(var.set_reverse_active_energy_sensor(sens)) cg.add(var.set_reverse_active_energy_sensor(sens))
if CONF_FREQUENCY in config: if frequency_config := config.get(CONF_FREQUENCY):
sens = await sensor.new_sensor(config[CONF_FREQUENCY]) sens = await sensor.new_sensor(frequency_config)
cg.add(var.set_freq_sensor(sens)) cg.add(var.set_freq_sensor(sens))
cg.add(var.set_line_freq(config[CONF_LINE_FREQUENCY])) cg.add(var.set_line_freq(config[CONF_LINE_FREQUENCY]))
cg.add(var.set_meter_constant(config[CONF_METER_CONSTANT])) cg.add(var.set_meter_constant(config[CONF_METER_CONSTANT]))

View file

@ -151,33 +151,35 @@ async def to_code(config):
conf = config[phase] conf = config[phase]
cg.add(var.set_volt_gain(i, conf[CONF_GAIN_VOLTAGE])) cg.add(var.set_volt_gain(i, conf[CONF_GAIN_VOLTAGE]))
cg.add(var.set_ct_gain(i, conf[CONF_GAIN_CT])) cg.add(var.set_ct_gain(i, conf[CONF_GAIN_CT]))
if CONF_VOLTAGE in conf: if voltage_config := conf.get(CONF_VOLTAGE):
sens = await sensor.new_sensor(conf[CONF_VOLTAGE]) sens = await sensor.new_sensor(voltage_config)
cg.add(var.set_voltage_sensor(i, sens)) cg.add(var.set_voltage_sensor(i, sens))
if CONF_CURRENT in conf: if current_config := conf.get(CONF_CURRENT):
sens = await sensor.new_sensor(conf[CONF_CURRENT]) sens = await sensor.new_sensor(current_config)
cg.add(var.set_current_sensor(i, sens)) cg.add(var.set_current_sensor(i, sens))
if CONF_POWER in conf: if power_config := conf.get(CONF_POWER):
sens = await sensor.new_sensor(conf[CONF_POWER]) sens = await sensor.new_sensor(power_config)
cg.add(var.set_power_sensor(i, sens)) cg.add(var.set_power_sensor(i, sens))
if CONF_REACTIVE_POWER in conf: if reactive_power_config := conf.get(CONF_REACTIVE_POWER):
sens = await sensor.new_sensor(conf[CONF_REACTIVE_POWER]) sens = await sensor.new_sensor(reactive_power_config)
cg.add(var.set_reactive_power_sensor(i, sens)) cg.add(var.set_reactive_power_sensor(i, sens))
if CONF_POWER_FACTOR in conf: if power_factor_config := conf.get(CONF_POWER_FACTOR):
sens = await sensor.new_sensor(conf[CONF_POWER_FACTOR]) sens = await sensor.new_sensor(power_factor_config)
cg.add(var.set_power_factor_sensor(i, sens)) cg.add(var.set_power_factor_sensor(i, sens))
if CONF_FORWARD_ACTIVE_ENERGY in conf: if forward_active_energy_config := conf.get(CONF_FORWARD_ACTIVE_ENERGY):
sens = await sensor.new_sensor(conf[CONF_FORWARD_ACTIVE_ENERGY]) sens = await sensor.new_sensor(forward_active_energy_config)
cg.add(var.set_forward_active_energy_sensor(i, sens)) cg.add(var.set_forward_active_energy_sensor(i, sens))
if CONF_REVERSE_ACTIVE_ENERGY in conf: if reverse_active_energy_config := conf.get(CONF_REVERSE_ACTIVE_ENERGY):
sens = await sensor.new_sensor(conf[CONF_REVERSE_ACTIVE_ENERGY]) sens = await sensor.new_sensor(reverse_active_energy_config)
cg.add(var.set_reverse_active_energy_sensor(i, sens)) cg.add(var.set_reverse_active_energy_sensor(i, sens))
if CONF_FREQUENCY in config:
sens = await sensor.new_sensor(config[CONF_FREQUENCY]) if frequency_config := config.get(CONF_FREQUENCY):
sens = await sensor.new_sensor(frequency_config)
cg.add(var.set_freq_sensor(sens)) cg.add(var.set_freq_sensor(sens))
if CONF_CHIP_TEMPERATURE in config: if chip_temperature_config := config.get(CONF_CHIP_TEMPERATURE):
sens = await sensor.new_sensor(config[CONF_CHIP_TEMPERATURE]) sens = await sensor.new_sensor(chip_temperature_config)
cg.add(var.set_chip_temperature_sensor(sens)) cg.add(var.set_chip_temperature_sensor(sens))
cg.add(var.set_line_freq(config[CONF_LINE_FREQUENCY])) cg.add(var.set_line_freq(config[CONF_LINE_FREQUENCY]))
cg.add(var.set_current_phases(config[CONF_CURRENT_PHASES])) cg.add(var.set_current_phases(config[CONF_CURRENT_PHASES]))
cg.add(var.set_pga_gain(config[CONF_GAIN_PGA])) cg.add(var.set_pga_gain(config[CONF_GAIN_PGA]))

View file

@ -87,6 +87,6 @@ async def to_code(config):
(CONF_MOISTURE, var.set_soil_moisture), (CONF_MOISTURE, var.set_soil_moisture),
(CONF_ILLUMINANCE, var.set_illuminance), (CONF_ILLUMINANCE, var.set_illuminance),
]: ]:
if config_key in config: if sensor_config := config.get(config_key):
sens = await sensor.new_sensor(config[config_key]) sens = await sensor.new_sensor(sensor_config)
cg.add(setter(sens)) cg.add(setter(sens))

View file

@ -57,19 +57,18 @@ async def to_code(config):
var.get_idle_trigger(), [], config[CONF_IDLE_ACTION] var.get_idle_trigger(), [], config[CONF_IDLE_ACTION]
) )
if CONF_COOL_ACTION in config: if cool_action_config := config.get(CONF_COOL_ACTION):
await automation.build_automation( await automation.build_automation(
var.get_cool_trigger(), [], config[CONF_COOL_ACTION] var.get_cool_trigger(), [], cool_action_config
) )
cg.add(var.set_supports_cool(True)) cg.add(var.set_supports_cool(True))
if CONF_HEAT_ACTION in config: if heat_action_config := config.get(CONF_HEAT_ACTION):
await automation.build_automation( await automation.build_automation(
var.get_heat_trigger(), [], config[CONF_HEAT_ACTION] var.get_heat_trigger(), [], heat_action_config
) )
cg.add(var.set_supports_heat(True)) cg.add(var.set_supports_heat(True))
if CONF_AWAY_CONFIG in config: if away := config.get(CONF_AWAY_CONFIG):
away = config[CONF_AWAY_CONFIG]
away_config = BangBangClimateTargetTempConfig( away_config = BangBangClimateTargetTempConfig(
away[CONF_DEFAULT_TARGET_TEMPERATURE_LOW], away[CONF_DEFAULT_TARGET_TEMPERATURE_LOW],
away[CONF_DEFAULT_TARGET_TEMPERATURE_HIGH], away[CONF_DEFAULT_TARGET_TEMPERATURE_HIGH],

View file

@ -45,8 +45,8 @@ async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config) await cg.register_component(var, config)
await ble_client.register_ble_node(var, config) await ble_client.register_ble_node(var, config)
if CONF_TIME_ID in config: if time_id := config.get(CONF_TIME_ID):
time_ = await cg.get_variable(config[CONF_TIME_ID]) time_ = await cg.get_variable(time_id)
cg.add(var.set_time_id(time_)) cg.add(var.set_time_id(time_))
if CONF_RECEIVE_TIMEOUT in config: if receive_timeout := config.get(CONF_RECEIVE_TIMEOUT):
cg.add(var.set_status_timeout(config[CONF_RECEIVE_TIMEOUT])) cg.add(var.set_status_timeout(receive_timeout))

View file

@ -3,6 +3,7 @@
#include "bedjet_hub.h" #include "bedjet_hub.h"
#include "bedjet_child.h" #include "bedjet_child.h"
#include "bedjet_const.h" #include "bedjet_const.h"
#include <cinttypes>
namespace esphome { namespace esphome {
namespace bedjet { namespace bedjet {
@ -373,7 +374,7 @@ void BedJetHub::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t ga
if (this->last_notify_ == 0 || delta > MIN_NOTIFY_THROTTLE || this->force_refresh_) { if (this->last_notify_ == 0 || delta > MIN_NOTIFY_THROTTLE || this->force_refresh_) {
// Set reentrant flag to prevent processing multiple packets. // Set reentrant flag to prevent processing multiple packets.
this->processing_ = true; this->processing_ = true;
ESP_LOGVV(TAG, "[%s] Decoding packet: last=%d, delta=%d, force=%s", this->get_name().c_str(), ESP_LOGVV(TAG, "[%s] Decoding packet: last=%" PRId32 ", delta=%" PRId32 ", force=%s", this->get_name().c_str(),
this->last_notify_, delta, this->force_refresh_ ? "y" : "n"); this->last_notify_, delta, this->force_refresh_ ? "y" : "n");
bool needs_extra = this->codec_->decode_notify(param->notify.value, param->notify.value_len); bool needs_extra = this->codec_->decode_notify(param->notify.value, param->notify.value_len);
@ -523,11 +524,11 @@ void BedJetHub::dispatch_status_() {
ESP_LOGI(TAG, "[%s] Still waiting for first GATT notify event.", this->get_name().c_str()); ESP_LOGI(TAG, "[%s] Still waiting for first GATT notify event.", this->get_name().c_str());
} else if (diff > NOTIFY_WARN_THRESHOLD) { } else if (diff > NOTIFY_WARN_THRESHOLD) {
ESP_LOGW(TAG, "[%s] Last GATT notify was %d seconds ago.", this->get_name().c_str(), diff / 1000); ESP_LOGW(TAG, "[%s] Last GATT notify was %" PRId32 " seconds ago.", this->get_name().c_str(), diff / 1000);
} }
if (this->timeout_ > 0 && diff > this->timeout_ && this->parent()->enabled) { if (this->timeout_ > 0 && diff > this->timeout_ && this->parent()->enabled) {
ESP_LOGW(TAG, "[%s] Timed out after %d sec. Retrying...", this->get_name().c_str(), this->timeout_); ESP_LOGW(TAG, "[%s] Timed out after %" PRId32 " sec. Retrying...", this->get_name().c_str(), this->timeout_);
// set_enabled(false) will only close the connection if state != IDLE. // set_enabled(false) will only close the connection if state != IDLE.
this->parent()->set_state(espbt::ClientState::CONNECTING); this->parent()->set_state(espbt::ClientState::CONNECTING);
this->parent()->set_enabled(false); this->parent()->set_enabled(false);

View file

@ -29,10 +29,10 @@ async def to_code(config):
output_ = await cg.get_variable(config[CONF_OUTPUT]) output_ = await cg.get_variable(config[CONF_OUTPUT])
cg.add(var.set_output(output_)) cg.add(var.set_output(output_))
if CONF_OSCILLATION_OUTPUT in config: if oscillation_output_id := config.get(CONF_OSCILLATION_OUTPUT):
oscillation_output = await cg.get_variable(config[CONF_OSCILLATION_OUTPUT]) oscillation_output = await cg.get_variable(oscillation_output_id)
cg.add(var.set_oscillating(oscillation_output)) cg.add(var.set_oscillating(oscillation_output))
if CONF_DIRECTION_OUTPUT in config: if direction_output_id := config.get(CONF_DIRECTION_OUTPUT):
direction_output = await cg.get_variable(config[CONF_DIRECTION_OUTPUT]) direction_output = await cg.get_variable(direction_output_id)
cg.add(var.set_direction(direction_output)) cg.add(var.set_direction(direction_output))

View file

@ -467,14 +467,14 @@ def binary_sensor_schema(
async def setup_binary_sensor_core_(var, config): async def setup_binary_sensor_core_(var, config):
await setup_entity(var, config) await setup_entity(var, config)
if CONF_DEVICE_CLASS in config: if device_class := config.get(CONF_DEVICE_CLASS):
cg.add(var.set_device_class(config[CONF_DEVICE_CLASS])) cg.add(var.set_device_class(device_class))
if CONF_PUBLISH_INITIAL_STATE in config: if publish_initial_state := config.get(CONF_PUBLISH_INITIAL_STATE):
cg.add(var.set_publish_initial_state(config[CONF_PUBLISH_INITIAL_STATE])) cg.add(var.set_publish_initial_state(publish_initial_state))
if CONF_INVERTED in config: if inverted := config.get(CONF_INVERTED):
cg.add(var.set_inverted(config[CONF_INVERTED])) cg.add(var.set_inverted(inverted))
if CONF_FILTERS in config: if filters_config := config.get(CONF_FILTERS):
filters = await cg.build_registry_list(FILTER_REGISTRY, config[CONF_FILTERS]) filters = await cg.build_registry_list(FILTER_REGISTRY, filters_config)
cg.add(var.add_filters(filters)) cg.add(var.add_filters(filters))
for conf in config.get(CONF_ON_PRESS, []): for conf in config.get(CONF_ON_PRESS, []):
@ -518,8 +518,8 @@ async def setup_binary_sensor_core_(var, config):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(bool, "x")], conf) await automation.build_automation(trigger, [(bool, "x")], conf)
if CONF_MQTT_ID in config: if mqtt_id := config.get(CONF_MQTT_ID):
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var) mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config) await mqtt.register_mqtt_component(mqtt_, config)

View file

@ -93,35 +93,27 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await uart.register_uart_device(var, config) await uart.register_uart_device(var, config)
if CONF_VOLTAGE in config: if voltage_config := config.get(CONF_VOLTAGE):
conf = config[CONF_VOLTAGE] sens = await sensor.new_sensor(voltage_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_voltage_sensor(sens)) cg.add(var.set_voltage_sensor(sens))
if CONF_CURRENT_1 in config: if current_1_config := config.get(CONF_CURRENT_1):
conf = config[CONF_CURRENT_1] sens = await sensor.new_sensor(current_1_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_current_sensor_1(sens)) cg.add(var.set_current_sensor_1(sens))
if CONF_CURRENT_2 in config: if current_2_config := config.get(CONF_CURRENT_2):
conf = config[CONF_CURRENT_2] sens = await sensor.new_sensor(current_2_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_current_sensor_2(sens)) cg.add(var.set_current_sensor_2(sens))
if CONF_ACTIVE_POWER_1 in config: if active_power_1_config := config.get(CONF_ACTIVE_POWER_1):
conf = config[CONF_ACTIVE_POWER_1] sens = await sensor.new_sensor(active_power_1_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_power_sensor_1(sens)) cg.add(var.set_power_sensor_1(sens))
if CONF_ACTIVE_POWER_2 in config: if active_power_2_config := config.get(CONF_ACTIVE_POWER_2):
conf = config[CONF_ACTIVE_POWER_2] sens = await sensor.new_sensor(active_power_2_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_power_sensor_2(sens)) cg.add(var.set_power_sensor_2(sens))
if CONF_ENERGY_1 in config: if energy_1_config := config.get(CONF_ENERGY_1):
conf = config[CONF_ENERGY_1] sens = await sensor.new_sensor(energy_1_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_energy_sensor_1(sens)) cg.add(var.set_energy_sensor_1(sens))
if CONF_ENERGY_2 in config: if energy_2_config := config.get(CONF_ENERGY_2):
conf = config[CONF_ENERGY_2] sens = await sensor.new_sensor(energy_2_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_energy_sensor_2(sens)) cg.add(var.set_energy_sensor_2(sens))
if CONF_ENERGY_TOTAL in config: if energy_total_config := config.get(CONF_ENERGY_TOTAL):
conf = config[CONF_ENERGY_TOTAL] sens = await sensor.new_sensor(energy_total_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_energy_sensor_sum(sens)) cg.add(var.set_energy_sensor_sum(sens))

View file

@ -79,27 +79,21 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await uart.register_uart_device(var, config) await uart.register_uart_device(var, config)
if CONF_VOLTAGE in config: if voltage_config := config.get(CONF_VOLTAGE):
conf = config[CONF_VOLTAGE] sens = await sensor.new_sensor(voltage_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_voltage_sensor(sens)) cg.add(var.set_voltage_sensor(sens))
if CONF_CURRENT in config: if current_config := config.get(CONF_CURRENT):
conf = config[CONF_CURRENT] sens = await sensor.new_sensor(current_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_current_sensor(sens)) cg.add(var.set_current_sensor(sens))
if CONF_POWER in config: if power_config := config.get(CONF_POWER):
conf = config[CONF_POWER] sens = await sensor.new_sensor(power_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_power_sensor(sens)) cg.add(var.set_power_sensor(sens))
if CONF_ENERGY in config: if energy_config := config.get(CONF_ENERGY):
conf = config[CONF_ENERGY] sens = await sensor.new_sensor(energy_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_energy_sensor(sens)) cg.add(var.set_energy_sensor(sens))
if CONF_INTERNAL_TEMPERATURE in config: if internal_temperature_config := config.get(CONF_INTERNAL_TEMPERATURE):
conf = config[CONF_INTERNAL_TEMPERATURE] sens = await sensor.new_sensor(internal_temperature_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_internal_temperature_sensor(sens)) cg.add(var.set_internal_temperature_sensor(sens))
if CONF_EXTERNAL_TEMPERATURE in config: if external_temperature_config := config.get(CONF_EXTERNAL_TEMPERATURE):
conf = config[CONF_EXTERNAL_TEMPERATURE] sens = await sensor.new_sensor(external_temperature_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_external_temperature_sensor(sens)) cg.add(var.set_external_temperature_sensor(sens))

View file

@ -71,23 +71,18 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await uart.register_uart_device(var, config) await uart.register_uart_device(var, config)
if CONF_VOLTAGE in config: if voltage_config := config.get(CONF_VOLTAGE):
conf = config[CONF_VOLTAGE] sens = await sensor.new_sensor(voltage_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_voltage_sensor(sens)) cg.add(var.set_voltage_sensor(sens))
if CONF_CURRENT in config: if current_config := config.get(CONF_CURRENT):
conf = config[CONF_CURRENT] sens = await sensor.new_sensor(current_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_current_sensor(sens)) cg.add(var.set_current_sensor(sens))
if CONF_POWER in config: if power_config := config.get(CONF_POWER):
conf = config[CONF_POWER] sens = await sensor.new_sensor(power_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_power_sensor(sens)) cg.add(var.set_power_sensor(sens))
if CONF_ENERGY in config: if energy_config := config.get(CONF_ENERGY):
conf = config[CONF_ENERGY] sens = await sensor.new_sensor(energy_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_energy_sensor(sens)) cg.add(var.set_energy_sensor(sens))
if CONF_FREQUENCY in config: if frequency_config := config.get(CONF_FREQUENCY):
conf = config[CONF_FREQUENCY] sens = await sensor.new_sensor(frequency_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_frequency_sensor(sens)) cg.add(var.set_frequency_sensor(sens))

View file

@ -129,32 +129,18 @@ async def characteristic_sensor_to_code(config):
) )
cg.add(var.set_char_uuid128(uuid128)) cg.add(var.set_char_uuid128(uuid128))
if CONF_DESCRIPTOR_UUID in config: if descriptor_uuid := config.get(CONF_DESCRIPTOR_UUID):
if len(config[CONF_DESCRIPTOR_UUID]) == len(esp32_ble_tracker.bt_uuid16_format): if len(descriptor_uuid) == len(esp32_ble_tracker.bt_uuid16_format):
cg.add( cg.add(var.set_descr_uuid16(esp32_ble_tracker.as_hex(descriptor_uuid)))
var.set_descr_uuid16( elif len(descriptor_uuid) == len(esp32_ble_tracker.bt_uuid32_format):
esp32_ble_tracker.as_hex(config[CONF_DESCRIPTOR_UUID]) cg.add(var.set_descr_uuid32(esp32_ble_tracker.as_hex(descriptor_uuid)))
) elif len(descriptor_uuid) == len(esp32_ble_tracker.bt_uuid128_format):
) uuid128 = esp32_ble_tracker.as_reversed_hex_array(descriptor_uuid)
elif len(config[CONF_DESCRIPTOR_UUID]) == len(
esp32_ble_tracker.bt_uuid32_format
):
cg.add(
var.set_descr_uuid32(
esp32_ble_tracker.as_hex(config[CONF_DESCRIPTOR_UUID])
)
)
elif len(config[CONF_DESCRIPTOR_UUID]) == len(
esp32_ble_tracker.bt_uuid128_format
):
uuid128 = esp32_ble_tracker.as_reversed_hex_array(
config[CONF_DESCRIPTOR_UUID]
)
cg.add(var.set_descr_uuid128(uuid128)) cg.add(var.set_descr_uuid128(uuid128))
if CONF_LAMBDA in config: if lambda_config := config.get(CONF_LAMBDA):
lambda_ = await cg.process_lambda( lambda_ = await cg.process_lambda(
config[CONF_LAMBDA], [(adv_data_t_const_ref, "x")], return_type=cg.float_ lambda_config, [(adv_data_t_const_ref, "x")], return_type=cg.float_
) )
cg.add(var.set_data_to_value(lambda_)) cg.add(var.set_data_to_value(lambda_))

View file

@ -88,27 +88,13 @@ async def to_code(config):
) )
cg.add(var.set_char_uuid128(uuid128)) cg.add(var.set_char_uuid128(uuid128))
if CONF_DESCRIPTOR_UUID in config: if descriptor_uuid := config:
if len(config[CONF_DESCRIPTOR_UUID]) == len(esp32_ble_tracker.bt_uuid16_format): if len(descriptor_uuid) == len(esp32_ble_tracker.bt_uuid16_format):
cg.add( cg.add(var.set_descr_uuid16(esp32_ble_tracker.as_hex(descriptor_uuid)))
var.set_descr_uuid16( elif len(descriptor_uuid) == len(esp32_ble_tracker.bt_uuid32_format):
esp32_ble_tracker.as_hex(config[CONF_DESCRIPTOR_UUID]) cg.add(var.set_descr_uuid32(esp32_ble_tracker.as_hex(descriptor_uuid)))
) elif len(descriptor_uuid) == len(esp32_ble_tracker.bt_uuid128_format):
) uuid128 = esp32_ble_tracker.as_reversed_hex_array(descriptor_uuid)
elif len(config[CONF_DESCRIPTOR_UUID]) == len(
esp32_ble_tracker.bt_uuid32_format
):
cg.add(
var.set_descr_uuid32(
esp32_ble_tracker.as_hex(config[CONF_DESCRIPTOR_UUID])
)
)
elif len(config[CONF_DESCRIPTOR_UUID]) == len(
esp32_ble_tracker.bt_uuid128_format
):
uuid128 = esp32_ble_tracker.as_reversed_hex_array(
config[CONF_DESCRIPTOR_UUID]
)
cg.add(var.set_descr_uuid128(uuid128)) cg.add(var.set_descr_uuid128(uuid128))
await cg.register_component(var, config) await cg.register_component(var, config)

View file

@ -39,7 +39,7 @@ CONFIG_SCHEMA = cv.All(
cv.Optional(CONF_IBEACON_MINOR): cv.uint16_t, cv.Optional(CONF_IBEACON_MINOR): cv.uint16_t,
cv.Optional(CONF_IBEACON_UUID): cv.uuid, cv.Optional(CONF_IBEACON_UUID): cv.uuid,
cv.Optional(CONF_MIN_RSSI): cv.All( cv.Optional(CONF_MIN_RSSI): cv.All(
cv.decibel, cv.int_range(min=-90, max=-30) cv.decibel, cv.int_range(min=-100, max=-30)
), ),
} }
) )
@ -55,35 +55,27 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await esp32_ble_tracker.register_ble_device(var, config) await esp32_ble_tracker.register_ble_device(var, config)
if CONF_MIN_RSSI in config: if min_rssi := config.get(CONF_MIN_RSSI):
cg.add(var.set_minimum_rssi(config[CONF_MIN_RSSI])) cg.add(var.set_minimum_rssi(min_rssi))
if CONF_MAC_ADDRESS in config: if mac_address := config.get(CONF_MAC_ADDRESS):
cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex)) cg.add(var.set_address(mac_address.as_hex))
if CONF_SERVICE_UUID in config: if service_uuid := config.get(CONF_SERVICE_UUID):
if len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid16_format): if len(service_uuid) == len(esp32_ble_tracker.bt_uuid16_format):
cg.add( cg.add(var.set_service_uuid16(esp32_ble_tracker.as_hex(service_uuid)))
var.set_service_uuid16( elif len(service_uuid) == len(esp32_ble_tracker.bt_uuid32_format):
esp32_ble_tracker.as_hex(config[CONF_SERVICE_UUID]) cg.add(var.set_service_uuid32(esp32_ble_tracker.as_hex(service_uuid)))
) elif len(service_uuid) == len(esp32_ble_tracker.bt_uuid128_format):
) uuid128 = esp32_ble_tracker.as_reversed_hex_array(service_uuid)
elif len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid32_format):
cg.add(
var.set_service_uuid32(
esp32_ble_tracker.as_hex(config[CONF_SERVICE_UUID])
)
)
elif len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid128_format):
uuid128 = esp32_ble_tracker.as_reversed_hex_array(config[CONF_SERVICE_UUID])
cg.add(var.set_service_uuid128(uuid128)) cg.add(var.set_service_uuid128(uuid128))
if CONF_IBEACON_UUID in config: if ibeacon_uuid := config.get(CONF_IBEACON_UUID):
ibeacon_uuid = esp32_ble_tracker.as_hex_array(str(config[CONF_IBEACON_UUID])) ibeacon_uuid = esp32_ble_tracker.as_hex_array(str(ibeacon_uuid))
cg.add(var.set_ibeacon_uuid(ibeacon_uuid)) cg.add(var.set_ibeacon_uuid(ibeacon_uuid))
if CONF_IBEACON_MAJOR in config: if ibeacon_major := config.get(CONF_IBEACON_MAJOR):
cg.add(var.set_ibeacon_major(config[CONF_IBEACON_MAJOR])) cg.add(var.set_ibeacon_major(ibeacon_major))
if CONF_IBEACON_MINOR in config: if ibeacon_minor := config.get(CONF_IBEACON_MINOR):
cg.add(var.set_ibeacon_minor(config[CONF_IBEACON_MINOR])) cg.add(var.set_ibeacon_minor(ibeacon_minor))

View file

@ -51,7 +51,7 @@ class BLEPresenceDevice : public binary_sensor::BinarySensorInitiallyOff,
this->found_ = false; this->found_ = false;
} }
bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override { bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override {
if (this->check_minimum_rssi_ && this->minimum_rssi_ <= device.get_rssi()) { if (this->check_minimum_rssi_ && this->minimum_rssi_ > device.get_rssi()) {
return false; return false;
} }
switch (this->match_by_) { switch (this->match_by_) {

View file

@ -57,32 +57,24 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await esp32_ble_tracker.register_ble_device(var, config) await esp32_ble_tracker.register_ble_device(var, config)
if CONF_MAC_ADDRESS in config: if mac_address := config.get(CONF_MAC_ADDRESS):
cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex)) cg.add(var.set_address(mac_address.as_hex))
if CONF_SERVICE_UUID in config: if service_uuid := config.get(CONF_SERVICE_UUID):
if len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid16_format): if len(service_uuid) == len(esp32_ble_tracker.bt_uuid16_format):
cg.add( cg.add(var.set_service_uuid16(esp32_ble_tracker.as_hex(service_uuid)))
var.set_service_uuid16( elif len(service_uuid) == len(esp32_ble_tracker.bt_uuid32_format):
esp32_ble_tracker.as_hex(config[CONF_SERVICE_UUID]) cg.add(var.set_service_uuid32(esp32_ble_tracker.as_hex(service_uuid)))
) elif len(service_uuid) == len(esp32_ble_tracker.bt_uuid128_format):
) uuid128 = esp32_ble_tracker.as_reversed_hex_array(service_uuid)
elif len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid32_format):
cg.add(
var.set_service_uuid32(
esp32_ble_tracker.as_hex(config[CONF_SERVICE_UUID])
)
)
elif len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid128_format):
uuid128 = esp32_ble_tracker.as_reversed_hex_array(config[CONF_SERVICE_UUID])
cg.add(var.set_service_uuid128(uuid128)) cg.add(var.set_service_uuid128(uuid128))
if CONF_IBEACON_UUID in config: if ibeacon_uuid := config.get(CONF_IBEACON_UUID):
ibeacon_uuid = esp32_ble_tracker.as_hex_array(str(config[CONF_IBEACON_UUID])) ibeacon_uuid = esp32_ble_tracker.as_hex_array(str(ibeacon_uuid))
cg.add(var.set_ibeacon_uuid(ibeacon_uuid)) cg.add(var.set_ibeacon_uuid(ibeacon_uuid))
if CONF_IBEACON_MAJOR in config: if ibeacon_major := config.get(CONF_IBEACON_MAJOR):
cg.add(var.set_ibeacon_major(config[CONF_IBEACON_MAJOR])) cg.add(var.set_ibeacon_major(ibeacon_major))
if CONF_IBEACON_MINOR in config: if ibeacon_minor := config.get(CONF_IBEACON_MINOR):
cg.add(var.set_ibeacon_minor(config[CONF_IBEACON_MINOR])) cg.add(var.set_ibeacon_minor(ibeacon_minor))

View file

@ -98,22 +98,19 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await i2c.register_i2c_device(var, config) await i2c.register_i2c_device(var, config)
if CONF_TEMPERATURE in config: if temperature_config := config.get(CONF_TEMPERATURE):
conf = config[CONF_TEMPERATURE] sens = await sensor.new_sensor(temperature_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_temperature_sensor(sens)) cg.add(var.set_temperature_sensor(sens))
cg.add(var.set_temperature_oversampling(conf[CONF_OVERSAMPLING])) cg.add(var.set_temperature_oversampling(temperature_config[CONF_OVERSAMPLING]))
if CONF_PRESSURE in config: if pressure_config := config.get(CONF_PRESSURE):
conf = config[CONF_PRESSURE] sens = await sensor.new_sensor(pressure_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_pressure_sensor(sens)) cg.add(var.set_pressure_sensor(sens))
cg.add(var.set_pressure_oversampling(conf[CONF_OVERSAMPLING])) cg.add(var.set_pressure_oversampling(pressure_config[CONF_OVERSAMPLING]))
if CONF_HUMIDITY in config: if humidity_config := config.get(CONF_HUMIDITY):
conf = config[CONF_HUMIDITY] sens = await sensor.new_sensor(humidity_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_humidity_sensor(sens)) cg.add(var.set_humidity_sensor(sens))
cg.add(var.set_humidity_oversampling(conf[CONF_OVERSAMPLING])) cg.add(var.set_humidity_oversampling(humidity_config[CONF_OVERSAMPLING]))
cg.add(var.set_iir_filter(config[CONF_IIR_FILTER])) cg.add(var.set_iir_filter(config[CONF_IIR_FILTER]))

View file

@ -130,27 +130,23 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await i2c.register_i2c_device(var, config) await i2c.register_i2c_device(var, config)
if CONF_TEMPERATURE in config: if temperature_config := config.get(CONF_TEMPERATURE):
conf = config[CONF_TEMPERATURE] sens = await sensor.new_sensor(temperature_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_temperature_sensor(sens)) cg.add(var.set_temperature_sensor(sens))
cg.add(var.set_temperature_oversampling(conf[CONF_OVERSAMPLING])) cg.add(var.set_temperature_oversampling(temperature_config[CONF_OVERSAMPLING]))
if CONF_PRESSURE in config: if pressure_config := config.get(CONF_PRESSURE):
conf = config[CONF_PRESSURE] sens = await sensor.new_sensor(pressure_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_pressure_sensor(sens)) cg.add(var.set_pressure_sensor(sens))
cg.add(var.set_pressure_oversampling(conf[CONF_OVERSAMPLING])) cg.add(var.set_pressure_oversampling(pressure_config[CONF_OVERSAMPLING]))
if CONF_HUMIDITY in config: if humidity_config := config.get(CONF_HUMIDITY):
conf = config[CONF_HUMIDITY] sens = await sensor.new_sensor(humidity_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_humidity_sensor(sens)) cg.add(var.set_humidity_sensor(sens))
cg.add(var.set_humidity_oversampling(conf[CONF_OVERSAMPLING])) cg.add(var.set_humidity_oversampling(humidity_config[CONF_OVERSAMPLING]))
if CONF_GAS_RESISTANCE in config: if gas_resistance_config := config.get(CONF_GAS_RESISTANCE):
conf = config[CONF_GAS_RESISTANCE] sens = await sensor.new_sensor(gas_resistance_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_gas_resistance_sensor(sens)) cg.add(var.set_gas_resistance_sensor(sens))
cg.add(var.set_iir_filter(IIR_FILTER_OPTIONS[config[CONF_IIR_FILTER]])) cg.add(var.set_iir_filter(IIR_FILTER_OPTIONS[config[CONF_IIR_FILTER]]))

View file

@ -108,12 +108,13 @@ CONFIG_SCHEMA = cv.Schema(
async def setup_conf(config, key, hub): async def setup_conf(config, key, hub):
if key in config: if sensor_config := config.get(key):
conf = config[key] sens = await sensor.new_sensor(sensor_config)
sens = await sensor.new_sensor(conf)
cg.add(getattr(hub, f"set_{key}_sensor")(sens)) cg.add(getattr(hub, f"set_{key}_sensor")(sens))
if CONF_SAMPLE_RATE in conf: if CONF_SAMPLE_RATE in sensor_config:
cg.add(getattr(hub, f"set_{key}_sample_rate")(conf[CONF_SAMPLE_RATE])) cg.add(
getattr(hub, f"set_{key}_sample_rate")(sensor_config[CONF_SAMPLE_RATE])
)
async def to_code(config): async def to_code(config):

View file

@ -21,9 +21,8 @@ CONFIG_SCHEMA = cv.Schema(
async def setup_conf(config, key, hub): async def setup_conf(config, key, hub):
if key in config: if sensor_config := config.get(key):
conf = config[key] sens = await text_sensor.new_text_sensor(sensor_config)
sens = await text_sensor.new_text_sensor(conf)
cg.add(getattr(hub, f"set_{key}_text_sensor")(sens)) cg.add(getattr(hub, f"set_{key}_text_sensor")(sens))

View file

@ -47,12 +47,10 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await i2c.register_i2c_device(var, config) await i2c.register_i2c_device(var, config)
if CONF_TEMPERATURE in config: if temperature_config := config.get(CONF_TEMPERATURE):
conf = config[CONF_TEMPERATURE] sens = await sensor.new_sensor(temperature_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_temperature(sens)) cg.add(var.set_temperature(sens))
if CONF_PRESSURE in config: if pressure_config := config.get(CONF_PRESSURE):
conf = config[CONF_PRESSURE] sens = await sensor.new_sensor(pressure_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_pressure(sens)) cg.add(var.set_pressure(sens))

View file

@ -83,16 +83,14 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await i2c.register_i2c_device(var, config) await i2c.register_i2c_device(var, config)
if CONF_TEMPERATURE in config: if temperature_config := config.get(CONF_TEMPERATURE):
conf = config[CONF_TEMPERATURE] sens = await sensor.new_sensor(temperature_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_temperature_sensor(sens)) cg.add(var.set_temperature_sensor(sens))
cg.add(var.set_temperature_oversampling(conf[CONF_OVERSAMPLING])) cg.add(var.set_temperature_oversampling(temperature_config[CONF_OVERSAMPLING]))
if CONF_PRESSURE in config: if pressure_config := config.get(CONF_PRESSURE):
conf = config[CONF_PRESSURE] sens = await sensor.new_sensor(pressure_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_pressure_sensor(sens)) cg.add(var.set_pressure_sensor(sens))
cg.add(var.set_pressure_oversampling(conf[CONF_OVERSAMPLING])) cg.add(var.set_pressure_oversampling(pressure_config[CONF_OVERSAMPLING]))
cg.add(var.set_iir_filter(config[CONF_IIR_FILTER])) cg.add(var.set_iir_filter(config[CONF_IIR_FILTER]))

View file

@ -87,14 +87,16 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await i2c.register_i2c_device(var, config) await i2c.register_i2c_device(var, config)
cg.add(var.set_iir_filter_config(config[CONF_IIR_FILTER])) cg.add(var.set_iir_filter_config(config[CONF_IIR_FILTER]))
if CONF_TEMPERATURE in config: if temperature_config := config.get(CONF_TEMPERATURE):
conf = config[CONF_TEMPERATURE] sens = await sensor.new_sensor(temperature_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_temperature_sensor(sens)) cg.add(var.set_temperature_sensor(sens))
cg.add(var.set_temperature_oversampling_config(conf[CONF_OVERSAMPLING])) cg.add(
var.set_temperature_oversampling_config(
temperature_config[CONF_OVERSAMPLING]
)
)
if CONF_PRESSURE in config: if pressure_config := config.get(CONF_PRESSURE):
conf = config[CONF_PRESSURE] sens = await sensor.new_sensor(pressure_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_pressure_sensor(sens)) cg.add(var.set_pressure_sensor(sens))
cg.add(var.set_pressure_oversampling_config(conf[CONF_OVERSAMPLING])) cg.add(var.set_pressure_oversampling_config(pressure_config[CONF_OVERSAMPLING]))

View file

@ -85,11 +85,11 @@ async def setup_button_core_(var, config):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], conf) await automation.build_automation(trigger, [], conf)
if CONF_DEVICE_CLASS in config: if device_class := config.get(CONF_DEVICE_CLASS):
cg.add(var.set_device_class(config[CONF_DEVICE_CLASS])) cg.add(var.set_device_class(device_class))
if CONF_MQTT_ID in config: if mqtt_id := config.get(CONF_MQTT_ID):
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var) mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config) await mqtt.register_mqtt_component(mqtt_, config)

View file

@ -17,11 +17,10 @@ CONF_ON_FRAME = "on_frame"
def validate_id(config): def validate_id(config):
if CONF_CAN_ID in config: if can_id := config.get(CONF_CAN_ID):
id_value = config[CONF_CAN_ID]
id_ext = config[CONF_USE_EXTENDED_ID] id_ext = config[CONF_USE_EXTENDED_ID]
if not id_ext: if not id_ext:
if id_value > 0x7FF: if can_id > 0x7FF:
raise cv.Invalid("Standard IDs must be 11 Bit (0x000-0x7ff / 0-2047)") raise cv.Invalid("Standard IDs must be 11 Bit (0x000-0x7ff / 0-2047)")
return config return config
@ -145,8 +144,8 @@ async def canbus_action_to_code(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg) var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_CANBUS_ID]) await cg.register_parented(var, config[CONF_CANBUS_ID])
if CONF_CAN_ID in config: if can_id := config.get(CONF_CAN_ID):
can_id = await cg.templatable(config[CONF_CAN_ID], args, cg.uint32) can_id = await cg.templatable(can_id, args, cg.uint32)
cg.add(var.set_can_id(can_id)) cg.add(var.set_can_id(can_id))
use_extended_id = await cg.templatable( use_extended_id = await cg.templatable(
config[CONF_USE_EXTENDED_ID], args, cg.uint32 config[CONF_USE_EXTENDED_ID], args, cg.uint32

View file

@ -37,8 +37,8 @@ async def to_code(config):
cg.add(var.set_touch_threshold(config[CONF_TOUCH_THRESHOLD])) cg.add(var.set_touch_threshold(config[CONF_TOUCH_THRESHOLD]))
cg.add(var.set_allow_multiple_touches(config[CONF_ALLOW_MULTIPLE_TOUCHES])) cg.add(var.set_allow_multiple_touches(config[CONF_ALLOW_MULTIPLE_TOUCHES]))
if CONF_RESET_PIN in config: if reset_pin_config := config.get(CONF_RESET_PIN):
pin = await cg.gpio_pin_expression(config[CONF_RESET_PIN]) pin = await cg.gpio_pin_expression(reset_pin_config)
cg.add(var.set_reset_pin(pin)) cg.add(var.set_reset_pin(pin))
await cg.register_component(var, config) await cg.register_component(var, config)

View file

@ -69,16 +69,16 @@ async def to_code(config):
sens = await sensor.new_sensor(config[CONF_TVOC]) sens = await sensor.new_sensor(config[CONF_TVOC])
cg.add(var.set_tvoc(sens)) cg.add(var.set_tvoc(sens))
if CONF_VERSION in config: if version_config := config.get(CONF_VERSION):
sens = await text_sensor.new_text_sensor(config[CONF_VERSION]) sens = await text_sensor.new_text_sensor(version_config)
cg.add(var.set_version(sens)) cg.add(var.set_version(sens))
if CONF_BASELINE in config: if baseline := config.get(CONF_BASELINE):
cg.add(var.set_baseline(config[CONF_BASELINE])) cg.add(var.set_baseline(baseline))
if CONF_TEMPERATURE in config: if temperature_id := config.get(CONF_TEMPERATURE):
sens = await cg.get_variable(config[CONF_TEMPERATURE]) sens = await cg.get_variable(temperature_id)
cg.add(var.set_temperature(sens)) cg.add(var.set_temperature(sens))
if CONF_HUMIDITY in config: if humidity_id := config.get(CONF_HUMIDITY):
sens = await cg.get_variable(config[CONF_HUMIDITY]) sens = await cg.get_variable(humidity_id)
cg.add(var.set_humidity(sens)) cg.add(var.set_humidity(sens))

View file

@ -127,8 +127,12 @@ def single_visual_temperature(value):
# Actions # Actions
ControlAction = climate_ns.class_("ControlAction", automation.Action) ControlAction = climate_ns.class_("ControlAction", automation.Action)
StateTrigger = climate_ns.class_("StateTrigger", automation.Trigger.template()) StateTrigger = climate_ns.class_(
ControlTrigger = climate_ns.class_("ControlTrigger", automation.Trigger.template()) "StateTrigger", automation.Trigger.template(Climate.operator("ref"))
)
ControlTrigger = climate_ns.class_(
"ControlTrigger", automation.Trigger.template(ClimateCall.operator("ref"))
)
VISUAL_TEMPERATURE_STEP_SCHEMA = cv.Any( VISUAL_TEMPERATURE_STEP_SCHEMA = cv.Any(
single_visual_temperature, single_visual_temperature,
@ -322,11 +326,15 @@ async def setup_climate_core_(var, config):
for conf in config.get(CONF_ON_STATE, []): for conf in config.get(CONF_ON_STATE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], conf) await automation.build_automation(
trigger, [(Climate.operator("ref"), "x")], conf
)
for conf in config.get(CONF_ON_CONTROL, []): for conf in config.get(CONF_ON_CONTROL, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], conf) await automation.build_automation(
trigger, [(ClimateCall.operator("ref"), "x")], conf
)
async def register_climate(var, config): async def register_climate(var, config):

View file

@ -42,17 +42,17 @@ template<typename... Ts> class ControlAction : public Action<Ts...> {
Climate *climate_; Climate *climate_;
}; };
class ControlTrigger : public Trigger<> { class ControlTrigger : public Trigger<ClimateCall &> {
public: public:
ControlTrigger(Climate *climate) { ControlTrigger(Climate *climate) {
climate->add_on_control_callback([this]() { this->trigger(); }); climate->add_on_control_callback([this](ClimateCall &x) { this->trigger(x); });
} }
}; };
class StateTrigger : public Trigger<> { class StateTrigger : public Trigger<Climate &> {
public: public:
StateTrigger(Climate *climate) { StateTrigger(Climate *climate) {
climate->add_on_state_callback([this]() { this->trigger(); }); climate->add_on_state_callback([this](Climate &x) { this->trigger(x); });
} }
}; };

View file

@ -7,6 +7,7 @@ namespace climate {
static const char *const TAG = "climate"; static const char *const TAG = "climate";
void ClimateCall::perform() { void ClimateCall::perform() {
this->parent_->control_callback_.call(*this);
ESP_LOGD(TAG, "'%s' - Setting", this->parent_->get_name().c_str()); ESP_LOGD(TAG, "'%s' - Setting", this->parent_->get_name().c_str());
this->validate_(); this->validate_();
if (this->mode_.has_value()) { if (this->mode_.has_value()) {
@ -44,7 +45,6 @@ void ClimateCall::perform() {
if (this->target_temperature_high_.has_value()) { if (this->target_temperature_high_.has_value()) {
ESP_LOGD(TAG, " Target Temperature High: %.2f", *this->target_temperature_high_); ESP_LOGD(TAG, " Target Temperature High: %.2f", *this->target_temperature_high_);
} }
this->parent_->control_callback_.call();
this->parent_->control(*this); this->parent_->control(*this);
} }
void ClimateCall::validate_() { void ClimateCall::validate_() {
@ -300,11 +300,11 @@ ClimateCall &ClimateCall::set_swing_mode(optional<ClimateSwingMode> swing_mode)
return *this; return *this;
} }
void Climate::add_on_state_callback(std::function<void()> &&callback) { void Climate::add_on_state_callback(std::function<void(Climate &)> &&callback) {
this->state_callback_.add(std::move(callback)); this->state_callback_.add(std::move(callback));
} }
void Climate::add_on_control_callback(std::function<void()> &&callback) { void Climate::add_on_control_callback(std::function<void(ClimateCall &)> &&callback) {
this->control_callback_.add(std::move(callback)); this->control_callback_.add(std::move(callback));
} }
@ -408,7 +408,7 @@ void Climate::publish_state() {
} }
// Send state to frontend // Send state to frontend
this->state_callback_.call(); this->state_callback_.call(*this);
// Save state // Save state
this->save_state_(); this->save_state_();
} }

View file

@ -198,7 +198,7 @@ class Climate : public EntityBase {
* *
* @param callback The callback to call. * @param callback The callback to call.
*/ */
void add_on_state_callback(std::function<void()> &&callback); void add_on_state_callback(std::function<void(Climate &)> &&callback);
/** /**
* Add a callback for the climate device configuration; each time the configuration parameters of a climate device * Add a callback for the climate device configuration; each time the configuration parameters of a climate device
@ -206,7 +206,7 @@ class Climate : public EntityBase {
* *
* @param callback The callback to call. * @param callback The callback to call.
*/ */
void add_on_control_callback(std::function<void()> &&callback); void add_on_control_callback(std::function<void(ClimateCall &)> &&callback);
/** Make a climate device control call, this is used to control the climate device, see the ClimateCall description /** Make a climate device control call, this is used to control the climate device, see the ClimateCall description
* for more info. * for more info.
@ -273,8 +273,8 @@ class Climate : public EntityBase {
void dump_traits_(const char *tag); void dump_traits_(const char *tag);
CallbackManager<void()> state_callback_{}; CallbackManager<void(Climate &)> state_callback_{};
CallbackManager<void()> control_callback_{}; CallbackManager<void(ClimateCall &)> control_callback_{};
ESPPreferenceObject rtc_; ESPPreferenceObject rtc_;
optional<float> visual_min_temperature_override_{}; optional<float> visual_min_temperature_override_{};
optional<float> visual_max_temperature_override_{}; optional<float> visual_max_temperature_override_{};

View file

@ -44,11 +44,11 @@ async def register_climate_ir(var, config):
cg.add(var.set_supports_cool(config[CONF_SUPPORTS_COOL])) cg.add(var.set_supports_cool(config[CONF_SUPPORTS_COOL]))
cg.add(var.set_supports_heat(config[CONF_SUPPORTS_HEAT])) cg.add(var.set_supports_heat(config[CONF_SUPPORTS_HEAT]))
if CONF_SENSOR in config: if sensor_id := config.get(CONF_SENSOR):
sens = await cg.get_variable(config[CONF_SENSOR]) sens = await cg.get_variable(sensor_id)
cg.add(var.set_sensor(sens)) cg.add(var.set_sensor(sens))
if CONF_RECEIVER_ID in config: if receiver_id := config.get(CONF_RECEIVER_ID):
receiver = await cg.get_variable(config[CONF_RECEIVER_ID]) receiver = await cg.get_variable(receiver_id)
cg.add(receiver.register_listener(var)) cg.add(receiver.register_listener(var))
transmitter = await cg.get_variable(config[CONF_TRANSMITTER_ID]) transmitter = await cg.get_variable(config[CONF_TRANSMITTER_ID])

View file

@ -113,17 +113,14 @@ async def to_code(config):
cg.add(var.set_hpf_enable(config[CONF_CURRENT_HPF], config[CONF_VOLTAGE_HPF])) cg.add(var.set_hpf_enable(config[CONF_CURRENT_HPF], config[CONF_VOLTAGE_HPF]))
cg.add(var.set_pulse_energy_wh(config[CONF_PULSE_ENERGY])) cg.add(var.set_pulse_energy_wh(config[CONF_PULSE_ENERGY]))
if CONF_VOLTAGE in config: if voltage_config := config.get(CONF_VOLTAGE):
conf = config[CONF_VOLTAGE] sens = await sensor.new_sensor(voltage_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_voltage_sensor(sens)) cg.add(var.set_voltage_sensor(sens))
if CONF_CURRENT in config: if current_config := config.get(CONF_CURRENT):
conf = config[CONF_CURRENT] sens = await sensor.new_sensor(current_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_current_sensor(sens)) cg.add(var.set_current_sensor(sens))
if CONF_POWER in config: if power_config := config.get(CONF_POWER):
conf = config[CONF_POWER] sens = await sensor.new_sensor(power_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_power_sensor(sens)) cg.add(var.set_power_sensor(sens))

View file

@ -69,19 +69,15 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await uart.register_uart_device(var, config) await uart.register_uart_device(var, config)
if CONF_VOLTAGE in config: if voltage_config := config.get(CONF_VOLTAGE):
conf = config[CONF_VOLTAGE] sens = await sensor.new_sensor(voltage_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_voltage_sensor(sens)) cg.add(var.set_voltage_sensor(sens))
if CONF_CURRENT in config: if current_config := config.get(CONF_CURRENT):
conf = config[CONF_CURRENT] sens = await sensor.new_sensor(current_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_current_sensor(sens)) cg.add(var.set_current_sensor(sens))
if CONF_POWER in config: if power_config := config.get(CONF_POWER):
conf = config[CONF_POWER] sens = await sensor.new_sensor(power_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_power_sensor(sens)) cg.add(var.set_power_sensor(sens))
if CONF_ENERGY in config: if energy_config := config.get(CONF_ENERGY):
conf = config[CONF_ENERGY] sens = await sensor.new_sensor(energy_config)
sens = await sensor.new_sensor(conf)
cg.add(var.set_energy_sensor(sens)) cg.add(var.set_energy_sensor(sens))

View file

@ -66,59 +66,57 @@ CONFIG_SCHEMA = cover.COVER_SCHEMA.extend(
).extend(cv.COMPONENT_SCHEMA) ).extend(cv.COMPONENT_SCHEMA)
def to_code(config): async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])
yield cg.register_component(var, config) await cg.register_component(var, config)
yield cover.register_cover(var, config) await cover.register_cover(var, config)
yield automation.build_automation( await automation.build_automation(
var.get_stop_trigger(), [], config[CONF_STOP_ACTION] var.get_stop_trigger(), [], config[CONF_STOP_ACTION]
) )
# OPEN # OPEN
bin = yield cg.get_variable(config[CONF_OPEN_SENSOR]) bin = await cg.get_variable(config[CONF_OPEN_SENSOR])
cg.add(var.set_open_sensor(bin)) cg.add(var.set_open_sensor(bin))
cg.add( cg.add(
var.set_open_moving_current_threshold( var.set_open_moving_current_threshold(
config[CONF_OPEN_MOVING_CURRENT_THRESHOLD] config[CONF_OPEN_MOVING_CURRENT_THRESHOLD]
) )
) )
if CONF_OPEN_OBSTACLE_CURRENT_THRESHOLD in config: if open_obsticle_current_threshold := config.get(
cg.add( CONF_OPEN_OBSTACLE_CURRENT_THRESHOLD
var.set_open_obstacle_current_threshold( ):
config[CONF_OPEN_OBSTACLE_CURRENT_THRESHOLD] cg.add(var.set_open_obstacle_current_threshold(open_obsticle_current_threshold))
)
)
cg.add(var.set_open_duration(config[CONF_OPEN_DURATION])) cg.add(var.set_open_duration(config[CONF_OPEN_DURATION]))
yield automation.build_automation( await automation.build_automation(
var.get_open_trigger(), [], config[CONF_OPEN_ACTION] var.get_open_trigger(), [], config[CONF_OPEN_ACTION]
) )
# CLOSE # CLOSE
bin = yield cg.get_variable(config[CONF_CLOSE_SENSOR]) bin = await cg.get_variable(config[CONF_CLOSE_SENSOR])
cg.add(var.set_close_sensor(bin)) cg.add(var.set_close_sensor(bin))
cg.add( cg.add(
var.set_close_moving_current_threshold( var.set_close_moving_current_threshold(
config[CONF_CLOSE_MOVING_CURRENT_THRESHOLD] config[CONF_CLOSE_MOVING_CURRENT_THRESHOLD]
) )
) )
if CONF_CLOSE_OBSTACLE_CURRENT_THRESHOLD in config: if close_obsticle_current_threshold := config.get(
CONF_CLOSE_OBSTACLE_CURRENT_THRESHOLD
):
cg.add( cg.add(
var.set_close_obstacle_current_threshold( var.set_close_obstacle_current_threshold(close_obsticle_current_threshold)
config[CONF_CLOSE_OBSTACLE_CURRENT_THRESHOLD]
)
) )
cg.add(var.set_close_duration(config[CONF_CLOSE_DURATION])) cg.add(var.set_close_duration(config[CONF_CLOSE_DURATION]))
yield automation.build_automation( await automation.build_automation(
var.get_close_trigger(), [], config[CONF_CLOSE_ACTION] var.get_close_trigger(), [], config[CONF_CLOSE_ACTION]
) )
cg.add(var.set_obstacle_rollback(config[CONF_OBSTACLE_ROLLBACK])) cg.add(var.set_obstacle_rollback(config[CONF_OBSTACLE_ROLLBACK]))
if CONF_MAX_DURATION in config: if max_duration := config.get(CONF_MAX_DURATION):
cg.add(var.set_max_duration(config[CONF_MAX_DURATION])) cg.add(var.set_max_duration(max_duration))
cg.add(var.set_malfunction_detection(config[CONF_MALFUNCTION_DETECTION])) cg.add(var.set_malfunction_detection(config[CONF_MALFUNCTION_DETECTION]))
if CONF_MALFUNCTION_ACTION in config: if malfunction_action := config.get(CONF_MALFUNCTION_ACTION):
yield automation.build_automation( await automation.build_automation(
var.get_malfunction_trigger(), [], config[CONF_MALFUNCTION_ACTION] var.get_malfunction_trigger(), [], malfunction_action
) )
cg.add(var.set_start_sensing_delay(config[CONF_START_SENSING_DELAY])) cg.add(var.set_start_sensing_delay(config[CONF_START_SENSING_DELAY]))

View file

@ -37,16 +37,12 @@ async def to_code(config):
cwhite = await cg.get_variable(config[CONF_COLD_WHITE]) cwhite = await cg.get_variable(config[CONF_COLD_WHITE])
cg.add(var.set_cold_white(cwhite)) cg.add(var.set_cold_white(cwhite))
if CONF_COLD_WHITE_COLOR_TEMPERATURE in config: if cold_white_color_temperature := config.get(CONF_COLD_WHITE_COLOR_TEMPERATURE):
cg.add( cg.add(var.set_cold_white_temperature(cold_white_color_temperature))
var.set_cold_white_temperature(config[CONF_COLD_WHITE_COLOR_TEMPERATURE])
)
wwhite = await cg.get_variable(config[CONF_WARM_WHITE]) wwhite = await cg.get_variable(config[CONF_WARM_WHITE])
cg.add(var.set_warm_white(wwhite)) cg.add(var.set_warm_white(wwhite))
if CONF_WARM_WHITE_COLOR_TEMPERATURE in config: if warm_white_color_temperature := config.get(CONF_WARM_WHITE_COLOR_TEMPERATURE):
cg.add( cg.add(var.set_warm_white_temperature(warm_white_color_temperature))
var.set_warm_white_temperature(config[CONF_WARM_WHITE_COLOR_TEMPERATURE])
)
cg.add(var.set_constant_brightness(config[CONF_CONSTANT_BRIGHTNESS])) cg.add(var.set_constant_brightness(config[CONF_CONSTANT_BRIGHTNESS]))

View file

@ -6,9 +6,11 @@ namespace duty_time_sensor {
static const char *const TAG = "duty_time_sensor"; static const char *const TAG = "duty_time_sensor";
#ifdef USE_BINARY_SENSOR
void DutyTimeSensor::set_sensor(binary_sensor::BinarySensor *const sensor) { void DutyTimeSensor::set_sensor(binary_sensor::BinarySensor *const sensor) {
sensor->add_on_state_callback([this](bool state) { this->process_state_(state); }); sensor->add_on_state_callback([this](bool state) { this->process_state_(state); });
} }
#endif
void DutyTimeSensor::start() { void DutyTimeSensor::start() {
if (!this->last_state_) if (!this->last_state_)

View file

@ -3,8 +3,10 @@
#include "esphome/core/automation.h" #include "esphome/core/automation.h"
#include "esphome/core/component.h" #include "esphome/core/component.h"
#include "esphome/core/preferences.h" #include "esphome/core/preferences.h"
#include "esphome/components/binary_sensor/binary_sensor.h"
#include "esphome/components/sensor/sensor.h" #include "esphome/components/sensor/sensor.h"
#ifdef USE_BINARY_SENSOR
#include "esphome/components/binary_sensor/binary_sensor.h"
#endif
namespace esphome { namespace esphome {
namespace duty_time_sensor { namespace duty_time_sensor {
@ -22,8 +24,10 @@ class DutyTimeSensor : public sensor::Sensor, public PollingComponent {
bool is_running() const { return this->last_state_; } bool is_running() const { return this->last_state_; }
void reset() { this->set_value_(0); } void reset() { this->set_value_(0); }
void set_lambda(std::function<bool()> &&func) { this->func_ = func; } #ifdef USE_BINARY_SENSOR
void set_sensor(binary_sensor::BinarySensor *sensor); void set_sensor(binary_sensor::BinarySensor *sensor);
#endif
void set_lambda(std::function<bool()> &&func) { this->func_ = func; }
void set_last_duty_time_sensor(sensor::Sensor *sensor) { this->last_duty_time_sensor_ = sensor; } void set_last_duty_time_sensor(sensor::Sensor *sensor) { this->last_duty_time_sensor_ = sensor; }
void set_restore(bool restore) { this->restore_ = restore; } void set_restore(bool restore) { this->restore_ = restore; }
@ -43,44 +47,26 @@ class DutyTimeSensor : public sensor::Sensor, public PollingComponent {
bool restore_; bool restore_;
}; };
template<typename... Ts> class StartAction : public Action<Ts...> { template<typename... Ts> class BaseAction : public Action<Ts...>, public Parented<DutyTimeSensor> {};
public:
explicit StartAction(DutyTimeSensor *parent) : parent_(parent) {}
template<typename... Ts> class StartAction : public BaseAction<Ts...> {
void play(Ts... x) override { this->parent_->start(); } void play(Ts... x) override { this->parent_->start(); }
protected:
DutyTimeSensor *parent_;
}; };
template<typename... Ts> class StopAction : public Action<Ts...> { template<typename... Ts> class StopAction : public BaseAction<Ts...> {
public:
explicit StopAction(DutyTimeSensor *parent) : parent_(parent) {}
void play(Ts... x) override { this->parent_->stop(); } void play(Ts... x) override { this->parent_->stop(); }
protected:
DutyTimeSensor *parent_;
}; };
template<typename... Ts> class ResetAction : public Action<Ts...> { template<typename... Ts> class ResetAction : public BaseAction<Ts...> {
public:
explicit ResetAction(DutyTimeSensor *parent) : parent_(parent) {}
void play(Ts... x) override { this->parent_->reset(); } void play(Ts... x) override { this->parent_->reset(); }
protected:
DutyTimeSensor *parent_;
}; };
template<typename... Ts> class RunningCondition : public Condition<Ts...> { template<typename... Ts> class RunningCondition : public Condition<Ts...>, public Parented<DutyTimeSensor> {
public: public:
explicit RunningCondition(DutyTimeSensor *parent, bool state) : parent_(parent), state_(state) {} explicit RunningCondition(DutyTimeSensor *parent, bool state) : Parented(parent), state_(state) {}
bool check(Ts... x) override { return this->parent_->is_running() == this->state_; }
protected: protected:
DutyTimeSensor *parent_; bool check(Ts... x) override { return this->parent_->is_running() == this->state_; }
bool state_; bool state_;
}; };

View file

@ -26,11 +26,14 @@ duty_time_sensor_ns = cg.esphome_ns.namespace("duty_time_sensor")
DutyTimeSensor = duty_time_sensor_ns.class_( DutyTimeSensor = duty_time_sensor_ns.class_(
"DutyTimeSensor", sensor.Sensor, cg.PollingComponent "DutyTimeSensor", sensor.Sensor, cg.PollingComponent
) )
StartAction = duty_time_sensor_ns.class_("StartAction", Action) BaseAction = duty_time_sensor_ns.class_("BaseAction", Action, cg.Parented)
StopAction = duty_time_sensor_ns.class_("StopAction", Action) StartAction = duty_time_sensor_ns.class_("StartAction", BaseAction)
ResetAction = duty_time_sensor_ns.class_("ResetAction", Action) StopAction = duty_time_sensor_ns.class_("StopAction", BaseAction)
SetAction = duty_time_sensor_ns.class_("SetAction", Action) ResetAction = duty_time_sensor_ns.class_("ResetAction", BaseAction)
RunningCondition = duty_time_sensor_ns.class_("RunningCondition", Condition) SetAction = duty_time_sensor_ns.class_("SetAction", BaseAction)
RunningCondition = duty_time_sensor_ns.class_(
"RunningCondition", Condition, cg.Parented
)
CONFIG_SCHEMA = cv.All( CONFIG_SCHEMA = cv.All(
@ -89,20 +92,23 @@ DUTY_TIME_ID_SCHEMA = maybe_simple_id(
@register_action("sensor.duty_time.start", StartAction, DUTY_TIME_ID_SCHEMA) @register_action("sensor.duty_time.start", StartAction, DUTY_TIME_ID_SCHEMA)
async def sensor_runtime_start_to_code(config, action_id, template_arg, args): async def sensor_runtime_start_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID]) var = cg.new_Pvariable(action_id, template_arg)
return cg.new_Pvariable(action_id, template_arg, paren) await cg.register_parented(var, config[CONF_ID])
return var
@register_action("sensor.duty_time.stop", StopAction, DUTY_TIME_ID_SCHEMA) @register_action("sensor.duty_time.stop", StopAction, DUTY_TIME_ID_SCHEMA)
async def sensor_runtime_stop_to_code(config, action_id, template_arg, args): async def sensor_runtime_stop_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID]) var = cg.new_Pvariable(action_id, template_arg)
return cg.new_Pvariable(action_id, template_arg, paren) await cg.register_parented(var, config[CONF_ID])
return var
@register_action("sensor.duty_time.reset", ResetAction, DUTY_TIME_ID_SCHEMA) @register_action("sensor.duty_time.reset", ResetAction, DUTY_TIME_ID_SCHEMA)
async def sensor_runtime_reset_to_code(config, action_id, template_arg, args): async def sensor_runtime_reset_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID]) var = cg.new_Pvariable(action_id, template_arg)
return cg.new_Pvariable(action_id, template_arg, paren) await cg.register_parented(var, config[CONF_ID])
return var
@register_condition( @register_condition(

View file

@ -81,6 +81,10 @@ def get_esp32_variant(core_obj=None):
return (core_obj or CORE).data[KEY_ESP32][KEY_VARIANT] return (core_obj or CORE).data[KEY_ESP32][KEY_VARIANT]
def get_board(core_obj=None):
return (core_obj or CORE).data[KEY_ESP32][KEY_BOARD]
def only_on_variant(*, supported=None, unsupported=None): def only_on_variant(*, supported=None, unsupported=None):
"""Config validator for features only available on some ESP32 variants.""" """Config validator for features only available on some ESP32 variants."""
if supported is not None and not isinstance(supported, list): if supported is not None and not isinstance(supported, list):

View file

@ -4,6 +4,7 @@
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
#include <cinttypes>
#include "esphome/core/log.h" #include "esphome/core/log.h"
namespace esphome { namespace esphome {
@ -166,7 +167,7 @@ std::string ESPBTUUID::to_string() const {
case ESP_UUID_LEN_16: case ESP_UUID_LEN_16:
return str_snprintf("0x%02X%02X", 6, this->uuid_.uuid.uuid16 >> 8, this->uuid_.uuid.uuid16 & 0xff); return str_snprintf("0x%02X%02X", 6, this->uuid_.uuid.uuid16 >> 8, this->uuid_.uuid.uuid16 & 0xff);
case ESP_UUID_LEN_32: case ESP_UUID_LEN_32:
return str_snprintf("0x%02X%02X%02X%02X", 10, this->uuid_.uuid.uuid32 >> 24, return str_snprintf("0x%02" PRIX32 "%02" PRIX32 "%02" PRIX32 "%02" PRIX32, 10, (this->uuid_.uuid.uuid32 >> 24),
(this->uuid_.uuid.uuid32 >> 16 & 0xff), (this->uuid_.uuid.uuid32 >> 8 & 0xff), (this->uuid_.uuid.uuid32 >> 16 & 0xff), (this->uuid_.uuid.uuid32 >> 8 & 0xff),
this->uuid_.uuid.uuid32 & 0xff); this->uuid_.uuid.uuid32 & 0xff);
default: default:

View file

@ -263,6 +263,7 @@ async def to_code(config):
# Match arduino CONFIG_BTU_TASK_STACK_SIZE # Match arduino CONFIG_BTU_TASK_STACK_SIZE
# https://github.com/espressif/arduino-esp32/blob/fd72cf46ad6fc1a6de99c1d83ba8eba17d80a4ee/tools/sdk/esp32/sdkconfig#L1866 # https://github.com/espressif/arduino-esp32/blob/fd72cf46ad6fc1a6de99c1d83ba8eba17d80a4ee/tools/sdk/esp32/sdkconfig#L1866
add_idf_sdkconfig_option("CONFIG_BTU_TASK_STACK_SIZE", 8192) add_idf_sdkconfig_option("CONFIG_BTU_TASK_STACK_SIZE", 8192)
add_idf_sdkconfig_option("CONFIG_BT_ACL_CONNECTIONS", 9)
cg.add_define("USE_OTA_STATE_CALLBACK") # To be notified when an OTA update starts cg.add_define("USE_OTA_STATE_CALLBACK") # To be notified when an OTA update starts
cg.add_define("USE_ESP32_BLE_CLIENT") cg.add_define("USE_ESP32_BLE_CLIENT")

View file

@ -15,6 +15,7 @@
#include <freertos/FreeRTOSConfig.h> #include <freertos/FreeRTOSConfig.h>
#include <freertos/task.h> #include <freertos/task.h>
#include <nvs_flash.h> #include <nvs_flash.h>
#include <cinttypes>
#ifdef USE_OTA #ifdef USE_OTA
#include "esphome/components/ota/ota_component.h" #include "esphome/components/ota/ota_component.h"
@ -614,7 +615,7 @@ uint64_t ESPBTDevice::address_uint64() const { return esp32_ble::ble_addr_to_uin
void ESP32BLETracker::dump_config() { void ESP32BLETracker::dump_config() {
ESP_LOGCONFIG(TAG, "BLE Tracker:"); ESP_LOGCONFIG(TAG, "BLE Tracker:");
ESP_LOGCONFIG(TAG, " Scan Duration: %u s", this->scan_duration_); ESP_LOGCONFIG(TAG, " Scan Duration: %" PRIu32 " s", this->scan_duration_);
ESP_LOGCONFIG(TAG, " Scan Interval: %.1f ms", this->scan_interval_ * 0.625f); ESP_LOGCONFIG(TAG, " Scan Interval: %.1f ms", this->scan_interval_ * 0.625f);
ESP_LOGCONFIG(TAG, " Scan Window: %.1f ms", this->scan_window_ * 0.625f); ESP_LOGCONFIG(TAG, " Scan Window: %.1f ms", this->scan_window_ * 0.625f);
ESP_LOGCONFIG(TAG, " Scan Type: %s", this->scan_active_ ? "ACTIVE" : "PASSIVE"); ESP_LOGCONFIG(TAG, " Scan Type: %s", this->scan_active_ ? "ACTIVE" : "PASSIVE");

View file

@ -118,6 +118,10 @@ void EthernetComponent::setup() {
ESPHL_ERROR_CHECK(err, "ETH event handler register error"); ESPHL_ERROR_CHECK(err, "ETH event handler register error");
err = esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &EthernetComponent::got_ip_event_handler, nullptr); err = esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &EthernetComponent::got_ip_event_handler, nullptr);
ESPHL_ERROR_CHECK(err, "GOT IP event handler register error"); ESPHL_ERROR_CHECK(err, "GOT IP event handler register error");
#if LWIP_IPV6
err = esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &EthernetComponent::got_ip6_event_handler, nullptr);
ESPHL_ERROR_CHECK(err, "GOT IP6 event handler register error");
#endif /* LWIP_IPV6 */
/* start Ethernet driver state machine */ /* start Ethernet driver state machine */
err = esp_eth_start(this->eth_handle_); err = esp_eth_start(this->eth_handle_);
@ -160,6 +164,20 @@ void EthernetComponent::loop() {
this->state_ = EthernetComponentState::CONNECTING; this->state_ = EthernetComponentState::CONNECTING;
this->start_connect_(); this->start_connect_();
} }
#if LWIP_IPV6
else if (this->got_ipv6_) {
esp_ip6_addr_t ip6_addr;
if (esp_netif_get_ip6_global(this->eth_netif_, &ip6_addr) == 0 &&
esp_netif_ip6_get_addr_type(&ip6_addr) == ESP_IP6_ADDR_IS_GLOBAL) {
ESP_LOGCONFIG(TAG, "IPv6 Addr (Global): " IPV6STR, IPV62STR(ip6_addr));
} else {
esp_netif_get_ip6_linklocal(this->eth_netif_, &ip6_addr);
ESP_LOGCONFIG(TAG, " IPv6: " IPV6STR, IPV62STR(ip6_addr));
}
this->got_ipv6_ = false;
}
#endif /* LWIP_IPV6 */
break; break;
} }
} }
@ -254,6 +272,15 @@ void EthernetComponent::got_ip_event_handler(void *arg, esp_event_base_t event_b
ESP_LOGV(TAG, "[Ethernet event] ETH Got IP (num=%" PRId32 ")", event_id); ESP_LOGV(TAG, "[Ethernet event] ETH Got IP (num=%" PRId32 ")", event_id);
} }
#if LWIP_IPV6
void EthernetComponent::got_ip6_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id,
void *event_data) {
ESP_LOGV(TAG, "[Ethernet event] ETH Got IP6 (num=%d)", event_id);
global_eth_component->got_ipv6_ = true;
global_eth_component->ipv6_count_ += 1;
}
#endif /* LWIP_IPV6 */
void EthernetComponent::start_connect_() { void EthernetComponent::start_connect_() {
this->connect_begin_ = millis(); this->connect_begin_ = millis();
this->status_set_warning(); this->status_set_warning();
@ -316,6 +343,12 @@ void EthernetComponent::start_connect_() {
if (err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED) { if (err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED) {
ESPHL_ERROR_CHECK(err, "DHCPC start error"); ESPHL_ERROR_CHECK(err, "DHCPC start error");
} }
#if LWIP_IPV6
err = esp_netif_create_ip6_linklocal(this->eth_netif_);
if (err != ESP_OK) {
ESPHL_ERROR_CHECK(err, "IPv6 local failed");
}
#endif /* LWIP_IPV6 */
} }
this->connect_begin_ = millis(); this->connect_begin_ = millis();
@ -343,6 +376,19 @@ void EthernetComponent::dump_connect_params_() {
ESP_LOGCONFIG(TAG, " DNS2: %s", network::IPAddress(dns_ip2->addr).str().c_str()); ESP_LOGCONFIG(TAG, " DNS2: %s", network::IPAddress(dns_ip2->addr).str().c_str());
#endif #endif
#if LWIP_IPV6
if (this->ipv6_count_ > 0) {
esp_ip6_addr_t ip6_addr;
esp_netif_get_ip6_linklocal(this->eth_netif_, &ip6_addr);
ESP_LOGCONFIG(TAG, " IPv6: " IPV6STR, IPV62STR(ip6_addr));
if (esp_netif_get_ip6_global(this->eth_netif_, &ip6_addr) == 0 &&
esp_netif_ip6_get_addr_type(&ip6_addr) == ESP_IP6_ADDR_IS_GLOBAL) {
ESP_LOGCONFIG(TAG, "IPv6 Addr (Global): " IPV6STR, IPV62STR(ip6_addr));
}
}
#endif /* LWIP_IPV6 */
esp_err_t err; esp_err_t err;
uint8_t mac[6]; uint8_t mac[6];

View file

@ -65,6 +65,9 @@ class EthernetComponent : public Component {
protected: protected:
static void eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); static void eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
static void got_ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); static void got_ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
#if LWIP_IPV6
static void got_ip6_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
#endif /* LWIP_IPV6 */
void start_connect_(); void start_connect_();
void dump_connect_params_(); void dump_connect_params_();
@ -83,6 +86,10 @@ class EthernetComponent : public Component {
bool started_{false}; bool started_{false};
bool connected_{false}; bool connected_{false};
#if LWIP_IPV6
bool got_ipv6_{false};
uint8_t ipv6_count_{0};
#endif /* LWIP_IPV6 */
EthernetComponentState state_{EthernetComponentState::STOPPED}; EthernetComponentState state_{EthernetComponentState::STOPPED};
uint32_t connect_begin_; uint32_t connect_begin_;
esp_netif_t *eth_netif_{nullptr}; esp_netif_t *eth_netif_{nullptr};

View file

@ -54,18 +54,23 @@ HonClimate = haier_ns.class_("HonClimate", HaierClimateBase)
Smartair2Climate = haier_ns.class_("Smartair2Climate", HaierClimateBase) Smartair2Climate = haier_ns.class_("Smartair2Climate", HaierClimateBase)
AirflowVerticalDirection = haier_ns.enum("AirflowVerticalDirection") AirflowVerticalDirection = haier_ns.enum("AirflowVerticalDirection", True)
AIRFLOW_VERTICAL_DIRECTION_OPTIONS = { AIRFLOW_VERTICAL_DIRECTION_OPTIONS = {
"HEALTH_UP": AirflowVerticalDirection.HEALTH_UP,
"MAX_UP": AirflowVerticalDirection.MAX_UP,
"UP": AirflowVerticalDirection.UP, "UP": AirflowVerticalDirection.UP,
"CENTER": AirflowVerticalDirection.CENTER, "CENTER": AirflowVerticalDirection.CENTER,
"DOWN": AirflowVerticalDirection.DOWN, "DOWN": AirflowVerticalDirection.DOWN,
"HEALTH_DOWN": AirflowVerticalDirection.HEALTH_DOWN,
} }
AirflowHorizontalDirection = haier_ns.enum("AirflowHorizontalDirection") AirflowHorizontalDirection = haier_ns.enum("AirflowHorizontalDirection", True)
AIRFLOW_HORIZONTAL_DIRECTION_OPTIONS = { AIRFLOW_HORIZONTAL_DIRECTION_OPTIONS = {
"MAX_LEFT": AirflowHorizontalDirection.MAX_LEFT,
"LEFT": AirflowHorizontalDirection.LEFT, "LEFT": AirflowHorizontalDirection.LEFT,
"CENTER": AirflowHorizontalDirection.CENTER, "CENTER": AirflowHorizontalDirection.CENTER,
"RIGHT": AirflowHorizontalDirection.RIGHT, "RIGHT": AirflowHorizontalDirection.RIGHT,
"MAX_RIGHT": AirflowHorizontalDirection.MAX_RIGHT,
} }
SUPPORTED_SWING_MODES_OPTIONS = { SUPPORTED_SWING_MODES_OPTIONS = {

View file

@ -81,22 +81,14 @@ void HonClimate::set_outdoor_temperature_sensor(esphome::sensor::Sensor *sensor)
AirflowVerticalDirection HonClimate::get_vertical_airflow() const { return this->vertical_direction_; }; AirflowVerticalDirection HonClimate::get_vertical_airflow() const { return this->vertical_direction_; };
void HonClimate::set_vertical_airflow(AirflowVerticalDirection direction) { void HonClimate::set_vertical_airflow(AirflowVerticalDirection direction) {
if (direction > AirflowVerticalDirection::DOWN) {
this->vertical_direction_ = AirflowVerticalDirection::CENTER;
} else {
this->vertical_direction_ = direction; this->vertical_direction_ = direction;
}
this->set_force_send_control_(true); this->set_force_send_control_(true);
} }
AirflowHorizontalDirection HonClimate::get_horizontal_airflow() const { return this->horizontal_direction_; } AirflowHorizontalDirection HonClimate::get_horizontal_airflow() const { return this->horizontal_direction_; }
void HonClimate::set_horizontal_airflow(AirflowHorizontalDirection direction) { void HonClimate::set_horizontal_airflow(AirflowHorizontalDirection direction) {
if (direction > AirflowHorizontalDirection::RIGHT) {
this->horizontal_direction_ = AirflowHorizontalDirection::CENTER;
} else {
this->horizontal_direction_ = direction; this->horizontal_direction_ = direction;
}
this->set_force_send_control_(true); this->set_force_send_control_(true);
} }

View file

@ -12,7 +12,7 @@ void HomeassistantSensor::setup() {
this->entity_id_, this->attribute_, [this](const std::string &state) { this->entity_id_, this->attribute_, [this](const std::string &state) {
auto val = parse_number<float>(state); auto val = parse_number<float>(state);
if (!val.has_value()) { if (!val.has_value()) {
ESP_LOGW(TAG, "Can't convert '%s' to number!", state.c_str()); ESP_LOGW(TAG, "'%s': Can't convert '%s' to number!", this->entity_id_.c_str(), state.c_str());
this->publish_state(NAN); this->publish_state(NAN);
return; return;
} }

View file

@ -185,7 +185,7 @@ void I2SAudioSpeaker::loop() {
} }
} }
bool I2SAudioSpeaker::play(const uint8_t *data, size_t length) { size_t I2SAudioSpeaker::play(const uint8_t *data, size_t length) {
if (this->state_ != speaker::STATE_RUNNING && this->state_ != speaker::STATE_STARTING) { if (this->state_ != speaker::STATE_RUNNING && this->state_ != speaker::STATE_STARTING) {
this->start(); this->start();
} }
@ -197,13 +197,13 @@ bool I2SAudioSpeaker::play(const uint8_t *data, size_t length) {
size_t to_send_length = std::min(remaining, BUFFER_SIZE); size_t to_send_length = std::min(remaining, BUFFER_SIZE);
event.len = to_send_length; event.len = to_send_length;
memcpy(event.data, data + index, to_send_length); memcpy(event.data, data + index, to_send_length);
if (xQueueSend(this->buffer_queue_, &event, 100 / portTICK_PERIOD_MS) == pdTRUE) { if (xQueueSend(this->buffer_queue_, &event, 0) != pdTRUE) {
return index;
}
remaining -= to_send_length; remaining -= to_send_length;
index += to_send_length; index += to_send_length;
} }
App.feed_wdt(); return index;
}
return true;
} }
} // namespace i2s_audio } // namespace i2s_audio

View file

@ -54,7 +54,7 @@ class I2SAudioSpeaker : public Component, public speaker::Speaker, public I2SAud
void start(); void start();
void stop() override; void stop() override;
bool play(const uint8_t *data, size_t length) override; size_t play(const uint8_t *data, size_t length) override;
protected: protected:
void start_(); void start_();

View file

@ -1,6 +1,7 @@
#include "ina226.h" #include "ina226.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include "esphome/core/hal.h" #include "esphome/core/hal.h"
#include <cinttypes>
namespace esphome { namespace esphome {
namespace ina226 { namespace ina226 {
@ -68,7 +69,7 @@ void INA226Component::setup() {
auto calibration = uint32_t(0.00512 / (lsb * this->shunt_resistance_ohm_ / 1000000.0f)); auto calibration = uint32_t(0.00512 / (lsb * this->shunt_resistance_ohm_ / 1000000.0f));
ESP_LOGV(TAG, " Using LSB=%u calibration=%u", lsb, calibration); ESP_LOGV(TAG, " Using LSB=%" PRIu32 " calibration=%" PRIu32, lsb, calibration);
if (!this->write_byte_16(INA226_REGISTER_CALIBRATION, calibration)) { if (!this->write_byte_16(INA226_REGISTER_CALIBRATION, calibration)) {
this->mark_failed(); this->mark_failed();

View file

@ -48,6 +48,7 @@ MODELS = {
"inkplate_6": InkplateModel.INKPLATE_6, "inkplate_6": InkplateModel.INKPLATE_6,
"inkplate_10": InkplateModel.INKPLATE_10, "inkplate_10": InkplateModel.INKPLATE_10,
"inkplate_6_plus": InkplateModel.INKPLATE_6_PLUS, "inkplate_6_plus": InkplateModel.INKPLATE_6_PLUS,
"inkplate_6_v2": InkplateModel.INKPLATE_6_V2,
} }
CONFIG_SCHEMA = cv.All( CONFIG_SCHEMA = cv.All(

View file

@ -69,9 +69,9 @@ void Inkplate6::initialize_() {
if (this->buffer_ != nullptr) if (this->buffer_ != nullptr)
allocator.deallocate(this->buffer_, buffer_size); allocator.deallocate(this->buffer_, buffer_size);
if (this->glut_ != nullptr) if (this->glut_ != nullptr)
allocator32.deallocate(this->glut_, 256 * (this->model_ == INKPLATE_6_PLUS ? 9 : 8)); allocator32.deallocate(this->glut_, 256 * 9);
if (this->glut2_ != nullptr) if (this->glut2_ != nullptr)
allocator32.deallocate(this->glut2_, 256 * (this->model_ == INKPLATE_6_PLUS ? 9 : 8)); allocator32.deallocate(this->glut2_, 256 * 9);
this->buffer_ = allocator.allocate(buffer_size); this->buffer_ = allocator.allocate(buffer_size);
if (this->buffer_ == nullptr) { if (this->buffer_ == nullptr) {
@ -80,7 +80,7 @@ void Inkplate6::initialize_() {
return; return;
} }
if (this->greyscale_) { if (this->greyscale_) {
uint8_t glut_size = (this->model_ == INKPLATE_6_PLUS ? 9 : 8); uint8_t glut_size = 9;
this->glut_ = allocator32.allocate(256 * glut_size); this->glut_ = allocator32.allocate(256 * glut_size);
if (this->glut_ == nullptr) { if (this->glut_ == nullptr) {
@ -95,12 +95,14 @@ void Inkplate6::initialize_() {
return; return;
} }
const auto *const waveform3_bit = waveform3BitAll[this->model_];
for (int i = 0; i < glut_size; i++) { for (int i = 0; i < glut_size; i++) {
for (uint32_t j = 0; j < 256; j++) { for (uint32_t j = 0; j < 256; j++) {
uint8_t z = (waveform3Bit[j & 0x07][i] << 2) | (waveform3Bit[(j >> 4) & 0x07][i]); uint8_t z = (waveform3_bit[j & 0x07][i] << 2) | (waveform3_bit[(j >> 4) & 0x07][i]);
this->glut_[i * 256 + j] = ((z & 0b00000011) << 4) | (((z & 0b00001100) >> 2) << 18) | this->glut_[i * 256 + j] = ((z & 0b00000011) << 4) | (((z & 0b00001100) >> 2) << 18) |
(((z & 0b00010000) >> 4) << 23) | (((z & 0b11100000) >> 5) << 25); (((z & 0b00010000) >> 4) << 23) | (((z & 0b11100000) >> 5) << 25);
z = ((waveform3Bit[j & 0x07][i] << 2) | (waveform3Bit[(j >> 4) & 0x07][i])) << 4; z = ((waveform3_bit[j & 0x07][i] << 2) | (waveform3_bit[(j >> 4) & 0x07][i])) << 4;
this->glut2_[i * 256 + j] = ((z & 0b00000011) << 4) | (((z & 0b00001100) >> 2) << 18) | this->glut2_[i * 256 + j] = ((z & 0b00000011) << 4) | (((z & 0b00001100) >> 2) << 18) |
(((z & 0b00010000) >> 4) << 23) | (((z & 0b11100000) >> 5) << 25); (((z & 0b00010000) >> 4) << 23) | (((z & 0b11100000) >> 5) << 25);
} }
@ -339,13 +341,16 @@ void Inkplate6::display1b_() {
clean_fast_(1, 21); clean_fast_(1, 21);
clean_fast_(2, 1); clean_fast_(2, 1);
clean_fast_(0, 12); clean_fast_(0, 12);
clean_fast_(2, 1);
} }
uint32_t clock = (1 << this->cl_pin_->get_pin()); uint32_t clock = (1 << this->cl_pin_->get_pin());
uint32_t data_mask = this->get_data_pin_mask_(); uint32_t data_mask = this->get_data_pin_mask_();
ESP_LOGV(TAG, "Display1b start loops (%ums)", millis() - start_time); ESP_LOGV(TAG, "Display1b start loops (%ums)", millis() - start_time);
for (int k = 0; k < 4; k++) { int rep = (this->model_ == INKPLATE_6_V2) ? 5 : 4;
for (int k = 0; k < rep; k++) {
buffer_ptr = &this->buffer_[this->get_buffer_length_() - 1]; buffer_ptr = &this->buffer_[this->get_buffer_length_() - 1];
vscan_start_(); vscan_start_();
for (int i = 0, im = this->get_height_internal(); i < im; i++) { for (int i = 0, im = this->get_height_internal(); i < im; i++) {
@ -365,8 +370,11 @@ void Inkplate6::display1b_() {
GPIO.out_w1ts = this->pin_lut_[data] | clock; GPIO.out_w1ts = this->pin_lut_[data] | clock;
GPIO.out_w1tc = data_mask | clock; GPIO.out_w1tc = data_mask | clock;
} }
// New Inkplate6 panel doesn't need last clock
if (this->model_ != INKPLATE_6_V2) {
GPIO.out_w1ts = clock; GPIO.out_w1ts = clock;
GPIO.out_w1tc = data_mask | clock; GPIO.out_w1tc = data_mask | clock;
}
vscan_end_(); vscan_end_();
} }
delayMicroseconds(230); delayMicroseconds(230);
@ -392,8 +400,11 @@ void Inkplate6::display1b_() {
GPIO.out_w1ts = this->pin_lut_[data] | clock; GPIO.out_w1ts = this->pin_lut_[data] | clock;
GPIO.out_w1tc = data_mask | clock; GPIO.out_w1tc = data_mask | clock;
} }
// New Inkplate6 panel doesn't need last clock
if (this->model_ != INKPLATE_6_V2) {
GPIO.out_w1ts = clock; GPIO.out_w1ts = clock;
GPIO.out_w1tc = data_mask | clock; GPIO.out_w1tc = data_mask | clock;
}
vscan_end_(); vscan_end_();
} }
delayMicroseconds(230); delayMicroseconds(230);
@ -415,8 +426,11 @@ void Inkplate6::display1b_() {
GPIO.out_w1ts = send | clock; GPIO.out_w1ts = send | clock;
GPIO.out_w1tc = data_mask | clock; GPIO.out_w1tc = data_mask | clock;
} }
GPIO.out_w1ts = send | clock; // New Inkplate6 panel doesn't need last clock
if (this->model_ != INKPLATE_6_V2) {
GPIO.out_w1ts = clock;
GPIO.out_w1tc = data_mask | clock; GPIO.out_w1tc = data_mask | clock;
}
vscan_end_(); vscan_end_();
} }
delayMicroseconds(230); delayMicroseconds(230);
@ -450,13 +464,14 @@ void Inkplate6::display3b_() {
clean_fast_(1, 21); clean_fast_(1, 21);
clean_fast_(2, 1); clean_fast_(2, 1);
clean_fast_(0, 12); clean_fast_(0, 12);
clean_fast_(2, 1);
} }
uint32_t clock = (1 << this->cl_pin_->get_pin()); uint32_t clock = (1 << this->cl_pin_->get_pin());
uint32_t data_mask = this->get_data_pin_mask_(); uint32_t data_mask = this->get_data_pin_mask_();
uint32_t pos; uint32_t pos;
uint32_t data; uint32_t data;
uint8_t glut_size = this->model_ == INKPLATE_6_PLUS ? 9 : 8; uint8_t glut_size = 9;
for (int k = 0; k < glut_size; k++) { for (int k = 0; k < glut_size; k++) {
pos = this->get_buffer_length_(); pos = this->get_buffer_length_();
vscan_start_(); vscan_start_();
@ -479,8 +494,11 @@ void Inkplate6::display3b_() {
GPIO.out_w1ts = data | clock; GPIO.out_w1ts = data | clock;
GPIO.out_w1tc = data_mask | clock; GPIO.out_w1tc = data_mask | clock;
} }
// New Inkplate6 panel doesn't need last clock
if (this->model_ != INKPLATE_6_V2) {
GPIO.out_w1ts = clock; GPIO.out_w1ts = clock;
GPIO.out_w1tc = data_mask | clock; GPIO.out_w1tc = data_mask | clock;
}
vscan_end_(); vscan_end_();
} }
delayMicroseconds(230); delayMicroseconds(230);
@ -517,10 +535,12 @@ bool Inkplate6::partial_update_() {
} }
ESP_LOGV(TAG, "Partial update buffer built after (%ums)", millis() - start_time); ESP_LOGV(TAG, "Partial update buffer built after (%ums)", millis() - start_time);
int rep = (this->model_ == INKPLATE_6_V2) ? 6 : 5;
eink_on_(); eink_on_();
uint32_t clock = (1 << this->cl_pin_->get_pin()); uint32_t clock = (1 << this->cl_pin_->get_pin());
uint32_t data_mask = this->get_data_pin_mask_(); uint32_t data_mask = this->get_data_pin_mask_();
for (int k = 0; k < 5; k++) { for (int k = 0; k < rep; k++) {
vscan_start_(); vscan_start_();
const uint8_t *data_ptr = &this->partial_buffer_2_[(this->get_buffer_length_() * 2) - 1]; const uint8_t *data_ptr = &this->partial_buffer_2_[(this->get_buffer_length_() * 2) - 1];
for (int i = 0; i < this->get_height_internal(); i++) { for (int i = 0; i < this->get_height_internal(); i++) {
@ -531,8 +551,11 @@ bool Inkplate6::partial_update_() {
GPIO.out_w1ts = this->pin_lut_[data] | clock; GPIO.out_w1ts = this->pin_lut_[data] | clock;
GPIO.out_w1tc = data_mask | clock; GPIO.out_w1tc = data_mask | clock;
} }
// New Inkplate6 panel doesn't need last clock
if (this->model_ != INKPLATE_6_V2) {
GPIO.out_w1ts = clock; GPIO.out_w1ts = clock;
GPIO.out_w1tc = data_mask | clock; GPIO.out_w1tc = data_mask | clock;
}
vscan_end_(); vscan_end_();
} }
delayMicroseconds(230); delayMicroseconds(230);
@ -634,8 +657,11 @@ void Inkplate6::clean_fast_(uint8_t c, uint8_t rep) {
GPIO.out_w1ts = clock; GPIO.out_w1ts = clock;
GPIO.out_w1tc = clock; GPIO.out_w1tc = clock;
} }
// New Inkplate6 panel doesn't need last clock
if (this->model_ != INKPLATE_6_V2) {
GPIO.out_w1ts = send | clock; GPIO.out_w1ts = send | clock;
GPIO.out_w1tc = clock; GPIO.out_w1tc = clock;
}
vscan_end_(); vscan_end_();
} }
delayMicroseconds(230); delayMicroseconds(230);

View file

@ -14,6 +14,7 @@ enum InkplateModel : uint8_t {
INKPLATE_6 = 0, INKPLATE_6 = 0,
INKPLATE_10 = 1, INKPLATE_10 = 1,
INKPLATE_6_PLUS = 2, INKPLATE_6_PLUS = 2,
INKPLATE_6_V2 = 3,
}; };
class Inkplate6 : public PollingComponent, public display::DisplayBuffer, public i2c::I2CDevice { class Inkplate6 : public PollingComponent, public display::DisplayBuffer, public i2c::I2CDevice {
@ -28,13 +29,42 @@ class Inkplate6 : public PollingComponent, public display::DisplayBuffer, public
const uint8_t pixelMaskLUT[8] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80}; const uint8_t pixelMaskLUT[8] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
const uint8_t pixelMaskGLUT[2] = {0x0F, 0xF0}; const uint8_t pixelMaskGLUT[2] = {0x0F, 0xF0};
const uint8_t waveform3Bit[8][8] = {{0, 1, 1, 0, 0, 1, 1, 0}, {0, 1, 2, 1, 1, 2, 1, 0}, {1, 1, 1, 2, 2, 1, 0, 0}, const uint8_t waveform3BitAll[4][8][9] = {// INKPLATE_6
{0, 0, 0, 1, 1, 1, 2, 0}, {2, 1, 1, 1, 2, 1, 2, 0}, {2, 2, 1, 1, 2, 1, 2, 0}, {{0, 1, 1, 0, 0, 1, 1, 0, 0},
{1, 1, 1, 2, 1, 2, 2, 0}, {0, 0, 0, 0, 0, 0, 2, 0}}; {0, 1, 2, 1, 1, 2, 1, 0, 0},
const uint8_t waveform3Bit6Plus[8][9] = {{0, 0, 0, 0, 0, 2, 1, 1, 0}, {0, 0, 2, 1, 1, 1, 2, 1, 0}, {1, 1, 1, 2, 2, 1, 0, 0, 0},
{0, 2, 2, 2, 1, 1, 2, 1, 0}, {0, 0, 2, 2, 2, 1, 2, 1, 0}, {0, 0, 0, 1, 1, 1, 2, 0, 0},
{0, 0, 0, 0, 2, 2, 2, 1, 0}, {0, 0, 2, 1, 2, 1, 1, 2, 0}, {2, 1, 1, 1, 2, 1, 2, 0, 0},
{0, 0, 2, 2, 2, 1, 1, 2, 0}, {0, 0, 0, 0, 2, 2, 2, 2, 0}}; {2, 2, 1, 1, 2, 1, 2, 0, 0},
{1, 1, 1, 2, 1, 2, 2, 0, 0},
{0, 0, 0, 0, 0, 0, 2, 0, 0}},
// INKPLATE_10
{{0, 0, 0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 2, 2, 2, 1, 1, 0},
{0, 0, 2, 1, 1, 2, 2, 1, 0},
{0, 1, 2, 2, 1, 2, 2, 1, 0},
{0, 0, 2, 1, 2, 2, 2, 1, 0},
{0, 2, 2, 2, 2, 2, 2, 1, 0},
{0, 0, 0, 0, 0, 2, 1, 2, 0},
{0, 0, 0, 2, 2, 2, 2, 2, 0}},
// INKPLATE_6_PLUS
{{0, 0, 0, 0, 0, 2, 1, 1, 0},
{0, 0, 2, 1, 1, 1, 2, 1, 0},
{0, 2, 2, 2, 1, 1, 2, 1, 0},
{0, 0, 2, 2, 2, 1, 2, 1, 0},
{0, 0, 0, 0, 2, 2, 2, 1, 0},
{0, 0, 2, 1, 2, 1, 1, 2, 0},
{0, 0, 2, 2, 2, 1, 1, 2, 0},
{0, 0, 0, 0, 2, 2, 2, 2, 0}},
// INKPLATE_6_V2
{{1, 0, 1, 0, 1, 1, 1, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 0, 0},
{1, 1, 1, 1, 0, 2, 1, 0, 0},
{1, 1, 1, 2, 2, 1, 1, 0, 0},
{1, 1, 1, 1, 2, 2, 1, 0, 0},
{0, 1, 1, 1, 2, 2, 1, 0, 0},
{0, 0, 0, 0, 1, 1, 2, 0, 0},
{0, 0, 0, 0, 0, 1, 2, 0, 0}}};
void set_greyscale(bool greyscale) { void set_greyscale(bool greyscale) {
this->greyscale_ = greyscale; this->greyscale_ = greyscale;
@ -111,7 +141,7 @@ class Inkplate6 : public PollingComponent, public display::DisplayBuffer, public
void pins_as_outputs_(); void pins_as_outputs_();
int get_width_internal() override { int get_width_internal() override {
if (this->model_ == INKPLATE_6) { if (this->model_ == INKPLATE_6 || this->model_ == INKPLATE_6_V2) {
return 800; return 800;
} else if (this->model_ == INKPLATE_10) { } else if (this->model_ == INKPLATE_10) {
return 1200; return 1200;
@ -122,7 +152,7 @@ class Inkplate6 : public PollingComponent, public display::DisplayBuffer, public
} }
int get_height_internal() override { int get_height_internal() override {
if (this->model_ == INKPLATE_6) { if (this->model_ == INKPLATE_6 || this->model_ == INKPLATE_6_V2) {
return 600; return 600;
} else if (this->model_ == INKPLATE_10) { } else if (this->model_ == INKPLATE_10) {
return 825; return 825;

View file

@ -125,7 +125,7 @@ void HOT Logger::log_message_(int level, const char *tag, int offset) {
#elif defined(USE_ESP32_VARIANT_ESP32S3) #elif defined(USE_ESP32_VARIANT_ESP32S3)
uart_ == UART_SELECTION_USB_CDC || uart_ == UART_SELECTION_USB_SERIAL_JTAG uart_ == UART_SELECTION_USB_CDC || uart_ == UART_SELECTION_USB_SERIAL_JTAG
#else #else
/* DISABLES CODE */ (false) /* DISABLES CODE */ (false) // NOLINT
#endif #endif
) { ) {
puts(msg); puts(msg);

View file

@ -89,11 +89,13 @@ void MatrixKeypad::loop() {
void MatrixKeypad::dump_config() { void MatrixKeypad::dump_config() {
ESP_LOGCONFIG(TAG, "Matrix Keypad:"); ESP_LOGCONFIG(TAG, "Matrix Keypad:");
ESP_LOGCONFIG(TAG, " Rows:"); ESP_LOGCONFIG(TAG, " Rows:");
for (auto &pin : this->rows_) for (auto &pin : this->rows_) {
LOG_PIN(" Pin: ", pin); LOG_PIN(" Pin: ", pin);
}
ESP_LOGCONFIG(TAG, " Cols:"); ESP_LOGCONFIG(TAG, " Cols:");
for (auto &pin : this->columns_) for (auto &pin : this->columns_) {
LOG_PIN(" Pin: ", pin); LOG_PIN(" Pin: ", pin);
}
} }
void MatrixKeypad::register_listener(MatrixKeypadListener *listener) { this->listeners_.push_back(listener); } void MatrixKeypad::register_listener(MatrixKeypadListener *listener) { this->listeners_.push_back(listener); }

View file

@ -2,6 +2,7 @@
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include <cmath> #include <cmath>
#include <cinttypes>
namespace esphome { namespace esphome {
namespace max31865 { namespace max31865 {
@ -45,14 +46,15 @@ void MAX31865Sensor::update() {
config = this->read_register_(CONFIGURATION_REG); config = this->read_register_(CONFIGURATION_REG);
fault_detect_time = micros() - start_time; fault_detect_time = micros() - start_time;
if ((fault_detect_time >= 6000) && (config & 0b00001100)) { if ((fault_detect_time >= 6000) && (config & 0b00001100)) {
ESP_LOGE(TAG, "Fault detection incomplete (0x%02X) after %uμs (datasheet spec is 600μs max)! Aborting read.", ESP_LOGE(TAG,
"Fault detection incomplete (0x%02X) after %" PRIu32 "μs (datasheet spec is 600μs max)! Aborting read.",
config, fault_detect_time); config, fault_detect_time);
this->publish_state(NAN); this->publish_state(NAN);
this->status_set_error(); this->status_set_error();
return; return;
} }
} while (config & 0b00001100); } while (config & 0b00001100);
ESP_LOGV(TAG, "Fault detection completed in %uμs.", fault_detect_time); ESP_LOGV(TAG, "Fault detection completed in %" PRIu32 "μs.", fault_detect_time);
// Start 1-shot conversion // Start 1-shot conversion
this->write_config_(0b11100000, 0b10100000); this->write_config_(0b11100000, 0b10100000);

View file

@ -22,6 +22,7 @@ class Microphone {
} }
bool is_running() const { return this->state_ == STATE_RUNNING; } bool is_running() const { return this->state_ == STATE_RUNNING; }
bool is_stopped() const { return this->state_ == STATE_STOPPED; }
protected: protected:
State state_{STATE_STOPPED}; State state_{STATE_STOPPED};

View file

@ -216,7 +216,7 @@ void MQTTClimateComponent::setup() {
}); });
} }
this->device_->add_on_state_callback([this]() { this->publish_state_(); }); this->device_->add_on_state_callback([this](Climate & /*unused*/) { this->publish_state_(); });
} }
MQTTClimateComponent::MQTTClimateComponent(Climate *device) : device_(device) {} MQTTClimateComponent::MQTTClimateComponent(Climate *device) : device_(device) {}
bool MQTTClimateComponent::send_initial_state() { return this->publish_state_(); } bool MQTTClimateComponent::send_initial_state() { return this->publish_state_(); }

View file

@ -1,3 +1,4 @@
from esphome.core import CORE
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.esp32 import add_idf_sdkconfig_option from esphome.components.esp32 import add_idf_sdkconfig_option
@ -14,8 +15,8 @@ IPAddress = network_ns.class_("IPAddress")
CONFIG_SCHEMA = cv.Schema( CONFIG_SCHEMA = cv.Schema(
{ {
cv.SplitDefault(CONF_ENABLE_IPV6, esp32_idf=False): cv.All( cv.SplitDefault(CONF_ENABLE_IPV6, esp32=False): cv.All(
cv.only_with_esp_idf, cv.boolean cv.only_on_esp32, cv.boolean
), ),
} }
) )
@ -23,7 +24,12 @@ CONFIG_SCHEMA = cv.Schema(
async def to_code(config): async def to_code(config):
if CONF_ENABLE_IPV6 in config: if CONF_ENABLE_IPV6 in config:
if CORE.using_esp_idf:
add_idf_sdkconfig_option("CONFIG_LWIP_IPV6", config[CONF_ENABLE_IPV6]) add_idf_sdkconfig_option("CONFIG_LWIP_IPV6", config[CONF_ENABLE_IPV6])
add_idf_sdkconfig_option( add_idf_sdkconfig_option(
"CONFIG_LWIP_IPV6_AUTOCONFIG", config[CONF_ENABLE_IPV6] "CONFIG_LWIP_IPV6_AUTOCONFIG", config[CONF_ENABLE_IPV6]
) )
else:
if config[CONF_ENABLE_IPV6]:
cg.add_build_flag("-DCONFIG_LWIP_IPV6")
cg.add_build_flag("-DCONFIG_LWIP_IPV6_AUTOCONFIG")

View file

@ -1,5 +1,6 @@
#include "pipsolar.h" #include "pipsolar.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include "esphome/core/helpers.h"
namespace esphome { namespace esphome {
namespace pipsolar { namespace pipsolar {
@ -768,7 +769,7 @@ uint8_t Pipsolar::check_incoming_length_(uint8_t length) {
uint8_t Pipsolar::check_incoming_crc_() { uint8_t Pipsolar::check_incoming_crc_() {
uint16_t crc16; uint16_t crc16;
crc16 = cal_crc_half_(read_buffer_, read_pos_ - 3); crc16 = crc16be(read_buffer_, read_pos_ - 3);
ESP_LOGD(TAG, "checking crc on incoming message"); ESP_LOGD(TAG, "checking crc on incoming message");
if (((uint8_t) ((crc16) >> 8)) == read_buffer_[read_pos_ - 3] && if (((uint8_t) ((crc16) >> 8)) == read_buffer_[read_pos_ - 3] &&
((uint8_t) ((crc16) &0xff)) == read_buffer_[read_pos_ - 2]) { ((uint8_t) ((crc16) &0xff)) == read_buffer_[read_pos_ - 2]) {
@ -797,7 +798,7 @@ uint8_t Pipsolar::send_next_command_() {
this->command_start_millis_ = millis(); this->command_start_millis_ = millis();
this->empty_uart_buffer_(); this->empty_uart_buffer_();
this->read_pos_ = 0; this->read_pos_ = 0;
crc16 = cal_crc_half_(byte_command, length); crc16 = crc16be(byte_command, length);
this->write_str(command); this->write_str(command);
// checksum // checksum
this->write(((uint8_t) ((crc16) >> 8))); // highbyte this->write(((uint8_t) ((crc16) >> 8))); // highbyte
@ -824,7 +825,7 @@ void Pipsolar::send_next_poll_() {
this->command_start_millis_ = millis(); this->command_start_millis_ = millis();
this->empty_uart_buffer_(); this->empty_uart_buffer_();
this->read_pos_ = 0; this->read_pos_ = 0;
crc16 = cal_crc_half_(this->used_polling_commands_[this->last_polling_command_].command, crc16 = crc16be(this->used_polling_commands_[this->last_polling_command_].command,
this->used_polling_commands_[this->last_polling_command_].length); this->used_polling_commands_[this->last_polling_command_].length);
this->write_array(this->used_polling_commands_[this->last_polling_command_].command, this->write_array(this->used_polling_commands_[this->last_polling_command_].command,
this->used_polling_commands_[this->last_polling_command_].length); this->used_polling_commands_[this->last_polling_command_].length);
@ -892,42 +893,5 @@ void Pipsolar::add_polling_command_(const char *command, ENUMPollingCommand poll
} }
} }
uint16_t Pipsolar::cal_crc_half_(uint8_t *msg, uint8_t len) {
uint16_t crc;
uint8_t da;
uint8_t *ptr;
uint8_t b_crc_hign;
uint8_t b_crc_low;
uint16_t crc_ta[16] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef};
ptr = msg;
crc = 0;
while (len-- != 0) {
da = ((uint8_t) (crc >> 8)) >> 4;
crc <<= 4;
crc ^= crc_ta[da ^ (*ptr >> 4)];
da = ((uint8_t) (crc >> 8)) >> 4;
crc <<= 4;
crc ^= crc_ta[da ^ (*ptr & 0x0f)];
ptr++;
}
b_crc_low = crc;
b_crc_hign = (uint8_t) (crc >> 8);
if (b_crc_low == 0x28 || b_crc_low == 0x0d || b_crc_low == 0x0a)
b_crc_low++;
if (b_crc_hign == 0x28 || b_crc_hign == 0x0d || b_crc_hign == 0x0a)
b_crc_hign++;
crc = ((uint16_t) b_crc_hign) << 8;
crc += b_crc_low;
return (crc);
}
} // namespace pipsolar } // namespace pipsolar
} // namespace esphome } // namespace esphome

View file

@ -22,8 +22,6 @@ class MideaData {
MideaData(const std::vector<uint8_t> &data) { MideaData(const std::vector<uint8_t> &data) {
std::copy_n(data.begin(), std::min(data.size(), this->data_.size()), this->data_.begin()); std::copy_n(data.begin(), std::min(data.size(), this->data_.size()), this->data_.begin());
} }
// Default copy constructor
MideaData(const MideaData &) = default;
uint8_t *data() { return this->data_.data(); } uint8_t *data() { return this->data_.data(); }
const uint8_t *data() const { return this->data_.data(); } const uint8_t *data() const { return this->data_.data(); }

View file

@ -187,11 +187,10 @@ std::string ProntoProtocol::dump_duration_(uint32_t duration, uint16_t timebase,
return dump_number_((duration + timebase / 2) / timebase, end); return dump_number_((duration + timebase / 2) / timebase, end);
} }
std::string ProntoProtocol::compensate_and_dump_sequence_(std::vector<int32_t> *data, uint16_t timebase) { std::string ProntoProtocol::compensate_and_dump_sequence_(const RawTimings &data, uint16_t timebase) {
std::string out; std::string out;
for (std::vector<int32_t>::size_type i = 0; i < data->size() - 1; i++) { for (int32_t t_length : data) {
int32_t t_length = data->at(i);
uint32_t t_duration; uint32_t t_duration;
if (t_length > 0) { if (t_length > 0) {
// Mark // Mark
@ -212,12 +211,12 @@ optional<ProntoData> ProntoProtocol::decode(RemoteReceiveData src) {
ProntoData out; ProntoData out;
uint16_t frequency = 38000U; uint16_t frequency = 38000U;
std::vector<int32_t> *data = src.get_raw_data(); auto &data = src.get_raw_data();
std::string prontodata; std::string prontodata;
prontodata += dump_number_(frequency > 0 ? LEARNED_TOKEN : LEARNED_NON_MODULATED_TOKEN); prontodata += dump_number_(frequency > 0 ? LEARNED_TOKEN : LEARNED_NON_MODULATED_TOKEN);
prontodata += dump_number_(to_frequency_code_(frequency)); prontodata += dump_number_(to_frequency_code_(frequency));
prontodata += dump_number_((data->size() + 1) / 2); prontodata += dump_number_((data.size() + 1) / 2);
prontodata += dump_number_(0); prontodata += dump_number_(0);
uint16_t timebase = to_timebase_(frequency); uint16_t timebase = to_timebase_(frequency);
prontodata += compensate_and_dump_sequence_(data, timebase); prontodata += compensate_and_dump_sequence_(data, timebase);

View file

@ -27,7 +27,7 @@ class ProntoProtocol : public RemoteProtocol<ProntoData> {
std::string dump_digit_(uint8_t x); std::string dump_digit_(uint8_t x);
std::string dump_number_(uint16_t number, bool end = false); std::string dump_number_(uint16_t number, bool end = false);
std::string dump_duration_(uint32_t duration, uint16_t timebase, bool end = false); std::string dump_duration_(uint32_t duration, uint16_t timebase, bool end = false);
std::string compensate_and_dump_sequence_(std::vector<int32_t> *data, uint16_t timebase); std::string compensate_and_dump_sequence_(const RawTimings &data, uint16_t timebase);
public: public:
void encode(RemoteTransmitData *dst, const ProntoData &data) override; void encode(RemoteTransmitData *dst, const ProntoData &data) override;

View file

@ -31,17 +31,17 @@ class RawBinarySensor : public RemoteReceiverBinarySensorBase {
size_t len_; size_t len_;
}; };
class RawTrigger : public Trigger<std::vector<int32_t>>, public Component, public RemoteReceiverListener { class RawTrigger : public Trigger<RawTimings>, public Component, public RemoteReceiverListener {
protected: protected:
bool on_receive(RemoteReceiveData src) override { bool on_receive(RemoteReceiveData src) override {
this->trigger(*src.get_raw_data()); this->trigger(src.get_raw_data());
return false; return false;
} }
}; };
template<typename... Ts> class RawAction : public RemoteTransmitterActionBase<Ts...> { template<typename... Ts> class RawAction : public RemoteTransmitterActionBase<Ts...> {
public: public:
void set_code_template(std::function<std::vector<int32_t>(Ts...)> func) { this->code_func_ = func; } void set_code_template(std::function<RawTimings(Ts...)> func) { this->code_func_ = func; }
void set_code_static(const int32_t *code, size_t len) { void set_code_static(const int32_t *code, size_t len) {
this->code_static_ = code; this->code_static_ = code;
this->code_static_len_ = len; this->code_static_len_ = len;
@ -65,7 +65,7 @@ template<typename... Ts> class RawAction : public RemoteTransmitterActionBase<Ts
} }
protected: protected:
std::function<std::vector<int32_t>(Ts...)> code_func_{}; std::function<RawTimings(Ts...)> code_func_{nullptr};
const int32_t *code_static_{nullptr}; const int32_t *code_static_{nullptr};
int32_t code_static_len_{0}; int32_t code_static_len_{0};
}; };

View file

@ -24,11 +24,105 @@ void RemoteRMTChannel::config_rmt(rmt_config_t &rmt) {
} }
#endif #endif
/* RemoteReceiveData */
bool RemoteReceiveData::peek_mark(uint32_t length, uint32_t offset) const {
if (!this->is_valid(offset))
return false;
const int32_t value = this->peek(offset);
const int32_t lo = this->lower_bound_(length);
const int32_t hi = this->upper_bound_(length);
return value >= 0 && lo <= value && value <= hi;
}
bool RemoteReceiveData::peek_space(uint32_t length, uint32_t offset) const {
if (!this->is_valid(offset))
return false;
const int32_t value = this->peek(offset);
const int32_t lo = this->lower_bound_(length);
const int32_t hi = this->upper_bound_(length);
return value <= 0 && lo <= -value && -value <= hi;
}
bool RemoteReceiveData::peek_space_at_least(uint32_t length, uint32_t offset) const {
if (!this->is_valid(offset))
return false;
const int32_t value = this->peek(offset);
const int32_t lo = this->lower_bound_(length);
return value <= 0 && lo <= -value;
}
bool RemoteReceiveData::expect_mark(uint32_t length) {
if (!this->peek_mark(length))
return false;
this->advance();
return true;
}
bool RemoteReceiveData::expect_space(uint32_t length) {
if (!this->peek_space(length))
return false;
this->advance();
return true;
}
bool RemoteReceiveData::expect_item(uint32_t mark, uint32_t space) {
if (!this->peek_item(mark, space))
return false;
this->advance(2);
return true;
}
bool RemoteReceiveData::expect_pulse_with_gap(uint32_t mark, uint32_t space) {
if (!this->peek_space_at_least(space, 1) || !this->peek_mark(mark))
return false;
this->advance(2);
return true;
}
/* RemoteReceiverBinarySensorBase */
bool RemoteReceiverBinarySensorBase::on_receive(RemoteReceiveData src) {
if (!this->matches(src))
return false;
this->publish_state(true);
yield();
this->publish_state(false);
return true;
}
/* RemoteReceiverBase */
void RemoteReceiverBase::register_dumper(RemoteReceiverDumperBase *dumper) {
if (dumper->is_secondary()) {
this->secondary_dumpers_.push_back(dumper);
} else {
this->dumpers_.push_back(dumper);
}
}
void RemoteReceiverBase::call_listeners_() {
for (auto *listener : this->listeners_)
listener->on_receive(RemoteReceiveData(this->temp_, this->tolerance_));
}
void RemoteReceiverBase::call_dumpers_() {
bool success = false;
for (auto *dumper : this->dumpers_) {
if (dumper->dump(RemoteReceiveData(this->temp_, this->tolerance_)))
success = true;
}
if (!success) {
for (auto *dumper : this->secondary_dumpers_)
dumper->dump(RemoteReceiveData(this->temp_, this->tolerance_));
}
}
void RemoteReceiverBinarySensorBase::dump_config() { LOG_BINARY_SENSOR("", "Remote Receiver Binary Sensor", this); } void RemoteReceiverBinarySensorBase::dump_config() { LOG_BINARY_SENSOR("", "Remote Receiver Binary Sensor", this); }
void RemoteTransmitterBase::send_(uint32_t send_times, uint32_t send_wait) { void RemoteTransmitterBase::send_(uint32_t send_times, uint32_t send_wait) {
#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE #ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
const std::vector<int32_t> &vec = this->temp_.get_data(); const auto &vec = this->temp_.get_data();
char buffer[256]; char buffer[256];
uint32_t buffer_offset = 0; uint32_t buffer_offset = 0;
buffer_offset += sprintf(buffer, "Sending times=%u wait=%ums: ", send_times, send_wait); buffer_offset += sprintf(buffer, "Sending times=%u wait=%ums: ", send_times, send_wait);

View file

@ -15,146 +15,65 @@
namespace esphome { namespace esphome {
namespace remote_base { namespace remote_base {
using RawTimings = std::vector<int32_t>;
class RemoteTransmitData { class RemoteTransmitData {
public: public:
void mark(uint32_t length) { this->data_.push_back(length); } void mark(uint32_t length) { this->data_.push_back(length); }
void space(uint32_t length) { this->data_.push_back(-length); } void space(uint32_t length) { this->data_.push_back(-length); }
void item(uint32_t mark, uint32_t space) { void item(uint32_t mark, uint32_t space) {
this->mark(mark); this->mark(mark);
this->space(space); this->space(space);
} }
void reserve(uint32_t len) { this->data_.reserve(len); } void reserve(uint32_t len) { this->data_.reserve(len); }
void set_carrier_frequency(uint32_t carrier_frequency) { this->carrier_frequency_ = carrier_frequency; } void set_carrier_frequency(uint32_t carrier_frequency) { this->carrier_frequency_ = carrier_frequency; }
uint32_t get_carrier_frequency() const { return this->carrier_frequency_; } uint32_t get_carrier_frequency() const { return this->carrier_frequency_; }
const RawTimings &get_data() const { return this->data_; }
const std::vector<int32_t> &get_data() const { return this->data_; } void set_data(const RawTimings &data) { this->data_ = data; }
void set_data(const std::vector<int32_t> &data) {
this->data_.clear();
this->data_.reserve(data.size());
for (auto dat : data)
this->data_.push_back(dat);
}
void reset() { void reset() {
this->data_.clear(); this->data_.clear();
this->carrier_frequency_ = 0; this->carrier_frequency_ = 0;
} }
std::vector<int32_t>::iterator begin() { return this->data_.begin(); }
std::vector<int32_t>::iterator end() { return this->data_.end(); }
protected: protected:
std::vector<int32_t> data_{}; RawTimings data_{};
uint32_t carrier_frequency_{0}; uint32_t carrier_frequency_{0};
}; };
class RemoteReceiveData { class RemoteReceiveData {
public: public:
RemoteReceiveData(std::vector<int32_t> *data, uint8_t tolerance) : data_(data), tolerance_(tolerance) {} explicit RemoteReceiveData(const RawTimings &data, uint8_t tolerance)
: data_(data), index_(0), tolerance_(tolerance) {}
bool peek_mark(uint32_t length, uint32_t offset = 0) { const RawTimings &get_raw_data() const { return this->data_; }
if (int32_t(this->index_ + offset) >= this->size()) uint32_t get_index() const { return index_; }
return false; int32_t operator[](uint32_t index) const { return this->data_[index]; }
int32_t value = this->peek(offset); int32_t size() const { return this->data_.size(); }
const int32_t lo = this->lower_bound_(length); bool is_valid(uint32_t offset) const { return this->index_ + offset < this->data_.size(); }
const int32_t hi = this->upper_bound_(length); int32_t peek(uint32_t offset = 0) const { return this->data_[this->index_ + offset]; }
return value >= 0 && lo <= value && value <= hi; bool peek_mark(uint32_t length, uint32_t offset = 0) const;
bool peek_space(uint32_t length, uint32_t offset = 0) const;
bool peek_space_at_least(uint32_t length, uint32_t offset = 0) const;
bool peek_item(uint32_t mark, uint32_t space, uint32_t offset = 0) const {
return this->peek_space(space, offset + 1) && this->peek_mark(mark, offset);
} }
bool peek_space(uint32_t length, uint32_t offset = 0) { bool expect_mark(uint32_t length);
if (int32_t(this->index_ + offset) >= this->size()) bool expect_space(uint32_t length);
return false; bool expect_item(uint32_t mark, uint32_t space);
int32_t value = this->peek(offset); bool expect_pulse_with_gap(uint32_t mark, uint32_t space);
const int32_t lo = this->lower_bound_(length);
const int32_t hi = this->upper_bound_(length);
return value <= 0 && lo <= -value && -value <= hi;
}
bool peek_space_at_least(uint32_t length, uint32_t offset = 0) {
if (int32_t(this->index_ + offset) >= this->size())
return false;
int32_t value = this->pos(this->index_ + offset);
const int32_t lo = this->lower_bound_(length);
return value <= 0 && lo <= -value;
}
bool peek_item(uint32_t mark, uint32_t space, uint32_t offset = 0) {
return this->peek_mark(mark, offset) && this->peek_space(space, offset + 1);
}
int32_t peek(uint32_t offset = 0) { return (*this)[this->index_ + offset]; }
void advance(uint32_t amount = 1) { this->index_ += amount; } void advance(uint32_t amount = 1) { this->index_ += amount; }
bool expect_mark(uint32_t length) {
if (this->peek_mark(length)) {
this->advance();
return true;
}
return false;
}
bool expect_space(uint32_t length) {
if (this->peek_space(length)) {
this->advance();
return true;
}
return false;
}
bool expect_item(uint32_t mark, uint32_t space) {
if (this->peek_item(mark, space)) {
this->advance(2);
return true;
}
return false;
}
bool expect_pulse_with_gap(uint32_t mark, uint32_t space) {
if (this->peek_mark(mark, 0) && this->peek_space_at_least(space, 1)) {
this->advance(2);
return true;
}
return false;
}
uint32_t get_index() { return index_; }
void reset() { this->index_ = 0; } void reset() { this->index_ = 0; }
int32_t pos(uint32_t index) const { return (*this->data_)[index]; }
int32_t operator[](uint32_t index) const { return this->pos(index); }
int32_t size() const { return this->data_->size(); }
std::vector<int32_t> *get_raw_data() { return this->data_; }
protected: protected:
int32_t lower_bound_(uint32_t length) { return int32_t(100 - this->tolerance_) * length / 100U; } int32_t lower_bound_(uint32_t length) const { return int32_t(100 - this->tolerance_) * length / 100U; }
int32_t upper_bound_(uint32_t length) { return int32_t(100 + this->tolerance_) * length / 100U; } int32_t upper_bound_(uint32_t length) const { return int32_t(100 + this->tolerance_) * length / 100U; }
uint32_t index_{0}; const RawTimings &data_;
std::vector<int32_t> *data_; uint32_t index_;
uint8_t tolerance_; uint8_t tolerance_;
}; };
template<typename T> class RemoteProtocol {
public:
virtual void encode(RemoteTransmitData *dst, const T &data) = 0;
virtual optional<T> decode(RemoteReceiveData src) = 0;
virtual void dump(const T &data) = 0;
};
class RemoteComponentBase { class RemoteComponentBase {
public: public:
explicit RemoteComponentBase(InternalGPIOPin *pin) : pin_(pin){}; explicit RemoteComponentBase(InternalGPIOPin *pin) : pin_(pin){};
@ -196,7 +115,6 @@ class RemoteTransmitterBase : public RemoteComponentBase {
RemoteTransmitData *get_data() { return &this->parent_->temp_; } RemoteTransmitData *get_data() { return &this->parent_->temp_; }
void set_send_times(uint32_t send_times) { send_times_ = send_times; } void set_send_times(uint32_t send_times) { send_times_ = send_times; }
void set_send_wait(uint32_t send_wait) { send_wait_ = send_wait; } void set_send_wait(uint32_t send_wait) { send_wait_ = send_wait; }
void perform() { this->parent_->send_(this->send_times_, this->send_wait_); } void perform() { this->parent_->send_(this->send_times_, this->send_wait_); }
protected: protected:
@ -234,51 +152,22 @@ class RemoteReceiverBase : public RemoteComponentBase {
public: public:
RemoteReceiverBase(InternalGPIOPin *pin) : RemoteComponentBase(pin) {} RemoteReceiverBase(InternalGPIOPin *pin) : RemoteComponentBase(pin) {}
void register_listener(RemoteReceiverListener *listener) { this->listeners_.push_back(listener); } void register_listener(RemoteReceiverListener *listener) { this->listeners_.push_back(listener); }
void register_dumper(RemoteReceiverDumperBase *dumper) { void register_dumper(RemoteReceiverDumperBase *dumper);
if (dumper->is_secondary()) {
this->secondary_dumpers_.push_back(dumper);
} else {
this->dumpers_.push_back(dumper);
}
}
void set_tolerance(uint8_t tolerance) { tolerance_ = tolerance; } void set_tolerance(uint8_t tolerance) { tolerance_ = tolerance; }
protected: protected:
bool call_listeners_() { void call_listeners_();
bool success = false; void call_dumpers_();
for (auto *listener : this->listeners_) {
auto data = RemoteReceiveData(&this->temp_, this->tolerance_);
if (listener->on_receive(data))
success = true;
}
return success;
}
void call_dumpers_() {
bool success = false;
for (auto *dumper : this->dumpers_) {
auto data = RemoteReceiveData(&this->temp_, this->tolerance_);
if (dumper->dump(data))
success = true;
}
if (!success) {
for (auto *dumper : this->secondary_dumpers_) {
auto data = RemoteReceiveData(&this->temp_, this->tolerance_);
dumper->dump(data);
}
}
}
void call_listeners_dumpers_() { void call_listeners_dumpers_() {
if (this->call_listeners_()) this->call_listeners_();
return;
// If a listener handled, then do not dump
this->call_dumpers_(); this->call_dumpers_();
} }
std::vector<RemoteReceiverListener *> listeners_; std::vector<RemoteReceiverListener *> listeners_;
std::vector<RemoteReceiverDumperBase *> dumpers_; std::vector<RemoteReceiverDumperBase *> dumpers_;
std::vector<RemoteReceiverDumperBase *> secondary_dumpers_; std::vector<RemoteReceiverDumperBase *> secondary_dumpers_;
std::vector<int32_t> temp_; RawTimings temp_;
uint8_t tolerance_{25}; uint8_t tolerance_;
}; };
class RemoteReceiverBinarySensorBase : public binary_sensor::BinarySensorInitiallyOff, class RemoteReceiverBinarySensorBase : public binary_sensor::BinarySensorInitiallyOff,
@ -288,15 +177,16 @@ class RemoteReceiverBinarySensorBase : public binary_sensor::BinarySensorInitial
explicit RemoteReceiverBinarySensorBase() {} explicit RemoteReceiverBinarySensorBase() {}
void dump_config() override; void dump_config() override;
virtual bool matches(RemoteReceiveData src) = 0; virtual bool matches(RemoteReceiveData src) = 0;
bool on_receive(RemoteReceiveData src) override { bool on_receive(RemoteReceiveData src) override;
if (this->matches(src)) { };
this->publish_state(true);
yield(); /* TEMPLATES */
this->publish_state(false);
return true; template<typename T> class RemoteProtocol {
} public:
return false; virtual void encode(RemoteTransmitData *dst, const T &data) = 0;
} virtual optional<T> decode(RemoteReceiveData src) = 0;
virtual void dump(const T &data) = 0;
}; };
template<typename T, typename D> class RemoteReceiverBinarySensor : public RemoteReceiverBinarySensorBase { template<typename T, typename D> class RemoteReceiverBinarySensor : public RemoteReceiverBinarySensorBase {

View file

@ -48,7 +48,7 @@ class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase,
esp_err_t error_code_{ESP_OK}; esp_err_t error_code_{ESP_OK};
bool inverted_{false}; bool inverted_{false};
#endif #endif
uint8_t carrier_duty_percent_{50}; uint8_t carrier_duty_percent_;
}; };
} // namespace remote_transmitter } // namespace remote_transmitter

View file

@ -1,6 +1,7 @@
#include "sen5x.h" #include "sen5x.h"
#include "esphome/core/hal.h" #include "esphome/core/hal.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include <cinttypes>
namespace esphome { namespace esphome {
namespace sen5x { namespace sen5x {
@ -140,15 +141,15 @@ void SEN5XComponent::setup() {
this->pref_ = global_preferences->make_preference<Sen5xBaselines>(hash, true); this->pref_ = global_preferences->make_preference<Sen5xBaselines>(hash, true);
if (this->pref_.load(&this->voc_baselines_storage_)) { if (this->pref_.load(&this->voc_baselines_storage_)) {
ESP_LOGI(TAG, "Loaded VOC baseline state0: 0x%04X, state1: 0x%04X", this->voc_baselines_storage_.state0, ESP_LOGI(TAG, "Loaded VOC baseline state0: 0x%04" PRIX32 ", state1: 0x%04" PRIX32,
voc_baselines_storage_.state1); this->voc_baselines_storage_.state0, voc_baselines_storage_.state1);
} }
// Initialize storage timestamp // Initialize storage timestamp
this->seconds_since_last_store_ = 0; this->seconds_since_last_store_ = 0;
if (this->voc_baselines_storage_.state0 > 0 && this->voc_baselines_storage_.state1 > 0) { if (this->voc_baselines_storage_.state0 > 0 && this->voc_baselines_storage_.state1 > 0) {
ESP_LOGI(TAG, "Setting VOC baseline from save state0: 0x%04X, state1: 0x%04X", ESP_LOGI(TAG, "Setting VOC baseline from save state0: 0x%04" PRIX32 ", state1: 0x%04" PRIX32,
this->voc_baselines_storage_.state0, voc_baselines_storage_.state1); this->voc_baselines_storage_.state0, voc_baselines_storage_.state1);
uint16_t states[4]; uint16_t states[4];
@ -252,7 +253,7 @@ void SEN5XComponent::dump_config() {
ESP_LOGCONFIG(TAG, " Firmware version: %d", this->firmware_version_); ESP_LOGCONFIG(TAG, " Firmware version: %d", this->firmware_version_);
ESP_LOGCONFIG(TAG, " Serial number %02d.%02d.%02d", serial_number_[0], serial_number_[1], serial_number_[2]); ESP_LOGCONFIG(TAG, " Serial number %02d.%02d.%02d", serial_number_[0], serial_number_[1], serial_number_[2]);
if (this->auto_cleaning_interval_.has_value()) { if (this->auto_cleaning_interval_.has_value()) {
ESP_LOGCONFIG(TAG, " Auto cleaning interval %d seconds", auto_cleaning_interval_.value()); ESP_LOGCONFIG(TAG, " Auto cleaning interval %" PRId32 " seconds", auto_cleaning_interval_.value());
} }
if (this->acceleration_mode_.has_value()) { if (this->acceleration_mode_.has_value()) {
switch (this->acceleration_mode_.value()) { switch (this->acceleration_mode_.value()) {
@ -302,8 +303,8 @@ void SEN5XComponent::update() {
this->voc_baselines_storage_.state1 = state1; this->voc_baselines_storage_.state1 = state1;
if (this->pref_.save(&this->voc_baselines_storage_)) { if (this->pref_.save(&this->voc_baselines_storage_)) {
ESP_LOGI(TAG, "Stored VOC baseline state0: 0x%04X ,state1: 0x%04X", this->voc_baselines_storage_.state0, ESP_LOGI(TAG, "Stored VOC baseline state0: 0x%04" PRIX32 " ,state1: 0x%04" PRIX32,
voc_baselines_storage_.state1); this->voc_baselines_storage_.state0, voc_baselines_storage_.state1);
} else { } else {
ESP_LOGW(TAG, "Could not store VOC baselines"); ESP_LOGW(TAG, "Could not store VOC baselines");
} }

View file

@ -31,6 +31,9 @@ from esphome.const import (
CONF_MQTT_ID, CONF_MQTT_ID,
CONF_FORCE_UPDATE, CONF_FORCE_UPDATE,
CONF_VALUE, CONF_VALUE,
CONF_MIN_VALUE,
CONF_MAX_VALUE,
CONF_METHOD,
DEVICE_CLASS_APPARENT_POWER, DEVICE_CLASS_APPARENT_POWER,
DEVICE_CLASS_AQI, DEVICE_CLASS_AQI,
DEVICE_CLASS_ATMOSPHERIC_PRESSURE, DEVICE_CLASS_ATMOSPHERIC_PRESSURE,
@ -227,6 +230,7 @@ OrFilter = sensor_ns.class_("OrFilter", Filter)
CalibrateLinearFilter = sensor_ns.class_("CalibrateLinearFilter", Filter) CalibrateLinearFilter = sensor_ns.class_("CalibrateLinearFilter", Filter)
CalibratePolynomialFilter = sensor_ns.class_("CalibratePolynomialFilter", Filter) CalibratePolynomialFilter = sensor_ns.class_("CalibratePolynomialFilter", Filter)
SensorInRangeCondition = sensor_ns.class_("SensorInRangeCondition", Filter) SensorInRangeCondition = sensor_ns.class_("SensorInRangeCondition", Filter)
ClampFilter = sensor_ns.class_("ClampFilter", Filter)
validate_unit_of_measurement = cv.string_strict validate_unit_of_measurement = cv.string_strict
validate_accuracy_decimals = cv.int_ validate_accuracy_decimals = cv.int_
@ -557,8 +561,24 @@ async def debounce_filter_to_code(config, filter_id):
return var return var
def validate_not_all_from_same(config): CONF_DATAPOINTS = "datapoints"
if all(conf[CONF_FROM] == config[0][CONF_FROM] for conf in config):
def validate_calibrate_linear(config):
datapoints = config[CONF_DATAPOINTS]
if config[CONF_METHOD] == "exact":
for i in range(len(datapoints) - 1):
if datapoints[i][CONF_FROM] > datapoints[i + 1][CONF_FROM]:
raise cv.Invalid(
"The 'from' values of the calibrate_linear filter must be sorted in ascending order."
)
for i in range(len(datapoints) - 1):
if datapoints[i][CONF_FROM] == datapoints[i + 1][CONF_FROM]:
raise cv.Invalid(
"The 'from' values of the calibrate_linear filter must not contain duplicates."
)
elif config[CONF_METHOD] == "least_squares":
if all(conf[CONF_FROM] == datapoints[0][CONF_FROM] for conf in datapoints):
raise cv.Invalid( raise cv.Invalid(
"The 'from' values of the calibrate_linear filter cannot all point " "The 'from' values of the calibrate_linear filter cannot all point "
"to the same value! Please add more values to the filter." "to the same value! Please add more values to the filter."
@ -569,18 +589,32 @@ def validate_not_all_from_same(config):
@FILTER_REGISTRY.register( @FILTER_REGISTRY.register(
"calibrate_linear", "calibrate_linear",
CalibrateLinearFilter, CalibrateLinearFilter,
cv.All( cv.maybe_simple_value(
cv.ensure_list(validate_datapoint), cv.Length(min=2), validate_not_all_from_same {
cv.Required(CONF_DATAPOINTS): cv.All(
cv.ensure_list(validate_datapoint), cv.Length(min=2)
),
cv.Optional(CONF_METHOD, default="least_squares"): cv.one_of(
"least_squares", "exact", lower=True
),
},
validate_calibrate_linear,
key=CONF_DATAPOINTS,
), ),
) )
async def calibrate_linear_filter_to_code(config, filter_id): async def calibrate_linear_filter_to_code(config, filter_id):
x = [conf[CONF_FROM] for conf in config] x = [conf[CONF_FROM] for conf in config[CONF_DATAPOINTS]]
y = [conf[CONF_TO] for conf in config] y = [conf[CONF_TO] for conf in config[CONF_DATAPOINTS]]
linear_functions = []
if config[CONF_METHOD] == "least_squares":
k, b = fit_linear(x, y) k, b = fit_linear(x, y)
return cg.new_Pvariable(filter_id, k, b) linear_functions = [[k, b, float("NaN")]]
elif config[CONF_METHOD] == "exact":
linear_functions = map_linear(x, y)
return cg.new_Pvariable(filter_id, linear_functions)
CONF_DATAPOINTS = "datapoints"
CONF_DEGREE = "degree" CONF_DEGREE = "degree"
@ -619,6 +653,36 @@ async def calibrate_polynomial_filter_to_code(config, filter_id):
return cg.new_Pvariable(filter_id, res) return cg.new_Pvariable(filter_id, res)
def validate_clamp(config):
if not math.isfinite(config[CONF_MIN_VALUE]) and not math.isfinite(
config[CONF_MAX_VALUE]
):
raise cv.Invalid("Either 'min_value' or 'max_value' must be set to a number.")
if config[CONF_MIN_VALUE] > config[CONF_MAX_VALUE]:
raise cv.Invalid("The 'min_value' must not be larger than the 'max_value'.")
return config
CLAMP_SCHEMA = cv.All(
cv.Schema(
{
cv.Optional(CONF_MIN_VALUE, default="NaN"): cv.float_,
cv.Optional(CONF_MAX_VALUE, default="NaN"): cv.float_,
}
),
validate_clamp,
)
@FILTER_REGISTRY.register("clamp", ClampFilter, CLAMP_SCHEMA)
async def clamp_filter_to_code(config, filter_id):
return cg.new_Pvariable(
filter_id,
config[CONF_MIN_VALUE],
config[CONF_MAX_VALUE],
)
async def build_filters(config): async def build_filters(config):
return await cg.build_registry_list(FILTER_REGISTRY, config) return await cg.build_registry_list(FILTER_REGISTRY, config)
@ -730,6 +794,22 @@ def fit_linear(x, y):
return k, b return k, b
def map_linear(x, y):
assert len(x) == len(y)
f = []
for i in range(len(x) - 1):
slope = (y[i + 1] - y[i]) / (x[i + 1] - x[i])
bias = y[i] - (slope * x[i])
next_x = x[i + 1]
if i == len(x) - 2:
next_x = float("NaN")
if f and f[-1][0] == slope and f[-1][1] == bias:
f[-1][2] = next_x
else:
f.append([slope, bias, next_x])
return f
def _mat_copy(m): def _mat_copy(m):
return [list(row) for row in m] return [list(row) for row in m]

View file

@ -416,8 +416,13 @@ void HeartbeatFilter::setup() {
} }
float HeartbeatFilter::get_setup_priority() const { return setup_priority::HARDWARE; } float HeartbeatFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
optional<float> CalibrateLinearFilter::new_value(float value) { return value * this->slope_ + this->bias_; } optional<float> CalibrateLinearFilter::new_value(float value) {
CalibrateLinearFilter::CalibrateLinearFilter(float slope, float bias) : slope_(slope), bias_(bias) {} for (std::array<float, 3> f : this->linear_functions_) {
if (!std::isfinite(f[2]) || value < f[2])
return (value * f[0]) + f[1];
}
return NAN;
}
optional<float> CalibratePolynomialFilter::new_value(float value) { optional<float> CalibratePolynomialFilter::new_value(float value) {
float res = 0.0f; float res = 0.0f;
@ -429,5 +434,16 @@ optional<float> CalibratePolynomialFilter::new_value(float value) {
return res; return res;
} }
ClampFilter::ClampFilter(float min, float max) : min_(min), max_(max) {}
optional<float> ClampFilter::new_value(float value) {
if (std::isfinite(value)) {
if (std::isfinite(this->min_) && value < this->min_)
return this->min_;
if (std::isfinite(this->max_) && value > this->max_)
return this->max_;
}
return value;
}
} // namespace sensor } // namespace sensor
} // namespace esphome } // namespace esphome

View file

@ -390,12 +390,12 @@ class OrFilter : public Filter {
class CalibrateLinearFilter : public Filter { class CalibrateLinearFilter : public Filter {
public: public:
CalibrateLinearFilter(float slope, float bias); CalibrateLinearFilter(std::vector<std::array<float, 3>> linear_functions)
: linear_functions_(std::move(linear_functions)) {}
optional<float> new_value(float value) override; optional<float> new_value(float value) override;
protected: protected:
float slope_; std::vector<std::array<float, 3>> linear_functions_;
float bias_;
}; };
class CalibratePolynomialFilter : public Filter { class CalibratePolynomialFilter : public Filter {
@ -407,5 +407,15 @@ class CalibratePolynomialFilter : public Filter {
std::vector<float> coefficients_; std::vector<float> coefficients_;
}; };
class ClampFilter : public Filter {
public:
ClampFilter(float min, float max);
optional<float> new_value(float value) override;
protected:
float min_{NAN};
float max_{NAN};
};
} // namespace sensor } // namespace sensor
} // namespace esphome } // namespace esphome

View file

@ -17,32 +17,9 @@ enum SmlType : uint8_t {
enum SmlMessageType : uint16_t { SML_PUBLIC_OPEN_RES = 0x0101, SML_GET_LIST_RES = 0x701 }; enum SmlMessageType : uint16_t { SML_PUBLIC_OPEN_RES = 0x0101, SML_GET_LIST_RES = 0x701 };
enum Crc16CheckResult : uint8_t { CHECK_CRC16_FAILED, CHECK_CRC16_X25_SUCCESS, CHECK_CRC16_KERMIT_SUCCESS };
// masks with two-bit mapping 0x1b -> 0b01; 0x01 -> 0b10; 0x1a -> 0b11 // masks with two-bit mapping 0x1b -> 0b01; 0x01 -> 0b10; 0x1a -> 0b11
const uint16_t START_MASK = 0x55aa; // 0x1b 1b 1b 1b 1b 01 01 01 01 const uint16_t START_MASK = 0x55aa; // 0x1b 1b 1b 1b 1b 01 01 01 01
const uint16_t END_MASK = 0x0157; // 0x1b 1b 1b 1b 1a const uint16_t END_MASK = 0x0157; // 0x1b 1b 1b 1b 1a
const uint16_t CRC16_X25_TABLE[256] = {
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5,
0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52,
0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3,
0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9,
0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e,
0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f,
0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862,
0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb,
0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948,
0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226,
0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497,
0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704,
0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb,
0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c,
0x3de3, 0x2c6a, 0x1ef1, 0x0f78};
} // namespace sml } // namespace sml
} // namespace esphome } // namespace esphome

View file

@ -1,5 +1,6 @@
#include "sml.h" #include "sml.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include "esphome/core/helpers.h"
#include "sml_parser.h" #include "sml_parser.h"
namespace esphome { namespace esphome {
@ -99,12 +100,15 @@ bool check_sml_data(const bytes &buffer) {
} }
uint16_t crc_received = (buffer.at(buffer.size() - 2) << 8) | buffer.at(buffer.size() - 1); uint16_t crc_received = (buffer.at(buffer.size() - 2) << 8) | buffer.at(buffer.size() - 1);
if (crc_received == calc_crc16_x25(buffer.begin(), buffer.end() - 2, 0x6e23)) { uint16_t crc_calculated = crc16(buffer.data(), buffer.size(), 0x6e23, 0x8408, true, true);
crc_calculated = (crc_calculated >> 8) | (crc_calculated << 8);
if (crc_received == crc_calculated) {
ESP_LOGV(TAG, "Checksum verification successful with CRC16/X25."); ESP_LOGV(TAG, "Checksum verification successful with CRC16/X25.");
return true; return true;
} }
if (crc_received == calc_crc16_kermit(buffer.begin(), buffer.end() - 2, 0xed50)) { crc_calculated = crc16(buffer.data(), buffer.size(), 0xed50, 0x8408);
if (crc_received == crc_calculated) {
ESP_LOGV(TAG, "Checksum verification successful with CRC16/KERMIT."); ESP_LOGV(TAG, "Checksum verification successful with CRC16/KERMIT.");
return true; return true;
} }
@ -113,22 +117,6 @@ bool check_sml_data(const bytes &buffer) {
return false; return false;
} }
uint16_t calc_crc16_p1021(bytes::const_iterator begin, bytes::const_iterator end, uint16_t crcsum) {
for (auto it = begin; it != end; it++) {
crcsum = (crcsum >> 8) ^ CRC16_X25_TABLE[(crcsum & 0xff) ^ *it];
}
return crcsum;
}
uint16_t calc_crc16_x25(bytes::const_iterator begin, bytes::const_iterator end, uint16_t crcsum = 0) {
crcsum = calc_crc16_p1021(begin, end, crcsum ^ 0xffff) ^ 0xffff;
return (crcsum >> 8) | ((crcsum & 0xff) << 8);
}
uint16_t calc_crc16_kermit(bytes::const_iterator begin, bytes::const_iterator end, uint16_t crcsum = 0) {
return calc_crc16_p1021(begin, end, crcsum);
}
uint8_t get_code(uint8_t byte) { uint8_t get_code(uint8_t byte) {
switch (byte) { switch (byte) {
case 0x1b: case 0x1b:

View file

@ -38,9 +38,6 @@ class Sml : public Component, public uart::UARTDevice {
}; };
bool check_sml_data(const bytes &buffer); bool check_sml_data(const bytes &buffer);
uint16_t calc_crc16_p1021(bytes::const_iterator begin, bytes::const_iterator end, uint16_t crcsum);
uint16_t calc_crc16_x25(bytes::const_iterator begin, bytes::const_iterator end, uint16_t crcsum);
uint16_t calc_crc16_kermit(bytes::const_iterator begin, bytes::const_iterator end, uint16_t crcsum);
uint8_t get_code(uint8_t byte); uint8_t get_code(uint8_t byte);
} // namespace sml } // namespace sml

View file

@ -12,8 +12,8 @@ enum State : uint8_t {
class Speaker { class Speaker {
public: public:
virtual bool play(const uint8_t *data, size_t length) = 0; virtual size_t play(const uint8_t *data, size_t length) = 0;
virtual bool play(const std::vector<uint8_t> &data) { return this->play(data.data(), data.size()); } virtual size_t play(const std::vector<uint8_t> &data) { return this->play(data.data(), data.size()); }
virtual void stop() = 0; virtual void stop() = 0;

View file

@ -21,7 +21,6 @@ void SPISSD1322::setup() {
void SPISSD1322::dump_config() { void SPISSD1322::dump_config() {
LOG_DISPLAY("", "SPI SSD1322", this); LOG_DISPLAY("", "SPI SSD1322", this);
ESP_LOGCONFIG(TAG, " Model: %s", this->model_str_()); ESP_LOGCONFIG(TAG, " Model: %s", this->model_str_());
if (this->cs_)
LOG_PIN(" CS Pin: ", this->cs_); LOG_PIN(" CS Pin: ", this->cs_);
LOG_PIN(" DC Pin: ", this->dc_pin_); LOG_PIN(" DC Pin: ", this->dc_pin_);
LOG_PIN(" Reset Pin: ", this->reset_pin_); LOG_PIN(" Reset Pin: ", this->reset_pin_);

View file

@ -21,7 +21,6 @@ void SPISSD1325::setup() {
void SPISSD1325::dump_config() { void SPISSD1325::dump_config() {
LOG_DISPLAY("", "SPI SSD1325", this); LOG_DISPLAY("", "SPI SSD1325", this);
ESP_LOGCONFIG(TAG, " Model: %s", this->model_str_()); ESP_LOGCONFIG(TAG, " Model: %s", this->model_str_());
if (this->cs_)
LOG_PIN(" CS Pin: ", this->cs_); LOG_PIN(" CS Pin: ", this->cs_);
LOG_PIN(" DC Pin: ", this->dc_pin_); LOG_PIN(" DC Pin: ", this->dc_pin_);
LOG_PIN(" Reset Pin: ", this->reset_pin_); LOG_PIN(" Reset Pin: ", this->reset_pin_);

View file

@ -21,7 +21,6 @@ void SPISSD1327::setup() {
void SPISSD1327::dump_config() { void SPISSD1327::dump_config() {
LOG_DISPLAY("", "SPI SSD1327", this); LOG_DISPLAY("", "SPI SSD1327", this);
ESP_LOGCONFIG(TAG, " Model: %s", this->model_str_()); ESP_LOGCONFIG(TAG, " Model: %s", this->model_str_());
if (this->cs_)
LOG_PIN(" CS Pin: ", this->cs_); LOG_PIN(" CS Pin: ", this->cs_);
LOG_PIN(" DC Pin: ", this->dc_pin_); LOG_PIN(" DC Pin: ", this->dc_pin_);
LOG_PIN(" Reset Pin: ", this->reset_pin_); LOG_PIN(" Reset Pin: ", this->reset_pin_);

View file

@ -20,7 +20,6 @@ void SPISSD1331::setup() {
} }
void SPISSD1331::dump_config() { void SPISSD1331::dump_config() {
LOG_DISPLAY("", "SPI SSD1331", this); LOG_DISPLAY("", "SPI SSD1331", this);
if (this->cs_)
LOG_PIN(" CS Pin: ", this->cs_); LOG_PIN(" CS Pin: ", this->cs_);
LOG_PIN(" DC Pin: ", this->dc_pin_); LOG_PIN(" DC Pin: ", this->dc_pin_);
LOG_PIN(" Reset Pin: ", this->reset_pin_); LOG_PIN(" Reset Pin: ", this->reset_pin_);

Some files were not shown because too many files have changed in this diff Show more