Update itctl to use api

This commit is contained in:
Elara 2021-10-23 18:41:03 -07:00
parent e45bfe3de8
commit 32cab6d00f
10 changed files with 71 additions and 294 deletions

14
api/notify.go Normal file
View File

@ -0,0 +1,14 @@
package api
import "go.arsenm.dev/itd/internal/types"
func (c *Client) Notify(title string, body string) error {
_, err := c.request(types.Request{
Type: types.ReqTypeNotify,
Data: types.ReqDataNotify{
Title: title,
Body: body,
},
})
return err
}

View File

@ -19,15 +19,11 @@
package firmware
import (
"bufio"
"encoding/json"
"net"
"github.com/cheggaaa/pb/v3"
"github.com/mitchellh/mapstructure"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.arsenm.dev/itd/api"
"go.arsenm.dev/itd/internal/types"
)
@ -36,47 +32,34 @@ type DFUProgress struct {
Total int64 `mapstructure:"total"`
}
// upgradeCmd represents the upgrade command
var upgradeCmd = &cobra.Command{
Use: "upgrade",
Short: "Upgrade InfiniTime firmware using files or archive",
Aliases: []string{"upg"},
Run: func(cmd *cobra.Command, args []string) {
// Connect to itd UNIX socket
conn, err := net.Dial("unix", viper.GetString("sockPath"))
if err != nil {
log.Fatal().Err(err).Msg("Error dialing socket. Is itd running?")
}
defer conn.Close()
client := viper.Get("client").(*api.Client)
var data types.ReqDataFwUpgrade
var upgType api.UpgradeType
var files []string
// Get relevant data struct
if viper.GetString("archive") != "" {
// Get archive data struct
data = types.ReqDataFwUpgrade{
Type: types.UpgradeTypeArchive,
Files: []string{viper.GetString("archive")},
}
upgType = types.UpgradeTypeArchive
files = []string{viper.GetString("archive")}
} else if viper.GetString("initPkt") != "" && viper.GetString("firmware") != "" {
// Get files data struct
data = types.ReqDataFwUpgrade{
Type: types.UpgradeTypeFiles,
Files: []string{viper.GetString("initPkt"), viper.GetString("firmware")},
}
upgType = types.UpgradeTypeFiles
files = []string{viper.GetString("initPkt"), viper.GetString("firmware")}
} else {
cmd.Usage()
log.Warn().Msg("Upgrade command requires either archive or init packet and firmware.")
return
}
// Encode response into connection
err = json.NewEncoder(conn).Encode(types.Request{
Type: types.ReqTypeFwUpgrade,
Data: data,
})
progress, err := client.FirmwareUpgrade(upgType, files...)
if err != nil {
log.Fatal().Err(err).Msg("Error making request")
log.Fatal().Err(err).Msg("Error initiating DFU")
}
// Create progress bar template
@ -84,23 +67,7 @@ var upgradeCmd = &cobra.Command{
// Start full bar at 0 total
bar := pb.ProgressBarTemplate(barTmpl).Start(0)
// Create new scanner of connection
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
var res types.Response
// Decode scanned line into response struct
err = json.Unmarshal(scanner.Bytes(), &res)
if err != nil {
log.Fatal().Err(err).Msg("Error decoding JSON response")
}
if res.Error {
log.Fatal().Msg(res.Message)
}
var event DFUProgress
// Decode response data into progress struct
err = mapstructure.Decode(res.Value, &event)
if err != nil {
log.Fatal().Err(err).Msg("Error decoding response data")
}
for event := range progress {
// Set total bytes in progress bar
bar.SetTotal(event.Total)
// Set amount of bytes received in progress bar
@ -112,9 +79,6 @@ var upgradeCmd = &cobra.Command{
}
// Finish progress bar
bar.Finish()
if scanner.Err() != nil {
log.Fatal().Err(scanner.Err()).Msg("Error while scanning output")
}
},
}

View File

@ -19,15 +19,12 @@
package firmware
import (
"bufio"
"encoding/json"
"fmt"
"net"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.arsenm.dev/itd/internal/types"
"go.arsenm.dev/itd/api"
)
// versionCmd represents the version command
@ -36,40 +33,14 @@ var versionCmd = &cobra.Command{
Aliases: []string{"ver"},
Short: "Get firmware version of InfiniTime",
Run: func(cmd *cobra.Command, args []string) {
// Connect to itd UNIX socket
conn, err := net.Dial("unix", viper.GetString("sockPath"))
client := viper.Get("client").(*api.Client)
version, err := client.Version()
if err != nil {
log.Fatal().Err(err).Msg("Error dialing socket. Is itd running?")
}
defer conn.Close()
// Encode request into connection
err = json.NewEncoder(conn).Encode(types.Request{
Type: types.ReqTypeFwVersion,
})
if err != nil {
log.Fatal().Err(err).Msg("Error making request")
log.Fatal().Err(err).Msg("Error getting firmware version")
}
// Read one line from connection
line, _, err := bufio.NewReader(conn).ReadLine()
if err != nil {
log.Fatal().Err(err).Msg("Error reading line from connection")
}
var res types.Response
// Decode line into response
err = json.Unmarshal(line, &res)
if err != nil {
log.Fatal().Err(err).Msg("Error decoding JSON data")
}
if res.Error {
log.Fatal().Msg(res.Message)
}
// Print returned value
fmt.Println(res.Value)
fmt.Println(version)
},
}

View File

@ -19,15 +19,12 @@
package get
import (
"bufio"
"encoding/json"
"fmt"
"net"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.arsenm.dev/itd/internal/types"
"go.arsenm.dev/itd/api"
)
// addressCmd represents the address command
@ -36,40 +33,14 @@ var addressCmd = &cobra.Command{
Aliases: []string{"addr"},
Short: "Get InfiniTime's bluetooth address",
Run: func(cmd *cobra.Command, args []string) {
// Connect to itd UNIX socket
conn, err := net.Dial("unix", viper.GetString("sockPath"))
client := viper.Get("client").(*api.Client)
address, err := client.Address()
if err != nil {
log.Fatal().Err(err).Msg("Error dialing socket. Is itd running?")
}
defer conn.Close()
// Encode request into connection
err = json.NewEncoder(conn).Encode(types.Request{
Type: types.ReqTypeBtAddress,
})
if err != nil {
log.Fatal().Err(err).Msg("Error making request")
log.Fatal().Err(err).Msg("Error getting bluetooth address")
}
// Read one line from connection
line, _, err := bufio.NewReader(conn).ReadLine()
if err != nil {
log.Fatal().Err(err).Msg("Error reading line from connection")
}
var res types.Response
// Decode line into response
err = json.Unmarshal(line, &res)
if err != nil {
log.Fatal().Err(err).Msg("Error decoding JSON data")
}
if res.Error {
log.Fatal().Msg(res.Message)
}
// Print returned value
fmt.Println(res.Value)
fmt.Println(address)
},
}

View File

@ -19,15 +19,12 @@
package get
import (
"bufio"
"encoding/json"
"fmt"
"net"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.arsenm.dev/itd/internal/types"
"go.arsenm.dev/itd/api"
)
// batteryCmd represents the batt command
@ -36,40 +33,15 @@ var batteryCmd = &cobra.Command{
Aliases: []string{"batt"},
Short: "Get battery level from InfiniTime",
Run: func(cmd *cobra.Command, args []string) {
// Connect to itd UNIX socket
conn, err := net.Dial("unix", viper.GetString("sockPath"))
if err != nil {
log.Fatal().Err(err).Msg("Error dialing socket. Is itd running?")
}
defer conn.Close()
client := viper.Get("client").(*api.Client)
// Encode request into connection
err = json.NewEncoder(conn).Encode(types.Request{
Type: types.ReqTypeBattLevel,
})
battLevel, err := client.BatteryLevel()
if err != nil {
log.Fatal().Err(err).Msg("Error making request")
}
// Read one line from connection
line, _, err := bufio.NewReader(conn).ReadLine()
if err != nil {
log.Fatal().Err(err).Msg("Error reading line from connection")
}
var res types.Response
// Deocde line into response
err = json.Unmarshal(line, &res)
if err != nil {
log.Fatal().Err(err).Msg("Error decoding JSON data")
}
if res.Error {
log.Fatal().Msg(res.Message)
log.Fatal().Err(err).Msg("Error getting battery level")
}
// Print returned percentage
fmt.Printf("%d%%\n", int(res.Value.(float64)))
fmt.Printf("%d%%\n", battLevel)
},
}

View File

@ -19,15 +19,12 @@
package get
import (
"bufio"
"encoding/json"
"fmt"
"net"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.arsenm.dev/itd/internal/types"
"go.arsenm.dev/itd/api"
)
// heartCmd represents the heart command
@ -35,40 +32,15 @@ var heartCmd = &cobra.Command{
Use: "heart",
Short: "Get heart rate from InfiniTime",
Run: func(cmd *cobra.Command, args []string) {
// Connect to itd UNIX socket
conn, err := net.Dial("unix", viper.GetString("sockPath"))
if err != nil {
log.Fatal().Err(err).Msg("Error dialing socket. Is itd running?")
}
defer conn.Close()
client := viper.Get("client").(*api.Client)
// Encode request into connection
err = json.NewEncoder(conn).Encode(types.Request{
Type: types.ReqTypeHeartRate,
})
heartRate, err := client.HeartRate()
if err != nil {
log.Fatal().Err(err).Msg("Error making request")
}
// Read one line from connection
line, _, err := bufio.NewReader(conn).ReadLine()
if err != nil {
log.Fatal().Err(err).Msg("Error reading line from connection")
}
var res types.Response
// Decode line into response
err = json.Unmarshal(line, &res)
if err != nil {
log.Fatal().Err(err).Msg("Error decoding JSON data")
}
if res.Error {
log.Fatal().Msg(res.Message)
log.Fatal().Err(err).Msg("Error getting heart rate")
}
// Print returned BPM
fmt.Printf("%d BPM\n", int(res.Value.(float64)))
fmt.Printf("%d BPM\n", heartRate)
},
}

View File

@ -19,16 +19,12 @@
package get
import (
"bufio"
"encoding/json"
"fmt"
"net"
"github.com/mitchellh/mapstructure"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.arsenm.dev/itd/internal/types"
"go.arsenm.dev/itd/api"
)
// steps.goCmd represents the steps.go command
@ -36,42 +32,11 @@ var motionCmd = &cobra.Command{
Use: "motion",
Short: "Get motion values from InfiniTime",
Run: func(cmd *cobra.Command, args []string) {
// Connect to itd UNIX socket
conn, err := net.Dial("unix", viper.GetString("sockPath"))
if err != nil {
log.Fatal().Err(err).Msg("Error dialing socket. Is itd running?")
}
defer conn.Close()
client := viper.Get("client").(*api.Client)
// Encode request into connection
err = json.NewEncoder(conn).Encode(types.Request{
Type: types.ReqTypeMotion,
})
motionVals, err := client.Motion()
if err != nil {
log.Fatal().Err(err).Msg("Error making request")
}
// Read one line from connection
line, _, err := bufio.NewReader(conn).ReadLine()
if err != nil {
log.Fatal().Err(err).Msg("Error reading line from connection")
}
var res types.Response
// Decode line into response
err = json.Unmarshal(line, &res)
if err != nil {
log.Fatal().Err(err).Msg("Error decoding JSON data")
}
var motionVals types.MotionValues
err = mapstructure.Decode(res.Value, &motionVals)
if err != nil {
log.Fatal().Err(err).Msg("Error decoding motion values")
}
if res.Error {
log.Fatal().Msg(res.Message)
log.Fatal().Err(err).Msg("Error getting motion values")
}
if viper.GetBool("shell") {

View File

@ -19,15 +19,12 @@
package get
import (
"bufio"
"encoding/json"
"fmt"
"net"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.arsenm.dev/itd/internal/types"
"go.arsenm.dev/itd/api"
)
// steps.goCmd represents the steps.go command
@ -35,40 +32,15 @@ var stepsCmd = &cobra.Command{
Use: "steps",
Short: "Get step count from InfiniTime",
Run: func(cmd *cobra.Command, args []string) {
// Connect to itd UNIX socket
conn, err := net.Dial("unix", viper.GetString("sockPath"))
if err != nil {
log.Fatal().Err(err).Msg("Error dialing socket. Is itd running?")
}
defer conn.Close()
client := viper.Get("client").(*api.Client)
// Encode request into connection
err = json.NewEncoder(conn).Encode(types.Request{
Type: types.ReqTypeStepCount,
})
stepCount, err := client.StepCount()
if err != nil {
log.Fatal().Err(err).Msg("Error making request")
}
// Read one line from connection
line, _, err := bufio.NewReader(conn).ReadLine()
if err != nil {
log.Fatal().Err(err).Msg("Error reading line from connection")
}
var res types.Response
// Decode line into response
err = json.Unmarshal(line, &res)
if err != nil {
log.Fatal().Err(err).Msg("Error decoding JSON data")
}
if res.Error {
log.Fatal().Msg(res.Message)
log.Fatal().Err(err).Msg("Error getting step count")
}
// Print returned BPM
fmt.Printf("%d Steps\n", int(res.Value.(float64)))
fmt.Printf("%d Steps\n", stepCount)
},
}

View File

@ -19,15 +19,11 @@
package notify
import (
"bufio"
"encoding/json"
"net"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.arsenm.dev/itd/api"
"go.arsenm.dev/itd/cmd/itctl/root"
"go.arsenm.dev/itd/internal/types"
)
// notifyCmd represents the notify command
@ -41,40 +37,11 @@ var notifyCmd = &cobra.Command{
log.Fatal().Msg("Command notify requires two arguments")
}
// Connect to itd UNIX socket
conn, err := net.Dial("unix", viper.GetString("sockPath"))
if err != nil {
log.Fatal().Err(err).Msg("Error dialing socket. Is itd running?")
}
defer conn.Close()
client := viper.Get("client").(*api.Client)
// Encode request into connection
err = json.NewEncoder(conn).Encode(types.Request{
Type: types.ReqTypeNotify,
Data: types.ReqDataNotify{
Title: args[0],
Body: args[1],
},
})
err := client.Notify(args[0], args[1])
if err != nil {
log.Fatal().Err(err).Msg("Error making request")
}
// Read one line from connection
line, _, err := bufio.NewReader(conn).ReadLine()
if err != nil {
log.Fatal().Err(err).Msg("Error reading line from connection")
}
var res types.Response
// Decode line into response
err = json.Unmarshal(line, &res)
if err != nil {
log.Fatal().Err(err).Msg("Error decoding JSON data")
}
if res.Error {
log.Fatal().Msg(res.Message)
log.Fatal().Err(err).Msg("Error sending notification")
}
},
}

View File

@ -20,8 +20,10 @@ package root
import (
"github.com/abiosoft/ishell"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.arsenm.dev/itd/api"
)
// RootCmd represents the base command when called without any subcommands
@ -61,18 +63,25 @@ var RootCmd = &cobra.Command{
// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
client, err := api.New(viper.GetString("sockPath"))
if err != nil {
log.Fatal().Err(err).Msg("Error connecting to socket. Is itd running?")
}
defer client.Close()
viper.Set("client", client)
RootCmd.CompletionOptions.DisableDefaultCmd = true
cobra.CheckErr(RootCmd.Execute())
}
func init() {
// Register flag for socket path
RootCmd.Flags().StringP("socket-path", "s", "", "Path to itd socket")
RootCmd.Flags().StringP("socket-path", "s", api.DefaultAddr, "Path to itd socket")
// Bind flag and environment variable to viper key
viper.BindPFlag("sockPath", RootCmd.Flags().Lookup("socket-path"))
viper.BindEnv("sockPath", "ITCTL_SOCKET_PATH")
// Set default value for socket path
viper.SetDefault("sockPath", "/tmp/itd/socket")
viper.SetDefault("sockPath", api.DefaultAddr)
}