mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-01-09 06:17:08 +00:00
Properly detect advertised features, expose alias
Signed-off-by: Martin Weinelt <hexa@darmstadt.ccc.de>
This commit is contained in:
parent
08fb487a06
commit
33b2800fe8
@ -15,18 +15,25 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import re
|
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# possible device features
|
||||||
|
FEATURE_ENERGY_METER = 'ENE'
|
||||||
|
FEATURE_TIMER = 'TIM'
|
||||||
|
|
||||||
|
ALL_FEATURES = (FEATURE_ENERGY_METER, FEATURE_TIMER)
|
||||||
|
|
||||||
|
|
||||||
class SmartPlug(object):
|
class SmartPlug(object):
|
||||||
"""Representation of a TP-Link Smart Switch.
|
"""Representation of a TP-Link Smart Switch.
|
||||||
|
|
||||||
Usage example when used as library:
|
Usage example when used as library:
|
||||||
p = SmartPlug("192.168.1.105")
|
p = SmartPlug("192.168.1.105")
|
||||||
|
# print the devices alias
|
||||||
|
print(p.alias)
|
||||||
# change state of plug
|
# change state of plug
|
||||||
p.state = "OFF"
|
p.state = "OFF"
|
||||||
p.state = "ON"
|
p.state = "ON"
|
||||||
@ -39,15 +46,13 @@ class SmartPlug(object):
|
|||||||
def __init__(self, ip):
|
def __init__(self, ip):
|
||||||
"""Create a new SmartPlug instance identified by the IP."""
|
"""Create a new SmartPlug instance identified by the IP."""
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
self.port = 9999
|
self.alias, self.model, self.features = self.identify()
|
||||||
self._error_report = False
|
|
||||||
self.model = self._identify_model()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self):
|
||||||
"""Get the device state (i.e. ON or OFF)."""
|
"""Get the device state (i.e. ON or OFF)."""
|
||||||
response = self.get_info()
|
response = self.get_sysinfo()
|
||||||
relay_state = response["system"]["get_sysinfo"]["relay_state"]
|
relay_state = response['relay_state']
|
||||||
|
|
||||||
if relay_state is None:
|
if relay_state is None:
|
||||||
return 'unknown'
|
return 'unknown'
|
||||||
@ -74,10 +79,11 @@ class SmartPlug(object):
|
|||||||
else:
|
else:
|
||||||
raise TypeError("State %s is not valid." % str(value))
|
raise TypeError("State %s is not valid." % str(value))
|
||||||
|
|
||||||
def get_info(self):
|
def get_sysinfo(self):
|
||||||
"""Interrogate the switch"""
|
"""Interrogate the switch"""
|
||||||
return TPLinkSmartHomeProtocol.query(
|
return TPLinkSmartHomeProtocol.query(
|
||||||
host=self.ip, request='{"system":{"get_sysinfo":{}}}')
|
host=self.ip, request='{"system":{"get_sysinfo":{}}}'
|
||||||
|
)['system']['get_sysinfo']
|
||||||
|
|
||||||
def turn_on(self):
|
def turn_on(self):
|
||||||
"""Turns the switch on
|
"""Turns the switch on
|
||||||
@ -109,6 +115,10 @@ class SmartPlug(object):
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def has_emeter(self):
|
||||||
|
return FEATURE_ENERGY_METER in self.features
|
||||||
|
|
||||||
def get_emeter_realtime(self):
|
def get_emeter_realtime(self):
|
||||||
"""Gets the current energy readings from the switch
|
"""Gets the current energy readings from the switch
|
||||||
|
|
||||||
@ -116,7 +126,7 @@ class SmartPlug(object):
|
|||||||
False if command is not successful or the switch doesn't support energy metering
|
False if command is not successful or the switch doesn't support energy metering
|
||||||
Dict with the current readings
|
Dict with the current readings
|
||||||
"""
|
"""
|
||||||
if self.model != 110:
|
if not self.has_emeter:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
response = TPLinkSmartHomeProtocol.query(
|
response = TPLinkSmartHomeProtocol.query(
|
||||||
@ -139,7 +149,7 @@ class SmartPlug(object):
|
|||||||
False if command is not successful or the switch doesn't support energy metering
|
False if command is not successful or the switch doesn't support energy metering
|
||||||
Dict where the keys represent the days, and the values are the aggregated statistics
|
Dict where the keys represent the days, and the values are the aggregated statistics
|
||||||
"""
|
"""
|
||||||
if self.model != 110:
|
if not self.has_emeter:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
response = TPLinkSmartHomeProtocol.query(
|
response = TPLinkSmartHomeProtocol.query(
|
||||||
@ -166,7 +176,7 @@ class SmartPlug(object):
|
|||||||
False if command is not successful or the switch doesn't support energy metering
|
False if command is not successful or the switch doesn't support energy metering
|
||||||
Dict - the keys represent the months, the values are the aggregated statistics
|
Dict - the keys represent the months, the values are the aggregated statistics
|
||||||
"""
|
"""
|
||||||
if self.model != 110:
|
if not self.has_emeter:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
response = TPLinkSmartHomeProtocol.query(
|
response = TPLinkSmartHomeProtocol.query(
|
||||||
@ -190,7 +200,7 @@ class SmartPlug(object):
|
|||||||
True: Success
|
True: Success
|
||||||
False: Failure or not supported by switch
|
False: Failure or not supported by switch
|
||||||
"""
|
"""
|
||||||
if self.model != 110:
|
if not self.has_emeter:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
response = TPLinkSmartHomeProtocol.query(
|
response = TPLinkSmartHomeProtocol.query(
|
||||||
@ -203,18 +213,30 @@ class SmartPlug(object):
|
|||||||
|
|
||||||
def current_consumption(self):
|
def current_consumption(self):
|
||||||
"""Get the current power consumption in Watt."""
|
"""Get the current power consumption in Watt."""
|
||||||
if self.model != 110:
|
if not self.has_emeter:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
response = self.get_emeter_realtime()
|
response = self.get_emeter_realtime()
|
||||||
|
|
||||||
return response["power"]
|
return response["power"]
|
||||||
|
|
||||||
def _identify_model(self):
|
def identify(self):
|
||||||
"""Query sysinfo and determine model"""
|
"""
|
||||||
sys_info = self.get_info()
|
Query device information to identify model and featureset
|
||||||
model = re.sub('HS', '', sys_info["system"]["get_sysinfo"]["model"][:5])
|
|
||||||
return model
|
:return: str model, list of supported features
|
||||||
|
"""
|
||||||
|
sys_info = self.get_sysinfo()
|
||||||
|
|
||||||
|
alias = sys_info['alias']
|
||||||
|
model = sys_info["model"]
|
||||||
|
features = sys_info['feature'].split(':')
|
||||||
|
|
||||||
|
for feature in features:
|
||||||
|
if feature not in ALL_FEATURES:
|
||||||
|
_LOGGER.warn('Unknown feature %s on device %s.', feature, model)
|
||||||
|
|
||||||
|
return alias, model, features
|
||||||
|
|
||||||
|
|
||||||
class TPLinkSmartHomeProtocol:
|
class TPLinkSmartHomeProtocol:
|
||||||
|
Loading…
Reference in New Issue
Block a user