diff --git a/esphome/components/dallas_temp/dallas_temp.cpp b/esphome/components/dallas_temp/dallas_temp.cpp index a518c96489..a3969e081e 100644 --- a/esphome/components/dallas_temp/dallas_temp.cpp +++ b/esphome/components/dallas_temp/dallas_temp.cpp @@ -70,7 +70,7 @@ bool DallasTemperatureSensor::read_scratch_pad_() { } void DallasTemperatureSensor::setup() { - if (!this->check_address_()) + if (!this->check_address_or_index_()) return; if (!this->read_scratch_pad_()) return; diff --git a/esphome/components/one_wire/__init__.py b/esphome/components/one_wire/__init__.py index 6d95b8fd33..e12cca3e27 100644 --- a/esphome/components/one_wire/__init__.py +++ b/esphome/components/one_wire/__init__.py @@ -1,6 +1,6 @@ import esphome.codegen as cg import esphome.config_validation as cv -from esphome.const import CONF_ADDRESS +from esphome.const import CONF_ADDRESS, CONF_INDEX CODEOWNERS = ["@ssieb"] @@ -21,7 +21,8 @@ def one_wire_device_schema(): return cv.Schema( { cv.GenerateID(CONF_ONE_WIRE_ID): cv.use_id(OneWireBus), - cv.Optional(CONF_ADDRESS): cv.hex_uint64_t, + cv.Exclusive(CONF_ADDRESS, "index_or_address"): cv.hex_uint64_t, + cv.Exclusive(CONF_INDEX, "index_or_address"): cv.uint8_t, } ) @@ -37,3 +38,5 @@ async def register_one_wire_device(var, config): cg.add(var.set_one_wire_bus(parent)) if (address := config.get(CONF_ADDRESS)) is not None: cg.add(var.set_address(address)) + if (index := config.get(CONF_INDEX)) is not None: + cg.add(var.set_index(index)) diff --git a/esphome/components/one_wire/one_wire.cpp b/esphome/components/one_wire/one_wire.cpp index 96e6145f63..fd139d0ddc 100644 --- a/esphome/components/one_wire/one_wire.cpp +++ b/esphome/components/one_wire/one_wire.cpp @@ -18,10 +18,20 @@ bool OneWireDevice::send_command_(uint8_t cmd) { return true; } -bool OneWireDevice::check_address_() { +bool OneWireDevice::check_address_or_index_() { if (this->address_ != 0) return true; auto devices = this->bus_->get_devices(); + + if (this->index_ != INDEX_NOT_SET) { + if (this->index_ >= devices.size()) { + ESP_LOGE(TAG, "Index %d out of range, only %d devices found", this->index_, devices.size()); + return false; + } + this->address_ = devices[this->index_]; + return true; + } + if (devices.empty()) { ESP_LOGE(TAG, "No devices, can't auto-select address"); return false; diff --git a/esphome/components/one_wire/one_wire.h b/esphome/components/one_wire/one_wire.h index e83c6e81e8..f6a956a92c 100644 --- a/esphome/components/one_wire/one_wire.h +++ b/esphome/components/one_wire/one_wire.h @@ -17,6 +17,8 @@ class OneWireDevice { /// @param address of the device void set_address(uint64_t address) { this->address_ = address; } + void set_index(uint8_t index) { this->index_ = index; } + /// @brief store the pointer to the OneWireBus to use /// @param bus pointer to the OneWireBus object void set_one_wire_bus(OneWireBus *bus) { this->bus_ = bus; } @@ -25,13 +27,16 @@ class OneWireDevice { const std::string &get_address_name(); protected: + static constexpr uint8_t INDEX_NOT_SET = 255; + uint64_t address_{0}; + uint8_t index_{INDEX_NOT_SET}; OneWireBus *bus_{nullptr}; ///< pointer to OneWireBus instance std::string address_name_; /// @brief find an address if necessary /// should be called from setup - bool check_address_(); + bool check_address_or_index_(); /// @brief send command on the bus /// @param cmd command to send diff --git a/tests/components/dallas_temp/common.yaml b/tests/components/dallas_temp/common.yaml index 6d865d8e93..abd8e0cfa3 100644 --- a/tests/components/dallas_temp/common.yaml +++ b/tests/components/dallas_temp/common.yaml @@ -9,3 +9,6 @@ sensor: resolution: 9 - platform: dallas_temp name: Dallas Temperature 2 + - platform: dallas_temp + name: Dallas Temperature 3 + index: 2