**The following is an example of accessing the Telldus PA-API using Python** This example requires the following 3rd party Python packages:\\ Flask requests_oauthlib You can install them using pip:\\ {{{ pip install -U flask requests_oauthlib }}} == The example project **Running the project** You can run the project's main application using python from the root of the project folder: {{{ python app.py }}} **Project directory** You can organise your project directory as follows: {{{ telldus_flask_app/ │ ├── app.py ├── config.py ├── requirements.txt └── templates/ ├── index.html ├── clients.html ├── devices.html └── authorization_failed.html }}} == App & configurations **Configuration** We define some commonly used constants here. `config.py` {{{ # config.py import os # Obtain the public and private key from https://pa-api.telldus.com/keys/showToken CONSUMER_KEY = 'Public key' CONSUMER_SECRET = 'Private key' # Defines the API end points REQUEST_TOKEN_URL = 'https://pa-api.telldus.com/oauth/requestToken' AUTHORIZE_URL = 'https://pa-api.telldus.com/oauth/authorize' ACCESS_TOKEN_URL = 'https://pa-api.telldus.com/oauth/accessToken' API_BASE_URL = 'https://pa-api.telldus.com/json' CALLBACK_URL = 'http://127.0.0.1:5000/callback' # Update with your domain # Flask secret key for session management SECRET_KEY = os.urandom(24) # Add to config.py TURNON = 1 # Example value, replace with actual constant TURNOFF = 2 # Example value, replace with actual constant }}} **The Flask application** The main application. `app.py` {{{ # app.py from flask import Flask, session, redirect, url_for, request, render_template, flash from requests_oauthlib import OAuth1Session import config import json app = Flask(__name__) app.config.from_object('config') # OAuth1Session setup def get_oauth_session(token=None, token_secret=None): return OAuth1Session( client_key=config.CONSUMER_KEY, client_secret=config.CONSUMER_SECRET, resource_owner_key=token, resource_owner_secret=token_secret, callback_uri=config.CALLBACK_URL ) def print_debug_message(message): print(f'[DEBUG] {message}') @app.route('/') def index(): access_token = session.get('access_token') access_token_secret = session.get('access_token_secret') print_debug_message("Accessing home page.") print_debug_message(f"Access Token: {access_token}") print_debug_message(f"Access Token Secret: {access_token_secret}") if not access_token: print_debug_message("No access token found. User not authenticated.") return render_template('index.html', authenticated=False) # Example API call: List devices oauth = get_oauth_session(access_token, access_token_secret) params = { 'supportedMethods': config.TURNOFF|config.TURNON, # Example parameter 'format': 'json' } print_debug_message(f"Making API call to {config.API_BASE_URL}/devices/list with params {params}") try: response = oauth.get(f"{config.API_BASE_URL}/devices/list", params=params) print_debug_message(f"API Response Status Code: {response.status_code}") if response.status_code != 200: flash('Failed to fetch devices.', 'danger') print_debug_message("Failed to fetch devices from API.") devices = [] else: devices = response.json().get('device', []) print_debug_message(f"Devices fetched: {json.dumps(devices, indent=2)}") except Exception as e: flash('An error occurred while fetching devices.', 'danger') print_debug_message(f"Exception during API call: {str(e)}") devices = [] return render_template('index.html', authenticated=True, devices=devices) @app.route('/login') def login(): print_debug_message("Initiating OAuth login process.") oauth = get_oauth_session() try: fetch_response = oauth.fetch_request_token(config.REQUEST_TOKEN_URL) print_debug_message(f"Request Token fetched: {fetch_response}") except ValueError as e: flash('Failed to obtain request token.', 'danger') print_debug_message(f"Failed to fetch request token: {str(e)}") return redirect(url_for('index')) session['resource_owner_key'] = fetch_response.get('oauth_token') session['resource_owner_secret'] = fetch_response.get('oauth_token_secret') print_debug_message(f"Stored request token in session: {session['resource_owner_key']}") authorization_url = oauth.authorization_url(config.AUTHORIZE_URL) print_debug_message(f"Redirecting to authorization URL: {authorization_url}") return redirect(authorization_url) @app.route('/callback') def callback(): print_debug_message("Handling OAuth callback.") resource_owner_key = session.get('resource_owner_key') resource_owner_secret = session.get('resource_owner_secret') print_debug_message(f"Resource Owner Key: {resource_owner_key}") print_debug_message(f"Resource Owner Secret: {resource_owner_secret}") if not resource_owner_key or not resource_owner_secret: flash('Missing request token.', 'danger') print_debug_message("Missing request token in session.") return redirect(url_for('index')) oauth = get_oauth_session(resource_owner_key, resource_owner_secret) oauth_response = oauth.parse_authorization_response(request.url) verifier = oauth_response.get('oauth_verifier') print_debug_message(f"OAuth Verifier obtained: {verifier}") if not verifier: flash('Authorization failed or was denied.', 'danger') print_debug_message("Authorization failed or was denied by the user.") return redirect(url_for('index')) try: oauth_tokens = oauth.fetch_access_token(config.ACCESS_TOKEN_URL, verifier=verifier) print_debug_message(f"Access Token fetched: {oauth_tokens}") except ValueError as e: flash('Failed to obtain access token.', 'danger') print_debug_message(f"Failed to fetch access token: {str(e)}") return redirect(url_for('index')) session['access_token'] = oauth_tokens.get('oauth_token') session['access_token_secret'] = oauth_tokens.get('oauth_token_secret') print_debug_message(f"Stored access token in session: {session['access_token']}") # Clear request tokens session.pop('resource_owner_key', None) session.pop('resource_owner_secret', None) print_debug_message("Cleared request tokens from session.") flash('You have successfully logged in.', 'success') print_debug_message("User successfully authenticated and logged in.") return redirect(url_for('index')) @app.route('/logout') def logout(): print_debug_message("Logging out user.") session.pop('access_token', None) session.pop('access_token_secret', None) flash('You have been logged out.', 'success') print_debug_message("Access tokens removed from session.") return redirect(url_for('index')) @app.route('/devices') def devices(): print_debug_message("Accessing devices route.") access_token = session.get('access_token') access_token_secret = session.get('access_token_secret') print_debug_message(f"Access Token: {access_token}") print_debug_message(f"Access Token Secret: {access_token_secret}") if not access_token: flash('You need to log in first.', 'warning') print_debug_message("User not authenticated. Redirecting to home.") return redirect(url_for('index')) oauth = get_oauth_session(access_token, access_token_secret) params = { 'supportedMethods': config.TURNON|config.TURNOFF, # Example parameter 'format': 'json' } print_debug_message(f"Making API call to {config.API_BASE_URL}/devices/list with params {params}") try: response = oauth.get(f"{config.API_BASE_URL}/devices/list", params=params) print_debug_message(f"API Response Status Code: {response.status_code}") if response.status_code != 200: flash('Failed to fetch devices.', 'danger') print_debug_message("Failed to fetch devices from API.") devices = [] else: devices = response.json().get('devices', []) print_debug_message(f"Devices fetched: {json.dumps(devices, indent=2)}") except Exception as e: flash('An error occurred while fetching devices.', 'danger') print_debug_message(f"Exception during API call: {str(e)}") devices = [] return render_template('devices.html', devices=devices) @app.route('/clients') def clients(): print_debug_message("Accessing clients route.") access_token = session.get('access_token') access_token_secret = session.get('access_token_secret') print_debug_message(f"Access Token: {access_token}") print_debug_message(f"Access Token Secret: {access_token_secret}") if not access_token: flash('You need to log in first.', 'warning') print_debug_message("User not authenticated. Redirecting to home.") return redirect(url_for('index')) oauth = get_oauth_session(access_token, access_token_secret) params = { 'format': 'json' } print_debug_message(f"Making API call to {config.API_BASE_URL}/json/clients/list with params {params}") try: response = oauth.get(f"{config.API_BASE_URL}/clients/list", params=params) print_debug_message(f"API Response Status Code: {response.status_code}") if response.status_code != 200: flash('Failed to fetch clients.', 'danger') print_debug_message("Failed to fetch clients from API.") clients = [] else: clients = response.json().get('client', []) print_debug_message(f"Clients fetched: {json.dumps(clients, indent=2)}") except Exception as e: flash('An error occurred while fetching clients.', 'danger') print_debug_message(f"Exception during API call: {str(e)}") clients = [] return render_template('clients.html', clients=clients) if __name__ == '__main__': app.secret_key = config.SECRET_KEY app.run(debug=True) }}} == The html templates **The home page** `templates/index.html` {{{ Telldus Flask App
{% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %} {% endfor %} {% endif %} {% endwith %}

Telldus Live! Integration

{% if not authenticated %}

You are not connected to Telldus Live!.

Connect with Telldus {% else %}

You are connected to Telldus Live!

Logout

Devices

{% if devices %} {% else %}

No devices found.

{% endif %}

Clients

View Clients {% endif %}
}}} **The devices page** `templates/devices.html` {{{ Your Devices
{% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %} {% endfor %} {% endif %} {% endwith %}

Your Devices

Back to Home {% if devices %} {% else %}

No devices found.

{% endif %}
}}} **The clients page** `templates/clients.html` {{{ Your Clients
{% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %} {% endfor %} {% endif %} {% endwith %}

Your Clients

Back to Home {% if clients %} {% else %}

No clients found.

{% endif %}
}}} **The authorisation failed page** `templates/authorization_failed.html` {{{ Authorisation Failed

Authorization Failed!

Go back

}}}