[gps] update lib, improve code/tests/config (#8768)

This commit is contained in:
Thomas Rupprecht 2025-05-15 12:07:41 +02:00 committed by Jesse Hills
parent 5a84bab9ec
commit c50e33f531
No known key found for this signature in database
GPG Key ID: BEAAE804EFD8E83A
6 changed files with 102 additions and 50 deletions

View File

@ -169,7 +169,7 @@ esphome/components/gp2y1010au0f/* @zry98
esphome/components/gp8403/* @jesserockz esphome/components/gp8403/* @jesserockz
esphome/components/gpio/* @esphome/core esphome/components/gpio/* @esphome/core
esphome/components/gpio/one_wire/* @ssieb esphome/components/gpio/one_wire/* @ssieb
esphome/components/gps/* @coogle esphome/components/gps/* @coogle @ximex
esphome/components/graph/* @synco esphome/components/graph/* @synco
esphome/components/graphical_display_menu/* @MrMDavidson esphome/components/graphical_display_menu/* @MrMDavidson
esphome/components/gree/* @orestismers esphome/components/gree/* @orestismers

View File

@ -9,23 +9,32 @@ from esphome.const import (
CONF_LONGITUDE, CONF_LONGITUDE,
CONF_SATELLITES, CONF_SATELLITES,
CONF_SPEED, CONF_SPEED,
DEVICE_CLASS_SPEED,
STATE_CLASS_MEASUREMENT, STATE_CLASS_MEASUREMENT,
UNIT_DEGREES, UNIT_DEGREES,
UNIT_KILOMETER_PER_HOUR, UNIT_KILOMETER_PER_HOUR,
UNIT_METER, 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"] DEPENDENCIES = ["uart"]
AUTO_LOAD = ["sensor"] AUTO_LOAD = ["sensor"]
CODEOWNERS = ["@coogle"] CODEOWNERS = ["@coogle", "@ximex"]
gps_ns = cg.esphome_ns.namespace("gps") gps_ns = cg.esphome_ns.namespace("gps")
GPS = gps_ns.class_("GPS", cg.Component, uart.UARTDevice) GPS = gps_ns.class_("GPS", cg.Component, uart.UARTDevice)
GPSListener = gps_ns.class_("GPSListener") GPSListener = gps_ns.class_("GPSListener")
CONF_GPS_ID = "gps_id"
CONF_HDOP = "hdop"
MULTI_CONF = True MULTI_CONF = True
CONFIG_SCHEMA = cv.All( CONFIG_SCHEMA = cv.All(
cv.Schema( cv.Schema(
@ -33,25 +42,37 @@ CONFIG_SCHEMA = cv.All(
cv.GenerateID(): cv.declare_id(GPS), cv.GenerateID(): cv.declare_id(GPS),
cv.Optional(CONF_LATITUDE): sensor.sensor_schema( cv.Optional(CONF_LATITUDE): sensor.sensor_schema(
unit_of_measurement=UNIT_DEGREES, unit_of_measurement=UNIT_DEGREES,
icon=ICON_LATITUDE,
accuracy_decimals=6, accuracy_decimals=6,
state_class=STATE_CLASS_MEASUREMENT,
), ),
cv.Optional(CONF_LONGITUDE): sensor.sensor_schema( cv.Optional(CONF_LONGITUDE): sensor.sensor_schema(
unit_of_measurement=UNIT_DEGREES, unit_of_measurement=UNIT_DEGREES,
icon=ICON_LONGITUDE,
accuracy_decimals=6, accuracy_decimals=6,
state_class=STATE_CLASS_MEASUREMENT,
), ),
cv.Optional(CONF_SPEED): sensor.sensor_schema( cv.Optional(CONF_SPEED): sensor.sensor_schema(
unit_of_measurement=UNIT_KILOMETER_PER_HOUR, unit_of_measurement=UNIT_KILOMETER_PER_HOUR,
icon=ICON_SPEEDOMETER,
accuracy_decimals=3, accuracy_decimals=3,
device_class=DEVICE_CLASS_SPEED,
state_class=STATE_CLASS_MEASUREMENT,
), ),
cv.Optional(CONF_COURSE): sensor.sensor_schema( cv.Optional(CONF_COURSE): sensor.sensor_schema(
unit_of_measurement=UNIT_DEGREES, unit_of_measurement=UNIT_DEGREES,
icon=ICON_COMPASS,
accuracy_decimals=2, accuracy_decimals=2,
state_class=STATE_CLASS_MEASUREMENT,
), ),
cv.Optional(CONF_ALTITUDE): sensor.sensor_schema( cv.Optional(CONF_ALTITUDE): sensor.sensor_schema(
unit_of_measurement=UNIT_METER, unit_of_measurement=UNIT_METER,
icon=ICON_ALTIMETER,
accuracy_decimals=2, accuracy_decimals=2,
state_class=STATE_CLASS_MEASUREMENT,
), ),
cv.Optional(CONF_SATELLITES): sensor.sensor_schema( cv.Optional(CONF_SATELLITES): sensor.sensor_schema(
icon=ICON_SATELLITE,
accuracy_decimals=0, accuracy_decimals=0,
state_class=STATE_CLASS_MEASUREMENT, state_class=STATE_CLASS_MEASUREMENT,
), ),
@ -73,28 +94,28 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await uart.register_uart_device(var, config) await uart.register_uart_device(var, config)
if CONF_LATITUDE in config: if latitude_config := config.get(CONF_LATITUDE):
sens = await sensor.new_sensor(config[CONF_LATITUDE]) sens = await sensor.new_sensor(latitude_config)
cg.add(var.set_latitude_sensor(sens)) cg.add(var.set_latitude_sensor(sens))
if CONF_LONGITUDE in config: if longitude_config := config.get(CONF_LONGITUDE):
sens = await sensor.new_sensor(config[CONF_LONGITUDE]) sens = await sensor.new_sensor(longitude_config)
cg.add(var.set_longitude_sensor(sens)) cg.add(var.set_longitude_sensor(sens))
if CONF_SPEED in config: if speed_config := config.get(CONF_SPEED):
sens = await sensor.new_sensor(config[CONF_SPEED]) sens = await sensor.new_sensor(speed_config)
cg.add(var.set_speed_sensor(sens)) cg.add(var.set_speed_sensor(sens))
if CONF_COURSE in config: if course_config := config.get(CONF_COURSE):
sens = await sensor.new_sensor(config[CONF_COURSE]) sens = await sensor.new_sensor(course_config)
cg.add(var.set_course_sensor(sens)) cg.add(var.set_course_sensor(sens))
if CONF_ALTITUDE in config: if altitude_config := config.get(CONF_ALTITUDE):
sens = await sensor.new_sensor(config[CONF_ALTITUDE]) sens = await sensor.new_sensor(altitude_config)
cg.add(var.set_altitude_sensor(sens)) cg.add(var.set_altitude_sensor(sens))
if CONF_SATELLITES in config: if satellites_config := config.get(CONF_SATELLITES):
sens = await sensor.new_sensor(config[CONF_SATELLITES]) sens = await sensor.new_sensor(satellites_config)
cg.add(var.set_satellites_sensor(sens)) cg.add(var.set_satellites_sensor(sens))
if hdop_config := config.get(CONF_HDOP): if hdop_config := config.get(CONF_HDOP):
@ -102,4 +123,4 @@ async def to_code(config):
cg.add(var.set_hdop_sensor(sens)) cg.add(var.set_hdop_sensor(sens))
# https://platformio.org/lib/show/1655/TinyGPSPlus # https://platformio.org/lib/show/1655/TinyGPSPlus
cg.add_library("mikalhart/TinyGPSPlus", "1.0.2") cg.add_library("mikalhart/TinyGPSPlus", "1.1.0")

View File

@ -10,6 +10,17 @@ static const char *const 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::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() { void GPS::update() {
if (this->latitude_sensor_ != nullptr) if (this->latitude_sensor_ != nullptr)
this->latitude_sensor_->publish_state(this->latitude_); this->latitude_sensor_->publish_state(this->latitude_);
@ -34,43 +45,48 @@ void GPS::update() {
} }
void GPS::loop() { void GPS::loop() {
while (this->available() && !this->has_time_) { while (this->available() > 0 && !this->has_time_) {
if (this->tiny_gps_.encode(this->read())) { if (this->tiny_gps_.encode(this->read())) {
if (tiny_gps_.location.isUpdated()) { if (this->tiny_gps_.location.isUpdated()) {
this->latitude_ = tiny_gps_.location.lat(); this->latitude_ = this->tiny_gps_.location.lat();
this->longitude_ = tiny_gps_.location.lng(); this->longitude_ = this->tiny_gps_.location.lng();
ESP_LOGD(TAG, "Location:"); ESP_LOGD(TAG, "Location:");
ESP_LOGD(TAG, " Lat: %f", this->latitude_); ESP_LOGD(TAG, " Lat: %.6f °", this->latitude_);
ESP_LOGD(TAG, " Lon: %f", this->longitude_); ESP_LOGD(TAG, " Lon: %.6f °", this->longitude_);
} }
if (tiny_gps_.speed.isUpdated()) { if (this->tiny_gps_.speed.isUpdated()) {
this->speed_ = tiny_gps_.speed.kmph(); this->speed_ = this->tiny_gps_.speed.kmph();
ESP_LOGD(TAG, "Speed: %.3f km/h", this->speed_); 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_); 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_); 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_); 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_); ESP_LOGD(TAG, "HDOP: %.3f", this->hdop_);
} }
for (auto *listener : this->listeners_) for (auto *listener : this->listeners_) {
listener->on_update(this->tiny_gps_); listener->on_update(this->tiny_gps_);
} }
} }
} }
}
} // namespace gps } // namespace gps
} // namespace esphome } // namespace esphome

View File

@ -5,7 +5,7 @@
#include "esphome/core/component.h" #include "esphome/core/component.h"
#include "esphome/components/uart/uart.h" #include "esphome/components/uart/uart.h"
#include "esphome/components/sensor/sensor.h" #include "esphome/components/sensor/sensor.h"
#include <TinyGPS++.h> #include <TinyGPSPlus.h>
#include <vector> #include <vector>
@ -27,13 +27,13 @@ class GPSListener {
class GPS : public PollingComponent, public uart::UARTDevice { class GPS : public PollingComponent, public uart::UARTDevice {
public: public:
void set_latitude_sensor(sensor::Sensor *latitude_sensor) { latitude_sensor_ = latitude_sensor; } void set_latitude_sensor(sensor::Sensor *latitude_sensor) { this->latitude_sensor_ = latitude_sensor; }
void set_longitude_sensor(sensor::Sensor *longitude_sensor) { longitude_sensor_ = longitude_sensor; } void set_longitude_sensor(sensor::Sensor *longitude_sensor) { this->longitude_sensor_ = longitude_sensor; }
void set_speed_sensor(sensor::Sensor *speed_sensor) { speed_sensor_ = speed_sensor; } void set_speed_sensor(sensor::Sensor *speed_sensor) { this->speed_sensor_ = speed_sensor; }
void set_course_sensor(sensor::Sensor *course_sensor) { course_sensor_ = course_sensor; } void set_course_sensor(sensor::Sensor *course_sensor) { this->course_sensor_ = course_sensor; }
void set_altitude_sensor(sensor::Sensor *altitude_sensor) { altitude_sensor_ = altitude_sensor; } void set_altitude_sensor(sensor::Sensor *altitude_sensor) { this->altitude_sensor_ = altitude_sensor; }
void set_satellites_sensor(sensor::Sensor *satellites_sensor) { satellites_sensor_ = satellites_sensor; } void set_satellites_sensor(sensor::Sensor *satellites_sensor) { this->satellites_sensor_ = satellites_sensor; }
void set_hdop_sensor(sensor::Sensor *hdop_sensor) { hdop_sensor_ = hdop_sensor; } void set_hdop_sensor(sensor::Sensor *hdop_sensor) { this->hdop_sensor_ = hdop_sensor; }
void register_listener(GPSListener *listener) { void register_listener(GPSListener *listener) {
listener->parent_ = this; listener->parent_ = this;
@ -41,19 +41,20 @@ class GPS : public PollingComponent, public uart::UARTDevice {
} }
float get_setup_priority() const override { return setup_priority::HARDWARE; } float get_setup_priority() const override { return setup_priority::HARDWARE; }
void dump_config() override;
void loop() override; void loop() override;
void update() override; void update() override;
TinyGPSPlus &get_tiny_gps() { return this->tiny_gps_; } TinyGPSPlus &get_tiny_gps() { return this->tiny_gps_; }
protected: protected:
float latitude_ = NAN; float latitude_{NAN};
float longitude_ = NAN; float longitude_{NAN};
float speed_ = NAN; float speed_{NAN};
float course_ = NAN; float course_{NAN};
float altitude_ = NAN; float altitude_{NAN};
int satellites_ = 0; uint16_t satellites_{0};
double hdop_ = NAN; float hdop_{NAN};
sensor::Sensor *latitude_sensor_{nullptr}; sensor::Sensor *latitude_sensor_{nullptr};
sensor::Sensor *longitude_sensor_{nullptr}; sensor::Sensor *longitude_sensor_{nullptr};

View File

@ -64,7 +64,7 @@ lib_deps =
heman/AsyncMqttClient-esphome@1.0.0 ; mqtt heman/AsyncMqttClient-esphome@1.0.0 ; mqtt
esphome/ESPAsyncWebServer-esphome@3.3.0 ; web_server_base esphome/ESPAsyncWebServer-esphome@3.3.0 ; web_server_base
fastled/FastLED@3.9.16 ; fastled_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 freekode/TM1651@1.0.1 ; tm1651
glmnet/Dsmr@0.7 ; dsmr glmnet/Dsmr@0.7 ; dsmr
rweather/Crypto@0.4.0 ; dsmr rweather/Crypto@0.4.0 ; dsmr

View File

@ -6,6 +6,20 @@ uart:
parity: EVEN parity: EVEN
gps: gps:
latitude:
name: "Latitude"
longitude:
name: "Longitude"
altitude:
name: "Altitude"
speed:
name: "Speed"
course:
name: "Course"
satellites:
name: "Satellites"
hdop:
name: "HDOP"
time: time:
- platform: gps - platform: gps