Source for file PolarPdd.class.php
Documentation is available at PolarPdd.class.php
* Class to parse Polar PDD file and insert / update data to database
* PDD file contains data related to 1 day (including some exercise data).
* This data comes from Polar Software.
* @author Jean-Philippe Brunon <jp75018@free.fr>
* @copyright 2007-2009 Jean-Philippe Brunon
* @license http://www.opensource.org/licenses/gpl-license.php GPL
* @version $Id: PolarPdd.class.php 29 2009-03-06 11:47:52Z jp75018 $
* Class common to all Polar files
require_once ('PolarFile.class.php');
* Class to parse Polar PDD file and insert / update data to database
* PDD file contains data related to 1 day, including some exercise data.
* The following fields are handled when present in PDD file :
* - date : Date of day (format : YYYYMMDD)
* - resting_hr : Rest heart rate (bpm)
* - weight : Weight in Kg * 10
* - sleep_minute : Sleep duration in minutes
* - sleep_pattern : Quality of sleep (list of values)
* - temperature : Temperature (in Celcius * 10)
* - weather : Weather (list of values)
* - description : Note for the day
* Exercise info (for each exercise) :
* - title : Exercise title
* - start_time : Start time (format : HH:MM:SS)
* - no_report : No report flag (list of values)
* - total_time : Duration in seconds * 10
* - rec_distance : Recorded distance in meters * 10
* - real_distance : Real distance in meters * 10
* - feeling : Feeling (list of values)
* - recovery : Recovery (list of values)
* - ranking : Ranking from 1 to 5 (0 if no ranking)
* - running_index : Polar running index
* - footpod_cal : Foot pod calibration (coeff around 1000)
* - avg_hr : Average heart rate (bpm)
* - max_hr : Maximum heart rate (bpm)
* - avg_speed : Average speed in km/h * 10
* - max_speed : Maximum speed in km/h * 10
* - avg_cadence : Average cadence in cycles / minute
* - max_cadence : Maximum cadence in cycles / minute
* - avg_altitude : Average altitude in meters
* - max_altitude : Maximum altitude in meters
* - ascend : Ascend in meters
* - energy : Energy consumption (Polar) in Kcal
* - beat_sum : Number of heart beats
* - description : Note for exercise
* - hrm_file : HRM file name (parse only)
* List of sleep patterns values (from 0 to 4)
'excellent', 'normal', 'disturbed', 'insufficient', 'insomnia');
* List of weather values (from 1 to 5)
'sunny', 'fewclouds', 'cloudy', 'rainy', 'snowy');
* List of "no report" values (from 0 to 3)
'all', 'count', 'report', 'none');
* List of feeling values (from 0 to 5)
'excellent', 'good', 'average', 'bad', 'very_bad', 'hurt');
* List of recovery values (from 0 to 4)
'fully', 'recovered', 'normal', 'tired', 'exhausted');
* @param string $fileName Polar PDD file name (full path name)
* @param integer $userId User ID (as in database)
* Insert day information into database
* - plw_day_info (insert / update)
* - plw_exercise (insert / update)
* @param array $day Structure for day information + some exercise data:
* - 'dayinfo' : Day fields
* - 'exerciseinfo' : Array of exercise fields, indexed by
$exes =
$day['exerciseinfo'];
// 1. Insert / update day part
$request =
sprintf("INSERT INTO plw_day_info(user_id, day, cre_date, mod_date, rest_hr, weight, sleep_minute, sleep_pattern, temperature, weather, description) VALUES(%d, %s, NOW(), NOW(), %s, %s, %s, %s, %d, %s, %s) ON DUPLICATE KEY UPDATE cre_date=cre_date, mod_date=NOW(), rest_hr=%s, weight=%s, sleep_minute=%s, sleep_pattern=%s, temperature=%d, weather=%s, description=%s",
$info['resting_hr'] >
0 ?
$info['resting_hr'] :
'NULL',
$info['weight'] >
0 ?
$info['weight'] :
'NULL',
$info['sleep_minute'] >
0 ?
$info['sleep_minute'] :
'NULL',
$info['sleep_pattern'] > -
1 ?
'\'' .
$this->sleepPattern[$info['sleep_pattern']] .
'\'' :
'NULL',
'\'' .
$this->weather[$info['weather']] .
'\'' :
'NULL',
$info['description'] !=
'' ?
$info['resting_hr'] >
0 ?
$info['resting_hr'] :
'NULL',
$info['weight'] >
0 ?
$info['weight'] :
'NULL',
$info['sleep_minute'] >
0 ?
$info['sleep_minute'] :
'NULL',
$info['sleep_pattern'] > -
1 ?
'\'' .
$this->sleepPattern[$info['sleep_pattern']] .
'\'' :
'NULL',
'\'' .
$this->weather[$info['weather']] .
'\'' :
'NULL',
$info['description'] !=
'' ?
// 2. Insert / update exercise parts
// Note : rec_distance, avg/max hr, avg/max speed, avg/max acdence,
// avg/max altitude, ascend, beat_sum not updated
// (better from HRM file)
for ($i =
1; $i <=
count($exes); $i++
)
// Parse note to extract contest distance or interval training expression
$real_dist =
$exes[$i]['real_distance'];
$note =
$exes[$i]['description'];
$exercise_type =
'training';
&$exercise_type, &$exact_dist, &$int_train, &$options);
// Check parsed distance is close enough to recorded distance (15%)
if (($real_dist >
0) &&
($exercise_type ==
'contest'))
if (abs($exact_dist -
$real_dist) /
($exact_dist +
$real_dist)>
0.075)
$real_dist =
($exact_dist >
0) ?
$exact_dist :
$real_dist;
// Note : elapsed not updated (1/10 second precision in HRM file)
// If no HRM file => Insert with 'online' status (manual data case)
// In this case => Take rank = Polar rank + 100 to avoid collisions
if ($exes[$i]['hrm_file'])
$exe_rank = (int)
substr($exes[$i]['hrm_file'],6,2);
$request =
sprintf("INSERT INTO plw_exercise(user_id, day, rank, status, cre_date, mod_date, sport_id, title, start_time, in_reports, elapsed, rec_distance, real_distance, feeling, recovery, ranking, running_index, footpod_cal, avg_hr, max_hr, avg_speed, max_speed, avg_cadence, max_cadence, avg_altitude, max_altitude, ascend, energy, beat_sum, exercise_type, description, shoe, shoe_ini_dist, footpod_id, footpod_batt) VALUES(%d, %s, %d, '%s', NOW(), NOW(), %d, %s, %s, %s, %d, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, '%s', %s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE status=IF(status='empty','empty','online'), cre_date=cre_date, mod_date=NOW(), sport_id=%d, title=%s, start_time=%s, in_reports=%s, real_distance=%d, feeling=%s, recovery=%s, ranking=%d, running_index=%d, footpod_cal=%d, energy=%d, exercise_type='%s', description=%s, shoe=%s, shoe_ini_dist=%s, footpod_id=%s, footpod_batt=%s",
$this->userId, $info['date'], $exe_rank, $exe_status,
$exes[$i]['title'] !=
'' ?
$exes[$i]['no_report'] > -
1 ?
'\'' .
$this->inReports[$exes[$i]['no_report']] .
'\'' :
'NULL',
$exes[$i]['rec_distance'] >
0 ?
$exes[$i]['rec_distance'] :
'NULL',
$real_dist >
0 ?
$real_dist :
'NULL',
$exes[$i]['feeling'] > -
1 ?
'\'' .
$this->feeling[$exes[$i]['feeling']] .
'\'' :
'NULL',
$exes[$i]['recovery'] > -
1 ?
'\'' .
$this->recovery[$exes[$i]['recovery']] .
'\'' :
'NULL',
$exes[$i]['ranking'] >
0 ?
$exes[$i]['ranking'] :
'NULL',
$exes[$i]['running_index'] >
0 ?
$exes[$i]['running_index'] :
'NULL',
$exes[$i]['footpod_cal'] >
0 ?
$exes[$i]['footpod_cal'] :
'NULL',
$exes[$i]['avg_hr'] >
0 ?
$exes[$i]['avg_hr'] :
'NULL',
$exes[$i]['max_hr'] >
0 ?
$exes[$i]['max_hr'] :
'NULL',
$exes[$i]['avg_speed'] >
0 ?
$exes[$i]['avg_speed'] :
'NULL',
$exes[$i]['max_speed'] >
0 ?
$exes[$i]['max_speed'] :
'NULL',
$exes[$i]['avg_cadence'] >
0 ?
$exes[$i]['avg_cadence'] :
'NULL',
$exes[$i]['max_cadence'] >
0 ?
$exes[$i]['max_cadence'] :
'NULL',
(($exes[$i]['avg_altitude'] !=
0) ||
($exes[$i]['ascend'] >
0)) ?
$exes[$i]['avg_altitude'] :
'NULL',
(($exes[$i]['avg_altitude'] !=
0) ||
($exes[$i]['ascend'] >
0)) ?
$exes[$i]['max_altitude'] :
'NULL',
(($exes[$i]['avg_altitude'] !=
0) ||
($exes[$i]['ascend'] >
0)) ?
$exes[$i]['ascend'] :
'NULL',
$exes[$i]['energy'] >
0 ?
$exes[$i]['energy'] :
'NULL',
$exes[$i]['beat_sum'] >
0 ?
$exes[$i]['beat_sum'] :
'NULL',
isset
($options['shoe_ini_dist']) ?
$options['shoe_ini_dist'] :
'NULL',
isset
($options['footpod_id']) ?
$options['footpod_id'] :
'NULL',
isset
($options['footpod_batt']) ?
$options['footpod_batt'] :
'NULL',
$exes[$i]['title'] !=
'' ?
$exes[$i]['no_report'] > -
1 ?
'\'' .
$this->inReports[$exes[$i]['no_report']] .
'\'' :
'NULL',
$real_dist >
0 ?
$real_dist :
'NULL',
$exes[$i]['feeling'] > -
1 ?
'\'' .
$this->feeling[$exes[$i]['feeling']] .
'\'' :
'NULL',
$exes[$i]['recovery'] > -
1 ?
'\'' .
$this->recovery[$exes[$i]['recovery']] .
'\'' :
'NULL',
$exes[$i]['ranking'] >
0 ?
$exes[$i]['ranking'] :
'NULL',
$exes[$i]['running_index'] >
0 ?
$exes[$i]['running_index'] :
'NULL',
$exes[$i]['footpod_cal'] >
0 ?
$exes[$i]['footpod_cal'] :
'NULL',
$exes[$i]['energy'] >
0 ?
$exes[$i]['energy'] :
'NULL',
isset
($options['shoe_ini_dist']) ?
$options['shoe_ini_dist'] :
'NULL',
isset
($options['footpod_id']) ?
$options['footpod_id'] :
'NULL',
isset
($options['footpod_batt']) ?
$options['footpod_batt'] :
'NULL'
// Get exercise ID to work with interval training
// Insert interval training elements, delete first
$request =
sprintf("DELETE FROM plw_int_training WHERE exercise_id=%d",
for ($int =
0; $int <
count($int_train); $int++
)
$train =
$int_train[$int];
$request =
sprintf("INSERT INTO plw_int_training(exercise_id, rank, repeat_nb, work_distance, work_duration, reco_distance, reco_duration) VALUES (%d, %d, %d, %s, %s, %s, %s)",
$exercise_id, $int, $train['repeat_nb'],
$train['work_distance'] >
0 ?
$train['work_distance'] :
'NULL',
$train['work_duration'] >
0 ?
$train['work_duration'] :
'NULL',
$train['reco_distance'] >
0 ?
$train['reco_distance'] :
'NULL',
$train['reco_duration'] >
0 ?
$train['reco_duration'] :
'NULL'
* Parse Polar PDD file (day information, including some exercise data)
* Note : Both <dayinfo> and <exerciseinfo> blocks are parsed.
* @return array Structure for day and exercises :
* - 'dayinfo' : Day fields
* - 'exerciseinfo' : Exercise fields, indexed by rank
while ($line_no <
count($buffer))
$begin_block =
$line_no +
1;
$lg_block =
$line_no -
$begin_block -
1;
if (! trim($buffer[$end_block]))
if (substr($block_name, 0, 12) ==
'exerciseinfo')
$exercise_nb = (int)
substr($block_name, 12);
$day['exerciseinfo'][$exercise_nb] =
$parse_func =
'_parse_block_' .
$block_name .
'_get';
$this->$parse_func(&$buffer, $begin_block, $lg_block);
// Check day match filename !
$data_day =
$day['dayinfo']['date'];
if ($file_day !=
$data_day)
* Parse <dayinfo> block in PDD file
* @param string $buffer Buffer with PDD file content
* @param integer $start Line number of block in buffer
* @param integer $nb Number of lines in block
* @return array Fields of day
$dayinfo->version =
$row[0];
$day['version'] =
$row[0];
$day['exercise_nb'] =
$row[1];
$day['resting_hr'] =
$row[2];
$day['weight'] =
round($row[4] /
10);
$day['sleep_minute'] =
round($row[5] /
60);
$day['sleep_pattern'] =
$row[0];
$day['weather'] =
$row[3];
$day['temperature'] =
$row[4];
for ($i =
0; $i <
$text_row_nb; $i++
)
{ $day['description'] .=
'\n'; }
trim($buffer[$start +
$info_row_nb +
$num_row_nb +
$i]);
* Parse <exerciseinfo> block in PDD file
* @param string $buffer Buffer with PDD file content
* @param integer $start Line number of block in buffer
* @param integer $nb Number of lines in block
* @return array Array of exercises, indexed by rank
$exercise['version'] =
$row[0];
$row =
explode("\t", trim($buffer[$start +
$info_row_nb]));
$exercise['no_report'] =
$row[1];
$exercise['rec_distance'] =
$row[3];
$exercise['start_time'] =
sprintf("%02d%02d%02d", floor($row[4] /
3600),
floor($row[4]/
60) -
60*
floor($row[4]/
3600), $row[4] %
60);
$exercise['total_time'] =
10 *
$row[5];
$row =
explode("\t", trim($buffer[$start +
$info_row_nb +
1]));
$exercise['sport_id'] =
$row[0];
$exercise['feeling'] =
$row[2];
$exercise['recovery'] =
$row[3];
$exercise['energy'] =
$row[5];
$row =
explode("\t", trim($buffer[$start +
$info_row_nb +
2]));
$exercise['real_distance'] =
$row[0];
$exercise['ascend'] =
$row[5];
$row =
explode("\t", trim($buffer[$start +
$info_row_nb +
7]));
$exercise['recording_rate'] =
$row[4];
$exercise['orig_ascend'] =
$row[5];
$row =
explode("\t", trim($buffer[$start +
$info_row_nb +
8]));
$exercise['avg_hr'] =
$row[0];
$exercise['max_hr'] =
$row[1];
$exercise['avg_speed'] =
$row[2];
$exercise['max_speed'] =
$row[3];
$exercise['avg_cadence'] =
$row[4];
$exercise['max_cadence'] =
$row[5];
$row =
explode("\t", trim($buffer[$start +
$info_row_nb +
9]));
$exercise['avg_altitude'] =
$row[0];
$exercise['max_altitude'] =
$row[1];
$row =
explode("\t", trim($buffer[$start +
$info_row_nb +
11]));
$exercise['avg_calory_rate'] =
$row[0];
$exercise['beat_sum'] =
$row[2];
$exercise['orig_energy'] =
$row[5];
$row =
explode("\t", trim($buffer[$start +
$info_row_nb +
14]));
$exercise['ranking'] =
$row[1];
$exercise['running_index'] =
$row[3];
$row =
explode("\t", trim($buffer[$start +
$info_row_nb +
15]));
$exercise['footpod_cal'] =
$row[3];
$exercise['title'] =
trim($buffer[$start +
$info_row_nb +
$num_row_nb]);
$exercise['description'] =
trim($buffer[$start +
$info_row_nb +
$num_row_nb +
1]);
trim($buffer[$start +
$info_row_nb +
$num_row_nb +
2]);
Documentation generated on Sat, 28 Mar 2009 23:16:54 +0000 by phpDocumentor 1.4.1