{"id":20374088,"url":"https://github.com/robcranfill/practicemonitor","last_synced_at":"2026-05-28T13:04:25.616Z","repository":{"id":204950499,"uuid":"705388850","full_name":"RobCranfill/practiceMonitor","owner":"RobCranfill","description":"A FitBit for MIDI keyboards","archived":false,"fork":false,"pushed_at":"2024-05-22T01:00:05.000Z","size":265,"stargazers_count":1,"open_issues_count":5,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-04T20:46:07.371Z","etag":null,"topics":["iot","midi","midi-keyboard"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RobCranfill.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-15T21:50:08.000Z","updated_at":"2024-05-22T01:00:09.000Z","dependencies_parsed_at":"2023-12-03T22:21:53.610Z","dependency_job_id":"a376cc3e-a5c7-4d68-9b26-4659493efc76","html_url":"https://github.com/RobCranfill/practiceMonitor","commit_stats":null,"previous_names":["robcranfill/practicemonitor"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/RobCranfill/practiceMonitor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobCranfill%2FpracticeMonitor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobCranfill%2FpracticeMonitor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobCranfill%2FpracticeMonitor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobCranfill%2FpracticeMonitor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RobCranfill","download_url":"https://codeload.github.com/RobCranfill/practiceMonitor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobCranfill%2FpracticeMonitor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33609253,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-28T02:00:06.440Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["iot","midi","midi-keyboard"],"created_at":"2024-11-15T01:22:13.858Z","updated_at":"2026-05-28T13:04:25.598Z","avatar_url":"https://github.com/RobCranfill.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pi Practice Monitor\n*Like a FitBit for (MIDI) keyboard players*\n\n## Goal\nA bit of hardware (plus software/firmware, of course) that I can plug into a\nMIDI keyboard (via USB) that will monitor my keyboard practice. At a minimum, show\nelapsed time for the week's practice. But other interesting stats are possible.\n\nFirst, implement a Minimum Viable Product; add bells and whistles later (what a concept!).\n\nEventually create a front-end \u0026ndash; app? website? \u0026ndash; to slice and dice the data.\nAdd social features?\n\n\n## Main Hardware\nWe need something that can act as a MIDI/USB \"host\". This seems to be problematic\nfor anything smaller than a Raspberry Pi Zero, which is what I'm using now (Zero2W).\nI was hoping to use a Pi Pico or the like, but USB Host capability is currently poorly\nsupported (in CircuitPython anyway). \n\n\n## Software\n* Full RPi Python (3.11.x) code\n  * with Adafruit Blinka (see 'Installation' below) and a bunch of other stuff!\n* Also some udev rules \u0026 scripts to run it all\n* If we ever move to a smaller device, CircuitPython will probably be necessary.\n\n\n## Display\nNow using an [Adafruit 1.3: TFT display](https://www.adafruit.com/product/4484) - looks nice! \nExcept it's *slow*! Either find a workaround or find a replacement display. \nMy first instance of this part has developed visible defects. Are they fragile? short lived?\n\n\n## Minimum Viable Product\nNeed to define this and implement it first! Nothing fancy!!\n\n\n## Stretch Goals (post MVP)\n* Data collection, storage, presentation\n * Use [Adafruit IoT](https://io.adafruit.com/robcranfill/overview) ?\n   * Device sends session data updates to cloud\n   * Phone/desktop app queries cloud and shows data analysis\n\n\n## Issues\n* Power-down safety\n This is the second reason, after cost, that I'd prefer a Pico - how to make it safe to \n simply power down the device? \n  * One solution: Make RPi Linux filesystem read-only. See https://learn.adafruit.com/read-only-raspberry-pi\n    * Can I make some of it R/W? For persistence? Needed??\n  * Workaround: GUI menu for shutdown\n * https://github.com/RobCranfill/practiceMonitor/security/dependabot/1\n * Alternate display \n  \nSince the display of the elapsed session time seems problematic (doesn't update nicely) \ncan we show something else? Like just a \"Session in progress\" screen? But that doesn't encourage \nextending a session (\"I see I have practiced for 17 minutes - can I make it to 20?\").\n\n## Installation\n* Python 3.11.2 used\n* Runs in a 'venv':\n  * \u003ccode\u003epython -m venv zenv --system-site-packages\u003c/code\u003e\n  * \u003ccode\u003esource zenv/bin/activate\u003c/code\u003e\n* Python libs\n  * Blinka:\n    * \u003ccode\u003epip3 install --upgrade adafruit-python-shell\u003c/code\u003e\n    * \u003ccode\u003ewget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/raspi-blinka.py\u003c/code\u003e\n    * \u003ccode\u003esudo -E env PATH=$PATH python3 raspi-blinka.py\u003c/code\u003e\n  * \u003ccode\u003esudo apt-get install python-dev\u003c/code\u003e\n  * \u003ccode\u003epip install -f requirements.txt\u003c/code\u003e\n* Misc\n  * sudo apt-get install fonts-dejavu\n  * Why did I have do do the following? (Did I have to??)\n  * \u003ccode\u003epython3 -m pip install --upgrade --force-reinstall adafruit-blinka\u003c/code\u003e\n  \n* The following are no longer needed, since we use the above requirements file. Delete after verification!\n  \u003cstrike\u003e\n* Linux softare\n  * RTMIDI backend for Mido\u003ccode\u003e\n    * pip install --pre python-rtmidi\n    * pip install mido[ports-rtmidi]\n    * sudo apt-get install libasound2-dev\n    * sudo apt-get install libjack-dev\u003c/code\u003e\n * Adafruit Blinka\nas per https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/installing-circuitpython-on-raspberry-pi\n * PIL\n  * pip install pillow\n   * Adafruit Libs\n     * pip install adafruit-circuitpython-rgb-display\n     * IOT (Internet of Things) \n       * \u003ccode\u003epip3 install adafruit-io\u003c/code\u003e\n       * see https://learn.adafruit.com/welcome-to-adafruit-io/python-and-adafruit-io\n\u003c/strike\u003e\n\n## Linux service\n* TODO:\n  * Use syslog (or whatever)\n  * Done:\n    * \u003cstrike\u003eHow to check if service already running? (For running from command line)\u003c/strike\u003e\n\n\n* Notes\n  * script at /lib/systesmd/system/pmz.service\n    * \u003ccode\u003esudo cp pmz.service /lib/systemd/system/\u003c/code\u003e\n    * \u003ccode\u003esudo chmod 644 /lib/systemd/system/pmz.service\u003c/code\u003e\n  * \u003ccode\u003esudo systemctl daemon-reload\u003c/code\u003e\n  * \u003ccode\u003esudo systemctl [enable|disable|start|stop|status] pmz.service\u003c/code\u003e\n\n\n## Workflow Revisited\n * Attach PiZero2W via USB MIDI cable (\u0026 OTC connector) to MPKmini; via USB to power brick.\n * Wait until 'ping pizero2w.local' returns a hit.\n * On PC, run './mountsmb.sh' to mount SMB share, start Code pointing to SMB share.\n * Use Termius (or whatever) to SSH to pizero2w.local.\n * On PiZero2w, run 'source zenv/bin/activate' to start venv for PMon.\n * Scripts on pmz:\n   * pmz.sh - runs the code in the forground, for development\n   * mountsmb.sh - as above\n   * check_pm_service.sh - sees if PMon is running in background; bad things happen if you try to run code twice.\n   * runPMZ.sh - script that runs the PMon as a service, for running standalone.\n     * Document above at \"Linux Service\"\n\n\n## To Do\n * USE GITHUB 'ISSUES' FOR THIS.\n * Completed:\n   * Handle no MIDI device attached - including displaying msg on LCD\n   * Handle SIGTERM/INT \u0026c (blank screen, etc)\n   * Show MIDI device name on LCD\n   * LCD display - backlight off doesn't work\n   * Clear/poweroff display when done\n   * Auto-select appropriate MIDI device\n   * Create stand-alone command to turn off backlight; use it.\n \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobcranfill%2Fpracticemonitor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobcranfill%2Fpracticemonitor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobcranfill%2Fpracticemonitor/lists"}