diff --git a/cmd/prime.go b/cmd/prime.go index 9a03462..8ba4da1 100644 --- a/cmd/prime.go +++ b/cmd/prime.go @@ -135,9 +135,11 @@ GOTCHAS (250ms between calls); ad-hoc loops should do the same. - Sleep score and apnea fields are populated only on supported devices. 'data.sleep_score' is null on unsupported wakeup-light models. - - 'workouts' category codes are integers; common ones are mapped to - string names (walk/run/bicycling/...) but unknown codes pass through - as 'unknown' with the numeric category_code preserved. + - 'workouts' category is a Withings integer code in JSON (1=walk, + 2=run, 6=bicycling, 16=lift_weights, ...). Markdown and CSV map + common codes to string names ('lift_weights', 'walk', ...) and + unknown codes render as 'unknown'; CSV also keeps the raw integer + in a 'category_code' column. ` var primeCmd = &cobra.Command{ diff --git a/cmd/shared.go b/cmd/shared.go index 69f821a..cb29751 100644 --- a/cmd/shared.go +++ b/cmd/shared.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "os" + "reflect" "strconv" "strings" "time" @@ -108,6 +109,12 @@ func untilDayOrToday(s string) (time.Time, error) { } func printJSON(v any) error { + // A nil slice marshals as "null"; force "[]" so empty windows match the + // prime contract (and don't blow up jq pipelines). + if rv := reflect.ValueOf(v); rv.Kind() == reflect.Slice && rv.IsNil() { + _, err := os.Stdout.WriteString("[]\n") + return err + } enc := json.NewEncoder(os.Stdout) enc.SetIndent("", " ") if err := enc.Encode(v); err != nil {