{"id":19518673,"url":"https://github.com/mik3y/esp32-ble-pinpad","last_synced_at":"2025-09-08T05:46:41.564Z","repository":{"id":67322491,"uuid":"585751787","full_name":"mik3y/esp32-ble-pinpad","owner":"mik3y","description":"An ESPHome component for accepting a secret PIN over Bluetooth LE.","archived":false,"fork":false,"pushed_at":"2024-04-07T19:54:53.000Z","size":51,"stargazers_count":7,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-15T21:47:30.729Z","etag":null,"topics":["esp32","esphome","home-assistant"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mik3y.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","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-01-06T01:22:03.000Z","updated_at":"2025-02-17T20:12:06.000Z","dependencies_parsed_at":"2025-01-08T12:52:24.042Z","dependency_job_id":"23675e01-78e1-4dfa-ad70-298688997598","html_url":"https://github.com/mik3y/esp32-ble-pinpad","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/mik3y/esp32-ble-pinpad","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mik3y%2Fesp32-ble-pinpad","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mik3y%2Fesp32-ble-pinpad/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mik3y%2Fesp32-ble-pinpad/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mik3y%2Fesp32-ble-pinpad/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mik3y","download_url":"https://codeload.github.com/mik3y/esp32-ble-pinpad/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mik3y%2Fesp32-ble-pinpad/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274140144,"owners_count":25229138,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-08T02:00:09.813Z","response_time":121,"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":["esp32","esphome","home-assistant"],"created_at":"2024-11-11T00:13:52.147Z","updated_at":"2025-09-08T05:46:41.543Z","avatar_url":"https://github.com/mik3y.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ESP32 Bluetooth LE (BLE) Pinpad\n\nThis an ESPHome custom component that exposes a \"pin pad\" BluetoothLE server.\n\nIt is a component which can trigger other things (such as an `output` device) when the correct value is received over BLE.\n\n\u003e **Status**: 🚨 Experimental! Use at your own risk.\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Why?](#why)\n- [Compatibility](#compatibility)\n- [Usage](#usage)\n- [Configuration options](#configuration-options)\n- [Protocol (how it works)](#protocol-how-it-works)\n- [Testing](#testing)\n- [Security](#security)\n- [Developer Instructions](#developer-instructions)\n  - [Using local sources in esphome](#using-local-sources-in-esphome)\n  - [Updating `README.md`](#updating-readmemd)\n  - [References and Reading](#references-and-reading)\n- [Help, Feedback, and Ideas](#help-feedback-and-ideas)\n- [License \u0026 Credit](#license--credit)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Why?\n\nA \"pin pad\" is a simple input device which receives a string over BLE, checks it against the valid PIN(s), and triggers an \"accepted\" or \"rejected\" callback within ESPHome.\n\nYou could use it to make a switch, lock, or other device which is unlocked via BLE.\n\nI wrote it because I had exactly that need, and specifically wanted something that didn't require wifi in order to work. Oh, and of course, I was bored/curious.\n\n## Compatibility\n\n* **ESPHome:** Version `2023.11.0` or newer.\n\n## Usage\n\nIn your esphome YML, first import this component:\n\n```yml\nexternal_components:\n  - source:\n      type: git\n      url: https://github.com/mik3y/esp32-ble-pinpad\n      ref: main\n    components: [ esp32_ble_pinpad ]\n```\n\nNext, and optionally, set up a status LED.\n\n```yml\noutput:\n  - platform: ledc\n    pin: GPIO2\n    id: onboard_status_led\n```\n\nFinally, add the component itself:\n\n```yml\nesp32_ble_pinpad:\n  secret_passcode: changeme\n  security_mode: hotp\n  status_indicator: onboard_status_led\n  on_pinpad_accepted:\n    - logger.log: \"Rad! Correct pin was given!\"\n  on_pinpad_rejected:\n    - logger.log: \"Bummer! Incorrect pin was given.\"\n```\n\nOf course, you'll probably want to do something other than log when the pin comes in. You can use [any availabe ESPHome trigger](https://esphome.io/guides/automations.html#all-triggers) here. For example, if you have a garage door set up as a cover, you could do:\n\n```yml\n  on_pinpad_accepted:\n    - logger.log: \"Got pin over BLE, opening door.\"\n    - cover.toggle: garage_door\n```\n\n## Configuration options\n\nYou can provide these options in the `esp32_ble_pinpad` yaml block:\n\n* **`secret_passcode`** (required): The secret passcode. Follow strong password rules for best security (i.e. longer values are better).\n* **`security_mode`** (required): One of `none`, `hotp`, or `totp`. If in doubt, `hotp` is recommended.\n    * **Warning:** Using `none` is highly insecure, as it means the passcode will be exposed over-the-wire. See _Security_ for further information.\n* **`status_indicator`** (optional): An `output` to use for blinking status.\n* **`on_pinpad_accepted`** (optional): Trigger(s) to fire when a PIN is accepted.\n* **`on_pinpad_rejected`** (optional): Trigger(s) to fire when a PIN is rejected.\n\n\n## Protocol (how it works)\n\nTwo configuration factors are set by you and flashed into the device:\n\n* `secret_passcode`: The value you will use and give to anyone wishing to \"pin in\".\n* `security_mode`: One of `none`, `hotp`, or `totp`, this determines how the passcode is used.\n\nTo authenticate (\"pin in\"), a client performs the following steps:\n\n1. Discover the device and create a BLE connection to the pinpad service.\n2. Read the `security_mode` setting of the device. This is available at the `PINPAD_SECURITY_MODE_CHR` BLE GATT characteristic.\n3. Compute the secret to send:\n    1. If `security_mode = none`, the value of `secret_passcode` is sent in full and in the clear. _This is the least secure option and is not recommended._\n    2. If `security_mode = hotp`, the client must read the current HOTP counter from `PINPAD_HOTP_COUNTER_CHR`, then generate and send a 6-digit HOTP code based on that value and using `secret_passcode` as the key.\n    3. If `security_mode = totp`, the client must generate and send a 6-digit TOTP code based on the current time and using `secret_passcode` as the key.\n4. Optionally, read `PINPAD_STATUS_CHR` to determine whether the operation succeeded.\n\n## Testing\n\nA debug program is included at `tools/pypinpad/pypinpad.py` which can be used to send a pin to a locally-discoverable BLE device.\n\nTo install the tool's dependencies, `poetry` is required.\n\n```\ncd tools/pypinpad\npoetry install\n```\n\nExample usage:\n\n```\n$ poetry shell\n(pypinpad-py3.10) $ python pypinpad.py pin\nSearching for BLE devices ...\nFound device ble-pinpad-example (9A4935AD-7909-4E76-8481-1D42C213B689). Use it? [Y/n]: y\nDevice security mode: hotp\nPlease enter the device password: changeme\nCurrent hotp counter: 13\nSending pin \"100596\" to device ...\n```\n\n\n## Security\n\n**Warning:** You should consider this component **totally insecure**. No warranty. Please review `LICENSE.txt`.\n\nWhen `security_mode` is `hotp` or `totp`, the secret passcode is never revealed on the wire. Captured payloads should not be replayable: In the case of `hotp`, the counter is incremented after every successful authentication and persisted to flash. `totp` follows a standard 30-second window.\n\n\n## Developer Instructions\n\nNotes for folks working on the component itself.\n\n### Using local sources in esphome\n\nSee `example.yml` for how to pull the component in.\n\n### Updating `README.md`\n\nUse `doctoc` to update the table of contents:\n\n```\nnpm install -g doctoc\ndoctoc --notitle --github README.md\n```\n\n### References and Reading\n\nHere are some things I found helpful while learning about BLE:\n\n* An overview of BLE (protocol \u0026 stack): https://novelbits.io/bluetooth-low-energy-ble-complete-guide\n* An unrelated ble stack bugreport, but with great discussion: https://github.com/espressif/arduino-esp32/issues/1038\n* BLE officially assigned numbers (PDF): https://btprodspecificationrefs.blob.core.windows.net/assigned-numbers/Assigned%20Number%20Types/Assigned%20Numbers.pdf\n\n\n## Help, Feedback, and Ideas\n\nPlease open an issue on GitHub!\n\nHere are some ideas I haven't gotten around to yet.\n\n- BLE interface for adding/revoking pins (using some sort of admin pin).\n- BLE interface for reading attempt history.\n\n## License \u0026 Credit\n\nWritten by **@mik3y**. \n\nAll code is offered under the MIT license. See `LICENSE.txt` for full terms.\n\nThis project includes a copy of the [esp-totp library](https://github.com/huming2207/esp-totp) by Jackson Ming Hu, also MIT licensed. See `otp.{cpp,h}`.\n\nInspired by \u0026 indebted to the built-in [esp32_improv component](https://github.com/esphome/esphome/blob/dev/esphome/components/esp32_improv).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmik3y%2Fesp32-ble-pinpad","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmik3y%2Fesp32-ble-pinpad","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmik3y%2Fesp32-ble-pinpad/lists"}