def get_all_workout_data(): variables = [ 'timestamp', 'fitness_discipline', 'title', 'duration', 'instructor', 'calories', 'distance' ] workouts = PelotonWorkout.list() df = pd.DataFrame(columns=variables) for workout in workouts: try: wkout = workout.__dict__ start_time = wkout['start_time'] workout_type = wkout['fitness_discipline'] workout_deets = wkout['ride'].__dict__ title = workout_deets['title'] duration = workout_deets['duration'] instructor = workout_deets['instructor'].name cals = (workout.metrics.calories_summary.__dict__)['value'] dist = (workout.metrics.distance_summary.__dict__)['value'] # avg_hr = workout.metrics.heart_rate.average if not (cals and dist): continue data = [ start_time, workout_type, title, duration, instructor, cals, dist ] df.loc[len(df.index)] = data except: # print("Uh oh. There was an error fetching data from workout", workout.id) continue return df
def main(): """ Run the above functions to generate a Peloton report for the user. Returns ------- None. """ ## Take user input for the name of whomever's login in is provided name = input('Provide name of user currently saved in ".config/peloton": ') ## Load all of the workouts and get the cycling rides for this report workouts = PelotonWorkout.list() cycling_rides = [p for p in workouts if p.fitness_discipline == 'cycling'] ## Calculate total distance of all rides distances = [] for ride in cycling_rides: if "distance_summary" in dir(ride.metrics): miles = ride.metrics.distance_summary.value if miles is not None: distances.append(miles) print( f"{name} has biked {np.sum(distances):,} miles through {len(cycling_rides)} Peloton rides " + f"({len(cycling_rides) - len(distances)} are missing distances).") ## Save a histogram of the distances distance_histogram(distances) ## Save a barchart of instructors instructor_barchart(cycling_rides) ## Save a linechart with the trend of FTP test results over time (if any) dates, ftps = ftp_trend_chart(cycling_rides) ftp_df = pd.DataFrame({'date': dates, 'ftp': ftps}) ## Save any PowerZone plots that haven't been saved yet if (ftps is not None) and (dates is not None): pzone_rides = pzone_rides = [ p for p in cycling_rides if 'Power Zone' in p.ride.title ] if len(pzone_rides) > 0: for r in pzone_rides: ride_date = r.start_time.strftime("%Y-%m-%d") ride_title = r.ride.title.lower().replace(' ', '_') path = f"plts/power_zone/{name}_{ride_title}_{ride_date}.png" if not os.path.exists(path): ## Determine FTP based on FTP results and dates returned by ftp_trend_chart if r.start_time < min(ftp_df['date']): ## Take earliest FTP result for any rides before the 1st test ftp = ftp_df['ftp'][ftp_df['date'].argmin()] else: ## Otherwise, take most recent FTP before the ride ftp_sub_df = ftp_df[ftp_df['date'] <= r.start_time].copy().reset_index() ftp = ftp_sub_df['ftp'][ftp_sub_df['date'].argmax()] power_zone_plot(r, path=path, ftp=ftp)
def main(): parser = argparse.ArgumentParser() parser.add_argument( '-F', '--force-update', action='store_true', help= "This will update all fields in every workout, even if it's already indexed" ) args = parser.parse_args() FORCE_UPDATE = args.force_update INDEX_NAME = "pelastic" try: parser = configparser.ConfigParser() conf_path = os.environ.get("PELASTIC_CONFIG", "~/.config/pelastic.ini") parser.read(os.path.expanduser(conf_path)) # Mandatory credentials is_local = parser.getboolean('elastic', 'local') if is_local: host = parser.get('elastic', 'host') port = int(parser.get('elastic', 'port')) es = Elasticsearch([{'host': host, 'port': port}]) else: cloud_id = parser.get("elastic", "id") elastic_username = parser.get("elastic", "username") elastic_password = parser.get("elastic", "password") es = Elasticsearch(cloud_id=cloud_id, http_auth=(elastic_username, elastic_password)) except Exception as e: get_logger().error(e) print("Successfully connected to Elastic Service") for workout in PelotonWorkout.list(limit=100): # Normalize some of the data # Rides and Runs have Distance # This will short-circuit if the id already exists if not FORCE_UPDATE: try: res = es.get(index=INDEX_NAME, id=workout.id) break except: pass distance_summary = -1 distance_unit = "" # Rides have "Outputs" output_summary = -1 output_unit = "" avg_output = -1 avg_output_unit = "" # If you have an HRM, you should have HRM stats avg_hr = -1 avg_hr_unit = "" if hasattr(workout.metrics, "distance_summary"): distance_summary = workout.metrics.distance_summary.value distance_unit = workout.metrics.distance_summary.unit if hasattr(workout.metrics, "output_summary"): # This only exists in Rides output_summary = workout.metrics.output_summary.value output_unit = workout.metrics.output_summary.unit if hasattr(workout.metrics, "calories_summary"): calories = workout.metrics.calories_summary.value else: calories = -1 if hasattr(workout.metrics, "output"): avg_output = workout.metrics.output.average avg_output_unit = workout.metrics.output.unit if hasattr(workout.metrics, "heart_rate"): avg_hr = workout.metrics.heart_rate.average avg_hr_unit = workout.metrics.heart_rate.unit if hasattr(workout.ride, "instructor"): instructor_name = workout.ride.instructor.name else: instructor_name = "" best_output = False for achievement in workout.achievements: if "best_output" == achievement.slug: best_output = True break doc = { 'id': workout.id, 'username': peloton.PELOTON_USERNAME, 'fitness_discipline': workout.fitness_discipline, 'instructor_name': instructor_name, 'total_output': output_summary, 'output_unit': output_unit, 'calories': calories, 'duration': workout.ride.duration, 'personal_record': best_output, 'distance_summary': distance_summary, 'distance_unit': distance_unit, 'avg_output': avg_output, 'avg_output_unit': avg_output_unit, 'avg_hr': avg_hr, 'avg_hr_unit': avg_hr_unit, 'status': workout.status, '@timestamp': workout.created_at.strftime("%Y/%m/%d %H:%M:%S"), 'start_time': workout.start_time.strftime("%Y/%m/%d %H:%M:%S"), 'end_time': workout.end_time.strftime("%Y/%m/%d %H:%M:%S") } res = es.index(index=INDEX_NAME, id=workout.id, body=doc) print(res['result'])
from numpy import * import matplotlib.pyplot as plt from peloton import PelotonWorkout workouts = PelotonWorkout.list() #grab the first cycling workout, other types don't have resistance for workout in workouts: if workout.metrics_type == 'cycling': metrics = workout.metrics resistance = metrics.resistance break plt.plot(resistance.values) plt.show()