fgebhart / workoutizer Goto Github PK
View Code? Open in Web Editor NEW:weight_lifting: Browser based Sport and Workout Organizer :running_woman:
License: MIT License
:weight_lifting: Browser based Sport and Workout Organizer :running_woman:
License: MIT License
In the summary sport view the rendering of the gps traces on the leaflet map does not work properly.
Due to the migration from gitlab ci to github actions, some tests still fail and have been excluded for now. Fix these.
It seems that there is no proper unmounting in place which causes this issue.
This could consist of the following:
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:
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
Because of several issues when running the FileImporter
in a separate process in background using multiprocessing
the #44 PR removed the long running process. With these changes the FileImporter
does no longer have a infinite while loop and only runs a single time (when triggered).
Currently only a newly connected device (garmin watch) will trigger the FileImporter
when the device gets mounted. This leads to the problem, that new gpx
files which are saved to the trace directory won't get imported.
In order to fix this it might be helpful to investigate watchdog and find out whether it could be used to watch the trace dir and trigger the FileImporter
once new files are added.
Note: It should be verified, that the watchdog process is also stopped when running the cli command wkz stop
to prevent dangling processes.
Describe the bug
The altitude in the above graph is incorrect, this exercise was around 35m not 270m+, Although the profile seems correct.
Additional context
I see this on a 910XT and a 920XT, with fitdump
you see this:
2513. record
* altitude: 2726
* enhanced_altitude: 45.200000000000045 [m]
Where enhanced_altitude
looks like the correct altitude, the devices both have an barometer, but I dont know if it is relevant for this issue.
When checking the demo fit file 2020-08-31-17-41-11.fit
I think I see the same issue:
2596. record
* altitude: 2728
* enhanced_altitude: 45.60000000000002 [m]
You can also see that altitude is wrong when using the Topo
view of the map, because that view renders height line on the map. Although the looks to be an small discrepancy between those lines and the enhanced_altitude
In the FIT SDK I could not (yet) find an description how to handle altitude.
Add some fancy datetime picker. Could be either a js widget or a django tool, similar to what is in place for the color picker.
For reference:
instead of hard coding the name mapping dict, it would be great for the sake of ux to have the mapping be configurable using the settings page and django model
Describe the bug
After merging #174 running the tests/db_tests/test_api.py::test_mount_device__success
test does not produce consistent results. When running the tests with the -n 1
parameter the tests fail, the tests suceed when running with -n 2
or an higher number of threads.
To Reproduce
Steps to reproduce the behavior:
./run_docker.sh
pytest tests/db_tests/test_api.py -n 2 --no-header -v
pytest tests/db_tests/test_api.py -n 1 --no-header -v
tests/db_tests/test_api.py::test_mount_device__success
test failAditionall context
The problem is two-fold:
_find_device_type
function. You can find the PR for this in #176. I consider this fixed with that PR.See github action template for Publish Python Package
.
Since a convenient way of operating workoutizer in a local network is running it on a Raspberry Pi, it would be great if Python3.7 would be fully supported.
This includes:
Describe the bug
When using the run_docker.sh
script, and initializing the database I get an timeout error. SOmtetimes it seems to be doing nothing, and after pushing ctrl+c
it show the timeout error.
To Reproduce
Steps to reproduce the behavior:
run_docker.sh
scriptwkz init --demo
Traceback (most recent call last):
File "/tmp/venv/lib/python3.8/site-packages/distributed/comm/core.py", line 285, in connect
comm = await asyncio.wait_for(
File "/usr/lib/python3.8/asyncio/tasks.py", line 490, in wait_for
raise exceptions.TimeoutError()
asyncio.exceptions.TimeoutError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/tmp/venv/bin/wkz", line 33, in <module>
sys.exit(load_entry_point('workoutizer', 'console_scripts', 'wkz')())
File "/tmp/venv/lib/python3.8/site-packages/click/core.py", line 1137, in __call__
return self.main(*args, **kwargs)
File "/tmp/venv/lib/python3.8/site-packages/click/core.py", line 1062, in main
rv = self.invoke(ctx)
File "/tmp/venv/lib/python3.8/site-packages/click/core.py", line 1668, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/tmp/venv/lib/python3.8/site-packages/click/core.py", line 1404, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/tmp/venv/lib/python3.8/site-packages/click/core.py", line 763, in invoke
return __callback(*args, **kwargs)
File "/workspaces/workoutizer/workoutizer/cli.py", line 40, in init
_init(import_demo_activities=demo)
File "/workspaces/workoutizer/workoutizer/cli.py", line 163, in _init
run_importer__dask(models, importing_demo_data=True)
File "/workspaces/workoutizer/wkz/file_importer.py", line 389, in run_importer__dask
sse.send(msg, "blue", "DEBUG")
File "/tmp/venv/lib/python3.8/site-packages/distributed/deploy/spec.py", line 454, in __exit__
super().__exit__(typ, value, traceback)
File "/tmp/venv/lib/python3.8/site-packages/distributed/deploy/cluster.py", line 419, in __exit__
return self.sync(self.__aexit__, typ, value, traceback)
File "/tmp/venv/lib/python3.8/site-packages/distributed/deploy/cluster.py", line 192, in sync
return sync(self.loop, func, *args, **kwargs)
File "/tmp/venv/lib/python3.8/site-packages/distributed/utils.py", line 354, in sync
raise exc.with_traceback(tb)
File "/tmp/venv/lib/python3.8/site-packages/distributed/utils.py", line 337, in f
result[0] = yield future
File "/tmp/venv/lib/python3.8/site-packages/tornado/gen.py", line 762, in run
value = future.result()
File "/tmp/venv/lib/python3.8/site-packages/tornado/ioloop.py", line 741, in _run_callback
ret = callback()
File "/tmp/venv/lib/python3.8/site-packages/tornado/ioloop.py", line 765, in _discard_future_result
future.result()
File "/tmp/venv/lib/python3.8/site-packages/distributed/deploy/cluster.py", line 428, in __aexit__
await f
File "/tmp/venv/lib/python3.8/site-packages/distributed/deploy/spec.py", line 426, in _close
await self._correct_state()
File "/tmp/venv/lib/python3.8/site-packages/distributed/deploy/spec.py", line 341, in _correct_state_internal
await self.scheduler_comm.retire_workers(workers=list(to_close))
File "/tmp/venv/lib/python3.8/site-packages/distributed/core.py", line 791, in send_recv_from_rpc
comm = await self.live_comm()
File "/tmp/venv/lib/python3.8/site-packages/distributed/core.py", line 749, in live_comm
comm = await connect(
File "/tmp/venv/lib/python3.8/site-packages/distributed/comm/core.py", line 309, in connect
raise IOError(
OSError: Timed out trying to connect to inproc://10.1.0.2/13/1 after 10 s
Additional context
It also happens when running the tests with `pytest tests/db_tests/test_cli.py, if I edit the tests file and remove the import tests all works well.
Describe the bug
When plugging in my Garmin device, I get the following error:
Jul 25 21:01:28 raspberrypi wkz[560]: 07-25 22:01:28 - ERROR - wkz.api - could not mount device: cannot unpack non-iterable NoneType object
Jul 25 21:01:28 raspberrypi wkz[560]: Traceback (most recent call last):
Jul 25 21:01:28 raspberrypi wkz[560]: File "/home/pi/venv/lib/python3.7/site-packages/wkz/api.py", line 18, in mount_device_endpoint
Jul 25 21:01:28 raspberrypi wkz[560]: mount_path = try_to_mount_device()
Jul 25 21:01:28 raspberrypi wkz[560]: File "/home/pi/venv/lib/python3.7/site-packages/wkz/file_helper/fit_collector.py", line 93, in try_to_mount_device
Jul 25 21:01:28 raspberrypi wkz[560]: (type, path) = _find_device_type(bus, dev)
Jul 25 21:01:28 raspberrypi wkz[560]: TypeError: cannot unpack non-iterable NoneType object
Jul 25 21:01:28 raspberrypi wkz[560]: 07-25 22:01:28 - ERROR - django.request - Internal Server Error: /mount-device/
Although this error should be handled better(I will take care of this), this is also caused by my block device not ready yet to be mounted when the wkz_mount.service is triggered by udev.
After some troubleshooting I check the output of the udevadm monitor
command
KERNEL[877.854533] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1 (usb)
KERNEL[877.858957] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0 (usb)
KERNEL[877.859569] add /devices/virtual/workqueue/scsi_tmf_0 (workqueue)
KERNEL[877.862380] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0 (scsi)
KERNEL[877.862451] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/scsi_host/host0 (scsi_host)
KERNEL[877.862533] bind /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0 (usb)
KERNEL[877.862648] bind /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1 (usb)
UDEV [877.865922] add /devices/virtual/workqueue/scsi_tmf_0 (workqueue)
UDEV [877.883068] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1 (usb)
UDEV [877.884524] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0 (usb)
UDEV [877.888102] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0 (scsi)
UDEV [877.891724] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/scsi_host/host0 (scsi_host)
UDEV [877.895082] bind /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0 (usb)
UDEV [877.907580] bind /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1 (usb)
KERNEL[878.872297] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0 (scsi)
KERNEL[878.872376] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0/0:0:0:0 (scsi)
KERNEL[878.872429] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0 (scsi_device)
KERNEL[878.872504] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0/0:0:0:0/scsi_generic/sg0 (scsi_generic)
KERNEL[878.872579] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0 (bsg)
KERNEL[878.872806] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0 (scsi_disk)
UDEV [878.876385] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0 (scsi)
KERNEL[878.876480] change /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0/0:0:0:0 (scsi)
UDEV [878.880500] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0/0:0:0:0 (scsi)
UDEV [878.885594] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0 (scsi_device)
UDEV [878.887239] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0/0:0:0:0/scsi_generic/sg0 (scsi_generic)
UDEV [878.888806] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0 (scsi_disk)
UDEV [878.890731] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0 (bsg)
UDEV [878.894677] change /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0/0:0:0:0 (scsi)
KERNEL[878.930324] add /devices/virtual/bdi/8:0 (bdi)
UDEV [878.931658] add /devices/virtual/bdi/8:0 (bdi)
KERNEL[879.007785] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0/0:0:0:0/block/sda (block)
KERNEL[879.010554] bind /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0/0:0:0:0 (scsi)
UDEV [886.931941] add /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0/0:0:0:0/block/sda (block)
UDEV [886.936138] bind /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/host0/target0:0:0/0:0:0:0 (scsi)
You see that first the USB subsystem (the last field between parenthesis) is triggered, after a while SCSI subsystem and the last subsystem is the block subsystem.
So I changed the udev rule to trigger on the block subsystem instead of the USB subsystem like:
ACTION=="add", SUBSYSTEM=="block", ATTRS{idVendor}=="091e", ATTRS{idProduct}=="26e5", TAG+="systemd", ENV{SYSTEMD_WANTS}="wkz_mount"
This works!
But this change could break for your device, So before I create an pull request with this change I would like to ask you for the output of udevadm monitor
when plugging in your device.
Add mypy to workoutizer:
Describe the bug
The readme in the setup dir says you should use Raspian 10 (buster). Raspian 10 comes with python3.7.3 installed. And a higher version is not in the repositories.
Since version 0.7.1 and later workoutizer requires python version >=3.8, So 0.7.0 will be the newest version installed
To Reproduce
Steps to reproduce the behavior:
pip install -vvv workoutizer
Link requires a different Python (3.7.3 not in: '>=3.8'): https://files.pythonhosted.org/packages/72/a2/ab6355491543ac1254dc3a93061a4c5bae70a100c2245084d18fbcb1bbb1/workoutizer-0.7.1-py3-none-any.whl#sha256=188e0c97d243a5c64be15309f033d529d49831bc1d481a78dab3ce35c56ebbe5 (from https://pypi.org/simple/workoutizer/) (requires-python:>=3.8)
Expected behavior
Install latest version of workoutizer
Additional context
You can probably install an newer version of python via other repositories.
To allow more people to use workoutizer, it would be great if it would be compatible with windows.
Help on this front is appreciated, since I'm not having direct access to a windows machine. Feel free to open up individual issues for specific problems or discuss general things within this issue.
using headless mode
Currently only Firefox is supported. To additionally support Chrome, the following tasks should be completed:
wizer/tests/integration_tests/browser_tests
pass locallywizer/tests/integration_tests/browser_tests
pass in CIWhen reimporting activity files from the settings page by clicking "Reimport Files" the user has no idea about what happens in the background. Providing feedback on whether some files are reimported or no files at all have been found, would improve the user experience.
make it either responsive or simply only display on large screens: https://stackoverflow.com/questions/48358208/how-to-show-text-only-on-mobile-with-css
Different devices do save their activity files on different paths on their file system. Thus it would be good if the path would not be hard coded (like it currently is with self.activity_path = "/Primary/GARMIN/Activity/"
) but configurable.
Turns out some garmin models do not provide the overall average speed attribute in their fit file. The activity file is imported without any problem, but it leads to the following error when opening the activity in the browser:
03-10 06:44:50 - ERROR - django.request - Internal Server Error: /activity/20
Traceback (most recent call last):
File "/tmp/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/tmp/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/tmp/venv/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/tmp/venv/lib/python3.8/site-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/workspaces/workoutizer/wizer/activity_views.py", line 47, in get
return render(request, self.template_name, {**context, **activity_context})
...
File "/workspaces/workoutizer/wizer/templatetags/filters.py", line 44, in m_per_s_to_km_per_h
return round(float(m_per_s) * 3.6, 1)
TypeError: float() argument must be a string or a number, not 'NoneType'
03-10 06:44:50 - ERROR - django.server - "GET /activity/20 HTTP/1.1" 500 476088
This was initially reported in #90.
This could be fixed by determining the avg (min and max) speed from the speed_list
, which the fit parser has available as pandas series.
However, an additional save guard mechanism for simply not displaying attributes which are None
would be good, since it is not foreseeable which attributes are always available and which not.
This currently seems to block workoutizer from supporting windows.
os.path
with pathlib
Parse fit files record-wise and include NaN for not available attributes to ensure same length of attributes from the early beginning. This will fix many related issues down-stream.
Describe the bug
A bit embarrassing but an incorrect if statement in the fit_collector._find_device_type
function causes Block devices to never be mounted
To Reproduce
Steps to reproduce the behavior:
07-10 11:03:59 - DEBUG - wkz.file_helper.fit_collector - trying to mount device...
07-10 11:03:59 - DEBUG - wkz.file_helper.fit_collector - found Garmin device in: Bus 001 Device 003: ID 091e:26e5 Garmin International
07-10 11:03:59 - DEBUG - wkz.file_helper.fit_collector - Looking up type of device
07-10 11:03:59 - DEBUG - wkz.file_helper.fit_collector - Device is block device
07-10 11:03:59 - ERROR - wkz.api - could not mount device: cannot unpack non-iterable NoneType object
Traceback (most recent call last):
File "/home/pi/venv/lib/python3.7/site-packages/wkz/api.py", line 18, in mount_device_endpoint
mount_path = try_to_mount_device()
File "/home/pi/venv/lib/python3.7/site-packages/wkz/file_helper/fit_collector.py", line 93, in try_to_mount_device
(type, path) = _find_device_type(bus, dev)
TypeError: cannot unpack non-iterable NoneType object
07-10 11:03:59 - ERROR - django.request - Internal Server Error: /mount-device/
07-10 11:03:59 - ERROR - django.channels.server - HTTP POST /mount-device/ 500 [0.26, 192.168.2.182:52808]
no possibility to change number of days back to broader time range when there is no activity data for narrow selected time range
Right now it's hardcoded to look in a /Activity subdirectory in the specified Garmin folder. I import my files from other devices (Wahoo) using other mechanisms, and I'm not using a /Activity folder. It would be nice if it could be optional to NOT look in that folder.
Copying sometimes lead to empty files with a size of 0 bytes. Subsequent parsing fails with
fitparse.utils.FitEOFError: Tried to read 12 bytes from .FIT file but got 0
Describe the bug
As I myself am not a particularly fast uphill rider, the two coordinates of a few consecutive points of an activity of mine (GPX file attached) were in such a close proximity, causing the rounding errors in function calculate_distance_between_points
(@wkz.gis.geo:30) to sum the mathematical formula beyond 1 and cause function acos()
(@wkz.gis.geo:33) to fail (Raising ValueError: math domain error
).
Line 33 in 768e676
To Reproduce
Steps to reproduce the behavior:
Environment:
Ubuntu 20.04.4 LTS
99.0
0.25.0
Additional context
Attached sample GPX file as TXT: BMC.txt
Suggested workaround/fix
The following code is my "bodge" / "fix". I highly appreciate somebody having a second look and share their thought.
TLDR: The math formula is wrapped in max(0,min(FORMULA,1))
# Original code:
# distance = acos(
# sin(_to_rad(coordinate_1[0])) * sin(_to_rad(coordinate_2[0]))
# + cos(_to_rad(coordinate_1[0])) * cos(_to_rad(coordinate_2[0])) * cos(_to_rad(coordinate_1[1] - coordinate_2[1]))
# )
distance = acos(
max(0,
min(
sin(_to_rad(coordinate_1[0])) * sin(_to_rad(coordinate_2[0]))
+ cos(_to_rad(coordinate_1[0])) * cos(_to_rad(coordinate_2[0]))
* cos(_to_rad(coordinate_1[1] - coordinate_2[1]))
,1)
)
)
# Back to original code:
# multiply by earth radius (nominal "zero tide" equatorial) in centimeter
return distance * 6378100
Edit
Hats down to the author for providing such a functional platform/portal. I was already making my own variant of this and found this one by accident, browsing for a gpx parsing pip package.
It is possible to set a lap marker on garmin devices even if the device does not have enough gps signal for determining the position. This leads to lap entries without any lat or lon values. In this case activity_map.html
fails with
Uncaught ReferenceError: None is not defined
This could be solved by avoiding to pass laps without coordinate data to the view.
Add isort to workoutizer
As first signaled in #90, the current flow of workoutizer expects that the device is unmounted before the files are copied. In some cases the OS automatically mounts the device (or the user uses a different way to mount the device).
In order to let the user profit from the automatic import process, it would be nice to add a command / route to workoutizer that only copies the files from the device_path
+ activity_folder_path
.
This gives the user the flexibility to use a different mounting strategy in combination with either manually running wkz import
or automatically triggering the command (maybe a cron job or something similar).
I think this issue would "fix" point 2 and 3 of #90 (comment).
When zooming in / out the position of the "collapse" button in the (left) sidebar is not adjusting its position properly. Its position should be fixed to the bottom of the page. See the attached images:
Here the position of the collapse button is correct:
When zooming out, the position of the button moves up instead of staying at the bottom of the page:
When refreshing the page in the new zoom level, the position of the collapse button again correct. However, it would be nice to have the position fixed and adapt responsive properly when zooming in and out.
Hey! ๐
Let me start by saying that I love the looks of your project! It looks really great and I would love to get this up-and-running for my device.
However, the setup for this project does not seem to be as simple as the README.md says. In fact, I have not been able to get it running using the package provided in pip.
I cloned the repo to investigate the problems and it seems to roughly boil down to these two:
/Primary/GARMIN/Activity
). Instead it is stored at /Garmin/Activity
. It would be nice if that value is configurable./run/media/bintzandt/GARMIN
. This would make the mounting step in mount-device
unnecessary.I managed to get it somewhat working by changing the following things:
/update/
route which does the same as mount-device
except for mounting the device ๐.After that, I got workoutizer to load the files. However, error did still occur:
m_per_s_to_km_per_h
filter crashed because m_per_s
was not defined in the file, causing float()
to run on NoneType
.I have added an additional check to make sure that that code only runs when m_per_s
is defined.
These changes allow me to run workoutizer
locally. Since I only have one workout file, I am unsure if these fixes are very stable.
Besides that, I am not a Python developer so I have probably created a lot of other error ๐
Anyways, I just wanted to let you know what is up. Hopefully, you (we?) will be able to resolve the issues.
Again: thanks a lot for creating this! I look forward to use it.
Describe the bug
The default run_docker script does not provide for forwarding the port the webserver is listening to. WHen manually adding -p 8000:8000
to run_dokcer.sh
. You still wont see the web-interface because the webserver is specifically listening on 127.0.0.1 which is not used for forwarding.
To Reproduce
Steps to reproduce the behavior:
run_docker.sh
wkz init
wkz run
Expected behavior
After starting the docker image, and browsing to http://localhost:8000 with my browser I would expect to see the workoutizer web interface
Environment:
Additional context
In my Forked repo I have an fix for this problem: gotiniens@191b7bf
This fixes the problem for me, but this can break your workflow.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.