src package

Submodules

src.iot_object module

src.iot_object.IOT_OBJ_LIST = [<src.iot_object.IotObject instance>, <src.iot_object.IotObject instance>, <src.iot_object.IotObject instance>]

List of all IoT devices that are supported by this lambda function

class src.iot_object.IotObject(pubTopic, subTopic, awsObjectProfile)[source]

Represents an IoT devices that can be discovered by Alexa smart home

create iot objects
param self:
param pubTopic:MQTT topic that this device publishses to
param subTopic:MQTT topic that this device subscribes to
param awsObjectProfile:
 the dictionary containing the aws profile of this object, the profile allocates the endpoints, specifies the capabilities, friendly name(which the user called to invoke)
src.iot_object.bedRoomLightAwsProfile = {'capabilities': [{'interface': 'Alexa', 'version': '3', 'type': 'AlexaInterface'}, {'interface': 'Alexa.PowerController', 'version': '3', 'type': 'AlexaInterface', 'properties': {'retrievable': True, 'supported': [{'name': 'powerState'}], 'proactivelyReported': True}}], 'cookie': {}, 'description': 'Controller for bed room light', 'displayCategories': ['SWITCH'], 'endpointId': 'endpoint-002', 'friendlyName': 'bed room light', 'manufacturerName': 'Kd'}

the bed room light controller aws profile

src.iot_object.pcControllerAwsProfile = {'capabilities': [{'interface': 'Alexa', 'version': '3', 'type': 'AlexaInterface'}, {'interface': 'Alexa.PowerController', 'version': '3', 'type': 'AlexaInterface', 'properties': {'retrievable': True, 'supported': [{'name': 'powerState'}], 'proactivelyReported': True}}, {'interface': 'Alexa.EndpointHealth', 'version': '3', 'type': 'AlexaInterface', 'properties': {'retrievable': True, 'supported': [{'name': 'connectivity'}], 'proactivelyReported': True}}, {'interface': 'Alexa.TemperatureSensor', 'version': '3', 'type': 'AlexaInterface', 'properties': {'retrievable': True, 'supported': [{'name': 'temperature'}], 'proactivelyReported': True}}], 'cookie': {}, 'description': 'Controller that controls and monitor the desktop PC', 'displayCategories': ['SWITCH', 'TEMPERATURE_SENSOR'], 'endpointId': 'endpoint-001', 'friendlyName': 'my computer', 'manufacturerName': 'Kd'}

the pc controller aws profile

src.iot_object.speakerControllerAwsProfile = {'capabilities': [{'interface': 'Alexa', 'version': '3', 'type': 'AlexaInterface'}, {'interface': 'Alexa.Speaker', 'version': '3', 'type': 'AlexaInterface', 'properties': {'retrievable': True, 'supported': [{'name': 'volume'}, {'name': 'muted'}], 'proactivelyReported': True}}, {'interface': 'Alexa.EndpointHealth', 'version': '3', 'type': 'AlexaInterface', 'properties': {'retrievable': True, 'supported': [{'name': 'connectivity'}], 'proactivelyReported': True}}], 'cookie': {}, 'description': 'speaker controller', 'displayCategories': ['OTHER'], 'endpointId': 'endpoint-005', 'friendlyName': 'my computer speaker', 'manufacturerName': 'Kd'}

the speaker controller aws profile

src.iot_object.thermostatAwsProfile = {'capabilities': [{'interface': 'Alexa', 'version': '3', 'type': 'AlexaInterface'}, {'interface': 'Alexa.ThermostatController', 'version': '3', 'type': 'AlexaInterface', 'properties': {'retrievable': True, 'supported': [{'name': 'AdjustTargetTemperature'}, {'name': 'SetTargetTemperature'}], 'proactivelyReported': True}}, {'interface': 'Alexa.EndpointHealth', 'version': '3', 'type': 'AlexaInterface', 'properties': {'retrievable': True, 'supported': [{'name': 'connectivity'}], 'proactivelyReported': True}}], 'cookie': {}, 'description': 'Adjust temperature level', 'displayCategories': ['THERMOSTAT'], 'endpointId': 'endpoint-004', 'friendlyName': 'thermostat', 'manufacturerName': 'Kd'}

the thermostat aws profile

src.lambda_master_handler module

class src.lambda_master_handler.MasterHandler[source]
docstring create a master handler project, create a logger as well as an mqtt manager for mqtt related task
param self:the instance of MasterHandler class
_expectedTopic = ''

the topic that the master handler is expecting to receive from, the _replyReceived flag is only set if the expected topic mateched the received topic

_logger = None

Instance of logger used for logging purpose

_mqttManager = None

Instance of an mqtt manager, used by the master handler for communicating with aws mqtt

_replyMessage = ''

message received by mqtt callback function

_replyReceived = False

flags used for signalling if the correct reply has been received by mqtt callback function

getApplicanceByMessage(message)[source]
Parse the message sent by Alexa for the target endpoint ID and then look for that endpoint in the database list in the mqtt manager
param self:instance of master handler
param message:the message received by lambda handler from Alexa
handleDiscoveryV3(request)[source]
Used to handle discovery request, which lets Alexa know the list of devices that is available and what they can do
param self:the instance of master hander
param request:the request received by the lambda handler
handleErrorResponse(request, errorType, errorMessage)[source]
Used for creating a response to Amazon that indicates something wrong has happened
param self:instance of master handler
param request:the request received by lambda handler
param errorType:
 type of error encountered, limited number of types supported
param errorMessage:
 error message to be included in the payload
handleNonDiscoveryV3(request, context)[source]
Most requests are handled here, the handler will parse the necessary detail, forward it to the correct devices(using endpoint-ID to identify who to send to), wait for repy and then either timeout or tranlsate the reply of the IoT device into something that Alexa can understand and then hand it to the original lambda_handler in lambda_main
param self:instance of master handler
param request:the request received by lambda handler
param context:execution contex, not used
static subCallBack(client, userdata, message)[source]
The mqtt subscribe callback function, used for receiving messages from the IoT devices
param client:derpecated param
param userdata:deperated param
param message:an object that contains the main payload as well as the topic that payload comes from

src.lambda_mqtt_manager module

class src.lambda_mqtt_manager.MqttManager[source]
Constructor for Mqtt Manager, create logger, connect to AWS mqtt client and grab the list of IoT devices that are available
param self:
awsDeviceList = None

This of aws profiles of the supported IoT devices, used during discovery request to advertise available devices

createAWSClient()[source]
Connect to AWS mqtt server using credentials included with the lambda deployment package, most settings are stored in the mqtt_constant module
param self:instance of MqttManager
createLogger()[source]
Create a logger to log mqtt messages
param self:instance of MqttManager
iotObjList = None

List of IoT mcu that this backend can talk to to fulfill Alexa request, it will also advertise this list to Alexa using Discovery Directives

mqttPub(package, pubTopic)[source]
Publish the given package to the supplied mqtt topic
param self:instance of MqttManager
param package:json dict to be published
param pubTopic:topic to publish to

src.mqtt_constant module

src.mqtt_constant.AUTHORITY_CERT_PATH = 'certs/VeriSign-Class_3-Public-Primary-Certification-Authority-G5.pem'

Relative path to certifcate of authority

src.mqtt_constant.AWS_ENDPOINT = '.iot.us-east-1.amazonaws.com'

The middle part of the endpoint that indicates regions of aws service

src.mqtt_constant.CERTIFICATE_PATH = 'certs/certificate.pem.crt'

Relative path to device certificate, downloaded from aws IoT

src.mqtt_constant.CLIENT_ID = 'lambda_service'

ID of this lambda handler function

src.mqtt_constant.CONNECT_DISCONNECT_TIMEOUT = 5

How many seconds to wait before concluding that the connect/disconnect operation has timed out

src.mqtt_constant.DRAINING_FREQ = 5

How many requests that the Mqtt will try to resolve per seconds(the unit is Hz) if there is a big queue

src.mqtt_constant.ENDPT_FILE_PATH = 'certs/accessPointID.txt'

relative file path that has accessPointID, access point ID can be obtained by obtaining the first part of the REST API in the aws IoT core console

src.mqtt_constant.INITIAL_BACKOFF_TIME = 1

How may seconds to stop before retransmitting upon the first conflict in mqtt

src.mqtt_constant.KEEP_ALIVE_SECONDS = 300

Duration between ping to mqtt server to indicate the intention to continue connection

src.mqtt_constant.MAX_BACKOFF_TIME = 5

Max seconds to stop before retransmitting upon continuous conflict in mqtt

src.mqtt_constant.MQTT_PORT = 8883

Port used by secure MQTT service

src.mqtt_constant.OFFLINE_PUB_QUEUE = 3

Max number of requests to be queue while the lambda handler is offline, 0 for none, -1 for infinite

src.mqtt_constant.OPERATION_TIMEOUT = 4

How many seconds to wait before concluding that general operation(not special one like connect/disconenct) has timed out

src.mqtt_constant.PRIVATE_KEY_PATH = 'certs/private.pem.key'

Relative path to private key, downloaded from aws IoT

src.mqtt_constant.PUB_QOS = 1

Publish Quality of service, service of 1 guarantees at least 1 delivery arrives at target, 0 means best effort not gurantee

src.mqtt_constant.STABLE_TIME = 3

How much time in seconds are considered stable, after this amount of time, the backoff time will be reset back to the initial level

src.mqtt_constant.SUB_QOS = 1

Subscribe QoS, similar to PUB_QOS

src.mqtt_constant.UNCERTAINTY_MS = 200

Uncertainty of measurement that is reported to Alexa during responses

src.translator module

class src.translator.Translator[source]

Responsible for translating from Alexa commands to commands for IoT and replies of IoT devices to Alexa responses to users

static translateToEcho(iotMessage, echoMessage)[source]
docstring here
param iotMessage:
 the message received from and IoT device
param echoMessage:
 the echo message originally received by the lambda handler
return:the final dict to be returned as return result of the lambda handler
static translateToIoT(echoMessage)[source]
docstring here
param echoMessage:
 message to be translated to IoT
return:the translated dict to be sent to IoT
src.translator.echoPropertiesPrototype = {'name': 'powerState', 'namespace': 'Alexa.PowerController', 'timeOfSample': '2017-09-27T18:30:30.45Z', 'uncertaintyInMilliseconds': 200, 'value': 'OFF'}

A skeleton dictionary represents a typical member of the properties list in the Discovery response to Alexa

src.translator.echoResponsePrototype = {'context': {'properties': []}, 'event': {'header': {'payloadVersion': '3', 'correlationToken': 'dFMb0z+PgpgdDmluhJ1LddFvSqZ/jCc8ptlAKulUj90jSqg==', 'namespace': 'Alexa', 'name': 'StateReport', 'messageId': '5f8a426e-01e4-4cc9-8b79-65f8bd0fd8a4'}, 'endpoint': {'scope': {'token': 'access-token-from-Amazon', 'type': 'BearerToken'}, 'endpointId': 'endpoint-001'}, 'payload': {}}}

A skeleton dictionary representing a response to Alexa, translator will fill this out with appropriate details and then return as the lambda final responses(if it passes the json validate test)

src.translator.iotMessagePrototype = {'name': 'TurnOff', 'namespace': 'Alexa.PowerController', 'payload': {}}

Contain a skeleton dictionary of a message to be sent to the IoT Devices, translator base on this for the final message

src.translator.iotReplyPrototype = {'name': 'brightness', 'namespace': 'Alexa.BrightnessController', 'value': 50}

A skeleton dictionary that represents typical reply by IoT devices, the translator copy this, extract the data from the IoT reply into the copy, and then attach into the final response to Alexa

src.utils module

src.utils.getAccessToken(echoMessage)[source]
Get Access Token of Alexa message
param echomessage:
 message sent to the lambda handler
src.utils.getCommandName(message)[source]
Get the command name in the json message sent to the lambda handler
param message:message sent to the lambda handler
src.utils.getCorrelationToken(message)[source]
Get the Correleation token for the of the Alexa message
param message:message sent to the lambda handler
src.utils.getEndpointID(echoMessage)[source]
Get the uniqe target endpoint ID of Alexa message so that it can be compared with database
param echomessage:
 message sent to the lambda handler
src.utils.getNameSpace(message)[source]
Return namespace of the command received
param message:message sent to the lambda handler
src.utils.getPayload(echoMessage)[source]
Get the paylod component of the message sent to lambda
param echomessage:
 message sent to the lambda handler
src.utils.getUtcTimeStamp(seconds=None)[source]
Used for returning current time for timestamp purpose in aws reply
param seconds=None:
 get current utc time
src.utils.getUuid()[source]

Get unique ID for message

src.utils.get_directive_version(request)[source]
Get the version directive to be either v2 or v3
param request:the request set to the hander

Module contents