Skip to main content

eakon

eakon is a simple python library to control air-conditioners.

There are many examples of such code on the web, but I found none did not cover my needs:

Each HVAC unit to control needs to have its own instance created (the instance being dependent on the unit maker).

  • Each instance keeps track of the current status of the air-conditioner (assuming it is not changed with the unit remote control)

  • The status can be made persistent

  • handle japanese market air-conditioners

Moreover, the code was to be kept the least esoteric as possible, to ensure readability and evolutions.

Usage of bitstring greatly helped to reach this objective.

Usage

During or after instantiation, settings are made, and you get either a bitstring or a wave. The wave is in a format to be consumed by the pigpio library, following the example of the sample irrp.py script.

N.B. : The irrp.py script has length limitations. You can refer to (or better yet, use) my AnaviInfraredPhat library which handles compression of waves for working around length limitations of pigpio.

The compression algorithm is credit of https://korintje.com/archives/28

hvac = Daikin()
hvac.power = daikin_enum.Power.ON
hvac.temperature = 21
hvac.mode = daikin_enum.Mode.COOL
hvac.fan_vertical_mode = daikin_enum.FanVerticalMode.TOP

logging.info("\r{}".format(hvac))
logging.info(hvac.bitstring)
logging.info(hvac.wave)
>>
2020 - 01 - 01
00: 00:00.000
UTC[INFO]
__init__:
Model: Daikin
power: ON
mode: COOL
temperature: 21°C
wide_vanne_mode: NOT_AVAILABLE
area_mode: NOT_AVAILABLE
fan_power: AUTO
fan_high_power: NOT_AVAILABLE
fan_vertical_mode: TOP
fan_horizontal_mode: UNDEFINED
fan_long: NOT_AVAILABLE

2020 - 01 - 01
00: 00:00.000
UTC[INFO]
__init__: 100010000101101111100100000000000100000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000010010010001000010110111110010000000000000000001001110001010100000000000000010100000000000000000110000000000110000000000000000011000011000000000000000001111100
2020 - 01 - 01
00: 00:00.000
UTC[INFO]
__init__: [433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 25194, 3495, 1746, 433, 1288, 433, 440, 433, 440, 433,
           440, 433, 1288, 433, 440, 433, 440, 433, 440, 433, 440, 433, 1288, 433, 440, 433, 1288, 433, 1288, 433, 440,
           433, 1288, 433, 1288, 433, 1288, 433, 1288, 433, 1288, 433, 440, 433, 440, 433, 1288, 433, 440, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 1288, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           1288, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           1288, 433, 440, 433, 440, 433, 1288, 433, 440, 433, 440, 433, 25194, 3495, 1746, 433, 1288, 433, 440, 433,
           440, 433, 440, 433, 1288, 433, 440, 433, 440, 433, 440, 433, 440, 433, 1288, 433, 440, 433, 1288, 433, 1288,
           433, 440, 433, 1288, 433, 1288, 433, 1288, 433, 1288, 433, 1288, 433, 440, 433, 440, 433, 1288, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 1288, 433, 440, 433, 440, 433, 1288, 433,
           1288, 433, 1288, 433, 440, 433, 440, 433, 440, 433, 1288, 433, 440, 433, 1288, 433, 440, 433, 1288, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 1288, 433, 440, 433, 1288, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 1288, 433, 1288, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 1288, 433, 1288, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 1288, 433, 1288, 433, 440, 433, 440, 433, 440, 433, 440, 433, 1288, 433, 1288, 433, 440, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 440, 433, 1288, 433, 1288, 433, 1288, 433, 1288, 433, 1288, 433, 440, 433,
           440, 433]

hvac.power = daikin_enum.Power.OFF
logging.info("\r{}".format(hvac))
logging.info(hvac.bitstring)
logging.info(hvac.wave)
>>
2020 - 01 - 01
00: 00:00.000
UTC[INFO]
__init__:
Model: Daikin
power: OFF
mode: COOL
temperature: 21°C
wide_vanne_mode: NOT_AVAILABLE
area_mode: NOT_AVAILABLE
fan_power: AUTO
fan_high_power: NOT_AVAILABLE
fan_vertical_mode: TOP
fan_horizontal_mode: UNDEFINED
fan_long: NOT_AVAILABLE

2020 - 01 - 01
00: 00:00.000
UTC[INFO]
__init__: 100010000101101111100100000000000100000000000000000000000000000000000000000000000000000000000001000010000000000000000000000000000000000000000000000000000010010110001000010110111110010000000000000000000001110001010100000000000000010100000000000000000110000000000110000000000000000011000011000000000000000010111100
2020 - 01 - 01
00: 00:00.000
UTC[INFO]
__init__: [433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 25194, 3495, 1746, 433, 1288, 433, 440, 433, 440, 433,
           440, 433, 1288, 433, 440, 433, 440, 433, 440, 433, 440, 433, 1288, 433, 440, 433, 1288, 433, 1288, 433, 440,
           433, 1288, 433, 1288, 433, 1288, 433, 1288, 433, 1288, 433, 440, 433, 440, 433, 1288, 433, 440, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 1288, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 1288, 433, 440, 433, 440, 433, 440, 433, 440,
           433, 1288, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           1288, 433, 440, 433, 440, 433, 1288, 433, 440, 433, 1288, 433, 25194, 3495, 1746, 433, 1288, 433, 440, 433,
           440, 433, 440, 433, 1288, 433, 440, 433, 440, 433, 440, 433, 440, 433, 1288, 433, 440, 433, 1288, 433, 1288,
           433, 440, 433, 1288, 433, 1288, 433, 1288, 433, 1288, 433, 1288, 433, 440, 433, 440, 433, 1288, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 1288, 433,
           1288, 433, 1288, 433, 440, 433, 440, 433, 440, 433, 1288, 433, 440, 433, 1288, 433, 440, 433, 1288, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 1288, 433, 440, 433, 1288, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 1288, 433, 1288, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 1288, 433, 1288, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433,
           440, 433, 1288, 433, 1288, 433, 440, 433, 440, 433, 440, 433, 440, 433, 1288, 433, 1288, 433, 440, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440, 433, 440,
           433, 440, 433, 440, 433, 440, 433, 1288, 433, 440, 433, 1288, 433, 1288, 433, 1288, 433, 1288, 433, 440, 433,
           440, 433]

The bitstring is mostly used for debugging purpose, but I assume it could be used for other purpose.

Now, you may have multiple HVAC of different models in your housing, and you may need an easy way to configure which model is in which room.

For such cases, a helper method is available for dynamically instantiating by name:

try:
  e = get_eakon_instance_by_model("toshiba")
  e.power = e.enums["Power"].ON
  e.temperature = 26
  e.mode = e.enums["Mode"].COOL
  logging.info("\r\n{}".format(e))
  logging.info(e.bitstring)
except NotImplementedError as e:
  logging.warning(e)
>>
2020 - 01 - 01
00: 00:00.000
UTC[INFO]
__init__:
Model: Toshiba
power: ON
mode: COOL
temperature: 26°C
wide_vanne_mode: NOT_AVAILABLE
area_mode: NOT_AVAILABLE
fan_power: UNDEFINED
fan_high_power: NOT_AVAILABLE
fan_vertical_mode: UNDEFINED
fan_horizontal_mode: NOT_AVAILABLE
fan_long: NOT_AVAILABLE

2020 - 01 - 01
00: 00:00.000
UTC[INFO]
__init__: 110000100011110110111111010000001101000000101111
2020 - 01 - 01
00: 00:00.000
UTC[WARNING]
__init__: No
module
toto
implementing


class Toto was found.Model toto is unsupported.

As you can notice comparing the two above examples, the Daikin class supports setting the 'fan_horizontal_mode' (but is currently UNDEFINED) but the Toshiba class doesn't.

Moreover, the first example shows settings the properties by direct use of the associated enumerations, while the second example shows setting properties by name.

N.B.: The purpose here is to allow accessing the model specific enumerations without having to refer to them in a hardcoded manner.

Settings values can also be set with strings, i.e. e.power = e.enums["Power"].ON is equivalent to e.power = e.enums["Power"]["ON"]

Accessing an unavailable enumeration element will raise either an AttributeError or a KeyError, depending on the access method employed:

e.power = e.enums["Power"].PARTIALLY_ON
>>
AttributeError: PARTIALLY_ON

e.power = e.enums["Power"]["PARTIALLY_ON"]
>>
KeyError: 'PARTIALLY_ON'

Lastly, if a model is unsupported, a NotImplementedError is raised:

try:
  e = get_eakon_instance_by_model("toto")
except NotImplementedError as e:
  logging.warning(e)
>>
2020 - 01 - 01
00: 00:00.000
UTC[WARNING]
__init__: No
module
toto
implementing


class Toto was found.Model toto is unsupported.

(Known) Supported models

As the name (エアコン) of the library implies, there is a strong focus on japanese brands, and quite possibly is limited to recent (2020) japanese models.

Development was done with the following models of remote controls:

Implementation of additional models should be relatively easy.

Limitations

Only standard functions are implemented, in extenso:

  • timers aren't supported (by lack of interest)
  • extra functions like unit cleaning, triggering of diagnostic, etc... aren't supported
  • half degrees available on some units aren't supported

Installation

python3 -m pip install eakon

Metadata

Release files for eakon 0.0.15

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

Source distribution (sdist)

Source distribution for eakon 0.0.15
File Size Uploaded Provenance Actions
eakon-0.0.15.tar.gz 16.7 kB Without provenance Details for eakon-0.0.15.tar.gz

Built distribution (wheel)

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

Total release size: 36.2 kB

Release files / eakon-0.0.15.tar.gz

Download URL eakon-0.0.15.tar.gz
Size 16.7 kB
Tags Source
SHA-256 checksum
How to use checksums
da2e5b97bfccebad5c8a5550913c8c4953fe3a067068aedcd9161ca509fbd859
BLAKE2b-256 checksum
How to use checksums
9631a4bfe66f2537b15d75b060a8b3c904f65cff72503accafd57129b915e682
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.12.7

Release files / eakon-0.0.15-py3-none-any.whl

Download URL eakon-0.0.15-py3-none-any.whl
Size 19.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7ee75e85d4f1ae821d254f19b0db4ed576d9508602660a177301a1e71d8615aa
BLAKE2b-256 checksum
How to use checksums
314fd7e6c1b97f9de1c60524f1447751609978d41a8b5e84601cb91bc49755ff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.12.7

Security for eakon 0.0.15

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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