mirror of
https://github.com/python-kasa/python-kasa.git
synced 2024-12-22 19:23:34 +00:00
Add support for DNS host names (#104)
This commit is contained in:
parent
a426488449
commit
d40fff4f9e
@ -23,7 +23,7 @@ Python Library to control TPLink smart plugs/switches and smart bulbs.
|
|||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
The package is shipped with a console tool named pyhs100, please refer to ```pyhs100 --help``` for detailed usage.
|
The package is shipped with a console tool named pyhs100, please refer to ```pyhs100 --help``` for detailed usage.
|
||||||
The device to which the commands are sent is chosen by `PYHS100_IP` environment variable or passing `--ip <address>` as an option.
|
The device to which the commands are sent is chosen by `PYHS100_HOST` environment variable or passing `--host <address>` as an option.
|
||||||
To see what is being sent to and received from the device, specify option `--debug`.
|
To see what is being sent to and received from the device, specify option `--debug`.
|
||||||
|
|
||||||
To avoid discovering the devices when executing commands its type can be passed by specifying either `--plug` or `--bulb`,
|
To avoid discovering the devices when executing commands its type can be passed by specifying either `--plug` or `--bulb`,
|
||||||
|
@ -18,12 +18,17 @@ pass_dev = click.make_pass_decorator(SmartDevice)
|
|||||||
|
|
||||||
|
|
||||||
@click.group(invoke_without_command=True)
|
@click.group(invoke_without_command=True)
|
||||||
@click.option('--ip', envvar="PYHS100_IP", required=False)
|
@click.option('--ip', envvar="PYHS100_IP", required=False,
|
||||||
|
help='The IP address of the device to connect to. This option '
|
||||||
|
'is deprecated and will be removed in the future; use --host '
|
||||||
|
'instead.')
|
||||||
|
@click.option('--host', envvar="PYHS100_HOST", required=False,
|
||||||
|
help='The host name or IP address of the device to connect to.')
|
||||||
@click.option('--debug/--normal', default=False)
|
@click.option('--debug/--normal', default=False)
|
||||||
@click.option('--bulb', default=False, is_flag=True)
|
@click.option('--bulb', default=False, is_flag=True)
|
||||||
@click.option('--plug', default=False, is_flag=True)
|
@click.option('--plug', default=False, is_flag=True)
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
def cli(ctx, ip, debug, bulb, plug):
|
def cli(ctx, ip, host, debug, bulb, plug):
|
||||||
"""A cli tool for controlling TP-Link smart home plugs."""
|
"""A cli tool for controlling TP-Link smart home plugs."""
|
||||||
if debug:
|
if debug:
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
@ -33,19 +38,22 @@ def cli(ctx, ip, debug, bulb, plug):
|
|||||||
if ctx.invoked_subcommand == "discover":
|
if ctx.invoked_subcommand == "discover":
|
||||||
return
|
return
|
||||||
|
|
||||||
if ip is None:
|
if ip is not None and host is None:
|
||||||
click.echo("No IP given, trying discovery..")
|
host = ip
|
||||||
|
|
||||||
|
if host is None:
|
||||||
|
click.echo("No host name given, trying discovery..")
|
||||||
ctx.invoke(discover)
|
ctx.invoke(discover)
|
||||||
return
|
return
|
||||||
|
|
||||||
elif ip is not None:
|
else:
|
||||||
if not bulb and not plug:
|
if not bulb and not plug:
|
||||||
click.echo("No --bulb nor --plug given, discovering..")
|
click.echo("No --bulb nor --plug given, discovering..")
|
||||||
dev = Discover.discover_single(ip)
|
dev = Discover.discover_single(host)
|
||||||
elif bulb:
|
elif bulb:
|
||||||
dev = SmartBulb(ip)
|
dev = SmartBulb(host)
|
||||||
elif plug:
|
elif plug:
|
||||||
dev = SmartPlug(ip)
|
dev = SmartPlug(host)
|
||||||
else:
|
else:
|
||||||
click.echo("Unable to detect type, use --bulb or --plug!")
|
click.echo("Unable to detect type, use --bulb or --plug!")
|
||||||
return
|
return
|
||||||
@ -90,7 +98,7 @@ def state(ctx, dev):
|
|||||||
|
|
||||||
click.echo(click.style("Device state: %s" % "ON" if dev.is_on else "OFF",
|
click.echo(click.style("Device state: %s" % "ON" if dev.is_on else "OFF",
|
||||||
fg="green" if dev.is_on else "red"))
|
fg="green" if dev.is_on else "red"))
|
||||||
click.echo("IP address: %s" % dev.ip_address)
|
click.echo("Host/IP: %s" % dev.host)
|
||||||
for k, v in dev.state_information.items():
|
for k, v in dev.state_information.items():
|
||||||
click.echo("%s: %s" % (k, v))
|
click.echo("%s: %s" % (k, v))
|
||||||
click.echo(click.style("== Generic information ==", bold=True))
|
click.echo(click.style("== Generic information ==", bold=True))
|
||||||
|
@ -61,14 +61,14 @@ class Discover:
|
|||||||
return devices
|
return devices
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def discover_single(ip_address: str,
|
def discover_single(host: str,
|
||||||
protocol: TPLinkSmartHomeProtocol = None
|
protocol: TPLinkSmartHomeProtocol = None
|
||||||
) -> SmartDevice:
|
) -> SmartDevice:
|
||||||
"""
|
"""
|
||||||
Similar to discover(), except only return device object for single
|
Similar to discover(), except only return device object for a single
|
||||||
passed device given by IP address.
|
host.
|
||||||
|
|
||||||
:param ip_address: IP address of device to query
|
:param host: Hostname of device to query
|
||||||
:param protocol: Protocol implementation to use
|
:param protocol: Protocol implementation to use
|
||||||
:rtype: SmartDevice
|
:rtype: SmartDevice
|
||||||
:return: Object for querying/controlling found device.
|
:return: Object for querying/controlling found device.
|
||||||
@ -76,11 +76,11 @@ class Discover:
|
|||||||
if protocol is None:
|
if protocol is None:
|
||||||
protocol = TPLinkSmartHomeProtocol()
|
protocol = TPLinkSmartHomeProtocol()
|
||||||
|
|
||||||
info = protocol.query(ip_address, Discover.DISCOVERY_QUERY)
|
info = protocol.query(host, Discover.DISCOVERY_QUERY)
|
||||||
|
|
||||||
device_class = Discover._get_device_class(info)
|
device_class = Discover._get_device_class(info)
|
||||||
if device_class is not None:
|
if device_class is not None:
|
||||||
return device_class(ip_address)
|
return device_class(host)
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ class TPLinkSmartHomeProtocol:
|
|||||||
Request information from a TP-Link SmartHome Device and return the
|
Request information from a TP-Link SmartHome Device and return the
|
||||||
response.
|
response.
|
||||||
|
|
||||||
:param str host: ip address of the device
|
:param str host: host name or ip address of the device
|
||||||
:param int port: port on the device (default: 9999)
|
:param int port: port on the device (default: 9999)
|
||||||
:param request: command to send to the device (can be either dict or
|
:param request: command to send to the device (can be either dict or
|
||||||
json string)
|
json string)
|
||||||
@ -41,10 +41,9 @@ class TPLinkSmartHomeProtocol:
|
|||||||
if isinstance(request, dict):
|
if isinstance(request, dict):
|
||||||
request = json.dumps(request)
|
request = json.dumps(request)
|
||||||
|
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
timeout = TPLinkSmartHomeProtocol.DEFAULT_TIMEOUT
|
||||||
sock.settimeout(TPLinkSmartHomeProtocol.DEFAULT_TIMEOUT)
|
|
||||||
try:
|
try:
|
||||||
sock.connect((host, port))
|
sock = socket.create_connection((host, port), timeout)
|
||||||
|
|
||||||
_LOGGER.debug("> (%i) %s", len(request), request)
|
_LOGGER.debug("> (%i) %s", len(request), request)
|
||||||
sock.send(TPLinkSmartHomeProtocol.encrypt(request))
|
sock.send(TPLinkSmartHomeProtocol.encrypt(request))
|
||||||
|
@ -42,9 +42,9 @@ class SmartBulb(SmartDevice):
|
|||||||
BULB_STATE_OFF = 'OFF'
|
BULB_STATE_OFF = 'OFF'
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
ip_address: str,
|
host: str,
|
||||||
protocol: 'TPLinkSmartHomeProtocol' = None) -> None:
|
protocol: 'TPLinkSmartHomeProtocol' = None) -> None:
|
||||||
SmartDevice.__init__(self, ip_address, protocol)
|
SmartDevice.__init__(self, host, protocol)
|
||||||
self.emeter_type = "smartlife.iot.common.emeter"
|
self.emeter_type = "smartlife.iot.common.emeter"
|
||||||
self.emeter_units = True
|
self.emeter_units = True
|
||||||
|
|
||||||
|
@ -40,15 +40,14 @@ class SmartDevice(object):
|
|||||||
ALL_FEATURES = (FEATURE_ENERGY_METER, FEATURE_TIMER)
|
ALL_FEATURES = (FEATURE_ENERGY_METER, FEATURE_TIMER)
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
ip_address: str,
|
host: str,
|
||||||
protocol: Optional[TPLinkSmartHomeProtocol] = None) -> None:
|
protocol: Optional[TPLinkSmartHomeProtocol] = None) -> None:
|
||||||
"""
|
"""
|
||||||
Create a new SmartDevice instance, identified through its IP address.
|
Create a new SmartDevice instance.
|
||||||
|
|
||||||
:param str ip_address: ip address on which the device listens
|
:param str host: host name or ip address on which the device listens
|
||||||
"""
|
"""
|
||||||
socket.inet_pton(socket.AF_INET, ip_address)
|
self.host = host
|
||||||
self.ip_address = ip_address
|
|
||||||
if not protocol:
|
if not protocol:
|
||||||
protocol = TPLinkSmartHomeProtocol()
|
protocol = TPLinkSmartHomeProtocol()
|
||||||
self.protocol = protocol
|
self.protocol = protocol
|
||||||
@ -73,7 +72,7 @@ class SmartDevice(object):
|
|||||||
arg = {}
|
arg = {}
|
||||||
try:
|
try:
|
||||||
response = self.protocol.query(
|
response = self.protocol.query(
|
||||||
host=self.ip_address,
|
host=self.host,
|
||||||
request={target: {cmd: arg}}
|
request={target: {cmd: arg}}
|
||||||
)
|
)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
@ -523,7 +522,7 @@ class SmartDevice(object):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<%s at %s (%s), is_on: %s - dev specific: %s>" % (
|
return "<%s at %s (%s), is_on: %s - dev specific: %s>" % (
|
||||||
self.__class__.__name__,
|
self.__class__.__name__,
|
||||||
self.ip_address,
|
self.host,
|
||||||
self.alias,
|
self.alias,
|
||||||
self.is_on,
|
self.is_on,
|
||||||
self.state_information)
|
self.state_information)
|
||||||
|
@ -32,9 +32,9 @@ class SmartPlug(SmartDevice):
|
|||||||
SWITCH_STATE_UNKNOWN = 'UNKNOWN'
|
SWITCH_STATE_UNKNOWN = 'UNKNOWN'
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
ip_address: str,
|
host: str,
|
||||||
protocol: 'TPLinkSmartHomeProtocol' = None) -> None:
|
protocol: 'TPLinkSmartHomeProtocol' = None) -> None:
|
||||||
SmartDevice.__init__(self, ip_address, protocol)
|
SmartDevice.__init__(self, host, protocol)
|
||||||
self.emeter_type = "emeter"
|
self.emeter_type = "emeter"
|
||||||
self.emeter_units = False
|
self.emeter_units = False
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user