Files
go-garth/internal/data/body_battery.go
sstent c1993ba022 fix: resolve build errors and implement missing health data types
- Fix various build errors in the CLI application.
- Implement missing health data types (VO2 Max, Heart Rate Zones).
- Corrected `tablewriter` usage from `SetHeader` to `Header`.
- Removed unused imports and fixed syntax errors.
2025-09-19 05:19:02 -07:00

139 lines
4.3 KiB
Go

package data
import (
"encoding/json"
"fmt"
"sort"
"time"
"go-garth/internal/api/client"
)
// DailyBodyBatteryStress represents complete daily Body Battery and stress data
type DailyBodyBatteryStress struct {
UserProfilePK int `json:"userProfilePk"`
CalendarDate time.Time `json:"calendarDate"`
StartTimestampGMT time.Time `json:"startTimestampGmt"`
EndTimestampGMT time.Time `json:"endTimestampGmt"`
StartTimestampLocal time.Time `json:"startTimestampLocal"`
EndTimestampLocal time.Time `json:"endTimestampLocal"`
MaxStressLevel int `json:"maxStressLevel"`
AvgStressLevel int `json:"avgStressLevel"`
StressChartValueOffset int `json:"stressChartValueOffset"`
StressChartYAxisOrigin int `json:"stressChartYAxisOrigin"`
StressValuesArray [][]int `json:"stressValuesArray"`
BodyBatteryValuesArray [][]any `json:"bodyBatteryValuesArray"`
}
// BodyBatteryEvent represents a Body Battery impact event
type BodyBatteryEvent struct {
EventType string `json:"eventType"`
EventStartTimeGMT time.Time `json:"eventStartTimeGmt"`
TimezoneOffset int `json:"timezoneOffset"`
DurationInMilliseconds int `json:"durationInMilliseconds"`
BodyBatteryImpact int `json:"bodyBatteryImpact"`
FeedbackType string `json:"feedbackType"`
ShortFeedback string `json:"shortFeedback"`
}
// BodyBatteryData represents legacy Body Battery events data
type BodyBatteryData struct {
Event *BodyBatteryEvent `json:"event"`
ActivityName string `json:"activityName"`
ActivityType string `json:"activityType"`
ActivityID string `json:"activityId"`
AverageStress float64 `json:"averageStress"`
StressValuesArray [][]int `json:"stressValuesArray"`
BodyBatteryValuesArray [][]any `json:"bodyBatteryValuesArray"`
}
// BodyBatteryReading represents an individual Body Battery reading
type BodyBatteryReading struct {
Timestamp int `json:"timestamp"`
Status string `json:"status"`
Level int `json:"level"`
Version float64 `json:"version"`
}
// StressReading represents an individual stress reading
type StressReading struct {
Timestamp int `json:"timestamp"`
StressLevel int `json:"stressLevel"`
}
// 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].(int)
status, ok2 := values[1].(string)
level, ok3 := values[2].(int)
version, ok4 := values[3].(float64)
if !ok1 || !ok2 || !ok3 || !ok4 {
continue
}
readings = append(readings, BodyBatteryReading{
Timestamp: timestamp,
Status: status,
Level: level,
Version: version,
})
}
sort.Slice(readings, func(i, j int) bool {
return readings[i].Timestamp < readings[j].Timestamp
})
return readings
}
// ParseStressReadings converts stress values array to structured readings
func ParseStressReadings(valuesArray [][]int) []StressReading {
readings := make([]StressReading, 0)
for _, values := range valuesArray {
if len(values) != 2 {
continue
}
readings = append(readings, StressReading{
Timestamp: values[0],
StressLevel: values[1],
})
}
sort.Slice(readings, func(i, j int) bool {
return readings[i].Timestamp < readings[j].Timestamp
})
return readings
}
// Get implements the Data interface for DailyBodyBatteryStress
func (d *DailyBodyBatteryStress) Get(day time.Time, client *client.Client) (any, error) {
dateStr := day.Format("2006-01-02")
path := fmt.Sprintf("/wellness-service/wellness/dailyStress/%s", dateStr)
data, err := client.ConnectAPI(path, "GET", nil, nil)
if err != nil {
return nil, err
}
if len(data) == 0 {
return nil, nil
}
var result DailyBodyBatteryStress
if err := json.Unmarshal(data, &result); err != nil {
return nil, err
}
return &result, nil
}
// List implements the Data interface for concurrent fetching
func (d *DailyBodyBatteryStress) List(end time.Time, days int, client *client.Client, maxWorkers int) ([]any, error) {
// Implementation to be added
return []any{}, nil
}