4#ifdef USE_TMP102_TEXT_SENSOR
9#ifdef USE_TMP102_TEXT_SENSOR
17static constexpr uint32_t READ_TEMP_TIMEOUT_ID = 0;
19static constexpr uint8_t TMP102_REGISTER_TEMPERATURE = 0x00;
20static constexpr float TMP102_CONVERSION_FACTOR = 0.0625f;
37#ifdef USE_TMP102_TEXT_SENSOR
38PROGMEM_STRING_TABLE(ThresholdStatusStrings,
"Not configured",
"Setup failed",
"OK",
"Restored thresholds reset",
39 "Restore reset; save failed",
"Preference save failed",
"Configuration recovery failed",
40 "Configuration restored",
"Write failed: high threshold",
"Write failed: low threshold",
41 "Rejected: sensor setup failed");
45#if defined(USE_TMP102_CONFIGURE) || defined(USE_TMP102_BINARY_SENSOR)
46static constexpr uint8_t TMP102_REGISTER_CONFIGURATION = 0x01;
47static constexpr uint16_t TMP102_ALERT_BIT = 0x0020;
48static constexpr uint16_t TMP102_ALERT_POLARITY_BIT = 0x0400;
50#ifdef USE_TMP102_CONFIGURE
51static constexpr uint8_t TMP102_REGISTER_LOW_LIMIT = 0x02;
52static constexpr uint8_t TMP102_REGISTER_HIGH_LIMIT = 0x03;
53#ifdef USE_TMP102_NUMBER
54static_assert(TMP102_REGISTER_LOW_LIMIT +
TMP102_LIMIT_HIGH == TMP102_REGISTER_HIGH_LIMIT);
57static constexpr uint16_t TMP102_CONFIGURATION_MASK = 0x1FD0;
58static constexpr uint16_t TMP102_RESET_CONFIGURATION = 0x60A0;
59static constexpr uint16_t TMP102_ONE_SHOT_BIT = 0x8000;
60static constexpr uint16_t TMP102_SHUTDOWN_BIT = 0x0100;
61static constexpr uint16_t TMP102_THERMOSTAT_MODE_BIT = 0x0200;
62static constexpr uint16_t TMP102_EXTENDED_MODE_BIT = 0x0010;
63static constexpr uint32_t TMP102_ONESHOT_DELAY_MS = 40;
65static float decode_temperature(uint16_t
raw,
bool extended) {
66 return (
static_cast<int16_t
>(
raw) >> (extended ? 3 : 4)) * TMP102_CONVERSION_FACTOR;
69#ifdef USE_TMP102_NUMBER
70static uint16_t encode_temperature(
float temperature,
bool extended) {
71 const int16_t steps =
static_cast<int16_t
>(std::lround(
temperature / TMP102_CONVERSION_FACTOR));
72 return static_cast<uint16_t
>(
static_cast<uint32_t>(
static_cast<uint16_t
>(steps)) << (extended ? 3 : 4));
77#if defined(USE_TMP102_CONFIGURE) || defined(USE_TMP102_TEXT_SENSOR)
79#ifdef USE_TMP102_CONFIGURE
89#ifdef USE_TMP102_CONFIGURE
91 bool corrected =
false;
92#ifdef USE_TMP102_NUMBER
94 bool restore_corrected[2]{};
102#ifdef USE_TMP102_NUMBER
104 for (uint8_t limit = 0; limit < 2; ++limit) {
106 if (control ==
nullptr)
109 if (restore_corrected[limit] || value != restored[limit])
114 ESP_LOGW(TAG,
"Failed to save threshold preferences");
124 ESP_LOGCONFIG(TAG,
"TMP102:");
125 LOG_I2C_DEVICE(
this);
126 LOG_UPDATE_INTERVAL(
this);
127 LOG_SENSOR(
" ",
"Temperature",
this);
128#ifdef USE_TMP102_BINARY_SENSOR
129 LOG_BINARY_SENSOR(
" ",
"Alert", this->alert_binary_sensor_);
131#ifdef USE_TMP102_TEXT_SENSOR
132 LOG_TEXT_SENSOR(
" ",
"Threshold Status", this->threshold_status_text_sensor_);
134#ifdef USE_TMP102_CONFIGURE
137 const uint8_t rate = (this->
config_ >> 6) & 0x03;
138 const LogString *rate_str = rate == 0 ? LOG_STR(
"0.25Hz")
139 : rate == 1 ? LOG_STR(
"1Hz")
140 : rate == 2 ? LOG_STR(
"4Hz")
142 const uint8_t fault_bits = (this->
config_ >> 11) & 0x03;
143 const bool extended = this->
config_ & TMP102_EXTENDED_MODE_BIT;
146 " Extended Mode: %s\n"
147 " One-Shot Mode: %s\n"
148 " Conversion Rate: %s\n"
149 " Thermostat Mode: %s\n"
150 " Alert Polarity: %s\n"
152 " Temperature High: %.4f°C\n"
153 " Temperature Low: %.4f°C",
154 YESNO(extended), YESNO(this->
config_ & TMP102_SHUTDOWN_BIT), LOG_STR_ARG(rate_str),
155 this->
config_ & TMP102_THERMOSTAT_MODE_BIT ? LOG_STR_LITERAL(
"Interrupt") : LOG_STR_LITERAL(
"Comparator"),
156 this->
config_ & TMP102_ALERT_POLARITY_BIT ? LOG_STR_LITERAL(
"Active High") : LOG_STR_LITERAL(
"Active Low"),
157 fault_bits == 3 ? 6 : 1U << fault_bits, decode_temperature(this->
high_limit_, extended),
158 decode_temperature(this->
low_limit_, extended));
159#ifdef USE_TMP102_NUMBER
160 LOG_NUMBER(
" ",
"High Limit", this->
limit_controls_[TMP102_LIMIT_HIGH]);
163 if (this->
config_ & TMP102_THERMOSTAT_MODE_BIT) {
164 ESP_LOGW(TAG,
"Register reads clear the interrupt-mode ALERT pin");
170#ifdef USE_TMP102_CONFIGURE
180 this->
set_timeout(READ_TEMP_TIMEOUT_ID, 50, [
this]() {
181 int16_t raw_temperature;
182 if (this->
read(
reinterpret_cast<uint8_t *
>(&raw_temperature), 2) !=
i2c::ERROR_OK) {
187 raw_temperature = raw_temperature >> 4;
188 float temperature = raw_temperature * TMP102_CONVERSION_FACTOR;
189 ESP_LOGD(TAG,
"Got Temperature=%.1f°C",
temperature);
192#ifdef USE_TMP102_BINARY_SENSOR
200#ifdef USE_TMP102_CONFIGURE
204 if (this->
config_ & TMP102_SHUTDOWN_BIT) {
216 uint8_t frame[3] = {
reg,
static_cast<uint8_t
>(value >> 8),
static_cast<uint8_t
>(value)};
219 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
231 if (!this->
read_byte_16(TMP102_REGISTER_CONFIGURATION, &config)) {
235 bool matches = (config & TMP102_CONFIGURATION_MASK) == (this->
config_ & TMP102_CONFIGURATION_MASK);
238 (this->
config_ & TMP102_CONFIGURATION_MASK) == (TMP102_RESET_CONFIGURATION & TMP102_CONFIGURATION_MASK)) {
240 if (!this->
read_byte_16(TMP102_REGISTER_HIGH_LIMIT, &high) ||
250 ESP_LOGW(TAG,
"Configuration changed; restoring configured settings and thresholds");
253 ESP_LOGW(TAG,
"Failed to restore configuration and thresholds");
268 ESP_LOGD(TAG,
"Got Temperature=%.2f°C",
temperature);
270#ifdef USE_TMP102_BINARY_SENSOR
277#ifdef USE_TMP102_NUMBER
283 const bool extended = this->
config_ & TMP102_EXTENDED_MODE_BIT;
285 bool corrected =
false;
286 for (uint8_t limit = 0; limit < 2; ++limit) {
288 if (control ==
nullptr)
290 restored[limit] = control->
load_value_(decode_temperature(
raw[limit], extended), restore_corrected[limit]);
291 corrected |= restore_corrected[limit];
292 raw[limit] = encode_temperature(restored[limit], extended);
295 ESP_LOGW(TAG,
"Restored thresholds are inverted; using configured values");
305 return decode_temperature(
raw, this->
config_ & TMP102_EXTENDED_MODE_BIT);
309 const bool extended = this->
config_ & TMP102_EXTENDED_MODE_BIT;
313 if (high ?
static_cast<int16_t
>(
raw) <
static_cast<int16_t
>(other)
314 :
static_cast<int16_t
>(
raw) >
static_cast<int16_t
>(other)) {
315 ESP_LOGW(TAG,
"Rejected %s threshold %.4f°C: crosses %s threshold %.4f°C",
316 high ? LOG_STR_LITERAL(
"high") : LOG_STR_LITERAL(
"low"), decode_temperature(
raw, extended),
317 high ? LOG_STR_LITERAL(
"low") : LOG_STR_LITERAL(
"high"), decode_temperature(other, extended));
321 if (!this->
write_register_(
static_cast<uint8_t
>(TMP102_REGISTER_LOW_LIMIT + limit),
raw)) {
333#ifdef USE_TMP102_TEXT_SENSOR
335 if (this->threshold_status_text_sensor_ ==
nullptr)
342 text[
sizeof(text) - 1] =
'\0';
343 this->threshold_status_text_sensor_->publish_state(text);
347 if (this->threshold_status_text_sensor_ ==
nullptr)
351 ESPHOME_snprintf_P(text,
sizeof(text), ESPHOME_PSTR(
"Rejected: high %.4f°C crosses low %.4f°C"), value, other);
353 ESPHOME_snprintf_P(text,
sizeof(text), ESPHOME_PSTR(
"Rejected: low %.4f°C crosses high %.4f°C"), value, other);
355 this->threshold_status_text_sensor_->publish_state(text);
359#ifdef USE_TMP102_BINARY_SENSOR
361 if (this->alert_binary_sensor_ !=
nullptr)
362 this->alert_binary_sensor_->invalidate_state();
367 if (!this->
read_byte_16(TMP102_REGISTER_CONFIGURATION, &config)) {
369 ESP_LOGW(TAG,
"Failed to read alert state");
373 const bool alert = bool(config & TMP102_ALERT_BIT) == bool(config & TMP102_ALERT_POLARITY_BIT);
374 this->alert_binary_sensor_->publish_state(alert);
379#ifdef USE_TMP102_NUMBER
381 float value = fallback;
386 if (!std::isfinite(value) || value < this->
traits.
get_min_value() || value > this->traits.get_max_value()) {
387 ESP_LOGW(TAG,
"Invalid restored threshold; using configured value");
398 if (this->
parent_->is_failed()) {
399 ESP_LOGW(TAG,
"Rejected threshold change: sensor setup failed");
403 const bool accepted = this->
parent_->set_limit_temperature_(this->
limit_type_, value);
407 ESP_LOGW(TAG,
"Failed to save threshold preference");
409 }
else if (accepted) {
void mark_failed()
Mark this component as failed.
virtual void setup()
Where the component's initialization should happen.
void status_set_warning()
void set_timeout(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a const char* name.
void status_clear_warning()
ESPPreferenceObject make_entity_preference(uint32_t version=0)
Create a preference object for storing this entity's state/settings.
TMP102Component * parent_
ErrorCode write(const uint8_t *data, size_t len) const
writes an array of bytes to a device using an I2CBus
ErrorCode read(uint8_t *data, size_t len) const
reads an array of bytes from the device using an I2CBus
bool read_byte_16(uint8_t a_register, uint16_t *data)
I2CRegister reg(uint8_t a_register)
calls the I2CRegister constructor
void publish_state(float state)
float get_min_value() const
void publish_state(float state)
Publish a new state to the front-end.
bool check_configuration_()
void publish_threshold_status_(uint8_t status)
bool write_register_(uint8_t reg, uint16_t value)
void dump_config() override
void publish_threshold_rejection_(bool high, float value, float other)
TMP102LimitNumber * limit_controls_[2]
void set_warning_and_invalidate_alert_()
float get_limit_temperature_(TMP102LimitType limit) const
bool set_limit_temperature_(TMP102LimitType limit, float temperature)
void set_limit_control(TMP102LimitNumber *number)
bool prepare_number_limits_(float *restored, bool *restore_corrected)
void update_configured_()
bool write_configuration_()
float load_value_(float fallback, bool &corrected)
TMP102LimitType limit_type_
bool save_value_(float value)
ESPPreferenceObject pref_
void control(float value) override
uint16_t i2ctohs(uint16_t i2cshort)
@ ERROR_OK
No error found during execution of method.
@ TMP102_THRESHOLD_STATUS_WRITE_LOW_FAILED
@ TMP102_THRESHOLD_STATUS_RECOVERED
@ TMP102_THRESHOLD_STATUS_PREFERENCE_SAVE_FAILED
@ TMP102_THRESHOLD_STATUS_NOT_CONFIGURED
@ TMP102_THRESHOLD_STATUS_COUNT
@ TMP102_THRESHOLD_STATUS_RESTORE_RESET_SAVE_FAILED
@ TMP102_THRESHOLD_STATUS_OK
@ TMP102_THRESHOLD_STATUS_SENSOR_SETUP_FAILED
@ TMP102_THRESHOLD_STATUS_WRITE_HIGH_FAILED
@ TMP102_THRESHOLD_STATUS_RECOVERY_FAILED
@ TMP102_THRESHOLD_STATUS_RESTORE_RESET
@ TMP102_THRESHOLD_STATUS_SETUP_FAILED
ESPHOME_LOG_TAG(TAG, "tmp102")
PROGMEM_STRING_TABLE(ThresholdStatusStrings, "Not configured", "Setup failed", "OK", "Restored thresholds reset", "Restore reset; save failed", "Preference save failed", "Configuration recovery failed", "Configuration restored", "Write failed: high threshold", "Write failed: low threshold", "Rejected: sensor setup failed")