npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

homebridge-klarstein-smart-ac

v1.0.1

Published

Homebridge dynamic platform plugin for Klarstein Kraftwerk Smart 12K / Klarstein Smart mobile air conditioners (Tuya / Smart Life). Local control, mock mode, and a datapoint discovery tool.

Readme

Homebridge Klarstein Smart AC

npm type

A Homebridge dynamic platform plugin for the Klarstein Kraftwerk Smart 12K and other Klarstein "Smart" / Smart-Life Tuya-based mobile air conditioners. It exposes the AC to Apple HomeKit either as a Heater Cooler tile or as a Thermostat (a circular temperature dial with an Off/Cool/Auto mode dropdown) — your choice per device — with power, setpoint, current temperature, fan speed, and optional Fan and Dry-mode tiles.

Because Tuya datapoints differ across models and firmwares, the plugin is fully configuration-driven and ships a discovery mode + CLI so you can map your exact device. It also includes a mock mode so you can try everything in HomeKit before touching real hardware.

⚠️ Datapoints differ by model/firmware. The default datapoint map is a starting point, not a guarantee. Always confirm your device's real datapoints with discovery (see Datapoint discovery) before relying on them. Example maps in this document are clearly marked UNVERIFIED.


Features

  • Two presentations (per device, via presentation): a Heater Cooler tile (Active, Cool/Auto, cooling setpoint 18–32 °C, current temperature, fan-speed slider, swing) or a Thermostat — a circular temperature dial with an Off / Cool / Auto mode dropdown (Dyson-style climate tile).
  • Mock mode — a fully working simulated AC; no hardware needed.
  • Tuya Local control over your LAN via tuyapi (no cloud round-trip, fast, private).
  • Configurable datapoint mapping — handles both the canonical low-DP scheme and the vendor high-DP scheme (including "inverted" fans where 1 = high).
  • Discovery mode + CLI to dump your device's datapoints safely (secrets are never logged).
  • Optional Fan tile — a 3-speed air-flow control that mirrors the AC power — and Dry-mode switch.
  • Robust: non-blocking HomeKit getters, background polling, automatic reconnect with backoff, graceful handling of bad config and offline devices.
  • Secret-safe logging: local keys/tokens are never printed; device ids are masked.

Supported / target devices

| | | |---|---| | Primary target | Klarstein Kraftwerk Smart 12K (12 000 BTU, 3-in-1, Wi-Fi / Klarstein app) | | Also intended for | Other Klarstein "Smart" portable ACs and many Tuya / Smart Life portable ACs (category kt) | | Control | Local LAN (recommended) or Mock. (Tuya Cloud is scaffolded but not implemented — see Roadmap.) | | Requires | The device's Tuya Device ID and Local Key (for local control). |

Any Tuya-based portable AC that the Smart Life / Tuya app controls is likely to work once its datapoints are mapped. If you map a device, please contribute the mapping!


Installation

Via the Homebridge UI (recommended): search for Klarstein Smart AC on the Plugins tab and install.

Via the command line:

npm install -g homebridge-klarstein-smart-ac

Requires Homebridge ≥ 1.8 and Node.js ≥ 20.18.


Quick start (mock mode)

Try it with no hardware first. Add this platform block to your Homebridge config.json (or use the UI form):

{
  "platforms": [
    {
      "platform": "KlarsteinSmartAC",
      "name": "Klarstein",
      "devices": [
        { "name": "Test AC", "protocol": "mock" }
      ]
    }
  ]
}

Restart Homebridge — a working "Test AC" Heater Cooler appears in the Home app. Toggle power, change the setpoint and fan speed; the simulated state responds (temperature drifts toward the setpoint while cooling).


Configuring a real device (Tuya Local)

You need two things from the device: its Device ID and its Local Key.

1. Obtain the Device ID and Local Key

These are not secrets the plugin can fetch for you — you obtain them once from your own Tuya account using any of the standard, well-documented tools (the plugin never scrapes credentials):

  • Tuya IoT Platform developer account → CloudDevicesDevice Details / Debug Device exposes the device id and local key.
  • tuya-cli: tuya-cli wizard walks you through linking your account and lists each device's id and key.
  • tinytuya (Python): python -m tinytuya wizard.
  • Home Assistant's LocalTuya / tuya-local document the same flow.

The Local Key changes if you remove and re-add the device in the Tuya/Smart Life app — grab a fresh key if control stops working.

2. Find the device IP

Assign the AC a static / reserved IP in your router (strongly recommended). If you leave the IP blank, the plugin will try to discover it on the LAN, but a fixed IP is far more reliable.

3. Add the device

UI: choose Tuya Local (LAN), fill in the Device ID, IP and Local Key. Or in config.json:

{
  "platforms": [
    {
      "platform": "KlarsteinSmartAC",
      "name": "Klarstein",
      "devices": [
        {
          "name": "Living Room AC",
          "protocol": "tuya-local",
          "id": "REPLACE_WITH_DEVICE_ID",
          "ip": "192.168.1.50",
          "key": "REPLACE_WITH_LOCAL_KEY",
          "version": "3.3",
          "discovery": true
        }
      ]
    }
  ]
}

Leave discovery on for the first run, check the log (see next section), map the datapoints, then turn it off.


Datapoint (DP) discovery

Tuya portable ACs use two incompatible datapoint schemes, and you cannot tell which one your unit uses without looking. Discovery shows you.

Option A — built-in discovery mode

Set "discovery": true on the device and restart Homebridge. After it connects, the log prints every datapoint with its id, type and current value:

[Living Room AC] ──────── Datapoint discovery ────────
[Living Room AC] Device "Living Room AC" [bf12…7f3a], protocol tuya-local.
[Living Room AC] Found 6 datapoint(s):
[Living Room AC]   DP   1   type=bool        value=true   ← currently configured as "power"
[Living Room AC]   DP   2   type=value       value=22
[Living Room AC]   DP 101   type=enum/string value="1"
[Living Room AC]   DP 104   type=enum/string value="3"
...

Operate the AC from its physical panel or the Klarstein app while watching the log — note which DP changes when you change power, temperature, mode and fan speed. (Some devices only reveal a DP once that function has been used.)

Option B — the discovery CLI

A standalone command does the same without Homebridge:

homebridge-klarstein-discover --id <DEVICE_ID> --key <LOCAL_KEY> --ip <IP> --version 3.3
# or, from a checkout:  npm run build && npm run discover -- --id <ID> --key <KEY> --ip <IP>

Credentials can also come from env vars: KLARSTEIN_ID, KLARSTEIN_KEY, KLARSTEIN_IP, KLARSTEIN_VERSION. The local key is read but never printed.

Close the Tuya / Smart Life app first — a Tuya device allows only one local connection at a time, and the app will block the plugin.

Option C — Home Assistant / external tools

tuya-local and LocalTuya also show live DPS, and tuya-cli get --id <ID> --key <KEY> --ip <IP> --protocol-version 3.3 --all dumps the raw map.

Mapping what you find

Put the ids you discovered into dataPoints, and the raw enum strings into modeMap / fanMap:

{
  "tempScale": 1,                 // 1 = whole degrees; use 10 if the device reports tenths
  "dataPoints": {
    "power": 1,
    "tempSet": 2,
    "tempCurrent": 3,
    "mode": 101,                  // whatever DP changed with mode
    "fanSpeed": 104,              // whatever DP changed with fan speed
    "swing": 0                    // omit if your unit has no network swing
  },
  "modeMap": { "cool": "1", "dry": "3", "fan": "5" },   // raw values you observed
  "fanMap":  { "low": "3", "medium": "2", "high": "1" } // note: this device's fan is "inverted"
}

Example datapoint maps (⚠️ UNVERIFIED — confirm with discovery)

There is no single correct map. Below are the two common schemes for portable ACs. Try one; if control does nothing, run discovery and adjust.

Scheme A — canonical Tuya kt (word enums) — plugin default

// DP 1 power (bool), 2 target °C, 3 current °C, 4 mode, 5 fan
{
  "dataPoints": { "power": 1, "tempSet": 2, "tempCurrent": 3, "mode": 4, "fanSpeed": 5 },
  "modeMap": { "cool": "cold", "auto": "auto", "dry": "wet", "fan": "wind" },
  "fanMap":  { "low": "low", "medium": "mid", "high": "high", "auto": "auto" }
}

Scheme B — vendor high-DP (numeric-string enums) — closest to the known Klarstein "Iceblock"

// Mirrors make-all/tuya-local "klarstein_iceblock_airconditioner". STILL verify for your model.
// Note: mode on DP101 as "1"/"3"/"5", fan on DP104 where "1"=high, "3"=low (inverted!).
{
  "dataPoints": { "power": 1, "tempSet": 2, "tempCurrent": 3, "mode": 101, "fanSpeed": 104 },
  "modeMap": { "cool": "1", "dry": "3", "fan": "5" },
  "fanMap":  { "low": "3", "medium": "2", "high": "1" }
}

The Kraftwerk Smart 12K is a different model from the Iceblock, so neither map is guaranteed — discovery is the source of truth.


How it appears in HomeKit

Pick the tile per device with presentation:

  • heatercooler (default) — a Heater Cooler tile: Active (on/off), a Cool/Auto control, cooling setpoint, current temperature, a fan-speed slider, and swing (if supported).
  • thermostat — a single Thermostat: a circular temperature dial plus a mode dropdown of Off / Cool / Auto (and Heat only if you map modeMap.heat). HomeKit hard-locks that dropdown to Off/Heat/Cool/Auto, so Dry and Fan-only are not dropdown entries — expose them as the separate tiles below instead.

| Device mode | HomeKit | |---|---| | Cool | Cool | | Auto | Auto (only if a modeMap.auto value is set) | | Dry / Dehumidify | optional Dry switch (exposeDryModeSwitch), requires modeMap.dry | | Fan only | covered by the optional Fan tile (exposeFanService), requires modeMap.fan |

The optional Fan tile is a 3-speed air-flow control: its on/off mirrors the AC power (it does not switch the AC off — that's the thermostat / Heater Cooler's job), and its slider sets the fan speed in any mode. Fan speed maps to RotationSpeed at Low 33 % / Medium 66 % / High 99 %. Both optional tiles are off by default — enable them per device once their mode is mapped.


Configuration reference

Each entry in devices:

| Key | Type | Default | Notes | |---|---|---|---| | name | string | — | Required. Display name in HomeKit. | | protocol | mock|tuya-local|tuya-cloud | mock | tuya-cloud is not implemented yet. | | id | string | — | Tuya device id. Required for tuya-local. | | ip | string | (auto) | Static IP recommended. | | key | string | — | Tuya local key. Required for tuya-local. Stored in plaintext in config.json. | | version | string | 3.3 | Tuya protocol: 3.1/3.2/3.3/3.4/3.5. | | pollInterval | int (s) | 30 | 5–600. | | minTemp / maxTemp | int °C | 18 / 32 | Cooling setpoint range. | | tempScale | int | 1 | Divide raw value by this to get °C (use 10 for tenths). | | presentation | heatercooler|thermostat | heatercooler | HomeKit tile: a Heater Cooler, or a Thermostat dial + Off/Cool/Auto dropdown. | | exposeFanService | bool | false | Adds a 3-speed Fan tile (air-flow; mirrors power). | | exposeDryModeSwitch | bool | false | Adds a dry-mode switch. | | fanControl | slider|switches|both | slider | Heater-Cooler fan UI: in-tile slider, named Low/Med/High switches, or both. | | debug | bool | false | Verbose, device-scoped logging. | | discovery | bool | false | Logs all datapoints at start-up. | | dataPoints | object | canonical kt | DP id map (see discovery). | | modeMap / fanMap | object | canonical | Raw enum value maps. |


Troubleshooting

| Symptom | Likely cause / fix | |---|---| | Accessory shows "No Response" | Device unreachable: wrong IP, wrong/expired local key, or the device is offline. Check the log. | | Connects then immediately disconnects | Wrong version. Try 3.4, then 3.5, then 3.1. | | Nothing happens when you change mode/fan | Wrong DP ids or wrong enum strings — run discovery and fix dataPoints / modeMap / fanMap. | | Fan slider feels backwards | The device uses an "inverted" fan map (1 = high). Set fanMap accordingly (Scheme B). | | Temperature reads 10× too high/low | Set tempScale (e.g. 10 if the device reports tenths). | | Can't connect at all / "key is incorrect" | The Tuya/Smart Life app (or another integration) holds the single local connection. Close it. Re-fetch the local key if you re-paired the device. | | No current temperature | Some units don't expose an ambient-temperature DP; the plugin then mirrors the setpoint. |

Collecting logs safely

Enable "debug": true on the device and reproduce the issue. The plugin redacts local keys and masks device ids in its own log lines, so its output is safe to share. Before posting a Homebridge log or your config.json, double-check you have removed key values and full ids from any parts not produced by this plugin.


Security notes

  • The Tuya local key is a secret. The plugin never logs it; ids are masked (bf12…7f3a).
  • The key is stored in plaintext in config.json (the UI only masks the input field). Protect your Homebridge config and host accordingly.
  • No telemetry, no analytics, no postinstall scripts. All control stays on your LAN.
  • Runtime state is kept only in Homebridge's accessory cache.

Roadmap

  • Tuya Cloud control is scaffolded (TuyaCloudClient) but not implemented — selecting it fails fast with a clear message. Use tuya-local. Cloud support may be added later behind the same DeviceClient interface.
  • Optional timer / child-lock / fault surfaces once enough devices are mapped.

Contributing a datapoint map

Mapped your device? Please open a PR or issue with:

  • Device model and Tuya product id (from discovery / the Tuya IoT platform — not your device id or key),
  • the working dataPoints, modeMap, fanMap, version, and tempScale,
  • anything unusual (inverted fan, deci-degree temperatures, missing sensors).

This builds a community library of verified maps for Klarstein/Tuya ACs.

Developing

npm install
npm run build      # compile TypeScript to dist/
npm run lint       # eslint (flat config)
npm test           # vitest unit tests
npm run watch      # incremental compile

The architecture keeps all device transport behind a DeviceClient interface (Mock / TuyaLocal / TuyaCloud), with pure, unit-tested mapping logic.


Disclaimer

Not affiliated with or endorsed by Klarstein or Tuya. "Klarstein", "Kraftwerk", "Tuya" and "Smart Life" are trademarks of their respective owners. Use at your own risk.

License

MIT