{"id":16609990,"url":"https://github.com/sopelj/python-ember-mug","last_synced_at":"2026-02-05T03:03:33.355Z","repository":{"id":58527855,"uuid":"531710127","full_name":"sopelj/python-ember-mug","owner":"sopelj","description":"Python Library to Interact with Ember Mugs","archived":false,"fork":false,"pushed_at":"2026-01-10T21:40:20.000Z","size":3357,"stargazers_count":46,"open_issues_count":1,"forks_count":6,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-01-11T06:36:54.944Z","etag":null,"topics":["bleak","bluetooth-low-energy","ember-mug","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","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/sopelj.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-09-01T22:54:50.000Z","updated_at":"2026-01-10T21:39:36.000Z","dependencies_parsed_at":"2022-09-12T19:40:41.909Z","dependency_job_id":"aee49e46-90eb-4fc9-8e20-3a378dc8b9a5","html_url":"https://github.com/sopelj/python-ember-mug","commit_stats":{"total_commits":135,"total_committers":3,"mean_commits":45.0,"dds":"0.45185185185185184","last_synced_commit":"58ea7299b3fe57e25dd81f70646d4ccaf77a6f7e"},"previous_names":[],"tags_count":72,"template":false,"template_full_name":null,"purl":"pkg:github/sopelj/python-ember-mug","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sopelj%2Fpython-ember-mug","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sopelj%2Fpython-ember-mug/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sopelj%2Fpython-ember-mug/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sopelj%2Fpython-ember-mug/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sopelj","download_url":"https://codeload.github.com/sopelj/python-ember-mug/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sopelj%2Fpython-ember-mug/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28517147,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T18:55:29.170Z","status":"ssl_error","status_checked_at":"2026-01-17T18:55:03.375Z","response_time":85,"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":["bleak","bluetooth-low-energy","ember-mug","python3"],"created_at":"2024-10-12T01:29:23.680Z","updated_at":"2026-01-17T19:33:28.116Z","avatar_url":"https://github.com/sopelj.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# Python Ember Mug\n\n[![pypi](https://img.shields.io/pypi/v/python-ember-mug.svg)](https://pypi.org/project/python-ember-mug/)\n[![python](https://img.shields.io/pypi/pyversions/python-ember-mug.svg)](https://pypi.org/project/python-ember-mug/)\n[![Build Status](https://github.com/sopelj/python-ember-mug/actions/workflows/tests.yml/badge.svg)](https://github.com/sopelj/python-ember-mug/actions/workflows/tests.yml)\n[![codecov](https://codecov.io/gh/sopelj/python-ember-mug/graph/badge.svg?token=2Lw2iVjKsG)](https://codecov.io/gh/sopelj/python-ember-mug)\n![Project Maintenance](https://img.shields.io/maintenance/yes/2026.svg)\n[![Maintainer](https://img.shields.io/badge/maintainer-%40sopelj-blue.svg)](https://github.com/sopelj)\n[![License](https://img.shields.io/github/license/sopelj/python-ember-mug.svg)](https://github.com/sopelj/python-ember-mug/blob/main/LICENSE)\n[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen)](https://github.com/pre-commit/pre-commit)\n\nPython Library for interacting with Ember Mugs, Cups, and Travel Mugs via Bluetooth\n\n* [📘 Documentation](https://sopelj.github.io/python-ember-mug)\n* [💻 GitHub](https://github.com/sopelj/python-ember-mug)\n* [🐍 PyPI](https://pypi.org/project/python-ember-mug/)\n\n## Summary\n\nThis is an *unofficial* library to attempt to interact with Ember Mugs via Bluetooth.\nThis was created for use with my [Home Assistant integration](https://github.com/sopelj/hass-ember-mug-component),\nbut could be useful separately and has a simple CLI interface too.\n\nAll known Ember Mugs, Cups, Tumblers and Travel Mugs have been tested and seem to work well.\nIf I missed one, or you have new feature ideas or issues, please [create an issue](https://github.com/sopelj/python-ember-mug/issues), if it isn't already there, and we'll figure it out.\n\n| Device       | Tested |\n|--------------|--------|\n| Mug          | ✓      |\n| Mug 2        | ✓      |\n| Cup          | ✓      |\n| Tumbler      | ✓      |\n| Travel Mug   | ✓      |\n| Travel Mug 2 | ✓      |\n\n## Features\n\n* Finding devices\n* Connecting to devices\n* Reading/Writing most values\n* Poll for changes\n\nAttributes by device:\n\n| Attribute           | Mug | Cup | Tumbler | Travel Mug | Description                                   |\n|---------------------|-----|-----|---------|------------|-----------------------------------------------|\n| Name                | R/W | N/A | N/A     | R          | Name to give device                           |\n| LED Colour          | R/W | R/W | R/W     | N/A        | Colour of front LED                           |\n| Current Temperature | R   | R   | R       | R          | Current temperature of the liquid in the mug  |\n| Target Temperature  | R/W | R/W | R/W     | R/W        | Desired temperature for the liquid            |\n| Temperature Unit    | R/W | R/W | R/W     | R/W        | Internal temperature unit for the app (C/F)   |\n| Liquid Level        | R   | R   | R       | R          | Approximate level of the liquid in the device |\n| Volume level        | N/A | N/A | N/A     | R/W        | Volume of the button press beep               |\n| Battery Percent     | R   | R   | R       | R          | Current battery level                         |\n| On Charger          | R   | R   | R       | R          | Device is on it's charger                     |\n\n\u003e **Note**\n\u003e Writing may only work if the devices has been set up in the app previously\n\n## Usage\n\n### Python\n\n```python\nfrom ember_mug.scanner import find_device, discover_devices\nfrom ember_mug.utils import get_model_info_from_advertiser_data\nfrom ember_mug.mug import EmberMug\n\n# if first time with mug in pairing\ndevices = await discover_devices()\n\n# after paired you can simply use\ndevice, advertisement = await find_device()\nmodel_info = get_model_info_from_advertiser_data(advertisement)\nmug = EmberMug(device, model_info)\nawait mug.update_all()\nprint(mug.data.formatted)\nawait mug.disconnect()\n\n# You can also use connection as a context manager\n# if you want to ensure connection before starting and cleanup on exit\nasync with mug.connection():\n    print('Connected.\\nFetching Info')\n    await mug.update_all()\n    print(mug.data.formatted)\n```\n\n### CLI Mode\n\nIt can also be run via command line either directly with `ember-mug --help` or as a module with `python -m ember_mug --help`\nThere are four options with different subsections. You can see them by specifying them before help. eg `ember-mug poll --help`\n\n```bash\nember-mug discover  # Finds the mug in pairing mode for the first time\nember-mug poll  # fetches info and keeps listening for notifications\nember-mug get name target-temp  # Prints name and target temp of mug\nember-mug set --name \"My mug\" --target-temp 56.8  # Sets the name and target temp to specified values\n```\n\nBasic options:\n\n| Command     | Use                                                                               |\n|-------------|-----------------------------------------------------------------------------------|\n| `discover`  | Find/List all detected unpaired devices in pairing mode                           |\n| `find`      | Find *one* already paired devices                                                 |\n| `info`      | Connect to *one* device and print its current state                               |\n| `poll`      | Connect to *one* device and print its current state and keep watching for changes |\n| `get`       | Get the value(s) of one or more attribute(s) by name                              |\n| `set`       | Set one or more values on the device                                              |\n\nExample:\n\u003c!-- termynal --\u003e\n```\n$ ember-mug poll\nFound device: C9:0F:59:D6:33:F9: Ember Ceramic Mug\nConnecting...\nConnected.\nFetching Info\nDevice Data\n+--------------+----------------------+\n| Device Name  | Jesse's Mug          |\n+--------------+----------------------+\n| Meta         | None                 |\n+--------------+----------------------+\n| Battery      | 64.0%                |\n|              | not on charging base |\n+--------------+----------------------+\n| Firmware     | None                 |\n+--------------+----------------------+\n| LED Colour   | #ff0fbb              |\n+--------------+----------------------+\n| Liquid State | Empty                |\n+--------------+----------------------+\n| Liquid Level | 0.00%                |\n+--------------+----------------------+\n| Current Temp | 24.50°C              |\n+--------------+----------------------+\n| Target Temp  | 55.00°C              |\n+--------------+----------------------+\n\nWatching for changes\nCurrent Temp changed from \"24.50°C\" to \"25.50°\"\nBattery changed from \"64.0%, on charging base\" to \"65.5%, on charging base\"\n```\n\n\n## Caveats\n\n* Since this api is not public, a lot of guesswork and reverse engineering is involved, so it's not perfect.\n* If the device has not been set up in the app since it was reset, writing is not allowed. I don't know what they set in the app, but it changes something, and it doesn't work without it.\n* Once that device has been set up in the app, you should ideally forget the device or at least turn off bluetooth whilst using it here, or you will probably get disconnected often\n* I haven't figured out some attributes like udsk, dsk, location and timezone, but they are not very useful anyway.\n\n## Troubleshooting\n\n##### Systematic timeouts or `le-connection-abort-by-local`\n\nIf your mug gets stuck in a state where it refuses to connect, you get constant reconnects, timeouts, and/or `le-connection-abort-by-local` messages in the debug logs, you may need to remove\nyour mug via `bluetoothctl remove my-mac-address` and factory reset your device. It should reconnect correctly afterward.\nYou may also need to re-add it to the app in order to make it writable again as well.\n\n### 'Operation failed with ATT error: 0x0e' or another connection error\n\nThis seems to be caused by the bluetooth adaptor being in some sort of passive mode. I have not yet figured out how to wake it programmatically so sadly, you need to manually open `bluetoothctl` to do so.\nPlease ensure the device is in pairing mode (ie the light is flashing blue or says \"PAIR\") and run the `bluetoothctl` command. You don't need to type anything. run it and wait until the mug connects.\n\n### Model incorrect or not found\n\nI don't have a lot of these devices, so if this library does not correctly identify your device, please open and issue with the advertisement data of your device, so I can update the library to correctly identify it. Thanks!\n\n## Development\n\nInstall:\n- [hatch](https://hatch.pypa.io/latest/install/)\n- [pre-commit](https://pre-commit.com/)\n\n```bash\npip install hatch\n# Use CLI interface\nhatch run ember-mug --help\n# Run Tests\nhatch run test:cov\n# View docs\nhatch docs:serve\n# Lint code\npre-commit run --all-files\n```\n\n## Credits\n\nThis package was created with [Cookiecutter](https://github.com/audreyr/cookiecutter) and the [waynerv/cookiecutter-pypackage](https://github.com/waynerv/cookiecutter-pypackage) project template.\n\n## Notice of Non-Affiliation and Disclaimer\n\nThis project is not affiliated, associated, authorized, endorsed by, or in any way officially connected with Ember.\n\nThe name Ember as well as related names, marks, emblems and images are registered trademarks of their respective owners.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsopelj%2Fpython-ember-mug","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsopelj%2Fpython-ember-mug","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsopelj%2Fpython-ember-mug/lists"}