Skip to content
This repository has been archived by the owner on Jan 7, 2024. It is now read-only.

ENH: Rework mounting mechanism to increase chances of successful mount #214

Merged
merged 21 commits into from Oct 18, 2021

Conversation

fgebhart
Copy link
Owner

@fgebhart fgebhart commented Oct 6, 2021

  • tests added / passed
  • Ensure pre-commit formatting checks are passing
  • changelog entry

This PR changes the mounting mechanism in the following way:

  • It simplifies the udev rule to be triggered on any device which is a garmin device (irrespective of the device type)
  • This allows to post to the workoutizer api endpoint already in the first second after the device was connected
  • Which means, that workoutizer has to take care of waiting until the device is ready for being mounted
  • Usually a garmin device would take up to ~60seconds for being ready for mounting
  • Thus workoutizer waits 5 times a 20 seconds and keeps on retrying to mount the device
  • You can figure this out by connecting your device and repeatably issue the lsusb command
  • With this implementation workoutizer has a higher chance of successfully mounting a garmin device.

From my tests this did not mount the device every time when I connected it, but at least most of the time. So I would consider this to fix #9.

return False


def _is_of_type_block(device_tree: pyudev.core.Context, path: str) -> bool:
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gotiniens I changed the implementation of the mount mechanism quite a bit. However, I tried to stick to what we used to have in place for determining the device type as far as possible. As we have discussed earlier testing this piece of code is of course not trivial. So I would appreciate if you could spend a moment for testing this implementation with your device, before I merge it.

You should be able to directly install the implementation of this PR using

pip install git+https://github.com/fgebhart/workoutizer.git@refs/pull/214/head#egg=workoutizer

Let me know if you encounter any issues.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note, that these changes also require you to use the simplified version of the udev rule as given here: https://github.com/fgebhart/workoutizer/pull/214/files#diff-aa7a481338e2c1cee33238469338ef1d478d3912ced41db1c35146b9e6521b1bR52

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fgebhart I just tested the pull request, first result is that it is not working for me, I get a general error:

10-10 14:42:25 - DEBUG - wkz.api - received POST request for mounting garmin device
10-10 14:42:25 - DEBUG - wkz.api - found connected garmin device
10-10 14:42:25 - ERROR - wkz.views - Error while loading /mount-device/

I need some extra logging to be sure of the exact problem, will try to add it locally later today

wkz/api.py Outdated Show resolved Hide resolved
wkz/api.py Outdated
Comment on lines 21 to 23
huey_task = HUEY.task(mount_device_and_collect_files)
# schedule huey task
huey_task()
Copy link
Contributor

@gotiniens gotiniens Oct 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found this solution to starting the huey task correctly, see also suggestion for line 12

Suggested change
huey_task = HUEY.task(mount_device_and_collect_files)
# schedule huey task
huey_task()
mount_device_and_collect_files_task()

You also need to add the following lines to wkz.tasks

from wkz.device.mount import mount_device_and_collect_files

@task()
def mount_device_and_collect_files_task():
    mount_device_and_collect_files()

This tried to mount the device, but mis identified my device as an MTP device, resulting in using the wrong mount method. Still researching that problem.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gotiniens Thanks for looking into it - you are right.

It seems during development and testing my huey instance somehow hold a correct reference to the function which I intended to run as huey.task in its db. Now I removed the db (rm /tmp/huey.db) to start from scratch and ran into the exact same problem you described.

Your proposed solution also solves the issue for me. Will implement it, adapt the tests accordingly and update this PR asap. Thanks 👍

FYI: when debugging you can set the DJANGO_DEBUG env var to True which will avoid these generic error messages and output the entire traceback.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just double checked and everything seems to be working as expected now on my side. I assume this to be working for you as well, since you essentially suggested the fix.

However, will wait a few days more before merging to give you another chance to comment, @gotiniens.

wkz/api.py Show resolved Hide resolved

def _is_of_type_mtp(device_tree: pyudev.core.Context, path: str) -> bool:
devices = (
device_tree.list_devices(subsystem="usb").match_property("DEVNAME", path).match_property("ID_MTP_DEVICE", "1")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple match_propery are 'OR'ed and not 'AND'ed like you probably expect here. That's why the old _find_device_type looped through all found devices, and did an check on every found device.

My device is seen as MTP because of this rule.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, seems like I assumed the wrong thing. Let me remove .match_property("DEVNAME", path) - this should prevent your device from being seen as MTP.



def _mount_device_using_pmount(path: str) -> str:
subprocess.check_output(["pmount", path, "garmin"]).decode("utf-8")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

path is here /dev/bus/usb/001/004, but pmount needs /dev/sdb, The old _find_device_type has some extra magic to make this translation. I'm not really sure how to implement this in this setup.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will refactor this to actually use the approach you implemented to achieve this translation to the correct path.

return True
else:
return False
def _get_block_device_path(device_tree: pyudev.core.Context, path: str) -> str:
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gotiniens I reverted this part back to almost reflect your original implementation. I hope this allows mounting block devices again (MTP still works with this implementation).

@gotiniens
Copy link
Contributor

Those latest changes seem to work for me,Plugging the device in it is mounted automatically after it fails a few times (due to it not having settled yet), so it looks pretty robust. Then the files are copied automatically and processed.

p.s. I got an e-mail from an comment you posted on thursday, could not find the comment anymore?

@fgebhart
Copy link
Owner Author

Those latest changes seem to work for me,Plugging the device in it is mounted automatically after it fails a few times (due to it not having settled yet), so it looks pretty robust. Then the files are copied automatically and processed.

Perfect. Thanks again for testing and providing feedback. Will merge this PR then.

p.s. I got an e-mail from an comment you posted on thursday, could not find the comment anymore?

yea... I deleted it a few minutes after I submitted it, because I realized I was out of my mind and sensed and bug where there actually was none 😆 I hoped you didn't get an email.. well just ignore it - all good 👍

@fgebhart fgebhart self-assigned this Oct 18, 2021
@fgebhart fgebhart merged commit a190e8f into main Oct 18, 2021
@fgebhart fgebhart deleted the rework_mounting_mechanism branch October 18, 2021 18:14
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

device gets mounted only every second time on Raspberry Pi
2 participants