{"id":20775018,"url":"https://github.com/qdot/khole-py","last_synced_at":"2026-04-18T20:32:14.127Z","repository":{"id":66557553,"uuid":"66165424","full_name":"qdot/khole-py","owner":"qdot","description":"kHole - Reverse Engineered Bluetooth Drivers for the Minna kGoal","archived":false,"fork":false,"pushed_at":"2016-11-17T07:30:46.000Z","size":9,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-11T21:27:20.020Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/qdot.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES.rst","contributing":null,"funding":null,"license":null,"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":"2016-08-20T19:53:05.000Z","updated_at":"2023-09-08T17:13:55.000Z","dependencies_parsed_at":"2023-07-10T14:15:58.527Z","dependency_job_id":null,"html_url":"https://github.com/qdot/khole-py","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/qdot/khole-py","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qdot%2Fkhole-py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qdot%2Fkhole-py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qdot%2Fkhole-py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qdot%2Fkhole-py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/qdot","download_url":"https://codeload.github.com/qdot/khole-py/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qdot%2Fkhole-py/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31984125,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"ssl_error","status_checked_at":"2026-04-18T20:23:29.375Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2024-11-17T12:34:15.112Z","updated_at":"2026-04-18T20:32:14.109Z","avatar_url":"https://github.com/qdot.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"kHole (Python Version)\n======================\n\nReverse engineered drivers for the\n`Minna kGoal \u003chttp://www.minnalife.com/products/kgoal\u003e`__ kegel\nexerciser.\n\nJavascript version at `khole-js \u003chttps://github.com/metafetish/khole-js\u003e`__\n\nDescription\n-----------\n\nThe kGoal is a Bluetooth LE Kegelcizer device, made to communicate\nwith iPhone and android phones. The kHole project aims to make the\ndevice accessible to other platforms, such as desktop, arduino,\nRaspberry Pi, and other bluetooth accessible systems.\n\nProtocol\n--------\n\nIn terms of communication, the kGoal is a fairly simple device, It\nuses BTLE to connect to a host, with no pairing or long term key\nexchange. After this, the host can do the following things:\n\n- Request the values of the internal pressure sensor\n- Set whether vibration feedback happens via \"Squeeze Pillow\" or\n  \"Control Arm\"\n  \nThat's pretty much it.\n\nTo read information from the device, issue a characteristic read\nrequest to handle 0x2a. This should return a 19 byte value, similar to\nthe one below:\n\n00 01 04 01 9b 07 67 00 00 00 00 00 00 00 00 00 00 00\n\nThe important values are:\n\n- bytes 3-4 (0x019b in example) - This is the big-endian calibrated\n  sensor reading, starting from 0 based on the last calibration\n  setting and going up. Calibration can be reset by hitting the button\n  on the top of the toy, which makes the LED turn green.\n- bytes 5-6 (0x0767 in example) - This is the big-endian uncalibrated\n  sensor reading. It'll always report the same range no matter the\n  calibration setting.\n\nSo, in the case of our example above, the calibration point was set at\n0x767 - 0x19b = 0x5cc. If the uncalibrated reading is \u003c= 0x5cc, the\ncalibrated reading will just read 0x0.\n\n\nPython Implementation\n---------------------\n\nThe python implementation in the library allows access to the\naforementioned functionality. As it is using pybluez and gattlib, it\nwill currently only work on linux (and also requires some boost\ninstalls. Sorry. I'm not happy about it either.). But who doesn't do\ntheir kegels near a linux box these days?\n\nLicense\n-------\n\nkHole-py is BSD licensed.\n\n    Copyright (c) 2016, Metafetish\n    All rights reserved.\n    \n    Redistribution and use in source and binary forms, with or without\n    modification, are permitted provided that the following conditions are met:\n    \n    * Redistributions of source code must retain the above copyright notice, this\n      list of conditions and the following disclaimer.\n    \n    * Redistributions in binary form must reproduce the above copyright notice,\n      this list of conditions and the following disclaimer in the documentation\n      and/or other materials provided with the distribution.\n    \n    * Neither the name of the project nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n    \n    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqdot%2Fkhole-py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqdot%2Fkhole-py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqdot%2Fkhole-py/lists"}