Fix GPS time source. (#704)

* Change ESP32 default power_save_mode to light

* Update
This commit is contained in:
Otto Winter 2019-08-27 22:11:50 +02:00 committed by GitHub
parent 65d08beaa4
commit 2c995cf145
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 76 additions and 35 deletions

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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};
}; };

View file

@ -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

View file

@ -84,12 +84,12 @@ template<typename T> bool increment_time_value(T &current, 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;

View file

@ -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();
} }

View file

@ -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};