Skip to content

Repository files navigation

Chainik

CI License: MIT Platform: Windows Python

Chainik is a one-purpose Windows utility: it reminds you that the kettle has boiled, so you do not forget to go back for your tea. That is the whole idea.

It watches the power consumption of a TP-Link Tapo P110 smart plug. When a normal electric kettle stops drawing heating power, Chainik shows a Windows notification and can optionally send a Telegram message.

Important: Chainik does not switch the plug or kettle on or off. It is a convenience reminder, not an electrical, fire-safety, or unattended-operation system.

Why this exists

You switch on the kettle, return to your desk, put on headphones, and forget about it. Chainik notices the characteristic drop in power after the heating cycle and says: "The kettle has boiled."

The tray window, logs, test mode, and autostart are only there to support that single function.

What it does

  • reads live power usage from one Tapo P110 on the local network;
  • detects a heating cycle from the rise and subsequent drop in power;
  • shows a Windows toast notification;
  • optionally sends a Telegram message;
  • runs in the system tray;
  • can start automatically when the current Windows user signs in;
  • keeps a small rotating diagnostic log.

What it does not do

  • it does not measure water temperature;
  • it does not prove that the water physically reached boiling point;
  • it does not turn the smart plug or kettle on or off;
  • it does not replace the kettle's own safety cutoff;
  • it does not work while the PC is off or asleep;
  • it does not support multiple plugs;
  • it is not tested with P100, P110M, P115, or other plug models;
  • it is not a Windows service and does not automatically restart after a crash.

A manual switch-off after a sufficiently long heating period can look exactly like a completed boil cycle because detection is based only on power usage.

How detection works

The default state machine is deliberately simple:

  1. IDLE — the kettle is not drawing heating power.
  2. A reading above 1500 W changes the state to HEATING.
  3. Heating must last for at least 30 seconds.
  4. Two consecutive readings below 50 W confirm the end of heating.
  5. Chainik sends the enabled notifications and returns to IDLE.
  6. A 5 minute cooldown prevents duplicate messages.

The plug is checked every 10 seconds, so the default notification usually appears roughly 10–20 seconds after the kettle switches itself off. All values can be changed in config.json.

Electric kettle -> Tapo P110 -> local power reading -> Chainik
                                                     |-> Windows toast
                                                     `-> Telegram (optional)

What you need to buy

Required hardware

  1. TP-Link Tapo P110 with energy monitoring. The code explicitly uses the P110 API and its current-power measurement. A Tapo P100 is not suitable because it does not provide the required energy telemetry. Compatibility with other models is not claimed.
  2. An ordinary electric kettle with a normal mechanical or electronic automatic shutoff.
  3. A Windows PC that stays on and awake while the kettle is heating.
  4. A Wi-Fi router/local network. The P110, PC, and router must be able to reach each other. A 2.4 GHz Wi-Fi network is needed for P110 onboarding.
  5. A smartphone with the official Tapo app for the initial plug setup.

No separate Tapo Hub is required for the P110.

Electrical safety before purchase

Check the exact label and official specification for the regional P110 model you are buying. A common 220–240 V regional P110 is rated up to 16 A / 3680 W, but ratings differ by country and plug type. The smart plug's permitted load must be greater than or equal to the kettle's rated power.

Do not use a damaged plug, kettle, adapter, or overloaded extension lead. Keep the plug and connections away from water. Follow TP-Link's and the kettle manufacturer's safety instructions. If the ratings are unclear, do not connect the kettle through the smart plug.

Prepare the Tapo P110

  1. Add the P110 to the official Tapo app and update its firmware.
  2. Confirm that the app can see the plug and its energy usage.
  3. Find the plug's local IP address in your router's client list.
  4. Create a DHCP reservation for that address if your router supports it. If the IP changes later, Chainik will stop finding the plug until .env is updated.
  5. Connect the kettle through the P110 only after checking the load rating.
  6. Keep the Windows PC on the same local network.

TP-Link also publishes an official P110 setup guide.

Software requirements

  • Windows 10 or Windows 11;
  • Python 3.10 or newer;
  • Git, or a downloaded ZIP of this repository;
  • a TP-Link ID that can access the P110;
  • internet access if Telegram notifications are enabled.

The project is Windows-only because it uses Windows notifications, Task Scheduler, VBScript, pythonw.exe, and the Windows msvcrt lock API.

Quick installation from source

Open PowerShell:

git clone https://github.com/DenisGeide/Chainik.git
Set-Location Chainik

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\setup.ps1

setup.ps1 creates venv, installs the pinned dependencies, and creates local .env and config.json files from their public examples. It never overwrites existing local configuration.

Then open the private settings file:

notepad .env

Manual installation

If you prefer not to use the setup script:

py -3 -m venv venv
.\venv\Scripts\python.exe -m pip install --upgrade pip
.\venv\Scripts\python.exe -m pip install -r requirements.txt

Copy-Item .env.example .env
Copy-Item config.example.json config.json

Configure .env

The .env file contains private credentials and is excluded from Git.

TAPO_EMAIL=your_tapo_account_email@example.com
TAPO_PASSWORD=your_tapo_account_password
TAPO_IP=192.168.1.100

# Optional unless Telegram is enabled in config.json:
TG_BOT_TOKEN=
TG_CHAT_ID=
Variable Meaning Required
TAPO_EMAIL Email of the TP-Link ID that can access the plug Yes
TAPO_PASSWORD Password for that TP-Link ID Yes
TAPO_IP Reserved local IP address of the P110 Yes
TG_BOT_TOKEN Token issued by Telegram @BotFather Only for Telegram
TG_CHAT_ID Telegram chat that receives the reminder Only for Telegram

Credentials are stored as plain text on this PC. Restrict access to the project folder, never commit .env, and treat the Telegram token like a password.

Optional Telegram setup

Telegram is disabled by default; Windows notifications work without it.

  1. Follow Telegram's official bot tutorial and create a bot through @BotFather.
  2. Send any message to the new bot.
  3. Request https://api.telegram.org/bot<TOKEN>/getUpdates and copy the numeric message.chat.id value. Be aware that a token placed in a URL can remain in browser history.
  4. Put the token and chat ID in .env.
  5. Set enable_telegram_notifications to true in config.json.
  6. Restart Chainik and run test mode.

Configure detection

config.json contains non-secret, machine-specific settings. It is created from config.example.json and intentionally excluded from Git.

Setting Default Meaning
poll_interval_seconds 10 Seconds between power readings
idle_power_threshold_w 50 A lower reading is considered idle
heating_power_threshold_w 1500 A higher reading starts heating
notification_cooldown_seconds 300 Minimum time between reminders
min_heating_duration_seconds 30 Rejects short power spikes
boiled_confirm_readings 2 Low readings required to confirm stop
debug_mode false Logs every power reading when enabled
log_max_size_mb 1 Maximum size of one log file
log_backup_count 3 Number of rotated logs to keep
enable_telegram_notifications false Enables Telegram delivery
enable_windows_notifications true Enables Windows toast delivery
telegram_message ☕ Чайник вскипел Telegram reminder text
windows_notification_title Чайник вскипел Toast title
windows_notification_message Можно идти за чаем ☕ Toast body

If your kettle is below 1500 W, reduce heating_power_threshold_w. Use --once and temporary debug_mode: true to learn the real idle/heating values. Keep the idle threshold well below the heating threshold.

Restart Chainik after editing .env or config.json.

Test and run

# Validates configuration, connects to P110, reads power,
# and sends real test notifications through every enabled channel.
.\venv\Scripts\python.exe monitor.py --test

# Prints one current-power reading and exits.
.\venv\Scripts\python.exe monitor.py --once

# Runs the monitor in the PowerShell window.
.\venv\Scripts\python.exe monitor.py --monitor

# Recommended desktop mode with tray icon and settings window.
.\venv\Scripts\python.exe tray_app.py

Closing the desktop window only hides it. Use Exit in the window or tray menu to stop the application completely. A single-instance lock prevents two monitors from running at the same time.

Run hidden without autostart

Double-click run_hidden.vbs. It starts the tray application minimized and does not open a console window.

The launcher looks for:

  1. TapoKettleMonitor.exe next to run_hidden.vbs;
  2. tray_app.py plus the local venv;
  3. dist\TapoKettleMonitor.exe as a fallback.

Enable autostart

From the folder containing run_hidden.vbs:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\install_autostart.ps1

This creates or replaces a Task Scheduler task named TapoKettleMonitor for the current user. It runs run_hidden.vbs when that user signs in and starts Chainik minimized in the tray. This is not a system boot service.

You can also toggle the same task from the tray window.

To remove it:

.\uninstall_autostart.ps1

Important autostart details:

  • the task stores an absolute path to run_hidden.vbs;
  • after moving or renaming the folder, uninstall and install the task again;
  • source mode requires the folder, venv, Python, and source files to remain;
  • EXE mode requires the EXE, .env, and config.json to remain together;
  • it starts only after user sign-in;
  • the PC must stay awake during the full heating cycle;
  • Task Scheduler starts the launcher but does not supervise/restart Chainik.

Build a standalone EXE

Activate the prepared virtual environment and run:

.\venv\Scripts\Activate.ps1
.\build_exe.ps1

The result is dist\TapoKettleMonitor.exe. The build also copies the public examples, autostart scripts, license, and third-party notices into dist. Your real .env is intentionally never copied.

Configure the EXE folder before the first launch:

Set-Location dist
Copy-Item .env.example .env
Copy-Item config.example.json config.json
notepad .env
.\TapoKettleMonitor.exe

To make the EXE version start automatically, run install_autostart.ps1 from inside dist. It replaces any existing task with the same name.

Generated EXE files are excluded from the repository. Anyone distributing a binary must also comply with the licenses of bundled dependencies; see THIRD_PARTY_NOTICES.md.

Logs and troubleshooting

The rotating log is written to kettle-monitor.log and is excluded from Git. Start diagnosis with:

.\venv\Scripts\python.exe monitor.py --test
.\venv\Scripts\python.exe monitor.py --once

P110 is unreachable

  • confirm the IP in .env has not changed;
  • confirm the PC and P110 can reach each other on the local network;
  • confirm the plug is online in the Tapo app;
  • verify the TP-Link ID credentials;
  • reserve the IP in the router;
  • restart Chainik after changing .env.

Kettle is not detected

  • set debug_mode to true temporarily;
  • boil once and inspect the real readings in kettle-monitor.log;
  • lower heating_power_threshold_w for a lower-power kettle;
  • adjust idle_power_threshold_w if idle power never falls below 50 W;
  • keep idle_power_threshold_w lower than heating_power_threshold_w.

Duplicate or false reminders

  • increase boiled_confirm_readings;
  • increase min_heating_duration_seconds;
  • increase notification_cooldown_seconds;
  • check the debug log for unusual power cycling.

Windows notification is missing

  • verify enable_windows_notifications is true;
  • check Windows notification settings and Do Not Disturb/Focus Assist;
  • run monitor.py --test from PowerShell and inspect the log.

Telegram is missing

  • verify both Telegram values in .env;
  • send a message to the bot first;
  • verify enable_telegram_notifications is true;
  • remember that Telegram requires internet access;
  • run test mode and inspect the log.

Privacy and security

  • .env contains the Tapo password and optional Telegram token in plain text;
  • logs may contain local IP addresses, timestamps, and local file paths;
  • .env, config.json, logs, virtual environments, caches, lock files, and build outputs are excluded by .gitignore;
  • notification contents are sent to Telegram only when Telegram is enabled;
  • power readings are queried from the configured plug through the community tapo client;
  • the Tapo integration is unofficial and a device firmware/API change may require a library or code update.

Do not attach .env or logs to a public issue. Redact credentials, IP addresses, chat IDs, tokens, usernames, and local paths first.

Project structure

Chainik/
|-- .github/workflows/ci.yml
|-- .env.example
|-- config.example.json
|-- monitor.py
|-- tray_app.py
|-- setup.ps1
|-- run_hidden.vbs
|-- install_autostart.ps1
|-- uninstall_autostart.ps1
|-- build_exe.ps1
|-- requirements.txt
|-- requirements-build.txt
|-- tests/
|-- CONTRIBUTING.md
|-- SECURITY.md
|-- THIRD_PARTY_NOTICES.md
|-- LICENSE
`-- README.md

Development checks

The detection tests do not contact a real plug or Telegram:

.\venv\Scripts\python.exe -m compileall -q monitor.py tray_app.py tests
.\venv\Scripts\python.exe -m unittest discover -s tests -v
.\venv\Scripts\python.exe -m pip check

GitHub Actions runs the same checks on Windows for every push and pull request.

Contributions are welcome when they keep the project understandable and stay within its narrow purpose. See CONTRIBUTING.md.

License

Chainik's source code is released under the MIT License. You may use, copy, modify, publish, distribute, sublicense, provided that the MIT copyright and permission notice are retained.

Dependencies keep their own licenses. See THIRD_PARTY_NOTICES.md.

About

One-purpose Windows utility that detects when a kettle has boiled from Tapo P110 power telemetry and sends desktop or Telegram reminders.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages