Common API¶
Contents
SmartDevice class¶
The basic functionalities of all supported devices are accessible using the common SmartDevice
base class.
The property accesses use the data obtained before by awaiting SmartDevice.update()
.
The values are cached until the next update call. In practice this means that property accesses do no I/O and are dependent, while I/O producing methods need to be awaited.
See Library Design & Modules for more detailed information.
Note
The device instances share the communication socket in background to optimize I/O accesses. This means that you need to use the same event loop for subsequent requests. The library gives a warning (“Detected protocol reuse between different event loop”) to hint if you are accessing the device incorrectly.
Methods changing the state of the device do not invalidate the cache (i.e., there is no implicit SmartDevice.update()
call made by the library).
You can assume that the operation has succeeded if no exception is raised.
These methods will return the device response, which can be useful for some use cases.
Errors are raised as SmartDeviceException
instances for the library user to handle.
Simple example script showing some functionality:
import asyncio
from kasa import SmartPlug
async def main():
p = SmartPlug("127.0.0.1")
await p.update() # Request the update
print(p.alias) # Print out the alias
print(p.emeter_realtime) # Print out current emeter status
await p.turn_off() # Turn the device off
if __name__ == "__main__":
asyncio.run(main())
If you want to perform updates in a loop, you need to make sure that the device accesses are done in the same event loop:
import asyncio
from kasa import SmartPlug
async def main():
dev = SmartPlug("127.0.0.1") # We create the instance inside the main loop
while True:
await dev.update() # Request an update
print(dev.emeter_realtime)
await asyncio.sleep(0.5) # Sleep some time between updates
if __name__ == "__main__":
asyncio.run(main())
Refer to device type specific classes for more examples:
SmartPlug
, SmartBulb
, SmartStrip
,
SmartDimmer
, SmartLightStrip
.
Energy Consumption and Usage Statistics¶
Note
In order to use the helper methods to calculate the statistics correctly, your devices need to have correct time set. The devices use NTP and public servers from NTP Pool Project to synchronize their time.
Energy Consumption¶
The availability of energy consumption sensors depend on the device.
While most of the bulbs support it, only specific switches (e.g., HS110) or strips (e.g., HS300) support it.
You can use has_emeter
to check for the availability.
Usage statistics¶
You can use on_since
to query for the time the device has been turned on.
Some devices also support reporting the usage statistics on daily or monthly basis.
You can access this information using through the usage module (kasa.modules.Usage
):
dev = SmartPlug("127.0.0.1")
usage = dev.modules["usage"]
print(f"Minutes on this month: {usage.usage_this_month}")
print(f"Minutes on today: {usage.usage_today}")
API documentation¶
- class kasa.SmartDevice(host: str)[source]¶
Base class for all supported device types.
You don’t usually want to construct this class which implements the shared common interfaces. The recommended way is to either use the discovery functionality, or construct one of the subclasses:
To initialize, you have to await
update()
at least once. This will allow accessing the properties using the exposed properties.All changes to the device are done using awaitable methods, which will not change the cached values, but you must await update() separately.
Errors reported by the device are raised as SmartDeviceExceptions, and should be handled by the user of the library.
- Examples:
>>> import asyncio >>> dev = SmartDevice("127.0.0.1") >>> asyncio.run(dev.update())
All devices provide several informational properties:
>>> dev.alias Kitchen >>> dev.model HS110(EU) >>> dev.rssi -71 >>> dev.mac 50:C7:BF:01:F8:CD
Some information can also be changed programmatically:
>>> asyncio.run(dev.set_alias("new alias")) >>> asyncio.run(dev.set_mac("01:23:45:67:89:ab")) >>> asyncio.run(dev.update()) >>> dev.alias new alias >>> dev.mac 01:23:45:67:89:ab
When initialized using discovery or using a subclass, you can check the type of the device:
>>> dev.is_bulb False >>> dev.is_strip False >>> dev.is_plug True
You can also get the hardware and software as a dict, or access the full device response:
>>> dev.hw_info {'sw_ver': '1.2.5 Build 171213 Rel.101523', 'hw_ver': '1.0', 'mac': '01:23:45:67:89:ab', 'type': 'IOT.SMARTPLUGSWITCH', 'hwId': '45E29DA8382494D2E82688B52A0B2EB5', 'fwId': '00000000000000000000000000000000', 'oemId': '3D341ECE302C0642C99E31CE2430544B', 'dev_name': 'Wi-Fi Smart Plug With Energy Monitoring'} >>> dev.sys_info
All devices can be turned on and off:
>>> asyncio.run(dev.turn_off()) >>> asyncio.run(dev.turn_on()) >>> asyncio.run(dev.update()) >>> dev.is_on True
Some devices provide energy consumption meter, and regular update will already fetch some information:
>>> dev.has_emeter True >>> dev.emeter_realtime <EmeterStatus power=0.983971 voltage=235.595234 current=0.015342 total=32.448> >>> dev.emeter_today >>> dev.emeter_this_month
You can also query the historical data (note that these needs to be awaited), keyed with month/day:
>>> asyncio.run(dev.get_emeter_monthly(year=2016)) {11: 1.089, 12: 1.582} >>> asyncio.run(dev.get_emeter_daily(year=2016, month=11)) {24: 0.026, 25: 0.109}
- property alias: str¶
Return device name (alias).
- property device_id: str¶
Return unique ID for the device.
If not overridden, this is the MAC address of the device. Individual sockets on strips will override this.
- property device_type: kasa.smartdevice.DeviceType¶
Return the device type.
- property emeter_realtime: kasa.emeterstatus.EmeterStatus¶
Return current energy readings.
- property emeter_this_month: Optional[float]¶
Return this month’s energy consumption in kWh.
- property emeter_today: Optional[float]¶
Return today’s energy consumption in kWh.
- emeter_type = 'emeter'¶
- property features: Set[str]¶
Return a set of features that the device supports.
- async get_emeter_daily(year: Optional[int] = None, month: Optional[int] = None, kwh: bool = True) Dict [source]¶
Retrieve daily statistics for a given month.
- Parameters
year – year for which to retrieve statistics (default: this year)
month – month for which to retrieve statistics (default: this month)
kwh – return usage in kWh (default: True)
- Returns
mapping of day of month to value
- async get_emeter_monthly(year: Optional[int] = None, kwh: bool = True) Dict [source]¶
Retrieve monthly statistics for a given year.
- Parameters
year – year for which to retrieve statistics (default: this year)
kwh – return usage in kWh (default: True)
- Returns
dict: mapping of month to value
- async get_emeter_realtime() kasa.emeterstatus.EmeterStatus [source]¶
Retrieve current energy readings.
- get_plug_by_index(index: int) kasa.smartdevice.SmartDevice [source]¶
Return child device for the given index.
- get_plug_by_name(name: str) kasa.smartdevice.SmartDevice [source]¶
Return child device for the given name.
- async get_time() Optional[datetime.datetime] [source]¶
Return current time from the device, if available.
- property has_emeter: bool¶
Return True if device has an energy meter.
- property hw_info: Dict¶
Return hardware information.
This returns just a selection of sysinfo keys that are related to hardware.
- property internal_state: Any¶
Return the internal state of the instance.
The returned object contains the raw results from the last update call. This should only be used for debugging purposes.
- property is_bulb: bool¶
Return True if the device is a bulb.
- property is_color: bool¶
Return True if the device supports color changes.
- property is_dimmable: bool¶
Return True if the device is dimmable.
- property is_dimmer: bool¶
Return True if the device is a dimmer.
- property is_light_strip: bool¶
Return True if the device is a led strip.
- property is_off: bool¶
Return True if device is off.
- property is_on: bool¶
Return True if the device is on.
- property is_plug: bool¶
Return True if the device is a plug.
- property is_strip: bool¶
Return True if the device is a strip.
- property is_strip_socket: bool¶
Return True if the device is a strip socket.
- property is_variable_color_temp: bool¶
Return True if the device supports color temperature.
- property location: Dict¶
Return geographical location.
- property mac: str¶
Return mac address.
- Returns
mac address in hexadecimal with colons, e.g. 01:23:45:67:89:ab
- property model: str¶
Return device model.
- property on_since: Optional[datetime.datetime]¶
Return pretty-printed on-time, or None if not available.
- async reboot(delay: int = 1) None [source]¶
Reboot the device.
Note that giving a delay of zero causes this to block, as the device reboots immediately without responding to the call.
- property rssi: Optional[int]¶
Return WiFi signal strength (rssi).
- async set_mac(mac)[source]¶
Set the mac address.
- Parameters
mac (str) – mac in hexadecimal with colons, e.g. 01:23:45:67:89:ab
- property state_information: Dict[str, Any]¶
Return device-type specific, end-user friendly state information.
- property supported_modules: List[str]¶
Return a set of modules supported by the device.
- property sys_info: Dict[str, Any]¶
Return system information.
- property time: datetime.datetime¶
Return current time from the device.
- property timezone: Dict¶
Return the current timezone.
- async update(update_children: bool = True)[source]¶
Query the device to update the data.
Needed for properties that are decorated with requires_update.