mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Implementing the remainder of GPS data for the GPS component. (#1676)
This commit is contained in:
		| @@ -38,6 +38,7 @@ esphome/components/ezo/* @ssieb | ||||
| esphome/components/fastled_base/* @OttoWinter | ||||
| esphome/components/globals/* @esphome/core | ||||
| esphome/components/gpio/* @esphome/core | ||||
| esphome/components/gps/* @coogle | ||||
| esphome/components/homeassistant/* @OttoWinter | ||||
| esphome/components/i2c/* @esphome/core | ||||
| esphome/components/inkbird_ibsth1_mini/* @fkirill | ||||
|   | ||||
| @@ -1,9 +1,27 @@ | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome.components import uart | ||||
| from esphome.const import CONF_ID | ||||
| from esphome.components import sensor | ||||
| from esphome.const import ( | ||||
|     CONF_ID, | ||||
|     CONF_LATITUDE, | ||||
|     CONF_LONGITUDE, | ||||
|     CONF_SPEED, | ||||
|     CONF_COURSE, | ||||
|     CONF_ALTITUDE, | ||||
|     CONF_SATELLITES, | ||||
|     UNIT_DEGREES, | ||||
|     UNIT_KILOMETER_PER_HOUR, | ||||
|     UNIT_METER, | ||||
|     UNIT_EMPTY, | ||||
|     ICON_EMPTY, | ||||
|     DEVICE_CLASS_EMPTY, | ||||
| ) | ||||
|  | ||||
| DEPENDENCIES = ["uart"] | ||||
| AUTO_LOAD = ["sensor"] | ||||
|  | ||||
| CODEOWNERS = ["@coogle"] | ||||
|  | ||||
| gps_ns = cg.esphome_ns.namespace("gps") | ||||
| GPS = gps_ns.class_("GPS", cg.Component, uart.UARTDevice) | ||||
| @@ -15,9 +33,27 @@ CONFIG_SCHEMA = ( | ||||
|     cv.Schema( | ||||
|         { | ||||
|             cv.GenerateID(): cv.declare_id(GPS), | ||||
|             cv.Optional(CONF_LATITUDE): sensor.sensor_schema( | ||||
|                 UNIT_DEGREES, ICON_EMPTY, 6, DEVICE_CLASS_EMPTY | ||||
|             ), | ||||
|             cv.Optional(CONF_LONGITUDE): sensor.sensor_schema( | ||||
|                 UNIT_DEGREES, ICON_EMPTY, 6, DEVICE_CLASS_EMPTY | ||||
|             ), | ||||
|             cv.Optional(CONF_SPEED): sensor.sensor_schema( | ||||
|                 UNIT_KILOMETER_PER_HOUR, ICON_EMPTY, 6, DEVICE_CLASS_EMPTY | ||||
|             ), | ||||
|             cv.Optional(CONF_COURSE): sensor.sensor_schema( | ||||
|                 UNIT_DEGREES, ICON_EMPTY, 2, DEVICE_CLASS_EMPTY | ||||
|             ), | ||||
|             cv.Optional(CONF_ALTITUDE): sensor.sensor_schema( | ||||
|                 UNIT_METER, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY | ||||
|             ), | ||||
|             cv.Optional(CONF_SATELLITES): sensor.sensor_schema( | ||||
|                 UNIT_EMPTY, ICON_EMPTY, 0, DEVICE_CLASS_EMPTY | ||||
|             ), | ||||
|         } | ||||
|     ) | ||||
|     .extend(cv.COMPONENT_SCHEMA) | ||||
|     .extend(cv.polling_component_schema("20s")) | ||||
|     .extend(uart.UART_DEVICE_SCHEMA) | ||||
| ) | ||||
|  | ||||
| @@ -27,5 +63,29 @@ def to_code(config): | ||||
|     yield cg.register_component(var, config) | ||||
|     yield uart.register_uart_device(var, config) | ||||
|  | ||||
|     if CONF_LATITUDE in config: | ||||
|         sens = yield sensor.new_sensor(config[CONF_LATITUDE]) | ||||
|         cg.add(var.set_latitude_sensor(sens)) | ||||
|  | ||||
|     if CONF_LONGITUDE in config: | ||||
|         sens = yield sensor.new_sensor(config[CONF_LONGITUDE]) | ||||
|         cg.add(var.set_longitude_sensor(sens)) | ||||
|  | ||||
|     if CONF_SPEED in config: | ||||
|         sens = yield sensor.new_sensor(config[CONF_SPEED]) | ||||
|         cg.add(var.set_speed_sensor(sens)) | ||||
|  | ||||
|     if CONF_COURSE in config: | ||||
|         sens = yield sensor.new_sensor(config[CONF_COURSE]) | ||||
|         cg.add(var.set_course_sensor(sens)) | ||||
|  | ||||
|     if CONF_ALTITUDE in config: | ||||
|         sens = yield sensor.new_sensor(config[CONF_ALTITUDE]) | ||||
|         cg.add(var.set_altitude_sensor(sens)) | ||||
|  | ||||
|     if CONF_SATELLITES in config: | ||||
|         sens = yield sensor.new_sensor(config[CONF_SATELLITES]) | ||||
|         cg.add(var.set_satellites_sensor(sens)) | ||||
|  | ||||
|     # https://platformio.org/lib/show/1655/TinyGPSPlus | ||||
|     cg.add_library("1655", "1.0.2")  # TinyGPSPlus, has name conflict | ||||
|   | ||||
| @@ -8,34 +8,57 @@ static const char *TAG = "gps"; | ||||
|  | ||||
| TinyGPSPlus &GPSListener::get_tiny_gps() { return this->parent_->get_tiny_gps(); } | ||||
|  | ||||
| void GPS::update() { | ||||
|   if (this->latitude_sensor_ != nullptr) | ||||
|     this->latitude_sensor_->publish_state(this->latitude_); | ||||
|  | ||||
|   if (this->longitude_sensor_ != nullptr) | ||||
|     this->longitude_sensor_->publish_state(this->longitude_); | ||||
|  | ||||
|   if (this->speed_sensor_ != nullptr) | ||||
|     this->speed_sensor_->publish_state(this->speed_); | ||||
|  | ||||
|   if (this->course_sensor_ != nullptr) | ||||
|     this->course_sensor_->publish_state(this->course_); | ||||
|  | ||||
|   if (this->altitude_sensor_ != nullptr) | ||||
|     this->altitude_sensor_->publish_state(this->altitude_); | ||||
|  | ||||
|   if (this->satellites_sensor_ != nullptr) | ||||
|     this->satellites_sensor_->publish_state(this->satellites_); | ||||
| } | ||||
|  | ||||
| void GPS::loop() { | ||||
|   while (this->available() && !this->has_time_) { | ||||
|     if (this->tiny_gps_.encode(this->read())) { | ||||
|       if (tiny_gps_.location.isUpdated()) { | ||||
|         this->latitude_ = tiny_gps_.location.lat(); | ||||
|         this->longitude_ = tiny_gps_.location.lng(); | ||||
|  | ||||
|         ESP_LOGD(TAG, "Location:"); | ||||
|         ESP_LOGD(TAG, "  Lat: %f", tiny_gps_.location.lat()); | ||||
|         ESP_LOGD(TAG, "  Lon: %f", tiny_gps_.location.lng()); | ||||
|         ESP_LOGD(TAG, "  Lat: %f", this->latitude_); | ||||
|         ESP_LOGD(TAG, "  Lon: %f", this->longitude_); | ||||
|       } | ||||
|  | ||||
|       if (tiny_gps_.speed.isUpdated()) { | ||||
|         this->speed_ = tiny_gps_.speed.kmph(); | ||||
|         ESP_LOGD(TAG, "Speed:"); | ||||
|         ESP_LOGD(TAG, "  %f km/h", tiny_gps_.speed.kmph()); | ||||
|         ESP_LOGD(TAG, "  %f km/h", this->speed_); | ||||
|       } | ||||
|       if (tiny_gps_.course.isUpdated()) { | ||||
|         this->course_ = tiny_gps_.course.deg(); | ||||
|         ESP_LOGD(TAG, "Course:"); | ||||
|         ESP_LOGD(TAG, "  %f °", tiny_gps_.course.deg()); | ||||
|         ESP_LOGD(TAG, "  %f °", this->course_); | ||||
|       } | ||||
|       if (tiny_gps_.altitude.isUpdated()) { | ||||
|         this->altitude_ = tiny_gps_.altitude.meters(); | ||||
|         ESP_LOGD(TAG, "Altitude:"); | ||||
|         ESP_LOGD(TAG, "  %f m", tiny_gps_.altitude.meters()); | ||||
|         ESP_LOGD(TAG, "  %f m", this->altitude_); | ||||
|       } | ||||
|       if (tiny_gps_.satellites.isUpdated()) { | ||||
|         this->satellites_ = tiny_gps_.satellites.value(); | ||||
|         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()); | ||||
|         ESP_LOGD(TAG, "  %d", this->satellites_); | ||||
|       } | ||||
|  | ||||
|       for (auto *listener : this->listeners_) | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| #include "esphome/core/component.h" | ||||
| #include "esphome/components/uart/uart.h" | ||||
| #include "esphome/components/sensor/sensor.h" | ||||
| #include <TinyGPS++.h> | ||||
|  | ||||
| namespace esphome { | ||||
| @@ -20,17 +21,41 @@ class GPSListener { | ||||
|   GPS *parent_; | ||||
| }; | ||||
|  | ||||
| class GPS : public Component, public uart::UARTDevice { | ||||
| class GPS : public PollingComponent, public uart::UARTDevice { | ||||
|  public: | ||||
|   void set_latitude_sensor(sensor::Sensor *latitude_sensor) { latitude_sensor_ = latitude_sensor; } | ||||
|   void set_longitude_sensor(sensor::Sensor *longitude_sensor) { longitude_sensor_ = longitude_sensor; } | ||||
|   void set_speed_sensor(sensor::Sensor *speed_sensor) { speed_sensor_ = speed_sensor; } | ||||
|   void set_course_sensor(sensor::Sensor *course_sensor) { course_sensor_ = course_sensor; } | ||||
|   void set_altitude_sensor(sensor::Sensor *altitude_sensor) { altitude_sensor_ = altitude_sensor; } | ||||
|   void set_satellites_sensor(sensor::Sensor *satellites_sensor) { satellites_sensor_ = satellites_sensor; } | ||||
|  | ||||
|   void register_listener(GPSListener *listener) { | ||||
|     listener->parent_ = this; | ||||
|     this->listeners_.push_back(listener); | ||||
|   } | ||||
|   float get_setup_priority() const override { return setup_priority::HARDWARE; } | ||||
|  | ||||
|   void loop() override; | ||||
|   void update() override; | ||||
|  | ||||
|   TinyGPSPlus &get_tiny_gps() { return this->tiny_gps_; } | ||||
|  | ||||
|  protected: | ||||
|   float latitude_ = -1; | ||||
|   float longitude_ = -1; | ||||
|   float speed_ = -1; | ||||
|   float course_ = -1; | ||||
|   float altitude_ = -1; | ||||
|   int satellites_ = -1; | ||||
|  | ||||
|   sensor::Sensor *latitude_sensor_{nullptr}; | ||||
|   sensor::Sensor *longitude_sensor_{nullptr}; | ||||
|   sensor::Sensor *speed_sensor_{nullptr}; | ||||
|   sensor::Sensor *course_sensor_{nullptr}; | ||||
|   sensor::Sensor *altitude_sensor_{nullptr}; | ||||
|   sensor::Sensor *satellites_sensor_{nullptr}; | ||||
|  | ||||
|   bool has_time_{false}; | ||||
|   TinyGPSPlus tiny_gps_; | ||||
|   std::vector<GPSListener *> listeners_{}; | ||||
|   | ||||
| @@ -4,7 +4,13 @@ import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome import automation | ||||
| from esphome.components import time | ||||
| from esphome.const import CONF_TIME_ID, CONF_ID, CONF_TRIGGER_ID | ||||
| from esphome.const import ( | ||||
|     CONF_TIME_ID, | ||||
|     CONF_ID, | ||||
|     CONF_TRIGGER_ID, | ||||
|     CONF_LATITUDE, | ||||
|     CONF_LONGITUDE, | ||||
| ) | ||||
|  | ||||
| CODEOWNERS = ["@OttoWinter"] | ||||
| sun_ns = cg.esphome_ns.namespace("sun") | ||||
| @@ -16,8 +22,6 @@ SunTrigger = sun_ns.class_( | ||||
| SunCondition = sun_ns.class_("SunCondition", automation.Condition) | ||||
|  | ||||
| CONF_SUN_ID = "sun_id" | ||||
| CONF_LATITUDE = "latitude" | ||||
| CONF_LONGITUDE = "longitude" | ||||
| CONF_ELEVATION = "elevation" | ||||
| CONF_ON_SUNRISE = "on_sunrise" | ||||
| CONF_ON_SUNSET = "on_sunset" | ||||
|   | ||||
| @@ -58,6 +58,7 @@ CONF_ACTION_ID = "action_id" | ||||
| CONF_ADDRESS = "address" | ||||
| CONF_ADDRESSABLE_LIGHT_ID = "addressable_light_id" | ||||
| CONF_ALPHA = "alpha" | ||||
| CONF_ALTITUDE = "altitude" | ||||
| CONF_AND = "and" | ||||
| CONF_AP = "ap" | ||||
| CONF_ARDUINO_VERSION = "arduino_version" | ||||
| @@ -130,6 +131,7 @@ CONF_CONTRAST = "contrast" | ||||
| CONF_COOL_ACTION = "cool_action" | ||||
| CONF_COOL_MODE = "cool_mode" | ||||
| CONF_COUNT_MODE = "count_mode" | ||||
| CONF_COURSE = "course" | ||||
| CONF_CRON = "cron" | ||||
| CONF_CS_PIN = "cs_pin" | ||||
| CONF_CSS_INCLUDE = "css_include" | ||||
| @@ -272,6 +274,7 @@ CONF_KEEP_ON_TIME = "keep_on_time" | ||||
| CONF_KEEPALIVE = "keepalive" | ||||
| CONF_KEY = "key" | ||||
| CONF_LAMBDA = "lambda" | ||||
| CONF_LATITUDE = "latitude" | ||||
| CONF_LENGTH = "length" | ||||
| CONF_LEVEL = "level" | ||||
| CONF_LG = "lg" | ||||
| @@ -284,6 +287,7 @@ CONF_LOCAL = "local" | ||||
| CONF_LOG_TOPIC = "log_topic" | ||||
| CONF_LOGGER = "logger" | ||||
| CONF_LOGS = "logs" | ||||
| CONF_LONGITUDE = "longitude" | ||||
| CONF_LOW = "low" | ||||
| CONF_LOW_VOLTAGE_REFERENCE = "low_voltage_reference" | ||||
| CONF_MAC_ADDRESS = "mac_address" | ||||
| @@ -458,6 +462,7 @@ CONF_RX_ONLY = "rx_only" | ||||
| CONF_RX_PIN = "rx_pin" | ||||
| CONF_SAFE_MODE = "safe_mode" | ||||
| CONF_SAMSUNG = "samsung" | ||||
| CONF_SATELLITES = "satellites" | ||||
| CONF_SCAN = "scan" | ||||
| CONF_SCL = "scl" | ||||
| CONF_SCL_PIN = "scl_pin" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user