예제 #1
0
    def import_fit_data(self):
        """
        Will look at the file location for our google fit files and loop though imported them by category. It will
        ignore any walking activity to remove clutter. Then call a function to move any read files to the ./imported
        folder
        """
        categories = ['Running', 'Yoga', 'Weights', 'Wal']
        for category in categories:
            file_names = self.get_tcx_files(category)
            for file in file_names:
                if category is not 'Wal':
                    tcx = tcxparser.TCXParser(self._activitiesLocation + '\\' +
                                              file)
                    date_str, duration, pace = self.convert_data(tcx)
                    name = category + " - " + date_str
                    notes = tcx.activity_notes
                    calories = tcx.calories
                    heart_rate = self.get_heart_rate(tcx)
                    distance = tcx.distance

                    fit_activity = Activity.Activity(category, name, date_str,
                                                     notes)
                    fit_activity.add_fit_entry(calories, heart_rate, pace,
                                               duration, distance)
                self.move_read_files(file)
예제 #2
0
def _parse(f: Path) -> Workout:
    tcx = tcxparser.TCXParser(str(f))

    sport = f.stem.split('_')[-1]  # todo not sure how reliable...
    hr_avg = tcx.hr_avg

    distance_m = tcx.distance
    duration_s = tcx.duration
    # kmh to match endomondo.. should probably be CI
    speed_avg_kmh = (distance_m / 1000) / (duration_s / 3600)

    # eh. not sure if there is a better way
    # for now use this to be compatible with Endomondo
    # https://beepb00p.xyz/heartbeats_vs_kcals.html
    # filtered for Endomondo running:
    reg_coeff = 0.0993
    intercept = -11.0739
    total_beats = hr_avg * (duration_s / 60)
    kcal_estimate = total_beats * reg_coeff + intercept

    return {
        'id': f.name,  # not sure?
        'start_time': isoparse(tcx.started_at),
        'duration': timedelta(seconds=tcx.duration),
        'sport': sport,
        'heart_rate_avg': tcx.hr_avg,
        'speed_avg': speed_avg_kmh,
        'kcal': kcal_estimate,
    }
예제 #3
0
 def __process_file(self, file_name):
     root_logger.info("Processing file: " + file_name)
     tcx = tcxparser.TCXParser(file_name)
     end_time = dateutil.parser.parse(tcx.completed_at, ignoretz=True)
     start_time = dateutil.parser.parse(tcx.started_at, ignoretz=True)
     manufacturer = GarminDB.Device.Manufacturer.Unknown
     product = tcx.creator
     if product is not None:
         match = re.search('Microsoft', product)
         if match:
             manufacturer = GarminDB.Device.Manufacturer.Microsoft
     serial_number = tcx.creator_version
     if serial_number is None or serial_number == 0:
         serial_number = GarminDB.Device.unknown_device_serial_number
     device = {
         'serial_number': serial_number,
         'timestamp': start_time,
         'manufacturer': manufacturer,
         'product': product,
         'hardware_version': None,
     }
     GarminDB.Device._create_or_update_not_none(self.garmin_db_session,
                                                device)
     (file_id, file_name) = GarminDB.File.name_and_id_from_path(file_name)
     file = {
         'id': file_id,
         'name': file_name,
         'type': GarminDB.File.FileType.tcx,
         'serial_number': serial_number,
     }
     GarminDB.File._find_or_create(self.garmin_db_session, file)
     distance = Fit.measurement.Distance.from_meters(tcx.distance)
     # ascent = Fit.Distance.from_meters(tcx.ascent)
     # descent = Fit.Distance.from_meters(tcx.descent)
     activity = {
         'activity_id': file_id,
         'start_time': start_time,
         'stop_time': end_time,
         'laps': len(tcx.activity.Lap),
         # 'sport'                     : tcx.activity_type,
         'calories': tcx.calories,
         'start_lat': tcx.start_latitude,
         'start_long': tcx.start_longitude,
         'stop_lat': tcx.end_latitude,
         'stop_long': tcx.end_longitude,
         'distance': distance.kms_or_miles(self.measurement_system),
         'avg_hr': tcx.hr_avg,
         'max_hr': tcx.hr_max,
         'max_cadence': tcx.cadence_max,
         'avg_cadence': tcx.cadence_avg,
         # 'ascent'                    : ascent.meters_or_feet(self.measurement_system),
         # 'descent'                   : descent.meters_or_feet(self.measurement_system)
     }
     activity_not_zero = {
         key: value
         for (key, value) in activity.iteritems() if value
     }
     GarminDB.Activities._create_or_update_not_none(
         self.garmin_act_db_session, activity_not_zero)
예제 #4
0
 def __init__(self, cpath=''):
     FILEDIRECTORY = './data'
     FILENAME = 'act1.tcx'
     FILEPATH = os.path.join(FILEDIRECTORY, FILENAME)
     if cpath:
         FILEPATH = cpath
     self.TCX_object = tp.TCXParser(FILEPATH)
     self.dict_data = {}
     self.getdata()
예제 #5
0
    def __init__(self, path_to_tcx: Union[Path, str]):

        self.path = Path(path_to_tcx)
        if not self.path.exists():
            raise FileNotFoundError(
                f'Provided path {self.path} does not exist.')
        elif self.path.suffix != '.tcx':
            raise ValueError('Provided path should lead to a .tcx file.')

        # needs string path for internal reasons
        self.tcx = tcxparser.TCXParser(str(self.path))
예제 #6
0
def _get_ifit_workouts(workout_dir):
    workouts = []
    for workout_file in glob.glob(os.path.join(workout_dir, '*')):
        tcx = tcxparser.TCXParser(workout_file)
        workout = Workout(workout_id=os.path.basename(workout_file),
                          started_at=tcx.started_at,
                          duration=tcx.duration,
                          notes=tcx.activity_notes,
                          tcx_file=workout_file)
        logging.debug(f"Workout: {workout}")
        workouts.append(workout)
    workouts.sort(key=lambda x: x.started_at)
    return workouts
def parseActivity(act):
    fn_key = 'filename'
    date_key = 'date'
    type_key = 'type'
    distance_key = 'distance'
    ascent_key = 'elevation'

    if 'Filename' in act:
        fn_key = 'Filename'
        date_key = 'Activity Date'
        type_key = 'Activity Type'
        distance_key = 'Distance'
        ascent_key = 'Elevation Gain'

    if not act[fn_key]:
        return None

    if act[fn_key].endswith('gpx.gz'):
        with skipWhitespace(gzip.open(act[fn_key], 'r')) as f:
            gpx = gpxpy.parse(f)
        ascent = calcGPXAscent(gpx)
    elif act[fn_key].endswith('tcx.gz'):
        with skipWhitespace(gzip.open(act[fn_key], 'r')) as f:
            tcx = tcxparser.TCXParser(f)
        ascent = tcx.ascent
    elif act[fn_key].endswith('fit.gz'):
        # TODO: parse fit.gz
        if ascent_key in act:
            ascent = float(act[ascent_key])
        else:
            return None
    else:
        raise Exception("Unknown activity file type")

    distance = 0
    distance_str = act[distance_key].replace(',', '')
    if distance_str: distance = float(distance_str)

    return dict(date=act[date_key],
                ascent=ascent,
                distance=distance,
                type=act[type_key])
예제 #8
0
def parse_tcx(filename):
    global last_tcx
    if last_tcx is not None and last_tcx["filename"] == filename:
        return last_tcx["tr"]

    tcx = tcxparser.TCXParser(filename)
    train = {}
    train['activity_type'] = tcx.activity_type
    train['calories'] = tcx.calories
    train['distance_units'] = tcx.distance_units
    train['date'] = tcx.time_values()[0]
    tr = pd.DataFrame({'time': [], 'hr': []})
    t1 = datetime.strptime(tcx.time_values()[0][:-1], "%Y-%m-%dT%H:%M:%S.%f")
    for i in range(min(len(tcx.time_values()), len(tcx.hr_values()))):
        t = (datetime.strptime(tcx.time_values()[i][:-1],
                               "%Y-%m-%dT%H:%M:%S.%f") - t1).total_seconds()
        tr = tr.append({
            "time": t,
            "hr": tcx.hr_values()[i]
        },
                       ignore_index=True)
    tr["duration"] = -tr["time"].diff(periods=-1)
    last_tcx = {"filename": filename, "tr": tr}
예제 #9
0
def tcx_to_dataframe(filename):

    with open(filename, "r") as f:
        lines = f.readlines()
    lines[0] = lines[0].lstrip()
    with open(filename, "w") as f:
        f.writelines(lines)

    tcx = tcxparser.TCXParser(filename)

    time = tcx.time_values()
    positions = tcx.position_values()
    latitude, longitude = zip(*positions)
    altitude = tcx.altitude_points()

    speed = np.nan * np.ones([len(time), 1])

    df = pd.DataFrame(
        zip(*[time, latitude, longitude]),
        columns=["time", "latitude", "longitude"],
    )

    df = clean(df)
    return df
예제 #10
0
				for child in root.getiterator():
					if not hasattr(child.tag, 'find'): continue  # (1)
					i = child.tag.find('}')
					if i >= 0:
						child.tag = child.tag[i + 1:]
				objectify.deannotate(root, cleanup_namespaces=True)
				
				# Get activity id from file name
				activity_id = filepath.split("_")
				try:
					activity_id = int(activity_id[1])
				except:
					activity_id = int(activity_id[1].split(".")[0])
				
				# Get activity summary data
				tcx = tcxparser.TCXParser(filepath)

				# Finding summary heart rate values, if hrt rate = 0 it will return ZeroDivisionError
				try:
					avg_hrt_rate = int(tcx.hr_avg)
					max_hrt_rate = int(tcx.hr_max)
				except ZeroDivisionError:
					avg_hrt_rate = 0
					max_hrt_rate = 0
				
				# Adding activities row
				session.add(Activities(act_id=activity_id, \
									act_type=tcx.activity_type, \
									act_duration=int(tcx.duration), \
									act_tot_distance=int(tcx.distance), \
									act_max_speed=1, \
 def process_files(self, db_params_dict):
     garmin_db = GarminDB.GarminDB(db_params_dict, self.debug - 1)
     garmin_act_db = GarminDB.ActivitiesDB(db_params_dict, self.debug)
     for file_name in self.file_names:
         logger.info("Processing file: " + file_name)
         tcx = tcxparser.TCXParser(file_name)
         end_time = dateutil.parser.parse(tcx.completed_at, ignoretz=True)
         start_time = dateutil.parser.parse(tcx.started_at, ignoretz=True)
         manufacturer = 'Unknown'
         product = tcx.creator
         if product is not None:
             match = re.search('Microsoft', product)
             if match:
                 manufacturer = 'Microsoft'
         serial_number = tcx.creator_version
         if serial_number is None or serial_number == 0:
             serial_number = GarminDB.Device.unknown_device_serial_number
         device = {
             'serial_number': serial_number,
             'timestamp': start_time,
             'manufacturer': manufacturer,
             'product': product,
             'hardware_version': None,
         }
         GarminDB.Device.create_or_update_not_none(garmin_db, device)
         file = {
             'name': file_name,
             'type': 'tcx',
             'serial_number': serial_number,
         }
         GarminDB.File.find_or_create(garmin_db, file)
         activity_id = GarminDB.File.get(garmin_db, file_name)
         if self.english_units and tcx.distance_units == 'meters':
             distance = Fit.Conversions.meters_to_miles(tcx.distance)
             ascent = Fit.Conversions.meters_to_feet(tcx.ascent)
             descent = Fit.Conversions.meters_to_feet(tcx.descent)
         else:
             distance = tcx.distance / 1000.0
             ascent = tcx.ascent / 1000.0
             descent = tcx.descent / 1000.0
         activity = {
             'activity_id': activity_id,
             'start_time': start_time,
             'stop_time': end_time,
             'laps': len(tcx.activity.Lap),
             # 'sport'                     : tcx.activity_type,
             'start_lat': tcx.start_latitude,
             'start_long': tcx.start_longitude,
             'stop_lat': tcx.end_latitude,
             'stop_long': tcx.end_longitude,
             'distance': distance,
             'avg_hr': tcx.hr_avg,
             'max_hr': tcx.hr_max,
             'calories': tcx.calories,
             'max_cadence': tcx.cadence_max,
             'avg_cadence': tcx.cadence_avg,
             #'ascent'                    : ascent,
             #'descent'                   : descent
         }
         activity_not_zero = {
             key: value
             for (key, value) in activity.iteritems() if value
         }
         print repr(activity_not_zero)
         GarminDB.Activities.create_or_update_not_none(
             garmin_act_db, activity_not_zero)
예제 #12
0
 def __init__(self, filename):
     """Return an instance of TcxFile containing a parsed TCX file."""
     self.tcx = tcxparser.TCXParser(filename)
예제 #13
0
# -*- coding: utf-8 -*-

import os,tcxparser

cd = os.path.dirname(os.path.abspath(__file__)) #use to browse tcx files at the correct location
file_list=os.listdir(os.getcwd())

f=open("result.txt","a")
f.write("date (ISO UTC Format)"+'\t'+"Distance [m]"+'\t'+"Duration [s]"+'\n')
for a in file_list:
    if a == "result.txt": 
        print()     #Quick and dirty...
    elif a== "readTCXFiles.py":
        print()     #Quick and dirty...
    else:    
        tcx=tcxparser.TCXParser(cd+'/'+a) #see https://github.com/vkurup/python-tcxparser/ for details
        if tcx.activity_type == 'biking'  :  #To select only my biking session (could be change to 'hiking', 'running' etc.)
            f.write(str(tcx.completed_at)+'\t'+str(tcx.distance)+'\t'+str(tcx.duration)+'\n')
f.close
예제 #14
0
def preproc_nike():

    # Grab all zipfiles
    nike_runs = sorted(
        [os.path.join(nike, i) for i in os.listdir(nike) if i.endswith('zip')])

    # Create Pandas Dataframe
    df_nike = pd.DataFrame(index=range(len(nike_runs)))

    # Loop through zip files, read json data and populate df
    for idx, nike_run in enumerate(nike_runs):

        # load zipfile
        nike_zip = zipfile.ZipFile(nike_run, 'r')

        # load json only
        nike_json = json.load([
            nike_zip.open(i) for i in nike_zip.namelist() if i.endswith('json')
        ][0])
        nike_tcx = tcxparser.TCXParser([
            nike_zip.open(i) for i in nike_zip.namelist() if i.endswith('tcx')
        ][0])

        try:
            if nike_tcx.latitude:
                lat = nike_tcx.latitude
                lon = nike_tcx.longitude
                city, country = getplace(lat, lon)
                location = '%s, %s' % (city, country)
                print idx, lat, lon, city, country
            else:
                location = 'indoor'
        except:
            location = 'indoor'

        df_nike.loc[idx, 'Source'] = '%s %s ' % (nike_json['source'],
                                                 nike_json['appversion'][:-5])
        df_nike.loc[idx, 'Location'] = location  # nike_json['title']
        df_nike.loc[idx, 'Latitude'] = lat
        df_nike.loc[idx, 'Longitude'] = lon
        df_nike.loc[idx, 'Source'] = '%s %s ' % (nike_json['source'],
                                                 nike_json['appversion'][:-5])
        df_nike.loc[idx, 'Speed_Max'] = nike_json['maxSpeed']
        df_nike.loc[idx, 'Date'] = nike_json['startTime']['time'][0:10]
        df_nike.loc[idx, 'Description'] = nike_json['description']
        df_nike.loc[idx, 'Speed'] = nike_json['avgSpeed']
        df_nike.loc[idx, 'Speed_Max'] = nike_json['maxSpeed']
        try:
            if nike_tcx.pace:
                df_nike.loc[idx, 'Tempo'] = nike_tcx.pace
            else:
                df_nike.loc[idx, 'Tempo'] = 'xxxxxxxxxxxx'
        except:
            pass
        df_nike.loc[idx, 'Distance'] = nike_tcx.distance / 1000
        df_nike.loc[idx, 'Duration'] = nike_tcx.duration / 60
        df_nike.loc[idx, 'Start'] = nike_json['startTime']['time'][11:-1]

        df_nike.loc[idx, 'Ascent'] = nike_tcx.ascent
        df_nike.loc[idx, 'Descent'] = nike_tcx.descent
        df_nike.loc[idx, 'Elevation_Gain'] = nike_json['elevationGain']
        df_nike.loc[idx, 'Elevation_Max'] = nike_json['maxElevation']

        df_nike.loc[idx, 'Calories'] = nike_json['calories']

        for lap_idx, lap in enumerate(nike_json['laps']):
            df_nike.loc[idx, 'Km_%s' %
                        (lap_idx + 1)] = 'Duration=%s, Speed=%s' % (np.round(
                            lap['duration'] / 60.,
                            3), np.round(lap['avgSpeed'], 2))

        df_nike.to_csv('./Data/NikeRunClub.csv', encoding='utf-8')
def output():
    #
    # man, this sucks
    #

    tracker = request.form.get('Tracker')
    username = request.form.get('Username')
    password = request.form.get('Password')
    location = request.form.get('Location')
    # dateStart=request.form.get('StartDate')
    # print("Date start is: " + str(dateStart))
    # dateEnd=request.form.get('EndDate')
    dataModified = []  # for Jawbone file check
    try:
        #
        # THIS GETS THE FILE. FLASK.
        #
        files = request.files.getlist('file[]')
        print files
        filenames = []
        for ifile in files:
            if ifile and allowed_file(ifile.filename):
                filenames.append(ifile.filename)
                ifile.save(
                    os.path.join(app.config['UPLOAD_RAW_DEST'],
                                 ifile.filename))
                print ifile.filename

        #get location of saved file
        #print( 'filename: ' + filename)
        filepath = os.path.join(app.config['UPLOAD_RAW_DEST'], filenames[0])
        print filepath
        print app.config['UPLOAD_RAW_DEST']

        if tracker == 'Jawbone':
            import glob
            # then this is a csv file
            os.chdir('/root/tmp/raw')
            # get the file
            for ifile in range(len(filenames)):
                print("FILE NAME IS: " + str(filenames[ifile]))
                ff = glob.glob(filenames[ifile])[0]
                dataAll = np.swapaxes(np.genfromtxt(ff, delimiter=','), 1, 0)

                temp=[ datetime.datetime.strptime(str(int(dataAll[0][j])), \
                       '%Y%m%d') for j in range(1,len(dataAll[0]))]
                dataYears = list(dataAll[0])
                time = [np.nan] + temp
                # now get the data that matters
                #
                # 41 is steps
                # 37 is distance in meters
                # 43 is calories
                # 35 is active time in seconds
                # 48 is sleep time
                #
                params = [
                    'Dates', 'Steps', 'Distance', 'Calories', 'ActiveTime',
                    'SleepTime'
                ]
                indicies = [0, 41, 37, 43, 35, 48]
                dataModified = {}
                # now have to adjust for the right dates
                for iP in range(len(params)):
                    dataModified[params[iP]] = []
                goodvals = np.isnan(dataYears[41])  # get rid of the nans

                dataModified['Steps'] += list(dataAll[41])
                dataModified['Distance'] += list(dataAll[37])
                dataModified['Calories'] += list(dataAll[43])
                dataModified['ActiveTime'] += list(dataAll[35])
                dataModified['SleepTime'] += list(dataAll[48])
                dataModified['Dates'] += list(np.array(time))
                #
        if tracker == 'Endomondo':
            import glob
            from geopy.geocoders import Nominatim
            import tcxparser
            # then this is a tcx file
            os.chdir('/root/tmp/raw')
            # get the file
            params = ['Date', 'ActiveTime', 'Distance', 'Calories', 'Location']
            dataModified = {}
            for iparam in params:
                dataModified[iparam] = []
            for ifile in range(len(filenames)):
                print("FILE NAME IS: " + str(filenames[ifile]))
                ff = glob.glob(filenames[ifile])[0]
                startDate = ff[0:10]
                tcx = tcxparser.TCXParser(ff)
                # get data
                workoutTime = tcx.duration
                latitude = str(tcx.latitude)
                longitude = str(tcx.longitude)
                timeStamp = tcx.completed_at
                try:
                    distance = tcx.distance
                except:
                    distance = 1e-31
                calories = tcx.calories
                # turn lat and longitude into a city
                geolocator = Nominatim()
                location = (geolocator.reverse(latitude + ',' +
                                               longitude)).address
                # now have to adjust for the right dates
                print startDate
                dataModified['Date'].append(startDate)
                dataModified['Distance'].append(distance)
                dataModified['Calories'].append(calories)
                dataModified['ActiveTime'].append(workoutTime)
                dataModified['Location'].append(location)

    except:
        print("no file uploaded")

#
# now load the relevant figures
#
    dateStart = 0
    dateEnd = 0
    if tracker == 'Jawbone':
        import readJawBone as PL
        data=PL.loadData(username, password, location,\
                          data=dataModified)


# elif tracker=='Polar Loop':
#         import dataStats as PL
#         data=PL.loadData(username, password, location, instartDate=dateStart, \
#                          inendDate=dateEnd)
#
# Jimmy's data
    elif tracker == 'Endomondo':
        import readTapiriik as PL
        data = PL.loadData(username,
                           password,
                           location,
                           dataModified=dataModified)

    dd = data[0]
    temp = data[0] * 1.1
    goal = ("%.0f" % temp)
    cals = ("%.0f" % dd)
    dayofweek = data[2]
    weather = data[1]

    boxwhisker = "/static/" + username + "/boxwhisker_Calories_daysofweek.png"
    scatter1 = "/static/" + username + "/seaborn_Calories_Wind_scatter.png"
    scatter2 = "/static/" + username + "/seaborn_Calories_MeanTemperature_scatter.png"
    scatter3 = "/static/" + username + "/seaborn_Calories_Precip_scatter.png"
    os.chdir('/root/Hosting/flaskexample')
    import stat
    os.chmod('/root/Hosting/flaskexample' + boxwhisker, 0o777)
    os.chmod('/root/Hosting/flaskexample' + scatter1, 0o777)
    os.chmod('/root/Hosting/flaskexample' + scatter2, 0o777)
    os.chmod('/root/Hosting/flaskexample' + scatter3, 0o777)
    print(scatter1)

    return render_template("output.html", calories=cals, tracker=tracker, \
                           goal=goal, dayofweek=str(dayofweek),\
                           weather=str(weather), boxwhisker=boxwhisker, \
                           scatter1=scatter1, scatter2=scatter2, \
                           scatter3=scatter3)