Beispiel #1
0
//fitness and freshness
func ff(user types.UserSettings, filter Filter) []types.Ff_data_point {
	user_id := user.Id
	ff_data := make([]types.Ff_data_point, 0)      //activity day
	ff_scan_data := make([]types.Ff_data_point, 0) //all days in range

	var user_data types.Metrics
	var user_cpms types.CPMs
	var end_summary_json []byte
	var cp_data_json []byte
	var has_power, has_heart bool
	var activity_start time.Time
	var firstDate time.Time
	var firstIter = true

	var activity_id string

	cluster := gocql.NewCluster(config.DbHost)
	cluster.Keyspace = "joulepersecond"
	cluster.Consistency = gocql.Quorum
	session, _ := cluster.CreateSession()
	defer session.Close()

	var lastNotableCp float64
	var thisCp int

	//get all of the user's data (at least all for now) TODO limit these queries by date if poss.
	iter := session.Query(`SELECT activity_start, activity_id, end_summary_json, has_power, has_heart FROM joulepersecond.user_activity WHERE user_id = ? ORDER BY activity_start ASC`, user_id).Iter()
	//loop through each activity
	for iter.Scan(&activity_start, &activity_id, &end_summary_json, &has_power, &has_heart) {
		iter := session.Query(`SELECT cp_data_json FROM joulepersecond.proc_activity WHERE activity_id = ? LIMIT 1`, activity_id).Iter()
		for iter.Scan(&cp_data_json) {
			json.Unmarshal(cp_data_json, &user_cpms)

		}
		if firstIter {
			firstDate = activity_start
			firstIter = false
		}
		var ff_data_point types.Ff_data_point
		//unmarshal the activtiy types.Metrics
		json.Unmarshal(end_summary_json, &user_data)

		//values for each scanned activity
		var user_tss int
		var perc_effort int
		var mot_level int

		//check for a tss override value
		session.Query(`SELECT activity_id, tss_value, motivation_level, perceived_effort FROM activity_meta WHERE activity_id = ?`, activity_id).Scan(&activity_id, &user_tss, &mot_level, &perc_effort)

		//get a value for tss whether from hr, power or (TODO user set)
		if user_tss > 0 {
			ff_data_point.Tss = user_tss
		} else {
			if has_power {
				ff_data_point.Tss = user_data.Tss
			} else if has_heart {
				ff_data_point.Tss = user_data.Etss
			}
		}

		if filter.S5 {
			thisCp = user_cpms.FiveSecondCP
		} else if filter.S20 {
			thisCp = user_cpms.TwentySecondCP
		} else if filter.S60 {
			thisCp = user_cpms.SixtySecondCP
		} else if filter.S300 {
			thisCp = user_cpms.FiveMinuteCP
		} else if filter.S1200 {
			thisCp = user_cpms.TwentyMinuteCP
		} else if filter.S3600 {
			thisCp = user_cpms.SixtyMinuteCP
		}

		if float64(thisCp) > lastNotableCp {
			lastNotableCp = float64(thisCp)
			ff_data_point.NotableCp = float64(thisCp)

		} else {
			lastNotableCp = lastNotableCp * float64(user.Ncp_rolloff) / 1000 //0.995 default
		}

		//get the date
		ff_data_point.Date = user_data.StartTime

		//add extended metrics
		ff_data_point.Meta.MotivationLevel = mot_level
		ff_data_point.Meta.PerceivedEffort = perc_effort

		//add date and tss to array slice
		ff_data = append(ff_data, ff_data_point)

	}
	if err := iter.Close(); err != nil {
		log.Fatal(err)
	}
	//calulate the number of days between first recorded activity and current date
	duration := time.Since(firstDate) //get total duration in time.Duration
	days := int(duration/day) + 1     //add one day to include current day

	//loop through each day.
	for i := 0; i <= days+30; i++ { //add 30 days to show roll off
		//create a var to hold a sample for each day scanned - it may or maynot contain an activity, but will still contain ctl, atl and tsb vals along with the date
		var scan_data_point types.Ff_data_point

		//get each day to be scanned (all days between first activity and current date)
		scanDate := firstDate.AddDate(0, 0, i)
		scan_data_point.Date = scanDate                 //get the date
		scanYear, scanMonth, scanDay := scanDate.Date() //get date elements that are easier to compare

		//these so we can print out UTC values to Highcharts
		scan_data_point.Day = scanDay
		scan_data_point.Month = int(scanMonth) - 1 //js months start at naught.
		scan_data_point.Year = scanYear

		//now get each of the days where we have an activity
		for _, val := range ff_data {
			actYear, actMonth, actDay := val.Date.Date()
			if actYear == scanYear && actMonth == scanMonth && actDay == scanDay {
				scan_data_point.Meta.PerceivedEffort = val.Meta.PerceivedEffort
				scan_data_point.Meta.MotivationLevel = val.Meta.MotivationLevel
				//these are the days where we have activites - add the TSS

				//we might have more than one activity in a day so append any others TSS on this day
				scan_data_point.Tss += val.Tss
				if val.NotableCp > 0 {
					scan_data_point.NotableCp = val.NotableCp
					scan_data_point.HasValue = true
				} else {
					scan_data_point.HasValue = false
				}

			}
			//else leave TSS as it is (0)
		}
		if i > 0 { //don't have a yesterday value on the first day
			scan_data_point.Atl = ff_scan_data[i-1].Atl + (float64(scan_data_point.Tss)-ff_scan_data[i-1].Atl)/float64(user.Atl_constant)
			scan_data_point.Ctl = ff_scan_data[i-1].Ctl + (float64(scan_data_point.Tss)-ff_scan_data[i-1].Ctl)/float64(user.Ctl_constant)
			scan_data_point.Tsb = scan_data_point.Ctl - scan_data_point.Atl
			//fmt.Printf("Atl: %v Ctl: %v Tsb: %v\n", scan_data_point.Atl, scan_data_point.Ctl, scan_data_point.Tsb)
		}

		//add the data to our array slice
		ff_scan_data = append(ff_scan_data, scan_data_point)

	}
	//OPTION (show reduced results) commenting out the follwing lines bypasses filter
	if len(ff_scan_data) > (filter.Historylen + 30) {
		ff_scan_data = ff_scan_data[len(ff_scan_data)-(filter.Historylen+30) : len(ff_scan_data)]
	}

	return ff_scan_data
}
Beispiel #2
0
func current_ff(user types.UserSettings) types.Current_ff {
	user_id := user.Id
	ff_data := make([]types.Ff_data_point, 0)      //activity day
	ff_scan_data := make([]types.Ff_data_point, 0) //all days in range

	var current_ff types.Current_ff

	var user_data types.Metrics
	var end_summary_json []byte
	var has_power, has_heart bool
	var activity_start time.Time
	var firstDate time.Time
	var firstIter = true

	var activity_id string
	var day = time.Hour * 24

	timeNow := time.Now()
	var recentMonths = timeNow.AddDate(0, -6, 0)

	cluster := gocql.NewCluster(config.DbHost)
	cluster.Keyspace = "joulepersecond"
	cluster.Consistency = gocql.Quorum
	session, _ := cluster.CreateSession()
	defer session.Close()

	//get all of the user's data (at least all for now) TODO limit these queries by date if poss.
	iter := session.Query(`SELECT activity_start, activity_id, end_summary_json, has_power, has_heart FROM joulepersecond.user_activity WHERE user_id = ? AND activity_start > ? ORDER BY activity_start ASC`, user_id, recentMonths).Iter()
	//loop through each activity
	for iter.Scan(&activity_start, &activity_id, &end_summary_json, &has_power, &has_heart) {
		if firstIter {
			firstDate = activity_start
			firstIter = false
		}
		var ff_data_point types.Ff_data_point
		//unmarshal the activtiy metrics
		json.Unmarshal(end_summary_json, &user_data)

		//values for each scanned activity
		var user_tss int

		//check for a tss override value
		session.Query(`SELECT activity_id, tss_value FROM activity_meta WHERE activity_id = ?`, activity_id).Scan(&activity_id, &user_tss)

		//get a value for tss whether from hr, power or (TODO user set)
		if user_tss > 0 {
			ff_data_point.Tss = user_tss
		} else {
			if has_power {
				ff_data_point.Tss = user_data.Tss
			} else if has_heart {
				ff_data_point.Tss = user_data.Etss
			}
		}
		//get the date
		ff_data_point.Date = user_data.StartTime

		//add date and tss to array slice
		ff_data = append(ff_data, ff_data_point)

	}
	if err := iter.Close(); err != nil {
		fmt.Printf("%v\n", err)
	}
	//calulate the number of days between first recorded activity and current date
	duration := time.Since(firstDate) //get total duration in time.Duration
	days := int(duration/day) + 1     //add one day to include current day

	//loop through each day.
	for i := 0; i <= days+30; i++ {
		//create a var to hold a sample for each day scanned - it may or maynot contain an activity, but will still contain ctl, atl and tsb vals along with the date
		var scan_data_point types.Ff_data_point

		//get each day to be scanned (all days between first activity and current date)
		scanDate := firstDate.AddDate(0, 0, i)
		scan_data_point.Date = scanDate                 //get the date
		scanYear, scanMonth, scanDay := scanDate.Date() //get date elements that are easier to compare

		//now get each of the days where we have an activity
		for _, val := range ff_data {

			actYear, actMonth, actDay := val.Date.Date()
			if actYear == scanYear && actMonth == scanMonth && actDay == scanDay {
				//these are the days where we have activites - add the TSS

				//we might have more than one activity in a day so append any others TSS on this day
				scan_data_point.Tss += val.Tss

			}
			//else leave TSS as it is (0)
		}
		if i > 0 { //don't have a yesterday value on the first day
			scan_data_point.Atl = ff_scan_data[i-1].Atl + (float64(scan_data_point.Tss)-ff_scan_data[i-1].Atl)/float64(user.Atl_constant)
			scan_data_point.Ctl = ff_scan_data[i-1].Ctl + (float64(scan_data_point.Tss)-ff_scan_data[i-1].Ctl)/float64(user.Ctl_constant)
			scan_data_point.Tsb = scan_data_point.Ctl - scan_data_point.Atl
		}

		//save off today's fitness and freshness...
		timeNow := time.Now()
		if scanDate.Year() == timeNow.Year() && scanDate.Month() == timeNow.Month() && scanDate.Day() == timeNow.Day() {
			current_ff.Atl = int(scan_data_point.Atl)
			current_ff.Ctl = int(scan_data_point.Ctl)
			current_ff.Tsb = int(scan_data_point.Tsb)

		}
		//add the data to our array slice
		ff_scan_data = append(ff_scan_data, scan_data_point)

	}
	return current_ff

}