Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
secret.txt
.env
.venv
token.txt

*.py[cod]

Expand Down
38 changes: 38 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,44 @@ Python API for the Honeywell Lyric™ Thermostat
=========================================================


Setup
=====

::

python3 -m venv .venv
source .venv/bin/activate
pip install -e .

This installs the package and its dependencies (``requests``, ``requests_oauthlib``, ``python-dotenv``).


Testing
=======

Create an app at the `Honeywell Developer Portal <https://developer.honeywellhome.com/>`_
to obtain your ``LYRIC_CLIENT_ID`` and ``LYRIC_CLIENT_SECRET``. Set the callback/redirect
URL to match ``LYRIC_REDIRECT_URI`` (e.g. ``https://localhost``).

Duplicate example.env as .env and populate it (or otherwise set these environment variables):

LYRIC_CLIENT_ID=your_client_id
LYRIC_CLIENT_SECRET=your_client_secret
LYRIC_REDIRECT_URI=https://localhost

On first run, the script will print an authorization URL. Open it in a browser,
log in with your Honeywell account (separate from Honeywell developer account),
and complete the authorization flow, which will result in being redirected to
a url containing "code" and "state" parameters (the URL will not work), paste
this URL back into the CLI.

A ``token.txt`` file will be created to cache the token for subsequent runs.

**General device test** — prints locations, thermostats, and water leak detectors::

python -m lyric.test


History
=======

Expand Down
3 changes: 3 additions & 0 deletions example.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
LYRIC_CLIENT_ID=your_client_id
LYRIC_CLIENT_SECRET=your_client_secret
LYRIC_REDIRECT_URI=https://localhost
77 changes: 33 additions & 44 deletions lyric/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,63 +2,52 @@

"""Battery of tests for lyric module."""

from . import lyric as lyric_local
import json
from .test_common import get_api

client_id = r""
client_secret = r""

redirect_uri = "https://hass.deproducties.com/api/lyric"
app_name = "Sample"
token_cache_file = "token.txt"

lapi = lyric_local.Lyric(
client_id=client_id,
client_secret=client_secret,
token_cache_file=token_cache_file,
redirect_uri=redirect_uri,
app_name=app_name,
)

if lapi._token is None:
print(lapi.getauthorize_url)
lapi = get_api()

print(lapi._locations)

for location in lapi.locations:
print(location)
print(location.id)
print(location.name)
print(location.city)
print(location.geoFences)
print(location.geoFences[0]["geoOccupancy"]["withinFence"])

print("Location ID:", location.id)
print("Name:", location.name)
print("City:", location.city)
print("GeoFences:", location.geoFences)
if location.geoFences:
print(location.geoFences[0]["geoOccupancy"]["withinFence"])

print ("===Users===")
for user in location.users:
print(user)
print(user.id)
print(user.name)
print(user.firstname)
print(user.lastname)
print("User ID:", user.id)
print("Name:", user.name)
print("First:", user.firstname)
print("Last:", user.lastname)

print ("===Devices===")
for device in location.devices:
print(device)
print(device.id)
print(device.name)
print(device.deviceType)
print(device.indoorTemperature)
print(device.temperatureSetpoint)
device.temperatureSetpoint = 18
print("Device ID:", device.id)
print("Name:", device.name)
print("Type:", device.deviceType)
print("Indoor Temp:", device.indoorTemperature)
print("Setpoint:", device.temperatureSetpoint)

print ("===Thermostats===")
for thermostat in location.thermostats:
print(thermostat)
print(thermostat.id)
print(thermostat.name)
print(thermostat.deviceType)
print(thermostat.outdoorTemperature)
print(thermostat.indoorHumidityStatus)
print(thermostat.temperatureSetpoint)

print("Thermostat ID:", thermostat.id)
print("Name:", thermostat.name)
print("Type:", thermostat.deviceType)
print("Outdoor Temp:", thermostat.outdoorTemperature)
print("Humidity Status:", thermostat.indoorHumidityStatus)
print("Setpoint:", thermostat.temperatureSetpoint)

print ("===Water Leak Detectors===")
for waterLeakDetector in location.waterLeakDetectors:
print(waterLeakDetector)
print(waterLeakDetector.id)
print(waterLeakDetector.name)
print(waterLeakDetector.deviceType)
print("Water Leak Detector ID:", waterLeakDetector.id)
print("Name:", waterLeakDetector.name)
print("Type:", waterLeakDetector.deviceType)
37 changes: 37 additions & 0 deletions lyric/test_common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# -*- coding:utf-8 -*-

"""Shared setup for test scripts."""

import os
from dotenv import load_dotenv
from . import Lyric

load_dotenv()

TOKEN_CACHE_FILE = "token.txt"


def get_api():
"""Create and authorize a Lyric API instance."""

lapi = Lyric(
client_id=os.environ["LYRIC_CLIENT_ID"],
client_secret=os.environ["LYRIC_CLIENT_SECRET"],
token_cache_file=TOKEN_CACHE_FILE,
redirect_uri=os.environ["LYRIC_REDIRECT_URI"],
app_name="Sample",
)

if lapi._token is None:
# Allow http://localhost for local OAuth redirect
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
print("Open this URL in a browser to authorize:")
print(lapi.getauthorize_url)
redirect_url = input(
"\nAfter you authorize you will be redirected to a URL containing"
" a \"code\" and \"state\" parameter, paste that full URL here: "
).strip()
lapi.authorization_response(redirect_url)
print("Token saved to %s" % TOKEN_CACHE_FILE)

return lapi
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@
url='https://github.com/bramkragten/python-lyric/',
packages=['lyric'],
install_requires=['requests>=1.0.0',
'requests_oauthlib>=0.7.0']
'requests_oauthlib>=0.7.0',
'python-dotenv>=0.9.0']
)