mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	[gps] update lib, improve code/tests/config (#8768)
This commit is contained in:
		
				
					committed by
					
						 Jesse Hills
						Jesse Hills
					
				
			
			
				
	
			
			
			
						parent
						
							5a84bab9ec
						
					
				
				
					commit
					c50e33f531
				
			| @@ -169,7 +169,7 @@ esphome/components/gp2y1010au0f/* @zry98 | ||||
| esphome/components/gp8403/* @jesserockz | ||||
| esphome/components/gpio/* @esphome/core | ||||
| esphome/components/gpio/one_wire/* @ssieb | ||||
| esphome/components/gps/* @coogle | ||||
| esphome/components/gps/* @coogle @ximex | ||||
| esphome/components/graph/* @synco | ||||
| esphome/components/graphical_display_menu/* @MrMDavidson | ||||
| esphome/components/gree/* @orestismers | ||||
|   | ||||
| @@ -9,23 +9,32 @@ from esphome.const import ( | ||||
|     CONF_LONGITUDE, | ||||
|     CONF_SATELLITES, | ||||
|     CONF_SPEED, | ||||
|     DEVICE_CLASS_SPEED, | ||||
|     STATE_CLASS_MEASUREMENT, | ||||
|     UNIT_DEGREES, | ||||
|     UNIT_KILOMETER_PER_HOUR, | ||||
|     UNIT_METER, | ||||
| ) | ||||
|  | ||||
| CONF_GPS_ID = "gps_id" | ||||
| CONF_HDOP = "hdop" | ||||
|  | ||||
| ICON_ALTIMETER = "mdi:altimeter" | ||||
| ICON_COMPASS = "mdi:compass" | ||||
| ICON_LATITUDE = "mdi:latitude" | ||||
| ICON_LONGITUDE = "mdi:longitude" | ||||
| ICON_SATELLITE = "mdi:satellite-variant" | ||||
| ICON_SPEEDOMETER = "mdi:speedometer" | ||||
|  | ||||
| DEPENDENCIES = ["uart"] | ||||
| AUTO_LOAD = ["sensor"] | ||||
|  | ||||
| CODEOWNERS = ["@coogle"] | ||||
| CODEOWNERS = ["@coogle", "@ximex"] | ||||
|  | ||||
| gps_ns = cg.esphome_ns.namespace("gps") | ||||
| GPS = gps_ns.class_("GPS", cg.Component, uart.UARTDevice) | ||||
| GPSListener = gps_ns.class_("GPSListener") | ||||
|  | ||||
| CONF_GPS_ID = "gps_id" | ||||
| CONF_HDOP = "hdop" | ||||
| MULTI_CONF = True | ||||
| CONFIG_SCHEMA = cv.All( | ||||
|     cv.Schema( | ||||
| @@ -33,25 +42,37 @@ CONFIG_SCHEMA = cv.All( | ||||
|             cv.GenerateID(): cv.declare_id(GPS), | ||||
|             cv.Optional(CONF_LATITUDE): sensor.sensor_schema( | ||||
|                 unit_of_measurement=UNIT_DEGREES, | ||||
|                 icon=ICON_LATITUDE, | ||||
|                 accuracy_decimals=6, | ||||
|                 state_class=STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|             cv.Optional(CONF_LONGITUDE): sensor.sensor_schema( | ||||
|                 unit_of_measurement=UNIT_DEGREES, | ||||
|                 icon=ICON_LONGITUDE, | ||||
|                 accuracy_decimals=6, | ||||
|                 state_class=STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|             cv.Optional(CONF_SPEED): sensor.sensor_schema( | ||||
|                 unit_of_measurement=UNIT_KILOMETER_PER_HOUR, | ||||
|                 icon=ICON_SPEEDOMETER, | ||||
|                 accuracy_decimals=3, | ||||
|                 device_class=DEVICE_CLASS_SPEED, | ||||
|                 state_class=STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|             cv.Optional(CONF_COURSE): sensor.sensor_schema( | ||||
|                 unit_of_measurement=UNIT_DEGREES, | ||||
|                 icon=ICON_COMPASS, | ||||
|                 accuracy_decimals=2, | ||||
|                 state_class=STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|             cv.Optional(CONF_ALTITUDE): sensor.sensor_schema( | ||||
|                 unit_of_measurement=UNIT_METER, | ||||
|                 icon=ICON_ALTIMETER, | ||||
|                 accuracy_decimals=2, | ||||
|                 state_class=STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|             cv.Optional(CONF_SATELLITES): sensor.sensor_schema( | ||||
|                 icon=ICON_SATELLITE, | ||||
|                 accuracy_decimals=0, | ||||
|                 state_class=STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
| @@ -73,28 +94,28 @@ async def to_code(config): | ||||
|     await cg.register_component(var, config) | ||||
|     await uart.register_uart_device(var, config) | ||||
|  | ||||
|     if CONF_LATITUDE in config: | ||||
|         sens = await sensor.new_sensor(config[CONF_LATITUDE]) | ||||
|     if latitude_config := config.get(CONF_LATITUDE): | ||||
|         sens = await sensor.new_sensor(latitude_config) | ||||
|         cg.add(var.set_latitude_sensor(sens)) | ||||
|  | ||||
|     if CONF_LONGITUDE in config: | ||||
|         sens = await sensor.new_sensor(config[CONF_LONGITUDE]) | ||||
|     if longitude_config := config.get(CONF_LONGITUDE): | ||||
|         sens = await sensor.new_sensor(longitude_config) | ||||
|         cg.add(var.set_longitude_sensor(sens)) | ||||
|  | ||||
|     if CONF_SPEED in config: | ||||
|         sens = await sensor.new_sensor(config[CONF_SPEED]) | ||||
|     if speed_config := config.get(CONF_SPEED): | ||||
|         sens = await sensor.new_sensor(speed_config) | ||||
|         cg.add(var.set_speed_sensor(sens)) | ||||
|  | ||||
|     if CONF_COURSE in config: | ||||
|         sens = await sensor.new_sensor(config[CONF_COURSE]) | ||||
|     if course_config := config.get(CONF_COURSE): | ||||
|         sens = await sensor.new_sensor(course_config) | ||||
|         cg.add(var.set_course_sensor(sens)) | ||||
|  | ||||
|     if CONF_ALTITUDE in config: | ||||
|         sens = await sensor.new_sensor(config[CONF_ALTITUDE]) | ||||
|     if altitude_config := config.get(CONF_ALTITUDE): | ||||
|         sens = await sensor.new_sensor(altitude_config) | ||||
|         cg.add(var.set_altitude_sensor(sens)) | ||||
|  | ||||
|     if CONF_SATELLITES in config: | ||||
|         sens = await sensor.new_sensor(config[CONF_SATELLITES]) | ||||
|     if satellites_config := config.get(CONF_SATELLITES): | ||||
|         sens = await sensor.new_sensor(satellites_config) | ||||
|         cg.add(var.set_satellites_sensor(sens)) | ||||
|  | ||||
|     if hdop_config := config.get(CONF_HDOP): | ||||
| @@ -102,4 +123,4 @@ async def to_code(config): | ||||
|         cg.add(var.set_hdop_sensor(sens)) | ||||
|  | ||||
|     # https://platformio.org/lib/show/1655/TinyGPSPlus | ||||
|     cg.add_library("mikalhart/TinyGPSPlus", "1.0.2") | ||||
|     cg.add_library("mikalhart/TinyGPSPlus", "1.1.0") | ||||
|   | ||||
| @@ -10,6 +10,17 @@ static const char *const TAG = "gps"; | ||||
|  | ||||
| TinyGPSPlus &GPSListener::get_tiny_gps() { return this->parent_->get_tiny_gps(); } | ||||
|  | ||||
| void GPS::dump_config() { | ||||
|   ESP_LOGCONFIG(TAG, "GPS:"); | ||||
|   LOG_SENSOR("  ", "Latitude", this->latitude_sensor_); | ||||
|   LOG_SENSOR("  ", "Longitude", this->longitude_sensor_); | ||||
|   LOG_SENSOR("  ", "Speed", this->speed_sensor_); | ||||
|   LOG_SENSOR("  ", "Course", this->course_sensor_); | ||||
|   LOG_SENSOR("  ", "Altitude", this->altitude_sensor_); | ||||
|   LOG_SENSOR("  ", "Satellites", this->satellites_sensor_); | ||||
|   LOG_SENSOR("  ", "HDOP", this->hdop_sensor_); | ||||
| } | ||||
|  | ||||
| void GPS::update() { | ||||
|   if (this->latitude_sensor_ != nullptr) | ||||
|     this->latitude_sensor_->publish_state(this->latitude_); | ||||
| @@ -34,42 +45,47 @@ void GPS::update() { | ||||
| } | ||||
|  | ||||
| void GPS::loop() { | ||||
|   while (this->available() && !this->has_time_) { | ||||
|   while (this->available() > 0 && !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(); | ||||
|       if (this->tiny_gps_.location.isUpdated()) { | ||||
|         this->latitude_ = this->tiny_gps_.location.lat(); | ||||
|         this->longitude_ = this->tiny_gps_.location.lng(); | ||||
|  | ||||
|         ESP_LOGD(TAG, "Location:"); | ||||
|         ESP_LOGD(TAG, "  Lat: %f", this->latitude_); | ||||
|         ESP_LOGD(TAG, "  Lon: %f", this->longitude_); | ||||
|         ESP_LOGD(TAG, "  Lat: %.6f °", this->latitude_); | ||||
|         ESP_LOGD(TAG, "  Lon: %.6f °", this->longitude_); | ||||
|       } | ||||
|  | ||||
|       if (tiny_gps_.speed.isUpdated()) { | ||||
|         this->speed_ = tiny_gps_.speed.kmph(); | ||||
|       if (this->tiny_gps_.speed.isUpdated()) { | ||||
|         this->speed_ = this->tiny_gps_.speed.kmph(); | ||||
|         ESP_LOGD(TAG, "Speed: %.3f km/h", this->speed_); | ||||
|       } | ||||
|       if (tiny_gps_.course.isUpdated()) { | ||||
|         this->course_ = tiny_gps_.course.deg(); | ||||
|  | ||||
|       if (this->tiny_gps_.course.isUpdated()) { | ||||
|         this->course_ = this->tiny_gps_.course.deg(); | ||||
|         ESP_LOGD(TAG, "Course: %.2f °", this->course_); | ||||
|       } | ||||
|       if (tiny_gps_.altitude.isUpdated()) { | ||||
|         this->altitude_ = tiny_gps_.altitude.meters(); | ||||
|  | ||||
|       if (this->tiny_gps_.altitude.isUpdated()) { | ||||
|         this->altitude_ = this->tiny_gps_.altitude.meters(); | ||||
|         ESP_LOGD(TAG, "Altitude: %.2f m", this->altitude_); | ||||
|       } | ||||
|       if (tiny_gps_.satellites.isUpdated()) { | ||||
|         this->satellites_ = tiny_gps_.satellites.value(); | ||||
|  | ||||
|       if (this->tiny_gps_.satellites.isUpdated()) { | ||||
|         this->satellites_ = this->tiny_gps_.satellites.value(); | ||||
|         ESP_LOGD(TAG, "Satellites: %d", this->satellites_); | ||||
|       } | ||||
|       if (tiny_gps_.hdop.isUpdated()) { | ||||
|         this->hdop_ = tiny_gps_.hdop.hdop(); | ||||
|  | ||||
|       if (this->tiny_gps_.hdop.isUpdated()) { | ||||
|         this->hdop_ = this->tiny_gps_.hdop.hdop(); | ||||
|         ESP_LOGD(TAG, "HDOP: %.3f", this->hdop_); | ||||
|       } | ||||
|  | ||||
|       for (auto *listener : this->listeners_) | ||||
|       for (auto *listener : this->listeners_) { | ||||
|         listener->on_update(this->tiny_gps_); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| }  // namespace gps | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| #include "esphome/core/component.h" | ||||
| #include "esphome/components/uart/uart.h" | ||||
| #include "esphome/components/sensor/sensor.h" | ||||
| #include <TinyGPS++.h> | ||||
| #include <TinyGPSPlus.h> | ||||
|  | ||||
| #include <vector> | ||||
|  | ||||
| @@ -27,13 +27,13 @@ class GPSListener { | ||||
|  | ||||
| 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 set_hdop_sensor(sensor::Sensor *hdop_sensor) { hdop_sensor_ = hdop_sensor; } | ||||
|   void set_latitude_sensor(sensor::Sensor *latitude_sensor) { this->latitude_sensor_ = latitude_sensor; } | ||||
|   void set_longitude_sensor(sensor::Sensor *longitude_sensor) { this->longitude_sensor_ = longitude_sensor; } | ||||
|   void set_speed_sensor(sensor::Sensor *speed_sensor) { this->speed_sensor_ = speed_sensor; } | ||||
|   void set_course_sensor(sensor::Sensor *course_sensor) { this->course_sensor_ = course_sensor; } | ||||
|   void set_altitude_sensor(sensor::Sensor *altitude_sensor) { this->altitude_sensor_ = altitude_sensor; } | ||||
|   void set_satellites_sensor(sensor::Sensor *satellites_sensor) { this->satellites_sensor_ = satellites_sensor; } | ||||
|   void set_hdop_sensor(sensor::Sensor *hdop_sensor) { this->hdop_sensor_ = hdop_sensor; } | ||||
|  | ||||
|   void register_listener(GPSListener *listener) { | ||||
|     listener->parent_ = this; | ||||
| @@ -41,19 +41,20 @@ class GPS : public PollingComponent, public uart::UARTDevice { | ||||
|   } | ||||
|   float get_setup_priority() const override { return setup_priority::HARDWARE; } | ||||
|  | ||||
|   void dump_config() override; | ||||
|   void loop() override; | ||||
|   void update() override; | ||||
|  | ||||
|   TinyGPSPlus &get_tiny_gps() { return this->tiny_gps_; } | ||||
|  | ||||
|  protected: | ||||
|   float latitude_ = NAN; | ||||
|   float longitude_ = NAN; | ||||
|   float speed_ = NAN; | ||||
|   float course_ = NAN; | ||||
|   float altitude_ = NAN; | ||||
|   int satellites_ = 0; | ||||
|   double hdop_ = NAN; | ||||
|   float latitude_{NAN}; | ||||
|   float longitude_{NAN}; | ||||
|   float speed_{NAN}; | ||||
|   float course_{NAN}; | ||||
|   float altitude_{NAN}; | ||||
|   uint16_t satellites_{0}; | ||||
|   float hdop_{NAN}; | ||||
|  | ||||
|   sensor::Sensor *latitude_sensor_{nullptr}; | ||||
|   sensor::Sensor *longitude_sensor_{nullptr}; | ||||
|   | ||||
| @@ -64,7 +64,7 @@ lib_deps = | ||||
|     heman/AsyncMqttClient-esphome@1.0.0                   ; mqtt | ||||
|     esphome/ESPAsyncWebServer-esphome@3.3.0               ; web_server_base | ||||
|     fastled/FastLED@3.9.16                                ; fastled_base | ||||
|     mikalhart/TinyGPSPlus@1.0.2                           ; gps | ||||
|     mikalhart/TinyGPSPlus@1.1.0                           ; gps | ||||
|     freekode/TM1651@1.0.1                                 ; tm1651 | ||||
|     glmnet/Dsmr@0.7                                       ; dsmr | ||||
|     rweather/Crypto@0.4.0                                 ; dsmr | ||||
|   | ||||
| @@ -6,6 +6,20 @@ uart: | ||||
|     parity: EVEN | ||||
|  | ||||
| gps: | ||||
|   latitude: | ||||
|     name: "Latitude" | ||||
|   longitude: | ||||
|     name: "Longitude" | ||||
|   altitude: | ||||
|     name: "Altitude" | ||||
|   speed: | ||||
|     name: "Speed" | ||||
|   course: | ||||
|     name: "Course" | ||||
|   satellites: | ||||
|     name: "Satellites" | ||||
|   hdop: | ||||
|     name: "HDOP" | ||||
|  | ||||
| time: | ||||
|   - platform: gps | ||||
|   | ||||
		Reference in New Issue
	
	Block a user