Skip to content

Commit

Permalink
save fields on message
Browse files Browse the repository at this point in the history
  • Loading branch information
sportlog committed Jan 4, 2021
1 parent d801ee6 commit 453028f
Show file tree
Hide file tree
Showing 92 changed files with 5,721 additions and 2,372 deletions.
31 changes: 23 additions & 8 deletions config/MessageGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ private function generateFiles($handle): array
$printer = new PsrPrinter();
$file = null;
$class = null;
$fields = [];
$files = [];

$fitBaseTypeReflection = new ReflectionClass(FitBaseType::class);
Expand Down Expand Up @@ -81,10 +82,6 @@ private function generateFiles($handle): array
$class->setFinal(true)
->addComment("{$classname} message")
->setExtends(Message::class);

$method = $class->addMethod('__construct')
->addComment("Creates a new message instance")
->setBody(sprintf('parent::__construct("%1$s", MessageNumber::%1$s);', $classId));
}

if (str_starts_with($line, self::FIELD_START) && !is_null($file)) {
Expand All @@ -102,7 +99,6 @@ private function generateFiles($handle): array
$units = substr($units, 1, strlen($units) - 2);

$phpType = Type::MIXED;
$phpTypeNullable = false;
switch ($profileType) {
case ProfileType::BOOL:
$phpType = Type::BOOL;
Expand All @@ -122,7 +118,6 @@ private function generateFiles($handle): array
case ProfileType::LOCALDATETIME:
case ProfileType::DATETIME:
$phpType = \DateTime::class;
$phpTypeNullable = true;
break;

case ProfileType::STRING:
Expand All @@ -146,16 +141,36 @@ private function generateFiles($handle): array
}

/** @var ClassType $class */
$class->addProperty(lcfirst($name))
/*$class->addProperty(lcfirst($name))
->setType($phpType)
->setNullable()
->addAttribute(Field::class, [$name, (int)$num,
new Literal("FitBaseType::" . $fitBaseTypeConstants[(int)$type]), (float)$scale, (float)$offset, $units,
$accumulated === 'true', new Literal("ProfileType::" . strtoupper($profileType))]);
$accumulated === 'true', new Literal("ProfileType::" . strtoupper($profileType))]);*/

$class->addMethod("get{$name}")
->setPublic()
->setReturnType($phpType)
->setReturnNullable()
->setBody('return $this->getValue(?);', [(int)$num]);


$fields[] = "new Field(" . join(", ", ["'{$name}'", (int)$num, new Literal("FitBaseType::" . $fitBaseTypeConstants[(int)$type]),
number_format((float)$scale, 1, '.', ''), number_format((float)$offset, 1, '.', ''),
"'{$units}'", $accumulated, new Literal("ProfileType::" . strtoupper($profileType))]) . ")";


}

if (str_starts_with($line, self::MESSAGE_END) && !is_null($file)) {
$method = $class->addMethod('__construct')
->addComment("Creates a new message instance")
->setBody(sprintf('parent::__construct("%1$s", MessageNumber::%1$s, [%3$s%2$s%3$s]);', $classId, join(", " . PHP_EOL . " ", $fields), PHP_EOL));

$files[$class->getName() . ".php"] = $printer->printFile($file);
$class = null;
// echo print_r($fields, true) . "<br>";
$fields = [];
}
}

Expand Down
10 changes: 3 additions & 7 deletions src/Decoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ private function nextRecordData(int $localMessagType, IOReader $reader): Message

// Assoociative array with the field definition number as key
// and it's decoded value.
$fields = [];
$message = MessageFactory::create($definition['global_message_number']);
foreach ($definition['field_definitions'] as $fieldDefinition) {
$size = $fieldDefinition['size'];
$fitBaseType = FitBaseType::fromType($fieldDefinition['base_type']);
Expand Down Expand Up @@ -122,13 +122,9 @@ private function nextRecordData(int $localMessagType, IOReader $reader): Message
$tmpSize -= $fitBaseTypeSize;
}
}
$fields[$fieldDefinition['field_definition_number']] = [
'value' => $fieldValue,
'type' => $fitBaseType
];
$message->setValue($fieldDefinition['field_definition_number'], $fieldValue, $fitBaseType);
}

$message = MessageFactory::create($definition['global_message_number'], $fields);

$this->logger->info("Data for '{$localMessagType}'");

return $message;
Expand Down
92 changes: 85 additions & 7 deletions src/Profile/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,28 @@
namespace FIT\Profile;

use ArrayIterator;
use DateTime;
use Exception;
use FIT\FitBaseType;
use FIT\FitBaseTypeDefinition;
use IteratorAggregate;
use Stringable;

abstract class Message implements IteratorAggregate, Stringable
{
public $values = [];
private $values = [];
private array $fields = [];

public function __construct(private string $name, private int $number)
public function __construct(private string $name, private int $number, array $fields = [])
{
foreach ($fields as $field) {
$this->addField($field);
}
}

public function addField(Field $field): void
{
$this->fields[$field->getNumber()] = $field;
}

/**
Expand All @@ -29,7 +42,8 @@ public function __construct(private string $name, private int $number)
*
* @return integer
*/
public function getMessageNumber(): int {
public function getMessageNumber(): int
{
return $this->number;
}

Expand All @@ -38,11 +52,13 @@ public function getMessageNumber(): int {
*
* @return string
*/
public function getName(): string {
public function getName(): string
{
return $this->name;
}

public function __toString() {
public function __toString()
{
return sprintf('%s (%s)', $this->getName(), $this->getMessageNumber());
/*$mapped = [];
Expand All @@ -64,7 +80,34 @@ public function __toString() {
*/
}

/**
public function getValue(int|string $fieldNumber): mixed
{
return isset($this->values[$fieldNumber]) ? $this->values[$fieldNumber] : null;
}

public function setValue(int $fieldNumber, mixed $value, FitBaseTypeDefinition $fitBaseType): void
{
$field = $this->getField($fieldNumber);
if ($field !== null) {
$baseType = FitBaseType::fromType($field->getType());
if ($baseType !== $fitBaseType) {
throw new Exception(sprintf(
'mismatch between base type in FIT message and base type declared in meta data of property "%s::%s".
Base type from FIT file is "%s", base type from property meta is "%s"',
self::class,
$field->getName(),
$fitBaseType->getName(),
$baseType->getName()
));
}

$value = $this->convertValueToFieldType($field, $value);
}

$this->values[$fieldNumber] = $value;
}

/**
* Gets an iterator.
*
* {@inheritDoc}
Expand All @@ -74,4 +117,39 @@ public function getIterator()
{
return new ArrayIterator($this->values);
}
}

public function getField(int $fieldNumber): ?Field
{
return isset($this->fields[$fieldNumber]) ? $this->fields[$fieldNumber] : null;
}

private function convertValueToFieldType(Field $field, mixed $value): mixed
{
$value /= $field->getScale();
$value -= $field->getOffset();

switch ($field->getProfileType()) {
case ProfileType::BOOL:
return $value !== 0;

case ProfileType::UINT8:
case ProfileType::SINT8:
case ProfileType::UINT16:
case ProfileType::SINT16:
case ProfileType::UINT16Z:
case ProfileType::UINT32:
case ProfileType::UINT32Z;
case ProfileType::SINT32:
return intval($value);

case ProfileType::LOCALDATETIME:
case ProfileType::DATETIME:
$date = new DateTime();
$date->setTimestamp(intval($value) + 631065600);
return $date;

default:
return $value;
}
}
}
87 changes: 62 additions & 25 deletions src/Profile/Message/AccelerometerDataMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,47 +21,84 @@
*/
final class AccelerometerDataMessage extends Message
{
#[Field('Timestamp', 253, FitBaseType::UINT32, 1.0, 0.0, 's', false, ProfileType::DATETIME)]
public ?DateTime $timestamp;
public function getTimestamp(): ?DateTime
{
return $this->getValue(253);
}

#[Field('TimestampMs', 0, FitBaseType::UINT16, 1.0, 0.0, 'ms', false, ProfileType::UINT16)]
public ?int $timestampMs;
public function getTimestampMs(): ?int
{
return $this->getValue(0);
}

#[Field('SampleTimeOffset', 1, FitBaseType::UINT16, 1.0, 0.0, 'ms', false, ProfileType::UINT16)]
public ?int $sampleTimeOffset;
public function getSampleTimeOffset(): ?int
{
return $this->getValue(1);
}

#[Field('AccelX', 2, FitBaseType::UINT16, 1.0, 0.0, 'counts', false, ProfileType::UINT16)]
public ?int $accelX;
public function getAccelX(): ?int
{
return $this->getValue(2);
}

#[Field('AccelY', 3, FitBaseType::UINT16, 1.0, 0.0, 'counts', false, ProfileType::UINT16)]
public ?int $accelY;
public function getAccelY(): ?int
{
return $this->getValue(3);
}

#[Field('AccelZ', 4, FitBaseType::UINT16, 1.0, 0.0, 'counts', false, ProfileType::UINT16)]
public ?int $accelZ;
public function getAccelZ(): ?int
{
return $this->getValue(4);
}

#[Field('CalibratedAccelX', 5, FitBaseType::FLOAT32, 1.0, 0.0, 'g', false, ProfileType::FLOAT32)]
public ?float $calibratedAccelX;
public function getCalibratedAccelX(): ?float
{
return $this->getValue(5);
}

#[Field('CalibratedAccelY', 6, FitBaseType::FLOAT32, 1.0, 0.0, 'g', false, ProfileType::FLOAT32)]
public ?float $calibratedAccelY;
public function getCalibratedAccelY(): ?float
{
return $this->getValue(6);
}

#[Field('CalibratedAccelZ', 7, FitBaseType::FLOAT32, 1.0, 0.0, 'g', false, ProfileType::FLOAT32)]
public ?float $calibratedAccelZ;
public function getCalibratedAccelZ(): ?float
{
return $this->getValue(7);
}

#[Field('CompressedCalibratedAccelX', 8, FitBaseType::SINT16, 1.0, 0.0, 'mG', false, ProfileType::SINT16)]
public ?int $compressedCalibratedAccelX;
public function getCompressedCalibratedAccelX(): ?int
{
return $this->getValue(8);
}

#[Field('CompressedCalibratedAccelY', 9, FitBaseType::SINT16, 1.0, 0.0, 'mG', false, ProfileType::SINT16)]
public ?int $compressedCalibratedAccelY;
public function getCompressedCalibratedAccelY(): ?int
{
return $this->getValue(9);
}

#[Field('CompressedCalibratedAccelZ', 10, FitBaseType::SINT16, 1.0, 0.0, 'mG', false, ProfileType::SINT16)]
public ?int $compressedCalibratedAccelZ;
public function getCompressedCalibratedAccelZ(): ?int
{
return $this->getValue(10);
}

/**
* Creates a new message instance
*/
public function __construct()
{
parent::__construct("AccelerometerData", MessageNumber::AccelerometerData);
parent::__construct("AccelerometerData", MessageNumber::AccelerometerData, [
new Field('Timestamp', 253, FitBaseType::UINT32, 1.0, 0.0, 's', false, ProfileType::DATETIME),
new Field('TimestampMs', 0, FitBaseType::UINT16, 1.0, 0.0, 'ms', false, ProfileType::UINT16),
new Field('SampleTimeOffset', 1, FitBaseType::UINT16, 1.0, 0.0, 'ms', false, ProfileType::UINT16),
new Field('AccelX', 2, FitBaseType::UINT16, 1.0, 0.0, 'counts', false, ProfileType::UINT16),
new Field('AccelY', 3, FitBaseType::UINT16, 1.0, 0.0, 'counts', false, ProfileType::UINT16),
new Field('AccelZ', 4, FitBaseType::UINT16, 1.0, 0.0, 'counts', false, ProfileType::UINT16),
new Field('CalibratedAccelX', 5, FitBaseType::FLOAT32, 1.0, 0.0, 'g', false, ProfileType::FLOAT32),
new Field('CalibratedAccelY', 6, FitBaseType::FLOAT32, 1.0, 0.0, 'g', false, ProfileType::FLOAT32),
new Field('CalibratedAccelZ', 7, FitBaseType::FLOAT32, 1.0, 0.0, 'g', false, ProfileType::FLOAT32),
new Field('CompressedCalibratedAccelX', 8, FitBaseType::SINT16, 1.0, 0.0, 'mG', false, ProfileType::SINT16),
new Field('CompressedCalibratedAccelY', 9, FitBaseType::SINT16, 1.0, 0.0, 'mG', false, ProfileType::SINT16),
new Field('CompressedCalibratedAccelZ', 10, FitBaseType::SINT16, 1.0, 0.0, 'mG', false, ProfileType::SINT16)
]);
}
}
Loading

0 comments on commit 453028f

Please sign in to comment.