diff --git a/cli/device/list.go b/cli/device/list.go
index 9e7a1036..718f17f3 100644
--- a/cli/device/list.go
+++ b/cli/device/list.go
@@ -19,6 +19,7 @@ package device
import (
"os"
+ "strings"
"github.com/arduino/arduino-cli/cli/errorcodes"
"github.com/arduino/arduino-cli/cli/feedback"
@@ -75,7 +76,7 @@ func (r listResult) String() string {
return "No devices found."
}
t := table.New()
- t.SetHeader("Name", "ID", "Board", "FQBN", "SerialNumber")
+ t.SetHeader("Name", "ID", "Board", "FQBN", "SerialNumber", "Tags")
for _, device := range r.devices {
t.AddRow(
device.Name,
@@ -83,6 +84,7 @@ func (r listResult) String() string {
device.Board,
device.FQBN,
device.Serial,
+ strings.Join(device.Tags, ","),
)
}
return t.Render()
diff --git a/cli/thing/list.go b/cli/thing/list.go
index ad149c60..e81e3612 100644
--- a/cli/thing/list.go
+++ b/cli/thing/list.go
@@ -93,7 +93,7 @@ func (r result) String() string {
}
t := table.New()
- h := []interface{}{"Name", "ID", "Device"}
+ h := []interface{}{"Name", "ID", "Device", "Tags"}
if listFlags.variables {
h = append(h, "Variables")
}
@@ -101,6 +101,7 @@ func (r result) String() string {
for _, thing := range r.things {
r := []interface{}{thing.Name, thing.ID, thing.DeviceID}
+ r = append(r, strings.Join(thing.Tags, ","))
if listFlags.variables {
r = append(r, strings.Join(thing.Variables, ", "))
}
diff --git a/command/device/device.go b/command/device/device.go
new file mode 100644
index 00000000..20678449
--- /dev/null
+++ b/command/device/device.go
@@ -0,0 +1,52 @@
+// This file is part of arduino-cloud-cli.
+//
+// Copyright (C) 2021 ARDUINO SA (http://www.arduino.cc/)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published
+// by the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package device
+
+import (
+ "github.com/arduino/arduino-cloud-cli/command/tag"
+ iotclient "github.com/arduino/iot-client-go"
+)
+
+// DeviceInfo contains the most interesting
+// parameters of an Arduino IoT Cloud device.
+type DeviceInfo struct {
+ Name string `json:"name"`
+ ID string `json:"id"`
+ Board string `json:"board"`
+ Serial string `json:"serial-number"`
+ FQBN string `json:"fqbn"`
+ Tags []string `json:"tags,omitempty"`
+}
+
+func getDeviceInfo(device *iotclient.ArduinoDevicev2) (*DeviceInfo, error) {
+ // Retrieve device tags
+ tags, err := tag.TagsInfo(device.Tags)
+ if err != nil {
+ return nil, err
+ }
+
+ dev := &DeviceInfo{
+ Name: device.Name,
+ ID: device.Id,
+ Board: device.Type,
+ Serial: device.Serial,
+ FQBN: device.Fqbn,
+ Tags: tags,
+ }
+ return dev, nil
+}
diff --git a/command/device/list.go b/command/device/list.go
index cd707521..9ace969e 100644
--- a/command/device/list.go
+++ b/command/device/list.go
@@ -18,20 +18,12 @@
package device
import (
+ "fmt"
+
"github.com/arduino/arduino-cloud-cli/internal/config"
"github.com/arduino/arduino-cloud-cli/internal/iot"
)
-// DeviceInfo contains the most interesting
-// parameters of an Arduino IoT Cloud device.
-type DeviceInfo struct {
- Name string `json:"name"`
- ID string `json:"id"`
- Board string `json:"board"`
- Serial string `json:"serial-number"`
- FQBN string `json:"fqbn"`
-}
-
// ListParams contains the optional parameters needed
// to filter the devices to be listed.
type ListParams struct {
@@ -57,14 +49,11 @@ func List(params *ListParams) ([]DeviceInfo, error) {
var devices []DeviceInfo
for _, foundDev := range foundDevices {
- dev := DeviceInfo{
- Name: foundDev.Name,
- ID: foundDev.Id,
- Board: foundDev.Type,
- Serial: foundDev.Serial,
- FQBN: foundDev.Fqbn,
+ dev, err := getDeviceInfo(&foundDev)
+ if err != nil {
+ return nil, fmt.Errorf("parsing device %s from cloud: %w", foundDev.Id, err)
}
- devices = append(devices, dev)
+ devices = append(devices, *dev)
}
return devices, nil
diff --git a/command/tag/tag.go b/command/tag/tag.go
new file mode 100644
index 00000000..319bb6b1
--- /dev/null
+++ b/command/tag/tag.go
@@ -0,0 +1,34 @@
+// This file is part of arduino-cloud-cli.
+//
+// Copyright (C) 2021 ARDUINO SA (http://www.arduino.cc/)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published
+// by the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package tag
+
+import "fmt"
+
+// TagsInfo transforms tags into user-readable strings
+// An error is returned if a tag value is not a string
+func TagsInfo(tags map[string]interface{}) ([]string, error) {
+ var str []string
+ for key, value := range tags {
+ valStr, ok := value.(string)
+ if !ok {
+ return nil, fmt.Errorf("value of tag `%s` should be of type `string` but is of type `%T`", key, value)
+ }
+ str = append(str, key+"="+valStr)
+ }
+ return str, nil
+}
diff --git a/command/thing/clone.go b/command/thing/clone.go
index d0a8c0a1..514268e8 100644
--- a/command/thing/clone.go
+++ b/command/thing/clone.go
@@ -54,7 +54,11 @@ func Clone(params *CloneParams) (*ThingInfo, error) {
return nil, err
}
- return getThingInfo(newThing), nil
+ t, err := getThingInfo(newThing)
+ if err != nil {
+ return nil, fmt.Errorf("parsing thing %s from cloud: %w", newThing.Id, err)
+ }
+ return t, nil
}
func retrieve(client iot.Client, thingID string) (*iotclient.Thing, error) {
diff --git a/command/thing/create.go b/command/thing/create.go
index 4be2bac7..a9572146 100644
--- a/command/thing/create.go
+++ b/command/thing/create.go
@@ -19,6 +19,7 @@ package thing
import (
"errors"
+ "fmt"
"github.com/arduino/arduino-cloud-cli/internal/config"
"github.com/arduino/arduino-cloud-cli/internal/iot"
@@ -62,5 +63,9 @@ func Create(params *CreateParams) (*ThingInfo, error) {
return nil, err
}
- return getThingInfo(newThing), nil
+ t, err := getThingInfo(newThing)
+ if err != nil {
+ return nil, fmt.Errorf("parsing the new thing %s from cloud: %w", newThing.Id, err)
+ }
+ return t, nil
}
diff --git a/command/thing/list.go b/command/thing/list.go
index e0d647a7..9fc4a95b 100644
--- a/command/thing/list.go
+++ b/command/thing/list.go
@@ -18,6 +18,8 @@
package thing
import (
+ "fmt"
+
"github.com/arduino/arduino-cloud-cli/internal/config"
"github.com/arduino/arduino-cloud-cli/internal/iot"
)
@@ -50,7 +52,10 @@ func List(params *ListParams) ([]ThingInfo, error) {
var things []ThingInfo
for _, foundThing := range foundThings {
- info := getThingInfo(&foundThing)
+ info, err := getThingInfo(&foundThing)
+ if err != nil {
+ return nil, fmt.Errorf("parsing thing %s from cloud: %w", foundThing.Id, err)
+ }
things = append(things, *info)
}
diff --git a/command/thing/thing.go b/command/thing/thing.go
index c5753de2..edbc9f6b 100644
--- a/command/thing/thing.go
+++ b/command/thing/thing.go
@@ -17,7 +17,10 @@
package thing
-import iotclient "github.com/arduino/iot-client-go"
+import (
+ "github.com/arduino/arduino-cloud-cli/command/tag"
+ iotclient "github.com/arduino/iot-client-go"
+)
// ThingInfo contains the main parameters of
// an Arduino IoT Cloud thing.
@@ -26,18 +29,27 @@ type ThingInfo struct {
ID string `json:"id"`
DeviceID string `json:"device-id"`
Variables []string `json:"variables"`
+ Tags []string `json:"tags,omitempty"`
}
-func getThingInfo(thing *iotclient.ArduinoThing) *ThingInfo {
+func getThingInfo(thing *iotclient.ArduinoThing) (*ThingInfo, error) {
+ // Process thing variables
var vars []string
for _, p := range thing.Properties {
vars = append(vars, p.Name)
}
+ // Process thing tags
+ tags, err := tag.TagsInfo(thing.Tags)
+ if err != nil {
+ return nil, err
+ }
+
info := &ThingInfo{
Name: thing.Name,
ID: thing.Id,
DeviceID: thing.DeviceId,
Variables: vars,
+ Tags: tags,
}
- return info
+ return info, nil
}