Skip to content
This repository has been archived by the owner on Sep 27, 2023. It is now read-only.

Commit

Permalink
Introduce new setup phase: "dump config" to allow fully-offline opera…
Browse files Browse the repository at this point in the history
…tion (#267)

* Introduce new setup phase: "dump config" to allow fully-offline operation

* Fixes

* Re-default to light power save mode

* Global variables

* Fix
  • Loading branch information
OttoWinter authored Nov 12, 2018
1 parent 4fe4c56 commit 2cb0f14
Show file tree
Hide file tree
Showing 179 changed files with 1,716 additions and 606 deletions.
9 changes: 8 additions & 1 deletion src/esphomelib/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void Application::setup() {
assert(this->application_state_ == COMPONENT_STATE_CONSTRUCTION && "setup() called twice.");
ESP_LOGV(TAG, "Sorting components by setup priority...");
std::stable_sort(this->components_.begin(), this->components_.end(), [](const Component *a, const Component *b) {
return a->get_setup_priority() > b->get_setup_priority();
return a->get_actual_setup_priority() > b->get_actual_setup_priority();
});

for (uint32_t i = 0; i < this->components_.size(); i++) {
Expand Down Expand Up @@ -86,11 +86,18 @@ void Application::setup() {

this->application_state_ = COMPONENT_STATE_SETUP;

ESP_LOGI(TAG, "setup() finished successfully!");

if (this->compilation_time_.empty()) {
ESP_LOGI(TAG, "You're running esphomelib v" ESPHOMELIB_VERSION);
} else {
ESP_LOGI(TAG, "You're running esphomelib v" ESPHOMELIB_VERSION " compiled on %s", this->compilation_time_.c_str());
}

for (uint32_t i = 0; i < this->components_.size(); i++) {
Component *component = this->components_[i];
component->dump_config();
}
}

void HOT Application::loop() {
Expand Down
16 changes: 16 additions & 0 deletions src/esphomelib/application.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,12 @@ class Application {
display::Nextion *make_nextion(UARTComponent *parent, uint32_t update_interval = 5000);
#endif

template<typename T>
GlobalVariableComponent<T> *make_global_variable();

template<typename T>
GlobalVariableComponent<T> *make_global_variable(T initial_value);




Expand Down Expand Up @@ -1366,6 +1372,16 @@ Automation<T> *Application::make_automation(Trigger<T> *trigger) {
return new Automation<T>(trigger);
}

template<typename T>
GlobalVariableComponent<T> *Application::make_global_variable() {
return this->register_component(new GlobalVariableComponent<T>());
}

template<typename T>
GlobalVariableComponent<T> *Application::make_global_variable(T initial_value) {
return this->register_component(new GlobalVariableComponent<T>(initial_value));
}

ESPHOMELIB_NAMESPACE_END

#endif //ESPHOMELIB_APPLICATION_H
3 changes: 3 additions & 0 deletions src/esphomelib/automation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ ShutdownTrigger::ShutdownTrigger() {
void LoopTrigger::loop() {
this->trigger();
}
float LoopTrigger::get_setup_priority() const {
return setup_priority::HARDWARE_LATE;
}

RangeCondition::RangeCondition() = default;

Expand Down
71 changes: 71 additions & 0 deletions src/esphomelib/automation.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "esphomelib/component.h"
#include "esphomelib/helpers.h"
#include "esphomelib/defines.h"
#include "esphomelib/esppreferences.h"

ESPHOMELIB_NAMESPACE_BEGIN

Expand Down Expand Up @@ -94,6 +95,7 @@ class ShutdownTrigger : public Trigger<const char *> {
class LoopTrigger : public Trigger<NoArg>, public Component {
public:
void loop() override;
float get_setup_priority() const override;
};

template<typename T>
Expand Down Expand Up @@ -130,6 +132,7 @@ class DelayAction : public Action<T>, public Component {
void set_delay(uint32_t delay);

void play(T x) override;
float get_setup_priority() const override;
protected:
TemplatableValue<uint32_t, T> delay_{0};
};
Expand Down Expand Up @@ -211,6 +214,29 @@ class Automation {
ActionList<T> actions_;
};

template<typename T>
class GlobalVariableComponent : public Component {
public:
explicit GlobalVariableComponent();
explicit GlobalVariableComponent(T initial_value);

T &value();

void setup() override;

float get_setup_priority() const override;

void loop() override;

void set_restore_value(uint32_t name_hash);

protected:
T value_{};
T prev_value_{};
bool restore_value_{false};
uint32_t name_hash_{};
ESPPreferenceObject rtc_;
};

// =============== TEMPLATE DEFINITIONS ===============

Expand Down Expand Up @@ -279,6 +305,10 @@ template<typename T>
void DelayAction<T>::set_delay(uint32_t delay) {
this->delay_ = delay;
}
template<typename T>
float DelayAction<T>::get_setup_priority() const {
return setup_priority::HARDWARE;
}

template<typename T>
Condition<T> *Automation<T>::add_condition(Condition<T> *condition) {
Expand Down Expand Up @@ -427,6 +457,47 @@ ScriptExecuteAction<T> *Script::make_execute_action() {
return new ScriptExecuteAction<T>(this);
}

template<typename T>
GlobalVariableComponent<T>::GlobalVariableComponent() {

}
template<typename T>
GlobalVariableComponent<T>::GlobalVariableComponent(T initial_value)
: value_(initial_value) {

}
template<typename T>
T &GlobalVariableComponent<T>::value() {
return this->value_;
}
template<typename T>
void GlobalVariableComponent<T>::setup() {
if (this->restore_value_) {
this->rtc_ = global_preferences.make_preference<T>(1944399030U ^ this->name_hash_);
this->rtc_.load(&this->value_);
}
memcpy(&this->prev_value_, &this->value_, sizeof(T));
}
template<typename T>
float GlobalVariableComponent<T>::get_setup_priority() const {
return setup_priority::HARDWARE;
}
template<typename T>
void GlobalVariableComponent<T>::loop() {
if (this->restore_value_) {
int diff = memcmp(&this->value_, &this->prev_value_, sizeof(T));
if (diff != 0) {
this->rtc_.save(&this->value_);
memcpy(&this->prev_value_, &this->value_, sizeof(T));
}
}
}
template<typename T>
void GlobalVariableComponent<T>::set_restore_value(uint32_t name_hash) {
this->restore_value_ = true;
this->name_hash_ = name_hash;
}

ESPHOMELIB_NAMESPACE_END

#endif //ESPHOMELIB_AUTOMATION_H
62 changes: 35 additions & 27 deletions src/esphomelib/binary_sensor/esp32_touch_binary_sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,32 @@ void ESP32TouchComponent::setup() {
ESP_LOGCONFIG(TAG, "Setting up ESP32 Touch Hub...");
touch_pad_init();

#ifdef ESPHOMELIB_LOG_HAS_CONFIG
ESP_LOGCONFIG(TAG, " Meas cycle: %.2fms", this->meas_cycle_ / (8000000.0f / 1000.0f));
ESP_LOGCONFIG(TAG, " Sleep cycle: %.2fms", this->sleep_cycle_ / (150000.0f / 1000.0f));
if (this->iir_filter_enabled_()) {
touch_pad_filter_start(this->iir_filter_);
}

touch_pad_set_meas_time(this->sleep_cycle_, this->meas_cycle_);
touch_pad_set_voltage(this->high_voltage_reference_, this->low_voltage_reference_,
this->voltage_attenuation_);

for (auto *child : this->children_) {
// Disable interrupt threshold
touch_pad_config(child->get_touch_pad(), 0);
}

add_shutdown_hook([this](const char *cause) {
if (this->iir_filter_enabled_()) {
touch_pad_filter_stop();
touch_pad_filter_delete();
}
touch_pad_deinit();
});
}

void ESP32TouchComponent::dump_config() {
ESP_LOGCONFIG(TAG, "Config for ESP32 Touch Hub:");
ESP_LOGCONFIG(TAG, " Meas cycle: %.2fms", this->meas_cycle_ / (8000000.0f / 1000.0f));
ESP_LOGCONFIG(TAG, " Sleep cycle: %.2fms", this->sleep_cycle_ / (150000.0f / 1000.0f));

const char *lv_s;
switch (this->low_voltage_reference_) {
Expand All @@ -27,7 +50,7 @@ void ESP32TouchComponent::setup() {
case TOUCH_LVOLT_0V8: lv_s = "0.8V"; break;
default: lv_s = "UNKNOWN"; break;
}
ESP_LOGCONFIG(TAG, " Low Voltage Reference: %s", lv_s);
ESP_LOGCONFIG(TAG, " Low Voltage Reference: %s", lv_s);

const char *hv_s;
switch (this->high_voltage_reference_) {
Expand All @@ -37,7 +60,7 @@ void ESP32TouchComponent::setup() {
case TOUCH_HVOLT_2V7: hv_s = "2.7V"; break;
default: hv_s = "UNKNOWN"; break;
}
ESP_LOGCONFIG(TAG, " High Voltage Reference: %s", hv_s);
ESP_LOGCONFIG(TAG, " High Voltage Reference: %s", hv_s);

const char *atten_s;
switch (this->voltage_attenuation_) {
Expand All @@ -47,39 +70,24 @@ void ESP32TouchComponent::setup() {
case TOUCH_HVOLT_ATTEN_0V: atten_s = "0V"; break;
default: atten_s = "UNKNOWN"; break;
}
ESP_LOGCONFIG(TAG, " Voltage Attenuation: %s", atten_s);
#endif
ESP_LOGCONFIG(TAG, " Voltage Attenuation: %s", atten_s);


if (this->iir_filter_enabled_()) {
ESP_LOGCONFIG(TAG, " IIR Filter: %ums", this->iir_filter_);
touch_pad_filter_start(this->iir_filter_);
} else {
ESP_LOGCONFIG(TAG, " IIR Filter DISABLED");
ESP_LOGCONFIG(TAG, " IIR Filter DISABLED");
}
if (this->setup_mode_) {
ESP_LOGCONFIG(TAG, " Setup Mode ENABLED!");
ESP_LOGCONFIG(TAG, " Setup Mode ENABLED!");
}

touch_pad_set_meas_time(this->sleep_cycle_, this->meas_cycle_);
touch_pad_set_voltage(this->high_voltage_reference_, this->low_voltage_reference_,
this->voltage_attenuation_);

for (auto *child : this->children_) {
// Disable interrupt threshold
touch_pad_config(child->get_touch_pad(), 0);

ESP_LOGCONFIG(TAG, " Pad '%s'", child->get_name().c_str());
ESP_LOGCONFIG(TAG, " Touch Pad: T%d", child->get_touch_pad());
ESP_LOGCONFIG(TAG, " Threshold: %u", child->get_threshold());
ESP_LOGCONFIG(TAG, " Pad '%s'", child->get_name().c_str());
ESP_LOGCONFIG(TAG, " Touch Pad: T%d", child->get_touch_pad());
ESP_LOGCONFIG(TAG, " Threshold: %u", child->get_threshold());
}

add_shutdown_hook([this](const char *cause) {
if (this->iir_filter_enabled_()) {
touch_pad_filter_stop();
touch_pad_filter_delete();
}
touch_pad_deinit();
});
}

void ESP32TouchComponent::loop() {
Expand Down
1 change: 1 addition & 0 deletions src/esphomelib/binary_sensor/esp32_touch_binary_sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ class ESP32TouchComponent : public Component {
// ========== INTERNAL METHODS ==========
// (In most use cases you won't need these)
void setup() override;
void dump_config() override;
void loop() override;
float get_setup_priority() const override;

Expand Down
9 changes: 9 additions & 0 deletions src/esphomelib/binary_sensor/filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ optional<bool> DelayedOnFilter::new_value(bool value) {
return false;
}
}
float DelayedOnFilter::get_setup_priority() const {
return setup_priority::HARDWARE;
}

void Filter::output(bool value) {
if (this->next_ == nullptr) {
Expand Down Expand Up @@ -51,6 +54,9 @@ optional<bool> DelayedOffFilter::new_value(bool value) {
return true;
}
}
float DelayedOffFilter::get_setup_priority() const {
return setup_priority::HARDWARE;
}

optional<bool> InvertFilter::new_value(bool value) {
return !value;
Expand Down Expand Up @@ -82,6 +88,9 @@ void HeartbeatFilter::setup() {
this->output(*this->value_);
});
}
float HeartbeatFilter::get_setup_priority() const {
return setup_priority::HARDWARE;
}
} // namespace binary_sensor

ESPHOMELIB_NAMESPACE_END
Expand Down
6 changes: 6 additions & 0 deletions src/esphomelib/binary_sensor/filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class DelayedOnFilter : public Filter, public Component {

optional<bool> new_value(bool value) override;

float get_setup_priority() const override;

protected:
uint32_t delay_;
};
Expand All @@ -44,6 +46,8 @@ class DelayedOffFilter : public Filter, public Component {

optional<bool> new_value(bool value) override;

float get_setup_priority() const override;

protected:
uint32_t delay_;
};
Expand All @@ -56,6 +60,8 @@ class HeartbeatFilter : public Filter, public Component {

void setup();

float get_setup_priority() const override;

protected:
uint32_t interval_;
optional<bool> value_{};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ void GPIOBinarySensorComponent::setup() {
this->publish_state(this->last_state_);
}

void GPIOBinarySensorComponent::dump_config() {
ESP_LOGCONFIG(TAG, "GPIO Binary Sensor '%s':", this->name_.c_str());
LOG_PIN(" Pin: ", this->pin_);
}

void GPIOBinarySensorComponent::loop() {
bool new_state = this->pin_->digital_read();
if (this->last_state_ != new_state) {
Expand All @@ -30,7 +35,6 @@ void GPIOBinarySensorComponent::loop() {
float GPIOBinarySensorComponent::get_setup_priority() const {
return setup_priority::HARDWARE;
}

GPIOBinarySensorComponent::GPIOBinarySensorComponent(const std::string &name, GPIOPin *pin)
: BinarySensor(name), pin_(pin) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class GPIOBinarySensorComponent : public BinarySensor, public Component {
// (In most use cases you won't need these)
/// Setup pin
void setup() override;
void dump_config() override;
/// Hardware priority
float get_setup_priority() const override;
/// Check sensor
Expand Down
Loading

0 comments on commit 2cb0f14

Please sign in to comment.