fgebhart / workoutizer

:weight_lifting: Browser based Sport and Workout Organizer :running_woman:
MIT License
62 stars 11 forks source link

[BUG] 920xt not mounting automatically #167

Closed gotiniens closed 3 years ago

gotiniens commented 3 years ago

Describe the bug Garmin Device 920xt is not mounted automatically after following Readme.md. Failing with an gio error To Reproduce Steps to reproduce the behavior:

  1. Follow Readme to install on Raspberry pi
  2. Connect 920XT
  3. See error:
    06-22 21:48:50 - DEBUG - wkz.file_helper.fit_collector - trying to mount device...
    06-22 21:48:50 - DEBUG - wkz.file_helper.fit_collector - found Garmin device in: Bus 001 Device 006: ID 091e:26e5 Garmin International 
    gio: /dev/bus/usb/001/006: No volume for device file
    06-22 21:48:50 - WARNING - wkz.file_helper.fit_collector - could not mount device: Command '['gio', 'mount', '-d', '/dev/bus/usb/001/006']' returned non-zero exit status 2.
    Traceback (most recent call last):
    File "/home/pi/venv/lib/python3.7/site-packages/wkz/file_helper/fit_collector.py", line 92, in try_to_mount_device
    mount_output = _mount_device_using_gio(bus, dev)
    File "/home/pi/venv/lib/python3.7/site-packages/wkz/file_helper/fit_collector.py", line 112, in _mount_device_using_gio
    return subprocess.check_output(["gio", "mount", "-d", f"/dev/bus/usb/{bus}/{dev}"]).decode("utf-8")
    File "/usr/lib/python3.7/subprocess.py", line 395, in check_output
    **kwargs).stdout
    File "/usr/lib/python3.7/subprocess.py", line 487, in run
    output=stdout, stderr=stderr)
    subprocess.CalledProcessError: Command '['gio', 'mount', '-d', '/dev/bus/usb/001/006']' returned non-zero exit status 2.
    06-22 21:48:50 - ERROR - wkz.api - could not mount device, no valid mount path available - got: None
    06-22 21:48:50 - ERROR - django.request - Internal Server Error: /mount-device/
    06-22 21:48:50 - ERROR - django.channels.server - HTTP POST /mount-device/ 500 [0.12, 192.168.2.146:40772]

Additional context I found a mention of the same problem in issue #90 , But I can not find the solution. I have the feeling it is because your device is mounted as an MTP device, and mine should be mounted as an block device.

Following the https://github.com/fgebhart/workoutizer/blob/main/setup/other/debugging.md I found the following info:

pi@raspberrypi:~ $ gio mount -d /dev/bus/usb/001/007
gio: /dev/bus/usb/001/007: No volume for device file
pi@raspberrypi:~ $ 
pi@raspberrypi:~ $ udevadm info --name=/dev/bus/usb/001/007 --query=property
DEVPATH=/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.3
DEVNAME=/dev/bus/usb/001/007
DEVTYPE=usb_device
DRIVER=usb
PRODUCT=91e/26e5/509
TYPE=0/0/0
BUSNUM=001
DEVNUM=007
MAJOR=189
MINOR=6
SUBSYSTEM=usb
USEC_INITIALIZED=4529355716
ID_VENDOR=091e
ID_VENDOR_ENC=091e
ID_VENDOR_ID=091e
ID_MODEL=26e5
ID_MODEL_ENC=26e5
ID_MODEL_ID=26e5
ID_REVISION=0509
ID_SERIAL=091e_26e5
ID_BUS=usb
ID_USB_INTERFACES=:080650:
ID_VENDOR_FROM_DATABASE=Garmin International
pi@raspberrypi:~ $ cat /proc/partitions 
major minor  #blocks  name

   1        0       4096 ram0
   1        1       4096 ram1
   1        2       4096 ram2
   1        3       4096 ram3
   1        4       4096 ram4
   1        5       4096 ram5
   1        6       4096 ram6
   1        7       4096 ram7
   1        8       4096 ram8
   1        9       4096 ram9
   1       10       4096 ram10
   1       11       4096 ram11
   1       12       4096 ram12
   1       13       4096 ram13
   1       14       4096 ram14
   1       15       4096 ram15
 179        0   31226880 mmcblk0
 179        1     262144 mmcblk0p1
 179        2   30960640 mmcblk0p2
   8        0      11238 sda

My own debugging also resulted in some info:

pi@raspberrypi:~ $ gio mount --list --detail
Drive(0): USDU1
  Type: GProxyDrive (GProxyVolumeMonitorUDisks2)
  ids:
   unix-device: '/dev/mmcblk0'
  themed icons:  [drive-removable-media-flash-sd]  [drive-removable-media-flash]  [drive-removable-media]  [drive-removable]  [drive]  [drive-removable-media-flash-sd-symbolic]  [drive-removable-media-flash-symbolic]  [drive-removable-media-symbolic]  [drive-removable-symbolic]  [drive-symbolic]
  symbolic themed icons:  [drive-removable-media-symbolic]  [drive-removable-symbolic]  [drive-symbolic]  [drive-removable-media]  [drive-removable]  [drive]
  is_removable=1
  is_media_removable=1
  has_media=1
  is_media_check_automatic=1
  can_poll_for_media=0
  can_eject=0
  can_start=0
  can_stop=0
  start_stop_type=shutdown
  sort_key=00coldplug/12removable/mmcblk0
Drive(1): Garmin FR920 FLASH
  Type: GProxyDrive (GProxyVolumeMonitorUDisks2)
  ids:
   unix-device: '/dev/sda'
  themed icons:  [drive-removable-media-usb]  [drive-removable-media]  [drive-removable]  [drive]  [drive-removable-media-usb-symbolic]  [drive-removable-media-symbolic]  [drive-removable-symbolic]  [drive-symbolic]
  symbolic themed icons:  [drive-removable-media-usb-symbolic]  [drive-removable-media-symbolic]  [drive-removable-symbolic]  [drive-symbolic]  [drive-removable-media-usb]  [drive-removable-media]  [drive-removable]  [drive]
  is_removable=1
  is_media_removable=1
  has_media=1
  is_media_check_automatic=1
  can_poll_for_media=0
  can_eject=1
  can_start=0
  can_stop=0
  start_stop_type=shutdown
  sort_key=01hotplug/1624392348454994
  Volume(0): GARMIN
    Type: GProxyVolume (GProxyVolumeMonitorUDisks2)
    ids:
     class: 'device'
     unix-device: '/dev/sda'
     label: 'GARMIN'
    themed icons:  [drive-removable-media-usb]  [drive-removable-media]  [drive-removable]  [drive]  [drive-removable-media-usb-symbolic]  [drive-removable-media-symbolic]  [drive-removable-symbolic]  [drive-symbolic]
    symbolic themed icons:  [drive-removable-media-usb-symbolic]  [drive-removable-media-symbolic]  [drive-removable-symbolic]  [drive-symbolic]  [drive-removable-media-usb]  [drive-removable-media]  [drive-removable]  [drive]
    can_mount=1
    can_eject=1
    should_automount=0
    sort_key=gvfs.time_detected_usec.1624392348562305
fgebhart commented 3 years ago

So from what I can see the following is happening:

  1. You connect your device via USB
  2. udev detects the connected device and calls the systemd wkz_mount.service
  3. the systemd service in turn triggers the workoutizer api endpoint mount-device
  4. workoutizer fails to mount the device

At least the first three steps are successful. The system recognizes the connected device, which is a good thing.

Unfortunately I don't have a 920XT laying around πŸ˜‰ so I'm not able to reproduce this. But one thing that directly pops to my mind is that I'm able to configure the "USB Mode" of my watch. When navigating to Settings > System > USB Mode I am able to select either "MTB (Media Transfer)" or "Garmin". Setting this to "MTP (Media Transfer)" allows workoutizer to successfully mount the device. Could you have a look if there is a similar option on your device?

gotiniens commented 3 years ago

Yes only the last part is failing, I used the API call during debugging to initiate the mount, because the raspberry was not near me.

I understand you don't own every Garmin device available, We can not all be DCRainmaker. I do also have an 910xt which is a future project, because it uses only ANT for fit file transfer. But i'm willing to help the project as much as I can, so I can troubleshoot/research this issue.

Unfortunately my device does not have the "USB Mode" setting

Can you send the output of the following commands, when your device is connected?:

gio mount --list --detail
gio mount -d /dev/bus/usb/{BUS}/{DEV}
udevadm info --name=/dev/bus/usb/{BUS}/{DEV} --query=property
cat /proc/partitions
fgebhart commented 3 years ago

Sure, find the output of the commands when my device is connected below.

Have you tried connecting your watch to your ubuntu machine? I learned that ubuntu does a great job in terms of auto-mounting my device. Could be helpful to compare the two setups and settings.

Having connected my FR645 on my RPI 3B:

 $ gio mount --list --detail
Drive(0): SC16G
  Type: GProxyDrive (GProxyVolumeMonitorUDisks2)
  ids:
   unix-device: '/dev/mmcblk0'
  themed icons:  [drive-removable-media-flash-sd]  [drive-removable-media-flash]  [drive-removable-media]  [drive-removable]  [drive]  [drive-removable-media-flash-sd-symbolic]
[drive-removable-media-flash-symbolic]  [drive-removable-media-symbolic]  [drive-removable-symbolic]  [drive-symbolic]
  symbolic themed icons:  [drive-removable-media-symbolic]  [drive-removable-symbolic]  [drive-symbolic]  [drive-removable-media]  [drive-removable]  [drive]
  is_removable=1
  is_media_removable=1
  has_media=1
  is_media_check_automatic=1
  can_poll_for_media=0
  can_eject=0
  can_start=0
  can_stop=0
  start_stop_type=shutdown
  sort_key=00coldplug/12removable/mmcblk0
Volume(0): 091e 4b48
  Type: GProxyVolume (GProxyVolumeMonitorMTP)
  ids:
   unix-device: '/dev/bus/usb/001/006'
  activation_root=mtp://091e_4b48_0000c4fa0516/
  themed icons:  [phone]
  symbolic themed icons:  [phone-symbolic]  [phone]
  can_mount=1
  can_eject=0
  should_automount=1
$ gio mount -d /dev/bus/usb/{BUS}/{DEV}
Mounted /dev/bus/usb/001/006 at /run/user/1000/gvfs/mtp:host=091e_4b48_0000c4fa0516
$ udevadm info --name=/dev/bus/usb/001/006 --query=property
DEVPATH=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4
DEVNAME=/dev/bus/usb/001/006
DEVTYPE=usb_device
DRIVER=usb
PRODUCT=91e/4b48/1
TYPE=0/0/0
BUSNUM=001
DEVNUM=006
MAJOR=189
MINOR=5
SUBSYSTEM=usb
USEC_INITIALIZED=39924319957
ID_VENDOR=091e
ID_VENDOR_ENC=091e
ID_VENDOR_ID=091e
ID_MODEL=4b48
ID_MODEL_ENC=4b48
ID_MODEL_ID=4b48
ID_REVISION=0001
ID_SERIAL=091e_4b48_0000c4fa0516
ID_SERIAL_SHORT=0000c4fa0516
ID_BUS=usb
ID_USB_INTERFACES=:ffff00:
ID_VENDOR_FROM_DATABASE=Garmin International
GPHOTO2_DRIVER=PTP
ID_GPHOTO2=1
ID_MEDIA_PLAYER=1
ID_MTP_DEVICE=1
ID_PATH=platform-3f980000.usb-usb-0:1.4
ID_PATH_TAG=platform-3f980000_usb-usb-0_1_4
ID_FOR_SEAT=usb-platform-3f980000_usb-usb-0_1_4
DEVLINKS=/dev/libmtp-1-1.4
TAGS=:seat:uaccess:
$ cat /proc/partitions
major minor  #blocks  name

   1        0       4096 ram0
   1        1       4096 ram1
   1        2       4096 ram2
   1        3       4096 ram3
   1        4       4096 ram4
   1        5       4096 ram5
   1        6       4096 ram6
   1        7       4096 ram7
   1        8       4096 ram8
   1        9       4096 ram9
   1       10       4096 ram10
   1       11       4096 ram11
   1       12       4096 ram12
   1       13       4096 ram13
   1       14       4096 ram14
   1       15       4096 ram15
 179        0   15558144 mmcblk0
 179        1     262144 mmcblk0p1
 179        2   15291904 mmcblk0p2

Let me know if there is anything else I can support you with while debugging this! If you should find another possibility of how to mount your device we could of course think about implementing a mechanism to automate this. I assume it would be likely that also other users would benefit from this.

PS. DCRainmaker would have to file a load of issues for all his devices πŸ˜„

gotiniens commented 3 years ago

There are clearly some differences, all taken from gio mount --list --detail:

I don't really know the significance of these differences, but I think that the ids.unix-device is used to match on the /dev/bus/usb/001/006 parameter give in the gio mount command. Maybe it is possible to add this value to the device?

Yes my Ubuntu machine auto-mounts my device on the path: /media/tim/GARMIN. Trying to replicate the behaviour manually I found the following:

But I was also able to use the udiskctl command on the raspberry, but it needed user interaction:

pi@raspberrypi:~ $ udisksctl mount -b /dev/sda
==== AUTHENTICATING FOR org.freedesktop.udisks2.filesystem-mount-other-seat ===
Authentication is required to mount Garmin FR920 FLASH (/dev/sda)
Authenticating as: ,,, (pi)
Password: 
==== AUTHENTICATION COMPLETE ===
Mounted /dev/sda at /media/pi/GARMIN.

Luckily there is an --no-user-interaction option, too bad it does not work:

pi@raspberrypi:~ $ udisksctl mount -b /dev/sda --no-user-interaction
Error mounting /dev/sda: GDBus.Error:org.freedesktop.UDisks2.Error.NotAuthorizedCanObtain: Not authorized to perform operation

Conclusion

gotiniens commented 3 years ago

I also found pmount /dev/sda garmin which mounts the device under /media/garmin.

I have a feeling it uses udisks API calles. but I have to check that

fgebhart commented 3 years ago

I also found pmount /dev/sda garmin which mounts the device under /media/garmin.

I assume it mounts your device at your ubuntu machine, right? Because once you are able to mount your device at the Raspberry Pi we can get started with automating it.

As long as we manage to get the workoutizer API endpoint mount-device triggered (via e.g. udev), we should be able to parse the output of one of the above commands (e.g. gio mount --list --detail) and from that output we should also be able to distinguish which device was connected and thus decide on the different mount options.

For the initial break through I would leave the "Path to Garmin Device" option as is and maybe enhance the RPI setup readme in a way so that people will get to know the mount path of their device and subsequently can enter this via the settings page of workoutizer.

In a next step we could also try to get rid of the "Path to Garmin Device" option entirely, since we could figure it out automatically during the different mount options. But that is nothing to worry about currently, I would say.

gotiniens commented 3 years ago

Sorry I was unclear, the pmount command works on the RaspberryPi after installing the package.

I will try to write implementation.

fgebhart commented 3 years ago

Great! Let me know if you need help πŸ™‚

gotiniens commented 3 years ago

With #174 Merged this issue is resolved