103 lines
2.0 KiB
Go
103 lines
2.0 KiB
Go
package api
|
|
|
|
import (
|
|
"bufio"
|
|
"encoding/json"
|
|
"errors"
|
|
"net"
|
|
|
|
"github.com/mitchellh/mapstructure"
|
|
"go.arsenm.dev/infinitime"
|
|
"go.arsenm.dev/itd/internal/types"
|
|
)
|
|
|
|
const DefaultAddr = "/tmp/itd/socket"
|
|
|
|
type Client struct {
|
|
conn net.Conn
|
|
respCh chan types.Response
|
|
heartRateCh chan uint8
|
|
battLevelCh chan uint8
|
|
stepCountCh chan uint32
|
|
motionCh chan infinitime.MotionValues
|
|
dfuProgressCh chan DFUProgress
|
|
}
|
|
|
|
func New(addr string) (*Client, error) {
|
|
conn, err := net.Dial("unix", addr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
out := &Client{
|
|
conn: conn,
|
|
respCh: make(chan types.Response, 5),
|
|
}
|
|
|
|
go func() {
|
|
scanner := bufio.NewScanner(conn)
|
|
for scanner.Scan() {
|
|
var res types.Response
|
|
err = json.Unmarshal(scanner.Bytes(), &res)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
out.handleResp(res)
|
|
}
|
|
}()
|
|
return out, err
|
|
}
|
|
|
|
func (c *Client) request(req types.Request) (types.Response, error) {
|
|
// Encode request into connection
|
|
err := json.NewEncoder(c.conn).Encode(req)
|
|
if err != nil {
|
|
return types.Response{}, err
|
|
}
|
|
|
|
res := <-c.respCh
|
|
|
|
if res.Error {
|
|
return res, errors.New(res.Message)
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func (c *Client) requestNoRes(req types.Request) error {
|
|
// Encode request into connection
|
|
err := json.NewEncoder(c.conn).Encode(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *Client) handleResp(res types.Response) error {
|
|
switch res.Type {
|
|
case types.ResTypeWatchHeartRate:
|
|
c.heartRateCh <- uint8(res.Value.(float64))
|
|
case types.ResTypeWatchBattLevel:
|
|
c.battLevelCh <- uint8(res.Value.(float64))
|
|
case types.ResTypeWatchStepCount:
|
|
c.stepCountCh <- uint32(res.Value.(float64))
|
|
case types.ResTypeWatchMotion:
|
|
out := infinitime.MotionValues{}
|
|
err := mapstructure.Decode(res.Value, &out)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
c.motionCh <- out
|
|
case types.ResTypeDFUProgress:
|
|
out := DFUProgress{}
|
|
err := mapstructure.Decode(res.Value, &out)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
c.dfuProgressCh <- out
|
|
default:
|
|
c.respCh <- res
|
|
}
|
|
return nil
|
|
}
|