ESPHome  2024.11.0
sun.h
Go to the documentation of this file.
1 #pragma once
2 
5 #include "esphome/core/helpers.h"
6 #include "esphome/core/time.h"
7 
9 
10 namespace esphome {
11 namespace sun {
12 
13 namespace internal {
14 
15 /* Usually, ESPHome uses single-precision floating point values
16  * because those tend to be accurate enough and are more efficient.
17  *
18  * However, some of the data in this class has to be quite accurate, so double is
19  * used everywhere.
20  */
21 using num_t = double;
22 struct GeoLocation {
25 
26  num_t latitude_rad() const;
27  num_t longitude_rad() const;
28 };
29 
30 struct Moment {
32 
33  num_t jd() const;
34  num_t jde() const;
35 };
36 
40 
41  num_t right_ascension_rad() const;
42  num_t declination_rad() const;
43 };
44 
48 
49  num_t elevation_rad() const;
50  num_t azimuth_rad() const;
51 };
52 
53 } // namespace internal
54 
55 class Sun {
56  public:
57  void set_time(time::RealTimeClock *time) { time_ = time; }
58  time::RealTimeClock *get_time() const { return time_; }
59  void set_latitude(double latitude) { location_.latitude = latitude; }
60  void set_longitude(double longitude) { location_.longitude = longitude; }
61 
62  // Check if the sun is above the horizon, with a default elevation angle of -0.83333 (standard for sunrise/set).
63  bool is_above_horizon(double elevation = -0.83333) { return this->elevation() > elevation; }
64 
65  optional<ESPTime> sunrise(double elevation);
66  optional<ESPTime> sunset(double elevation);
67  optional<ESPTime> sunrise(ESPTime date, double elevation);
68  optional<ESPTime> sunset(ESPTime date, double elevation);
69 
70  double elevation();
71  double azimuth();
72 
73  protected:
74  internal::HorizontalCoordinate calc_coords_();
75  optional<ESPTime> calc_event_(bool rising, double zenith);
76  optional<ESPTime> calc_event_(ESPTime date, bool rising, double zenith);
77 
80 };
81 
82 class SunTrigger : public Trigger<>, public PollingComponent, public Parented<Sun> {
83  public:
85 
86  void set_sunrise(bool sunrise) { sunrise_ = sunrise; }
87  void set_elevation(double elevation) { elevation_ = elevation; }
88 
89  void update() override {
90  double current = this->parent_->elevation();
91  if (std::isnan(current))
92  return;
93 
94  bool crossed;
95  if (this->sunrise_) {
96  crossed = this->last_elevation_ <= this->elevation_ && this->elevation_ < current;
97  } else {
98  crossed = this->last_elevation_ >= this->elevation_ && this->elevation_ > current;
99  }
100 
101  if (crossed && !std::isnan(this->last_elevation_)) {
102  this->trigger();
103  }
104  this->last_elevation_ = current;
105  }
106 
107  protected:
108  bool sunrise_;
109  double last_elevation_{NAN};
110  double elevation_;
111 };
112 
113 template<typename... Ts> class SunCondition : public Condition<Ts...>, public Parented<Sun> {
114  public:
115  TEMPLATABLE_VALUE(double, elevation);
116  void set_above(bool above) { above_ = above; }
117 
118  bool check(Ts... x) override {
119  double elevation = this->elevation_.value(x...);
120  double current = this->parent_->elevation();
121  if (this->above_) {
122  return current > elevation;
123  } else {
124  return current < elevation;
125  }
126  }
127 
128  protected:
129  bool above_;
130 };
131 
132 } // namespace sun
133 } // namespace esphome
internal::GeoLocation location_
Definition: sun.h:79
The RealTimeClock class exposes common timekeeping functions via the device&#39;s local real-time clock...
uint16_t x
Definition: tt21100.cpp:17
void set_sunrise(bool sunrise)
Definition: sun.h:86
A more user-friendly version of struct tm from time.h.
Definition: time.h:17
void set_longitude(double longitude)
Definition: sun.h:60
void update() override
Definition: sun.h:89
This class simplifies creating components that periodically check a state.
Definition: component.h:283
time::RealTimeClock * get_time() const
Definition: sun.h:58
void set_time(time::RealTimeClock *time)
Definition: sun.h:57
Base class for all automation conditions.
Definition: automation.h:74
void set_elevation(double elevation)
Definition: sun.h:87
bool is_above_horizon(double elevation=-0.83333)
Definition: sun.h:63
void set_above(bool above)
Definition: sun.h:116
bool check(Ts... x) override
Definition: sun.h:118
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
time::RealTimeClock * time_
Definition: sun.h:78
Helper class to easily give an object a parent of type T.
Definition: helpers.h:522
void set_latitude(double latitude)
Definition: sun.h:59