mirror of
https://github.com/esphome/esphome.git
synced 2024-11-10 09:17:46 +01:00
commit
0d800958aa
9 changed files with 79 additions and 19 deletions
|
@ -39,10 +39,14 @@ void BP5758D::loop() {
|
||||||
uint8_t data[17];
|
uint8_t data[17];
|
||||||
if (this->pwm_amounts_[0] == 0 && this->pwm_amounts_[1] == 0 && this->pwm_amounts_[2] == 0 &&
|
if (this->pwm_amounts_[0] == 0 && this->pwm_amounts_[1] == 0 && this->pwm_amounts_[2] == 0 &&
|
||||||
this->pwm_amounts_[3] == 0 && this->pwm_amounts_[4] == 0) {
|
this->pwm_amounts_[3] == 0 && this->pwm_amounts_[4] == 0) {
|
||||||
// Off / Sleep
|
|
||||||
data[0] = BP5758D_MODEL_ID + BP5758D_ADDR_STANDBY;
|
|
||||||
for (int i = 1; i < 16; i++)
|
for (int i = 1; i < 16; i++)
|
||||||
data[i] = 0;
|
data[i] = 0;
|
||||||
|
|
||||||
|
// First turn all channels off
|
||||||
|
data[0] = BP5758D_MODEL_ID + BP5758D_ADDR_START_3CH;
|
||||||
|
this->write_buffer_(data, 17);
|
||||||
|
// Then sleep
|
||||||
|
data[0] = BP5758D_MODEL_ID + BP5758D_ADDR_STANDBY;
|
||||||
this->write_buffer_(data, 17);
|
this->write_buffer_(data, 17);
|
||||||
} else if (this->pwm_amounts_[0] == 0 && this->pwm_amounts_[1] == 0 && this->pwm_amounts_[2] == 0 &&
|
} else if (this->pwm_amounts_[0] == 0 && this->pwm_amounts_[1] == 0 && this->pwm_amounts_[2] == 0 &&
|
||||||
(this->pwm_amounts_[3] > 0 || this->pwm_amounts_[4] > 0)) {
|
(this->pwm_amounts_[3] > 0 || this->pwm_amounts_[4] > 0)) {
|
||||||
|
|
|
@ -235,6 +235,7 @@ ESP32_BOARD_PINS = {
|
||||||
"SDA": 5,
|
"SDA": 5,
|
||||||
"SS": 15,
|
"SS": 15,
|
||||||
},
|
},
|
||||||
|
"denky_d4": {"RX": 8, "LED": 14},
|
||||||
"esp-wrover-kit": {},
|
"esp-wrover-kit": {},
|
||||||
"esp32-devkitlipo": {},
|
"esp32-devkitlipo": {},
|
||||||
"esp32-evb": {
|
"esp32-evb": {
|
||||||
|
|
|
@ -54,6 +54,21 @@ CONF_FORCE_SW = "force_sw"
|
||||||
CONF_INTERFACE = "interface"
|
CONF_INTERFACE = "interface"
|
||||||
CONF_INTERFACE_INDEX = "interface_index"
|
CONF_INTERFACE_INDEX = "interface_index"
|
||||||
|
|
||||||
|
# RP2040 SPI pin assignments are complicated. Refer to https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf
|
||||||
|
|
||||||
|
RP_SPI_PINSETS = [
|
||||||
|
{
|
||||||
|
CONF_MISO_PIN: [0, 4, 16, 20, -1],
|
||||||
|
CONF_CLK_PIN: [2, 6, 18, 22],
|
||||||
|
CONF_MOSI_PIN: [3, 7, 19, 23, -1],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_MISO_PIN: [8, 12, 24, 28, -1],
|
||||||
|
CONF_CLK_PIN: [10, 14, 26],
|
||||||
|
CONF_MOSI_PIN: [11, 23, 27, -1],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def get_target_platform():
|
def get_target_platform():
|
||||||
return (
|
return (
|
||||||
|
@ -85,7 +100,7 @@ def get_hw_interface_list():
|
||||||
return [["spi", "spi2"]]
|
return [["spi", "spi2"]]
|
||||||
return [["spi", "spi2"], ["spi3"]]
|
return [["spi", "spi2"], ["spi3"]]
|
||||||
if target_platform == "rp2040":
|
if target_platform == "rp2040":
|
||||||
return [["spi"]]
|
return [["spi"], ["spi1"]]
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,8 +114,10 @@ def get_spi_index(name):
|
||||||
|
|
||||||
|
|
||||||
# Check that pins are suitable for HW spi
|
# Check that pins are suitable for HW spi
|
||||||
|
# \param spi the config data for the spi instance
|
||||||
|
# \param index the selected hw interface number, -1 if not yet known
|
||||||
# TODO verify that the pins are internal
|
# TODO verify that the pins are internal
|
||||||
def validate_hw_pins(spi):
|
def validate_hw_pins(spi, index=-1):
|
||||||
clk_pin = spi[CONF_CLK_PIN]
|
clk_pin = spi[CONF_CLK_PIN]
|
||||||
if clk_pin[CONF_INVERTED]:
|
if clk_pin[CONF_INVERTED]:
|
||||||
return False
|
return False
|
||||||
|
@ -129,7 +146,28 @@ def validate_hw_pins(spi):
|
||||||
if target_platform == "esp32":
|
if target_platform == "esp32":
|
||||||
return clk_pin_no >= 0
|
return clk_pin_no >= 0
|
||||||
|
|
||||||
|
if target_platform == "rp2040":
|
||||||
|
pin_set = (
|
||||||
|
list(filter(lambda s: clk_pin_no in s[CONF_CLK_PIN], RP_SPI_PINSETS))[0]
|
||||||
|
if index == -1
|
||||||
|
else RP_SPI_PINSETS[index]
|
||||||
|
)
|
||||||
|
if pin_set is None:
|
||||||
return False
|
return False
|
||||||
|
if sdo_pin_no not in pin_set[CONF_MOSI_PIN]:
|
||||||
|
return False
|
||||||
|
if sdi_pin_no not in pin_set[CONF_MISO_PIN]:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def get_hw_spi(config, available):
|
||||||
|
"""Get an available hardware spi interface suitable for this config"""
|
||||||
|
matching = list(filter(lambda idx: validate_hw_pins(config, idx), available))
|
||||||
|
if len(matching) != 0:
|
||||||
|
return matching[0]
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def validate_spi_config(config):
|
def validate_spi_config(config):
|
||||||
|
@ -147,9 +185,10 @@ def validate_spi_config(config):
|
||||||
if not validate_hw_pins(spi):
|
if not validate_hw_pins(spi):
|
||||||
spi[CONF_INTERFACE] = "software"
|
spi[CONF_INTERFACE] = "software"
|
||||||
elif interface == "hardware":
|
elif interface == "hardware":
|
||||||
if len(available) == 0:
|
index = get_hw_spi(spi, available)
|
||||||
raise cv.Invalid("No hardware interface available")
|
if index is None:
|
||||||
index = spi[CONF_INTERFACE_INDEX] = available[0]
|
raise cv.Invalid("No suitable hardware interface available")
|
||||||
|
spi[CONF_INTERFACE_INDEX] = index
|
||||||
available.remove(index)
|
available.remove(index)
|
||||||
else:
|
else:
|
||||||
# Must be a specific name
|
# Must be a specific name
|
||||||
|
@ -164,11 +203,14 @@ def validate_spi_config(config):
|
||||||
# Any specific names and any 'hardware' requests will have already been filled,
|
# Any specific names and any 'hardware' requests will have already been filled,
|
||||||
# so just need to assign remaining hardware to 'any' requests.
|
# so just need to assign remaining hardware to 'any' requests.
|
||||||
for spi in config:
|
for spi in config:
|
||||||
if spi[CONF_INTERFACE] == "any" and len(available) != 0:
|
if spi[CONF_INTERFACE] == "any":
|
||||||
index = available[0]
|
index = get_hw_spi(spi, available)
|
||||||
|
if index is not None:
|
||||||
spi[CONF_INTERFACE_INDEX] = index
|
spi[CONF_INTERFACE_INDEX] = index
|
||||||
available.remove(index)
|
available.remove(index)
|
||||||
if CONF_INTERFACE_INDEX in spi and not validate_hw_pins(spi):
|
if CONF_INTERFACE_INDEX in spi and not validate_hw_pins(
|
||||||
|
spi, spi[CONF_INTERFACE_INDEX]
|
||||||
|
):
|
||||||
raise cv.Invalid("Invalid pin selections for hardware SPI interface")
|
raise cv.Invalid("Invalid pin selections for hardware SPI interface")
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
@ -181,7 +223,7 @@ def get_spi_interface(index):
|
||||||
# Arduino code follows
|
# Arduino code follows
|
||||||
platform = get_target_platform()
|
platform = get_target_platform()
|
||||||
if platform == "rp2040":
|
if platform == "rp2040":
|
||||||
return "&spi1"
|
return ["&SPI", "&SPI1"][index]
|
||||||
if index == 0:
|
if index == 0:
|
||||||
return "&SPI"
|
return "&SPI"
|
||||||
# Following code can't apply to C2, H2 or 8266 since they have only one SPI
|
# Following code can't apply to C2, H2 or 8266 since they have only one SPI
|
||||||
|
|
|
@ -6,6 +6,7 @@ from esphome.const import (
|
||||||
CONF_NUMBER_DATAPOINT,
|
CONF_NUMBER_DATAPOINT,
|
||||||
CONF_MAX_VALUE,
|
CONF_MAX_VALUE,
|
||||||
CONF_MIN_VALUE,
|
CONF_MIN_VALUE,
|
||||||
|
CONF_MULTIPLY,
|
||||||
CONF_STEP,
|
CONF_STEP,
|
||||||
)
|
)
|
||||||
from .. import tuya_ns, CONF_TUYA_ID, Tuya
|
from .. import tuya_ns, CONF_TUYA_ID, Tuya
|
||||||
|
@ -31,6 +32,7 @@ CONFIG_SCHEMA = cv.All(
|
||||||
cv.Required(CONF_MAX_VALUE): cv.float_,
|
cv.Required(CONF_MAX_VALUE): cv.float_,
|
||||||
cv.Required(CONF_MIN_VALUE): cv.float_,
|
cv.Required(CONF_MIN_VALUE): cv.float_,
|
||||||
cv.Required(CONF_STEP): cv.positive_float,
|
cv.Required(CONF_STEP): cv.positive_float,
|
||||||
|
cv.Optional(CONF_MULTIPLY, default=1.0): cv.float_,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.extend(cv.COMPONENT_SCHEMA),
|
.extend(cv.COMPONENT_SCHEMA),
|
||||||
|
@ -49,7 +51,8 @@ async def to_code(config):
|
||||||
step=config[CONF_STEP],
|
step=config[CONF_STEP],
|
||||||
)
|
)
|
||||||
|
|
||||||
paren = await cg.get_variable(config[CONF_TUYA_ID])
|
cg.add(var.set_write_multiply(config[CONF_MULTIPLY]))
|
||||||
cg.add(var.set_tuya_parent(paren))
|
parent = await cg.get_variable(config[CONF_TUYA_ID])
|
||||||
|
cg.add(var.set_tuya_parent(parent))
|
||||||
|
|
||||||
cg.add(var.set_number_id(config[CONF_NUMBER_DATAPOINT]))
|
cg.add(var.set_number_id(config[CONF_NUMBER_DATAPOINT]))
|
||||||
|
|
|
@ -10,7 +10,7 @@ void TuyaNumber::setup() {
|
||||||
this->parent_->register_listener(this->number_id_, [this](const TuyaDatapoint &datapoint) {
|
this->parent_->register_listener(this->number_id_, [this](const TuyaDatapoint &datapoint) {
|
||||||
if (datapoint.type == TuyaDatapointType::INTEGER) {
|
if (datapoint.type == TuyaDatapointType::INTEGER) {
|
||||||
ESP_LOGV(TAG, "MCU reported number %u is: %d", datapoint.id, datapoint.value_int);
|
ESP_LOGV(TAG, "MCU reported number %u is: %d", datapoint.id, datapoint.value_int);
|
||||||
this->publish_state(datapoint.value_int * this->traits.get_step());
|
this->publish_state(datapoint.value_int / multiply_by_);
|
||||||
} else if (datapoint.type == TuyaDatapointType::ENUM) {
|
} else if (datapoint.type == TuyaDatapointType::ENUM) {
|
||||||
ESP_LOGV(TAG, "MCU reported number %u is: %u", datapoint.id, datapoint.value_enum);
|
ESP_LOGV(TAG, "MCU reported number %u is: %u", datapoint.id, datapoint.value_enum);
|
||||||
this->publish_state(datapoint.value_enum);
|
this->publish_state(datapoint.value_enum);
|
||||||
|
@ -22,7 +22,7 @@ void TuyaNumber::setup() {
|
||||||
void TuyaNumber::control(float value) {
|
void TuyaNumber::control(float value) {
|
||||||
ESP_LOGV(TAG, "Setting number %u: %f", this->number_id_, value);
|
ESP_LOGV(TAG, "Setting number %u: %f", this->number_id_, value);
|
||||||
if (this->type_ == TuyaDatapointType::INTEGER) {
|
if (this->type_ == TuyaDatapointType::INTEGER) {
|
||||||
int integer_value = lround(value / this->traits.get_step());
|
int integer_value = lround(value * multiply_by_);
|
||||||
this->parent_->set_integer_datapoint_value(this->number_id_, integer_value);
|
this->parent_->set_integer_datapoint_value(this->number_id_, integer_value);
|
||||||
} else if (this->type_ == TuyaDatapointType::ENUM) {
|
} else if (this->type_ == TuyaDatapointType::ENUM) {
|
||||||
this->parent_->set_enum_datapoint_value(this->number_id_, value);
|
this->parent_->set_enum_datapoint_value(this->number_id_, value);
|
||||||
|
|
|
@ -12,6 +12,7 @@ class TuyaNumber : public number::Number, public Component {
|
||||||
void setup() override;
|
void setup() override;
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
void set_number_id(uint8_t number_id) { this->number_id_ = number_id; }
|
void set_number_id(uint8_t number_id) { this->number_id_ = number_id; }
|
||||||
|
void set_write_multiply(float factor) { multiply_by_ = factor; }
|
||||||
|
|
||||||
void set_tuya_parent(Tuya *parent) { this->parent_ = parent; }
|
void set_tuya_parent(Tuya *parent) { this->parent_ = parent; }
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@ class TuyaNumber : public number::Number, public Component {
|
||||||
|
|
||||||
Tuya *parent_;
|
Tuya *parent_;
|
||||||
uint8_t number_id_{0};
|
uint8_t number_id_{0};
|
||||||
|
float multiply_by_{1.0};
|
||||||
TuyaDatapointType type_{};
|
TuyaDatapointType type_{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"""Constants used by esphome."""
|
"""Constants used by esphome."""
|
||||||
|
|
||||||
__version__ = "2023.9.2"
|
__version__ = "2023.9.3"
|
||||||
|
|
||||||
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||||
VALID_SUBSTITUTIONS_CHARACTERS = (
|
VALID_SUBSTITUTIONS_CHARACTERS = (
|
||||||
|
|
|
@ -11,7 +11,7 @@ esptool==4.6.2
|
||||||
click==8.1.7
|
click==8.1.7
|
||||||
esphome-dashboard==20230904.0
|
esphome-dashboard==20230904.0
|
||||||
aioesphomeapi==15.0.0
|
aioesphomeapi==15.0.0
|
||||||
zeroconf==0.112.0
|
zeroconf==0.115.1
|
||||||
|
|
||||||
# esp-idf requires this, but doesn't bundle it by default
|
# esp-idf requires this, but doesn't bundle it by default
|
||||||
# https://github.com/espressif/esp-idf/blob/220590d599e134d7a5e7f1e683cc4550349ffbf8/requirements.txt#L24
|
# https://github.com/espressif/esp-idf/blob/220590d599e134d7a5e7f1e683cc4550349ffbf8/requirements.txt#L24
|
||||||
|
|
|
@ -39,6 +39,14 @@ switch:
|
||||||
output: pin_4
|
output: pin_4
|
||||||
id: pin_4_switch
|
id: pin_4_switch
|
||||||
|
|
||||||
|
|
||||||
|
spi: # Pins are for SPI1 on the RP2040 Pico-W
|
||||||
|
miso_pin: 8
|
||||||
|
clk_pin: 10
|
||||||
|
mosi_pin: 11
|
||||||
|
id: spi_0
|
||||||
|
interface: hardware
|
||||||
|
|
||||||
#light:
|
#light:
|
||||||
# - platform: rp2040_pio_led_strip
|
# - platform: rp2040_pio_led_strip
|
||||||
# id: led_strip
|
# id: led_strip
|
||||||
|
|
Loading…
Reference in a new issue