From 021055f0b8c8f450fdfed5a57d34f796cae68b46 Mon Sep 17 00:00:00 2001 From: krahabb Date: Sun, 24 May 2020 02:52:29 +0200 Subject: [PATCH] Added auto discovery and setup to Dallas Platform (#1028) * Added auto discovery and setup to Dallas Platform * Added auto discovery and setup to Dallas Platform * Added auto discovery and setup to Dallas Platform * Added auto discovery and setup to Dallas Platform * Added auto discovery and setup to Dallas Platform --- esphome/components/dallas/__init__.py | 26 ++++++++++++- .../components/dallas/dallas_component.cpp | 37 +++++++++++++++++++ esphome/components/dallas/dallas_component.h | 20 ++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/esphome/components/dallas/__init__.py b/esphome/components/dallas/__init__.py index 85ab4300ee..28fc9785ad 100644 --- a/esphome/components/dallas/__init__.py +++ b/esphome/components/dallas/__init__.py @@ -1,12 +1,18 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome import pins -from esphome.const import CONF_ID, CONF_PIN +from esphome.const import CONF_ID, CONF_PIN, \ + CONF_RESOLUTION, CONF_UNIT_OF_MEASUREMENT, UNIT_CELSIUS, \ + CONF_ICON, ICON_THERMOMETER, CONF_ACCURACY_DECIMALS MULTI_CONF = True AUTO_LOAD = ['sensor'] CONF_ONE_WIRE_ID = 'one_wire_id' +CONF_AUTO_SETUP_SENSORS = 'auto_setup_sensors' +CONF_SENSOR_NAME_TEMPLATE = 'sensor_name_template' +SENSOR_NAME_TEMPLATE_DEFAULT = '%s.%s' + dallas_ns = cg.esphome_ns.namespace('dallas') DallasComponent = dallas_ns.class_('DallasComponent', cg.PollingComponent) ESPOneWire = dallas_ns.class_('ESPOneWire') @@ -15,6 +21,12 @@ CONFIG_SCHEMA = cv.Schema({ cv.GenerateID(): cv.declare_id(DallasComponent), cv.GenerateID(CONF_ONE_WIRE_ID): cv.declare_id(ESPOneWire), cv.Required(CONF_PIN): pins.gpio_input_pin_schema, + cv.Optional(CONF_AUTO_SETUP_SENSORS, default=False): cv.boolean, + cv.Optional(CONF_SENSOR_NAME_TEMPLATE, default=SENSOR_NAME_TEMPLATE_DEFAULT): cv.string_strict, + cv.Optional(CONF_RESOLUTION, default=12): cv.int_range(min=9, max=12), + cv.Optional(CONF_UNIT_OF_MEASUREMENT, default=UNIT_CELSIUS): cv.string_strict, + cv.Optional(CONF_ICON, default=ICON_THERMOMETER): cv.icon, + cv.Optional(CONF_ACCURACY_DECIMALS, default=1): cv.int_, }).extend(cv.polling_component_schema('60s')) @@ -22,4 +34,16 @@ def to_code(config): pin = yield cg.gpio_pin_expression(config[CONF_PIN]) one_wire = cg.new_Pvariable(config[CONF_ONE_WIRE_ID], pin) var = cg.new_Pvariable(config[CONF_ID], one_wire) + if CONF_AUTO_SETUP_SENSORS in config: + cg.add(var.set_auto_setup_sensors(config[CONF_AUTO_SETUP_SENSORS])) + if CONF_SENSOR_NAME_TEMPLATE in config: + cg.add(var.set_sensor_name_template(config[CONF_SENSOR_NAME_TEMPLATE])) + if CONF_RESOLUTION in config: + cg.add(var.set_resolution(config[CONF_RESOLUTION])) + if CONF_UNIT_OF_MEASUREMENT in config: + cg.add(var.set_unit_of_measurement(config[CONF_UNIT_OF_MEASUREMENT])) + if CONF_ICON in config: + cg.add(var.set_icon(config[CONF_ICON])) + if CONF_ACCURACY_DECIMALS in config: + cg.add(var.set_accuracy_decimals(config[CONF_ACCURACY_DECIMALS])) yield cg.register_component(var, config) diff --git a/esphome/components/dallas/dallas_component.cpp b/esphome/components/dallas/dallas_component.cpp index aa839e7331..d657f6c498 100644 --- a/esphome/components/dallas/dallas_component.cpp +++ b/esphome/components/dallas/dallas_component.cpp @@ -1,5 +1,6 @@ #include "dallas_component.h" #include "esphome/core/log.h" +#include "esphome/core/application.h" namespace esphome { namespace dallas { @@ -52,6 +53,29 @@ void DallasComponent::setup() { continue; } this->found_sensors_.push_back(address); + + if (this->auto_setup_sensors_) { + // avoid re-generating pre-configured sensors + bool skip = false; + for (auto sensor : this->sensors_) { + if (sensor->get_address() == address) { + skip = true; + break; + } + } + if (!skip) { + auto dallastemperaturesensor = this->get_sensor_by_address(address, this->resolution_); + char sensor_name[64]; + snprintf(sensor_name, sizeof(sensor_name), this->sensor_name_template_.c_str(), App.get_name().c_str(), + s.c_str()); + dallastemperaturesensor->set_name(sensor_name); + dallastemperaturesensor->set_unit_of_measurement(this->unit_of_measurement_); + dallastemperaturesensor->set_icon(this->icon_); + dallastemperaturesensor->set_accuracy_decimals(this->accuracy_decimals_); + dallastemperaturesensor->set_force_update(false); + App.register_sensor(dallastemperaturesensor); + } + } } for (auto sensor : this->sensors_) { @@ -156,12 +180,25 @@ void DallasComponent::update() { } } DallasComponent::DallasComponent(ESPOneWire *one_wire) : one_wire_(one_wire) {} +void DallasComponent::set_auto_setup_sensors(bool auto_setup_sensors) { + this->auto_setup_sensors_ = auto_setup_sensors; +} +void DallasComponent::set_sensor_name_template(const std::string &sensor_name_template) { + this->sensor_name_template_ = sensor_name_template; +} +void DallasComponent::set_resolution(uint8_t resolution) { this->resolution_ = resolution; } +void DallasComponent::set_unit_of_measurement(const std::string &unit_of_measurement) { + this->unit_of_measurement_ = unit_of_measurement; +} +void DallasComponent::set_icon(const std::string &icon) { this->icon_ = icon; } +void DallasComponent::set_accuracy_decimals(int8_t accuracy_decimals) { this->accuracy_decimals_ = accuracy_decimals; } DallasTemperatureSensor::DallasTemperatureSensor(uint64_t address, uint8_t resolution, DallasComponent *parent) : parent_(parent) { this->set_address(address); this->set_resolution(resolution); } +const uint64_t &DallasTemperatureSensor::get_address() const { return this->address_; } void DallasTemperatureSensor::set_address(uint64_t address) { this->address_ = address; } uint8_t DallasTemperatureSensor::get_resolution() const { return this->resolution_; } void DallasTemperatureSensor::set_resolution(uint8_t resolution) { this->resolution_ = resolution; } diff --git a/esphome/components/dallas/dallas_component.h b/esphome/components/dallas/dallas_component.h index d32aec1758..f2acf09d75 100644 --- a/esphome/components/dallas/dallas_component.h +++ b/esphome/components/dallas/dallas_component.h @@ -22,12 +22,30 @@ class DallasComponent : public PollingComponent { void update() override; + /// Automatic sensors instantiation + bool get_auto_setup_sensors() const; + void set_auto_setup_sensors(bool auto_setup_sensors); + + /// Get/Set properties for automatically generated sensors. + void set_sensor_name_template(const std::string &sensor_name_template); + void set_resolution(uint8_t resolution); + void set_unit_of_measurement(const std::string &unit_of_measurement); + void set_icon(const std::string &icon); + void set_accuracy_decimals(int8_t accuracy_decimals); + protected: friend DallasTemperatureSensor; ESPOneWire *one_wire_; std::vector sensors_; std::vector found_sensors_; + + bool auto_setup_sensors_; + std::string sensor_name_template_; + uint8_t resolution_; + std::string unit_of_measurement_; + std::string icon_; + int8_t accuracy_decimals_; }; /// Internal class that helps us create multiple sensors for one Dallas hub. @@ -40,6 +58,8 @@ class DallasTemperatureSensor : public sensor::Sensor { /// Helper to create (and cache) the name for this sensor. For example "0xfe0000031f1eaf29". const std::string &get_address_name(); + /// Get the 64-bit unsigned address of this sensor. + const uint64_t &get_address() const; /// Set the 64-bit unsigned address for this sensor. void set_address(uint64_t address); /// Get the index of this sensor. (0 if using address.)