Alexa Integration
This example demonstrates how to integrate SmartHomeHarmonizer with Amazon Alexa Smart Home Skills.
Note
This documentation is under development. See the example file for the current implementation.
Example Code
Alexa Smart Home Skill integration
"""Example Alexa Smart Home Skill integration."""
import json
from flask import request, jsonify
from smarthomeharmonizer import create_app, DeviceManager
from smarthomeharmonizer.adapters.smart_light import SmartLightAdapter
import logging
logger = logging.getLogger(__name__)
def create_alexa_app(device_manager: DeviceManager = None):
"""Create Flask app with Alexa endpoints."""
app = create_app(device_manager)
@app.route('/alexa/smart_home', methods=['POST'])
def alexa_smart_home():
"""Handle Alexa Smart Home directives."""
directive = request.json
# Extract directive information
header = directive.get('directive', {}).get('header', {})
namespace = header.get('namespace')
name = header.get('name')
# Handle discovery
if namespace == 'Alexa.Discovery' and name == 'Discover':
return handle_discovery()
# Handle control
if namespace == 'Alexa.PowerController':
return handle_power_control(directive)
if namespace == 'Alexa.BrightnessController':
return handle_brightness_control(directive)
# Handle state reporting
if namespace == 'Alexa' and name == 'ReportState':
return handle_report_state(directive)
# Unknown directive
return create_error_response('INVALID_DIRECTIVE', 'Unknown directive')
def handle_discovery():
"""Handle device discovery requests from Alexa."""
devices = app.device_manager.list_devices()
endpoints = []
for device in devices:
endpoint = {
'endpointId': device['deviceId'],
'friendlyName': device['name'],
'description': f'SmartHomeHarmonizer {device["type"]}',
'manufacturerName': 'SmartHomeHarmonizer',
'displayCategories': ['LIGHT'], # Adjust based on device type
'capabilities': []
}
# Add capabilities based on supported commands
if 'turnOn' in device['supportedCommands']:
endpoint['capabilities'].append({
'type': 'AlexaInterface',
'interface': 'Alexa.PowerController',
'version': '3',
'properties': {
'supported': [{'name': 'powerState'}],
'proactivelyReported': True,
'retrievable': True
}
})
if 'setBrightness' in device['supportedCommands']:
endpoint['capabilities'].append({
'type': 'AlexaInterface',
'interface': 'Alexa.BrightnessController',
'version': '3',
'properties': {
'supported': [{'name': 'brightness'}],
'proactivelyReported': True,
'retrievable': True
}
})
endpoints.append(endpoint)
return jsonify({
'event': {
'header': {
'namespace': 'Alexa.Discovery',
'name': 'Discover.Response',
'payloadVersion': '3',
'messageId': generate_message_id()
},
'payload': {
'endpoints': endpoints
}
}
})
def handle_power_control(directive):
"""Handle power control directives."""
endpoint_id = directive['directive']['endpoint']['endpointId']
name = directive['directive']['header']['name']
command = 'turnOn' if name == 'TurnOn' else 'turnOff'
try:
state = app.device_manager.execute_command(endpoint_id, command)
return create_response(
directive,
'Alexa.PowerController',
[
{
'namespace': 'Alexa.PowerController',
'name': 'powerState',
'value': state['powerState'],
'timeOfSample': get_utc_timestamp()
}
]
)
except Exception as e:
logger.error(f"Error handling power control: {e}")
return create_error_response('ENDPOINT_UNREACHABLE', str(e))
def handle_brightness_control(directive):
"""Handle brightness control directives."""
endpoint_id = directive['directive']['endpoint']['endpointId']
brightness = directive['directive']['payload']['brightness']
try:
state = app.device_manager.execute_command(
endpoint_id,
'setBrightness',
{'brightness': brightness}
)
return create_response(
directive,
'Alexa.BrightnessController',
[
{
'namespace': 'Alexa.BrightnessController',
'name': 'brightness',
'value': state['brightness'],
'timeOfSample': get_utc_timestamp()
}
]
)
except Exception as e:
logger.error(f"Error handling brightness control: {e}")
return create_error_response('ENDPOINT_UNREACHABLE', str(e))
def handle_report_state(directive):
"""Handle state reporting requests."""
endpoint_id = directive['directive']['endpoint']['endpointId']
try:
state = app.device_manager.get_device_state(endpoint_id)
properties = []
# Add power state
if 'powerState' in state:
properties.append({
'namespace': 'Alexa.PowerController',
'name': 'powerState',
'value': state['powerState'],
'timeOfSample': get_utc_timestamp()
})
# Add brightness
if 'brightness' in state:
properties.append({
'namespace': 'Alexa.BrightnessController',
'name': 'brightness',
'value': state['brightness'],
'timeOfSample': get_utc_timestamp()
})
return create_response(directive, 'Alexa', properties)
except Exception as e:
logger.error(f"Error reporting state: {e}")
return create_error_response('ENDPOINT_UNREACHABLE', str(e))
return app
def create_response(request_directive, namespace, properties):
"""Create Alexa response."""
import uuid
from datetime import datetime
return jsonify({
'event': {
'header': {
'namespace': namespace,
'name': 'Response',
'messageId': str(uuid.uuid4()),
'correlationToken': request_directive['directive']['header'].get('correlationToken'),
'payloadVersion': '3'
},
'endpoint': request_directive['directive']['endpoint'],
'payload': {}
},
'context': {
'properties': properties
}
})
def create_error_response(error_type, message):
"""Create Alexa error response."""
import uuid
return jsonify({
'event': {
'header': {
'namespace': 'Alexa',
'name': 'ErrorResponse',
'messageId': str(uuid.uuid4()),
'payloadVersion': '3'
},
'payload': {
'type': error_type,
'message': message
}
}
})
def generate_message_id():
"""Generate unique message ID."""
import uuid
return str(uuid.uuid4())
def get_utc_timestamp():
"""Get current UTC timestamp in ISO format."""
from datetime import datetime
return datetime.utcnow().isoformat() + 'Z'
# Example usage
if __name__ == '__main__':
# Create device manager
manager = DeviceManager()
# Register devices
light1 = SmartLightAdapter('light1', 'Living Room Light')
light2 = SmartLightAdapter('light2', 'Bedroom Light')
manager.register_device(light1)
manager.register_device(light2)
# Create Alexa-enabled app
app = create_alexa_app(manager)
print("Alexa Smart Home Skill endpoint ready!")
print("Configure your Alexa skill to use:")
print(" https://your-domain.com/alexa/smart_home")
print("\nNote: As an Amazon employee, ensure you have proper approvals")
print("This is a personal project and not affiliated with Amazon.")
app.run(host='0.0.0.0', port=5000, debug=True)
For more information, see the example file in the repository.