1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-13 21:35:48 +00:00

Compare commits

..

11 Commits

Author SHA1 Message Date
Jesse Hills
71b28be3c8 Merge pull request #4822 from esphome/bump-2023.5.0b3
2023.5.0b3
2023-05-15 13:06:10 +12:00
Jesse Hills
e25d92e1f5 Bump version to 2023.5.0b3 2023-05-15 11:37:55 +12:00
Jesse Hills
65cda10884 Dontr try stop if not actually started (#4814) 2023-05-15 11:37:55 +12:00
Jesse Hills
625126df68 Fix i2s media player volume control (#4813) 2023-05-15 11:37:55 +12:00
richardhopton
e0ee8ca17c Tuya: Prevent loop when setting colors on case-sensitive dps (#4809)
Co-authored-by: Samuel Sieb <samuel-github@sieb.net>
2023-05-15 11:37:54 +12:00
Federico G. Schwindt
af95e781f5 Wording (#4805) 2023-05-15 11:37:54 +12:00
Jesse Hills
9b230a7d93 Merge pull request #4808 from esphome/bump-2023.5.0b2
2023.5.0b2
2023-05-12 11:02:45 +12:00
Jesse Hills
e2f3e7c3a6 Bump version to 2023.5.0b2 2023-05-12 10:32:59 +12:00
Alex Dekker
2fd2e5ceb2 Supposed to fix #4069, by changing the default value to 0s (timeunit instead of int) to pass validation (#4806)
Co-authored-by: Alex1602 <alex1602@gmail.com>
2023-05-12 10:32:59 +12:00
Jesse Hills
d88358be8e Remove AUTO_LOAD from apds9960 (#4746) 2023-05-12 10:32:59 +12:00
Jimmy Hedman
d80885c7a8 Fixed access point for ESP32 IDF platform (#4784) 2023-05-12 10:32:59 +12:00
13 changed files with 136 additions and 90 deletions

View File

@@ -4,7 +4,6 @@ from esphome.components import i2c
from esphome.const import CONF_ID
DEPENDENCIES = ["i2c"]
AUTO_LOAD = ["sensor", "binary_sensor"]
MULTI_CONF = True
CONF_APDS9960_ID = "apds9960_id"

View File

@@ -116,8 +116,12 @@ void APDS9960::setup() {
APDS9960_WRITE_BYTE(0x80, val);
}
bool APDS9960::is_color_enabled_() const {
return this->red_channel_ != nullptr || this->green_channel_ != nullptr || this->blue_channel_ != nullptr ||
this->clear_channel_ != nullptr;
#ifdef USE_SENSOR
return this->red_sensor_ != nullptr || this->green_sensor_ != nullptr || this->blue_sensor_ != nullptr ||
this->clear_sensor_ != nullptr;
#else
return false;
#endif
}
void APDS9960::dump_config() {
@@ -125,6 +129,15 @@ void APDS9960::dump_config() {
LOG_I2C_DEVICE(this);
LOG_UPDATE_INTERVAL(this);
#ifdef USE_SENSOR
LOG_SENSOR(" ", "Red channel", this->red_sensor_);
LOG_SENSOR(" ", "Green channel", this->green_sensor_);
LOG_SENSOR(" ", "Blue channel", this->blue_sensor_);
LOG_SENSOR(" ", "Clear channel", this->clear_sensor_);
LOG_SENSOR(" ", "Proximity", this->proximity_sensor_);
#endif
if (this->is_failed()) {
switch (this->error_code_) {
case COMMUNICATION_FAILED:
@@ -181,17 +194,22 @@ void APDS9960::read_color_data_(uint8_t status) {
float blue_perc = (uint_blue / float(UINT16_MAX)) * 100.0f;
ESP_LOGD(TAG, "Got clear=%.1f%% red=%.1f%% green=%.1f%% blue=%.1f%%", clear_perc, red_perc, green_perc, blue_perc);
if (this->clear_channel_ != nullptr)
this->clear_channel_->publish_state(clear_perc);
if (this->red_channel_ != nullptr)
this->red_channel_->publish_state(red_perc);
if (this->green_channel_ != nullptr)
this->green_channel_->publish_state(green_perc);
if (this->blue_channel_ != nullptr)
this->blue_channel_->publish_state(blue_perc);
#ifdef USE_SENSOR
if (this->clear_sensor_ != nullptr)
this->clear_sensor_->publish_state(clear_perc);
if (this->red_sensor_ != nullptr)
this->red_sensor_->publish_state(red_perc);
if (this->green_sensor_ != nullptr)
this->green_sensor_->publish_state(green_perc);
if (this->blue_sensor_ != nullptr)
this->blue_sensor_->publish_state(blue_perc);
#endif
}
void APDS9960::read_proximity_data_(uint8_t status) {
if (this->proximity_ == nullptr)
#ifndef USE_SENSOR
return;
#else
if (this->proximity_sensor_ == nullptr)
return;
if ((status & 0b10) == 0x00) {
@@ -204,7 +222,8 @@ void APDS9960::read_proximity_data_(uint8_t status) {
float prox_perc = (prox / float(UINT8_MAX)) * 100.0f;
ESP_LOGD(TAG, "Got proximity=%.1f%%", prox_perc);
this->proximity_->publish_state(prox_perc);
this->proximity_sensor_->publish_state(prox_perc);
#endif
}
void APDS9960::read_gesture_data_() {
if (!this->is_gesture_enabled_())
@@ -256,28 +275,29 @@ void APDS9960::read_gesture_data_() {
}
}
void APDS9960::report_gesture_(int gesture) {
#ifdef USE_BINARY_SENSOR
binary_sensor::BinarySensor *bin;
switch (gesture) {
case 1:
bin = this->up_direction_;
bin = this->up_direction_binary_sensor_;
this->gesture_up_started_ = false;
this->gesture_down_started_ = false;
ESP_LOGD(TAG, "Got gesture UP");
break;
case 2:
bin = this->down_direction_;
bin = this->down_direction_binary_sensor_;
this->gesture_up_started_ = false;
this->gesture_down_started_ = false;
ESP_LOGD(TAG, "Got gesture DOWN");
break;
case 3:
bin = this->left_direction_;
bin = this->left_direction_binary_sensor_;
this->gesture_left_started_ = false;
this->gesture_right_started_ = false;
ESP_LOGD(TAG, "Got gesture LEFT");
break;
case 4:
bin = this->right_direction_;
bin = this->right_direction_binary_sensor_;
this->gesture_left_started_ = false;
this->gesture_right_started_ = false;
ESP_LOGD(TAG, "Got gesture RIGHT");
@@ -290,6 +310,7 @@ void APDS9960::report_gesture_(int gesture) {
bin->publish_state(true);
bin->publish_state(false);
}
#endif
}
void APDS9960::process_dataset_(int up, int down, int left, int right) {
/* Algorithm: (see Figure 11 in datasheet)
@@ -365,10 +386,22 @@ void APDS9960::process_dataset_(int up, int down, int left, int right) {
}
}
float APDS9960::get_setup_priority() const { return setup_priority::DATA; }
bool APDS9960::is_proximity_enabled_() const { return this->proximity_ != nullptr || this->is_gesture_enabled_(); }
bool APDS9960::is_proximity_enabled_() const {
return
#ifdef USE_SENSOR
this->proximity_sensor_ != nullptr
#else
false
#endif
|| this->is_gesture_enabled_();
}
bool APDS9960::is_gesture_enabled_() const {
return this->up_direction_ != nullptr || this->left_direction_ != nullptr || this->down_direction_ != nullptr ||
this->right_direction_ != nullptr;
#ifdef USE_BINARY_SENSOR
return this->up_direction_binary_sensor_ != nullptr || this->left_direction_binary_sensor_ != nullptr ||
this->down_direction_binary_sensor_ != nullptr || this->right_direction_binary_sensor_ != nullptr;
#else
return false;
#endif
}
} // namespace apds9960

View File

@@ -1,14 +1,34 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/i2c/i2c.h"
#include "esphome/core/component.h"
#include "esphome/core/defines.h"
#ifdef USE_SENSOR
#include "esphome/components/sensor/sensor.h"
#endif
#ifdef USE_BINARY_SENSOR
#include "esphome/components/binary_sensor/binary_sensor.h"
#endif
namespace esphome {
namespace apds9960 {
class APDS9960 : public PollingComponent, public i2c::I2CDevice {
#ifdef USE_SENSOR
SUB_SENSOR(red)
SUB_SENSOR(green)
SUB_SENSOR(blue)
SUB_SENSOR(clear)
SUB_SENSOR(proximity)
#endif
#ifdef USE_BINARY_SENSOR
SUB_BINARY_SENSOR(up_direction)
SUB_BINARY_SENSOR(right_direction)
SUB_BINARY_SENSOR(down_direction)
SUB_BINARY_SENSOR(left_direction)
#endif
public:
void setup() override;
void dump_config() override;
@@ -23,16 +43,6 @@ class APDS9960 : public PollingComponent, public i2c::I2CDevice {
void set_gesture_gain(uint8_t gain) { this->gesture_gain_ = gain; }
void set_gesture_wait_time(uint8_t wait_time) { this->gesture_wait_time_ = wait_time; }
void set_red_channel(sensor::Sensor *red_channel) { red_channel_ = red_channel; }
void set_green_channel(sensor::Sensor *green_channel) { green_channel_ = green_channel; }
void set_blue_channel(sensor::Sensor *blue_channel) { blue_channel_ = blue_channel; }
void set_clear_channel(sensor::Sensor *clear_channel) { clear_channel_ = clear_channel; }
void set_up_direction(binary_sensor::BinarySensor *up_direction) { up_direction_ = up_direction; }
void set_right_direction(binary_sensor::BinarySensor *right_direction) { right_direction_ = right_direction; }
void set_down_direction(binary_sensor::BinarySensor *down_direction) { down_direction_ = down_direction; }
void set_left_direction(binary_sensor::BinarySensor *left_direction) { left_direction_ = left_direction; }
void set_proximity(sensor::Sensor *proximity) { proximity_ = proximity; }
protected:
bool is_color_enabled_() const;
bool is_proximity_enabled_() const;
@@ -50,15 +60,6 @@ class APDS9960 : public PollingComponent, public i2c::I2CDevice {
uint8_t gesture_gain_;
uint8_t gesture_wait_time_;
sensor::Sensor *red_channel_{nullptr};
sensor::Sensor *green_channel_{nullptr};
sensor::Sensor *blue_channel_{nullptr};
sensor::Sensor *clear_channel_{nullptr};
binary_sensor::BinarySensor *up_direction_{nullptr};
binary_sensor::BinarySensor *right_direction_{nullptr};
binary_sensor::BinarySensor *down_direction_{nullptr};
binary_sensor::BinarySensor *left_direction_{nullptr};
sensor::Sensor *proximity_{nullptr};
enum ErrorCode {
NONE = 0,
COMMUNICATION_FAILED,

View File

@@ -6,19 +6,14 @@ from . import APDS9960, CONF_APDS9960_ID
DEPENDENCIES = ["apds9960"]
DIRECTIONS = {
"UP": "set_up_direction",
"DOWN": "set_down_direction",
"LEFT": "set_left_direction",
"RIGHT": "set_right_direction",
}
DIRECTIONS = ["up", "down", "left", "right"]
CONFIG_SCHEMA = binary_sensor.binary_sensor_schema(
device_class=DEVICE_CLASS_MOVING
).extend(
{
cv.GenerateID(CONF_APDS9960_ID): cv.use_id(APDS9960),
cv.Required(CONF_DIRECTION): cv.one_of(*DIRECTIONS, upper=True),
cv.Required(CONF_DIRECTION): cv.one_of(*DIRECTIONS, lower=True),
}
)
@@ -26,5 +21,5 @@ CONFIG_SCHEMA = binary_sensor.binary_sensor_schema(
async def to_code(config):
hub = await cg.get_variable(config[CONF_APDS9960_ID])
var = await binary_sensor.new_binary_sensor(config)
func = getattr(hub, DIRECTIONS[config[CONF_DIRECTION]])
func = getattr(hub, f"set_{config[CONF_DIRECTION]}_direction_binary_sensor")
cg.add(func(var))

View File

@@ -11,13 +11,7 @@ from . import APDS9960, CONF_APDS9960_ID
DEPENDENCIES = ["apds9960"]
TYPES = {
"CLEAR": "set_clear_channel",
"RED": "set_red_channel",
"GREEN": "set_green_channel",
"BLUE": "set_blue_channel",
"PROXIMITY": "set_proximity",
}
TYPES = ["clear", "red", "green", "blue", "proximity"]
CONFIG_SCHEMA = sensor.sensor_schema(
unit_of_measurement=UNIT_PERCENT,
@@ -26,7 +20,7 @@ CONFIG_SCHEMA = sensor.sensor_schema(
state_class=STATE_CLASS_MEASUREMENT,
).extend(
{
cv.Required(CONF_TYPE): cv.one_of(*TYPES, upper=True),
cv.Required(CONF_TYPE): cv.one_of(*TYPES, lower=True),
cv.GenerateID(CONF_APDS9960_ID): cv.use_id(APDS9960),
}
)
@@ -35,5 +29,5 @@ CONFIG_SCHEMA = sensor.sensor_schema(
async def to_code(config):
hub = await cg.get_variable(config[CONF_APDS9960_ID])
var = await sensor.new_sensor(config)
func = getattr(hub, TYPES[config[CONF_TYPE]])
func = getattr(hub, f"set_{config[CONF_TYPE]}_sensor")
cg.add(func(var))

View File

@@ -22,14 +22,14 @@ void I2SAudioMediaPlayer::control(const media_player::MediaPlayerCall &call) {
this->start();
}
}
if (this->i2s_state_ != I2S_STATE_RUNNING) {
return;
}
if (call.get_volume().has_value()) {
this->volume = call.get_volume().value();
this->set_volume_(volume);
this->unmute_();
}
if (this->i2s_state_ != I2S_STATE_RUNNING) {
return;
}
if (call.get_command().has_value()) {
switch (call.get_command().value()) {
case media_player::MEDIA_PLAYER_COMMAND_PLAY:
@@ -97,7 +97,8 @@ void I2SAudioMediaPlayer::unmute_() {
this->muted_ = false;
}
void I2SAudioMediaPlayer::set_volume_(float volume, bool publish) {
this->audio_->setVolume(remap<uint8_t, float>(volume, 0.0f, 1.0f, 0, 21));
if (this->audio_ != nullptr)
this->audio_->setVolume(remap<uint8_t, float>(volume, 0.0f, 1.0f, 0, 21));
if (publish)
this->volume = volume;
}
@@ -157,13 +158,23 @@ void I2SAudioMediaPlayer::start_() {
#endif
this->i2s_state_ = I2S_STATE_RUNNING;
this->high_freq_.start();
this->audio_->setVolume(remap<uint8_t, float>(this->volume, 0.0f, 1.0f, 0, 21));
if (this->current_url_.has_value()) {
this->audio_->connecttohost(this->current_url_.value().c_str());
this->state = media_player::MEDIA_PLAYER_STATE_PLAYING;
this->publish_state();
}
}
void I2SAudioMediaPlayer::stop() { this->i2s_state_ = I2S_STATE_STOPPING; }
void I2SAudioMediaPlayer::stop() {
if (this->i2s_state_ == I2S_STATE_STOPPED) {
return;
}
if (this->i2s_state_ == I2S_STATE_STARTING) {
this->i2s_state_ = I2S_STATE_STOPPED;
return;
}
this->i2s_state_ = I2S_STATE_STOPPING;
}
void I2SAudioMediaPlayer::stop_() {
if (this->audio_->isRunning()) {
this->audio_->stopSong();

View File

@@ -89,6 +89,10 @@ void I2SAudioMicrophone::start_() {
void I2SAudioMicrophone::stop() {
if (this->state_ == microphone::STATE_STOPPED || this->is_failed())
return;
if (this->state_ == microphone::STATE_STARTING) {
this->state_ = microphone::STATE_STOPPED;
return;
}
this->state_ = microphone::STATE_STOPPING;
}

View File

@@ -136,6 +136,10 @@ void I2SAudioSpeaker::player_task(void *params) {
void I2SAudioSpeaker::stop() {
if (this->state_ == speaker::STATE_STOPPED)
return;
if (this->state_ == speaker::STATE_STARTING) {
this->state_ = speaker::STATE_STOPPED;
return;
}
this->state_ = speaker::STATE_STOPPING;
DataEvent data;
data.stop = true;

View File

@@ -252,7 +252,7 @@ void SEN5XComponent::dump_config() {
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]);
if (this->auto_cleaning_interval_.has_value()) {
ESP_LOGCONFIG(TAG, " Auto auto cleaning interval %d seconds", auto_cleaning_interval_.value());
ESP_LOGCONFIG(TAG, " Auto cleaning interval %d seconds", auto_cleaning_interval_.value());
}
if (this->acceleration_mode_.has_value()) {
switch (this->acceleration_mode_.value()) {

View File

@@ -275,7 +275,7 @@ SPRINKLER_ACTION_SET_RUN_DURATION_SCHEMA = cv.Schema(
SPRINKLER_ACTION_QUEUE_VALVE_SCHEMA = cv.Schema(
{
cv.Required(CONF_ID): cv.use_id(Sprinkler),
cv.Optional(CONF_RUN_DURATION, default=0): cv.templatable(
cv.Optional(CONF_RUN_DURATION, default="0s"): cv.templatable(
cv.positive_time_period_seconds
),
cv.Required(CONF_VALVE_NUMBER): cv.templatable(cv.positive_int),

View File

@@ -57,37 +57,43 @@ void TuyaLight::setup() {
return;
}
float red, green, blue;
switch (*this->color_type_) {
case TuyaColorType::RGBHSV:
case TuyaColorType::RGB: {
auto red = parse_hex<uint8_t>(datapoint.value_string.substr(0, 2));
auto green = parse_hex<uint8_t>(datapoint.value_string.substr(2, 2));
auto blue = parse_hex<uint8_t>(datapoint.value_string.substr(4, 2));
if (red.has_value() && green.has_value() && blue.has_value()) {
auto rgb_call = this->state_->make_call();
rgb_call.set_rgb(float(*red) / 255, float(*green) / 255, float(*blue) / 255);
rgb_call.perform();
}
auto rgb = parse_hex<uint32_t>(datapoint.value_string.substr(0, 6));
if (!rgb.has_value())
return;
red = (*rgb >> 16) / 255.0f;
green = ((*rgb >> 8) & 0xff) / 255.0f;
blue = (*rgb & 0xff) / 255.0f;
break;
}
case TuyaColorType::HSV: {
auto hue = parse_hex<uint16_t>(datapoint.value_string.substr(0, 4));
auto saturation = parse_hex<uint16_t>(datapoint.value_string.substr(4, 4));
auto value = parse_hex<uint16_t>(datapoint.value_string.substr(8, 4));
if (hue.has_value() && saturation.has_value() && value.has_value()) {
float red, green, blue;
hsv_to_rgb(*hue, float(*saturation) / 1000, float(*value) / 1000, red, green, blue);
auto rgb_call = this->state_->make_call();
rgb_call.set_rgb(red, green, blue);
rgb_call.perform();
}
if (!hue.has_value() || !saturation.has_value() || !value.has_value())
return;
hsv_to_rgb(*hue, float(*saturation) / 1000, float(*value) / 1000, red, green, blue);
break;
}
}
float current_red, current_green, current_blue;
this->state_->current_values_as_rgb(&current_red, &current_green, &current_blue);
if (red == current_red && green == current_green && blue == current_blue)
return;
auto rgb_call = this->state_->make_call();
rgb_call.set_rgb(red, green, blue);
rgb_call.perform();
});
}
if (min_value_datapoint_id_.has_value()) {
parent_->set_integer_datapoint_value(*this->min_value_datapoint_id_, this->min_value_);
this->parent_->set_integer_datapoint_value(*this->min_value_datapoint_id_, this->min_value_);
}
}
@@ -156,7 +162,7 @@ void TuyaLight::write_state(light::LightState *state) {
}
if (!state->current_values.is_on() && this->switch_id_.has_value()) {
parent_->set_boolean_datapoint_value(*this->switch_id_, false);
this->parent_->set_boolean_datapoint_value(*this->switch_id_, false);
return;
}
@@ -166,14 +172,14 @@ void TuyaLight::write_state(light::LightState *state) {
if (this->color_temperature_invert_) {
color_temp_int = this->color_temperature_max_value_ - color_temp_int;
}
parent_->set_integer_datapoint_value(*this->color_temperature_id_, color_temp_int);
this->parent_->set_integer_datapoint_value(*this->color_temperature_id_, color_temp_int);
}
if (this->dimmer_id_.has_value()) {
auto brightness_int = static_cast<uint32_t>(brightness * this->max_value_);
brightness_int = std::max(brightness_int, this->min_value_);
parent_->set_integer_datapoint_value(*this->dimmer_id_, brightness_int);
this->parent_->set_integer_datapoint_value(*this->dimmer_id_, brightness_int);
}
}
@@ -210,7 +216,7 @@ void TuyaLight::write_state(light::LightState *state) {
}
if (this->switch_id_.has_value()) {
parent_->set_boolean_datapoint_value(*this->switch_id_, true);
this->parent_->set_boolean_datapoint_value(*this->switch_id_, true);
}
}

View File

@@ -767,11 +767,10 @@ bool WiFiComponent::wifi_ap_ip_config_(optional<ManualIP> manual_ip) {
info.gw.addr = static_cast<uint32_t>(network::IPAddress(192, 168, 4, 1));
info.netmask.addr = static_cast<uint32_t>(network::IPAddress(255, 255, 255, 0));
}
esp_netif_dhcp_status_t dhcp_status;
esp_netif_dhcps_get_status(s_sta_netif, &dhcp_status);
err = esp_netif_dhcps_stop(s_sta_netif);
if (err != ESP_OK) {
ESP_LOGV(TAG, "esp_netif_dhcps_stop failed! %d", err);
err = esp_netif_dhcpc_stop(s_sta_netif);
if (err != ESP_OK && err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED) {
ESP_LOGV(TAG, "esp_netif_dhcpc_stop failed: %s", esp_err_to_name(err));
return false;
}

View File

@@ -1,6 +1,6 @@
"""Constants used by esphome."""
__version__ = "2023.5.0b1"
__version__ = "2023.5.0b3"
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"