Skip to main content

aio-panasonic-comfort-cloud

aio-panasonic-comfort-cloud: Asynchronous Python library for Panasonic Comfort Cloud API

This library provides asynchronous access to the Panasonic Comfort Cloud API, enabling developers to interact with Panasonic air conditioning units.

Installation

pip install aio-panasonic-comfort-cloud

Quick Start

Basic Usage

import asyncio
import aiohttp
from aio_panasonic_comfort_cloud import ApiClient

async def main():
    async with aiohttp.ClientSession() as session:
        client = ApiClient("your_email@example.com", "your_password", session)
        
        # Start the session (authenticate and fetch devices)
        await client.start_session()
        
        # Get list of devices
        devices = client.get_devices()
        
        for device_info in devices:
            print(f"Device: {device_info.name}")
            
            # Get full device status
            device = await client.get_device(device_info)
            params = device.parameters
            
            print(f"  Power:       {params.power.name}")
            print(f"  Mode:        {params.mode.name}")
            print(f"  Fan Speed:   {params.fan_speed.name}")
            print(f"  Target Temp: {params.target_temperature}°C")
            print(f"  Inside Temp: {params.inside_temperature}°C")
        
        # Clean up the session
        await client.stop_session()

asyncio.run(main())

Controlling a Device

Use ChangeRequestBuilder for a fluent API to build and apply changes:

from aio_panasonic_comfort_cloud import ApiClient, ChangeRequestBuilder, constants

# ... (start session as above)

device = await client.get_device(devices[0])

builder = ChangeRequestBuilder(device)
builder.set_power_mode(constants.Power.On)
builder.set_hvac_mode(constants.OperationMode.Cool)
builder.set_target_temperature(24)
builder.set_fan_speed(constants.FanSpeed.Auto)

if builder.has_changes:
    await client.set_device_raw(device, builder.build())

Available Enums

Category Values
Power Off, On
OperationMode Auto, Dry, Cool, Heat, Fan
FanSpeed Auto, Low, LowMid, Mid, HighMid, High
EcoMode Auto, Powerful, Quiet
AirSwingUD Auto, Up, UpMid, Mid, DownMid, Down, Swing
AirSwingLR Auto, Left, LeftMid, Mid, RightMid, Right, Unavailable
NanoeMode Unavailable, Off, On, ModeG, All

ChangeRequestBuilder Methods

  • set_power_mode(value) — Set power on/off
  • set_hvac_mode(value) — Set operation mode (cool, heat, etc.)
  • set_target_temperature(value) — Set target temperature in °C
  • set_fan_speed(value) — Set fan speed
  • set_eco_mode(value) — Set eco mode
  • set_horizontal_swing(value) — Set horizontal air swing
  • set_vertical_swing(value) — Set vertical air swing
  • set_nanoe_mode(value) — Set Nanoe mode
  • set_eco_navi_mode(value) — Set EcoNavi mode
  • set_eco_function_mode(value) — Set EcoFunction mode

Getting Energy History

from datetime import date
from aio_panasonic_comfort_cloud import constants

today = date.today().strftime("%Y%m%d")
history = await client.history(device_info.id, constants.DataMode.Day, today)

Aquarea (Air to Water heat pump) Support

Aquarea units show up in the same account/group listing as air conditioners, but expose a different status shape (hot water tank + heating/cooling zones instead of a single parameters object), so they're kept separate from get_devices():

devices = client.get_devices()          # air conditioners
aquarea_devices = client.aquarea_devices  # Aquarea heat pumps

for device_info in aquarea_devices:
    device = await client.get_aquarea_device(device_info)
    params = device.parameters

    print(f"{device_info.name}: {params.operation_status.name} / {params.operation_mode.name}")
    if params.has_tank:
        print(f"  Tank: {params.tank.temperature}°C -> {params.tank.heat_set}°C")
    for zone in params.zones:
        print(f"  Zone {zone.id} ({zone.name}): {zone.temperature}°C -> {zone.heat_set}°C")

    # Refresh status in place
    await client.try_update_aquarea_device(device)

Controlling a unit:

from aio_panasonic_comfort_cloud import constants

await client.set_aquarea_operation_status(device_info, constants.AquareaOperationStatus.On)
await client.set_aquarea_operation_mode(device_info, constants.AquareaUpdateOperationMode.Heat)
await client.set_aquarea_tank_temperature(device_info, 55)
await client.set_aquarea_tank_operation_status(device_info, constants.AquareaOperationStatus.On)
await client.set_aquarea_zone_temperature(device_info, zone_id=1, temperature=22, mode="heat")
await client.set_aquarea_quiet_mode(device_info, constants.AquareaQuietMode.Level1)
await client.set_aquarea_force_dhw(device_info, constants.AquareaForceDHW.On)

Terms / Privacy Policy Agreements

Panasonic occasionally updates its Terms of Use, Privacy Policy or Cookie Policy; when that happens, API calls start failing with error code 4103 until the account re-accepts them. You can fetch and handle this yourself:

# Fetch the current documents (set include_content=True to get the full text)
documents = await client.get_agreement_documents(include_content=True)
for doc in documents:
    print(doc["type"], doc["version"], doc.get("content", "")[:80])

# See what's already been accepted on this account
accepted = await client.get_agreement_status()

# Auto-accept anything outdated/missing (Terms, Privacy, Cookie Policy —
# the Turkey-only Service Agreement is intentionally excluded, matching
# the official app's behavior of only surfacing it to a subset of accounts)
await client.ensure_all_agreements_accepted()

This isn't called automatically on login — auto-accepting legal agreements is a decision your application should make deliberately, not something the library does silently. A typical pattern is to catch AgreementNotAcceptedError from start_session()/_get_groups() and call ensure_all_agreements_accepted() (or show the fetched document text to the user first) in response.

2FA / MFA Support

If your account has two-factor authentication enabled, start_session() raises MFARequiredError instead of logging in. Catch it, prompt the user for the OTP code from their authenticator app, and retry with it:

from aio_panasonic_comfort_cloud.exceptions import MFARequiredError

try:
    await client.start_session()
except MFARequiredError:
    otp_code = input("Enter the 2FA code: ")
    await client.start_session(otp_code=otp_code)

Alternative: Browser-Based Authentication

start_session() drives Panasonic's login page itself — it POSTs your credentials and scrapes the resulting HTML/redirects, which has to correctly handle whatever Auth0 renders for every connection type (password, MFA, social login, ...). As an alternative that sidesteps all of that, you can let a real browser (a WebView, the system browser, etc.) handle the login instead and just hand the result back to the library:

# 1. Build the URL and open it in any browser
auth_url, code_verifier = client.get_browser_authorization_url()
print(f"Open this URL and log in: {auth_url}")

# 2. After login, the browser is redirected to a URL starting with
#    "panasonic-iot-cfc://...callback?code=...". Capture that redirect
#    (however your application observes it — a WebView navigation listener,
#    a custom URI scheme handler, pasting it in, etc.) and finish the login:
redirect_url = input("Paste the redirect URL here: ")
await client.complete_browser_authentication(redirect_url, code_verifier)

# From here on, the client behaves exactly as if start_session() had been
# called — get_devices(), get_device(), etc. all work normally.
devices = client.get_devices()

This is entirely separate from start_session()/authenticate() — it doesn't change how the default username/password flow behaves, it's just another way to obtain the same tokens. Because Auth0's own hosted page handles the actual login, this path naturally supports MFA, social login, etc. without any special-casing in the library.

Full Example

See example.py for a complete working example.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aio_panasonic_comfort_cloud-2026.8.0.tar.gz (43.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aio_panasonic_comfort_cloud-2026.8.0-py3-none-any.whl (41.5 kB view details)

Uploaded Python 3

File details

Details for the file aio_panasonic_comfort_cloud-2026.8.0.tar.gz.

File metadata

File hashes

Hashes for aio_panasonic_comfort_cloud-2026.8.0.tar.gz
Algorithm Hash digest
SHA256 4148231f748a74737d3ba8eab9950da9cc92dcd8607353da60f4dbe2eaf25eaa
MD5 a69e3d73b71094226866492c5d034080
BLAKE2b-256 71d7ae5f5c75882bfa2a4e751df795a97eef7fb6e4b726e7ebd35c92bccfb82b

See more details on using hashes here.

Provenance

The following attestation bundles were made for aio_panasonic_comfort_cloud-2026.8.0.tar.gz:

Publisher: python-publish.yml on sockless-coding/aio-panasonic-comfort-cloud

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file aio_panasonic_comfort_cloud-2026.8.0-py3-none-any.whl.

File metadata

File hashes

Hashes for aio_panasonic_comfort_cloud-2026.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 513095a5ef69c59256e2b4b5bd865530f51b6133486ff6b6d5c5135e29904ecd
MD5 c5e86bb369f6da345a0a3dec90283014
BLAKE2b-256 7a4d4163b8836a5a5bda0883a15e6890b58d777d776b0f8ad51fc682b5c8871b

See more details on using hashes here.

Provenance

The following attestation bundles were made for aio_panasonic_comfort_cloud-2026.8.0-py3-none-any.whl:

Publisher: python-publish.yml on sockless-coding/aio-panasonic-comfort-cloud

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

2026.8.9

2 files

2026.8.8

2 files

2026.8.7

2 files

2026.8.6

2 files

2026.8.5

2 files

2026.8.4

2 files

2026.8.3

2 files

2026.8.2

2 files

2026.8.1

2 files

This release

2026.8.0 This release

2 files

2026.6.2

2 files

2026.6.1

2 files

2026.6.0

2 files

2025.5.1

2 files

2025.5.0

2 files

2025.1.2

2 files

2025.1.1

2 files

2025.1.0

2 files

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