Skip to content

Commit

Permalink
Add schedule conversion; tidy up Creator class moving conversion out …
Browse files Browse the repository at this point in the history
…into separate class
  • Loading branch information
jpickup committed Jan 12, 2017
1 parent 196ec22 commit 98cfc1d
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 55 deletions.
24 changes: 24 additions & 0 deletions GarminWorkoutCreator.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="fit" level="project" />
<orderEntry type="library" name="log4j-1.2.13" level="project" />
<orderEntry type="library" name="lombok" level="project" />
<orderEntry type="library" name="hamcrest-core-1.3" level="project" />
<orderEntry type="library" name="slf4j-api-1.7.22" level="project" />
<orderEntry type="library" name="antlr-4.5.3-complete" level="project" />
<orderEntry type="library" name="antlr-4.6-complete" level="project" />
<orderEntry type="library" name="backport-util-concurrent-3.1" level="project" />
<orderEntry type="library" name="groovy-all-2.1.1" level="project" />
<orderEntry type="library" name="poi-3.11-beta2-20140822" level="project" />
</component>
</module>
53 changes: 24 additions & 29 deletions src/com/johnpickup/GarminScheduleGenerator.java
Original file line number Diff line number Diff line change
@@ -1,57 +1,52 @@
package com.johnpickup;

import com.johnpickup.converter.PaceConverter;
import com.johnpickup.converter.PaceConverterFactory;
import com.johnpickup.converter.PaceNameConverter;
import com.johnpickup.converter.WorkoutConverter;
import com.johnpickup.converter.*;
import com.johnpickup.excel.ExcelWorkoutScheduleReader;
import com.johnpickup.garmin.WorkoutCreator;
import com.johnpickup.garmin.unit.PaceTarget;
import com.johnpickup.parser.Pace;
import com.johnpickup.parser.PaceName;
import com.johnpickup.parser.Workout;
import com.johnpickup.garmin.WorkoutSaver;
import com.johnpickup.parser.WorkoutSchedule;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


/**
* Created by john on 11/01/2017.
* Simple class with command-line interface that takes an Excel definition of a workout schedule and proceduces a set
* of FIT files for loading onto the Garmin device
*/
@Slf4j
public class GarminScheduleGenerator {
private Map<String, PaceTarget> namedPaces = new HashMap<>();

public static void main(String[] args) {
try {
GarminScheduleGenerator instance = new GarminScheduleGenerator();
instance.init();
instance.generate(args[0]);
} catch (Exception e) {
e.printStackTrace();
log.error("Failed to generate workout schedule", e);
}
}

private void init() {
PaceNameConverter namedPaceConverter = new PaceNameConverter(namedPaces);
PaceConverterFactory.getInstance().register(namedPaceConverter, PaceName.class);
}

private void generate(String inputFilename) throws IOException {
log.info("Converting {}", inputFilename);
ExcelWorkoutScheduleReader reader = new ExcelWorkoutScheduleReader();
WorkoutScheduleConverter converter = new WorkoutScheduleConverter();
WorkoutSaver workoutSaver = new WorkoutSaver();
log.info("Reading workout schedule");
WorkoutSchedule workoutSchedule = reader.read(inputFilename);
WorkoutConverter workoutConverter = new WorkoutConverter();
WorkoutCreator workoutCreator = new WorkoutCreator();
for (Map.Entry<String, Pace> namedPace : workoutSchedule.getPaces().entrySet()) {
Pace pace = namedPace.getValue();
namedPaces.put(namedPace.getKey(), PaceConverterFactory.getInstance().getPaceConverter(pace).convert(pace));
}

for (Workout workout : workoutSchedule.getWorkouts().values()) {
com.johnpickup.garmin.workout.Workout garminWorkout = workoutConverter.convert(workout);
workoutCreator.save(garminWorkout, generateWorkoutFilename(garminWorkout));
log.info("Converting workout schedule");
converter.convert(workoutSchedule);

log.info("Saving workouts");
for (com.johnpickup.garmin.workout.Workout garminWorkout : converter.getGarminWorkouts()) {
String workoutFilename = generateWorkoutFilename(garminWorkout);
workoutSaver.save(garminWorkout, workoutFilename);
log.info("Saved workout {} as {}", garminWorkout.getName(), workoutFilename);
}

log.info("Saving schedule");
String scheduleFilename = "schedule.fit";
workoutSaver.save(converter.getTrainingSchedule(), scheduleFilename);
log.info("Saved workout schedule as {}", scheduleFilename);
}

private String generateWorkoutFilename(com.johnpickup.garmin.workout.Workout garminWorkout) {
Expand Down
62 changes: 62 additions & 0 deletions src/com/johnpickup/converter/WorkoutScheduleConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.johnpickup.converter;

import com.johnpickup.garmin.schedule.*;
import com.johnpickup.garmin.unit.PaceTarget;
import com.johnpickup.parser.*;
import com.johnpickup.parser.ScheduledWorkout;
import com.johnpickup.parser.Workout;
import lombok.Getter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Created by john on 12/01/2017.
*/
public class WorkoutScheduleConverter {
private Map<String, PaceTarget> namedPaces = new HashMap<>();
@Getter
private List<com.johnpickup.garmin.workout.Workout> garminWorkouts = new ArrayList<>();
@Getter
private TrainingSchedule trainingSchedule = new TrainingSchedule();
private Map<Workout, com.johnpickup.garmin.workout.Workout> workoutMap = new HashMap<>();

public WorkoutScheduleConverter() {
PaceNameConverter namedPaceConverter = new PaceNameConverter(namedPaces);
PaceConverterFactory.getInstance().register(namedPaceConverter, PaceName.class);
}

public void convert(WorkoutSchedule workoutSchedule) {
init();
for (Map.Entry<String, Pace> namedPace : workoutSchedule.getPaces().entrySet()) {
Pace pace = namedPace.getValue();
namedPaces.put(namedPace.getKey(), PaceConverterFactory.getInstance().getPaceConverter(pace).convert(pace));
}

WorkoutConverter workoutConverter = new WorkoutConverter();

for (Map.Entry<String, Workout> workoutEntry : workoutSchedule.getWorkouts().entrySet()) {
com.johnpickup.garmin.workout.Workout garminWorkout = workoutConverter.convert(workoutEntry.getValue());
garminWorkout.setName(workoutEntry.getKey());
garminWorkouts.add(garminWorkout);
workoutMap.put(workoutEntry.getValue(), garminWorkout);
}

for (ScheduledWorkout scheduledWorkout: workoutSchedule.getSchedule()) {
Workout workout = scheduledWorkout.getWorkout();
com.johnpickup.garmin.workout.Workout garminWorkout = workoutMap.get(workout);
com.johnpickup.garmin.schedule.ScheduledWorkout garminScheduledWorkout = new com.johnpickup.garmin.schedule.ScheduledWorkout(garminWorkout, scheduledWorkout.getDate());
trainingSchedule.addScheduledWorkout(garminScheduledWorkout);
}

}

private void init() {
namedPaces.clear();
garminWorkouts.clear();
workoutMap.clear();
trainingSchedule.clear();
}
}
17 changes: 17 additions & 0 deletions src/com/johnpickup/garmin/WorkoutSaver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.johnpickup.garmin;

import com.garmin.fit.FileEncoder;
import com.garmin.fit.Fit;
import com.johnpickup.garmin.fit.FitGenerator;

/**
* Class that can save output from a FitGenerator to a fie
*/
public class WorkoutSaver {

public void save(FitGenerator fitGenerator, String filename) {
FileEncoder encode = new FileEncoder( new java.io.File(filename), Fit.ProtocolVersion.V1_0);
encode.write(fitGenerator.generate());
encode.close();
}
}
Original file line number Diff line number Diff line change
@@ -1,57 +1,44 @@
package com.johnpickup.garmin;

import com.garmin.fit.*;
import com.johnpickup.converter.WorkoutConverter;
import com.johnpickup.garmin.fit.FitGenerator;
import com.johnpickup.garmin.schedule.ScheduledWorkout;
import com.johnpickup.garmin.schedule.TrainingSchedule;
import com.johnpickup.garmin.unit.*;
import com.johnpickup.garmin.unit.Distance;
import com.johnpickup.garmin.unit.DistanceUnit;
import com.johnpickup.garmin.unit.PaceTarget;
import com.johnpickup.garmin.unit.PaceUnit;
import com.johnpickup.garmin.workout.*;
import com.johnpickup.garmin.workout.Workout;
import com.johnpickup.parser.*;
import lombok.extern.slf4j.Slf4j;
import com.johnpickup.parser.WorkoutTextParser;

import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
* Created by john on 19/11/2016.
* Created by john on 12/01/2017.
*/
@Slf4j
public class WorkoutCreator {

public void save(FitGenerator fitGenerator, String filename) {
FileEncoder encode = new FileEncoder( new java.io.File(filename), Fit.ProtocolVersion.V1_0);
encode.write(fitGenerator.generate());
encode.close();
log.info("Saved {} as {}", fitGenerator, filename);
}

public class WorkoutSaverTest {
public static void main(String[] args) throws Exception {
WorkoutCreator app = new WorkoutCreator();
WorkoutSaver saver = new WorkoutSaver();
WorkoutTextParser parser = new WorkoutTextParser();
WorkoutConverter converter = new WorkoutConverter();

com.johnpickup.parser.Workout twoMile = parser.parse("2mi");
Workout garminTwoMileWorkout = converter.convert(twoMile);
app.save(garminTwoMileWorkout, "parsed_2mi.fit");
saver.save(garminTwoMileWorkout, "parsed_2mi.fit");

com.johnpickup.parser.Workout interval = parser.parse("1mi + (1mi@06:00-07:00/mi + 400m) * 4 + 1mi");
Workout garminInterval = converter.convert(interval);
app.save(garminInterval, "parsed_interval.fit");
saver.save(garminInterval, "parsed_interval.fit");

WorkoutStep testDistance = new SimpleDistanceWorkoutStep(new Distance(2, DistanceUnit.MILE));
Workout testDistanceWorkout = new Workout(Collections.singletonList(testDistance));
app.save(testDistanceWorkout, "testDist.fit");
saver.save(testDistanceWorkout, "testDist.fit");

WorkoutStep testPace = new SimplePaceWorkoutStep(new Distance(2, DistanceUnit.MILE), new PaceTarget(null, 5, 6, PaceUnit.MIN_PER_MILE));
Workout testPaceWorkout = new Workout(Collections.singletonList(testPace));
app.save(testPaceWorkout, "testPace.fit");
saver.save(testPaceWorkout, "testPace.fit");

WorkoutStep testInterval = new PaceIntervalWorkoutStep(
4,
Expand All @@ -61,7 +48,7 @@ public static void main(String[] args) throws Exception {
new PaceTarget(null, 9, 12, PaceUnit.MIN_PER_MILE));
Workout testIntervalWorkout = new Workout(Collections.singletonList(testInterval));
testIntervalWorkout.setName("4x1mi No WU");
app.save(testIntervalWorkout, "testInterval1.fit");
saver.save(testIntervalWorkout, "testInterval1.fit");

WorkoutStep warmcool = new SimpleDistanceWorkoutStep(new Distance(1, DistanceUnit.KILOMETRE));
WorkoutStep testInterval2 = new PaceIntervalWorkoutStep(
Expand All @@ -74,13 +61,12 @@ public static void main(String[] args) throws Exception {

Workout testIntervalWorkout2 = new Workout(Arrays.asList(interval2Steps));
testIntervalWorkout2.setName("3x1km WUCD");
app.save(testIntervalWorkout2, "testInterval2.fit");
saver.save(testIntervalWorkout2, "testInterval2.fit");

TrainingSchedule trainingSchedule = new TrainingSchedule();
trainingSchedule.addScheduledWorkout(new ScheduledWorkout(testDistanceWorkout, new Date()));
trainingSchedule.addScheduledWorkout(new ScheduledWorkout(testPaceWorkout, new Date(new Date().getTime() + TimeUnit.DAYS.toMillis(1))));
//trainingSchedule.addScheduledWorkout(new ScheduledWorkout(testInterval, new Date(2017,1,3)));
app.save(trainingSchedule, "testSchedule.fit");

saver.save(trainingSchedule, "testSchedule.fit");
}
}
4 changes: 4 additions & 0 deletions src/com/johnpickup/garmin/schedule/TrainingSchedule.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ protected List<Mesg> createMessageHeader() {
return messages;
}

public void clear() {
workouts.clear();
}

@Override
public List<Mesg> generate() {
List<Mesg> messages = createMessageHeader();
Expand Down
3 changes: 3 additions & 0 deletions src/com/johnpickup/parser/ScheduledWorkout.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.johnpickup.parser;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;

Expand All @@ -13,6 +14,8 @@
@EqualsAndHashCode
@ToString
public class ScheduledWorkout {
@Getter
private final Date date;
@Getter
private final Workout workout;
}

0 comments on commit 98cfc1d

Please sign in to comment.