From f56046536471e1a49053056dc5d084ad0fe9d270 Mon Sep 17 00:00:00 2001 From: cmsassot Date: Wed, 11 Jun 2025 12:07:51 +0200 Subject: [PATCH] feat(CorrectionInput): method to configure the source of correction data --- reach/client/operations.go | 27 +++++++ reach/client/protocol/operations.go | 6 ++ reach/client/protocol/set_base_correction.go | 56 +++++++++++++ reach/client/protocol/testsuite/operations.go | 72 +++++++++++++++++ reach/client/protocol/v2/internal.go | 10 +++ .../protocol/v2/model/corrections_input.go | 81 +++++++++++++++++++ reach/client/protocol/v2/operations.go | 66 +++++++++++++++ 7 files changed, 318 insertions(+) create mode 100644 reach/client/protocol/set_base_correction.go create mode 100644 reach/client/protocol/v2/model/corrections_input.go diff --git a/reach/client/operations.go b/reach/client/operations.go index 83abd19..5e12c31 100644 --- a/reach/client/operations.go +++ b/reach/client/operations.go @@ -166,4 +166,31 @@ func (c *Client) AveragePosition(ctx context.Context) (*protocol.TaskMessage, er return taskMsg, err } + +// GetNTRIPMountPoint implements protocol.Operations. +func (c *Client) GetNTRIPMountPoint(ctx context.Context) error { + _, ops, err := c.getProtocol(ctx) + if err != nil { + return errors.WithStack(err) + } + + if err := ops.GetNTRIPMountPoint(ctx); err != nil { + return errors.WithStack(err) + } + + return nil +} + +// SetBaseCorrections implements protocol.Operations. +func (c *Client) SetBaseCorrections(ctx context.Context, funcs ...protocol.SetBaseCorrectionsFunc) error { + _, ops, err := c.getProtocol(ctx) + if err != nil { + return errors.WithStack(err) + } + + if err := ops.SetBaseCorrections(ctx, funcs...); err != nil { + return errors.WithStack(err) + } + return nil +} var _ protocol.Operations = &Client{} diff --git a/reach/client/protocol/operations.go b/reach/client/protocol/operations.go index d916e70..0a029ea 100644 --- a/reach/client/protocol/operations.go +++ b/reach/client/protocol/operations.go @@ -52,4 +52,10 @@ type Operations interface { // AveragePosition gathers data and computes the average position AveragePosition(ctx context.Context) (*TaskMessage, error) + + //GetNTRIPMountPoint retrieves availables mount point + GetNTRIPMountPoint(ctx context.Context) error + + //SetBaseCorrections updates the corrections obtaining station + SetBaseCorrections(ctx context.Context, funcs ...SetBaseCorrectionsFunc) error } diff --git a/reach/client/protocol/set_base_correction.go b/reach/client/protocol/set_base_correction.go new file mode 100644 index 0000000..f8cfcac --- /dev/null +++ b/reach/client/protocol/set_base_correction.go @@ -0,0 +1,56 @@ +package protocol + +type SetBaseCorrectionsOptions struct { + Address *string + Port *int + Username *string + Password *string + MountPoint *string + SendPositionToBase *bool +} + +type SetBaseCorrectionsFunc func(opts *SetBaseCorrectionsOptions) + +func NewSetBaseCorrectionsOptions(funcs ...SetBaseCorrectionsFunc) *SetBaseCorrectionsOptions { + opts := &SetBaseCorrectionsOptions{} + for _, fn := range funcs { + fn(opts) + } + return opts +} + +func WithNTRIPAddress(value string) SetBaseCorrectionsFunc { + return func(opts *SetBaseCorrectionsOptions) { + opts.Address = &value + } +} + +func WithNTRIPPort(value int) SetBaseCorrectionsFunc { + return func(opts *SetBaseCorrectionsOptions) { + opts.Port = &value + } +} + +func WithNTRIPUsername(value string) SetBaseCorrectionsFunc { + return func(opts *SetBaseCorrectionsOptions) { + opts.Username = &value + } +} + +func WithNTRIPPassword(value string) SetBaseCorrectionsFunc { + return func(opts *SetBaseCorrectionsOptions) { + opts.Password = &value + } +} + +func WithNTRIPMountPoint(value string) SetBaseCorrectionsFunc { + return func(opts *SetBaseCorrectionsOptions) { + opts.MountPoint = &value + } +} + +func WithSendPositionToBase(value bool) SetBaseCorrectionsFunc { + return func(opts *SetBaseCorrectionsOptions) { + opts.SendPositionToBase = &value + } +} diff --git a/reach/client/protocol/testsuite/operations.go b/reach/client/protocol/testsuite/operations.go index 6a72599..4490b7f 100644 --- a/reach/client/protocol/testsuite/operations.go +++ b/reach/client/protocol/testsuite/operations.go @@ -264,6 +264,78 @@ var testCases = []operationTestCase{ t.Logf("Task Message : %s", taskmessage) }, }, + { + Name: "SetBaseCorrections", + Run: func(t *testing.T, ops protocol.Operations) { + ctx := context.Background() + if err := ops.Connect(ctx); err != nil { + t.Errorf("%+v", errors.WithStack(err)) + return + } + + defer func() { + if err := ops.Close(ctx); err != nil { + t.Errorf("%+v", errors.WithStack(err)) + } + }() + opts := []protocol.SetBaseCorrectionsFunc{ + protocol.WithNTRIPAddress("crtk.net"), + protocol.WithNTRIPPort(2101), + protocol.WithNTRIPUsername("centipede"), + protocol.WithNTRIPPassword("centipede"), + protocol.WithNTRIPMountPoint("EPI21"), + protocol.WithSendPositionToBase(true), + } + + if err := ops.SetBaseCorrections(ctx, opts...); err != nil { + t.Errorf("%+v", errors.WithStack(err)) + return + } + t.Logf("BaseCorrection Update") + + }, + }, + { + Name: "GetNTRIPMountPoint", + Run: func(t *testing.T, ops protocol.Operations) { + ctx := context.Background() + + if err := ops.Connect(ctx); err != nil { + t.Errorf("%+v", errors.WithStack(err)) + return + } + + defer func() { + if err := ops.Close(ctx); err != nil { + t.Errorf("%+v", errors.WithStack(err)) + } + }() + + if err := ops.GetNTRIPMountPoint(ctx); err != nil { + t.Errorf("%+v", errors.WithStack(err)) + return + } + broadcastCtx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + + messages, err := ops.On(broadcastCtx, "task_status") + if err != nil { + t.Errorf("%+v", errors.WithStack(err)) + return + } + + count := 0 + + for m := range messages { + t.Logf("new message: %s", spew.Sdump(m)) + count++ + } + + if e, g := 1, count; g < e { + t.Errorf("expected total messages > %d, got %d", e, g) + } + }, + }, } func TestOperations(t *testing.T, opsFactory OperationsFactoryFunc) { diff --git a/reach/client/protocol/v2/internal.go b/reach/client/protocol/v2/internal.go index 4a3aa4e..fa9cb88 100644 --- a/reach/client/protocol/v2/internal.go +++ b/reach/client/protocol/v2/internal.go @@ -126,6 +126,16 @@ func (o *Operations) PostDevice(ctx context.Context, device *model.Configuration return &updated, nil } +func (o *Operations) PostBaseCorrection(ctx context.Context, base *model.IOConfig) (*model.IOConfig, error) { + var updated model.IOConfig + + if err := o.PostJSON("/configuration/correction_input/base_corrections", base, &updated); err != nil { + return nil, errors.WithStack(err) + } + + return &updated, nil +} + func (o *Operations) GetUpdater(ctx context.Context) (*model.Updater, error) { updater := &model.Updater{} if err := o.GetJSON("/updater", updater); err != nil { diff --git a/reach/client/protocol/v2/model/corrections_input.go b/reach/client/protocol/v2/model/corrections_input.go new file mode 100644 index 0000000..4f81281 --- /dev/null +++ b/reach/client/protocol/v2/model/corrections_input.go @@ -0,0 +1,81 @@ +package model + +type IOConfig struct { + IOType string `json:"io_type"` + Settings IOConfigSettings `json:"settings"` +} + +type IOConfigSettings struct { + NTRIPCli NTRIPCliConfig `json:"ntripcli"` +} + +type NTRIPCliConfig struct { + Address string `json:"address"` + Port int `json:"port"` + Username string `json:"username"` + Password string `json:"password"` + MountPoint string `json:"mount_point"` + SendPositionToBase bool `json:"send_position_to_base"` +} + +type NTRIPResponse struct { + Name string `json:"name"` + Payload NTRIPPayload `json:"payload"` + State string `json:"state"` +} + +type NTRIPPayload struct { + CAS []CasterInfo `json:"cas"` + Net []NetworkInfo `json:"net"` + Str []StreamInfo `json:"str"` +} + +type CasterInfo struct { + Country string `json:"country"` + Distance float64 `json:"distance"` + FallbackHost string `json:"fallback_host"` + FallbackPort string `json:"fallback_port"` + Host string `json:"host"` + ID string `json:"id"` + Latitude string `json:"latitude"` + Longitude string `json:"longitude"` + NMEA string `json:"nmea"` + Operator string `json:"operator"` + OtherDetails *string `json:"other_details"` + Port string `json:"port"` + Site string `json:"site"` +} + +type NetworkInfo struct { + Authentication string `json:"authentication"` + Distance *float64 `json:"distance"` + Fee string `json:"fee"` + ID string `json:"id"` + Operator string `json:"operator"` + OtherDetails string `json:"other_details"` + WebNet string `json:"web_net"` + WebReg string `json:"web_reg"` + WebStr string `json:"web_str"` +} + +type StreamInfo struct { + Authentication string `json:"authentication"` + Bitrate string `json:"bitrate"` + Carrier string `json:"carrier"` + ComprEncryp string `json:"compr_encryp"` + Country string `json:"country"` + Distance float64 `json:"distance"` + Fee string `json:"fee"` + Format string `json:"format"` + FormatDetails string `json:"format_details"` + Generator string `json:"generator"` + ID string `json:"id"` + Latitude string `json:"latitude"` + Longitude string `json:"longitude"` + Mountpoint string `json:"mountpoint"` + NavSystem string `json:"nav_system"` + Network string `json:"network"` + NMEA string `json:"nmea"` + OtherDetails string `json:"other_details"` + Solution string `json:"solution"` +} diff --git a/reach/client/protocol/v2/operations.go b/reach/client/protocol/v2/operations.go index 0ec7a72..beb920a 100644 --- a/reach/client/protocol/v2/operations.go +++ b/reach/client/protocol/v2/operations.go @@ -296,4 +296,70 @@ func (o *Operations) AveragePosition(ctx context.Context) (*protocol.TaskMessage return nil, err } +// GetNTRIPMountPoint implements protocol.Operations. +func (o *Operations) GetNTRIPMountPoint(ctx context.Context) error { + var err error + + config, err := o.GetConfiguration(ctx) + if err != nil { + return errors.WithStack(err) + } + + go func() { + <-ctx.Done() + err = ctx.Err() + }() + + payload := map[string]any{ + "address": config.CorrectionInput.BaseCorrections.Settings.Ntripcli.Address, + "port": config.CorrectionInput.BaseCorrections.Settings.Ntripcli.Port, + } + + if err = o.client.Emit("task", &model.Action{Name: "get_ntrip_mountpoints", Paylaod: payload}); err != nil { + return err + } + + return err +} + +// SetBaseCorrections implements protocol.Operations. +func (o *Operations) SetBaseCorrections(ctx context.Context, funcs ...protocol.SetBaseCorrectionsFunc) error { + opts := protocol.NewSetBaseCorrectionsOptions(funcs...) + if opts.Address == nil { + return errors.New("NTRIP address is required") + } + if opts.Port == nil { + return errors.New("NTRIP port is required") + } + if opts.Username == nil { + return errors.New("NTRIP username is required") + } + if opts.Password == nil { + return errors.New("NTRIP password is required") + } + if opts.MountPoint == nil { + return errors.New("NTRIP mount point is required") + } + + config := &model.IOConfig{ + // todo parametrage du type + IOType: "ntripcli", + Settings: model.IOConfigSettings{ + NTRIPCli: model.NTRIPCliConfig{ + Address: *opts.Address, + Port: *opts.Port, + Username: *opts.Username, + Password: *opts.Password, + MountPoint: *opts.MountPoint, + SendPositionToBase: opts.SendPositionToBase != nil && *opts.SendPositionToBase, + }, + }, + } + + if _, err := o.PostBaseCorrection(ctx, config); err != nil { + return errors.WithStack(err) + } + + return nil +} var _ protocol.Operations = &Operations{}