mirror of
https://github.com/sstent/go-garth-cli.git
synced 2025-12-06 08:02:01 +00:00
114 lines
3.0 KiB
Go
114 lines
3.0 KiB
Go
package data
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"sort"
|
|
"time"
|
|
|
|
types "github.com/sstent/go-garth/models/types"
|
|
shared "github.com/sstent/go-garth-cli/shared/interfaces"
|
|
)
|
|
|
|
// BodyBatteryReading represents a single body battery data point
|
|
type BodyBatteryReading struct {
|
|
Timestamp int `json:"timestamp"`
|
|
Status string `json:"status"`
|
|
Level int `json:"level"`
|
|
Version float64 `json:"version"`
|
|
}
|
|
|
|
// ParseBodyBatteryReadings converts body battery values array to structured readings
|
|
func ParseBodyBatteryReadings(valuesArray [][]any) []BodyBatteryReading {
|
|
readings := make([]BodyBatteryReading, 0)
|
|
for _, values := range valuesArray {
|
|
if len(values) < 4 {
|
|
continue
|
|
}
|
|
|
|
timestamp, ok1 := values[0].(float64)
|
|
status, ok2 := values[1].(string)
|
|
level, ok3 := values[2].(float64)
|
|
version, ok4 := values[3].(float64)
|
|
|
|
if !ok1 || !ok2 || !ok3 || !ok4 {
|
|
continue
|
|
}
|
|
|
|
readings = append(readings, BodyBatteryReading{
|
|
Timestamp: int(timestamp),
|
|
Status: status,
|
|
Level: int(level),
|
|
Version: version,
|
|
})
|
|
}
|
|
sort.Slice(readings, func(i, j int) bool {
|
|
return readings[i].Timestamp < readings[j].Timestamp
|
|
})
|
|
return readings
|
|
}
|
|
|
|
// BodyBatteryDataWithMethods embeds types.DetailedBodyBatteryData and adds methods
|
|
type BodyBatteryDataWithMethods struct {
|
|
types.DetailedBodyBatteryData
|
|
}
|
|
|
|
func (d *BodyBatteryDataWithMethods) Get(day time.Time, c shared.APIClient) (interface{}, error) {
|
|
dateStr := day.Format("2006-01-02")
|
|
|
|
// Get main Body Battery data
|
|
path1 := fmt.Sprintf("/wellness-service/wellness/dailyStress/%s", dateStr)
|
|
data1, err := c.ConnectAPI(path1, "GET", nil, nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get Body Battery stress data: %w", err)
|
|
}
|
|
|
|
// Get Body Battery events
|
|
path2 := fmt.Sprintf("/wellness-service/wellness/bodyBattery/%s", dateStr)
|
|
data2, err := c.ConnectAPI(path2, "GET", nil, nil)
|
|
if err != nil {
|
|
// Events might not be available, continue without them
|
|
data2 = []byte("[]")
|
|
}
|
|
|
|
var result types.DetailedBodyBatteryData
|
|
if len(data1) > 0 {
|
|
if err := json.Unmarshal(data1, &result); err != nil {
|
|
return nil, fmt.Errorf("failed to parse Body Battery data: %w", err)
|
|
}
|
|
}
|
|
|
|
var events []types.BodyBatteryEvent
|
|
if len(data2) > 0 {
|
|
if err := json.Unmarshal(data2, &events); err == nil {
|
|
result.Events = events
|
|
}
|
|
}
|
|
|
|
return &BodyBatteryDataWithMethods{DetailedBodyBatteryData: result}, nil
|
|
}
|
|
|
|
// GetCurrentLevel returns the most recent Body Battery level
|
|
func (d *BodyBatteryDataWithMethods) GetCurrentLevel() int {
|
|
if len(d.BodyBatteryValuesArray) == 0 {
|
|
return 0
|
|
}
|
|
|
|
readings := ParseBodyBatteryReadings(d.BodyBatteryValuesArray)
|
|
if len(readings) == 0 {
|
|
return 0
|
|
}
|
|
|
|
return readings[len(readings)-1].Level
|
|
}
|
|
|
|
// GetDayChange returns the Body Battery change for the day
|
|
func (d *BodyBatteryDataWithMethods) GetDayChange() int {
|
|
readings := ParseBodyBatteryReadings(d.BodyBatteryValuesArray)
|
|
if len(readings) < 2 {
|
|
return 0
|
|
}
|
|
|
|
return readings[len(readings)-1].Level - readings[0].Level
|
|
}
|