Announcement

Collapse
No announcement yet.

C# integration with Garmin Connect

Collapse
X
  • Time
  • Show
Clear All
new posts

  • C# integration with Garmin Connect

    We were looking for a solution to taking and analysing information posted to Garmin connect for a project. Garmin have not released any sort of web service interface for garmin connect so quite a challenge to get that information. Listed below is the C# code (still a bit rough) that logs in to Garmin and uses the activity-search rest services to receive information:

    Login Method:

    private CookieContainer LoginGRMN(string loginURL,string userName,string password)
    {
    CookieContainer cookiJar = new CookieContainer();
    string loginResponse = "";
    try
    {
    HttpWebRequest getLogin = (HttpWebRequest)HttpWebRequest.Create(loginURL.Replace("https://", "http://"));
    getLogin.Method = "GET";
    getLogin.CookieContainer = cookiJar;
    getLogin.KeepAlive = true;
    var getLoginResp = getLogin.GetResponse();

    HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(loginURL);
    httpRequest.Method = "POST";
    httpRequest.ContentType = "application/x-www-form-urlencoded";
    httpRequest.CookieContainer = cookiJar;
    httpRequest.KeepAlive = true;

    string formData = string.Format("login=login&login%3AloginUsernameField={0}&login%3Apassword={1}&login%3AsignInButton= Sign+In&login%3ArememberMe=false&javax.faces.ViewState=j_id1", HttpUtility.UrlEncode(userName), HttpUtility.UrlEncode(password));

    byte[] bytedata = Encoding.ASCII.GetBytes(formData);
    httpRequest.ContentLength = bytedata.Length;
    Stream requestStream = httpRequest.GetRequestStream();
    requestStream.Write(bytedata, 0, bytedata.Length);
    requestStream.Flush();
    requestStream.Close();

    HttpWebResponse logResponse = (HttpWebResponse)httpRequest.GetResponse();

    Encoding enc = System.Text.Encoding.GetEncoding(1252);
    StreamReader loResponseStream = new
    StreamReader(logResponse.GetResponseStream(), enc);

    loginResponse= loResponseStream.ReadToEnd();
    }
    catch (Exception exp)
    {
    throw new Exception("Error connecting to Garmin Connect for login", exp);
    }
    if (loginResponse.Contains("login:loginUsernameField"))
    {
    throw new Exception("Error logging in to Garmin Connect");
    }


    return cookiJar;
    }

    Search activities method using the JSON response:


    public List<Domain.IntegrationActivity> SearchActivities(Domain.ActivitySearchDetails activitySearch)
    {
    //login to Garmin Connect
    var cookiJar= LoginGRMN(activitySearch.LoginURL, activitySearch.Username, activitySearch.Password);

    //load activities
    string url = activitySearch.ActionURL + "?beginTimestamp>" + activitySearch.FromDate.ToString("s");
    HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);

    req.CookieContainer = cookiJar;
    req.Method = "GET";
    var grmnResponse = req.GetResponse();

    Encoding enc = System.Text.Encoding.GetEncoding(1252);
    StreamReader loResponseStream = new
    StreamReader(grmnResponse.GetResponseStream(), enc);

    string grmnXML = loResponseStream.ReadToEnd();

    //deserialize the JSON response
    var reader = new JsonReader();
    dynamic output = reader.Read(grmnXML);

    if (!PropertyExists("results",output))
    {
    throw new Exception("Error on Garmin Json response");
    }

    //return object
    List<Domain.IntegrationActivity> returnAct = new List<Domain.IntegrationActivity>();
    foreach (dynamic activity in output.results.activities)
    {
    DateTime captureDate = DateTime.Parse(activity.activity.uploadDate.display);


    Domain.IntegrationActivity retActivity = new Domain.IntegrationActivity()
    {
    ActivityReference = activity.activity.activityId,
    CaptureDate =captureDate,
    Calories = PropertyExists("activitySummarySumEnergy", activity.activity) ? int.Parse(activity.activity.activitySummarySumEnergy.display) : 0,
    StartTime =PropertyExists("activitySummaryBeginTimestamp", activity.activity)? DateTime.Parse(activity.activity.activitySummaryBeginTimestamp.display): new DateTime(captureDate.Year,captureDate.Month,captureDate.Day,0,0,0),
    EndTime = PropertyExists("activitySummaryEndTimestamp", activity.activity) ? DateTime.Parse(activity.activity.activitySummaryEndTimestamp.display) : new DateTime(captureDate.Year, captureDate.Month, captureDate.Day, 0, 0, 0),
    Factors = new List<Domain.ActivityFactor>()
    };

    //ADD other factors
    retActivity.Factors.Add(new Domain.ActivityFactor() { Name = "ActivityName", Value = PropertyExists("activityName",activity.activity)?activity.activity.activityName.value:"" });
    retActivity.Factors.Add(new Domain.ActivityFactor() { Name = "ActivityType", Value = PropertyExists("activityType", activity.activity) ? activity.activity.activityType.display : "" });
    retActivity.Factors.Add(new Domain.ActivityFactor() { Name = "Distance", Value = PropertyExists("activitySummarySumDistance", activity.activity) ? activity.activity.activitySummarySumDistance.value : "0" });
    retActivity.Factors.Add(new Domain.ActivityFactor() { Name = "Duration", Value = PropertyExists("activitySummarySumDuration", activity.activity) ? activity.activity.activitySummarySumDuration.minutesSeconds : "0" });
    retActivity.Factors.Add(new Domain.ActivityFactor() { Name = "AverageSpeed", Value = PropertyExists("activitySummaryWeightedMeanSpeed", activity.activity) ? activity.activity.activitySummaryWeightedMeanSpeed.withUnitAbbr : "0" });
    retActivity.Factors.Add(new Domain.ActivityFactor() { Name = "MaxHeartRate", Value = PropertyExists("activitySummaryMaxHeartRate", activity.activity) ? activity.activity.activitySummaryMaxHeartRate.value : "0" });
    retActivity.Factors.Add(new Domain.ActivityFactor() { Name = "MinHeartRate", Value = PropertyExists("activitySummaryMinHeartRate", activity.activity) ? activity.activity.activitySummaryMinHeartRate.value : "0" });
    retActivity.Factors.Add(new Domain.ActivityFactor() { Name = "AverageHeartRate", Value = PropertyExists("activitySummaryWeightedMeanHeartRate", activity.activity) ? activity.activity.activitySummaryWeightedMeanHeartRate.value : "0" });




    returnAct.Add(retActivity);

    }


    return returnAct;
    }


    private bool PropertyExists(string name,ExpandoObject obj)
    {
    return((IDictionary<String, Object>)obj).ContainsKey(name);
    }


    Hope this helps someone

    Sincerely

    Martin Naude

  • #2
    Interesting, thanks for posting. Am I right to assume your project references the DLLs in Garmin's API? I downloaded the API months ago but haven't had the chance to use it yet.

    For my personal project (also written in C#), I just export and use the TCX file and use this as my input data source.

    Comment


    • #3
      please send me your code

      would you mind sharing your project file?
      email me to adammendoza => hotmail

      thanks!
      Adam J. Mendoza
      swim - bike - run
      I will love thee, O LORD, my strength.

      Comment


      • #4
        With full credit to Martin Naude and his generous code sample above, I created a more complete utility based on it, which I've made public (and I plan to share the source code on GitHub for those interested). In the mean-time, I've described it on my blog:

        Garcon Utility

        David Jacobson

        Comment


        • #5
          Thanks for this nice coding sample

          Thanks for sharing this sample. Trying to integrate this into my own test app I bumped into two (newbie) questions.

          1) What's this actionURL used?
          2) Where does the Domain.IntegrationActivity come from? I can't seem to find this class anywhere.

          Thanks in advance,
          Bart

          Comment


          • #6
            Hello,
            I want to get client garmin device data from health api using c# application. I try to use garmin connect dll but it did not worked. Also I have created a method to get request token as described in api document but I am getting error method not allowed even its POST request.

            Please suggest or provide some reference code in order to retrieve data.

            Thanks,

            Comment

            Working...
            X