Skip to main content

pythermacell

A modern, fully-typed async Python client for Thermacell IoT devices (LIV Hub) built on the ESP RainMaker API.

PyPI Version Python Versions License CI GitHub Sponsors Ko-fi Built with Omnigent

What It Does

pythermacell is an asynchronous Python library for controlling and monitoring Thermacell LIV mosquito-repellent devices through their cloud platform (Espressif ESP RainMaker). It handles authentication, device discovery, power and LED control, and status monitoring behind a clean, fully-typed API. It is the engine behind the Thermacell LIV Home Assistant integration, and is equally suitable for standalone scripts and other applications.

Features

  • Fully asynchronous (aiohttp) with comprehensive type hints (strict mypy).
  • Three-layer architecture: low-level API, coordinating client, stateful devices.
  • Power control, RGB LED control (HSV), and refill/runtime/status monitoring.
  • Optimistic updates with automatic rollback for instant UI responsiveness.
  • State caching, optional background auto-refresh, and change listeners.
  • Built-in resilience: circuit breaker, exponential backoff, and rate limiting.
  • Session injection for sharing an aiohttp session (e.g. with Home Assistant).
  • Custom exception hierarchy and high unit + integration test coverage.

Installation

See INSTALL.md for the complete guide.

pip install pythermacell
# or
uv add pythermacell

Requires Python 3.13+.

Quick Start

import asyncio

from pythermacell import ThermacellClient


async def main() -> None:
    async with ThermacellClient(
        username="your@email.com",
        password="your_password",
    ) as client:
        for device in await client.get_devices():
            print(f"{device.name} ({device.model}) online={device.is_online}")

            await device.turn_on()
            await device.set_led_color(hue=120, brightness=80)

            print(f"Refill life: {device.refill_life}%")


asyncio.run(main())

Usage

The most common workflow is: construct a ThermacellClient, enter its async context, fetch devices, then control or monitor them through ThermacellDevice objects. Device control methods apply optimistically (local state updates immediately, then the API call runs in the background and rolls back on failure).

device = (await client.get_devices())[0]

await device.turn_on()                              # power on (optimistic)
await device.set_led_color(hue=240, brightness=80)  # blue
await device.refresh()                              # pull latest state from API

print(device.is_powered_on, device.refill_life, device.system_status)

For depth — authentication, LED rules, monitoring, optimistic updates, auto-refresh and change listeners, session injection, resilience patterns, and full error handling — see the Usage Guide. Runnable scripts live in examples/.

API Reference

Full reference lives in docs/. Key entry points:

Symbol Description
ThermacellClient High-level client: authentication, device discovery, caching
ThermacellDevice Stateful device: power, LED, monitoring, listeners
ThermacellAPI Low-level ESP RainMaker HTTP layer
AuthenticationHandler JWT authentication and token refresh
pythermacell.resilience Circuit breaker, backoff, rate limiter
Exceptions ThermacellError hierarchy

Endpoint-level details are documented under docs/api/.

Development

See docs/DEVELOPMENT.md. In short:

git clone https://github.com/joyfulhouse/pythermacell.git
cd pythermacell
uv sync
uv run pytest
uv run ruff check
uv run mypy

Support

Support Development

If this library is useful to you, please consider supporting its development:

License

This project is licensed under the MIT License — see LICENSE for details.

This is an unofficial library and is not affiliated with, endorsed by, or sponsored by Thermacell Repellents, Inc. All product names, logos, and brands are the property of their respective owners.

  • Thermacell LIV — the Home Assistant integration built on this library.

Built with Omnigent
Built with Omnigent — the open-source AI agent framework and meta-harness.

Native Services and LAN Control

Version 0.3.1 adds capability-driven timers, schedules, reboot, timezone, cloud OTA, and encrypted RainMaker local transport. See verified contracts and examples. Native timers, power confirmation, and cloud services are validated on live hubs (firmware 5.4.7). LAN control is experimental: it is validated only against HTTP/protocol simulators because no tested firmware advertises local control; offline startup is unsupported (#76).

Metadata

Release files for pythermacell 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pythermacell 0.3.1
File Size Uploaded Provenance
pythermacell-0.3.1.tar.gz 303.1 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pythermacell 0.3.1
File Interpreter ABI Platform
pythermacell-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 372.2 kB

Release files / pythermacell-0.3.1.tar.gz

Download URL pythermacell-0.3.1.tar.gz
Size 303.1 kB
Tags Source
SHA-256 checksum
How to use checksums
221d8d407153546cc0efc19556b0a9f58f8e61a766fce48469251353101100a6
BLAKE2b-256 checksum
How to use checksums
902a47024915a800bd7484a0b8d2387774863cd822ba809681d68b92c7de0a8a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / pythermacell-0.3.1-py3-none-any.whl

Download URL pythermacell-0.3.1-py3-none-any.whl
Size 69.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3cabd24752c4c0593bf8e8ed8e46f5b253648e3025506aa29e5234405f067387
BLAKE2b-256 checksum
How to use checksums
e01dfaa4b7e35da74c99e5e77341090c05c42a47d12f4476bf3f0da8bf6863f8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Security for pythermacell 0.3.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pythermacell-0.3.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page