7 static const char *
const TAG =
"dallas.sensor";
9 static const uint8_t DALLAS_MODEL_DS18S20 = 0x10;
10 static const uint8_t DALLAS_MODEL_DS1822 = 0x22;
11 static const uint8_t DALLAS_MODEL_DS18B20 = 0x28;
12 static const uint8_t DALLAS_MODEL_DS1825 = 0x3B;
13 static const uint8_t DALLAS_MODEL_DS28EA00 = 0x42;
14 static const uint8_t DALLAS_COMMAND_START_CONVERSION = 0x44;
15 static const uint8_t DALLAS_COMMAND_READ_SCRATCH_PAD = 0xBE;
16 static const uint8_t DALLAS_COMMAND_WRITE_SCRATCH_PAD = 0x4E;
32 ESP_LOGCONFIG(TAG,
"Setting up DallasComponent...");
42 std::vector<uint64_t> raw_sensors;
43 raw_sensors = this->one_wire_->search_vec();
45 for (
auto &address : raw_sensors) {
46 auto *address8 =
reinterpret_cast<uint8_t *
>(&address);
47 if (
crc8(address8, 7) != address8[7]) {
48 ESP_LOGW(TAG,
"Dallas device 0x%s has invalid CRC.",
format_hex(address).c_str());
51 if (address8[0] != DALLAS_MODEL_DS18S20 && address8[0] != DALLAS_MODEL_DS1822 &&
52 address8[0] != DALLAS_MODEL_DS18B20 && address8[0] != DALLAS_MODEL_DS1825 &&
53 address8[0] != DALLAS_MODEL_DS28EA00) {
54 ESP_LOGW(TAG,
"Unknown device type 0x%02X.", address8[0]);
57 this->found_sensors_.push_back(address);
60 for (
auto *sensor : this->sensors_) {
61 if (sensor->get_index().has_value()) {
62 if (*sensor->get_index() >= this->found_sensors_.size()) {
63 this->status_set_error();
66 sensor->set_address(this->found_sensors_[*sensor->get_index()]);
69 if (!sensor->setup_sensor()) {
70 this->status_set_error();
75 ESP_LOGCONFIG(TAG,
"DallasComponent:");
76 LOG_PIN(
" Pin: ", this->pin_);
77 LOG_UPDATE_INTERVAL(
this);
79 if (this->found_sensors_.empty()) {
80 ESP_LOGW(TAG,
" Found no sensors!");
82 ESP_LOGD(TAG,
" Found sensors:");
83 for (
auto &address : this->found_sensors_) {
84 ESP_LOGD(TAG,
" 0x%s",
format_hex(address).c_str());
88 for (
auto *sensor : this->sensors_) {
89 LOG_SENSOR(
" ",
"Device", sensor);
90 if (sensor->get_index().has_value()) {
91 ESP_LOGCONFIG(TAG,
" Index %u", *sensor->get_index());
92 if (*sensor->get_index() >= this->found_sensors_.size()) {
93 ESP_LOGE(TAG,
"Couldn't find sensor by index - not connected. Proceeding without it.");
97 ESP_LOGCONFIG(TAG,
" Address: %s", sensor->get_address_name().c_str());
98 ESP_LOGCONFIG(TAG,
" Resolution: %u", sensor->get_resolution());
104 this->status_clear_warning();
109 result = this->one_wire_->reset();
112 ESP_LOGE(TAG,
"Requesting conversion failed");
113 this->status_set_warning();
114 for (
auto *sensor : this->sensors_) {
115 sensor->publish_state(NAN);
122 this->one_wire_->skip();
123 this->one_wire_->write8(DALLAS_COMMAND_START_CONVERSION);
126 for (
auto *sensor : this->sensors_) {
127 this->set_timeout(sensor->get_address_name(), sensor->millis_to_wait_for_conversion(), [
this, sensor] {
128 bool res = sensor->read_scratch_pad();
131 ESP_LOGW(TAG,
"'%s' - Resetting bus for read failed!", sensor->get_name().c_str());
132 sensor->publish_state(NAN);
133 this->status_set_warning();
136 if (!sensor->check_scratch_pad()) {
137 sensor->publish_state(NAN);
138 this->status_set_warning();
142 float tempc = sensor->get_temp_c();
143 ESP_LOGD(TAG,
"'%s': Got Temperature=%.1f°C", sensor->get_name().c_str(), tempc);
144 sensor->publish_state(tempc);
168 if (!wire->reset()) {
177 wire->write8(DALLAS_COMMAND_READ_SCRATCH_PAD);
190 ESP_LOGE(TAG,
"Reading scratchpad failed: reset");
201 ESP_LOGW(TAG,
"DS18S20 doesn't support setting resolution.");
226 wire->write8(DALLAS_COMMAND_WRITE_SCRATCH_PAD);
244 bool config_validity =
false;
247 case DALLAS_MODEL_DS18B20:
248 config_validity = ((this->
scratch_pad_[4] & 0x9F) == 0x1F);
251 config_validity = ((this->
scratch_pad_[4] & 0x10) == 0x10);
254 #ifdef ESPHOME_LOG_LEVEL_VERY_VERBOSE 255 ESP_LOGVV(TAG,
"Scratch pad: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X (%02X)", this->
scratch_pad_[0],
260 if (!chksum_validity) {
261 ESP_LOGW(TAG,
"'%s' - Scratch pad checksum invalid!", this->
get_name().c_str());
262 }
else if (!config_validity) {
263 ESP_LOGW(TAG,
"'%s' - Scratch pad config register invalid!", this->
get_name().c_str());
265 return chksum_validity && config_validity;
271 temp = ((temp & 0xFFF0) << 3) - 16 + (diff / this->
scratch_pad_[7]);
274 return temp / 128.0f;
optional< uint8_t > get_index() const
Get the index of this sensor. (0 if using address.)
void set_address(uint64_t address)
Set the 64-bit unsigned address for this sensor.
Internal class that helps us create multiple sensors for one Dallas hub.
std::string format_hex(const uint8_t *data, size_t length)
Format the byte array data of length len in lowercased hex.
void dump_config() override
uint8_t crc8(uint8_t *data, uint8_t len)
Calculate a CRC-8 checksum of data with size len.
uint8_t get_resolution() const
Get the set resolution for this sensor.
const std::string & get_address_name()
Helper to create (and cache) the name for this sensor. For example "0xfe0000031f1eaf29".
uint16_t millis_to_wait_for_conversion() const
Get the number of milliseconds we have to wait for the conversion phase.
optional< uint8_t > index_
std::string str_lower_case(const std::string &str)
Convert the string to lower case.
uint8_t * get_address8()
Helper to get a pointer to the address as uint8_t.
DallasComponent * parent_
Helper class to disable interrupts.
void set_resolution(uint8_t resolution)
Set the resolution for this sensor.
void register_sensor(DallasTemperatureSensor *sensor)
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)
void set_index(uint8_t index)
Set the index of this sensor. If using index, address will be set after setup.
std::string address_name_
std::string unique_id() override
const StringRef & get_name() const
void IRAM_ATTR HOT delay(uint32_t ms)