From f811b1157cb34db306da451804a4e0363e2bec50 Mon Sep 17 00:00:00 2001
From: Otto Winter
Date: Sun, 12 May 2019 23:04:36 +0200
Subject: [PATCH] Updates for 1.13 (#546)
* Update CI matcher
* Check Executable bit
* Quicklint
* Updates
* Allow pm1.0 and pm10.0 for PMS5003ST
Fixes https://github.com/esphome/feature-requests/issues/225
* PowerSupplyRequester
* Lint
* Include debug data in generated main.cpp
* Updates
* Auto-select bit_depth
* Updates
---
.travis.yml | 4 +-
esphome/__main__.py | 23 +++-
esphome/codegen.py | 2 +-
esphome/components/binary_sensor/filter.cpp | 2 +-
.../ble_presence/ble_presence_device.cpp | 2 +-
.../components/esp8266_pwm/esp8266_pwm.cpp | 2 +-
esphome/components/fastled_base/__init__.py | 11 +-
.../components/fastled_base/fastled_light.cpp | 21 ---
.../components/fastled_base/fastled_light.h | 12 --
esphome/components/integration/sensor.py | 2 +-
esphome/components/ledc/output.py | 42 +++++-
esphome/components/light/__init__.py | 9 +-
esphome/components/light/addressable_light.h | 28 +++-
esphome/components/neopixelbus/light.py | 10 +-
.../neopixelbus/neopixelbus_light.h | 33 -----
esphome/components/output/binary_output.h | 15 +-
esphome/components/output/float_output.cpp | 10 +-
esphome/components/pmsx003/pmsx003.cpp | 6 +
esphome/components/pmsx003/sensor.py | 4 +-
.../components/power_supply/power_supply.cpp | 2 +-
.../components/power_supply/power_supply.h | 21 +++
esphome/components/sun/sun.h | 31 ++---
esphome/components/time/automation.cpp | 2 +-
esphome/config.py | 4 -
esphome/config_validation.py | 6 +-
esphome/const.py | 2 -
esphome/core/application.cpp | 2 +-
esphome/core_config.py | 7 +-
esphome/cpp_generator.py | 11 ++
esphome/dashboard/dashboard.py | 2 +-
esphome/dashboard/static/esphome.js | 8 ++
esphome/dashboard/templates/index.html | 5 +-
script/build_compile_commands.py | 90 +-----------
script/ci-custom.py | 23 +++-
script/{clang-format.py => clang-format} | 47 +------
script/{clang-tidy.py => clang-tidy} | 126 +----------------
script/helpers.py | 128 ++++++++++++++++++
script/lint-cpp | 4 +-
script/lint-python | 78 ++++++++++-
script/quicklint | 11 ++
tests/test1.yaml | 8 ++
41 files changed, 438 insertions(+), 418 deletions(-)
rename script/{clang-format.py => clang-format} (77%)
rename script/{clang-tidy.py => clang-tidy} (54%)
create mode 100644 script/helpers.py
create mode 100755 script/quicklint
diff --git a/.travis.yml b/.travis.yml
index b5642478f5..fd2e759fc7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -51,6 +51,6 @@ matrix:
- clang-format-7 -version
- clang-apply-replacements-7 -version
script:
- - script/clang-tidy.py --all-headers -j 2 --fix
- - script/clang-format.py -i -j 2
+ - script/clang-tidy --all-headers -j 2 --fix
+ - script/clang-format -i -j 2
- script/ci-suggest-changes
diff --git a/esphome/__main__.py b/esphome/__main__.py
index c06b570cb5..199b68a6f1 100644
--- a/esphome/__main__.py
+++ b/esphome/__main__.py
@@ -1,16 +1,18 @@
from __future__ import print_function
import argparse
+import functools
import logging
import os
import sys
from datetime import datetime
from esphome import const, writer, yaml_util
+import esphome.codegen as cg
from esphome.config import iter_components, read_config, strip_default_ids
from esphome.const import CONF_BAUD_RATE, CONF_BROKER, CONF_LOGGER, CONF_OTA, \
CONF_PASSWORD, CONF_PORT
-from esphome.core import CORE, EsphomeError
+from esphome.core import CORE, EsphomeError, coroutine, coroutine_with_priority
from esphome.helpers import color, indent
from esphome.py_compat import IS_PY2, safe_input
from esphome.util import run_external_command, run_external_process, safe_print
@@ -117,12 +119,27 @@ def run_miniterm(config, port):
config, line, backtrace_state=backtrace_state)
+def wrap_to_code(name, comp):
+ coro = coroutine(comp.to_code)
+
+ @functools.wraps(comp.to_code)
+ @coroutine_with_priority(coro.priority)
+ def wrapped(conf):
+ cg.add(cg.LineComment(u"{}:".format(name)))
+ if comp.config_schema is not None:
+ cg.add(cg.LineComment(indent(yaml_util.dump(conf).decode('utf-8'))))
+ yield coro(conf)
+
+ return wrapped
+
+
def write_cpp(config):
_LOGGER.info("Generating C++ source...")
- for _, component, conf in iter_components(CORE.config):
+ for name, component, conf in iter_components(CORE.config):
if component.to_code is not None:
- CORE.add_job(component.to_code, conf)
+ coro = wrap_to_code(name, component)
+ CORE.add_job(coro, conf)
CORE.flush_tasks()
diff --git a/esphome/codegen.py b/esphome/codegen.py
index c2dea04995..46d652a3cd 100644
--- a/esphome/codegen.py
+++ b/esphome/codegen.py
@@ -10,7 +10,7 @@
# pylint: disable=unused-import
from esphome.cpp_generator import ( # noqa
Expression, RawExpression, RawStatement, TemplateArguments,
- StructInitializer, ArrayInitializer, safe_exp, Statement,
+ StructInitializer, ArrayInitializer, safe_exp, Statement, LineComment,
progmem_array, statement, variable, Pvariable, new_Pvariable,
add, add_global, add_library, add_build_flag, add_define,
get_variable, get_variable_with_full_id, process_lambda, is_template, templatable, MockObj,
diff --git a/esphome/components/binary_sensor/filter.cpp b/esphome/components/binary_sensor/filter.cpp
index 439847f72a..39b88f867c 100644
--- a/esphome/components/binary_sensor/filter.cpp
+++ b/esphome/components/binary_sensor/filter.cpp
@@ -5,7 +5,7 @@ namespace esphome {
namespace binary_sensor {
-static const char *TAG = "something.Filter";
+static const char *TAG = "sensor.filter";
void Filter::output(bool value, bool is_initial) {
if (!this->dedup_.next(value))
diff --git a/esphome/components/ble_presence/ble_presence_device.cpp b/esphome/components/ble_presence/ble_presence_device.cpp
index 5a69d48a86..ad6b5ece88 100644
--- a/esphome/components/ble_presence/ble_presence_device.cpp
+++ b/esphome/components/ble_presence/ble_presence_device.cpp
@@ -6,7 +6,7 @@
namespace esphome {
namespace ble_presence {
-static const char *TAG = "something.something";
+static const char *TAG = "ble_presence";
void BLEPresenceDevice::dump_config() { LOG_BINARY_SENSOR("", "BLE Presence", this); }
diff --git a/esphome/components/esp8266_pwm/esp8266_pwm.cpp b/esphome/components/esp8266_pwm/esp8266_pwm.cpp
index 363f4d24bc..96290871e0 100644
--- a/esphome/components/esp8266_pwm/esp8266_pwm.cpp
+++ b/esphome/components/esp8266_pwm/esp8266_pwm.cpp
@@ -11,7 +11,7 @@
namespace esphome {
namespace esp8266_pwm {
-static const char *TAG = "something.something";
+static const char *TAG = "esp8266_pwm";
void ESP8266PWM::setup() {
ESP_LOGCONFIG(TAG, "Setting up ESP8266 PWM Output...");
diff --git a/esphome/components/fastled_base/__init__.py b/esphome/components/fastled_base/__init__.py
index 5ad7280ee8..aad30198af 100644
--- a/esphome/components/fastled_base/__init__.py
+++ b/esphome/components/fastled_base/__init__.py
@@ -1,8 +1,7 @@
import esphome.codegen as cg
import esphome.config_validation as cv
-from esphome.components import light, power_supply
-from esphome.const import CONF_OUTPUT_ID, CONF_NUM_LEDS, CONF_RGB_ORDER, CONF_MAX_REFRESH_RATE, \
- CONF_POWER_SUPPLY
+from esphome.components import light
+from esphome.const import CONF_OUTPUT_ID, CONF_NUM_LEDS, CONF_RGB_ORDER, CONF_MAX_REFRESH_RATE
from esphome.core import coroutine
fastled_base_ns = cg.esphome_ns.namespace('fastled_base')
@@ -24,8 +23,6 @@ BASE_SCHEMA = light.ADDRESSABLE_LIGHT_SCHEMA.extend({
cv.Required(CONF_NUM_LEDS): cv.positive_not_null_int,
cv.Optional(CONF_RGB_ORDER): cv.one_of(*RGB_ORDERS, upper=True),
cv.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds,
-
- cv.Optional(CONF_POWER_SUPPLY): cv.use_id(power_supply.PowerSupply),
}).extend(cv.COMPONENT_SCHEMA)
@@ -37,10 +34,6 @@ def new_fastled_light(config):
if CONF_MAX_REFRESH_RATE in config:
cg.add(var.set_max_refresh_rate(config[CONF_MAX_REFRESH_RATE]))
- if CONF_POWER_SUPPLY in config:
- var_ = yield cg.get_variable(config[CONF_POWER_SUPPLY])
- cg.add(var.set_power_supply(var_))
-
yield light.register_light(var, config)
cg.add_library('FastLED', '3.2.0')
yield var
diff --git a/esphome/components/fastled_base/fastled_light.cpp b/esphome/components/fastled_base/fastled_light.cpp
index d5cc85d266..8420748dd5 100644
--- a/esphome/components/fastled_base/fastled_light.cpp
+++ b/esphome/components/fastled_base/fastled_light.cpp
@@ -33,27 +33,6 @@ void FastLEDLightOutput::loop() {
this->mark_shown_();
ESP_LOGVV(TAG, "Writing RGB values to bus...");
-
-#ifdef USE_POWER_SUPPLY
- if (this->power_supply_ != nullptr) {
- bool is_on = false;
- for (int i = 0; i < this->num_leds_; i++) {
- if (bool(this->leds_[i])) {
- is_on = true;
- break;
- }
- }
-
- if (is_on && !this->has_requested_high_power_) {
- this->power_supply_->request_high_power();
- this->has_requested_high_power_ = true;
- }
- if (!is_on && this->has_requested_high_power_) {
- this->power_supply_->unrequest_high_power();
- this->has_requested_high_power_ = false;
- }
- }
-#endif
this->controller_->showLeds();
}
diff --git a/esphome/components/fastled_base/fastled_light.h b/esphome/components/fastled_base/fastled_light.h
index 55a48fcb3e..f9ae2f58d5 100644
--- a/esphome/components/fastled_base/fastled_light.h
+++ b/esphome/components/fastled_base/fastled_light.h
@@ -4,10 +4,6 @@
#include "esphome/core/helpers.h"
#include "esphome/components/light/addressable_light.h"
-#ifdef USE_POWER_SUPPLY
-#include "esphome/components/power_supply/power_supply.h"
-#endif
-
#define FASTLED_ESP8266_RAW_PIN_ORDER
#define FASTLED_ESP32_RAW_PIN_ORDER
#define FASTLED_RMT_BUILTIN_DRIVER true
@@ -30,10 +26,6 @@ class FastLEDLightOutput : public Component, public light::AddressableLight {
/// Set a maximum refresh rate in µs as some lights do not like being updated too often.
void set_max_refresh_rate(uint32_t interval_us) { this->max_refresh_rate_ = interval_us; }
-#ifdef USE_POWER_SUPPLY
- void set_power_supply(power_supply::PowerSupply *power_supply) { this->power_supply_ = power_supply; }
-#endif
-
/// Add some LEDS, can only be called once.
CLEDController &add_leds(CLEDController *controller, int num_leds) {
this->controller_ = controller;
@@ -242,10 +234,6 @@ class FastLEDLightOutput : public Component, public light::AddressableLight {
int num_leds_{0};
uint32_t last_refresh_{0};
optional max_refresh_rate_{};
-#ifdef USE_POWER_SUPPLY
- power_supply::PowerSupply *power_supply_{nullptr};
- bool has_requested_high_power_{false};
-#endif
};
} // namespace fastled_base
diff --git a/esphome/components/integration/sensor.py b/esphome/components/integration/sensor.py
index 13c69f81f2..9e4dc0847f 100644
--- a/esphome/components/integration/sensor.py
+++ b/esphome/components/integration/sensor.py
@@ -33,7 +33,7 @@ CONFIG_SCHEMA = sensor.SENSOR_SCHEMA.extend({
cv.Required(CONF_TIME_UNIT): cv.enum(INTEGRATION_TIMES, lower=True),
cv.Optional(CONF_INTEGRATION_METHOD, default='trapezoid'):
cv.enum(INTEGRATION_METHODS, lower=True),
- cv.Optional(CONF_RESTORE, default=True): cv.boolean,
+ cv.Optional(CONF_RESTORE, default=False): cv.boolean,
}).extend(cv.COMPONENT_SCHEMA)
diff --git a/esphome/components/ledc/output.py b/esphome/components/ledc/output.py
index e9e41c398a..e5cb073ca9 100644
--- a/esphome/components/ledc/output.py
+++ b/esphome/components/ledc/output.py
@@ -1,20 +1,54 @@
+import math
from esphome import pins
from esphome.components import output
import esphome.config_validation as cv
import esphome.codegen as cg
-from esphome.const import APB_CLOCK_FREQ, CONF_BIT_DEPTH, CONF_CHANNEL, CONF_FREQUENCY, \
+from esphome.const import CONF_BIT_DEPTH, CONF_CHANNEL, CONF_FREQUENCY, \
CONF_ID, CONF_PIN, ESP_PLATFORM_ESP32
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
+def calc_max_frequency(bit_depth):
+ return 80e6 / (2**bit_depth)
+
+
+def calc_min_frequency(bit_depth):
+ # LEDC_DIV_NUM_HSTIMER is 15-bit unsigned integer
+ # lower 8 bits represent fractional part
+ max_div_num = ((1 << 16) - 1) / 256.0
+ return 80e6 / (max_div_num * (2**bit_depth))
+
+
def validate_frequency_bit_depth(obj):
frequency = obj[CONF_FREQUENCY]
+ if CONF_BIT_DEPTH not in obj:
+ obj = obj.copy()
+ for bit_depth in range(15, 0, -1):
+ if calc_min_frequency(bit_depth) <= frequency <= calc_max_frequency(bit_depth):
+ obj[CONF_BIT_DEPTH] = bit_depth
+ break
+ else:
+ min_freq = min(calc_min_frequency(x) for x in range(1, 16))
+ max_freq = max(calc_max_frequency(x) for x in range(1, 16))
+ if frequency < min_freq:
+ raise cv.Invalid("This frequency setting is not possible, please choose a higher "
+ "frequency (at least {}Hz)".format(int(min_freq)))
+ if frequency > max_freq:
+ raise cv.Invalid("This frequency setting is not possible, please choose a lower "
+ "frequency (at most {}Hz)".format(int(max_freq)))
+ raise cv.Invalid("Invalid frequency!")
+
bit_depth = obj[CONF_BIT_DEPTH]
- max_freq = APB_CLOCK_FREQ / (2**bit_depth)
+ min_freq = calc_min_frequency(bit_depth)
+ max_freq = calc_max_frequency(bit_depth)
if frequency > max_freq:
- raise cv.Invalid('Maximum frequency for bit depth {} is {}Hz'.format(bit_depth, max_freq))
+ raise cv.Invalid('Maximum frequency for bit depth {} is {}Hz. Please decrease the '
+ 'bit_depth.'.format(bit_depth, int(math.floor(max_freq))))
+ if frequency < calc_min_frequency(bit_depth):
+ raise cv.Invalid('Minimum frequency for bit depth {} is {}Hz. Please increase the '
+ 'bit_depth.'.format(bit_depth, int(math.ceil(min_freq))))
return obj
@@ -25,7 +59,7 @@ CONFIG_SCHEMA = cv.All(output.FLOAT_OUTPUT_SCHEMA.extend({
cv.Required(CONF_ID): cv.declare_id(LEDCOutput),
cv.Required(CONF_PIN): pins.internal_gpio_output_pin_schema,
cv.Optional(CONF_FREQUENCY, default='1kHz'): cv.frequency,
- cv.Optional(CONF_BIT_DEPTH, default=12): cv.int_range(min=1, max=15),
+ cv.Optional(CONF_BIT_DEPTH): cv.int_range(min=1, max=15),
cv.Optional(CONF_CHANNEL): cv.int_range(min=0, max=15),
}).extend(cv.COMPONENT_SCHEMA), validate_frequency_bit_depth)
diff --git a/esphome/components/light/__init__.py b/esphome/components/light/__init__.py
index 858475f8cf..e0ea8f246d 100644
--- a/esphome/components/light/__init__.py
+++ b/esphome/components/light/__init__.py
@@ -1,9 +1,9 @@
import esphome.codegen as cg
import esphome.config_validation as cv
-from esphome.components import mqtt
+from esphome.components import mqtt, power_supply
from esphome.const import CONF_COLOR_CORRECT, \
CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_ID, \
- CONF_INTERNAL, CONF_NAME, CONF_MQTT_ID
+ CONF_INTERNAL, CONF_NAME, CONF_MQTT_ID, CONF_POWER_SUPPLY
from esphome.core import coroutine, coroutine_with_priority
from .automation import light_control_to_code # noqa
from .effects import validate_effects, BINARY_EFFECTS, \
@@ -35,6 +35,7 @@ ADDRESSABLE_LIGHT_SCHEMA = RGB_LIGHT_SCHEMA.extend({
cv.GenerateID(): cv.declare_id(AddressableLightState),
cv.Optional(CONF_EFFECTS): validate_effects(ADDRESSABLE_EFFECTS),
cv.Optional(CONF_COLOR_CORRECT): cv.All([cv.percentage], cv.Length(min=3, max=4)),
+ cv.Optional(CONF_POWER_SUPPLY): cv.use_id(power_supply.PowerSupply),
})
@@ -52,6 +53,10 @@ def setup_light_core_(light_var, output_var, config):
if CONF_COLOR_CORRECT in config:
cg.add(output_var.set_correction(*config[CONF_COLOR_CORRECT]))
+ if CONF_POWER_SUPPLY in config:
+ var_ = yield cg.get_variable(config[CONF_POWER_SUPPLY])
+ cg.add(output_var.set_power_supply(var_))
+
if CONF_MQTT_ID in config:
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], light_var)
yield mqtt.register_mqtt_component(mqtt_, config)
diff --git a/esphome/components/light/addressable_light.h b/esphome/components/light/addressable_light.h
index 993b430d3c..b4249097db 100644
--- a/esphome/components/light/addressable_light.h
+++ b/esphome/components/light/addressable_light.h
@@ -1,9 +1,14 @@
#pragma once
#include "esphome/core/component.h"
+#include "esphome/core/defines.h"
#include "light_output.h"
#include "light_state.h"
+#ifdef USE_POWER_SUPPLY
+#include "esphome/components/power_supply/power_supply.h"
+#endif
+
namespace esphome {
namespace light {
@@ -30,6 +35,7 @@ struct ESPColor {
};
};
uint8_t raw[4];
+ uint32_t raw_32;
};
inline ESPColor() ALWAYS_INLINE : r(0), g(0), b(0), w(0) {} // NOLINT
inline ESPColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t white) ALWAYS_INLINE : r(red),
@@ -47,7 +53,7 @@ struct ESPColor {
this->b = rhs.b;
this->w = rhs.w;
}
- inline bool is_on() ALWAYS_INLINE { return this->r != 0 || this->g != 0 || this->b != 0 || this->w != 0; }
+ inline bool is_on() ALWAYS_INLINE { return this->raw_32 != 0; }
inline ESPColor &operator=(const ESPColor &rhs) ALWAYS_INLINE {
this->r = rhs.r;
this->g = rhs.g;
@@ -527,14 +533,32 @@ class AddressableLight : public LightOutput {
void setup_state(LightState *state) override { this->correction_.calculate_gamma_table(state->get_gamma_correct()); }
void schedule_show() { this->next_show_ = true; }
+#ifdef USE_POWER_SUPPLY
+ void set_power_supply(power_supply::PowerSupply *power_supply) { this->power_.set_parent(power_supply); }
+#endif
+
protected:
bool should_show_() const { return this->effect_active_ || this->next_show_; }
- void mark_shown_() { this->next_show_ = false; }
+ void mark_shown_() {
+ this->next_show_ = false;
+#ifdef USE_POWER_SUPPLY
+ for (auto c : *this) {
+ if (c.get().is_on()) {
+ this->power_.request();
+ return;
+ }
+ }
+ this->power_.unrequest();
+#endif
+ }
virtual ESPColorView get_view_internal(int32_t index) const = 0;
bool effect_active_{false};
bool next_show_{true};
ESPColorCorrection correction_{};
+#ifdef USE_POWER_SUPPLY
+ power_supply::PowerSupplyRequester power_;
+#endif
};
} // namespace light
diff --git a/esphome/components/neopixelbus/light.py b/esphome/components/neopixelbus/light.py
index 060aeb0648..f07bdc80d7 100644
--- a/esphome/components/neopixelbus/light.py
+++ b/esphome/components/neopixelbus/light.py
@@ -1,9 +1,9 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
-from esphome.components import light, power_supply
+from esphome.components import light
from esphome.const import CONF_CLOCK_PIN, CONF_DATA_PIN, CONF_METHOD, CONF_NUM_LEDS, CONF_PIN, \
- CONF_POWER_SUPPLY, CONF_TYPE, CONF_VARIANT, CONF_OUTPUT_ID
+ CONF_TYPE, CONF_VARIANT, CONF_OUTPUT_ID
from esphome.core import CORE
neopixelbus_ns = cg.esphome_ns.namespace('neopixelbus')
@@ -138,8 +138,6 @@ CONFIG_SCHEMA = cv.All(light.ADDRESSABLE_LIGHT_SCHEMA.extend({
cv.Optional(CONF_DATA_PIN): pins.output_pin,
cv.Required(CONF_NUM_LEDS): cv.positive_not_null_int,
-
- cv.Optional(CONF_POWER_SUPPLY): cv.use_id(power_supply.PowerSupply),
}).extend(cv.COMPONENT_SCHEMA), validate, validate_method_pin)
@@ -162,8 +160,4 @@ def to_code(config):
cg.add(var.set_pixel_order(getattr(ESPNeoPixelOrder, config[CONF_TYPE])))
- if CONF_POWER_SUPPLY in config:
- var_ = yield cg.get_variable(config[CONF_POWER_SUPPLY])
- cg.add(var.set_power_supply(var_))
-
cg.add_library('NeoPixelBus', '2.4.1')
diff --git a/esphome/components/neopixelbus/neopixelbus_light.h b/esphome/components/neopixelbus/neopixelbus_light.h
index 68d99fb374..25e10d9bbd 100644
--- a/esphome/components/neopixelbus/neopixelbus_light.h
+++ b/esphome/components/neopixelbus/neopixelbus_light.h
@@ -9,10 +9,6 @@
#error The NeoPixelBus library requires at least arduino_core_version 2.4.x
#endif
-#ifdef USE_POWER_SUPPLY
-#include "esphome/components/power_supply/power_supply.h"
-#endif
-
#include "NeoPixelBus.h"
namespace esphome {
@@ -54,10 +50,6 @@ enum class ESPNeoPixelOrder {
template
class NeoPixelBusLightOutputBase : public Component, public light::AddressableLight {
public:
-#ifdef USE_POWER_SUPPLY
- void set_power_supply(power_supply::PowerSupply *power_supply) { this->power_supply_ = power_supply; }
-#endif
-
NeoPixelBus *get_controller() const { return this->controller_; }
void clear_effect_data() override {
@@ -95,27 +87,6 @@ class NeoPixelBusLightOutputBase : public Component, public light::AddressableLi
this->mark_shown_();
this->controller_->Dirty();
-#ifdef USE_POWER_SUPPLY
- if (this->power_supply_ != nullptr) {
- bool is_light_on = false;
- for (int i = 0; i < this->size(); i++) {
- if ((*this)[i].get().is_on()) {
- is_light_on = true;
- break;
- }
- }
-
- if (is_light_on && !this->has_requested_high_power_) {
- this->power_supply_->request_high_power();
- this->has_requested_high_power_ = true;
- }
- if (!is_light_on && this->has_requested_high_power_) {
- this->power_supply_->unrequest_high_power();
- this->has_requested_high_power_ = false;
- }
- }
-#endif
-
this->controller_->Show();
}
@@ -135,10 +106,6 @@ class NeoPixelBusLightOutputBase : public Component, public light::AddressableLi
NeoPixelBus *controller_{nullptr};
uint8_t *effect_data_{nullptr};
uint8_t rgb_offsets_[4]{0, 1, 2, 3};
-#ifdef USE_POWER_SUPPLY
- power_supply::PowerSupply *power_supply_{nullptr};
- bool has_requested_high_power_{false};
-#endif
};
template
diff --git a/esphome/components/output/binary_output.h b/esphome/components/output/binary_output.h
index 96f6b3fb48..2697b23616 100644
--- a/esphome/components/output/binary_output.h
+++ b/esphome/components/output/binary_output.h
@@ -27,16 +27,13 @@ class BinaryOutput {
*
* @param power_supply The PowerSupplyComponent, set this to nullptr to disable the power supply.
*/
- void set_power_supply(power_supply::PowerSupply *power_supply) { this->power_supply_ = power_supply; }
+ void set_power_supply(power_supply::PowerSupply *power_supply) { this->power_.set_parent(power_supply); }
#endif
/// Enable this binary output.
virtual void turn_on() {
#ifdef USE_POWER_SUPPLY
- if (this->power_supply_ != nullptr && !this->has_requested_high_power_) {
- this->power_supply_->request_high_power();
- this->has_requested_high_power_ = true;
- }
+ this->power_.request();
#endif
this->write_state(!this->inverted_);
}
@@ -44,10 +41,7 @@ class BinaryOutput {
/// Disable this binary output.
virtual void turn_off() {
#ifdef USE_POWER_SUPPLY
- if (this->power_supply_ != nullptr && this->has_requested_high_power_) {
- this->power_supply_->unrequest_high_power();
- this->has_requested_high_power_ = false;
- }
+ this->power_.unrequest();
#endif
this->write_state(this->inverted_);
}
@@ -62,8 +56,7 @@ class BinaryOutput {
bool inverted_{false};
#ifdef USE_POWER_SUPPLY
- power_supply::PowerSupply *power_supply_{nullptr};
- bool has_requested_high_power_{false};
+ power_supply::PowerSupplyRequester power_{};
#endif
};
diff --git a/esphome/components/output/float_output.cpp b/esphome/components/output/float_output.cpp
index 30984aecc8..0d536d0946 100644
--- a/esphome/components/output/float_output.cpp
+++ b/esphome/components/output/float_output.cpp
@@ -24,15 +24,9 @@ void FloatOutput::set_level(float state) {
#ifdef USE_POWER_SUPPLY
if (state > 0.0f) { // ON
- if (this->power_supply_ != nullptr && !this->has_requested_high_power_) {
- this->power_supply_->request_high_power();
- this->has_requested_high_power_ = true;
- }
+ this->power_.request();
} else { // OFF
- if (this->power_supply_ != nullptr && this->has_requested_high_power_) {
- this->power_supply_->unrequest_high_power();
- this->has_requested_high_power_ = false;
- }
+ this->power_.unrequest();
}
#endif
diff --git a/esphome/components/pmsx003/pmsx003.cpp b/esphome/components/pmsx003/pmsx003.cpp
index bbf76ce697..548099a495 100644
--- a/esphome/components/pmsx003/pmsx003.cpp
+++ b/esphome/components/pmsx003/pmsx003.cpp
@@ -132,14 +132,20 @@ void PMSX003Component::parse_data_() {
break;
}
case PMSX003_TYPE_5003ST: {
+ uint16_t pm_1_0_concentration = this->get_16_bit_uint_(10);
uint16_t pm_2_5_concentration = this->get_16_bit_uint_(12);
+ uint16_t pm_10_0_concentration = this->get_16_bit_uint_(14);
uint16_t formaldehyde = this->get_16_bit_uint_(28);
float temperature = this->get_16_bit_uint_(30) / 10.0f;
float humidity = this->get_16_bit_uint_(32) / 10.0f;
ESP_LOGD(TAG, "Got PM2.5 Concentration: %u µg/m^3, Temperature: %.1f°C, Humidity: %.1f%% Formaldehyde: %u µg/m^3",
pm_2_5_concentration, temperature, humidity, formaldehyde);
+ if (this->pm_1_0_sensor_ != nullptr)
+ this->pm_1_0_sensor_->publish_state(pm_1_0_concentration);
if (this->pm_2_5_sensor_ != nullptr)
this->pm_2_5_sensor_->publish_state(pm_2_5_concentration);
+ if (this->pm_10_0_sensor_ != nullptr)
+ this->pm_10_0_sensor_->publish_state(pm_10_0_concentration);
if (this->temperature_sensor_ != nullptr)
this->temperature_sensor_->publish_state(temperature);
if (this->humidity_sensor_ != nullptr)
diff --git a/esphome/components/pmsx003/sensor.py b/esphome/components/pmsx003/sensor.py
index a949fbb1ca..fa9a92d430 100644
--- a/esphome/components/pmsx003/sensor.py
+++ b/esphome/components/pmsx003/sensor.py
@@ -24,9 +24,9 @@ PMSX003_TYPES = {
}
SENSORS_TO_TYPE = {
- CONF_PM_1_0: [CONF_PMSX003],
+ CONF_PM_1_0: [CONF_PMSX003, CONF_PMS5003ST],
CONF_PM_2_5: [CONF_PMSX003, CONF_PMS5003T, CONF_PMS5003ST],
- CONF_PM_10_0: [CONF_PMSX003],
+ CONF_PM_10_0: [CONF_PMSX003, CONF_PMS5003ST],
CONF_TEMPERATURE: [CONF_PMS5003T, CONF_PMS5003ST],
CONF_HUMIDITY: [CONF_PMS5003T, CONF_PMS5003ST],
CONF_FORMALDEHYDE: [CONF_PMS5003ST],
diff --git a/esphome/components/power_supply/power_supply.cpp b/esphome/components/power_supply/power_supply.cpp
index 5ce2e38eed..1f8471ac9f 100644
--- a/esphome/components/power_supply/power_supply.cpp
+++ b/esphome/components/power_supply/power_supply.cpp
@@ -42,7 +42,7 @@ void PowerSupply::request_high_power() {
void PowerSupply::unrequest_high_power() {
this->active_requests_--;
if (this->active_requests_ < 0) {
- // if asserts are disabled we're just going to use 0 as our now counter.
+ // we're just going to use 0 as our now counter.
this->active_requests_ = 0;
}
diff --git a/esphome/components/power_supply/power_supply.h b/esphome/components/power_supply/power_supply.h
index b49da3b32a..12d2a9984f 100644
--- a/esphome/components/power_supply/power_supply.h
+++ b/esphome/components/power_supply/power_supply.h
@@ -39,5 +39,26 @@ class PowerSupply : public Component {
int16_t active_requests_{0}; // use signed integer to make catching negative requests easier.
};
+class PowerSupplyRequester {
+ public:
+ void set_parent(PowerSupply *parent) { parent_ = parent; }
+ void request() {
+ if (!this->requested_ && this->parent_ != nullptr) {
+ this->parent_->request_high_power();
+ this->requested_ = true;
+ }
+ }
+ void unrequest() {
+ if (this->requested_ && this->parent_ != nullptr) {
+ this->parent_->unrequest_high_power();
+ this->requested_ = false;
+ }
+ }
+
+ protected:
+ PowerSupply *parent_{nullptr};
+ bool requested_{false};
+};
+
} // namespace power_supply
} // namespace esphome
diff --git a/esphome/components/sun/sun.h b/esphome/components/sun/sun.h
index 8e477e9196..2592c75c62 100644
--- a/esphome/components/sun/sun.h
+++ b/esphome/components/sun/sun.h
@@ -92,36 +92,27 @@ class SunTrigger : public Trigger<>, public PollingComponent, public Parentedparent_->get_time()->utcnow();
- if (!now.is_valid())
+ double current = this->parent_->elevation();
+ if (isnan(current))
return;
- if (!this->last_result_.has_value() || this->last_result_->day_of_year != now.day_of_year) {
- this->recalc_();
- return;
+ bool crossed;
+ if (this->sunrise_) {
+ crossed = this->last_elevation_ <= this->elevation_ && this->elevation_ < current;
+ } else {
+ crossed = this->last_elevation_ >= this->elevation_ && this->elevation_ > current;
}
- if (this->prev_check_ != -1) {
- auto res = *this->last_result_;
- // now >= sunrise > prev_check
- if (now.timestamp >= res.timestamp && res.timestamp > this->prev_check_) {
- this->trigger();
- }
+ if (crossed) {
+ this->trigger();
}
- this->prev_check_ = now.timestamp;
+ this->last_elevation_ = current;
}
protected:
- void recalc_() {
- if (this->sunrise_)
- this->last_result_ = this->parent_->sunrise(this->elevation_);
- else
- this->last_result_ = this->parent_->sunset(this->elevation_);
- }
bool sunrise_;
+ double last_elevation_;
double elevation_;
- time_t prev_check_{-1};
- optional last_result_{};
};
template class SunCondition : public Condition, public Parented {
diff --git a/esphome/components/time/automation.cpp b/esphome/components/time/automation.cpp
index b6032ca2a2..1232e6f834 100644
--- a/esphome/components/time/automation.cpp
+++ b/esphome/components/time/automation.cpp
@@ -4,7 +4,7 @@
namespace esphome {
namespace time {
-static const char *TAG = "something.something";
+static const char *TAG = "automation";
void CronTrigger::add_second(uint8_t second) { this->seconds_[second] = true; }
void CronTrigger::add_minute(uint8_t minute) { this->minutes_[minute] = true; }
diff --git a/esphome/config.py b/esphome/config.py
index c969641422..d6f5735066 100644
--- a/esphome/config.py
+++ b/esphome/config.py
@@ -69,10 +69,6 @@ class ComponentManifest(object):
def auto_load(self):
return getattr(self.module, 'AUTO_LOAD', [])
- @property
- def to_code_priority(self):
- return getattr(self.module, 'TO_CODE_PRIORITY', [])
-
def _get_flags_set(self, name, config):
if not hasattr(self.module, name):
return set()
diff --git a/esphome/config_validation.py b/esphome/config_validation.py
index 7676f2816a..a424d800dc 100644
--- a/esphome/config_validation.py
+++ b/esphome/config_validation.py
@@ -8,6 +8,7 @@ import re
from contextlib import contextmanager
import uuid as uuid_
from datetime import datetime
+from string import ascii_letters, digits
import voluptuous as vol
@@ -279,8 +280,9 @@ def validate_id_name(value):
raise Invalid("First character in ID cannot be a digit.")
if '-' in value:
raise Invalid("Dashes are not supported in IDs, please use underscores instead.")
+ valid_chars = ascii_letters + digits + '_'
for char in value:
- if char != '_' and not char.isalnum():
+ if char not in valid_chars:
raise Invalid(u"IDs must only consist of upper/lowercase characters, the underscore"
u"character and numbers. The character '{}' cannot be used"
u"".format(char))
@@ -611,7 +613,7 @@ if IS_PY2:
path = u' @ data[%s]' % u']['.join(map(repr, self.path)) \
if self.path else ''
# pylint: disable=no-member
- output = Exception.__unicode__(self)
+ output = self.message
if self.error_type:
output += u' for ' + self.error_type
return output + path
diff --git a/esphome/const.py b/esphome/const.py
index 4e98dee394..b820c0d4c1 100644
--- a/esphome/const.py
+++ b/esphome/const.py
@@ -11,8 +11,6 @@ ESP_PLATFORM_ESP32 = 'ESP32'
ESP_PLATFORM_ESP8266 = 'ESP8266'
ESP_PLATFORMS = [ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266]
-APB_CLOCK_FREQ = 80000000
-
ALLOWED_NAME_CHARS = u'abcdefghijklmnopqrstuvwxyz0123456789_'
ARDUINO_VERSION_ESP32_DEV = 'https://github.com/platformio/platform-espressif32.git#feature/stage'
ARDUINO_VERSION_ESP32_1_0_0 = 'espressif32@1.5.0'
diff --git a/esphome/core/application.cpp b/esphome/core/application.cpp
index 99d5f7fe29..98eca4ce87 100644
--- a/esphome/core/application.cpp
+++ b/esphome/core/application.cpp
@@ -60,7 +60,7 @@ void Application::setup() {
this->dump_config();
}
void Application::dump_config() {
- ESP_LOGI(TAG, "esphome-core version " ESPHOME_VERSION " compiled on %s", this->compilation_time_.c_str());
+ ESP_LOGI(TAG, "esphome version " ESPHOME_VERSION " compiled on %s", this->compilation_time_.c_str());
for (auto component : this->components_) {
component->dump_config();
diff --git a/esphome/core_config.py b/esphome/core_config.py
index 8d2f83c4f1..3ed07a8343 100644
--- a/esphome/core_config.py
+++ b/esphome/core_config.py
@@ -89,8 +89,7 @@ def default_build_path():
CONFIG_SCHEMA = cv.Schema({
cv.Required(CONF_NAME): cv.valid_name,
- cv.Required(CONF_PLATFORM): cv.one_of('ESP8266', 'ESP32', 'ESPRESSIF32',
- upper=True),
+ cv.Required(CONF_PLATFORM): cv.one_of('ESP8266', 'ESP32', upper=True),
cv.Required(CONF_BOARD): validate_board,
cv.Optional(CONF_ARDUINO_VERSION, default='recommended'): validate_arduino_version,
cv.Optional(CONF_BUILD_PATH, default=default_build_path): cv.string,
@@ -114,6 +113,10 @@ CONFIG_SCHEMA = cv.Schema({
}),
cv.Optional(CONF_INCLUDES, default=[]): cv.ensure_list(cv.file_),
cv.Optional(CONF_LIBRARIES, default=[]): cv.ensure_list(cv.string_strict),
+
+ cv.Optional('esphome_core_version'): cv.invalid("The esphome_core_version option has been "
+ "removed in 1.13 - the esphome core source "
+ "files are now bundled with ESPHome.")
})
PRELOAD_CONFIG_SCHEMA = cv.Schema({
diff --git a/esphome/cpp_generator.py b/esphome/cpp_generator.py
index 38217ea9bb..c1e4a87179 100644
--- a/esphome/cpp_generator.py
+++ b/esphome/cpp_generator.py
@@ -328,6 +328,17 @@ class ExpressionStatement(Statement):
return u"{};".format(self.expression)
+class LineComment(Statement):
+ def __init__(self, value): # type: (unicode) -> None
+ super(LineComment, self).__init__()
+ self._value = value
+
+ def __str__(self):
+ parts = self._value.split(u'\n')
+ parts = [u'// {}'.format(x) for x in parts]
+ return u'\n'.join(parts)
+
+
class ProgmemAssignmentExpression(AssignmentExpression):
def __init__(self, type, name, rhs, obj):
super(ProgmemAssignmentExpression, self).__init__(
diff --git a/esphome/dashboard/dashboard.py b/esphome/dashboard/dashboard.py
index 91370a8194..0d6a26c6ee 100644
--- a/esphome/dashboard/dashboard.py
+++ b/esphome/dashboard/dashboard.py
@@ -729,7 +729,7 @@ def start_web_server(args):
webbrowser.open('localhost:{}'.format(args.port))
- if not settings.status_use_ping:
+ if settings.status_use_ping:
status_thread = PingStatusThread()
else:
status_thread = MDNSStatusThread()
diff --git a/esphome/dashboard/static/esphome.js b/esphome/dashboard/static/esphome.js
index 5a4a89ef5f..568537a3c9 100644
--- a/esphome/dashboard/static/esphome.js
+++ b/esphome/dashboard/static/esphome.js
@@ -708,3 +708,11 @@ const startWizard = () => {
};
setupWizardStart.addEventListener('click', startWizard);
+
+jQuery.validator.addMethod("nospaces", (value, element) => {
+ return value.indexOf(' ') < 0;
+}, "Name must not contain spaces.");
+
+jQuery.validator.addMethod("lowercase", (value, element) => {
+ return value === value.toLowerCase();
+}, "Name must be lowercase.");
diff --git a/esphome/dashboard/templates/index.html b/esphome/dashboard/templates/index.html
index e7259b719d..b7df4509cc 100644
--- a/esphome/dashboard/templates/index.html
+++ b/esphome/dashboard/templates/index.html
@@ -189,7 +189,7 @@
0-9 and _)
-
+
@@ -207,8 +207,7 @@
Please choose the board you're using below.
- If you're not sure you can also use similar ones or even the
- "Generic" option. In most cases that will work too.
+ If unsure you can also select a similar board or choose the "Generic" option.