mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 16:37:52 +01:00
Updates
This commit is contained in:
parent
c3d4ef284d
commit
521c080989
@ -48,6 +48,11 @@ void ADCSensor::dump_config() {
|
||||
}
|
||||
float ADCSensor::get_setup_priority() const { return setup_priority::DATA; }
|
||||
void ADCSensor::update() {
|
||||
float value_v = this->sample();
|
||||
ESP_LOGD(TAG, "'%s': Got voltage=%.2fV", this->get_name().c_str(), value_v);
|
||||
this->publish_state(value_v);
|
||||
}
|
||||
float ADCSensor::sample() {
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
float value_v = analogRead(this->pin_) / 4095.0f;
|
||||
switch (this->attenuation_) {
|
||||
@ -64,19 +69,16 @@ void ADCSensor::update() {
|
||||
value_v *= 3.9;
|
||||
break;
|
||||
}
|
||||
return value_v;
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP8266
|
||||
#ifdef USE_ADC_SENSOR_VCC
|
||||
float value_v = ESP.getVcc() / 1024.0f;
|
||||
return ESP.getVcc() / 1024.0f;
|
||||
#else
|
||||
float value_v = analogRead(this->pin_) / 1024.0f;
|
||||
return analogRead(this->pin_) / 1024.0f;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ESP_LOGD(TAG, "'%s': Got voltage=%.2fV", this->get_name().c_str(), value_v);
|
||||
|
||||
this->publish_state(value_v);
|
||||
}
|
||||
#ifdef ARDUINO_ARCH_ESP8266
|
||||
std::string ADCSensor::unique_id() { return get_mac_address() + "-adc"; }
|
||||
|
@ -3,19 +3,23 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/esphal.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/voltage_sampler/voltage_sampler.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace adc {
|
||||
|
||||
class ADCSensor : public sensor::Sensor, public PollingComponent {
|
||||
#ifdef USE_ADC_SENSOR_VCC
|
||||
ADC_MODE(ADC_VCC)
|
||||
#endif
|
||||
|
||||
class ADCSensor : public sensor::Sensor, public PollingComponent,
|
||||
public voltage_sampler::VoltageSampler {
|
||||
public:
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
/// Set the attenuation for this pin. Only available on the ESP32.
|
||||
void set_attenuation(adc_attenuation_t attenuation);
|
||||
#endif
|
||||
|
||||
// ========== INTERNAL METHODS ==========
|
||||
// (In most use cases you won't need these)
|
||||
/// Update adc values.
|
||||
void update() override;
|
||||
/// Setup ADc
|
||||
@ -24,6 +28,7 @@ class ADCSensor : public sensor::Sensor, public PollingComponent {
|
||||
/// `HARDWARE_LATE` setup priority.
|
||||
float get_setup_priority() const override;
|
||||
void set_pin(uint8_t pin) { this->pin_ = pin; }
|
||||
float sample() override;
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP8266
|
||||
std::string unique_id() override;
|
||||
|
@ -1,9 +1,12 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.components import sensor
|
||||
from esphome.components import sensor, voltage_sampler
|
||||
from esphome.const import CONF_ATTENUATION, CONF_ID, CONF_PIN, ICON_FLASH, UNIT_VOLT
|
||||
|
||||
|
||||
AUTO_LOAD = ['voltage_sampler']
|
||||
|
||||
ATTENUATION_MODES = {
|
||||
'0db': cg.global_ns.ADC_0db,
|
||||
'2.5db': cg.global_ns.ADC_2_5db,
|
||||
@ -20,7 +23,8 @@ def validate_adc_pin(value):
|
||||
|
||||
|
||||
adc_ns = cg.esphome_ns.namespace('adc')
|
||||
ADCSensor = adc_ns.class_('ADCSensor', sensor.PollingSensorComponent)
|
||||
ADCSensor = adc_ns.class_('ADCSensor', sensor.Sensor, cg.PollingComponent,
|
||||
voltage_sampler.VoltageSampler)
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_VOLT, ICON_FLASH, 2).extend({
|
||||
cv.GenerateID(): cv.declare_id(ADCSensor),
|
||||
@ -37,7 +41,6 @@ def to_code(config):
|
||||
|
||||
if config[CONF_PIN] == 'VCC':
|
||||
cg.add_define('USE_ADC_SENSOR_VCC')
|
||||
cg.add_global(cg.global_ns.ADC_MODE(cg.global_ns.ADC_VCC))
|
||||
else:
|
||||
cg.add(var.set_pin(config[CONF_PIN]))
|
||||
|
||||
|
@ -4,7 +4,7 @@ from esphome.components import i2c
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
AUTO_LOAD = ['sensor']
|
||||
AUTO_LOAD = ['sensor', 'voltage_sampler']
|
||||
MULTI_CONF = True
|
||||
|
||||
ads1115_ns = cg.esphome_ns.namespace('ads1115')
|
||||
|
@ -59,7 +59,9 @@ void ADS1115Component::setup() {
|
||||
}
|
||||
for (auto *sensor : this->sensors_) {
|
||||
this->set_interval(sensor->get_name(), sensor->update_interval(),
|
||||
[this, sensor] { this->request_measurement_(sensor); });
|
||||
[this, sensor] {
|
||||
this->request_measurement_(sensor);
|
||||
});
|
||||
}
|
||||
}
|
||||
void ADS1115Component::dump_config() {
|
||||
@ -76,11 +78,11 @@ void ADS1115Component::dump_config() {
|
||||
}
|
||||
}
|
||||
float ADS1115Component::get_setup_priority() const { return setup_priority::DATA; }
|
||||
void ADS1115Component::request_measurement_(ADS1115Sensor *sensor) {
|
||||
float ADS1115Component::request_measurement_(ADS1115Sensor *sensor) {
|
||||
uint16_t config;
|
||||
if (!this->read_byte_16(ADS1115_REGISTER_CONFIG, &config)) {
|
||||
this->status_set_warning();
|
||||
return;
|
||||
return NAN;
|
||||
}
|
||||
// Multiplexer
|
||||
// 0bxBBBxxxxxxxxxxxx
|
||||
@ -96,7 +98,7 @@ void ADS1115Component::request_measurement_(ADS1115Sensor *sensor) {
|
||||
|
||||
if (!this->write_byte_16(ADS1115_REGISTER_CONFIG, config)) {
|
||||
this->status_set_warning();
|
||||
return;
|
||||
return NAN;
|
||||
}
|
||||
|
||||
// about 1.6 ms with 860 samples per second
|
||||
@ -107,7 +109,7 @@ void ADS1115Component::request_measurement_(ADS1115Sensor *sensor) {
|
||||
if (millis() - start > 100) {
|
||||
ESP_LOGW(TAG, "Reading ADS1115 timed out");
|
||||
this->status_set_warning();
|
||||
return;
|
||||
return NAN;
|
||||
}
|
||||
yield();
|
||||
}
|
||||
@ -115,7 +117,7 @@ void ADS1115Component::request_measurement_(ADS1115Sensor *sensor) {
|
||||
uint16_t raw_conversion;
|
||||
if (!this->read_byte_16(ADS1115_REGISTER_CONVERSION, &raw_conversion)) {
|
||||
this->status_set_warning();
|
||||
return;
|
||||
return NAN;
|
||||
}
|
||||
auto signed_conversion = static_cast<int16_t>(raw_conversion);
|
||||
|
||||
@ -143,16 +145,24 @@ void ADS1115Component::request_measurement_(ADS1115Sensor *sensor) {
|
||||
millivolts = NAN;
|
||||
}
|
||||
|
||||
float v = millivolts / 1000.0f;
|
||||
ESP_LOGD(TAG, "'%s': Got Voltage=%fV", sensor->get_name().c_str(), v);
|
||||
sensor->publish_state(v);
|
||||
this->status_clear_warning();
|
||||
return millivolts / 1e4f;
|
||||
}
|
||||
|
||||
uint8_t ADS1115Sensor::get_multiplexer() const { return this->multiplexer_; }
|
||||
void ADS1115Sensor::set_multiplexer(ADS1115Multiplexer multiplexer) { this->multiplexer_ = multiplexer; }
|
||||
uint8_t ADS1115Sensor::get_gain() const { return this->gain_; }
|
||||
void ADS1115Sensor::set_gain(ADS1115Gain gain) { this->gain_ = gain; }
|
||||
float ADS1115Sensor::sample() {
|
||||
return this->parent_->request_measurement_(this);
|
||||
}
|
||||
void ADS1115Sensor::update() {
|
||||
float v = this->parent_->request_measurement_(this);
|
||||
if (!isnan(v)) {
|
||||
ESP_LOGD(TAG, "'%s': Got Voltage=%fV", this->get_name().c_str(), v);
|
||||
this->publish_state(v);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ads1115
|
||||
} // namespace esphome
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/components/voltage_sampler/voltage_sampler.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace ads1115 {
|
||||
@ -38,28 +39,30 @@ class ADS1115Component : public Component, public i2c::I2CDevice {
|
||||
/// HARDWARE_LATE setup priority
|
||||
float get_setup_priority() const override;
|
||||
|
||||
protected:
|
||||
/// Helper method to request a measurement from a sensor.
|
||||
void request_measurement_(ADS1115Sensor *sensor);
|
||||
float request_measurement_(ADS1115Sensor *sensor);
|
||||
|
||||
protected:
|
||||
std::vector<ADS1115Sensor *> sensors_;
|
||||
};
|
||||
|
||||
/// Internal holder class that is in instance of Sensor so that the hub can create individual sensors.
|
||||
class ADS1115Sensor : public sensor::Sensor {
|
||||
class ADS1115Sensor : public sensor::Sensor, public PollingComponent,
|
||||
public voltage_sampler::VoltageSampler {
|
||||
public:
|
||||
ADS1115Sensor(ADS1115Component *parent) : parent_(parent) {}
|
||||
void update() override;
|
||||
void set_multiplexer(ADS1115Multiplexer multiplexer);
|
||||
void set_gain(ADS1115Gain gain);
|
||||
|
||||
// ========== INTERNAL METHODS ==========
|
||||
// (In most use cases you won't need these)
|
||||
float sample() override;
|
||||
uint8_t get_multiplexer() const;
|
||||
uint8_t get_gain() const;
|
||||
|
||||
protected:
|
||||
ADS1115Component *parent_;
|
||||
ADS1115Multiplexer multiplexer_;
|
||||
ADS1115Gain gain_;
|
||||
uint32_t update_interval_;
|
||||
};
|
||||
|
||||
} // namespace ads1115
|
||||
|
@ -1,6 +1,6 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor
|
||||
from esphome.components import sensor, voltage_sampler
|
||||
from esphome.components.ads1115 import ADS1115Component
|
||||
from esphome.const import CONF_GAIN, CONF_MULTIPLEXER, ICON_FLASH, UNIT_VOLT, CONF_ID
|
||||
from esphome.py_compat import string_types
|
||||
@ -40,7 +40,8 @@ def validate_gain(value):
|
||||
return cv.enum(GAIN)(value)
|
||||
|
||||
|
||||
ADS1115Sensor = ads1115_ns.class_('ADS1115Sensor', sensor.Sensor)
|
||||
ADS1115Sensor = ads1115_ns.class_('ADS1115Sensor', sensor.Sensor, cg.PollingComponent,
|
||||
voltage_sampler.VoltageSampler)
|
||||
|
||||
CONF_ADS1115_ID = 'ads1115_id'
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_VOLT, ICON_FLASH, 3).extend({
|
||||
@ -52,11 +53,12 @@ CONFIG_SCHEMA = sensor.sensor_schema(UNIT_VOLT, ICON_FLASH, 3).extend({
|
||||
|
||||
|
||||
def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
paren = yield cg.get_variable(config[CONF_ADS1115_ID])
|
||||
var = cg.new_Pvariable(config[CONF_ID], paren)
|
||||
yield sensor.register_sensor(var, config)
|
||||
yield cg.register_component(var, config)
|
||||
|
||||
cg.add(var.set_multiplexer(config[CONF_MULTIPLEXER]))
|
||||
cg.add(var.set_gain(config[CONF_GAIN]))
|
||||
|
||||
hub = yield cg.get_variable(config[CONF_ADS1115_ID])
|
||||
cg.add(hub.register_sensor(var))
|
||||
cg.add(paren.register_sensor(var))
|
||||
|
@ -260,7 +260,6 @@ APIConnection::APIConnection(AsyncClient *client, APIServer *parent)
|
||||
}
|
||||
APIConnection::~APIConnection() { delete this->client_; }
|
||||
void APIConnection::on_error_(int8_t error) {
|
||||
ESP_LOGD(TAG, "Error from client '%s': %d", this->client_info_.c_str(), error);
|
||||
// disconnect will also be called, nothing to do here
|
||||
this->remove_ = true;
|
||||
}
|
||||
|
18
esphome/components/ble_ibeacon/__init__.py
Normal file
18
esphome/components/ble_ibeacon/__init__.py
Normal file
@ -0,0 +1,18 @@
|
||||
import esphome.config_validation as cv
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import esp32_ble_tracker
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
DEPENDENCIES = ['esp32_ble_tracker']
|
||||
ble_ibeacon_ns = cg.esphome_ns.namespace('ble_ibeacon')
|
||||
IBeaconListener = ble_ibeacon_ns.class_('IBeaconListener', esp32_ble_tracker.ESPBTDeviceListener)
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(IBeaconListener),
|
||||
}).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
yield esp32_ble_tracker.register_ble_device(var, config)
|
@ -1,24 +1,24 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import binary_sensor
|
||||
from esphome.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP_BLE_DEVICE_SCHEMA, \
|
||||
ESPBTDeviceListener
|
||||
from esphome.const import CONF_MAC_ADDRESS, CONF_NAME, CONF_ID
|
||||
from esphome.components import binary_sensor, esp32_ble_tracker
|
||||
from esphome.const import CONF_MAC_ADDRESS, CONF_ID
|
||||
|
||||
DEPENDENCIES = ['esp32_ble_tracker']
|
||||
|
||||
ble_presence_ns = cg.esphome_ns.namespace('ble_presence')
|
||||
BLEPresenceDevice = ble_presence_ns.class_('BLEPresenceDevice', binary_sensor.BinarySensor,
|
||||
cg.Component, ESPBTDeviceListener)
|
||||
cg.Component, esp32_ble_tracker.ESPBTDeviceListener)
|
||||
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(BLEPresenceDevice),
|
||||
cv.Required(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
}).extend(ESP_BLE_DEVICE_SCHEMA).extend(cv.COMPONENT_SCHEMA)
|
||||
}).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
hub = yield cg.get_variable(config[CONF_ESP32_BLE_ID])
|
||||
var = cg.new_Pvariable(config[CONF_ID], config[CONF_NAME], hub, config[CONF_MAC_ADDRESS].as_hex)
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
yield cg.register_component(var, config)
|
||||
yield esp32_ble_tracker.register_ble_device(var, config)
|
||||
yield binary_sensor.register_binary_sensor(var, config)
|
||||
|
||||
cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex))
|
||||
|
@ -13,9 +13,9 @@ class BLEPresenceDevice : public binary_sensor::BinarySensor,
|
||||
public esp32_ble_tracker::ESPBTDeviceListener,
|
||||
public Component {
|
||||
public:
|
||||
BLEPresenceDevice(const std::string &name, esp32_ble_tracker::ESP32BLETracker *parent, uint64_t address)
|
||||
: binary_sensor::BinarySensor(name), esp32_ble_tracker::ESPBTDeviceListener(parent), address_(address) {}
|
||||
|
||||
void set_address(uint64_t address) {
|
||||
address_ = address;
|
||||
}
|
||||
void on_scan_end() override {
|
||||
if (!this->found_)
|
||||
this->publish_state(false);
|
||||
@ -29,7 +29,6 @@ class BLEPresenceDevice : public binary_sensor::BinarySensor,
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void setup() override { this->setup_ble(); }
|
||||
void dump_config() override;
|
||||
float get_setup_priority() const override { return setup_priority::DATA; }
|
||||
|
||||
|
@ -11,9 +11,9 @@ namespace ble_rssi {
|
||||
|
||||
class BLERSSISensor : public sensor::Sensor, public esp32_ble_tracker::ESPBTDeviceListener, public Component {
|
||||
public:
|
||||
BLERSSISensor(const std::string &name, esp32_ble_tracker::ESP32BLETracker *parent, uint64_t address)
|
||||
: sensor::Sensor(name), esp32_ble_tracker::ESPBTDeviceListener(parent), address_(address) {}
|
||||
|
||||
void set_address(uint64_t address) {
|
||||
address_ = address;
|
||||
}
|
||||
void on_scan_end() override {
|
||||
if (!this->found_)
|
||||
this->publish_state(NAN);
|
||||
@ -27,7 +27,6 @@ class BLERSSISensor : public sensor::Sensor, public esp32_ble_tracker::ESPBTDevi
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void setup() override { this->setup_ble(); }
|
||||
void dump_config() override;
|
||||
float get_setup_priority() const override { return setup_priority::DATA; }
|
||||
|
||||
|
@ -1,24 +1,24 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor
|
||||
from esphome.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESPBTDeviceListener, \
|
||||
ESP_BLE_DEVICE_SCHEMA
|
||||
from esphome.const import CONF_MAC_ADDRESS, CONF_NAME, CONF_ID, UNIT_DECIBEL, ICON_SIGNAL
|
||||
from esphome.components import sensor, esp32_ble_tracker
|
||||
from esphome.const import CONF_MAC_ADDRESS, CONF_ID, UNIT_DECIBEL, ICON_SIGNAL
|
||||
|
||||
DEPENDENCIES = ['esp32_ble_tracker']
|
||||
|
||||
ble_rssi_ns = cg.esphome_ns.namespace('ble_rssi')
|
||||
BLERSSISensor = ble_rssi_ns.class_('BLERSSISensor', sensor.Sensor, cg.Component,
|
||||
ESPBTDeviceListener)
|
||||
esp32_ble_tracker.ESPBTDeviceListener)
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_DECIBEL, ICON_SIGNAL, 0).extend({
|
||||
cv.GenerateID(): cv.declare_id(BLERSSISensor),
|
||||
cv.Required(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
}).extend(ESP_BLE_DEVICE_SCHEMA).extend(cv.COMPONENT_SCHEMA)
|
||||
}).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
hub = yield cg.get_variable(config[CONF_ESP32_BLE_ID])
|
||||
var = cg.new_Pvariable(config[CONF_ID], config[CONF_NAME], hub, config[CONF_MAC_ADDRESS].as_hex)
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
yield cg.register_component(var, config)
|
||||
yield esp32_ble_tracker.register_ble_device(var, config)
|
||||
yield sensor.register_sensor(var, config)
|
||||
|
||||
cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex))
|
||||
|
@ -1,9 +1,10 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_SCAN_INTERVAL, ESP_PLATFORM_ESP32
|
||||
from esphome.core import coroutine
|
||||
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||
AUTO_LOAD = ['xiaomi_ble']
|
||||
AUTO_LOAD = ['xiaomi_ble', 'ble_ibeacon']
|
||||
|
||||
CONF_ESP32_BLE_ID = 'esp32_ble_id'
|
||||
esp32_ble_tracker_ns = cg.esphome_ns.namespace('esp32_ble_tracker')
|
||||
@ -24,3 +25,10 @@ def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
yield cg.register_component(var, config)
|
||||
cg.add(var.set_scan_interval(config[CONF_SCAN_INTERVAL]))
|
||||
|
||||
|
||||
@coroutine
|
||||
def register_ble_device(var, config):
|
||||
paren = yield cg.get_variable(config[CONF_ESP32_BLE_ID])
|
||||
cg.add(paren.register_listener(var))
|
||||
yield var
|
||||
|
@ -201,6 +201,22 @@ void ESP32BLETracker::gap_scan_result(const esp_ble_gap_cb_param_t::ble_scan_res
|
||||
}
|
||||
}
|
||||
|
||||
std::string hexencode(const std::string &raw_data) {
|
||||
char buf[20];
|
||||
std::string res;
|
||||
for (size_t i = 0; i < raw_data.size(); i++) {
|
||||
if (i + 1 != raw_data.size()) {
|
||||
sprintf(buf, "0x%02X.", static_cast<uint8_t>(raw_data[i]));
|
||||
} else {
|
||||
sprintf(buf, "0x%02X ", static_cast<uint8_t>(raw_data[i]));
|
||||
}
|
||||
res += buf;
|
||||
}
|
||||
sprintf(buf, "(%zu)", raw_data.size());
|
||||
res += buf;
|
||||
return res;
|
||||
}
|
||||
|
||||
ESPBTUUID::ESPBTUUID() : uuid_() {}
|
||||
ESPBTUUID ESPBTUUID::from_uint16(uint16_t uuid) {
|
||||
ESPBTUUID ret;
|
||||
@ -259,12 +275,22 @@ std::string ESPBTUUID::to_string() {
|
||||
return sbuf;
|
||||
}
|
||||
|
||||
ESPBLEiBeacon::ESPBLEiBeacon(const uint8_t *data) { memcpy(&this->beacon_data_, data, sizeof(beacon_data_)); }
|
||||
optional<ESPBLEiBeacon> ESPBLEiBeacon::from_manufacturer_data(const std::string &data) {
|
||||
if (data.size() != 25)
|
||||
return {};
|
||||
if (data[0] != 0x4C || data[1] != 0x00)
|
||||
return {};
|
||||
|
||||
return ESPBLEiBeacon(reinterpret_cast<const uint8_t *>(data.data()));
|
||||
}
|
||||
|
||||
void ESPBTDevice::parse_scan_rst(const esp_ble_gap_cb_param_t::ble_scan_result_evt_param ¶m) {
|
||||
for (uint8_t i = 0; i < ESP_BD_ADDR_LEN; i++)
|
||||
this->address_[i] = param.bda[i];
|
||||
this->address_type_ = param.ble_addr_type;
|
||||
this->rssi_ = param.rssi;
|
||||
this->parse_adv(param);
|
||||
this->parse_adv_(param);
|
||||
|
||||
#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
|
||||
ESP_LOGVV(TAG, "Parse Result:");
|
||||
@ -287,7 +313,7 @@ void ESPBTDevice::parse_scan_rst(const esp_ble_gap_cb_param_t::ble_scan_result_e
|
||||
this->address_[2], this->address_[3], this->address_[4], this->address_[5], address_type);
|
||||
|
||||
ESP_LOGVV(TAG, " RSSI: %d", this->rssi_);
|
||||
ESP_LOGVV(TAG, " Name: %s", this->name_.c_str());
|
||||
ESP_LOGVV(TAG, " Name: '%s'", this->name_.c_str());
|
||||
if (this->tx_power_.has_value()) {
|
||||
ESP_LOGVV(TAG, " TX Power: %d", *this->tx_power_);
|
||||
}
|
||||
@ -300,26 +326,18 @@ void ESPBTDevice::parse_scan_rst(const esp_ble_gap_cb_param_t::ble_scan_result_e
|
||||
for (auto uuid : this->service_uuids_) {
|
||||
ESP_LOGVV(TAG, " Service UUID: %s", uuid.to_string().c_str());
|
||||
}
|
||||
ESP_LOGVV(TAG, " Manufacturer data: '%s'", this->manufacturer_data_.c_str());
|
||||
ESP_LOGVV(TAG, " Service data: '%s'", this->service_data_.c_str());
|
||||
ESP_LOGVV(TAG, " Manufacturer data: %s", hexencode(this->manufacturer_data_).c_str());
|
||||
ESP_LOGVV(TAG, " Service data: %s", hexencode(this->service_data_).c_str());
|
||||
|
||||
if (this->service_data_uuid_.has_value()) {
|
||||
ESP_LOGVV(TAG, " Service Data UUID: %s", this->service_data_uuid_->to_string().c_str());
|
||||
}
|
||||
|
||||
char buffer[200];
|
||||
size_t off = 0;
|
||||
for (uint8_t i = 0; i < param.adv_data_len; i++) {
|
||||
int ret = snprintf(buffer + off, sizeof(buffer) - off, "%02X.", param.ble_adv[i]);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
off += ret;
|
||||
}
|
||||
ESP_LOGVV(TAG, "Adv data: %s (%u bytes)", buffer, param.adv_data_len);
|
||||
ESP_LOGVV(TAG, "Adv data: %s",
|
||||
hexencode(std::string(reinterpret_cast<const char *>(param.ble_adv), param.adv_data_len)).c_str());
|
||||
#endif
|
||||
}
|
||||
void ESPBTDevice::parse_adv(const esp_ble_gap_cb_param_t::ble_scan_result_evt_param ¶m) {
|
||||
void ESPBTDevice::parse_adv_(const esp_ble_gap_cb_param_t::ble_scan_result_evt_param ¶m) {
|
||||
size_t offset = 0;
|
||||
const uint8_t *payload = param.ble_adv;
|
||||
uint8_t len = param.adv_data_len;
|
||||
@ -472,8 +490,6 @@ void ESP32BLETracker::print_bt_device_info(const ESPBTDevice &device) {
|
||||
}
|
||||
}
|
||||
|
||||
void ESPBTDeviceListener::setup_ble() { this->parent_->add_listener(this); }
|
||||
|
||||
} // namespace esp32_ble_tracker
|
||||
} // namespace esphome
|
||||
|
||||
|
@ -31,12 +31,31 @@ class ESPBTUUID {
|
||||
esp_bt_uuid_t uuid_;
|
||||
};
|
||||
|
||||
class ESPBLEiBeacon {
|
||||
public:
|
||||
ESPBLEiBeacon(const uint8_t *data);
|
||||
static optional<ESPBLEiBeacon> from_manufacturer_data(const std::string &data);
|
||||
|
||||
uint16_t get_major() { return reverse_bits_16(this->beacon_data_.major); }
|
||||
uint16_t get_minor() { return reverse_bits_16(this->beacon_data_.minor); }
|
||||
int8_t get_signal_power() { return this->beacon_data_.signal_power; }
|
||||
ESPBTUUID get_uuid() { return ESPBTUUID::from_raw(this->beacon_data_.proximity_uuid); }
|
||||
|
||||
protected:
|
||||
struct {
|
||||
uint16_t manufacturer_id;
|
||||
uint8_t sub_type;
|
||||
uint8_t proximity_uuid[16];
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
int8_t signal_power;
|
||||
} PACKED beacon_data_;
|
||||
};
|
||||
|
||||
class ESPBTDevice {
|
||||
public:
|
||||
void parse_scan_rst(const esp_ble_gap_cb_param_t::ble_scan_result_evt_param ¶m);
|
||||
|
||||
void parse_adv(const esp_ble_gap_cb_param_t::ble_scan_result_evt_param ¶m);
|
||||
|
||||
std::string address_str() const;
|
||||
|
||||
uint64_t address_uint64() const;
|
||||
@ -51,8 +70,13 @@ class ESPBTDevice {
|
||||
const std::string &get_manufacturer_data() const;
|
||||
const std::string &get_service_data() const;
|
||||
const optional<ESPBTUUID> &get_service_data_uuid() const;
|
||||
const optional<ESPBLEiBeacon> get_ibeacon() const {
|
||||
return ESPBLEiBeacon::from_manufacturer_data(this->manufacturer_data_);
|
||||
}
|
||||
|
||||
protected:
|
||||
void parse_adv_(const esp_ble_gap_cb_param_t::ble_scan_result_evt_param ¶m);
|
||||
|
||||
esp_bd_addr_t address_{
|
||||
0,
|
||||
};
|
||||
@ -72,28 +96,30 @@ class ESP32BLETracker;
|
||||
|
||||
class ESPBTDeviceListener {
|
||||
public:
|
||||
ESPBTDeviceListener(ESP32BLETracker *parent) : parent_(parent) {}
|
||||
void setup_ble();
|
||||
virtual void on_scan_end() {}
|
||||
virtual bool parse_device(const ESPBTDevice &device) = 0;
|
||||
void set_parent(ESP32BLETracker *parent) {
|
||||
parent_ = parent;
|
||||
}
|
||||
|
||||
protected:
|
||||
ESP32BLETracker *parent_;
|
||||
ESP32BLETracker *parent_{nullptr};
|
||||
};
|
||||
|
||||
class ESP32BLETracker : public Component {
|
||||
public:
|
||||
void set_scan_interval(uint32_t scan_interval);
|
||||
|
||||
// ========== INTERNAL METHODS ==========
|
||||
// (In most use cases you won't need these)
|
||||
/// Setup the FreeRTOS task and the Bluetooth stack.
|
||||
void setup() override;
|
||||
void dump_config() override;
|
||||
|
||||
void loop() override;
|
||||
|
||||
void add_listener(ESPBTDeviceListener *listener) { this->listeners_.push_back(listener); }
|
||||
void register_listener(ESPBTDeviceListener *listener) {
|
||||
listener->set_parent(this);
|
||||
this->listeners_.push_back(listener);
|
||||
}
|
||||
|
||||
void print_bt_device_info(const ESPBTDevice &device);
|
||||
|
||||
|
@ -112,7 +112,7 @@ template<typename... Ts> class AddressableSet : public Action<Ts...> {
|
||||
void play(Ts... x) override {
|
||||
auto *out = (AddressableLight *) this->parent_->get_output();
|
||||
int32_t range_from = this->range_from_.value_or(x..., 0);
|
||||
int32_t range_to = this->range_to_.value_or(x..., out->size());
|
||||
int32_t range_to = this->range_to_.value_or(x..., out->size() - 1) + 1;
|
||||
auto range = out->range(range_from, range_to);
|
||||
if (this->red_.has_value())
|
||||
range.set_red(this->red_.value(x...));
|
||||
|
@ -3,8 +3,9 @@ import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.const import CONF_ID, CONF_TRANSITION_LENGTH, CONF_STATE, CONF_FLASH_LENGTH, \
|
||||
CONF_EFFECT, CONF_BRIGHTNESS, CONF_RED, CONF_GREEN, CONF_BLUE, CONF_WHITE, \
|
||||
CONF_COLOR_TEMPERATURE
|
||||
from .types import DimRelativeAction, ToggleAction, LightState, LightControlAction
|
||||
CONF_COLOR_TEMPERATURE, CONF_RANGE_FROM, CONF_RANGE_TO
|
||||
from .types import DimRelativeAction, ToggleAction, LightState, LightControlAction, \
|
||||
AddressableLightState, AddressableSet
|
||||
|
||||
|
||||
@automation.register_action('light.toggle', ToggleAction, automation.maybe_simple_id({
|
||||
@ -87,7 +88,7 @@ def light_control_to_code(config, action_id, template_arg, args):
|
||||
CONF_RELATIVE_BRIGHTNESS = 'relative_brightness'
|
||||
LIGHT_DIM_RELATIVE_ACTION_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.use_id(LightState),
|
||||
cv.Required(CONF_RELATIVE_BRIGHTNESS): cv.templatable(cv.percentage),
|
||||
cv.Required(CONF_RELATIVE_BRIGHTNESS): cv.templatable(cv.possibly_negative_percentage),
|
||||
cv.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
|
||||
})
|
||||
|
||||
@ -103,3 +104,41 @@ def light_dim_relative_to_code(config, action_id, template_arg, args):
|
||||
templ = yield cg.templatable(config[CONF_TRANSITION_LENGTH], args, cg.uint32)
|
||||
cg.add(var.set_transition_length(templ))
|
||||
yield var
|
||||
|
||||
|
||||
LIGHT_ADDRESSABLE_SET_ACTION_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.use_id(AddressableLightState),
|
||||
cv.Optional(CONF_RANGE_FROM): cv.templatable(cv.positive_int),
|
||||
cv.Optional(CONF_RANGE_TO): cv.templatable(cv.positive_int),
|
||||
cv.Optional(CONF_RED): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_GREEN): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_BLUE): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_WHITE): cv.templatable(cv.percentage),
|
||||
})
|
||||
|
||||
|
||||
@automation.register_action('light.addressable_set', AddressableSet,
|
||||
LIGHT_ADDRESSABLE_SET_ACTION_SCHEMA)
|
||||
def light_addressable_set_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
if CONF_RANGE_FROM in config:
|
||||
templ = yield cg.templatable(config[CONF_RANGE_FROM], args, cg.int32)
|
||||
cg.add(var.set_range_from(templ))
|
||||
if CONF_RANGE_TO in config:
|
||||
templ = yield cg.templatable(config[CONF_RANGE_TO], args, cg.int32)
|
||||
cg.add(var.set_range_to(templ))
|
||||
rgbw_to_exp = lambda x: int(round(x * 255))
|
||||
if CONF_RED in config:
|
||||
templ = yield cg.templatable(config[CONF_RED], args, cg.uint8, to_exp=rgbw_to_exp)
|
||||
cg.add(var.set_red(templ))
|
||||
if CONF_GREEN in config:
|
||||
templ = yield cg.templatable(config[CONF_GREEN], args, cg.uint8, to_exp=rgbw_to_exp)
|
||||
cg.add(var.set_green(templ))
|
||||
if CONF_BLUE in config:
|
||||
templ = yield cg.templatable(config[CONF_BLUE], args, cg.uint8, to_exp=rgbw_to_exp)
|
||||
cg.add(var.set_blue(templ))
|
||||
if CONF_WHITE in config:
|
||||
templ = yield cg.templatable(config[CONF_WHITE], args, cg.uint8, to_exp=rgbw_to_exp)
|
||||
cg.add(var.set_white(templ))
|
||||
yield var
|
||||
|
@ -15,6 +15,7 @@ LightColorValues = light_ns.class_('LightColorValues')
|
||||
ToggleAction = light_ns.class_('ToggleAction', automation.Action)
|
||||
LightControlAction = light_ns.class_('LightControlAction', automation.Action)
|
||||
DimRelativeAction = light_ns.class_('DimRelativeAction', automation.Action)
|
||||
AddressableSet = light_ns.class_('AddressableSet', automation.Action)
|
||||
|
||||
# Effects
|
||||
LightEffect = light_ns.class_('LightEffect')
|
||||
|
@ -71,6 +71,7 @@ def validate_local_no_higher_than_global(value):
|
||||
|
||||
Logger = logger_ns.class_('Logger', cg.Component)
|
||||
|
||||
CONF_ESP8266_STORE_LOG_STRINGS_IN_FLASH = 'esp8266_store_log_strings_in_flash'
|
||||
CONFIG_SCHEMA = cv.All(cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(Logger),
|
||||
cv.Optional(CONF_BAUD_RATE, default=115200): cv.positive_int,
|
||||
@ -79,7 +80,10 @@ CONFIG_SCHEMA = cv.All(cv.Schema({
|
||||
cv.Optional(CONF_LEVEL, default='DEBUG'): is_log_level,
|
||||
cv.Optional(CONF_LOGS, default={}): cv.Schema({
|
||||
cv.string: is_log_level,
|
||||
})
|
||||
}),
|
||||
|
||||
cv.SplitDefault(CONF_ESP8266_STORE_LOG_STRINGS_IN_FLASH, esp8266=True):
|
||||
cv.All(cv.only_on_esp8266, cv.boolean),
|
||||
}).extend(cv.COMPONENT_SCHEMA), validate_local_no_higher_than_global)
|
||||
|
||||
|
||||
@ -126,7 +130,7 @@ def to_code(config):
|
||||
cg.add_build_flag('-DCORE_DEBUG_LEVEL=5')
|
||||
if CORE.is_esp32 and is_at_least_very_verbose:
|
||||
cg.add_build_flag('-DENABLE_I2C_DEBUG_BUFFER')
|
||||
if CORE.is_esp8266:
|
||||
if config.get(CONF_ESP8266_STORE_LOG_STRINGS_IN_FLASH):
|
||||
cg.add_build_flag('-DUSE_STORE_LOG_STR_IN_FLASH')
|
||||
|
||||
# Register at end for safe mode
|
||||
|
@ -99,17 +99,18 @@ void MPU6050Component::dump_config() {
|
||||
|
||||
void MPU6050Component::update() {
|
||||
ESP_LOGV(TAG, " Updating MPU6050...");
|
||||
uint16_t data[7];
|
||||
if (!this->read_bytes_16(MPU6050_REGISTER_ACCEL_XOUT_H, data, 7)) {
|
||||
uint16_t raw_data[7];
|
||||
if (!this->read_bytes_16(MPU6050_REGISTER_ACCEL_XOUT_H, raw_data, 7)) {
|
||||
this->status_set_warning();
|
||||
return;
|
||||
}
|
||||
auto *data = reinterpret_cast<int16_t *>(raw_data);
|
||||
|
||||
float accel_x = data[0] * MPU6050_RANGE_PER_DIGIT_2G * GRAVITY_EARTH;
|
||||
float accel_y = data[1] * MPU6050_RANGE_PER_DIGIT_2G * GRAVITY_EARTH;
|
||||
float accel_z = data[2] * MPU6050_RANGE_PER_DIGIT_2G * GRAVITY_EARTH;
|
||||
|
||||
float temperature = data[3] / 340.0f + 36.53f;
|
||||
float temperature = raw_data[3] / 340.0f + 36.53f;
|
||||
|
||||
float gyro_x = data[4] * MPU6050_SCALE_DPS_PER_DIGIT_2000;
|
||||
float gyro_y = data[5] * MPU6050_SCALE_DPS_PER_DIGIT_2000;
|
||||
|
@ -51,8 +51,6 @@ sensor_ns = cg.esphome_ns.namespace('sensor')
|
||||
Sensor = sensor_ns.class_('Sensor', cg.Nameable)
|
||||
SensorPtr = Sensor.operator('ptr')
|
||||
|
||||
PollingSensorComponent = sensor_ns.class_('PollingSensorComponent', cg.PollingComponent, Sensor)
|
||||
|
||||
# Triggers
|
||||
SensorStateTrigger = sensor_ns.class_('SensorStateTrigger', automation.Trigger.template(cg.float_))
|
||||
SensorRawStateTrigger = sensor_ns.class_('SensorRawStateTrigger',
|
||||
|
@ -11,16 +11,6 @@ namespace time {
|
||||
static const char *TAG = "time";
|
||||
|
||||
RealTimeClock::RealTimeClock() = default;
|
||||
ESPTime RealTimeClock::now() {
|
||||
time_t t = ::time(nullptr);
|
||||
struct tm *c_tm = ::localtime(&t);
|
||||
return ESPTime::from_tm(c_tm, t);
|
||||
}
|
||||
ESPTime RealTimeClock::utcnow() {
|
||||
time_t t = ::time(nullptr);
|
||||
struct tm *c_tm = ::gmtime(&t);
|
||||
return ESPTime::from_tm(c_tm, t);
|
||||
}
|
||||
void RealTimeClock::call_setup() {
|
||||
this->setup_internal_();
|
||||
setenv("TZ", this->timezone_.c_str(), 1);
|
||||
@ -44,7 +34,7 @@ size_t ESPTime::strftime(char *buffer, size_t buffer_len, const char *format) {
|
||||
struct tm c_tm = this->to_c_tm();
|
||||
return ::strftime(buffer, buffer_len, format, &c_tm);
|
||||
}
|
||||
ESPTime ESPTime::from_tm(struct tm *c_tm, time_t c_time) {
|
||||
ESPTime ESPTime::from_c_tm(struct tm *c_tm, time_t c_time) {
|
||||
return ESPTime{.second = uint8_t(c_tm->tm_sec),
|
||||
.minute = uint8_t(c_tm->tm_min),
|
||||
.hour = uint8_t(c_tm->tm_hour),
|
||||
|
@ -52,7 +52,26 @@ struct ESPTime {
|
||||
|
||||
bool in_range() const;
|
||||
|
||||
static ESPTime from_tm(struct tm *c_tm, time_t c_time);
|
||||
static ESPTime from_c_tm(struct tm *c_tm, time_t c_time);
|
||||
|
||||
/** Convert an epoch timestamp to an ESPTime instance of local time.
|
||||
*
|
||||
* @param epoch Seconds since 1st January 1970. In UTC.
|
||||
* @return The generated ESPTime
|
||||
*/
|
||||
static ESPTime from_epoch_local(time_t epoch) {
|
||||
struct tm *c_tm = ::localtime(&epoch);
|
||||
return ESPTime::from_c_tm(c_tm, epoch);
|
||||
}
|
||||
/** Convert an epoch timestamp to an ESPTime instance of UTC time.
|
||||
*
|
||||
* @param epoch Seconds since 1st January 1970. In UTC.
|
||||
* @return The generated ESPTime
|
||||
*/
|
||||
static ESPTime from_epoch_utc(time_t epoch) {
|
||||
struct tm *c_tm = ::gmtime(&epoch);
|
||||
return ESPTime::from_c_tm(c_tm, epoch);
|
||||
}
|
||||
|
||||
struct tm to_c_tm();
|
||||
|
||||
@ -81,10 +100,19 @@ class RealTimeClock : public Component {
|
||||
std::string get_timezone() { return this->timezone_; }
|
||||
|
||||
/// Get the time in the currently defined timezone.
|
||||
ESPTime now();
|
||||
ESPTime now() {
|
||||
return ESPTime::from_epoch_utc(this->timestamp_now());
|
||||
}
|
||||
|
||||
/// Get the time without any time zone or DST corrections.
|
||||
ESPTime utcnow();
|
||||
ESPTime utcnow() {
|
||||
return ESPTime::from_epoch_local(this->timestamp_now());
|
||||
}
|
||||
|
||||
/// Get the current time as the UTC epoch since January 1st 1970.
|
||||
time_t timestamp_now() {
|
||||
return ::time(nullptr);
|
||||
}
|
||||
|
||||
void call_setup() override;
|
||||
|
||||
|
4
esphome/components/voltage_sampler/__init__.py
Normal file
4
esphome/components/voltage_sampler/__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
import esphome.codegen as cg
|
||||
|
||||
voltage_sampler_ns = cg.esphome_ns.namespace('voltage_sampler')
|
||||
VoltageSampler = voltage_sampler_ns.class_('VoltageSampler')
|
16
esphome/components/voltage_sampler/voltage_sampler.h
Normal file
16
esphome/components/voltage_sampler/voltage_sampler.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace voltage_sampler {
|
||||
|
||||
/// Abstract interface for components to request voltage (usually ADC readings)
|
||||
class VoltageSampler {
|
||||
public:
|
||||
/// Get a voltage reading, in V.
|
||||
virtual float sample() = 0;
|
||||
};
|
||||
|
||||
} // namespace voltage_sampler
|
||||
} // namespace esphome
|
@ -468,10 +468,6 @@ std::string WiFiComponent::format_mac_addr(const uint8_t *mac) {
|
||||
sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
return buf;
|
||||
}
|
||||
void WiFiComponent::on_safe_shutdown() {
|
||||
// Disable WiFi interface on shutdown
|
||||
this->wifi_mode_(false, false);
|
||||
}
|
||||
|
||||
bool sta_field_equal(const uint8_t *field_a, const uint8_t *field_b, int len) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
|
@ -164,8 +164,6 @@ class WiFiComponent : public Component {
|
||||
/// Reconnect WiFi if required.
|
||||
void loop() override;
|
||||
|
||||
void on_safe_shutdown() override;
|
||||
|
||||
bool has_sta() const;
|
||||
bool has_ap() const;
|
||||
|
||||
|
@ -173,6 +173,8 @@ bool WiFiComponent::wifi_sta_connect_(WiFiAP ap) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->wifi_apply_hostname_();
|
||||
|
||||
err = esp_wifi_connect();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGW(TAG, "esp_wifi_connect failed! %d", err);
|
||||
|
@ -196,6 +196,8 @@ bool WiFiComponent::wifi_sta_connect_(WiFiAP ap) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->wifi_apply_hostname_();
|
||||
|
||||
ETS_UART_INTR_DISABLE();
|
||||
ret = wifi_station_connect();
|
||||
ETS_UART_INTR_ENABLE();
|
||||
|
@ -1,20 +1,18 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESPBTDeviceListener, \
|
||||
ESP_BLE_DEVICE_SCHEMA
|
||||
from esphome.components import esp32_ble_tracker
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
DEPENDENCIES = ['esp32_ble_tracker']
|
||||
|
||||
xiaomi_ble_ns = cg.esphome_ns.namespace('xiaomi_ble')
|
||||
XiaomiListener = xiaomi_ble_ns.class_('XiaomiListener', cg.Component, ESPBTDeviceListener)
|
||||
XiaomiListener = xiaomi_ble_ns.class_('XiaomiListener', esp32_ble_tracker.ESPBTDeviceListener)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(XiaomiListener),
|
||||
}).extend(ESP_BLE_DEVICE_SCHEMA).extend(cv.COMPONENT_SCHEMA)
|
||||
}).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
hub = yield cg.get_variable(config[CONF_ESP32_BLE_ID])
|
||||
var = cg.new_Pvariable(config[CONF_ID], hub)
|
||||
yield cg.register_component(var, config)
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
yield esp32_ble_tracker.register_ble_device(var, config)
|
||||
|
@ -138,8 +138,6 @@ bool XiaomiListener::parse_device(const esp32_ble_tracker::ESPBTDevice &device)
|
||||
|
||||
return true;
|
||||
}
|
||||
void XiaomiListener::setup() { this->setup_ble(); }
|
||||
XiaomiListener::XiaomiListener(esp32_ble_tracker::ESP32BLETracker *parent) : ESPBTDeviceListener(parent) {}
|
||||
|
||||
} // namespace xiaomi_ble
|
||||
} // namespace esphome
|
||||
|
@ -22,11 +22,9 @@ bool parse_xiaomi_data_byte(uint8_t data_type, const uint8_t *data, uint8_t data
|
||||
|
||||
optional<XiaomiParseResult> parse_xiaomi(const esp32_ble_tracker::ESPBTDevice &device);
|
||||
|
||||
class XiaomiListener : public Component, public esp32_ble_tracker::ESPBTDeviceListener {
|
||||
class XiaomiListener : public esp32_ble_tracker::ESPBTDeviceListener {
|
||||
public:
|
||||
XiaomiListener(esp32_ble_tracker::ESP32BLETracker *parent);
|
||||
bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override;
|
||||
void setup() override;
|
||||
};
|
||||
|
||||
} // namespace xiaomi_ble
|
||||
|
@ -1,8 +1,6 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor
|
||||
from esphome.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESPBTDeviceListener, \
|
||||
ESP_BLE_DEVICE_SCHEMA
|
||||
from esphome.components import sensor, esp32_ble_tracker
|
||||
from esphome.const import CONF_BATTERY_LEVEL, CONF_MAC_ADDRESS, CONF_TEMPERATURE, \
|
||||
UNIT_CELSIUS, ICON_THERMOMETER, UNIT_PERCENT, ICON_WATER_PERCENT, ICON_BATTERY, CONF_ID, \
|
||||
CONF_MOISTURE, CONF_ILLUMINANCE, ICON_BRIGHTNESS_5, UNIT_LUX, CONF_CONDUCTIVITY, \
|
||||
@ -12,7 +10,8 @@ DEPENDENCIES = ['esp32_ble_tracker']
|
||||
AUTO_LOAD = ['xiaomi_ble']
|
||||
|
||||
xiaomi_miflora_ns = cg.esphome_ns.namespace('xiaomi_miflora')
|
||||
XiaomiMiflora = xiaomi_miflora_ns.class_('XiaomiMiflora', ESPBTDeviceListener, cg.Component)
|
||||
XiaomiMiflora = xiaomi_miflora_ns.class_('XiaomiMiflora', esp32_ble_tracker.ESPBTDeviceListener,
|
||||
cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(XiaomiMiflora),
|
||||
@ -23,13 +22,15 @@ CONFIG_SCHEMA = cv.Schema({
|
||||
cv.Optional(CONF_CONDUCTIVITY):
|
||||
sensor.sensor_schema(UNIT_MICROSIEMENS_PER_CENTIMETER, ICON_FLOWER, 0),
|
||||
cv.Optional(CONF_BATTERY_LEVEL): sensor.sensor_schema(UNIT_PERCENT, ICON_BATTERY, 0),
|
||||
}).extend(ESP_BLE_DEVICE_SCHEMA)
|
||||
}).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
hub = yield cg.get_variable(config[CONF_ESP32_BLE_ID])
|
||||
var = cg.new_Pvariable(config[CONF_ID], hub, config[CONF_MAC_ADDRESS].as_hex)
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
yield cg.register_component(var, config)
|
||||
yield esp32_ble_tracker.register_ble_device(var, config)
|
||||
|
||||
cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex))
|
||||
|
||||
if CONF_TEMPERATURE in config:
|
||||
sens = yield sensor.new_sensor(config[CONF_TEMPERATURE])
|
||||
|
@ -12,8 +12,9 @@ namespace xiaomi_miflora {
|
||||
|
||||
class XiaomiMiflora : public Component, public esp32_ble_tracker::ESPBTDeviceListener {
|
||||
public:
|
||||
XiaomiMiflora(esp32_ble_tracker::ESP32BLETracker *parent, uint64_t address)
|
||||
: ESPBTDeviceListener(parent), address_(address) {}
|
||||
void set_address(uint64_t address) {
|
||||
address_ = address;
|
||||
}
|
||||
|
||||
bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override {
|
||||
if (device.address_uint64() != this->address_)
|
||||
|
@ -1,8 +1,6 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor
|
||||
from esphome.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESPBTDeviceListener, \
|
||||
ESP_BLE_DEVICE_SCHEMA
|
||||
from esphome.components import sensor, esp32_ble_tracker
|
||||
from esphome.const import CONF_BATTERY_LEVEL, CONF_HUMIDITY, CONF_MAC_ADDRESS, CONF_TEMPERATURE, \
|
||||
UNIT_CELSIUS, ICON_THERMOMETER, UNIT_PERCENT, ICON_WATER_PERCENT, ICON_BATTERY, CONF_ID
|
||||
|
||||
@ -10,7 +8,8 @@ DEPENDENCIES = ['esp32_ble_tracker']
|
||||
AUTO_LOAD = ['xiaomi_ble']
|
||||
|
||||
xiaomi_mijia_ns = cg.esphome_ns.namespace('xiaomi_mijia')
|
||||
XiaomiMijia = xiaomi_mijia_ns.class_('XiaomiMijia', ESPBTDeviceListener, cg.Component)
|
||||
XiaomiMijia = xiaomi_mijia_ns.class_('XiaomiMijia', esp32_ble_tracker.ESPBTDeviceListener,
|
||||
cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(XiaomiMijia),
|
||||
@ -18,13 +17,15 @@ CONFIG_SCHEMA = cv.Schema({
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(UNIT_CELSIUS, ICON_THERMOMETER, 1),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(UNIT_PERCENT, ICON_WATER_PERCENT, 1),
|
||||
cv.Optional(CONF_BATTERY_LEVEL): sensor.sensor_schema(UNIT_PERCENT, ICON_BATTERY, 0),
|
||||
}).extend(ESP_BLE_DEVICE_SCHEMA)
|
||||
}).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
hub = yield cg.get_variable(config[CONF_ESP32_BLE_ID])
|
||||
var = cg.new_Pvariable(config[CONF_ID], hub, config[CONF_MAC_ADDRESS].as_hex)
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
yield cg.register_component(var, config)
|
||||
yield esp32_ble_tracker.register_ble_device(var, config)
|
||||
|
||||
cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex))
|
||||
|
||||
if CONF_TEMPERATURE in config:
|
||||
sens = yield sensor.new_sensor(config[CONF_TEMPERATURE])
|
||||
|
@ -12,8 +12,9 @@ namespace xiaomi_mijia {
|
||||
|
||||
class XiaomiMijia : public Component, public esp32_ble_tracker::ESPBTDeviceListener {
|
||||
public:
|
||||
XiaomiMijia(esp32_ble_tracker::ESP32BLETracker *parent, uint64_t address)
|
||||
: ESPBTDeviceListener(parent), address_(address) {}
|
||||
void set_address(uint64_t address) {
|
||||
address_ = address;
|
||||
}
|
||||
|
||||
bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override {
|
||||
if (device.address_uint64() != this->address_)
|
||||
|
@ -317,6 +317,8 @@ CONF_PULSE_LENGTH = 'pulse_length'
|
||||
CONF_QOS = 'qos'
|
||||
CONF_RANDOM = 'random'
|
||||
CONF_RANGE = 'range'
|
||||
CONF_RANGE_FROM = 'range_from'
|
||||
CONF_RANGE_TO = 'range_to'
|
||||
CONF_RATE = 'rate'
|
||||
CONF_RAW = 'raw'
|
||||
CONF_REBOOT_TIMEOUT = 'reboot_timeout'
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define HOT __attribute__((hot))
|
||||
#define ESPDEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||
#define ALWAYS_INLINE __attribute__((always_inline))
|
||||
#define PACKED __attribute__((packed))
|
||||
|
||||
namespace esphome {
|
||||
|
||||
|
79
script/build_compile_commands.py
Executable file
79
script/build_compile_commands.py
Executable file
@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env python
|
||||
import codecs
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
root_path = os.path.abspath(os.path.normpath(os.path.join(__file__, '..', '..')))
|
||||
basepath = os.path.join(root_path, 'esphome')
|
||||
|
||||
|
||||
def walk_files(path):
|
||||
for root, _, files in os.walk(path):
|
||||
for name in files:
|
||||
yield os.path.join(root, name)
|
||||
|
||||
|
||||
def shlex_quote(s):
|
||||
if not s:
|
||||
return u"''"
|
||||
if re.search(r'[^\w@%+=:,./-]', s) is None:
|
||||
return s
|
||||
|
||||
return u"'" + s.replace(u"'", u"'\"'\"'") + u"'"
|
||||
|
||||
|
||||
def build_compile_commands():
|
||||
gcc_flags_json = os.path.join(root_path, '.gcc-flags.json')
|
||||
if not os.path.isfile(gcc_flags_json):
|
||||
print("Could not find {} file which is required for clang-tidy.")
|
||||
print('Please run "pio init --ide atom" in the root esphome folder to generate that file.')
|
||||
sys.exit(1)
|
||||
with codecs.open(gcc_flags_json, 'r', encoding='utf-8') as f:
|
||||
gcc_flags = json.load(f)
|
||||
exec_path = gcc_flags['execPath']
|
||||
include_paths = gcc_flags['gccIncludePaths'].split(',')
|
||||
includes = ['-I{}'.format(p) for p in include_paths]
|
||||
cpp_flags = gcc_flags['gccDefaultCppFlags'].split(' ')
|
||||
defines = [flag for flag in cpp_flags if flag.startswith('-D')]
|
||||
command = [exec_path]
|
||||
command.extend(includes)
|
||||
command.extend(defines)
|
||||
command.append('-std=gnu++11')
|
||||
command.append('-Wall')
|
||||
command.append('-Wno-delete-non-virtual-dtor')
|
||||
command.append('-Wno-unused-variable')
|
||||
command.append('-Wunreachable-code')
|
||||
|
||||
source_files = []
|
||||
for path in walk_files(basepath):
|
||||
filetypes = ('.cpp',)
|
||||
ext = os.path.splitext(path)[1]
|
||||
if ext in filetypes:
|
||||
source_files.append(os.path.abspath(path))
|
||||
source_files.sort()
|
||||
compile_commands = [{
|
||||
'directory': root_path,
|
||||
'command': ' '.join(shlex_quote(x) for x in (command + ['-o', p + '.o', '-c', p])),
|
||||
'file': p
|
||||
} for p in source_files]
|
||||
compile_commands_json = os.path.join(root_path, 'compile_commands.json')
|
||||
if os.path.isfile(compile_commands_json):
|
||||
with codecs.open(compile_commands_json, 'r', encoding='utf-8') as f:
|
||||
try:
|
||||
if json.load(f) == compile_commands:
|
||||
return
|
||||
except:
|
||||
pass
|
||||
with codecs.open(compile_commands_json, 'w', encoding='utf-8') as f:
|
||||
json.dump(compile_commands, f, indent=2)
|
||||
|
||||
|
||||
def main():
|
||||
build_compile_commands()
|
||||
print("Done.")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -45,6 +45,8 @@ def run_tidy(args, tmpdir, queue, lock, failed_files):
|
||||
invocation.append('-p=.')
|
||||
if args.quiet:
|
||||
invocation.append('-quiet')
|
||||
for arg in ['-Wfor-loop-analysis', '-Wshadow-field', '-Wshadow-field-in-constructor']:
|
||||
invocation.append('-extra-arg={}'.format(arg))
|
||||
invocation.append(os.path.abspath(path))
|
||||
invocation_s = ' '.join(shlex_quote(x) for x in invocation)
|
||||
|
||||
@ -135,9 +137,6 @@ def build_compile_commands():
|
||||
command.append('-Wall')
|
||||
command.append('-Wno-delete-non-virtual-dtor')
|
||||
command.append('-Wno-unused-variable')
|
||||
command.append('-Wfor-loop-analysis')
|
||||
command.append('-Wshadow-field')
|
||||
command.append('-Wshadow-field-in-constructor')
|
||||
command.append('-Wunreachable-code')
|
||||
|
||||
source_files = []
|
||||
|
Loading…
Reference in New Issue
Block a user