polyvertex / fitdecode

A FIT file parsing and decoding library written in Python3
MIT License
155 stars 33 forks source link

KeyError when adding dev field description for Apple Watch .fit files #10

Closed wjkaufman closed 3 years ago

wjkaufman commented 4 years ago

When trying to parse a .fit file recorded on an Apple Watch, the following error occurs:

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-4-c6809f50fb7e> in <module>
      2 
      3 with fd.FitReader(file_name) as fit:
----> 4     for frame in fit:
      5         if isinstance(frame, fd.FitHeader):
      6             continue

~/anaconda3/lib/python3.7/site-packages/fitdecode/reader.py in __iter__(self)
    191 
    192     def __iter__(self):
--> 193         yield from self._read_next()
    194 
    195     @property

~/anaconda3/lib/python3.7/site-packages/fitdecode/reader.py in _read_next(self)
    298                 assert self._header
    299 
--> 300                 record = self._read_record()
    301                 if not record:
    302                     break

~/anaconda3/lib/python3.7/site-packages/fitdecode/reader.py in _read_record(self)
    443                     self._add_dev_data_id(message)
    444                 elif message.mesg_type.mesg_num == profile.MESG_NUM_FIELD_DESCRIPTION:
--> 445                     self._add_dev_field_description(message)
    446 
    447         return message

~/anaconda3/lib/python3.7/site-packages/fitdecode/reader.py in _add_dev_field_description(self, message)
    780         base_type_id = message.get_field('fit_base_type_id').raw_value
    781         field_name = message.get_field('field_name').raw_value
--> 782         units = message.get_field('units').raw_value
    783 
    784         # try:

~/anaconda3/lib/python3.7/site-packages/fitdecode/records.py in get_field(self, field_name_or_num, idx)
    188         raise KeyError(
    189             f'field "{field_name_or_num}" (idx #{idx}) not found in ' +
--> 190             f'message "{self.name}"')
    191 
    192     def get_fields(self, field_name_or_num):

KeyError: 'field "units" (idx #0) not found in message "field_description"'

It looks like there isn't a "units" field for the given message. It seems like adding a try statement to https://github.com/polyvertex/fitdecode/blob/master/fitdecode/reader.py#L782 does the trick:

try:
    units = message.get_field('units').raw_value
except KeyError:
    units = None
polyvertex commented 3 years ago

Quite reluctant to blindly apply a patch for device compat but well, thanks for reporting this!