TcxBase * Edge305Device::readFitnessDataFromGarmin() { TcxBase * fitData = NULL; garmin_unit garmin; garmin_data * data0; garmin_data * data1; garmin_data * data2; garmin_list * runs = NULL; garmin_list * laps = NULL; garmin_list * tracks = NULL; if ( garmin_init(&garmin,0) != 0 ) { Log::dbg("Extracting data from Garmin "+this->displayName); garmin_data * fitnessdata = garmin_get(&garmin,GET_RUNS); //garmin_data * fitnessdata = garmin_load("/workout/2010/02/20100227T152346.gmn"); //Testing only if (fitnessdata != NULL ) { Log::dbg("Received data from Garmin, processing data..."); fitData = new TcxBase(); // Add author information TcxAuthor * author = new TcxAuthor(); *(fitData)<<author; data0 = garmin_list_data(fitnessdata,0); data1 = garmin_list_data(fitnessdata,1); data2 = garmin_list_data(fitnessdata,2); if ( data0 != NULL && (data0->data != NULL) && data1 != NULL && (laps = (garmin_list*)data1->data) != NULL && data2 != NULL && (tracks = (garmin_list*)data2->data) != NULL ) { if (data0->type == data_Dlist) { runs = (garmin_list*)(data0->data); } else { runs = garmin_list_append(NULL,data0); } *(fitData) << printActivities(runs, laps, tracks, garmin); if (data0->type != data_Dlist) { garmin_free_list_only(runs); } Log::dbg("Done processing data..."); } else { Log::err("Some of the data read from the device was null (runs/laps/tracks)"); } } else { Log::err("Unable to extract any data!"); } garmin_free_data(fitnessdata); garmin_close(&garmin); } else { Log::err("Unable to open garmin device. Is it connected?"); } return fitData; }
static PyObject* get_runs(PyObject* obj, PyObject* args) { garmin_unit garmin; if (!initialize_garmin(&garmin)) return NULL; garmin_data * data; if ( (data = garmin_get(&garmin, GET_RUNS)) == NULL ) { PyErr_SetString(PyExc_RuntimeError, "Unable to extract any data."); return NULL; } /* We should have a list with three elements: 1) The runs (which identify the track and lap indices) 2) The laps (which are related to the runs) 3) The tracks (which are related to the runs) */ garmin_data * tmpdata; garmin_list * runs = NULL; garmin_list * laps = NULL; garmin_list * tracks = NULL; tmpdata = garmin_list_data(data, 0); if ( tmpdata == NULL ) { PyErr_SetString(PyExc_RuntimeError, "Toplevel data missing element 0 (runs)"); return NULL; } runs = tmpdata->data; if ( runs == NULL ) { PyErr_SetString(PyExc_RuntimeError, "No runs extracted."); return NULL; } tmpdata = garmin_list_data(data, 1); if ( tmpdata == NULL ) { PyErr_SetString(PyExc_RuntimeError, "Toplevel data missing element 1 (laps)"); return NULL; } laps = tmpdata->data; if ( laps == NULL ) { PyErr_SetString(PyExc_RuntimeError, "No laps extracted."); return NULL; } tmpdata = garmin_list_data(data, 2); if ( tmpdata == NULL ) { PyErr_SetString(PyExc_RuntimeError, "Toplevel data missing element 2 (tracks)"); return NULL; } tracks = tmpdata->data; if ( tracks == NULL ) { PyErr_SetString(PyExc_RuntimeError, "No tracks extracted."); return NULL; } garmin_list_node * n; garmin_list_node * m; garmin_list_node * o; uint32 trk; uint32 f_lap; uint32 l_lap; uint32 l_idx; time_type start; /* Print some debug output if requested. */ if ( verbose != 0 ) { for ( m = laps->head; m != NULL; m = m->next ) { if ( get_lap_index(m->data,&l_idx) != 0 ) printf("[garmin] lap: index [%d]\n", l_idx); else printf("[garmin] lap: index [??]\n"); } } /* For each run, get its laps and track points. */ PyObject* dict = PyDict_New(); for ( n = runs->head; n != NULL; n = n->next ) { if ( get_run_track_lap_info(n->data, &trk, &f_lap, &l_lap) != 0 ) { time_type f_lap_start = 0; PyObject* run = PyDict_New(); PyObject* rlaps = PyDict_New(); PyDict_SetItem(run, PyString_FromString("track"), Py_BuildValue("i", trk)); PyDict_SetItem(run, PyString_FromString("first_lap"), Py_BuildValue("i", f_lap)); PyDict_SetItem(run, PyString_FromString("last_lap"), Py_BuildValue("i", l_lap)); PyDict_SetItem(run, PyString_FromString("type"), Py_BuildValue("i", (int)n->data->type)); /* TODO: Implement something similar for the other run types, D1000 and D1010 See src/run.c get_run_track_lap_info() for more information */ if (n->data->type == data_D1009) { D1009 * d1009; d1009 = n->data->data; PyDict_SetItem(run, PyString_FromString("multisport"), PyBool_FromLong(d1009->multisport)); switch (d1009->sport_type) { case D1000_running: PyDict_SetItem(run, PyString_FromString("sport"), PyString_FromString("running")); break; case D1000_biking: PyDict_SetItem(run, PyString_FromString("sport"), PyString_FromString("biking")); break; case D1000_other: PyDict_SetItem(run, PyString_FromString("sport"), PyString_FromString("other")); break; } } if (verbose != 0) printf("[garmin] run: track [%d], laps [%d:%d]\n",trk,f_lap,l_lap); for ( m = laps->head; m != NULL; m = m->next ) { if ( get_lap_index(m->data, &l_idx) != 0 ) { if ( l_idx >= f_lap && l_idx <= l_lap ) { PyObject* lap = PyDict_New(); if (verbose != 0) printf("[garmin] lap [%d] falls within laps [%d:%d]\n", l_idx,f_lap,l_lap); start = 0; get_lap_start_time(m->data, &start); if (start != 0) { if (l_idx == f_lap) f_lap_start = start; PyDict_SetItem(lap, PyString_FromString("start_time"), Py_BuildValue("i", (int)start)); PyDict_SetItem(lap, PyString_FromString("type"), Py_BuildValue("i", (int)m->data->type)); if (m->data->type == data_D1015) { D1015 * d1015; d1015 = m->data->data; PyDict_SetItem(lap, PyString_FromString("duration"), Py_BuildValue("i", d1015->total_time)); PyDict_SetItem(lap, PyString_FromString("distance"), Py_BuildValue("f", d1015->total_dist)); PyDict_SetItem(lap, PyString_FromString("max_speed"), Py_BuildValue("f", d1015->max_speed)); } PyObject * points = PyList_New(0); bool have_track = 0; bool done = 0; for ( o = tracks->head; o != NULL; o = o->next ) { if ( o->data != NULL ) { if (o->data->type == data_D311) { if ( ! have_track ) { D311 * d311; d311 = o->data->data; if ( d311->index == trk ) have_track = 1; } else /* We've reached the end of the track */ done = 1; } else if (o->data->type == data_D304 && have_track) { D304 * d304; d304 = o->data->data; PyObject* point = PyDict_New(); if (d304->posn.lat != 2147483647 && d304->posn.lon != 2147483647) { PyDict_SetItem(point, PyString_FromString("position"), Py_BuildValue("(ff)", SEMI2DEG(d304->posn.lat), SEMI2DEG(d304->posn.lon))); PyDict_SetItem(point, PyString_FromString("type"), Py_BuildValue("i", (int)o->data->type)); PyDict_SetItem(point, PyString_FromString("time"), Py_BuildValue("f", (float)(d304->time + TIME_OFFSET))); PyDict_SetItem(point, PyString_FromString("distance"), Py_BuildValue("f", d304->distance)); PyDict_SetItem(point, PyString_FromString("altitude"), Py_BuildValue("f", d304->alt)); PyDict_SetItem(point, PyString_FromString("heart_rate"), Py_BuildValue("i", d304->heart_rate)); if (d304->cadence != 255) PyDict_SetItem(point, PyString_FromString("cadence"), Py_BuildValue("i", d304->cadence)); PyList_Append(points, Py_BuildValue("N", point)); } } else if (have_track) printf("get_track: point type %d invalid!\n",o->data->type); } if ( done ) break; } PyDict_SetItem(lap, PyString_FromString("points"), Py_BuildValue("N", points)); } else PyErr_Warn(PyExc_Warning, "Start time of first lap not found."); PyDict_SetItem(rlaps, PyString_FromFormat("%d", (int)l_idx), Py_BuildValue("N", lap)); } } } PyDict_SetItem(run, PyString_FromString("laps"), Py_BuildValue("N", rlaps)); PyDict_SetItem(dict, PyString_FromFormat("%d", (int)f_lap_start), Py_BuildValue("N", run)); } } garmin_free_data(data); garmin_close(&garmin); return Py_BuildValue("N", dict); }