package main import ( "context" "encoding/json" "flag" "fmt" "log/slog" "os" reach "forge.cadoles.com/cadoles/go-emlid/reach/client" "forge.cadoles.com/cadoles/go-emlid/reach/client/logger" "forge.cadoles.com/cadoles/go-emlid/reach/client/protocol" "forge.cadoles.com/cadoles/go-emlid/reach/client/protocol/v2/model" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" ) var ( host string = "192.168.42.1" rawLogLevel string = "ERROR" ) func init() { flag.StringVar(&rawLogLevel, "log-level", rawLogLevel, "log level") flag.StringVar(&host, "host", host, "the reachrs module host") } type Coordinates struct { Latitude float64 `json:"latitude"` Longitude float64 `json:"longitude"` Height float64 `json:"height"` } type Payload struct { Coordinates Coordinates `json:"coordinates"` AntennaOffset float64 `json:"antenna_offset"` } func main() { flag.Parse() ctx := context.Background() client := reach.NewClient(host) logLevel, err := logger.ParseLevel(rawLogLevel) if err != nil { fmt.Printf("[FATAL] %+v", errors.WithStack(err)) os.Exit(1) } slog.SetLogLoggerLevel(logLevel) if err := client.Connect(ctx); err != nil { fmt.Printf("[FATAL] %+v", errors.WithStack(err)) os.Exit(1) } defer func() { if err := client.Close(ctx); err != nil { fmt.Printf("[FATAL] %+v", errors.WithStack(err)) os.Exit(1) } }() // récupération de la configurationa actuelle de la base config, err := retrieveAndProcessConfig(ctx, client) if err != nil { fmt.Printf("[FATAL] %+v", errors.WithStack(err)) os.Exit(1) } latitude := config.BaseMode.BaseCoordinates.Coordinates.Latitude longitude := config.BaseMode.BaseCoordinates.Coordinates.Longitude height := config.BaseMode.BaseCoordinates.Coordinates.Height antennaOffset := config.BaseMode.BaseCoordinates.AntennaOffset fmt.Printf("setting base (latitude: %v, longitude: %v, height: %v, antennaOffset: %v", latitude, longitude, height, antennaOffset) opts := []protocol.SetBaseOptionFunc{ protocol.WithBaseLatitude(latitude), protocol.WithBaseLongitude(longitude), protocol.WithBaseHeight(height), protocol.WithBaseAntennaOffset(antennaOffset), protocol.WithBaseMode("single-and-hold"), } // Passage de la base en "single-and-hold" permettant la collecte des données if err := client.SetBase(ctx, opts...); err != nil { fmt.Printf("[FATAL] %+v", errors.WithStack(err)) return } client.AveragePosition(ctx) broadcasts, err := reach.OnMessageType(ctx, client, "task_status") if err != nil { fmt.Printf("[FATAL] %+v", errors.WithStack(err)) os.Exit(1) } for b := range broadcasts { data, err := json.MarshalIndent(b, "", " ") if err != nil { fmt.Printf("[ERROR] %+v", errors.WithStack(err)) continue } fmt.Println(string(data)) var payload Payload err = mapstructure.Decode(b.Payload, &payload) if err != nil { fmt.Printf("Erreur de désérialisation : %v\n", err) continue } // la collecte est terminée, enregistrement du résultat en configuration if b.State == "completed" { fmt.Printf("lat: %g, long: %g, altitude:%g", payload.Coordinates.Latitude, payload.Coordinates.Longitude, payload.Coordinates.Height) opts := []protocol.SetBaseOptionFunc{ protocol.WithBaseLatitude(payload.Coordinates.Latitude), protocol.WithBaseLongitude(payload.Coordinates.Longitude), protocol.WithBaseHeight(payload.Coordinates.Height), protocol.WithBaseAntennaOffset(payload.AntennaOffset), protocol.WithBaseMode("manual"), } // enregistrement du résultat en configuration if err := client.SetBase(ctx, opts...); err != nil { fmt.Printf("[FATAL] %+v", errors.WithStack(err)) return } } } } func retrieveAndProcessConfig(ctx context.Context, client *reach.Client) (*model.Configuration, error) { configData, err := client.Configuration(ctx) if err != nil { fmt.Printf("[ERROR] %+v", errors.WithStack(err)) } var config model.Configuration err = mapstructure.Decode(configData, &config) if err != nil { fmt.Printf("[ERROR] %+v", errors.WithStack(err)) } return &config, nil }