mirror of
https://github.com/esphome/esphome.git
synced 2024-11-10 10:00:36 +01:00
1e96a19d09
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
118 lines
3.2 KiB
C++
118 lines
3.2 KiB
C++
#include "date_entity.h"
|
|
|
|
#ifdef USE_DATETIME_DATE
|
|
|
|
#include "esphome/core/log.h"
|
|
|
|
namespace esphome {
|
|
namespace datetime {
|
|
|
|
static const char *const TAG = "datetime.date_entity";
|
|
|
|
void DateEntity::publish_state() {
|
|
if (this->year_ == 0 || this->month_ == 0 || this->day_ == 0) {
|
|
this->has_state_ = false;
|
|
return;
|
|
}
|
|
if (this->year_ < 1970 || this->year_ > 3000) {
|
|
this->has_state_ = false;
|
|
ESP_LOGE(TAG, "Year must be between 1970 and 3000");
|
|
return;
|
|
}
|
|
if (this->month_ < 1 || this->month_ > 12) {
|
|
this->has_state_ = false;
|
|
ESP_LOGE(TAG, "Month must be between 1 and 12");
|
|
return;
|
|
}
|
|
if (this->day_ > days_in_month(this->month_, this->year_)) {
|
|
this->has_state_ = false;
|
|
ESP_LOGE(TAG, "Day must be between 1 and %d for month %d", days_in_month(this->month_, this->year_), this->month_);
|
|
return;
|
|
}
|
|
this->has_state_ = true;
|
|
ESP_LOGD(TAG, "'%s': Sending date %d-%d-%d", this->get_name().c_str(), this->year_, this->month_, this->day_);
|
|
this->state_callback_.call();
|
|
}
|
|
|
|
DateCall DateEntity::make_call() { return DateCall(this); }
|
|
|
|
void DateCall::validate_() {
|
|
if (this->year_.has_value() && (this->year_ < 1970 || this->year_ > 3000)) {
|
|
ESP_LOGE(TAG, "Year must be between 1970 and 3000");
|
|
this->year_.reset();
|
|
}
|
|
if (this->month_.has_value() && (this->month_ < 1 || this->month_ > 12)) {
|
|
ESP_LOGE(TAG, "Month must be between 1 and 12");
|
|
this->month_.reset();
|
|
}
|
|
if (this->day_.has_value()) {
|
|
uint16_t year = 0;
|
|
uint8_t month = 0;
|
|
if (this->month_.has_value()) {
|
|
month = *this->month_;
|
|
} else {
|
|
if (this->parent_->month != 0) {
|
|
month = this->parent_->month;
|
|
} else {
|
|
ESP_LOGE(TAG, "Month must be set to validate day");
|
|
this->day_.reset();
|
|
}
|
|
}
|
|
if (this->year_.has_value()) {
|
|
year = *this->year_;
|
|
} else {
|
|
if (this->parent_->year != 0) {
|
|
year = this->parent_->year;
|
|
} else {
|
|
ESP_LOGE(TAG, "Year must be set to validate day");
|
|
this->day_.reset();
|
|
}
|
|
}
|
|
if (this->day_.has_value() && *this->day_ > days_in_month(month, year)) {
|
|
ESP_LOGE(TAG, "Day must be between 1 and %d for month %d", days_in_month(month, year), month);
|
|
this->day_.reset();
|
|
}
|
|
}
|
|
}
|
|
|
|
void DateCall::perform() {
|
|
this->validate_();
|
|
this->parent_->control(*this);
|
|
}
|
|
|
|
DateCall &DateCall::set_date(uint16_t year, uint8_t month, uint8_t day) {
|
|
this->year_ = year;
|
|
this->month_ = month;
|
|
this->day_ = day;
|
|
return *this;
|
|
};
|
|
|
|
DateCall &DateCall::set_date(ESPTime time) { return this->set_date(time.year, time.month, time.day_of_month); };
|
|
|
|
DateCall &DateCall::set_date(const std::string &date) {
|
|
ESPTime val{};
|
|
if (!ESPTime::strptime(date, val)) {
|
|
ESP_LOGE(TAG, "Could not convert the date string to an ESPTime object");
|
|
return *this;
|
|
}
|
|
return this->set_date(val);
|
|
}
|
|
|
|
DateCall DateEntityRestoreState::to_call(DateEntity *date) {
|
|
DateCall call = date->make_call();
|
|
call.set_date(this->year, this->month, this->day);
|
|
return call;
|
|
}
|
|
|
|
void DateEntityRestoreState::apply(DateEntity *date) {
|
|
date->year_ = this->year;
|
|
date->month_ = this->month;
|
|
date->day_ = this->day;
|
|
date->publish_state();
|
|
}
|
|
|
|
} // namespace datetime
|
|
} // namespace esphome
|
|
|
|
#endif // USE_DATETIME_DATE
|