Skip to content

Commit

Permalink
WIP: Improve psk handling (#118)
Browse files Browse the repository at this point in the history
* Add json store and load functionality
* Add tradfri_standalone_psk.conf to gitignore
* Improve key handling using randing identifies in example files
  • Loading branch information
Patrik authored Nov 26, 2017
1 parent a076775 commit 8902f2e
Show file tree
Hide file tree
Showing 8 changed files with 240 additions and 58 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ dist/
.tox

gateway_psk.txt
tradfri_standalone_psk.conf

# Emacs backup files
*~
*~
55 changes: 41 additions & 14 deletions example_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,31 @@
"""

import asyncio
import logging
import sys

from pytradfri import Gateway
from pytradfri.api.aiocoap_api import APIFactory
from pytradfri.error import PytradfriError
from pytradfri.util import load_json, save_json

from pathlib import Path
import uuid
import argparse

CONFIG_FILE = 'tradfri_standalone_psk.conf'


parser = argparse.ArgumentParser()
parser.add_argument('-H', '--hostname', dest='host', required=True,
help='IP Address of your Tradfri gateway')
parser.add_argument('-K', '--key', dest='key', required=False,
help='Key found on your Tradfri gateway')
args = parser.parse_args()


if Path(CONFIG_FILE).is_file() is False and args.key is None:
raise PytradfriError("Please provide they key found on your "
"Tradfri gateway using the -K flag to this script.")

root = logging.getLogger()
root.setLevel(logging.INFO)

try:
# pylint: disable=ungrouped-imports
Expand All @@ -35,16 +52,26 @@
def run():
# Assign configuration variables.
# The configuration check takes care they are present.
api_factory = APIFactory(sys.argv[1])
with open('gateway_psk.txt', 'a+') as file:
file.seek(0)
psk = file.read()
if psk:
api_factory.psk = psk.strip()
else:
psk = yield from api_factory.generate_psk(sys.argv[2])
conf = load_json(CONFIG_FILE)

try:
identity = conf[args.host].get('identity')
psk = conf[args.host].get('key')
api_factory = APIFactory(host=args.host, psk_id=identity, psk=psk)
except KeyError:
identity = uuid.uuid4().hex
api_factory = APIFactory(host=args.host, psk_id=identity)

try:
psk = yield from api_factory.generate_psk(args.key)
print('Generated PSK: ', psk)
file.write(psk)

conf[args.host] = {'identity': identity,
'key': psk}
save_json(CONFIG_FILE, conf)
except AttributeError:
raise PytradfriError("Please provide your Key")

api = api_factory.request

gateway = Gateway()
Expand Down Expand Up @@ -86,7 +113,7 @@ def observe_err_callback(err):
print("Name:", light.name)

# Example 4: Set the light level of the light
dim_command = light.light_control.set_dimmer(255)
dim_command = light.light_control.set_dimmer(254)
yield from api(dim_command)

# Example 5: Change color of the light
Expand Down
76 changes: 61 additions & 15 deletions example_color.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,78 @@
Hex (for some colors)
"""

import sys
import asyncio

from pytradfri import Gateway
from pytradfri.api.libcoap_api import APIFactory
from pytradfri.api.aiocoap_api import APIFactory
from pytradfri.error import PytradfriError
from pytradfri.util import load_json, save_json

from colormath.color_conversions import convert_color
from colormath.color_objects import sRGBColor, XYZColor

from pathlib import Path
import uuid
import argparse

CONFIG_FILE = 'tradfri_standalone_psk.conf'


parser = argparse.ArgumentParser()
parser.add_argument('-H', '--hostname', dest='host', required=True,
help='IP Address of your Tradfri gateway')
parser.add_argument('-K', '--key', dest='key', required=False,
help='Key found on your Tradfri gateway')
args = parser.parse_args()


if Path(CONFIG_FILE).is_file() is False and args.key is None:
raise PytradfriError("Please provide they key found on your "
"Tradfri gateway using the -K flag to this script.")


try:
# pylint: disable=ungrouped-imports
from asyncio import ensure_future
except ImportError:
# Python 3.4.3 and earlier has this as async
# pylint: disable=unused-import
from asyncio import async
ensure_future = async


@asyncio.coroutine
def run():
# Assign configuration variables.
# The configuration check takes care they are present.
api_factory = APIFactory(sys.argv[1])
with open('gateway_psk.txt', 'a+') as file:
file.seek(0)
psk = file.read()
if psk:
api_factory.psk = psk.strip()
else:
psk = api_factory.generate_psk(sys.argv[2])
conf = load_json(CONFIG_FILE)

try:
identity = conf[args.host].get('identity')
psk = conf[args.host].get('key')
api_factory = APIFactory(host=args.host, psk_id=identity, psk=psk)
except KeyError:
identity = uuid.uuid4().hex
api_factory = APIFactory(host=args.host, psk_id=identity)

try:
psk = yield from api_factory.generate_psk(args.key)
print('Generated PSK: ', psk)
file.write(psk)

conf[args.host] = {'identity': identity,
'key': psk}
save_json(CONFIG_FILE, conf)
except AttributeError:
raise PytradfriError("Please provide your Key")

api = api_factory.request

gateway = Gateway()

devices_command = gateway.get_devices()
devices_commands = api(devices_command)
devices = api(devices_commands)
devices_commands = yield from api(devices_command)
devices = yield from api(devices_commands)

lights = [dev for dev in devices if dev.has_light_control]

rgb = (0, 0, 102)
Expand All @@ -58,7 +101,8 @@ def run():
xy = int(xyz.xyz_x), int(xyz.xyz_y)

# Assuming lights[3] is a RGB bulb
api(lights[3].light_control.set_xy_color(xy[0], xy[1]))
xy_command = lights[3].light_control.set_xy_color(xy[0], xy[1])
yield from api(xy_command)

# Assuming lights[3] is a RGB bulb
xy = lights[3].light_control.lights[0].xy_color
Expand All @@ -71,5 +115,7 @@ def run():
rgb = (int(rgb.rgb_r), int(rgb.rgb_g), int(rgb.rgb_b))
print(rgb)

yield from asyncio.sleep(120)


run()
asyncio.get_event_loop().run_until_complete(run())
51 changes: 39 additions & 12 deletions example_pair.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,60 @@

import asyncio
import logging
import sys

from pytradfri import Gateway
from pytradfri.command import Command
from pytradfri.const import ROOT_DEVICES
from pytradfri.api.aiocoap_api import APIFactory
from pytradfri.error import PytradfriError
from pytradfri.util import load_json, save_json

from pathlib import Path
import uuid
import argparse

logging.basicConfig(level=logging.INFO)

CONFIG_FILE = 'tradfri_standalone_psk.conf'


parser = argparse.ArgumentParser()
parser.add_argument('-H', '--hostname', dest='host', required=True,
help='IP Address of your Tradfri gateway')
parser.add_argument('-K', '--key', dest='key', required=False,
help='Key found on your Tradfri gateway')
args = parser.parse_args()


if Path(CONFIG_FILE).is_file() is False and args.key is None:
raise PytradfriError("Please provide they key found on your "
"Tradfri gateway using the -K flag to this script.")


@asyncio.coroutine
def run(shutdown):
# initialization is copy/pasted from example_async.py

# Assign configuration variables.
# The configuration check takes care they are present.
api_factory = APIFactory(sys.argv[1])
with open('gateway_psk.txt', 'a+') as file:
file.seek(0)
psk = file.read()
if psk:
api_factory.psk = psk.strip()
else:
psk = yield from api_factory.generate_psk(sys.argv[2])
conf = load_json(CONFIG_FILE)

try:
identity = conf[args.host].get('identity')
psk = conf[args.host].get('key')
api_factory = APIFactory(host=args.host, psk_id=identity, psk=psk)
except KeyError:
identity = uuid.uuid4().hex
api_factory = APIFactory(host=args.host, psk_id=identity)

try:
psk = yield from api_factory.generate_psk(args.key)
print('Generated PSK: ', psk)
file.write(psk)

conf[args.host] = {'identity': identity,
'key': psk}
save_json(CONFIG_FILE, conf)
except AttributeError:
raise PytradfriError("Please provide your Key")

api = api_factory.request

gateway = Gateway()
Expand Down
53 changes: 42 additions & 11 deletions example_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,33 @@
<KEY> is found on the back of your IKEA gateway.
"""

import sys
import threading

import time

from pytradfri import Gateway
from pytradfri.api.libcoap_api import APIFactory
from pytradfri.error import PytradfriError
from pytradfri.util import load_json, save_json

from pathlib import Path
import uuid
import argparse

CONFIG_FILE = 'tradfri_standalone_psk.conf'


parser = argparse.ArgumentParser()
parser.add_argument('-H', '--hostname', dest='host', required=True,
help='IP Address of your Tradfri gateway')
parser.add_argument('-K', '--key', dest='key', required=False,
help='Key found on your Tradfri gateway')
args = parser.parse_args()


if Path(CONFIG_FILE).is_file() is False and args.key is None:
raise PytradfriError("Please provide they key found on your "
"Tradfri gateway using the -K flag to this script.")


def observe(api, device):
Expand All @@ -39,16 +59,27 @@ def worker():
def run():
# Assign configuration variables.
# The configuration check takes care they are present.
api_factory = APIFactory(sys.argv[1])
with open('gateway_psk.txt', 'a+') as file:
file.seek(0)
psk = file.read()
if psk:
api_factory.psk = psk.strip()
else:
psk = api_factory.generate_psk(sys.argv[2])
conf = load_json(CONFIG_FILE)

try:
identity = conf[args.host].get('identity')
psk = conf[args.host].get('key')
api_factory = APIFactory(host=args.host, psk_id=identity, psk=psk)
except KeyError:
identity = uuid.uuid4().hex
api_factory = APIFactory(host=args.host, psk_id=identity)

try:
psk = api_factory.generate_psk(args.key)
print('Generated PSK: ', psk)
file.write(psk)

conf[args.host] = {'identity': identity,
'key': psk}
save_json(CONFIG_FILE, conf)

except AttributeError:
raise PytradfriError("Please provide your Key")

api = api_factory.request

gateway = Gateway()
Expand Down Expand Up @@ -77,7 +108,7 @@ def run():
print(light.name)

# Example 4: Set the light level of the light
dim_command = light.light_control.set_dimmer(255)
dim_command = light.light_control.set_dimmer(254)
api(dim_command)

# Example 5: Change color of the light
Expand Down
4 changes: 2 additions & 2 deletions pytradfri/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""Implement an API wrapper around Ikea Tradfri."""

from .error import (
PyTradFriError, RequestError, ClientError, ServerError, RequestTimeout)
PytradfriError, RequestError, ClientError, ServerError, RequestTimeout)
from .gateway import Gateway

__all__ = ['Gateway', 'PyTradFriError', 'RequestError', 'ClientError',
__all__ = ['Gateway', 'PytradfriError', 'RequestError', 'ClientError',
'ServerError', 'RequestTimeout']
6 changes: 3 additions & 3 deletions pytradfri/error.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
"""Errors for PyTradfri."""


class PyTradFriError(Exception):
class PytradfriError(Exception):
"""Base Error"""
pass


class RequestError(PyTradFriError):
class RequestError(PytradfriError):
"""An error happened sending or receiving a command."""
pass


class ColorError(PyTradFriError):
class ColorError(PytradfriError):
"""An error happened matching color name."""
pass

Expand Down
Loading

0 comments on commit 8902f2e

Please sign in to comment.