mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Fix GPS time source. (#704)
* Change ESP32 default power_save_mode to light * Update
This commit is contained in:
		| @@ -8,5 +8,41 @@ static const char *TAG = "gps"; | |||||||
|  |  | ||||||
| TinyGPSPlus &GPSListener::get_tiny_gps() { return this->parent_->get_tiny_gps(); } | TinyGPSPlus &GPSListener::get_tiny_gps() { return this->parent_->get_tiny_gps(); } | ||||||
|  |  | ||||||
|  | void GPS::loop() { | ||||||
|  |   while (this->available() && !this->has_time_) { | ||||||
|  |     if (this->tiny_gps_.encode(this->read())) { | ||||||
|  |       if (tiny_gps_.location.isUpdated()) { | ||||||
|  |         ESP_LOGD(TAG, "Location:"); | ||||||
|  |         ESP_LOGD(TAG, "  Lat: %f", tiny_gps_.location.lat()); | ||||||
|  |         ESP_LOGD(TAG, "  Lon: %f", tiny_gps_.location.lng()); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if (tiny_gps_.speed.isUpdated()) { | ||||||
|  |         ESP_LOGD(TAG, "Speed:"); | ||||||
|  |         ESP_LOGD(TAG, "  %f km/h", tiny_gps_.speed.kmph()); | ||||||
|  |       } | ||||||
|  |       if (tiny_gps_.course.isUpdated()) { | ||||||
|  |         ESP_LOGD(TAG, "Course:"); | ||||||
|  |         ESP_LOGD(TAG, "  %f °", tiny_gps_.course.deg()); | ||||||
|  |       } | ||||||
|  |       if (tiny_gps_.altitude.isUpdated()) { | ||||||
|  |         ESP_LOGD(TAG, "Altitude:"); | ||||||
|  |         ESP_LOGD(TAG, "  %f m", tiny_gps_.altitude.meters()); | ||||||
|  |       } | ||||||
|  |       if (tiny_gps_.satellites.isUpdated()) { | ||||||
|  |         ESP_LOGD(TAG, "Satellites:"); | ||||||
|  |         ESP_LOGD(TAG, "  %d", tiny_gps_.satellites.value()); | ||||||
|  |       } | ||||||
|  |       if (tiny_gps_.satellites.isUpdated()) { | ||||||
|  |         ESP_LOGD(TAG, "HDOP:"); | ||||||
|  |         ESP_LOGD(TAG, "  %.2f", tiny_gps_.hdop.hdop()); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       for (auto *listener : this->listeners_) | ||||||
|  |         listener->on_update(this->tiny_gps_); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| }  // namespace gps | }  // namespace gps | ||||||
| }  // namespace esphome | }  // namespace esphome | ||||||
|   | |||||||
| @@ -27,14 +27,7 @@ class GPS : public Component, public uart::UARTDevice { | |||||||
|     this->listeners_.push_back(listener); |     this->listeners_.push_back(listener); | ||||||
|   } |   } | ||||||
|   float get_setup_priority() const override { return setup_priority::HARDWARE; } |   float get_setup_priority() const override { return setup_priority::HARDWARE; } | ||||||
|   void loop() override { |   void loop() override; | ||||||
|     while (this->available() && !this->has_time_) { |  | ||||||
|       if (this->tiny_gps_.encode(this->read())) { |  | ||||||
|         for (auto *listener : this->listeners_) |  | ||||||
|           listener->on_update(this->tiny_gps_); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   TinyGPSPlus &get_tiny_gps() { return this->tiny_gps_; } |   TinyGPSPlus &get_tiny_gps() { return this->tiny_gps_; } | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   | |||||||
| @@ -6,5 +6,29 @@ namespace gps { | |||||||
|  |  | ||||||
| static const char *TAG = "gps.time"; | static const char *TAG = "gps.time"; | ||||||
|  |  | ||||||
|  | void GPSTime::from_tiny_gps_(TinyGPSPlus &tiny_gps) { | ||||||
|  |   if (!tiny_gps.time.isValid() || !tiny_gps.date.isValid()) | ||||||
|  |     return; | ||||||
|  |   if (!tiny_gps.time.isUpdated() || !tiny_gps.date.isUpdated()) | ||||||
|  |     return; | ||||||
|  |   if (tiny_gps.date.year() < 2019) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   time::ESPTime val{}; | ||||||
|  |   val.year = tiny_gps.date.year(); | ||||||
|  |   val.month = tiny_gps.date.month(); | ||||||
|  |   val.day_of_month = tiny_gps.date.day(); | ||||||
|  |   // Set these to valid value for  recalc_timestamp_utc - it's not used for calculation | ||||||
|  |   val.day_of_week = 1; | ||||||
|  |   val.day_of_year = 1; | ||||||
|  |  | ||||||
|  |   val.hour = tiny_gps.time.hour(); | ||||||
|  |   val.minute = tiny_gps.time.minute(); | ||||||
|  |   val.second = tiny_gps.time.second(); | ||||||
|  |   val.recalc_timestamp_utc(false); | ||||||
|  |   this->synchronize_epoch_(val.timestamp); | ||||||
|  |   this->has_time_ = true; | ||||||
|  | } | ||||||
|  |  | ||||||
| }  // namespace gps | }  // namespace gps | ||||||
| }  // namespace esphome | }  // namespace esphome | ||||||
|   | |||||||
| @@ -18,20 +18,7 @@ class GPSTime : public time::RealTimeClock, public GPSListener { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   void from_tiny_gps_(TinyGPSPlus &tiny_gps) { |   void from_tiny_gps_(TinyGPSPlus &tiny_gps); | ||||||
|     if (!tiny_gps.time.isValid() || !tiny_gps.date.isValid()) |  | ||||||
|       return; |  | ||||||
|     time::ESPTime val{}; |  | ||||||
|     val.year = tiny_gps.date.year(); |  | ||||||
|     val.month = tiny_gps.date.month(); |  | ||||||
|     val.day_of_month = tiny_gps.date.day(); |  | ||||||
|     val.hour = tiny_gps.time.hour(); |  | ||||||
|     val.minute = tiny_gps.time.minute(); |  | ||||||
|     val.second = tiny_gps.time.second(); |  | ||||||
|     val.recalc_timestamp_utc(false); |  | ||||||
|     this->synchronize_epoch_(val.timestamp); |  | ||||||
|     this->has_time_ = true; |  | ||||||
|   } |  | ||||||
|   bool has_time_{false}; |   bool has_time_{false}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -115,8 +115,9 @@ def convert_tz(pytz_obj): | |||||||
|                                 _tz_dst_str(dst_begins_local), _tz_dst_str(dst_ends_local)) |                                 _tz_dst_str(dst_begins_local), _tz_dst_str(dst_ends_local)) | ||||||
|     _LOGGER.info("Detected timezone '%s' with UTC offset %s and daylight savings time from " |     _LOGGER.info("Detected timezone '%s' with UTC offset %s and daylight savings time from " | ||||||
|                  "%s to %s", |                  "%s to %s", | ||||||
|                  tzname_off, _tz_timedelta(utcoffset_off), dst_begins_local.strftime("%x %X"), |                  tzname_off, _tz_timedelta(utcoffset_off), | ||||||
|                  dst_ends_local.strftime("%x %X")) |                  dst_begins_local.strftime("%d %B %X"), | ||||||
|  |                  dst_ends_local.strftime("%d %B %X")) | ||||||
|     return tzbase + tzext |     return tzbase + tzext | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -84,12 +84,12 @@ template<typename T> bool increment_time_value(T ¤t, uint16_t begin, uint1 | |||||||
|  |  | ||||||
| static bool is_leap_year(uint32_t year) { return (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0); } | static bool is_leap_year(uint32_t year) { return (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0); } | ||||||
|  |  | ||||||
| static bool days_in_month(uint8_t month, uint16_t year) { | static uint8_t days_in_month(uint8_t month, uint16_t year) { | ||||||
|   static const uint8_t DAYS_IN_MONTH[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; |   static const uint8_t DAYS_IN_MONTH[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; | ||||||
|   uint8_t days_in_month = DAYS_IN_MONTH[month]; |   uint8_t days = DAYS_IN_MONTH[month]; | ||||||
|   if (month == 2 && is_leap_year(year)) |   if (month == 2 && is_leap_year(year)) | ||||||
|     days_in_month = 29; |     return 29; | ||||||
|   return days_in_month; |   return days; | ||||||
| } | } | ||||||
|  |  | ||||||
| void ESPTime::increment_second() { | void ESPTime::increment_second() { | ||||||
| @@ -127,13 +127,13 @@ void ESPTime::recalc_timestamp_utc(bool use_day_of_year) { | |||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   for (uint16_t i = 1970; i < this->year; i++) |   for (int i = 1970; i < this->year; i++) | ||||||
|     res += is_leap_year(i) ? 366 : 365; |     res += is_leap_year(i) ? 366 : 365; | ||||||
|  |  | ||||||
|   if (use_day_of_year) { |   if (use_day_of_year) { | ||||||
|     res += this->day_of_year - 1; |     res += this->day_of_year - 1; | ||||||
|   } else { |   } else { | ||||||
|     for (uint8_t i = 1; i < this->month; ++i) |     for (int i = 1; i < this->month; i++) | ||||||
|       res += days_in_month(i, this->year); |       res += days_in_month(i, this->year); | ||||||
|  |  | ||||||
|     res += this->day_of_month - 1; |     res += this->day_of_month - 1; | ||||||
|   | |||||||
| @@ -291,12 +291,12 @@ void ICACHE_RAM_ATTR HOT ESP8266SoftwareSerial::write_byte(uint8_t data) { | |||||||
|   this->write_bit_(true, &wait, start); |   this->write_bit_(true, &wait, start); | ||||||
|   enable_interrupts(); |   enable_interrupts(); | ||||||
| } | } | ||||||
| void ESP8266SoftwareSerial::wait_(uint32_t *wait, const uint32_t &start) { | void ICACHE_RAM_ATTR ESP8266SoftwareSerial::wait_(uint32_t *wait, const uint32_t &start) { | ||||||
|   while (ESP.getCycleCount() - start < *wait) |   while (ESP.getCycleCount() - start < *wait) | ||||||
|     ; |     ; | ||||||
|   *wait += this->bit_time_; |   *wait += this->bit_time_; | ||||||
| } | } | ||||||
| bool ESP8266SoftwareSerial::read_bit_(uint32_t *wait, const uint32_t &start) { | bool ICACHE_RAM_ATTR ESP8266SoftwareSerial::read_bit_(uint32_t *wait, const uint32_t &start) { | ||||||
|   this->wait_(wait, start); |   this->wait_(wait, start); | ||||||
|   return this->rx_pin_->digital_read(); |   return this->rx_pin_->digital_read(); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -24,9 +24,9 @@ class ESP8266SoftwareSerial { | |||||||
|  protected: |  protected: | ||||||
|   static void gpio_intr(ESP8266SoftwareSerial *arg); |   static void gpio_intr(ESP8266SoftwareSerial *arg); | ||||||
|  |  | ||||||
|   inline void wait_(uint32_t *wait, const uint32_t &start); |   void wait_(uint32_t *wait, const uint32_t &start); | ||||||
|   inline bool read_bit_(uint32_t *wait, const uint32_t &start); |   bool read_bit_(uint32_t *wait, const uint32_t &start); | ||||||
|   inline void write_bit_(bool bit, uint32_t *wait, const uint32_t &start); |   void write_bit_(bool bit, uint32_t *wait, const uint32_t &start); | ||||||
|  |  | ||||||
|   uint32_t bit_time_{0}; |   uint32_t bit_time_{0}; | ||||||
|   uint8_t *rx_buffer_{nullptr}; |   uint8_t *rx_buffer_{nullptr}; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user