ESPHome  2024.4.0
duty_time_sensor.cpp
Go to the documentation of this file.
1 #include "duty_time_sensor.h"
2 #include "esphome/core/hal.h"
3 
4 namespace esphome {
5 namespace duty_time_sensor {
6 
7 static const char *const TAG = "duty_time_sensor";
8 
9 #ifdef USE_BINARY_SENSOR
11  sensor->add_on_state_callback([this](bool state) { this->process_state_(state); });
12 }
13 #endif
14 
16  if (!this->last_state_)
17  this->process_state_(true);
18 }
19 
21  if (this->last_state_)
22  this->process_state_(false);
23 }
24 
26  if (this->last_state_)
27  this->process_state_(true);
28 }
29 
31  if (this->func_ == nullptr)
32  return;
33 
34  const bool state = this->func_();
35 
36  if (state != this->last_state_)
37  this->process_state_(state);
38 }
39 
41  uint32_t seconds = 0;
42 
43  if (this->restore_) {
44  this->pref_ = global_preferences->make_preference<uint32_t>(this->get_object_id_hash());
45  this->pref_.load(&seconds);
46  }
47 
48  this->set_value_(seconds);
49 }
50 
51 void DutyTimeSensor::set_value_(const uint32_t sec) {
52  this->last_time_ = 0;
53  if (this->last_state_)
54  this->last_time_ = millis(); // last time with 0 ms correction
55  this->publish_and_save_(sec, 0);
56 }
57 
59  const uint32_t now = millis();
60 
61  if (this->last_state_) {
62  // update or falling edge
63  const uint32_t tm = now - this->last_time_;
64  const uint32_t ms = tm % 1000;
65 
66  this->publish_and_save_(this->total_sec_ + tm / 1000, ms);
67  this->last_time_ = now - ms; // store time with ms correction
68 
69  if (!state) {
70  // falling edge
71  this->last_time_ = ms; // temporary store ms correction only
72  this->last_state_ = false;
73 
74  if (this->last_duty_time_sensor_ != nullptr) {
75  const uint32_t turn_on_ms = now - this->edge_time_;
76  this->last_duty_time_sensor_->publish_state(turn_on_ms * 1e-3f);
77  }
78  }
79 
80  } else if (state) {
81  // rising edge
82  this->last_time_ = now - this->last_time_; // store time with ms correction
83  this->edge_time_ = now; // store turn-on start time
84  this->last_state_ = true;
85  }
86 }
87 
88 void DutyTimeSensor::publish_and_save_(const uint32_t sec, const uint32_t ms) {
89  this->total_sec_ = sec;
90  this->publish_state(sec + ms * 1e-3f);
91 
92  if (this->restore_)
93  this->pref_.save(&sec);
94 }
95 
97  ESP_LOGCONFIG(TAG, "Duty Time:");
98  ESP_LOGCONFIG(TAG, " Update Interval: %" PRId32 "ms", this->get_update_interval());
99  ESP_LOGCONFIG(TAG, " Restore: %s", ONOFF(this->restore_));
100  LOG_SENSOR(" ", "Duty Time Sensor:", this);
101  LOG_SENSOR(" ", "Last Duty Time Sensor:", this->last_duty_time_sensor_);
102 }
103 
104 } // namespace duty_time_sensor
105 } // namespace esphome
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:25
bool save(const T *src)
Definition: preferences.h:21
float state
This member variable stores the last state that has passed through all filters.
Definition: sensor.h:131
ESPPreferences * global_preferences
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:39
virtual uint32_t get_update_interval() const
Get the update interval in ms of this sensor.
Definition: component.cpp:228
void publish_and_save_(uint32_t sec, uint32_t ms)
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)=0
void add_on_state_callback(std::function< void(bool)> &&callback)
Add a callback to be notified of state changes.
void set_sensor(binary_sensor::BinarySensor *sensor)
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
Base class for all binary_sensor-type classes.
Definition: binary_sensor.h:37
uint32_t get_object_id_hash()
Definition: entity_base.cpp:76