From 47fa973b73d939531dd63cbbc8c95e22fa34ff05 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 16 Jan 2026 17:38:36 +0000 Subject: [PATCH 1/3] Initial plan From dbb5b4b70e31960b807dfc015212f46e686a9098 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 16 Jan 2026 18:00:38 +0000 Subject: [PATCH 2/3] Fix RMC precedence flags to reset when data is unavailable Co-authored-by: rustyeddy <2903425+rustyeddy@users.noreply.github.com> --- sensors/gtu7.go | 4 +++ sensors/gtu7_test.go | 73 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/sensors/gtu7.go b/sensors/gtu7.go index 26b63a3..e57ea37 100644 --- a/sensors/gtu7.go +++ b/sensors/gtu7.go @@ -123,10 +123,14 @@ func (g *GTU7) Run(ctx context.Context) error { last.SpeedKnots = fix.SpeedKnots last.SpeedMPS = fix.SpeedMPS haveRMCSpeed = true + } else { + haveRMCSpeed = false } if !math.IsNaN(fix.CourseDeg) { last.CourseDeg = fix.CourseDeg haveRMCCourse = true + } else { + haveRMCCourse = false } if fix.Status != "" { last.Status = fix.Status diff --git a/sensors/gtu7_test.go b/sensors/gtu7_test.go index 8fde078..4b0ff31 100644 --- a/sensors/gtu7_test.go +++ b/sensors/gtu7_test.go @@ -55,3 +55,76 @@ $GPRMC,160446.00,A,3340.34121,N,11800.11332,W,7.25,123.40,160126,,,A*00 require.FailNow(t, "run did not exit") } } + +func TestGTU7_FallbackToVTGWhenRMCStopsProvidingData(t *testing.T) { + // Scenario: RMC initially provides speed/course, then stops (empty fields). + // VTG should be used for speed/course after RMC stops providing it. + input := ` +$GPGGA,160446.00,3340.34121,N,11800.11332,W,2,08,1.20,11.8,M,-33.1,M,,0000*58 +$GPRMC,160446.00,A,3340.34121,N,11800.11332,W,7.25,123.40,160126,,,A*00 +$GPGGA,160447.00,3340.34121,N,11800.11332,W,2,08,1.20,11.8,M,-33.1,M,,0000*58 +$GPRMC,160447.00,A,3340.34121,N,11800.11332,W,,,160126,,,A*00 +$GPVTG,54.70,T,,M,5.50,N,10.19,K,A*00 +` + + gps := NewGTU7(GTU7Config{ + Reader: strings.NewReader(input), + }) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + done := make(chan error, 1) + go func() { done <- gps.Run(ctx) }() + + // First GGA + var fix GPSFix + select { + case fix = <-gps.Out(): + case <-time.After(time.Second): + require.FailNow(t, "timeout on first GGA") + } + + // First RMC with speed/course + select { + case fix = <-gps.Out(): + require.InDelta(t, 7.25, fix.SpeedKnots, 1e-6) + require.InDelta(t, 123.40, fix.CourseDeg, 1e-6) + case <-time.After(time.Second): + require.FailNow(t, "timeout on first RMC") + } + + // Second GGA + select { + case fix = <-gps.Out(): + case <-time.After(time.Second): + require.FailNow(t, "timeout on second GGA") + } + + // Second RMC without speed/course (empty fields) + select { + case fix = <-gps.Out(): + // Speed/course from first RMC should still be in the state + require.InDelta(t, 7.25, fix.SpeedKnots, 1e-6) + case <-time.After(time.Second): + require.FailNow(t, "timeout on second RMC") + } + + // VTG should now update speed/course since RMC stopped providing it + select { + case fix = <-gps.Out(): + cancel() + require.InDelta(t, 5.50, fix.SpeedKnots, 1e-6) + require.InDelta(t, 5.50*0.514444, fix.SpeedMPS, 1e-6) + require.InDelta(t, 54.70, fix.CourseDeg, 1e-6) + case <-time.After(time.Second): + require.FailNow(t, "timeout waiting for VTG to override") + } + + select { + case err := <-done: + require.NoError(t, err) + case <-time.After(time.Second): + require.FailNow(t, "run did not exit") + } +} From e79c3217d154e7f28618cd6edbd17280c28f790e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 16 Jan 2026 18:02:02 +0000 Subject: [PATCH 3/3] Complete: Fixed RMC precedence flag reset issue Co-authored-by: rustyeddy <2903425+rustyeddy@users.noreply.github.com> --- go.mod | 5 +---- go.sum | 6 ------ 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 0adf072..545d374 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,9 @@ module github.com/rustyeddy/devices go 1.24.5 require ( - github.com/maciej/bme280 v0.2.0 - github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 github.com/stretchr/testify v1.11.1 github.com/warthog618/go-gpiocdev v0.9.1 - golang.org/x/image v0.23.0 + golang.org/x/sys v0.29.0 periph.io/x/conn/v3 v3.7.2 periph.io/x/devices/v3 v3.7.4 periph.io/x/host/v3 v3.8.5 @@ -16,6 +14,5 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/sys v0.29.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 9384d76..c1946cb 100644 --- a/go.sum +++ b/go.sum @@ -2,10 +2,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= -github.com/maciej/bme280 v0.2.0 h1:WsoHmIxw15AbhyoY5EWYH6loHNnsCayW1yWVLmukJVQ= -github.com/maciej/bme280 v0.2.0/go.mod h1:uhS+osHzBXnIwpXTCklgoi0q4XiA5Mr5ehJfGIPlfQY= -github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= -github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -16,8 +12,6 @@ github.com/warthog618/go-gpiocdev v0.9.1 h1:pwHPaqjJfhCipIQl78V+O3l9OKHivdRDdmgX github.com/warthog618/go-gpiocdev v0.9.1/go.mod h1:dN3e3t/S2aSNC+hgigGE/dBW8jE1ONk9bDSEYfoPyl8= github.com/warthog618/go-gpiosim v0.1.1 h1:MRAEv+T+itmw+3GeIGpQJBfanUVyg0l3JCTwHtwdre4= github.com/warthog618/go-gpiosim v0.1.1/go.mod h1:YXsnB+I9jdCMY4YAlMSRrlts25ltjmuIsrnoUrBLdqU= -golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68= -golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=