diff --git a/cmd/broadcast/main.go b/cmd/broadcast/main.go new file mode 100644 index 0000000..faefc28 --- /dev/null +++ b/cmd/broadcast/main.go @@ -0,0 +1,58 @@ +package main + +import ( + "context" + "flag" + "log" + "time" + + "forge.cadoles.com/Pyxis/orion/emlid" + "forge.cadoles.com/Pyxis/orion/emlid/reachview" + "github.com/davecgh/go-spew/spew" +) + +var ( + host = "192.168.42.1" +) + +func init() { + flag.StringVar(&host, "host", host, "ReachRS module host") +} + +func main() { + + flag.Parse() + + c := connect() + defer c.Close() + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + events, err := c.Broadcast(ctx) + if err != nil { + log.Fatal(err) + } + + for e := range events { + log.Printf("received event: %s", spew.Sdump(e)) + } + + log.Println("done") +} + +func connect() *reachview.Client { + c := reachview.NewClient( + emlid.WithEndpoint(host, 80), + ) + + log.Printf("connecting to module '%s'", host) + if err := c.Connect(); err != nil { + log.Fatal(err) + } + + log.Println("connected") + + return c + +} diff --git a/emlid/reachview/broadcast.go b/emlid/reachview/broadcast.go new file mode 100644 index 0000000..d944994 --- /dev/null +++ b/emlid/reachview/broadcast.go @@ -0,0 +1,53 @@ +package reachview + +import ( + "context" + + gosocketio "forge.cadoles.com/Pyxis/golang-socketio" + "github.com/mitchellh/mapstructure" + "github.com/pkg/errors" +) + +const ( + eventBroadcast = "broadcast" +) + +const ( + BroadcastRoverStatus = "rover_status" + BroadcastBaseStatus = "base_status" + BroadcastRTKStatus = "rtk_status" + BroadcastObservations = "observations" + BroadcastTimeMarks = "time_marks" + BroadcastBatteryStatus = "battery_status" +) + +// Broadcast is a broadcasted message containing modules status informations. +type Broadcast struct { + Name string `mapstructure:"name"` + Payload map[string]interface{} `mapstructure:"payload"` +} + +// Broadcast listens for broadcast messages. +func (c *Client) Broadcast(ctx context.Context) (chan Broadcast, error) { + out := make(chan Broadcast) + + handler := func(_ *gosocketio.Channel, data interface{}) { + res := Broadcast{} + if err := mapstructure.WeakDecode(data, &res); err != nil { + c.Logf("error while decoding broadcast message: %s", errors.WithStack(err)) + } + select { + case <-ctx.Done(): + c.Off(eventBroadcast) + close(out) + default: + out <- res + } + } + + if err := c.On(eventBroadcast, handler); err != nil { + return nil, errors.WithStack(err) + } + + return out, nil +} diff --git a/emlid/reachview/status_broadcast_test.go b/emlid/reachview/broadcast_test.go similarity index 86% rename from emlid/reachview/status_broadcast_test.go rename to emlid/reachview/broadcast_test.go index 76ca1be..c6f4f1e 100644 --- a/emlid/reachview/status_broadcast_test.go +++ b/emlid/reachview/broadcast_test.go @@ -10,7 +10,6 @@ import ( ) func TestReachViewStatusBroadcast(t *testing.T) { - if !*runReachViewIntegrationTests { t.Skip("To run this test, use: go test -reachview-integration") } @@ -27,13 +26,12 @@ func TestReachViewStatusBroadcast(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - statuses, err := client.StatusBroadcast(ctx) + broadcastChan, err := client.Broadcast(ctx) if err != nil { t.Fatal(err) } - for s := range statuses { - spew.Dump(s) + for b := range broadcastChan { + spew.Dump(b) } - } diff --git a/emlid/reachview/status_broadcast.go b/emlid/reachview/status_broadcast.go deleted file mode 100644 index 1b07b31..0000000 --- a/emlid/reachview/status_broadcast.go +++ /dev/null @@ -1,142 +0,0 @@ -package reachview - -import ( - "context" - - "forge.cadoles.com/Pyxis/golang-socketio" - "github.com/mitchellh/mapstructure" -) - -const ( - eventStatusBroadcast = "status broadcast" -) - -// StatusBroadcast is a broadcasted message containing modules' -// positioning informations -/* Source sample -{ - "receiver time mark count": "0", - "ant type base": "", - "solution status": "-", - "vel enu (m/s) base": "0.000,0.000,0.000", - "time of receiver clock rover": "2018/10/16 13:55:26.006000000", - "baseline length float (m)": "0.000", - "# of rtcm messages rover": "", - "time sys offset (ns)": "26.748,-6.962,0.000,0.000", - "# of average single pos base": "0", - "pos xyz float std (m) rover": "0.000,0.000,0.000", - "ant delta rover": "0.000 0.000 0.000", - "# of rtcm messages corr": "", - "accumulated time to run": "05:45:59.7", - "cpu time for a cycle (ms)": "16", - "Parameter": "Value", - "# of rtcm messages base": "", - "vel enu (m/s) rover": "0.467,0.476,0.577", - "ant type rover": "", - "pos xyz single (m) rover": "4315030.518,379718.279,4666208.342", - "pos xyz (m) base": "0.000,0.000,0.000", - "# of input data corr": "obs(0),nav(0),gnav(0),ion(0),sbs(0),pos(0),dgps(0),ssr(0),err(0)", - "rtk server state": "run", - "pos xyz fixed (m) rover": "0.000,0.000,0.000", - "age of differential (s)": "0.000", - "pos xyz fixed std (m) rover": "0.000,0.000,0.000", - "# of all estimated states": "170", - "processing cycle (ms)": "10", - "ant delta base": "0.000 0.000 0.000", - "# of valid satellites": "6", - "rtklib version": "2.4.3 Emlid b28", - "bytes in input buffer": "0,0", - "# of satellites rover": "11", - "# of input data rover": "obs(103738),nav(60),gnav(45),ion(3305),sbs(0),pos(0),dgps(0),ssr(0),err(0)", - "pos xyz float (m) rover": "0.000,0.000,0.000", - "ratio for ar validation": "0.000", - "pos llh (deg,m) base": "0.00000000,0.00000000,0.000", - "missing obs data count": "4468", - "# of real estimated states": "9", - "baseline length fixed (m)": "0.000", - "# of satellites base": "0", - "last time mark": "-", - "# of input data base": "obs(0),nav(0),gnav(0),ion(0),sbs(0),pos(0),dgps(0),ssr(0),err(0)", - "GDOP/PDOP/HDOP/VDOP": "0.0,0.0,0.0,0.0", - "positioning mode": "kinematic", - "pos llh single (deg,m) rover": "47.32085966,5.02901552,257.086", - "solution interval (s)": "0.200", - "rtklib time mark count": "0" -} -*/ -type Status struct { - ReceiverTimeMarkCount int `mapstructure:"receiver time mark count"` - BaseAntType string `mapstructure:"ant type base"` - SolutionStatus string `mapstructure:"solution status"` - PositioningMode string `mapstructure:"positioning mode"` - BaseVelocityEnum string `mapstructure:"vel enu (m/s) base"` - RoverReceiverTime string `mapstructure:"time of receiver clock rover"` - BaselineLengthFloat string `mapstructure:"baseline length float (m)"` - RoverNumberOfRTCMMessages string `mapstructure:"# of rtcm messages rover"` - TimeSysOffset string `mapstructure:"time sys offset (ns)"` - BaseNumberOfAverageSinglePos int `mapstructure:"# of average single pos base"` - RoverPosXYZStandaloneFloat string `mapstructure:"pos xyz float std (m) rover"` - RoverAntDelta string `mapstructure:"ant delta rover"` - NumberOfRTCMCorrection string `mapstructure:"# of rtcm messages corr"` - AccumulatedTimeToRun string `mapstructure:"accumulated time to run"` - CPUTimeForACycle int `mapstructure:"cpu time for a cycle (ms)"` - Parameter string `mapstructure:"Parameter"` - BaseNumberOfRTCMMessages string `mapstructure:"# of rtcm messages base"` - RoverVelocityEnum string `mapstructure:"vel enu (m/s) rover"` - RoverAntType string `mapstructure:"ant type rover"` - RoverPosXYZSingle string `mapstructure:"pos xyz single (m) rover"` - BasePosXYZ string `mapstructure:"pos xyz (m) base"` - NumberOfInputDataCorrection string `mapstructure:"# of input data corr"` - RTKServerState string `mapstructure:"rtk server state"` - RoverPosXYZFixed string `mapstructure:"pos xyz fixed (m) rover"` - AgeOfDifferential float32 `mapstructure:"age of differential (s)"` - RoverPosXYZStandaloneFixed string `mapstructure:"pos xyz fixed std (m) rover"` - NumberOfAllEstimatedStates int `mapstructure:"# of all estimated states"` - ProcessingCycle int `mapstructure:"processing cycle (ms)"` - BaseAntDelta string `mapstructure:"ant delta base"` - NumberOfValidSatellites int `mapstructure:"# of valid satellites"` - RTKLibVersion string `mapstructure:"2.4.3 Emlid b28"` - BytesInInputBuffer string `mapstructure:"bytes in input buffer"` - RoverNumberOfSatellites int `mapstructure:"# of satellites rover"` - RoverNumberOfInputData string `mapstructure:"# of input data rover"` - RoverPosXYZFloat string `mapstructure:"pos xyz float (m) rover"` - RatioForARValidation float32 `mapstructure:"ratio for ar validation"` - BasePosLLH string `mapstructure:"pos llh (deg,m) base"` - MissingObsDataCount int `mapstructure:"missing obs data count"` - NumberOfRealEstimatedStates int `mapstructure:"# of real estimated states"` - BaselineLengthFixed float32 `mapstructure:"baseline length fixed (m)"` - BaseNumberOfSatellites int `mapstructure:"# of satellites base"` - LastTimemark string `mapstructure:"last time mark"` - BaseNumberOfInputData string `mapstructure:"# of input data base"` - GdopPdopHdopVdop string `mapstructure:"GDOP/PDOP/HDOP/VDOP"` - RoverPosLLHSingle string `mapstructure:"pos llh single (deg,m) rover"` - SolutionInterval float32 `mapstructure:"solution interval (s)"` - RTKLibTimeMarkCount int `mapstructure:"rtklib time mark count"` -} - -// StatusBroadcast listens for StatusBroadcast messages -func (c *Client) StatusBroadcast(ctx context.Context) (chan Status, error) { - - out := make(chan Status) - - handler := func(_ *gosocketio.Channel, data interface{}) { - res := Status{} - if err := mapstructure.WeakDecode(data, &res); err != nil { - c.Logf("error while decoding status broadcast: %s", err) - } - select { - case <-ctx.Done(): - c.Off(eventStatusBroadcast) - close(out) - default: - out <- res - } - } - - if err := c.On(eventStatusBroadcast, handler); err != nil { - return nil, err - } - - return out, nil - -}