Use api package in itgui

This commit is contained in:
Elara 2021-10-24 13:27:14 -07:00
parent be5bdc625b
commit 76875db7ea
6 changed files with 73 additions and 158 deletions

View File

@ -48,7 +48,7 @@ func (c *Client) BatteryLevel() (uint8, error) {
func (c *Client) WatchBatteryLevel() (<-chan uint8, func(), error) { func (c *Client) WatchBatteryLevel() (<-chan uint8, func(), error) {
c.battLevelCh = make(chan types.Response, 2) c.battLevelCh = make(chan types.Response, 2)
err := c.requestNoRes(types.Request{ err := c.requestNoRes(types.Request{
Type: types.ReqTypeBattLevel, Type: types.ReqTypeWatchBattLevel,
}) })
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err

View File

@ -1,11 +1,9 @@
package main package main
import ( import (
"bufio"
"errors" "errors"
"fmt" "fmt"
"image/color" "image/color"
"net"
"encoding/json" "encoding/json"
@ -13,10 +11,11 @@ import (
"fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/theme"
"go.arsenm.dev/itd/api"
"go.arsenm.dev/itd/internal/types" "go.arsenm.dev/itd/internal/types"
) )
func infoTab(parent fyne.Window) *fyne.Container { func infoTab(parent fyne.Window, client *api.Client) *fyne.Container {
infoLayout := container.NewVBox( infoLayout := container.NewVBox(
// Add rectangle for a bit of padding // Add rectangle for a bit of padding
canvas.NewRectangle(color.Transparent), canvas.NewRectangle(color.Transparent),
@ -32,13 +31,18 @@ func infoTab(parent fyne.Window) *fyne.Container {
) )
infoLayout.Add(heartRate) infoLayout.Add(heartRate)
// Watch for heart rate updates fmt.Println(3)
go watch(types.ReqTypeWatchHeartRate, func(data interface{}) { heartRateCh, cancel, err := client.WatchHeartRate()
onClose = append(onClose, cancel)
go func() {
for heartRate := range heartRateCh {
// Change text of heart rate label // Change text of heart rate label
heartRateLbl.Text = fmt.Sprintf("%d BPM", int(data.(float64))) heartRateLbl.Text = fmt.Sprintf("%d BPM", heartRate)
// Refresh label // Refresh label
heartRateLbl.Refresh() heartRateLbl.Refresh()
}, parent) }
}()
fmt.Println(4)
// Create label for battery level // Create label for battery level
battLevelLbl := newText("0%", 24) battLevelLbl := newText("0%", 24)
@ -50,32 +54,43 @@ func infoTab(parent fyne.Window) *fyne.Container {
) )
infoLayout.Add(battLevel) infoLayout.Add(battLevel)
// Watch for changes in battery level fmt.Println(5)
go watch(types.ReqTypeWatchBattLevel, func(data interface{}) { battLevelCh, cancel, err := client.WatchBatteryLevel()
battLevelLbl.Text = fmt.Sprintf("%d%%", int(data.(float64))) onClose = append(onClose, cancel)
go func() {
for battLevel := range battLevelCh {
// Change text of battery level label
battLevelLbl.Text = fmt.Sprintf("%d%%", battLevel)
// Refresh label
battLevelLbl.Refresh() battLevelLbl.Refresh()
}, parent) }
}()
fmt.Println(6)
fwVerString, err := get(types.ReqTypeFwVersion) fmt.Println(7)
fwVerString, err := client.Version()
if err != nil { if err != nil {
guiErr(err, "Error getting firmware string", true, parent) guiErr(err, "Error getting firmware string", true, parent)
} }
fmt.Println(8)
fwVer := container.NewVBox( fwVer := container.NewVBox(
newText("Firmware Version", 12), newText("Firmware Version", 12),
newText(fwVerString.(string), 24), newText(fwVerString, 24),
canvas.NewLine(theme.ShadowColor()), canvas.NewLine(theme.ShadowColor()),
) )
infoLayout.Add(fwVer) infoLayout.Add(fwVer)
btAddrString, err := get(types.ReqTypeBtAddress) fmt.Println(9)
btAddrString, err := client.Address()
if err != nil { if err != nil {
panic(err) panic(err)
} }
fmt.Println(10)
btAddr := container.NewVBox( btAddr := container.NewVBox(
newText("Bluetooth Address", 12), newText("Bluetooth Address", 12),
newText(btAddrString.(string), 24), newText(btAddrString, 24),
canvas.NewLine(theme.ShadowColor()), canvas.NewLine(theme.ShadowColor()),
) )
infoLayout.Add(btAddr) infoLayout.Add(btAddr)
@ -83,53 +98,6 @@ func infoTab(parent fyne.Window) *fyne.Container {
return infoLayout return infoLayout
} }
func watch(req int, onRecv func(data interface{}), parent fyne.Window) error {
conn, err := net.Dial("unix", SockPath)
if err != nil {
return err
}
defer conn.Close()
err = json.NewEncoder(conn).Encode(types.Request{
Type: req,
})
if err != nil {
return err
}
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
res, err := getResp(scanner.Bytes())
if err != nil {
guiErr(err, "Error getting response from connection", false, parent)
continue
}
onRecv(res.Value)
}
return nil
}
func get(req int) (interface{}, error) {
conn, err := net.Dial("unix", SockPath)
if err != nil {
return nil, err
}
defer conn.Close()
err = json.NewEncoder(conn).Encode(types.Request{
Type: req,
})
if err != nil {
return nil, err
}
line, _, err := bufio.NewReader(conn).ReadLine()
if err != nil {
return nil, err
}
res, err := getResp(line)
if err != nil {
return nil, err
}
return res.Value, nil
}
func getResp(line []byte) (*types.Response, error) { func getResp(line []byte) (*types.Response, error) {
var res types.Response var res types.Response
err := json.Unmarshal(line, &res) err := json.Unmarshal(line, &res)

View File

@ -1,31 +1,42 @@
package main package main
import ( import (
"net" "fmt"
"fyne.io/fyne/v2/app" "fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"go.arsenm.dev/itd/api"
) )
var SockPath = "/tmp/itd/socket" var onClose []func()
func main() { func main() {
// Create new app // Create new app
a := app.New() a := app.New()
// Create new window with title "itgui" // Create new window with title "itgui"
window := a.NewWindow("itgui") window := a.NewWindow("itgui")
window.SetOnClosed(func() {
_, err := net.Dial("unix", SockPath) for _, closeFn := range onClose {
if err != nil { closeFn()
guiErr(err, "Error dialing itd socket", true, window)
} }
})
fmt.Println(1)
client, err := api.New(api.DefaultAddr)
if err != nil {
guiErr(err, "Error connecting to itd", true, window)
}
onClose = append(onClose, func() {
client.Close()
})
fmt.Println(2)
// Create new app tabs container // Create new app tabs container
tabs := container.NewAppTabs( tabs := container.NewAppTabs(
container.NewTabItem("Info", infoTab(window)), container.NewTabItem("Info", infoTab(window, client)),
container.NewTabItem("Notify", notifyTab(window)), container.NewTabItem("Notify", notifyTab(window, client)),
container.NewTabItem("Set Time", timeTab(window)), container.NewTabItem("Set Time", timeTab(window, client)),
container.NewTabItem("Upgrade", upgradeTab(window)), container.NewTabItem("Upgrade", upgradeTab(window, client)),
) )
// Set tabs as window content // Set tabs as window content

View File

@ -1,17 +1,14 @@
package main package main
import ( import (
"encoding/json"
"net"
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"go.arsenm.dev/itd/internal/types" "go.arsenm.dev/itd/api"
) )
func notifyTab(parent fyne.Window) *fyne.Container { func notifyTab(parent fyne.Window, client *api.Client) *fyne.Container {
// Create new entry for notification title // Create new entry for notification title
titleEntry := widget.NewEntry() titleEntry := widget.NewEntry()
titleEntry.SetPlaceHolder("Title") titleEntry.SetPlaceHolder("Title")
@ -22,20 +19,11 @@ func notifyTab(parent fyne.Window) *fyne.Container {
// Create new button to send notification // Create new button to send notification
sendBtn := widget.NewButton("Send", func() { sendBtn := widget.NewButton("Send", func() {
// Dial itd UNIX socket err := client.Notify(titleEntry.Text, bodyEntry.Text)
conn, err := net.Dial("unix", SockPath)
if err != nil { if err != nil {
guiErr(err, "Error dialing socket", false, parent) guiErr(err, "Error sending notification", false, parent)
return return
} }
// Encode notify request on connection
json.NewEncoder(conn).Encode(types.Request{
Type: types.ReqTypeNotify,
Data: types.ReqDataNotify{
Title: titleEntry.Text,
Body: bodyEntry.Text,
},
})
}) })
// Return new container containing all elements // Return new container containing all elements

View File

@ -1,18 +1,16 @@
package main package main
import ( import (
"encoding/json"
"net"
"time" "time"
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"go.arsenm.dev/itd/internal/types" "go.arsenm.dev/itd/api"
) )
func timeTab(parent fyne.Window) *fyne.Container { func timeTab(parent fyne.Window, client *api.Client) *fyne.Container {
// Create new entry for time string // Create new entry for time string
timeEntry := widget.NewEntry() timeEntry := widget.NewEntry()
// Set text to current time formatter properly // Set text to current time formatter properly
@ -21,7 +19,7 @@ func timeTab(parent fyne.Window) *fyne.Container {
// Create button to set current time // Create button to set current time
currentBtn := widget.NewButton("Set Current", func() { currentBtn := widget.NewButton("Set Current", func() {
timeEntry.SetText(time.Now().Format(time.RFC1123)) timeEntry.SetText(time.Now().Format(time.RFC1123))
setTime(true) setTime(client, true)
}) })
// Create button to set time inside entry // Create button to set time inside entry
@ -33,7 +31,7 @@ func timeTab(parent fyne.Window) *fyne.Container {
return return
} }
// Set time to parsed time // Set time to parsed time
setTime(false, parsedTime) setTime(client, false, parsedTime)
}) })
// Return new container with all elements centered // Return new container with all elements centered
@ -48,30 +46,13 @@ func timeTab(parent fyne.Window) *fyne.Container {
// setTime sets the first element in the variadic parameter // setTime sets the first element in the variadic parameter
// if current is false, otherwise, it sets the current time. // if current is false, otherwise, it sets the current time.
func setTime(current bool, t ...time.Time) error { func setTime(client *api.Client, current bool, t ...time.Time) error {
// Dial UNIX socket var err error
conn, err := net.Dial("unix", SockPath)
if err != nil {
return err
}
defer conn.Close()
var data string
// If current is true, use the string "now"
// otherwise, use the formatted time from the
// first element in the variadic parameter.
// "now" is more accurate than formatting
// current time as only seconds are preserved
// in that case.
if current { if current {
data = "now" err = client.SetTimeNow()
} else { } else {
data = t[0].Format(time.RFC3339) err = client.SetTime(t[0])
} }
// Encode SetTime request with above data
err = json.NewEncoder(conn).Encode(types.Request{
Type: types.ReqTypeSetTime,
Data: data,
})
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,10 +1,7 @@
package main package main
import ( import (
"bufio"
"encoding/json"
"fmt" "fmt"
"net"
"path/filepath" "path/filepath"
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
@ -13,11 +10,11 @@ import (
"fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/storage" "fyne.io/fyne/v2/storage"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"github.com/mitchellh/mapstructure" "go.arsenm.dev/itd/api"
"go.arsenm.dev/itd/internal/types" "go.arsenm.dev/itd/internal/types"
) )
func upgradeTab(parent fyne.Window) *fyne.Container { func upgradeTab(parent fyne.Window, client *api.Client) *fyne.Container {
var ( var (
archivePath string archivePath string
firmwarePath string firmwarePath string
@ -117,7 +114,7 @@ func upgradeTab(parent fyne.Window) *fyne.Container {
// Resize modal to 300x100 // Resize modal to 300x100
progressDlg.Resize(fyne.NewSize(300, 100)) progressDlg.Resize(fyne.NewSize(300, 100))
var fwUpgType int var fwUpgType api.UpgradeType
var files []string var files []string
// Get appropriate upgrade type and file paths // Get appropriate upgrade type and file paths
switch upgradeTypeSelect.Selected { switch upgradeTypeSelect.Selected {
@ -129,48 +126,18 @@ func upgradeTab(parent fyne.Window) *fyne.Container {
files = append(files, initPktPath, firmwarePath) files = append(files, initPktPath, firmwarePath)
} }
// Dial itd UNIX socket progress, err := client.FirmwareUpgrade(fwUpgType, files...)
conn, err := net.Dial("unix", SockPath)
if err != nil { if err != nil {
guiErr(err, "Error dialing socket", false, parent) guiErr(err, "Error initiating DFU", false, parent)
return return
} }
defer conn.Close()
// Encode firmware upgrade request to connection
json.NewEncoder(conn).Encode(types.Request{
Type: types.ReqTypeFwUpgrade,
Data: types.ReqDataFwUpgrade{
Type: fwUpgType,
Files: files,
},
})
// Show progress dialog // Show progress dialog
progressDlg.Show() progressDlg.Show()
// Hide progress dialog after completion // Hide progress dialog after completion
defer progressDlg.Hide() defer progressDlg.Hide()
scanner := bufio.NewScanner(conn) for event := range progress {
for scanner.Scan() {
var res types.Response
// Decode scanned line into response struct
err = json.Unmarshal(scanner.Bytes(), &res)
if err != nil {
guiErr(err, "Error decoding response", false, parent)
return
}
if res.Error {
guiErr(err, "Error returned in response", false, parent)
return
}
var event types.DFUProgress
// Decode response data into progress struct
err = mapstructure.Decode(res.Value, &event)
if err != nil {
guiErr(err, "Error decoding response value", false, parent)
return
}
// Set label text to received / total B // Set label text to received / total B
progressLbl.SetText(fmt.Sprintf("%d / %d B", event.Received, event.Total)) progressLbl.SetText(fmt.Sprintf("%d / %d B", event.Received, event.Total))
// Set progress bar values // Set progress bar values
@ -179,7 +146,7 @@ func upgradeTab(parent fyne.Window) *fyne.Container {
// Refresh progress bar // Refresh progress bar
progressBar.Refresh() progressBar.Refresh()
// If transfer finished, break // If transfer finished, break
if event.Received == event.Total { if event.Sent == event.Total {
break break
} }
} }