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.
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.
- 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.
- 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.
The default state machine is deliberately simple:
IDLE— the kettle is not drawing heating power.- A reading above
1500 Wchanges the state toHEATING. - Heating must last for at least
30 seconds. - Two consecutive readings below
50 Wconfirm the end of heating. - Chainik sends the enabled notifications and returns to
IDLE. - A
5 minutecooldown 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)
- 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.
- An ordinary electric kettle with a normal mechanical or electronic automatic shutoff.
- A Windows PC that stays on and awake while the kettle is heating.
- 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.
- A smartphone with the official Tapo app for the initial plug setup.
No separate Tapo Hub is required for the P110.
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.
- Add the P110 to the official Tapo app and update its firmware.
- Confirm that the app can see the plug and its energy usage.
- Find the plug's local IP address in your router's client list.
- Create a DHCP reservation for that address if your router supports it. If
the IP changes later, Chainik will stop finding the plug until
.envis updated. - Connect the kettle through the P110 only after checking the load rating.
- Keep the Windows PC on the same local network.
TP-Link also publishes an official P110 setup guide.
- 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.
Open PowerShell:
git clone https://github.com/DenisGeide/Chainik.git
Set-Location Chainik
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\setup.ps1setup.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 .envIf 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.jsonThe .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.
Telegram is disabled by default; Windows notifications work without it.
- Follow Telegram's official bot tutorial
and create a bot through
@BotFather. - Send any message to the new bot.
- Request
https://api.telegram.org/bot<TOKEN>/getUpdatesand copy the numericmessage.chat.idvalue. Be aware that a token placed in a URL can remain in browser history. - Put the token and chat ID in
.env. - Set
enable_telegram_notificationstotrueinconfig.json. - Restart Chainik and run test mode.
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.
# 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.pyClosing 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:
TapoKettleMonitor.exenext torun_hidden.vbs;tray_app.pyplus the localvenv;dist\TapoKettleMonitor.exeas a fallback.
From the folder containing run_hidden.vbs:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\install_autostart.ps1This 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.ps1Important 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, andconfig.jsonto 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.
Activate the prepared virtual environment and run:
.\venv\Scripts\Activate.ps1
.\build_exe.ps1The 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.exeTo 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.
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- confirm the IP in
.envhas 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.
- set
debug_modetotruetemporarily; - boil once and inspect the real readings in
kettle-monitor.log; - lower
heating_power_threshold_wfor a lower-power kettle; - adjust
idle_power_threshold_wif idle power never falls below 50 W; - keep
idle_power_threshold_wlower thanheating_power_threshold_w.
- increase
boiled_confirm_readings; - increase
min_heating_duration_seconds; - increase
notification_cooldown_seconds; - check the debug log for unusual power cycling.
- verify
enable_windows_notificationsistrue; - check Windows notification settings and Do Not Disturb/Focus Assist;
- run
monitor.py --testfrom PowerShell and inspect the log.
- verify both Telegram values in
.env; - send a message to the bot first;
- verify
enable_telegram_notificationsistrue; - remember that Telegram requires internet access;
- run test mode and inspect the log.
.envcontains 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
tapoclient; - 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.
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
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 checkGitHub 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.
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.