Merge pull request #44 from marxav/power_and_cadence

Add power and cadence as possible targets
master
Nikola Petkov 7 years ago committed by GitHub
commit c8485b44a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      README.md
  2. 24
      src/main/scala/com.github.mgifos.workouts/model/Target.scala
  3. 24
      src/test/scala/com/github/mgifos/workouts/model/TargetSpec.scala

@ -93,7 +93,7 @@ The reserved keywords of the notation are: workout, warmup, cooldown, run, bike,
**`<time-duration>`** := `<minutes>:<seconds>`
**`<target>`** := `<zone-target> | <pace-target> | <hr-target>`
**`<target>`** := `<zone-target> | <pace-target> | <hr-target> | <speed-target> | <power-target> | <cadence-target>`
**`<zone-target>`** := `z[1-6]`
@ -101,6 +101,10 @@ The reserved keywords of the notation are: workout, warmup, cooldown, run, bike,
**`<hr-target>`** := `\d{1,3} - \d{1,3} bpm`
**`<power-target>`** := `\d{1,3} - \d{1,3} W`
**`<cadence-target>`** := `\d{1,3} - \d{1,3} rpm`
**`<speed-target>`** := `<kph-speed> - <kph-speed> (kph | mph)?`
**`<pace>`** := `<minutes>:<seconds>`
@ -128,4 +132,4 @@ If not specified -m value from configuration will be used ('metric' by default).
- It is highly recommended to use Google Spreadsheets or LibreOffice Calc to edit CSV files, as they both force line-feed (LF)
instead of carriage-return (CR) character for internal line breaks when defining workouts.
The parser we use is not able to parse CR values within the quoted values at the moment.
The parser we use is not able to parse CR values within the quoted values at the moment.

@ -36,6 +36,26 @@ case class PaceTarget(from: Pace, to: Pace) extends Target {
)
}
case class PowerCustomTarget(from: Int, to: Int) extends Target {
override def json =
Json.obj(
"targetType" -> Json.obj("workoutTargetTypeId" -> 2, "workoutTargetTypeKey" -> "power.zone"),
"targetValueOne" -> from,
"targetValueTwo" -> to,
"zoneNumber" -> JsNull
)
}
case class CadenceCustomTarget(from: Int, to: Int) extends Target {
override def json =
Json.obj(
"targetType" -> Json.obj("workoutTargetTypeId" -> 3, "workoutTargetTypeKey" -> "cadence.zone"),
"targetValueOne" -> from,
"targetValueTwo" -> to,
"zoneNumber" -> JsNull
)
}
case class SpeedTarget(from: Speed, to: Speed) extends Target {
override def json =
Json.obj(
@ -75,14 +95,18 @@ case class Speed(unit: DistanceUnits.DistanceUnit, exp: String) {
}
object Target {
private val CadenceCustomRx = """^(\d{1,3})\s*-\s*(\d{1,3})\s*rpm$""".r
private val HrZoneRx = """^z(\d)$""".r
private val HrCustomRx = """^(\d{1,3})\s*-\s*(\d{1,3})\s*bpm$""".r
private val PaceRangeRx = """^(\d{1,2}:\d{2})\s*-\s*(\d{1,2}:\d{2})\s*(mpk|mpm)?$""".r
private val PowerCustomRx = """^(\d{1,3})\s*-\s*(\d{1,3})\s*W$""".r
private val SpeedRangeRx = """^(\d{1,3}(\.\d{1})?)\s*-\s*(\d{1,3}(\.\d{1})?)\s*(kph|mph)?""".r
def parse(x: String)(implicit msys: MeasurementSystems.MeasurementSystem): Target = x.trim match {
case CadenceCustomRx(from, to) => CadenceCustomTarget(from.toInt, to.toInt)
case HrZoneRx(zone) => HrZoneTarget(zone.toInt)
case HrCustomRx(from, to) => HrCustomTarget(from.toInt, to.toInt)
case PowerCustomRx(from, to) => PowerCustomTarget(from.toInt, to.toInt)
case SpeedRangeRx(from, _, to, _, uom) =>
val du = Option(uom).fold(msys.distance)(DistanceUnits.withSpeedUOM)
SpeedTarget(Speed(du, from), Speed(du, to))

@ -43,4 +43,28 @@ class TargetSpec extends FlatSpec with Matchers {
"targetValueTwo" -> 150,
"zoneNumber" -> JsNull))
}
"Target" should "handle custom POWER specification correctly" in {
val powTarget = Target.parse("230-250 W").asInstanceOf[PowerCustomTarget]
powTarget should be(PowerCustomTarget(230, 250))
powTarget.json should be(Json.obj(
"targetType" -> Json.obj(
"workoutTargetTypeId" -> 2,
"workoutTargetTypeKey" -> "power.zone"),
"targetValueOne" -> 230,
"targetValueTwo" -> 250,
"zoneNumber" -> JsNull))
}
"Target" should "handle custom CADENCE specification correctly" in {
val cadenceTarget = Target.parse("80-90 rpm").asInstanceOf[CadenceCustomTarget]
cadenceTarget should be(CadenceCustomTarget(80, 90))
cadenceTarget.json should be(Json.obj(
"targetType" -> Json.obj(
"workoutTargetTypeId" -> 3,
"workoutTargetTypeKey" -> "cadence.zone"),
"targetValueOne" -> 80,
"targetValueTwo" -> 90,
"zoneNumber" -> JsNull))
}
}

Loading…
Cancel
Save