diff --git a/cli/cli.go b/cli/cli.go index f0c6a7c..7cfaa8f 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -2,7 +2,7 @@ package cli import ( "flag" - "github.com/cyrilix/robocar-base/mqttdevice" + "fmt" "github.com/cyrilix/robocar-base/service" MQTT "github.com/eclipse/paho.mqtt.golang" "log" @@ -92,5 +92,24 @@ func InitFloat64Flag(key string, defValue float64) float64 { } func Connect(uri, username, password, clientId string) (MQTT.Client, error) { - return mqttdevice.Connect(uri, username, password, clientId) + //create a ClientOptions struct setting the broker address, clientid, turn + //off trace output and set the default message handler + opts := MQTT.NewClientOptions().AddBroker(uri) + opts.SetUsername(username) + opts.SetPassword(password) + opts.SetClientID(clientId) + opts.SetAutoReconnect(true) + opts.SetDefaultPublishHandler( + //define a function for the default message handler + func(client MQTT.Client, msg MQTT.Message) { + fmt.Printf("TOPIC: %s\n", msg.Topic()) + fmt.Printf("MSG: %s\n", msg.Payload()) + }) + + //create and start a client using the above ClientOptions + client := MQTT.NewClient(opts) + if token := client.Connect(); token.Wait() && token.Error() != nil { + return nil, fmt.Errorf("unable to connect to mqtt bus: %v", token.Error()) + } + return client, nil } diff --git a/mqttdevice/mqttdevice.go b/mqttdevice/mqttdevice.go deleted file mode 100644 index dba5368..0000000 --- a/mqttdevice/mqttdevice.go +++ /dev/null @@ -1,141 +0,0 @@ -package mqttdevice - -import ( - "encoding/json" - "fmt" - "github.com/cyrilix/robocar-base/types" - MQTT "github.com/eclipse/paho.mqtt.golang" - "log" - "strconv" -) - -type Publisher interface { - Publish(topic string, payload MqttValue) -} - -type Subscriber interface { - Subscribe(topic string, mh MQTT.MessageHandler) -} - -type MQTTPubSub interface { - Publisher - Subscriber -} - -type pahoMqttPubSub struct { - client MQTT.Client - qos int - retain bool -} - -func NewPahoMqttPubSub(client MQTT.Client, qos int, retain bool) MQTTPubSub { - p := pahoMqttPubSub{client: client, qos: qos, retain: retain} - return &p -} - -func Connect(uri, username, password, clientId string) (MQTT.Client, error) { - //create a ClientOptions struct setting the broker address, clientid, turn - //off trace output and set the default message handler - opts := MQTT.NewClientOptions().AddBroker(uri) - opts.SetUsername(username) - opts.SetPassword(password) - opts.SetClientID(clientId) - opts.SetAutoReconnect(true) - opts.SetDefaultPublishHandler( - //define a function for the default message handler - func(client MQTT.Client, msg MQTT.Message) { - fmt.Printf("TOPIC: %s\n", msg.Topic()) - fmt.Printf("MSG: %s\n", msg.Payload()) - }) - - //create and start a client using the above ClientOptions - client := MQTT.NewClient(opts) - if token := client.Connect(); token.Wait() && token.Error() != nil { - return nil, fmt.Errorf("unable to connect to mqtt bus: %v", token.Error()) - } - return client, nil -} - -// Publish message to broker -func (p *pahoMqttPubSub) Publish(topic string, payload MqttValue) { - tokenResp := p.client.Publish(topic, byte(p.qos), p.retain, string(payload)) - if tokenResp.Error() != nil { - log.Fatalf("%+v\n", tokenResp.Error()) - } -} - -// Register func to execute on message -func (p *pahoMqttPubSub) Subscribe(topic string, callback MQTT.MessageHandler) { - tokenResp := p.client.Subscribe(topic, byte(p.qos), callback) - if tokenResp.Error() != nil { - log.Fatalf("%+v\n", tokenResp.Error()) - } -} - -type MqttValue []byte - -func NewMqttValue(v interface{}) MqttValue { - switch val := v.(type) { - case string: - return MqttValue(val) - case float32, float64: - return MqttValue(fmt.Sprintf("%0.2f", val)) - case int, int8, int16, int32, int64: - return MqttValue(fmt.Sprintf("%d", val)) - case bool: - if val { - return []byte("ON") - } else { - return []byte("OFF") - } - case []byte: - return val - case MqttValue: - return val - default: - jsonValue, err := json.Marshal(v) - if err != nil { - log.Printf("unable to mashall to json value '%v': %v", v, err) - return nil - } - return jsonValue - } -} - -func (m *MqttValue) IntValue() (int, error) { - return strconv.Atoi(string(*m)) -} - -func (m *MqttValue) Float32Value() (float32, error) { - val := string(*m) - r, err := strconv.ParseFloat(val, 32) - return float32(r), err -} -func (m *MqttValue) Float64Value() (float64, error) { - val := string(*m) - return strconv.ParseFloat(val, 64) -} -func (m *MqttValue) StringValue() (string, error) { - return string(*m), nil -} -func (m *MqttValue) DriveModeValue() (types.DriveMode, error) { - val, err := m.IntValue() - if err != nil { - return types.DriveModeInvalid, err - } - return types.DriveMode(val), nil -} -func (m *MqttValue) ByteSliceValue() ([]byte, error) { - return *m, nil -} -func (m *MqttValue) BoolValue() (bool, error) { - val := string(*m) - switch val { - case "ON": - return true, nil - case "OFF": - return false, nil - default: - return false, fmt.Errorf("value %v can't be converted to bool", val) - } -} diff --git a/mqttdevice/mqttdevice_test.go b/mqttdevice/mqttdevice_test.go deleted file mode 100644 index 5d26709..0000000 --- a/mqttdevice/mqttdevice_test.go +++ /dev/null @@ -1,215 +0,0 @@ -package mqttdevice - -import ( - "github.com/cyrilix/robocar-base/testtools/docker" - "github.com/cyrilix/robocar-base/types" - mqtt "github.com/eclipse/paho.mqtt.golang" - log "github.com/sirupsen/logrus" - "testing" -) - -func TestIntegration(t *testing.T) { - - ctx, mqttC, mqttUri := docker.MqttContainer(t) - defer func(){ - err := mqttC.Terminate(ctx) - log.Errorf("unable to terminate container: %v", err) - }() - - t.Run("ConnectAndClose", func(t *testing.T) { - t.Logf("Mqtt connection %s ready", mqttUri) - - client, err := Connect(mqttUri, "TestMqtt", "guest", "guest") - if err != nil { - t.Errorf("unable to init mqtt connection: %v", err) - } - defer client.Disconnect(10) - }) - t.Run("Publish", func(t *testing.T) { - options := mqtt.NewClientOptions().AddBroker(mqttUri) - options.SetUsername("guest") - options.SetPassword("guest") - - client := mqtt.NewClient(options) - token := client.Connect() - defer client.Disconnect(100) - token.Wait() - if token.Error() != nil { - t.Fatalf("unable to connect to mqtt broker: %v\n", token.Error()) - } - defer client.Disconnect(10) - - c := make(chan string) - defer close(c) - client.Subscribe("test/publish", 0, func(client mqtt.Client, message mqtt.Message) { - c <- string(message.Payload()) - }).Wait() - - p := pahoMqttPubSub{client: client} - - p.Publish("test/publish", []byte("Test1234")) - result := <-c - if result != "Test1234" { - t.Fatalf("bad message: %v\n", result) - } - - }) -} - -func TestNewMqttValue(t *testing.T) { - cases := []struct { - value interface{} - expected MqttValue - }{ - {"text", []byte("text")}, - {float32(2.0123), []byte("2.01")}, - {3.12345, []byte("3.12")}, - {12, []byte("12")}, - {true, []byte("ON")}, - {false, []byte("OFF")}, - {MqttValue("13"), []byte("13")}, - {[]byte("test bytes"), []byte("test bytes")}, - - {struct { - Content string - }{"other"}, []byte(`{"Content":"other"}`)}, - } - - for _, c := range cases { - val := NewMqttValue(c.value) - if string(val) != string(c.expected) { - t.Errorf("NewMqttValue(%v): %v, wants %v", c.value, string(val), string(c.expected)) - } - } -} - -func TestMqttValue_BoolValue(t *testing.T) { - cases := []struct { - value MqttValue - expected bool - }{ - {NewMqttValue("ON"), true}, - {NewMqttValue("OFF"), false}, - } - for _, c := range cases { - val, err := c.value.BoolValue() - if err != nil { - t.Errorf("unexpected conversion error: %v", err) - } - if c.expected != val { - t.Errorf("MqttValue.BoolValue(): %v, wants %v", val, c.expected) - } - } -} - -func TestMqttValue_ByteSliceValue(t *testing.T) { - cases := []struct { - value MqttValue - expected []byte - }{ - {NewMqttValue([]byte("content")), []byte("content")}, - } - for _, c := range cases { - val, err := c.value.ByteSliceValue() - if err != nil { - t.Errorf("unexpected conversion error: %v", err) - } - if string(c.expected) != string(val) { - t.Errorf("MqttValue.BoolValue(): %v, wants %v", val, c.expected) - } - } -} - -func TestMqttValue_Float32Value(t *testing.T) { - cases := []struct { - value MqttValue - expected float32 - }{ - {NewMqttValue("32.0123"), float32(32.0123)}, - {NewMqttValue("33"), float32(33.)}, - } - for _, c := range cases { - val, err := c.value.Float32Value() - if err != nil { - t.Errorf("unexpected conversion error: %v", err) - } - if c.expected != val { - t.Errorf("MqttValue.BoolValue(): %v, wants %v", val, c.expected) - } - } -} - -func TestMqttValue_Float64Value(t *testing.T) { - cases := []struct { - value MqttValue - expected float64 - }{ - {NewMqttValue("32.0123"), 32.0123}, - {NewMqttValue("33"), 33.}, - } - for _, c := range cases { - val, err := c.value.Float64Value() - if err != nil { - t.Errorf("unexpected conversion error: %v", err) - } - if c.expected != val { - t.Errorf("MqttValue.BoolValue(): %v, wants %v", val, c.expected) - } - } -} -func TestMqttValue_IntValue(t *testing.T) { - cases := []struct { - value MqttValue - expected int - }{ - {NewMqttValue("1"), 1}, - {NewMqttValue("-10"), -10}, - } - for _, c := range cases { - val, err := c.value.IntValue() - if err != nil { - t.Errorf("unexpected conversion error: %v", err) - } - if c.expected != val { - t.Errorf("MqttValue.BoolValue(): %v, wants %v", val, c.expected) - } - } -} -func TestMqttValue_StringValue(t *testing.T) { - cases := []struct { - value MqttValue - expected string - }{ - {NewMqttValue("ON"), "ON"}, - {NewMqttValue("OFF"), "OFF"}, - } - for _, c := range cases { - val, err := c.value.StringValue() - if err != nil { - t.Errorf("unexpected conversion error: %v", err) - } - if c.expected != val { - t.Errorf("MqttValue.BoolValue(): %v, wants %v", val, c.expected) - } - } -} - -func TestMqttValue_DriveModeValue(t *testing.T) { - cases := []struct { - value MqttValue - expected types.DriveMode - }{ - {NewMqttValue(types.DriveModeUser), types.DriveModeUser}, - {NewMqttValue(types.DriveModePilot), types.DriveModePilot}, - {NewMqttValue(types.DriveModeInvalid), types.DriveModeInvalid}, - } - for _, c := range cases { - val, err := c.value.DriveModeValue() - if err != nil { - t.Errorf("unexpected conversion error: %v", err) - } - if c.expected != val { - t.Errorf("MqttValue.DriveMode(): %v, wants %v", val, c.expected) - } - } -} diff --git a/types/mode.go b/types/mode.go deleted file mode 100644 index de839a9..0000000 --- a/types/mode.go +++ /dev/null @@ -1,36 +0,0 @@ -package types - -import ( - "log" -) - -type DriveMode int - -const ( - DriveModeInvalid = -1 - DriveModeUser = iota - DriveModePilot -) - -func ToString(mode DriveMode) string { - switch mode { - case DriveModeUser: - return "user" - case DriveModePilot: - return "pilot" - default: - return "" - } -} - -func ParseString(val string) DriveMode { - switch val { - case "user": - return DriveModeUser - case "pilot": - return DriveModePilot - default: - log.Printf("invalid DriveMode: %v", val) - return DriveModeInvalid - } -} diff --git a/types/mode_test.go b/types/mode_test.go deleted file mode 100644 index f49af40..0000000 --- a/types/mode_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package types - -import "testing" - -func TestToString(t *testing.T) { - cases := []struct { - value DriveMode - expected string - }{ - {DriveModeUser, "user"}, - {DriveModePilot, "pilot"}, - {DriveModeInvalid, ""}, - } - - for _, c := range cases { - val := ToString(c.value) - if val != c.expected { - t.Errorf("ToString(%v): %v, wants %v", c.value, val, c.expected) - } - } -} - -func TestParseString(t *testing.T) { - cases := []struct { - value string - expected DriveMode - }{ - {"user", DriveModeUser}, - {"pilot", DriveModePilot}, - {"", DriveModeInvalid}, - {"invalid", DriveModeInvalid}, - } - - for _, c := range cases { - val := ParseString(c.value) - if val != c.expected { - t.Errorf("ParseString(%v): %v, wants %v", c.value, val, c.expected) - } - } -} diff --git a/types/rc.go b/types/rc.go deleted file mode 100644 index 6568d92..0000000 --- a/types/rc.go +++ /dev/null @@ -1,10 +0,0 @@ -package types - -/* Radio control value */ -type RCValue struct { - Value float64 - Confidence float64 -} - -type Steering RCValue -type Throttle RCValue diff --git a/types/types.go b/types/types.go deleted file mode 100644 index 583dc65..0000000 --- a/types/types.go +++ /dev/null @@ -1,5 +0,0 @@ -package types - -type BoundingBox struct { - Left, Top, Right, Bottom int -}