From ee76646901dad6c7f758ee3ca8ecc4100af12a26 Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Mon, 5 Jul 2021 16:50:00 +0200 Subject: [PATCH 1/4] Restructure commands organization --- cli/ping/ping.go | 118 +++++++++++++++++++++++++++++++++++++++++++++++ cli/root.go | 18 ++++++++ command/ping.go | 117 ---------------------------------------------- command/root.go | 16 ------- main.go | 4 +- 5 files changed, 138 insertions(+), 135 deletions(-) create mode 100644 cli/ping/ping.go create mode 100644 cli/root.go delete mode 100644 command/ping.go delete mode 100644 command/root.go diff --git a/cli/ping/ping.go b/cli/ping/ping.go new file mode 100644 index 00000000..fea17db1 --- /dev/null +++ b/cli/ping/ping.go @@ -0,0 +1,118 @@ +package ping + +import ( + "fmt" + "log" + "math/rand" + "os" + "os/signal" + "syscall" + "time" + + "github.com/bcmi-labs/iot-cloud-cli/adapters/mqtt" + "github.com/bcmi-labs/iot-cloud-cli/internal/properties" + paho "github.com/eclipse/paho.mqtt.golang" + "github.com/spf13/cobra" +) + +var ( + host string + username string + password string + thingID string + troubleshooting bool +) + +func NewCommand() *cobra.Command { + pingCommand := &cobra.Command{ + Use: "ping", + Short: "Ping Arduino IoT Cloud", + Long: "Ping Arduino IoT Cloud", + RunE: runPingCommand, + } + + pingCommand.Flags().StringVarP(&host, "host", "b", "tcps://mqtts-up.iot.arduino.cc:8884", "Broker endpoint (required)") + pingCommand.Flags().StringVarP(&username, "username", "u", "", "Username (required)") + pingCommand.Flags().StringVarP(&password, "password", "p", "", "Password (required)") + pingCommand.Flags().StringVarP(&thingID, "thing_id", "t", "", "Thing ID (required)") + + pingCommand.Flags().BoolVar(&troubleshooting, "troubleshooting", false, "Enable troubleshooting mode (full logs from the MQTT client)") + + pingCommand.MarkFlagRequired("username") + pingCommand.MarkFlagRequired("password") + pingCommand.MarkFlagRequired("thing_id") + + return pingCommand +} + +func runPingCommand(cmd *cobra.Command, args []string) error { + if troubleshooting { + paho.ERROR = log.New(os.Stdout, "[ERROR] ", 0) + paho.CRITICAL = log.New(os.Stdout, "[CRIT] ", 0) + paho.WARN = log.New(os.Stdout, "[WARN] ", 0) + paho.DEBUG = log.New(os.Stdout, "[DEBUG] ", 0) + } + + mqttAdapter := mqtt.NewAdapterWithAuth( + host, + username, + username, + password, + ) + + err := mqttAdapter.Connect() + if err != nil { + return err + } + fmt.Println("Connected to Arduino IoT Cloud") + + inboundTopic := fmt.Sprintf("/a/t/%s/e/i", thingID) + outboundTopic := fmt.Sprintf("/a/t/%s/e/o", thingID) + + // Subscribing to the thing inbound topic to received new properties + // values from the cloud. + ok, _ := mqttAdapter.On(inboundTopic, func(msg paho.Message) { + fmt.Println("received a message", msg) + }) + fmt.Println("Subscribed", ok) + + // Sending new random values (in the 0-100 range) to the thing specified + // using the flags + go func() { + for { + randomValue := rand.Intn(100) + + property, err := properties.NewInteger("counter", randomValue) + if err != nil { + fmt.Println("Failed to encode property value", err) + } + + // Publishing a new random value to the outbound topic of the thing + err = mqttAdapter.Publish(outboundTopic, property) + if err != nil { + fmt.Println("Failed to send property to Arduino IoT Cloud", err) + } + fmt.Println("Property value sent successfully", randomValue) + + wait := 3 + time.Sleep(time.Duration(wait) * time.Second) + } + }() + + // Wait for a sigterm signal (CTRL+C) to disconnect from the broker + // and say good bye + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGINT) + + // blocking here waiting for a signal from the terminal 😪 + <-c + + mqttAdapter.Disconnect() + if err != nil { + return err + } + fmt.Println("Disconnected from Arduino IoT Cloud.") + fmt.Println("Completed successfully.") + + return nil +} diff --git a/cli/root.go b/cli/root.go new file mode 100644 index 00000000..3e158bda --- /dev/null +++ b/cli/root.go @@ -0,0 +1,18 @@ +package cli + +import ( + "fmt" + "os" + + "github.com/bcmi-labs/iot-cloud-cli/cli/ping" + "github.com/spf13/cobra" +) + +func Execute() { + rootCmd := &cobra.Command{} + rootCmd.AddCommand(ping.NewCommand()) + + if err := rootCmd.Execute(); err != nil { + fmt.Fprintln(os.Stderr, err) + } +} diff --git a/command/ping.go b/command/ping.go deleted file mode 100644 index 2be7cacb..00000000 --- a/command/ping.go +++ /dev/null @@ -1,117 +0,0 @@ -package command - -import ( - "fmt" - "log" - "math/rand" - "os" - "os/signal" - "syscall" - "time" - - "github.com/bcmi-labs/iot-cloud-cli/adapters/mqtt" - "github.com/bcmi-labs/iot-cloud-cli/internal/properties" - paho "github.com/eclipse/paho.mqtt.golang" - "github.com/spf13/cobra" -) - -var ( - host string - username string - password string - thingID string - troubleshooting bool -) - -func init() { - pingCommand.Flags().StringVarP(&host, "host", "b", "tcps://mqtts-up.iot.arduino.cc:8884", "Broker endpoint (required)") - pingCommand.Flags().StringVarP(&username, "username", "u", "", "Username (required)") - pingCommand.Flags().StringVarP(&password, "password", "p", "", "Password (required)") - pingCommand.Flags().StringVarP(&thingID, "thing_id", "t", "", "Thing ID (required)") - - pingCommand.Flags().BoolVar(&troubleshooting, "troubleshooting", false, "Enable troubleshooting mode (full logs from the MQTT client)") - - pingCommand.MarkFlagRequired("username") - pingCommand.MarkFlagRequired("password") - pingCommand.MarkFlagRequired("thing_id") - - RootCmd.AddCommand(pingCommand) -} - -var pingCommand = &cobra.Command{ - Use: "ping", - Short: "Ping Arduino IoT Cloud", - Long: "Ping Arduino IoT Cloud", - RunE: func(cmd *cobra.Command, args []string) error { - - if troubleshooting { - paho.ERROR = log.New(os.Stdout, "[ERROR] ", 0) - paho.CRITICAL = log.New(os.Stdout, "[CRIT] ", 0) - paho.WARN = log.New(os.Stdout, "[WARN] ", 0) - paho.DEBUG = log.New(os.Stdout, "[DEBUG] ", 0) - } - - mqttAdapter := mqtt.NewAdapterWithAuth( - host, - username, - username, - password, - ) - - err := mqttAdapter.Connect() - if err != nil { - return err - } - fmt.Println("Connected to Arduino IoT Cloud") - - inboundTopic := fmt.Sprintf("/a/t/%s/e/i", thingID) - outboundTopic := fmt.Sprintf("/a/t/%s/e/o", thingID) - - // Subscribing to the thing inbound topic to received new properties - // values from the cloud. - ok, _ := mqttAdapter.On(inboundTopic, func(msg paho.Message) { - fmt.Println("received a message", msg) - }) - fmt.Println("Subscribed", ok) - - // Sending new random values (in the 0-100 range) to the thing specified - // using the flags - go func() { - for { - randomValue := rand.Intn(100) - - property, err := properties.NewInteger("counter", randomValue) - if err != nil { - fmt.Println("Failed to encode property value", err) - } - - // Publishing a new random value to the outbound topic of the thing - err = mqttAdapter.Publish(outboundTopic, property) - if err != nil { - fmt.Println("Failed to send property to Arduino IoT Cloud", err) - } - fmt.Println("Property value sent successfully", randomValue) - - wait := 3 - time.Sleep(time.Duration(wait) * time.Second) - } - }() - - // Wait for a sigterm signal (CTRL+C) to disconnect from the broker - // and say good bye - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGINT) - - // blocking here waiting for a signal from the terminal 😪 - <-c - - mqttAdapter.Disconnect() - if err != nil { - return err - } - fmt.Println("Disconnected from Arduino IoT Cloud.") - fmt.Println("Completed successfully.") - - return nil - }, -} diff --git a/command/root.go b/command/root.go deleted file mode 100644 index 3c45d23c..00000000 --- a/command/root.go +++ /dev/null @@ -1,16 +0,0 @@ -package command - -import ( - "fmt" - "os" - - "github.com/spf13/cobra" -) - -var RootCmd = &cobra.Command{} - -func Execute() { - if err := RootCmd.Execute(); err != nil { - fmt.Fprintln(os.Stderr, err) - } -} diff --git a/main.go b/main.go index e973b9fc..519bd385 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,7 @@ package main -import "github.com/bcmi-labs/iot-cloud-cli/command" +import "github.com/bcmi-labs/iot-cloud-cli/cli" func main() { - command.Execute() + cli.Execute() } From ae5d0fa370b824656e79bbe241c015fe2a99934f Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Fri, 16 Jul 2021 16:20:22 +0200 Subject: [PATCH 2/4] Restructure mqtt package --- cli/ping/ping.go | 2 +- {adapters => internal}/mqtt/adapter.go | 0 {utils => internal/mqtt}/topic.go | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename {adapters => internal}/mqtt/adapter.go (100%) rename {utils => internal/mqtt}/topic.go (99%) diff --git a/cli/ping/ping.go b/cli/ping/ping.go index fea17db1..aa0dec7a 100644 --- a/cli/ping/ping.go +++ b/cli/ping/ping.go @@ -9,7 +9,7 @@ import ( "syscall" "time" - "github.com/bcmi-labs/iot-cloud-cli/adapters/mqtt" + "github.com/bcmi-labs/iot-cloud-cli/internal/mqtt" "github.com/bcmi-labs/iot-cloud-cli/internal/properties" paho "github.com/eclipse/paho.mqtt.golang" "github.com/spf13/cobra" diff --git a/adapters/mqtt/adapter.go b/internal/mqtt/adapter.go similarity index 100% rename from adapters/mqtt/adapter.go rename to internal/mqtt/adapter.go diff --git a/utils/topic.go b/internal/mqtt/topic.go similarity index 99% rename from utils/topic.go rename to internal/mqtt/topic.go index 400c3ff2..34449f63 100644 --- a/utils/topic.go +++ b/internal/mqtt/topic.go @@ -1,4 +1,4 @@ -package utils +package mqtt import ( "regexp" From 91ef2a243407e122c88f050de3f612ccc434a4dc Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Wed, 21 Jul 2021 16:07:49 +0200 Subject: [PATCH 3/4] Split ping in cli and command --- cli/ping/ping.go | 86 ++++----------------------------------- command/ping/ping.go | 95 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 78 deletions(-) create mode 100644 command/ping/ping.go diff --git a/cli/ping/ping.go b/cli/ping/ping.go index aa0dec7a..20ed68d9 100644 --- a/cli/ping/ping.go +++ b/cli/ping/ping.go @@ -1,17 +1,7 @@ package ping import ( - "fmt" - "log" - "math/rand" - "os" - "os/signal" - "syscall" - "time" - - "github.com/bcmi-labs/iot-cloud-cli/internal/mqtt" - "github.com/bcmi-labs/iot-cloud-cli/internal/properties" - paho "github.com/eclipse/paho.mqtt.golang" + "github.com/bcmi-labs/iot-cloud-cli/command/ping" "github.com/spf13/cobra" ) @@ -46,73 +36,13 @@ func NewCommand() *cobra.Command { } func runPingCommand(cmd *cobra.Command, args []string) error { - if troubleshooting { - paho.ERROR = log.New(os.Stdout, "[ERROR] ", 0) - paho.CRITICAL = log.New(os.Stdout, "[CRIT] ", 0) - paho.WARN = log.New(os.Stdout, "[WARN] ", 0) - paho.DEBUG = log.New(os.Stdout, "[DEBUG] ", 0) - } - - mqttAdapter := mqtt.NewAdapterWithAuth( - host, - username, - username, - password, - ) - - err := mqttAdapter.Connect() - if err != nil { - return err - } - fmt.Println("Connected to Arduino IoT Cloud") - - inboundTopic := fmt.Sprintf("/a/t/%s/e/i", thingID) - outboundTopic := fmt.Sprintf("/a/t/%s/e/o", thingID) - - // Subscribing to the thing inbound topic to received new properties - // values from the cloud. - ok, _ := mqttAdapter.On(inboundTopic, func(msg paho.Message) { - fmt.Println("received a message", msg) - }) - fmt.Println("Subscribed", ok) - - // Sending new random values (in the 0-100 range) to the thing specified - // using the flags - go func() { - for { - randomValue := rand.Intn(100) - - property, err := properties.NewInteger("counter", randomValue) - if err != nil { - fmt.Println("Failed to encode property value", err) - } - - // Publishing a new random value to the outbound topic of the thing - err = mqttAdapter.Publish(outboundTopic, property) - if err != nil { - fmt.Println("Failed to send property to Arduino IoT Cloud", err) - } - fmt.Println("Property value sent successfully", randomValue) - - wait := 3 - time.Sleep(time.Duration(wait) * time.Second) - } - }() - - // Wait for a sigterm signal (CTRL+C) to disconnect from the broker - // and say good bye - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGINT) - - // blocking here waiting for a signal from the terminal 😪 - <-c - - mqttAdapter.Disconnect() - if err != nil { - return err + params := &ping.PingParams{ + Host: host, + Username: username, + Password: password, + ThingID: thingID, + Troubleshooting: troubleshooting, } - fmt.Println("Disconnected from Arduino IoT Cloud.") - fmt.Println("Completed successfully.") - return nil + return ping.Ping(params) } diff --git a/command/ping/ping.go b/command/ping/ping.go new file mode 100644 index 00000000..3d9d0dfc --- /dev/null +++ b/command/ping/ping.go @@ -0,0 +1,95 @@ +package ping + +import ( + "fmt" + "log" + "math/rand" + "os" + "os/signal" + "syscall" + "time" + + "github.com/bcmi-labs/iot-cloud-cli/internal/mqtt" + "github.com/bcmi-labs/iot-cloud-cli/internal/properties" + paho "github.com/eclipse/paho.mqtt.golang" +) + +type PingParams struct { + Host string + Username string + Password string + ThingID string + Troubleshooting bool +} + +func Ping(params *PingParams) error { + if params.Troubleshooting { + paho.ERROR = log.New(os.Stdout, "[ERROR] ", 0) + paho.CRITICAL = log.New(os.Stdout, "[CRIT] ", 0) + paho.WARN = log.New(os.Stdout, "[WARN] ", 0) + paho.DEBUG = log.New(os.Stdout, "[DEBUG] ", 0) + } + + mqttAdapter := mqtt.NewAdapterWithAuth( + params.Host, + params.Username, + params.Username, + params.Password, + ) + + err := mqttAdapter.Connect() + if err != nil { + return err + } + fmt.Println("Connected to Arduino IoT Cloud") + + inboundTopic := fmt.Sprintf("/a/t/%s/e/i", params.ThingID) + outboundTopic := fmt.Sprintf("/a/t/%s/e/o", params.ThingID) + + // Subscribing to the thing inbound topic to received new properties + // values from the cloud. + ok, _ := mqttAdapter.On(inboundTopic, func(msg paho.Message) { + fmt.Println("received a message", msg) + }) + fmt.Println("Subscribed", ok) + + // Sending new random values (in the 0-100 range) to the thing specified + // using the flags + go func() { + for { + randomValue := rand.Intn(100) + + property, err := properties.NewInteger("counter", randomValue) + if err != nil { + fmt.Println("Failed to encode property value", err) + } + + // Publishing a new random value to the outbound topic of the thing + err = mqttAdapter.Publish(outboundTopic, property) + if err != nil { + fmt.Println("Failed to send property to Arduino IoT Cloud", err) + } + fmt.Println("Property value sent successfully", randomValue) + + wait := 3 + time.Sleep(time.Duration(wait) * time.Second) + } + }() + + // Wait for a sigterm signal (CTRL+C) to disconnect from the broker + // and say good bye + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGINT) + + // blocking here waiting for a signal from the terminal 😪 + <-c + + mqttAdapter.Disconnect() + if err != nil { + return err + } + + fmt.Println("Disconnected from Arduino IoT Cloud.") + fmt.Println("Completed successfully.") + return nil +} From 910e7a2606a2fc0ac0e05bf75125b3668114e593 Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Wed, 21 Jul 2021 17:08:00 +0200 Subject: [PATCH 4/4] Rename ping params --- cli/ping/ping.go | 2 +- command/ping/ping.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/ping/ping.go b/cli/ping/ping.go index 20ed68d9..1a579a12 100644 --- a/cli/ping/ping.go +++ b/cli/ping/ping.go @@ -36,7 +36,7 @@ func NewCommand() *cobra.Command { } func runPingCommand(cmd *cobra.Command, args []string) error { - params := &ping.PingParams{ + params := &ping.Params{ Host: host, Username: username, Password: password, diff --git a/command/ping/ping.go b/command/ping/ping.go index 3d9d0dfc..f07e30e2 100644 --- a/command/ping/ping.go +++ b/command/ping/ping.go @@ -14,7 +14,7 @@ import ( paho "github.com/eclipse/paho.mqtt.golang" ) -type PingParams struct { +type Params struct { Host string Username string Password string @@ -22,7 +22,7 @@ type PingParams struct { Troubleshooting bool } -func Ping(params *PingParams) error { +func Ping(params *Params) error { if params.Troubleshooting { paho.ERROR = log.New(os.Stdout, "[ERROR] ", 0) paho.CRITICAL = log.New(os.Stdout, "[CRIT] ", 0)