Self-hosted energy consumption monitoring

I’m always curious about how much electricity my homelab devices are consuming, I have implemented a power consumption monitoring and reporting system at home without the use of any cloud services. Everything is self-hosted locally. Sharing some insights on how you too could do this at home.

Hardware & software requirements

The software stack is

  • InfluxDB v2 for time series database storage.
  • Grafana for visualization and charts of the data.
  • https://github.com/lux4rd0/kasa-collector for self-hosted local fetching of power usage metrics from the local network devices, then storing the data in influxdb.

So, is it working?… kinda

I won’t go over setup and complexity but will share some insights and lessons learned. This setup is working as expected for the individual smart plugs with energy monitoring, the smart power strip metrics are not working.

There are some caveats and issues that I think everyone trying to replicate this setup should know about TP-Link and Tapo devices. Unplug any existing TP-link/Tapo devices from your network before onboarding a new device.

  • The TP-Link Simple Setup (TSS) protocol, which shares credentials from existing devices, can break authentication with the python-kasa library which is a dependency in this stack.

How do you know TSS broke it?

Check it with the kasa discover command and look for “tss”

root@kasapi:~/python-kasa# uv run kasa --debug --username xx --password "xx" --host 192.168.66.240 discover
DEBUG:kasa.transports.klaptransport:Handshake1 posted at 2025-07-23 14:37:43.119547. Host is 192.168.66.240, Response status is 200, Request was 20708b23c4238cf0ce6da978d69f6e6e
DEBUG:kasa.transports.klaptransport:Handshake1 success at 2025-07-23 14:37:43.119597. Host is 192.168.66.240, Server remote_seed is: fff7df5db632df5ff316dd5f5734dd5e, server hash is: 06a480a245ab224d4875bc8fdcd75a68dc0ebf1a61818f5e194bcb5adc5eb3b0
DEBUG:kasa.transports.klaptransport:Device response did not match our challenge on ip 192.168.66.240, check that your e-mail and password (both case-sensitive) are correct. 
DEBUG:kasa.protocols.smartprotocol:Unable to authenticate with 192.168.66.240, not retrying: Device response did not match our challenge on ip 192.168.66.240, check that your e-mail and password (both case-sensitive) are correct. 
== Authentication failed for device ==
	== Discovery Result ==
	Device Type:        SMART.TAPOPLUG
	Device Model:       P316M(US)
	IP:                 192.168.66.240
	MAC:                REDACTED
	Device Id (hash):   REDACTED
	Owner (hash):       xx
	Supports IOT Cloud: True
	OBD Src:            tss
	Encrypt Type:       KLAP
	HTTP Port:          80
	Login version:      2

What it should look like in order for authentication to not be broken you ask?

root@kasapi:~/python-kasa/python-kasa# uv run kasa discover
== Authentication failed for device ==
        == Discovery Result ==
        Device Type:        SMART.TAPOPLUG
        Device Model:       P115(US)
        IP:                 192.168.66.179
        MAC:                REDACTED
        Device Id (hash):   REDACTED
        Owner (hash):       REDACTED
        Supports IOT Cloud: True
        OBD Src:            tplink
        Encrypt Type:       KLAP
        HTTP Port:          80
        Login version:      2


== Authentication failed for device ==
        == Discovery Result ==
        Device Type:        SMART.TAPOPLUG
        Device Model:       P316M(US)
        IP:                 192.168.66.240
        MAC:                REDACTED
        Device Id (hash):   REDACTED
        Owner (hash):       REDACTED
        Supports IOT Cloud: True
        OBD Src:            tplink
        Encrypt Type:       KLAP
        HTTP Port:          80
        Login version:      2

P316M device information when fully authenticated with proper credentials and no ‘tss’

The below is what you should expect to see:

root@kasapi:~/python-kasa/python-kasa# uv run kasa --username xyz --password xyz --host 192.168.66.240 discover
Discovering device 192.168.66.240 for 10 seconds
== None - P316M ==
Host: 192.168.66.240
Port: 80
Device state: False
Time:         2025-07-24 12:45:51-04:00 (tz: America/New_York)
Hardware:     1.6 (US)
Firmware:     1.0.5 Build 250306 Rel.151943
MAC (rssi):   REDACTED (-46)

== Primary features ==

== Information ==
Signal Level (signal_level): 3
Cloud connection (cloud_connection): True
Update available (update_available): None
Check latest firmware (check_latest_firmware): <Action>

== Configuration ==
Auto update enabled (auto_update_enabled): True
LED (led): True

== Debug ==
Device ID (device_id): x
RSSI (rssi): -46 dBm
SSID (ssid): x
Reboot (reboot): <Action>
Device time (device_time): 2025-07-24 12:45:51-04:00
Current firmware version (current_firmware_version): 1.0.5 Build 250306 Rel.151943
Available firmware version (available_firmware_version): None
Matter setup code (matter_setup_code): x
Matter setup payload (matter_setup_payload): MT:x

== Children ==

        == Smart Plug 1 (P316M) ==

        == Primary features ==
        State (state): True
        Current consumption (current_consumption): 0.0 W
        Voltage (voltage): 120.3 V
        Current (current): 0.0 A

        == Information ==
        Auto off at (auto_off_at): None
        Today's consumption (consumption_today): 0.0 kWh
        This month's consumption (consumption_this_month): 0.0 kWh
        Overloaded (overloaded): False

        == Configuration ==
        Auto off enabled (auto_off_enabled): False
        Auto off in (auto_off_minutes): 120 min (range: 0-65536)
        Unable to read value (power_protection_threshold): 'enabled'

        == Debug ==
        Device ID (device_id): x
        On since (on_since): 2025-07-23 17:42:09-04:00
        Reboot (reboot): <Action>

        == Smart Plug 2 (P316M) ==

        == Primary features ==
        State (state): True
        Current consumption (current_consumption): 0.0 W
        Voltage (voltage): 120.2 V
        Current (current): 0.0 A

        == Information ==
        Auto off at (auto_off_at): None
        Today's consumption (consumption_today): 0.0 kWh
        This month's consumption (consumption_this_month): 0.0 kWh
        Overloaded (overloaded): False

        == Configuration ==
        Auto off enabled (auto_off_enabled): False
        Auto off in (auto_off_minutes): 120 min (range: 0-65536)
        Unable to read value (power_protection_threshold): 'enabled'

        == Debug ==
        Device ID (device_id): x
        On since (on_since): 2025-07-23 17:42:09-04:00
        Reboot (reboot): <Action>

        == Smart Plug 3 (P316M) ==

        == Primary features ==
        State (state): True
        Current consumption (current_consumption): 37.5 W
        Voltage (voltage): 119.4 V
        Current (current): 0.33 A

        == Information ==
        Auto off at (auto_off_at): None
        Today's consumption (consumption_today): 0.49 kWh
        This month's consumption (consumption_this_month): 0.73 kWh
        Overloaded (overloaded): False

        == Configuration ==
        Auto off enabled (auto_off_enabled): False
        Auto off in (auto_off_minutes): 120 min (range: 0-65536)
        Unable to read value (power_protection_threshold): 'enabled'

        == Debug ==
        Device ID (device_id): x
        On since (on_since): 2025-07-23 17:42:09-04:00
        Reboot (reboot): <Action>

        == Smart Plug 4 (P316M) ==

        == Primary features ==
        State (state): True
        Current consumption (current_consumption): 62.0 W
        Voltage (voltage): 119.9 V
        Current (current): 0.54 A

        == Information ==
        Auto off at (auto_off_at): None
        Today's consumption (consumption_today): 0.618 kWh
        This month's consumption (consumption_this_month): 0.787 kWh
        Overloaded (overloaded): False

        == Configuration ==
        Auto off enabled (auto_off_enabled): False
        Auto off in (auto_off_minutes): 120 min (range: 0-65536)
        Unable to read value (power_protection_threshold): 'enabled'

        == Debug ==
        Device ID (device_id): x
        On since (on_since): 2025-07-23 17:42:09-04:00
        Reboot (reboot): <Action>

        == Smart Plug 5 (P316M) ==

        == Primary features ==
        State (state): True
        Current consumption (current_consumption): 0.0 W
        Voltage (voltage): 120.1 V
        Current (current): 0.0 A

        == Information ==
        Auto off at (auto_off_at): None
        Today's consumption (consumption_today): 0.0 kWh
        This month's consumption (consumption_this_month): 0.0 kWh
        Overloaded (overloaded): False

        == Configuration ==
        Auto off enabled (auto_off_enabled): False
        Auto off in (auto_off_minutes): 120 min (range: 0-65536)
        Unable to read value (power_protection_threshold): 'enabled'

        == Debug ==
        Device ID (device_id): x
        On since (on_since): 2025-07-23 17:42:09-04:00
        Reboot (reboot): <Action>

        == Smart Plug 6 (P316M) ==

        == Primary features ==
        State (state): True
        Current consumption (current_consumption): 0.0 W
        Voltage (voltage): 119.9 V
        Current (current): 0.0 A

        == Information ==
        Auto off at (auto_off_at): None
        Today's consumption (consumption_today): 0.0 kWh
        This month's consumption (consumption_this_month): 0.0 kWh
        Overloaded (overloaded): False

        == Configuration ==
        Auto off enabled (auto_off_enabled): False
        Auto off in (auto_off_minutes): 120 min (range: 0-65536)
        Unable to read value (power_protection_threshold): 'enabled'

        == Debug ==
        Device ID (device_id): x
        On since (on_since): 2025-07-23 17:42:09-04:00
        Reboot (reboot): <Action>


root@kasapi:~/python-kasa/python-kasa# 

Leave a Reply