diff --git a/esphome/components/time/__init__.py b/esphome/components/time/__init__.py index c888705ba2..dff646ecbd 100644 --- a/esphome/components/time/__init__.py +++ b/esphome/components/time/__init__.py @@ -25,8 +25,9 @@ from esphome.const import ( CONF_HOUR, CONF_MINUTE, ) -from esphome.core import coroutine_with_priority +from esphome.core import coroutine_with_priority, CORE from esphome.automation import Condition +from esphome.components.zephyr import zephyr_add_prj_conf _LOGGER = logging.getLogger(__name__) @@ -269,7 +270,10 @@ def validate_tz(value: str) -> str: TIME_SCHEMA = cv.Schema( { - cv.Optional(CONF_TIMEZONE, default=detect_tz): validate_tz, + cv.Optional(CONF_TIMEZONE, default=detect_tz): cv.All( + cv.only_with_arduino_or_esp_idf, + validate_tz, + ), cv.Optional(CONF_ON_TIME): automation.validate_automation( { cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(CronTrigger), @@ -294,7 +298,8 @@ TIME_SCHEMA = cv.Schema( async def setup_time_core_(time_var, config): - cg.add(time_var.set_timezone(config[CONF_TIMEZONE])) + if not CORE.using_zephyr: + cg.add(time_var.set_timezone(config[CONF_TIMEZONE])) for conf in config.get(CONF_ON_TIME, []): trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], time_var) @@ -328,6 +333,8 @@ async def register_time(time_var, config): @coroutine_with_priority(100.0) async def to_code(config): + if CORE.using_zephyr: + zephyr_add_prj_conf("POSIX_CLOCK", True) cg.add_define("USE_TIME") cg.add_global(time_ns.using) diff --git a/esphome/components/time/real_time_clock.cpp b/esphome/components/time/real_time_clock.cpp index 2b9a95c6bd..556889fd3d 100644 --- a/esphome/components/time/real_time_clock.cpp +++ b/esphome/components/time/real_time_clock.cpp @@ -2,13 +2,15 @@ #include "esphome/core/log.h" #ifdef USE_HOST #include +#elif defined(USE_ZEPHYR) +#include #else #include "lwip/opt.h" #endif #ifdef USE_ESP8266 #include "sys/time.h" #endif -#ifdef USE_RP2040 +#if defined(USE_RP2040) || defined(USE_ZEPHYR) #include #endif #include @@ -22,15 +24,18 @@ static const char *const TAG = "time"; RealTimeClock::RealTimeClock() = default; void RealTimeClock::call_setup() { +#ifndef USE_ZEPHYR this->apply_timezone_(); +#endif PollingComponent::call_setup(); } void RealTimeClock::synchronize_epoch_(uint32_t epoch) { + ESP_LOGVV(TAG, "Got epoch %" PRIu32, epoch); // Update UTC epoch time. +#ifndef USE_ZEPHYR struct timeval timev { .tv_sec = static_cast(epoch), .tv_usec = 0, }; - ESP_LOGVV(TAG, "Got epoch %" PRIu32, epoch); struct timezone tz = {0, 0}; int ret = settimeofday(&timev, &tz); if (ret == EINVAL) { @@ -45,7 +50,18 @@ void RealTimeClock::synchronize_epoch_(uint32_t epoch) { if (ret != 0) { ESP_LOGW(TAG, "setimeofday() failed with code %d", ret); } +#else + struct timespec ts; + ts.tv_nsec = 0; + ts.tv_sec = static_cast(epoch); + int ret = clock_settime(CLOCK_REALTIME, &ts); + + if (ret != 0) { + ESP_LOGW(TAG, "clock_settime() failed with code %d", ret); + } + +#endif auto time = this->now(); ESP_LOGD(TAG, "Synchronized time: %04d-%02d-%02d %02d:%02d:%02d", time.year, time.month, time.day_of_month, time.hour, time.minute, time.second); @@ -53,10 +69,12 @@ void RealTimeClock::synchronize_epoch_(uint32_t epoch) { this->time_sync_callback_.call(); } +#ifndef USE_ZEPHYR void RealTimeClock::apply_timezone_() { setenv("TZ", this->timezone_.c_str(), 1); tzset(); } +#endif } // namespace time } // namespace esphome diff --git a/esphome/components/time/real_time_clock.h b/esphome/components/time/real_time_clock.h index a17168ae6f..db6a2fee65 100644 --- a/esphome/components/time/real_time_clock.h +++ b/esphome/components/time/real_time_clock.h @@ -19,13 +19,13 @@ namespace time { class RealTimeClock : public PollingComponent { public: explicit RealTimeClock(); - +#ifndef USE_ZEPHYR /// Set the time zone. void set_timezone(const std::string &tz) { this->timezone_ = tz; } /// Get the time zone currently in use. std::string get_timezone() { return this->timezone_; } - +#endif /// Get the time in the currently defined timezone. ESPTime now() { return ESPTime::from_epoch_local(this->timestamp_now()); } @@ -44,10 +44,10 @@ class RealTimeClock : public PollingComponent { protected: /// Report a unix epoch as current time. void synchronize_epoch_(uint32_t epoch); - +#ifndef USE_ZEPHYR std::string timezone_{}; void apply_timezone_(); - +#endif CallbackManager time_sync_callback_; }; diff --git a/esphome/config_validation.py b/esphome/config_validation.py index b3a9a3a078..6318d822d8 100644 --- a/esphome/config_validation.py +++ b/esphome/config_validation.py @@ -609,6 +609,7 @@ only_on_nrf52 = only_on(PLATFORM_NRF52) only_with_arduino = only_with_framework("arduino") only_with_esp_idf = only_with_framework("esp-idf") only_with_zephyr = only_with_framework("zephyr") +only_with_arduino_or_esp_idf = only_with_framework(["arduino", "esp-idf"]) # Adapted from: diff --git a/script/test_build_components b/script/test_build_components index 6157db4d40..e885294b99 100755 --- a/script/test_build_components +++ b/script/test_build_components @@ -58,10 +58,6 @@ for f in ./tests/components/$target_component/*.*.yaml; do IFS='.' read -r -a file_name <<< "${folder_name[4]}" test_name="${file_name[0]}" - if [ "$test_name" = "exclude" ]; then - # this is not a test file. we need to skip it. - continue - fi target_platform="${file_name[1]}" file_name_parts=${#file_name[@]} @@ -73,11 +69,6 @@ for f in ./tests/components/$target_component/*.*.yaml; do IFS='.' read -r -a file_name <<< "${folder_name[3]}" target_platform="${file_name[1]}" - if [ -f "./tests/components/$target_component/exclude.$test_name.$target_platform.yaml" ]; then - echo "Component $target_component is excluded from testing on $target_platform" - continue - fi - start_esphome done diff --git a/tests/components/datetime/exclude.test.nrf52-adafruit.yaml b/tests/components/datetime/exclude.test.nrf52-adafruit.yaml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/components/datetime/exclude.test.nrf52-mcumgr.yaml b/tests/components/datetime/exclude.test.nrf52-mcumgr.yaml deleted file mode 100644 index e69de29bb2..0000000000