1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
package cli
import (
"context"
"fmt"
"log"
"os"
"strconv"
"strings"
"time"
"github.com/la5nta/pat/app"
"github.com/la5nta/pat/internal/gpsd"
"github.com/la5nta/wl2k-go/catalog"
"github.com/spf13/pflag"
)
var ExamplePosition = `
position -c "QRV 145.500MHz" Send position and comment with coordinates retrieved from GPSd.
position --latlon 59.123,005.123 Send position 59.123N 005.123E.
position --latlon 40.704,-73.945 Send position 40.704N 073.945W.
position --latlon -10.123,-60.123 Send position 10.123S 060.123W.
`
func PositionHandle(ctx context.Context, app *app.App, args []string) {
var latlon, comment string
set := pflag.NewFlagSet("position", pflag.ExitOnError)
set.StringVar(&latlon, "latlon", "", "")
set.StringVarP(&comment, "comment", "c", "", "")
set.Parse(args)
report := catalog.PosReport{Comment: comment}
if latlon != "" {
parts := strings.Split(latlon, ",")
if len(parts) != 2 {
log.Fatal(`Invalid position format. Expected "latitude,longitude".`)
}
lat, err := strconv.ParseFloat(parts[0], 64)
if err != nil {
log.Fatal(err)
}
report.Lat = &lat
lon, err := strconv.ParseFloat(parts[1], 64)
if err != nil {
log.Fatal(err)
}
report.Lon = &lon
} else if app.Config().GPSd.Addr != "" {
conn, err := gpsd.Dial(app.Config().GPSd.Addr)
if err != nil {
log.Fatalf("GPSd daemon: %s", err)
}
defer conn.Close()
conn.Watch(true)
posChan := make(chan gpsd.Position)
go func() {
defer close(posChan)
pos, err := conn.NextPos()
if err != nil {
log.Printf("GPSd: %s", err)
return
}
posChan <- pos
}()
log.Println("Waiting for position from GPSd...") // TODO: Spinning bar?
var pos gpsd.Position
select {
case p := <-posChan:
pos = p
case <-ctx.Done():
log.Println("Cancelled")
return
}
report.Lat = &pos.Lat
report.Lon = &pos.Lon
if app.Config().GPSd.UseServerTime {
report.Date = time.Now()
} else {
report.Date = pos.Time
}
// Course and speed is part of the spec, but does not seem to be
// supported by winlink.org anymore. Ignore it for now.
if false && pos.Track != 0 {
course := CourseFromFloat64(pos.Track, false)
report.Course = &course
}
} else {
fmt.Println("No position available. See --help")
os.Exit(1)
}
if report.Date.IsZero() {
report.Date = time.Now()
}
postMessage(app, report.Message(app.Options().MyCall))
}
func CourseFromFloat64(f float64, magnetic bool) catalog.Course {
c := catalog.Course{Magnetic: magnetic}
str := fmt.Sprintf("%03.0f", f)
for i := 0; i < 3; i++ {
c.Digits[i] = str[i]
}
return c
}
|