Async client for old Samsung air conditioners using the DPLUG/AC14K protocol (TLS, port 2878)
Project description
pysamsung-dplug
Async Python client for old Samsung air conditioners that speak the legacy
DPLUG / AC14K protocol over TLS on port 2878 (Wi-Fi modules such as
SWL-B70F, used by the AR**HSFS generation, ~2013–2015).
These units were dropped by SmartThings. This library lets you control them
locally again — no cloud. It is the protocol layer used by the
samsung_ac_dplug Home Assistant
integration, but works standalone.
Features
- Mutual-TLS handshake with the bundled Samsung client certificate (legacy TLS 1.0 / weak ciphers handled for you).
- Token acquisition (
GetToken), authentication (AuthToken). - Read full device state (
DeviceState) and send commands (DeviceControl). - Auto-discover the device id (
DeviceList) and a passiveasync_probe(). - Live push updates with auto-reconnect (
SamsungAcStream), alongside the short-lived-connectionSamsungAcClient. - On-device scheduling: read, create/edit and delete the unit's built-in schedules, with local↔UTC time conversion.
- Capability decoding from
AC_ADD2_OPTIONCODE(OptionCode), the device clock, firmware versions, and Wi-Fi provisioning for AP-mode onboarding.
Install
pip install pysamsung-dplug
Usage
import asyncio
from samsung_dplug import SamsungAcClient, build_ssl_context
async def main():
ctx = build_ssl_context() # uses the bundled certificate
client = SamsungAcClient("192.168.1.53", token="xxxxxxxx-....", ssl_context=ctx)
state = await client.async_get_state()
print("Power:", state["AC_FUN_POWER"], "Room:", state["AC_FUN_TEMPNOW"])
await client.async_set("AC_FUN_POWER", "On")
asyncio.run(main())
Getting a token
The unit only issues a token at power-on (a physical proof-of-access step):
client = SamsungAcClient("192.168.1.53", ssl_context=ctx)
# turn the unit OFF, call this, then turn it ON within ~30 s:
token = await client.async_get_token()
build_ssl_context()does blocking file I/O; inside async frameworks run it in an executor (e.g. Home Assistant:await hass.async_add_executor_job(build_ssl_context)).
On-device schedules
The unit has a built-in scheduler that runs off its own clock, even with nothing
connected. Times are stored in UTC; pass your local tzinfo and the library
converts both ways.
from zoneinfo import ZoneInfo
from samsung_dplug import Schedule, EVERYWEEK, weekdays_to_mask
tz = ZoneInfo("Europe/Rome")
await client.async_get_schedules(tz=tz) # -> list[Schedule] (local time)
await client.async_set_schedule( # turn on at 07:00 on weekdays
Schedule(hour=7, minute=0, repeat=EVERYWEEK,
days=weekdays_to_mask(range(5)), # Mon–Fri
attrs={"AC_FUN_POWER": "On"}),
tz=tz,
)
await client.async_delete_schedule("0")
Protocol documentation
Reverse-engineered from the official Smart Air Conditioner app and live
devices. The unit greets with DPLUG-1.x, requires mutual TLS, and uses an
XML request/response protocol over port 2878; the DUID equals the Wi-Fi module
MAC without separators.
The full, structured write-up lives in docs/ — transport &
TLS, connection lifecycle & auth, state & control, scheduling, the other
commands, capability decoding, WiFi provisioning, and the reverse-engineering
notes behind it all.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pysamsung_dplug-1.0.0.tar.gz.
File metadata
- Download URL: pysamsung_dplug-1.0.0.tar.gz
- Upload date:
- Size: 23.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4e46b4b4ce7154de91f4c8972c848026182397376a623bc40ea439428ba4cbc
|
|
| MD5 |
139028802b3134769aea69e76533df4e
|
|
| BLAKE2b-256 |
842aee32feca4c2ad71874524607dcc35d1d220caecb9b5c4d71f8ad8096492b
|
Provenance
The following attestation bundles were made for pysamsung_dplug-1.0.0.tar.gz:
Publisher:
publish.yml on porech/pysamsung-dplug
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pysamsung_dplug-1.0.0.tar.gz -
Subject digest:
f4e46b4b4ce7154de91f4c8972c848026182397376a623bc40ea439428ba4cbc - Sigstore transparency entry: 1824504722
- Sigstore integration time:
-
Permalink:
porech/pysamsung-dplug@f2ea106ae3a0ecbc160fd86c2717b4680836c798 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/porech
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f2ea106ae3a0ecbc160fd86c2717b4680836c798 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pysamsung_dplug-1.0.0-py3-none-any.whl.
File metadata
- Download URL: pysamsung_dplug-1.0.0-py3-none-any.whl
- Upload date:
- Size: 24.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90c3905125e81a500eb8528d0352697659fa6c7d0bc99f4cced06697dfa9525d
|
|
| MD5 |
1c9347c72dccd66a58d5811cb223bb1b
|
|
| BLAKE2b-256 |
3ac387764820f08cf554c5dce29231d73b5786c35e0f65999c424223877f0ddc
|
Provenance
The following attestation bundles were made for pysamsung_dplug-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on porech/pysamsung-dplug
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pysamsung_dplug-1.0.0-py3-none-any.whl -
Subject digest:
90c3905125e81a500eb8528d0352697659fa6c7d0bc99f4cced06697dfa9525d - Sigstore transparency entry: 1824504858
- Sigstore integration time:
-
Permalink:
porech/pysamsung-dplug@f2ea106ae3a0ecbc160fd86c2717b4680836c798 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/porech
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f2ea106ae3a0ecbc160fd86c2717b4680836c798 -
Trigger Event:
push
-
Statement type: