Package gfit: Include the DataStreamName in the DataStreadID.
[kraftakt.git] / gfit / gfit.go
index fcd88f1..581a9fe 100644 (file)
@@ -3,7 +3,6 @@ package gfit
 import (
        "context"
        "fmt"
-       "math"
        "net/http"
        "strings"
        "time"
@@ -23,6 +22,7 @@ const (
        userID    = "me"
 
        dataTypeNameCalories  = "com.google.calories.expended"
+       dataTypeNameDistance  = "com.google.distance.delta"
        dataTypeNameSteps     = "com.google.step_count.delta"
        dataTypeNameHeartrate = "com.google.heart_rate.summary"
 )
@@ -35,6 +35,7 @@ var oauthConfig = &oauth2.Config{
        Scopes: []string{
                fitness.FitnessActivityWriteScope,
                fitness.FitnessBodyWriteScope,
+               fitness.FitnessLocationWriteScope,
        },
 }
 
@@ -102,6 +103,10 @@ func DataStreamID(dataSource *fitness.DataSource) string {
                }
        }
 
+       if dataSource.DataStreamName != "" {
+               fields = append(fields, dataSource.DataStreamName)
+       }
+
        return strings.Join(fields, ":")
 }
 
@@ -147,6 +152,28 @@ func (c *Client) DataSetPatch(ctx context.Context, dataSourceID string, points [
        return nil
 }
 
+func (c *Client) SetDistance(ctx context.Context, meters float64, startOfDay time.Time) error {
+       return c.updateCumulative(ctx,
+               &fitness.DataSource{
+                       Application: Application(ctx),
+                       DataType: &fitness.DataType{
+                               Field: []*fitness.DataTypeField{
+                                       &fitness.DataTypeField{
+                                               Name:   "distance",
+                                               Format: "floatPoint",
+                                       },
+                               },
+                               Name: dataTypeNameDistance,
+                       },
+                       Name: "Distance covered",
+                       Type: "raw",
+               },
+               &fitness.Value{
+                       FpVal: meters,
+               },
+               startOfDay)
+}
+
 func (c *Client) SetSteps(ctx context.Context, totalSteps int, startOfDay time.Time) error {
        return c.updateCumulative(ctx,
                &fitness.DataSource{
@@ -344,7 +371,7 @@ func (c *Client) heartRate(ctx context.Context, dataSource *fitness.DataSource,
        return results, maxEndTime, nil
 }
 
-func (c *Client) SetHeartRate(ctx context.Context, totalDurations []fitbit.HeartRateZone, startOfDay time.Time) error {
+func (c *Client) SetHeartRate(ctx context.Context, totalDurations []fitbit.HeartRateZone, restingHeartRate int, startOfDay time.Time) error {
        dataSource := &fitness.DataSource{
                Application: Application(ctx),
                DataType: &fitness.DataType{
@@ -417,13 +444,18 @@ func (c *Client) SetHeartRate(ctx context.Context, totalDurations []fitbit.Heart
                        break
                }
 
+               average := float64(d.Min+d.Max) / 2.0
+               if d.Min <= restingHeartRate && restingHeartRate <= d.Max {
+                       average = float64(restingHeartRate)
+               }
+
                dataPoints = append(dataPoints, &fitness.DataPoint{
                        DataTypeName:   dataSource.DataType.Name,
                        StartTimeNanos: startTime.UnixNano(),
                        EndTimeNanos:   endTime.UnixNano(),
                        Value: []*fitness.Value{
                                &fitness.Value{
-                                       FpVal: math.NaN(),
+                                       FpVal: average,
                                },
                                &fitness.Value{
                                        FpVal: float64(d.Max),