From f94e9b6b1eea43048fcbcdfc4a29211b03b007b2 Mon Sep 17 00:00:00 2001 From: DAVe3283 Date: Wed, 6 Nov 2019 05:56:43 -0700 Subject: [PATCH] Add MAX31865 sensor support, fix MAX31855 sensor (#832) * Add MAX31865 sensor support, fix MAX31855 sensor. # MAX31865 Added support for the MAX31865 RTD-to-Digital Converter to measure PT100 and similar RTDs. Verified with an Adafruit unit (product ID: 3328) and a PT100 probe. # MAX31855 This was setup for incorrect SPI clock polarity and phase, and would return bad data due to a race condition measuring on the wrong edge (verified with Saleae Logic scope). Selecting the correct configuration fixes that problem. Re-wrote the decode off the datasheet to handle error states better (sends NaN as an update on failure to read temperature, which shows the value as Unknown in Home Assistant). Added the *optional* ability to monitor the internal high-precision temperature sensor, which can be nice in some applications. * Tests for MAX31855/MAX38165. * Update style to match project rules. Also fix CONF_REFERENCE_RESISTANCE and CONF_REFERENCE_TEMPERATURE being defined multiple places. Missed this when I added them to const.py. * Update style to match project rules. Pylint line limit 101/100 ("missed it by that much"). Also apparently I can't read and patched the wrong line in max31855.cpp. * Minor string/style cleanup. There was a copy-paste leftover in max31855.cpp and max31865/sensor.py had unnecessary whitespace. * Improve MAX31865 fault detection and logging. Log levels are more in-line with the documented descriptions. Fault detection code is improved. A transient fault between reads is still reported, but now only faults *during* a read cause the sensor to fail and return NAN ("unknown" in Home Assistant). * Update style to match project rules. I just now realized the .clang-format and pylintrc files are included. D'oh! * MAX31855 & MAX31865 code style alignment. @OttoWinter caught some style mismatches, updated to match project better. * Fix a lost '\' in max31865/sensor.py. --- esphome/components/max31855/max31855.cpp | 110 +++++++----- esphome/components/max31855/max31855.h | 7 +- esphome/components/max31855/sensor.py | 7 +- esphome/components/max31865/__init__.py | 0 esphome/components/max31865/max31865.cpp | 214 +++++++++++++++++++++++ esphome/components/max31865/max31865.h | 56 ++++++ esphome/components/max31865/sensor.py | 34 ++++ esphome/components/ntc/sensor.py | 7 +- esphome/const.py | 5 + tests/test1.yaml | 8 + 10 files changed, 397 insertions(+), 51 deletions(-) create mode 100644 esphome/components/max31865/__init__.py create mode 100644 esphome/components/max31865/max31865.cpp create mode 100644 esphome/components/max31865/max31865.h create mode 100644 esphome/components/max31865/sensor.py diff --git a/esphome/components/max31855/max31855.cpp b/esphome/components/max31855/max31855.cpp index 0462ed4342..88f9e836f9 100644 --- a/esphome/components/max31855/max31855.cpp +++ b/esphome/components/max31855/max31855.cpp @@ -1,10 +1,11 @@ #include "max31855.h" + #include "esphome/core/log.h" namespace esphome { namespace max31855 { -static const char *TAG = "max31855"; +static const char* TAG = "max31855"; void MAX31855Sensor::update() { this->enable(); @@ -22,9 +23,15 @@ void MAX31855Sensor::setup() { this->spi_setup(); } void MAX31855Sensor::dump_config() { - LOG_SENSOR("", "MAX31855", this); + ESP_LOGCONFIG(TAG, "MAX31855:"); LOG_PIN(" CS Pin: ", this->cs_); LOG_UPDATE_INTERVAL(this); + LOG_SENSOR(" ", "Thermocouple", this); + if (this->temperature_reference_) { + LOG_SENSOR(" ", "Reference", this->temperature_reference_); + } else { + ESP_LOGCONFIG(TAG, " Reference temperature disabled."); + } } float MAX31855Sensor::get_setup_priority() const { return setup_priority::DATA; } void MAX31855Sensor::read_data_() { @@ -32,53 +39,68 @@ void MAX31855Sensor::read_data_() { delay(1); uint8_t data[4]; this->read_array(data, 4); - - // val is 14 bits of signed temperature data followed by 2 bits of status flags - int16_t val = data[1] | data[0] << 8; - - // test data from MAX31855 datasheet - // val = 0x6400 // 1600.00°C - // val = 0x3E80 // 1000.00°C - // val = 0x064C // 100.75°C - // val = 0x0190 // 25.00°C - // val = 0x0000 // 0.00°C - // val = 0xFFFC // -0.25°C - // val = 0xFFF0 // -1.00°C - // val = 0xF060 // -250.00°C - this->disable(); - if ((data[3] & 0x01) != 0) { - ESP_LOGW(TAG, "Got thermocouple not connected from MAX31855Sensor (0x%04X) (0x%04X)", val, data[3] | data[2] << 8); - this->status_set_warning(); - return; - } - if ((data[3] & 0x02) != 0) { - ESP_LOGW(TAG, "Got short circuit to ground from MAX31855Sensor (0x%04X) (0x%04X)", val, data[3] | data[2] << 8); - this->status_set_warning(); - return; - } - if ((data[3] & 0x04) != 0) { - ESP_LOGW(TAG, "Got short circuit to power from MAX31855Sensor (0x%04X) (0x%04X)", val, data[3] | data[2] << 8); - this->status_set_warning(); - return; - } - if ((data[1] & 0x01) != 0) { - ESP_LOGW(TAG, "Got faulty reading from MAX31855Sensor (0x%04X) (0x%04X)", val, data[3] | data[2] << 8); - this->status_set_warning(); - return; - } - if ((val & 0x8000) != 0) { - // Negative value, drop the lower 2 bits and explicitly extend sign bits. - val = 0xE000 | ((val >> 2) & 0x1FFF); + const uint32_t mem = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3] << 0; + + // Verify we got data + if (mem != 0 && mem != 0xFFFFFFFF) { + this->status_clear_error(); } else { - // Positive value, just drop the lower 2 bits. - val >>= 2; + ESP_LOGE(TAG, "No data received from MAX31855 (0x%08X). Check wiring!", mem); + this->publish_state(NAN); + if (this->temperature_reference_) { + this->temperature_reference_->publish_state(NAN); + } + this->status_set_error(); + return; } - float temperature = float(val) / 4.0f; - ESP_LOGD(TAG, "'%s': Got temperature=%.1f°C", this->name_.c_str(), temperature); - this->publish_state(temperature); + // Internal reference temperature always works + if (this->temperature_reference_) { + int16_t val = (mem & 0x0000FFF0) >> 4; + if (val & 0x0800) { + val |= 0xF000; // Pad out 2's complement + } + const float t_ref = float(val) * 0.0625f; + ESP_LOGD(TAG, "Got reference temperature: %.4f°C", t_ref); + this->temperature_reference_->publish_state(t_ref); + } + + // Check thermocouple faults + if (mem & 0x00000001) { + ESP_LOGW(TAG, "Thermocouple open circuit (not connected) fault from MAX31855 (0x%08X)", mem); + this->publish_state(NAN); + this->status_set_warning(); + return; + } + if (mem & 0x00000002) { + ESP_LOGW(TAG, "Thermocouple short circuit to ground fault from MAX31855 (0x%08X)", mem); + this->publish_state(NAN); + this->status_set_warning(); + return; + } + if (mem & 0x00000004) { + ESP_LOGW(TAG, "Thermocouple short circuit to VCC fault from MAX31855 (0x%08X)", mem); + this->publish_state(NAN); + this->status_set_warning(); + return; + } + if (mem & 0x00010000) { + ESP_LOGW(TAG, "Got faulty reading from MAX31855 (0x%08X)", mem); + this->publish_state(NAN); + this->status_set_warning(); + return; + } + + // Decode thermocouple temperature + int16_t val = (mem & 0xFFFC0000) >> 18; + if (val & 0x2000) { + val |= 0xC000; // Pad out 2's complement + } + const float t_sense = float(val) * 0.25f; + ESP_LOGD(TAG, "Got thermocouple temperature: %.2f°C", t_sense); + this->publish_state(t_sense); this->status_clear_warning(); } diff --git a/esphome/components/max31855/max31855.h b/esphome/components/max31855/max31855.h index 1d0fc79ac0..c0ed8a467d 100644 --- a/esphome/components/max31855/max31855.h +++ b/esphome/components/max31855/max31855.h @@ -9,9 +9,11 @@ namespace max31855 { class MAX31855Sensor : public sensor::Sensor, public PollingComponent, - public spi::SPIDevice { + public spi::SPIDevice { public: + void set_reference_sensor(sensor::Sensor *temperature_sensor) { temperature_reference_ = temperature_sensor; } + void setup() override; void dump_config() override; float get_setup_priority() const override; @@ -20,6 +22,7 @@ class MAX31855Sensor : public sensor::Sensor, protected: void read_data_(); + sensor::Sensor *temperature_reference_{nullptr}; }; } // namespace max31855 diff --git a/esphome/components/max31855/sensor.py b/esphome/components/max31855/sensor.py index b4d9f82b03..dce28bd542 100644 --- a/esphome/components/max31855/sensor.py +++ b/esphome/components/max31855/sensor.py @@ -1,7 +1,7 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome.components import sensor, spi -from esphome.const import CONF_ID, ICON_THERMOMETER, UNIT_CELSIUS +from esphome.const import CONF_ID, CONF_REFERENCE_TEMPERATURE, ICON_THERMOMETER, UNIT_CELSIUS max31855_ns = cg.esphome_ns.namespace('max31855') MAX31855Sensor = max31855_ns.class_('MAX31855Sensor', sensor.Sensor, cg.PollingComponent, @@ -9,6 +9,8 @@ MAX31855Sensor = max31855_ns.class_('MAX31855Sensor', sensor.Sensor, cg.PollingC CONFIG_SCHEMA = sensor.sensor_schema(UNIT_CELSIUS, ICON_THERMOMETER, 1).extend({ cv.GenerateID(): cv.declare_id(MAX31855Sensor), + cv.Optional(CONF_REFERENCE_TEMPERATURE): + sensor.sensor_schema(UNIT_CELSIUS, ICON_THERMOMETER, 2), }).extend(cv.polling_component_schema('60s')).extend(spi.SPI_DEVICE_SCHEMA) @@ -17,3 +19,6 @@ def to_code(config): yield cg.register_component(var, config) yield spi.register_spi_device(var, config) yield sensor.register_sensor(var, config) + if CONF_REFERENCE_TEMPERATURE in config: + tc_ref = yield sensor.new_sensor(config[CONF_REFERENCE_TEMPERATURE]) + cg.add(var.set_reference_sensor(tc_ref)) diff --git a/esphome/components/max31865/__init__.py b/esphome/components/max31865/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/esphome/components/max31865/max31865.cpp b/esphome/components/max31865/max31865.cpp new file mode 100644 index 0000000000..500b5b2883 --- /dev/null +++ b/esphome/components/max31865/max31865.cpp @@ -0,0 +1,214 @@ +#include "max31865.h" + +#include "esphome/core/log.h" +#include + +namespace esphome { +namespace max31865 { + +static const char* TAG = "max31865"; + +void MAX31865Sensor::update() { + // Check new faults since last measurement + if (!has_fault_) { + const uint8_t faults = this->read_register_(FAULT_STATUS_REG); + if (faults & 0b11111100) { + if (faults & (1 << 2)) { + ESP_LOGW(TAG, "Overvoltage/undervoltage fault between measurements"); + } + if (faults & (1 << 3)) { + ESP_LOGW(TAG, "RTDIN- < 0.85 x V_BIAS (FORCE- open) between measurements"); + } + if (faults & (1 << 4)) { + ESP_LOGW(TAG, "REFIN- < 0.85 x V_BIAS (FORCE- open) between measurements"); + } + if (faults & (1 << 5)) { + ESP_LOGW(TAG, "REFIN- > 0.85 x V_BIAS between measurements"); + } + if (!has_warn_) { + if (faults & (1 << 6)) { + ESP_LOGW(TAG, "RTD Low Threshold between measurements"); + } + if (faults & (1 << 7)) { + ESP_LOGW(TAG, "RTD High Threshold between measurements"); + } + } + } + } + + // Run fault detection + write_register_(CONFIGURATION_REG, 0b11101110, 0b10000110); + const uint32_t start_time = micros(); + uint8_t config; + uint32_t fault_detect_time; + do { + config = this->read_register_(CONFIGURATION_REG); + fault_detect_time = micros() - start_time; + if ((fault_detect_time >= 6000) && (config & 0b00001100)) { + ESP_LOGE(TAG, "Fault detection incomplete (0x%02X) after %uμs (datasheet spec is 600μs max)! Aborting read.", + config, fault_detect_time); + this->publish_state(NAN); + this->status_set_error(); + return; + } + } while (config & 0b00001100); + ESP_LOGV(TAG, "Fault detection completed in %uμs.", fault_detect_time); + + // Start 1-shot conversion + this->write_register_(CONFIGURATION_REG, 0b11100000, 0b10100000); + + // Datasheet max conversion time is 55ms for 60Hz / 66ms for 50Hz + auto f = std::bind(&MAX31865Sensor::read_data_, this); + this->set_timeout("value", filter_ == FILTER_60HZ ? 55 : 66, f); +} + +void MAX31865Sensor::setup() { + ESP_LOGCONFIG(TAG, "Setting up MAX31865Sensor '%s'...", this->name_.c_str()); + this->spi_setup(); + + // Build configuration + uint8_t config = 0b00000010; + config |= (filter_ & 1) << 0; + if (rtd_wires_ == 3) { + config |= 1 << 4; + } + this->write_register_(CONFIGURATION_REG, 0b11111111, config); +} + +void MAX31865Sensor::dump_config() { + LOG_SENSOR("", "MAX31865", this); + LOG_PIN(" CS Pin: ", this->cs_); + LOG_UPDATE_INTERVAL(this); + ESP_LOGCONFIG(TAG, " Reference Resistance: %.2fΩ", reference_resistance_); + ESP_LOGCONFIG(TAG, " RTD: %u-wire %.2fΩ", rtd_wires_, rtd_nominal_resistance_); + ESP_LOGCONFIG(TAG, " Filter: %s", + (filter_ == FILTER_60HZ ? "60 Hz" : (filter_ == FILTER_50HZ ? "50 Hz" : "Unknown!"))); +} + +float MAX31865Sensor::get_setup_priority() const { return setup_priority::DATA; } + +void MAX31865Sensor::read_data_() { + // Read temperature, disable V_BIAS (save power) + const uint16_t rtd_resistance_register = this->read_register_16_(RTD_RESISTANCE_MSB_REG); + this->write_register_(CONFIGURATION_REG, 0b11000000, 0b00000000); + + // Check faults + const uint8_t faults = this->read_register_(FAULT_STATUS_REG); + if ((has_fault_ = faults & 0b00111100)) { + if (faults & (1 << 2)) { + ESP_LOGE(TAG, "Overvoltage/undervoltage fault"); + } + if (faults & (1 << 3)) { + ESP_LOGE(TAG, "RTDIN- < 0.85 x V_BIAS (FORCE- open)"); + } + if (faults & (1 << 4)) { + ESP_LOGE(TAG, "REFIN- < 0.85 x V_BIAS (FORCE- open)"); + } + if (faults & (1 << 5)) { + ESP_LOGE(TAG, "REFIN- > 0.85 x V_BIAS"); + } + this->publish_state(NAN); + this->status_set_error(); + return; + } else { + this->status_clear_error(); + } + if ((has_warn_ = faults & 0b11000000)) { + if (faults & (1 << 6)) { + ESP_LOGW(TAG, "RTD Low Threshold"); + } + if (faults & (1 << 7)) { + ESP_LOGW(TAG, "RTD High Threshold"); + } + this->status_set_warning(); + } else { + this->status_clear_warning(); + } + + // Process temperature + if (rtd_resistance_register & 0x0001) { + ESP_LOGW(TAG, "RTD Resistance Registers fault bit set! (0x%04X)", rtd_resistance_register); + this->status_set_warning(); + } + const float rtd_ratio = static_cast(rtd_resistance_register >> 1) / static_cast((1 << 15) - 1); + const float temperature = this->calc_temperature_(rtd_ratio); + ESP_LOGV(TAG, "RTD read complete. %.5f (ratio) * %.1fΩ (reference) = %.2fΩ --> %.2f°C", rtd_ratio, + reference_resistance_, reference_resistance_ * rtd_ratio, temperature); + this->publish_state(temperature); +} + +void MAX31865Sensor::write_register_(uint8_t reg, uint8_t mask, uint8_t bits, uint8_t start_position) { + uint8_t value = this->read_register_(reg); + + value &= (~mask); + value |= (bits << start_position); + + this->enable(); + this->write_byte(reg |= SPI_WRITE_M); + this->write_byte(value); + this->disable(); + ESP_LOGVV(TAG, "write_register_ 0x%02X: 0x%02X", reg, value); +} + +const uint8_t MAX31865Sensor::read_register_(uint8_t reg) { + this->enable(); + this->write_byte(reg); + const uint8_t value(this->read_byte()); + this->disable(); + ESP_LOGVV(TAG, "read_register_ 0x%02X: 0x%02X", reg, value); + return value; +} + +const uint16_t MAX31865Sensor::read_register_16_(uint8_t reg) { + this->enable(); + this->write_byte(reg); + const uint8_t msb(this->read_byte()); + const uint8_t lsb(this->read_byte()); + this->disable(); + const uint16_t value((msb << 8) | lsb); + ESP_LOGVV(TAG, "read_register_16_ 0x%02X: 0x%04X", reg, value); + return value; +} + +float MAX31865Sensor::calc_temperature_(const float& rtd_ratio) { + // Based loosely on Adafruit's library: https://github.com/adafruit/Adafruit_MAX31865 + // Mainly based on formulas provided by Analog: + // http://www.analog.com/media/en/technical-documentation/application-notes/AN709_0.pdf + + const float a = 3.9083e-3; + const float b = -5.775e-7; + const float z1 = -a; + const float z2 = a * a - 4 * b; + const float z3 = 4 * b / rtd_nominal_resistance_; + const float z4 = 2 * b; + + float rtd_resistance = rtd_ratio * reference_resistance_; + + // ≥ 0°C Formula + const float pos_temp = (z1 + std::sqrt(z2 + (z3 * rtd_resistance))) / z4; + if (pos_temp >= 0) { + return pos_temp; + } + + // < 0°C Formula + if (rtd_nominal_resistance_ != 100) { + // Normalize RTD to 100Ω + rtd_resistance /= rtd_nominal_resistance_; + rtd_resistance *= 100; + } + float rpoly = rtd_resistance; + float neg_temp = -242.02; + neg_temp += 2.2228 * rpoly; + rpoly *= rtd_resistance; // square + neg_temp += 2.5859e-3 * rpoly; + rpoly *= rtd_resistance; // ^3 + neg_temp -= 4.8260e-6 * rpoly; + rpoly *= rtd_resistance; // ^4 + neg_temp -= 2.8183e-8 * rpoly; + rpoly *= rtd_resistance; // ^5 + neg_temp += 1.5243e-10 * rpoly; + return neg_temp; +} + +} // namespace max31865 +} // namespace esphome diff --git a/esphome/components/max31865/max31865.h b/esphome/components/max31865/max31865.h new file mode 100644 index 0000000000..e63be8e6c5 --- /dev/null +++ b/esphome/components/max31865/max31865.h @@ -0,0 +1,56 @@ +#pragma once + +#include "esphome/core/component.h" +#include "esphome/components/sensor/sensor.h" +#include "esphome/components/spi/spi.h" + +namespace esphome { +namespace max31865 { + +enum MAX31865RegisterMasks { SPI_WRITE_M = 0x80 }; +enum MAX31865Registers { + CONFIGURATION_REG = 0x00, + RTD_RESISTANCE_MSB_REG = 0x01, + RTD_RESISTANCE_LSB_REG = 0x02, + FAULT_THRESHOLD_H_MSB_REG = 0x03, + FAULT_THRESHOLD_H_LSB_REG = 0x04, + FAULT_THRESHOLD_L_MSB_REG = 0x05, + FAULT_THRESHOLD_L_LSB_REG = 0x06, + FAULT_STATUS_REG = 0x07, +}; +enum MAX31865ConfigFilter { + FILTER_60HZ = 0, + FILTER_50HZ = 1, +}; + +class MAX31865Sensor : public sensor::Sensor, + public PollingComponent, + public spi::SPIDevice { + public: + void set_reference_resistance(float reference_resistance) { reference_resistance_ = reference_resistance; } + void set_nominal_resistance(float nominal_resistance) { rtd_nominal_resistance_ = nominal_resistance; } + void set_filter(MAX31865ConfigFilter filter) { filter_ = filter; } + void set_num_rtd_wires(uint8_t rtd_wires) { rtd_wires_ = rtd_wires; } + void setup() override; + void dump_config() override; + float get_setup_priority() const override; + + void update() override; + + protected: + float reference_resistance_; + float rtd_nominal_resistance_; + MAX31865ConfigFilter filter_; + uint8_t rtd_wires_; + bool has_fault_ = false; + bool has_warn_ = false; + void read_data_(); + void write_register_(uint8_t reg, uint8_t mask, uint8_t bits, uint8_t start_position = 0); + const uint8_t read_register_(uint8_t reg); + const uint16_t read_register_16_(uint8_t reg); + float calc_temperature_(const float& rtd_ratio); +}; + +} // namespace max31865 +} // namespace esphome diff --git a/esphome/components/max31865/sensor.py b/esphome/components/max31865/sensor.py new file mode 100644 index 0000000000..ff1df9c5c8 --- /dev/null +++ b/esphome/components/max31865/sensor.py @@ -0,0 +1,34 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import sensor, spi +from esphome.const import CONF_ID, CONF_MAINS_FILTER, CONF_REFERENCE_RESISTANCE, \ + CONF_RTD_NOMINAL_RESISTANCE, CONF_RTD_WIRES, ICON_THERMOMETER, UNIT_CELSIUS + +max31865_ns = cg.esphome_ns.namespace('max31865') +MAX31865Sensor = max31865_ns.class_('MAX31865Sensor', sensor.Sensor, cg.PollingComponent, + spi.SPIDevice) + +MAX31865ConfigFilter = max31865_ns.enum('MAX31865ConfigFilter') +FILTER = { + '50HZ': MAX31865ConfigFilter.FILTER_50HZ, + '60HZ': MAX31865ConfigFilter.FILTER_60HZ, +} + +CONFIG_SCHEMA = sensor.sensor_schema(UNIT_CELSIUS, ICON_THERMOMETER, 2).extend({ + cv.GenerateID(): cv.declare_id(MAX31865Sensor), + cv.Required(CONF_REFERENCE_RESISTANCE): cv.All(cv.resistance, cv.Range(min=100, max=10000)), + cv.Required(CONF_RTD_NOMINAL_RESISTANCE): cv.All(cv.resistance, cv.Range(min=100, max=1000)), + cv.Optional(CONF_MAINS_FILTER, default='60HZ'): cv.enum(FILTER, upper=True, space=''), + cv.Optional(CONF_RTD_WIRES, default=4): cv.int_range(min=2, max=4), +}).extend(cv.polling_component_schema('60s')).extend(spi.SPI_DEVICE_SCHEMA) + + +def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + yield cg.register_component(var, config) + yield spi.register_spi_device(var, config) + yield sensor.register_sensor(var, config) + cg.add(var.set_reference_resistance(config[CONF_REFERENCE_RESISTANCE])) + cg.add(var.set_nominal_resistance(config[CONF_RTD_NOMINAL_RESISTANCE])) + cg.add(var.set_filter(config[CONF_MAINS_FILTER])) + cg.add(var.set_num_rtd_wires(config[CONF_RTD_WIRES])) diff --git a/esphome/components/ntc/sensor.py b/esphome/components/ntc/sensor.py index a528183ac8..7ff4f4e137 100644 --- a/esphome/components/ntc/sensor.py +++ b/esphome/components/ntc/sensor.py @@ -4,15 +4,14 @@ from math import log import esphome.config_validation as cv import esphome.codegen as cg from esphome.components import sensor -from esphome.const import UNIT_CELSIUS, ICON_THERMOMETER, CONF_SENSOR, CONF_TEMPERATURE, \ - CONF_VALUE, CONF_CALIBRATION, CONF_ID +from esphome.const import CONF_CALIBRATION, CONF_ID, CONF_REFERENCE_RESISTANCE, \ + CONF_REFERENCE_TEMPERATURE, CONF_SENSOR, CONF_TEMPERATURE, CONF_VALUE, ICON_THERMOMETER, \ + UNIT_CELSIUS ntc_ns = cg.esphome_ns.namespace('ntc') NTC = ntc_ns.class_('NTC', cg.Component, sensor.Sensor) CONF_B_CONSTANT = 'b_constant' -CONF_REFERENCE_TEMPERATURE = 'reference_temperature' -CONF_REFERENCE_RESISTANCE = 'reference_resistance' CONF_A = 'a' CONF_B = 'b' CONF_C = 'c' diff --git a/esphome/const.py b/esphome/const.py index dc607d62ff..cde9134eae 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -224,6 +224,7 @@ CONF_LOGS = 'logs' CONF_LOW = 'low' CONF_LOW_VOLTAGE_REFERENCE = 'low_voltage_reference' CONF_MAC_ADDRESS = 'mac_address' +CONF_MAINS_FILTER = 'mains_filter' CONF_MAKE_ID = 'make_id' CONF_MANUAL_IP = 'manual_ip' CONF_MASK_DISTURBER = 'mask_disturber' @@ -343,6 +344,8 @@ CONF_RAW = 'raw' CONF_REBOOT_TIMEOUT = 'reboot_timeout' CONF_RECEIVE_TIMEOUT = 'receive_timeout' CONF_RED = 'red' +CONF_REFERENCE_RESISTANCE = 'reference_resistance' +CONF_REFERENCE_TEMPERATURE = 'reference_temperature' CONF_REPEAT = 'repeat' CONF_REPOSITORY = 'repository' CONF_RESET_PIN = 'reset_pin' @@ -358,6 +361,8 @@ CONF_RGBW = 'rgbw' CONF_RISING_EDGE = 'rising_edge' CONF_ROTATION = 'rotation' CONF_RS_PIN = 'rs_pin' +CONF_RTD_NOMINAL_RESISTANCE = 'rtd_nominal_resistance' +CONF_RTD_WIRES = 'rtd_wires' CONF_RUN_CYCLES = 'run_cycles' CONF_RUN_DURATION = 'run_duration' CONF_RW_PIN = 'rw_pin' diff --git a/tests/test1.yaml b/tests/test1.yaml index 66f0220836..60f3b7f418 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -451,6 +451,14 @@ sensor: name: "Den Temperature" cs_pin: GPIO23 update_interval: 15s + reference_temperature: + name: "MAX31855 Internal Temperature" + - platform: max31865 + name: "Water Tank Temperature" + cs_pin: GPIO23 + update_interval: 15s + reference_resistance: "430 Ω" + rtd_nominal_resistance: "100 Ω" - platform: mhz19 co2: name: "MH-Z19 CO2 Value"