Skip to content

Instantly share code, notes, and snippets.

@benrules2

benrules2/ThingShadow.ino

Last active Apr 3, 2021
Embed
What would you like to do?
Alexa Smart Home and Arduino Yun Smart Light Code
/*
* Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
#ifndef config_usr_h
#define config_usr_h
// Copy and paste your configuration into this file
//===============================================================
#define AWS_IOT_MQTT_HOST "<your endpoint>" // your endpoint e.g. 12345abcd.iot.us-east-1.amazonaws.com
#define AWS_IOT_MQTT_PORT 443 // your port
#define AWS_IOT_CLIENT_ID "ArduinoYun" // your client ID
#define AWS_IOT_MY_THING_NAME "<your thing name>" // your thing name e.g. "Light1"
#define AWS_IOT_ROOT_CA_FILENAME "<root-certificate filename>.pem" // your root-CA filename
#define AWS_IOT_CERTIFICATE_FILENAME "<your filename>.pem.crt" // your certificate filename
#define AWS_IOT_PRIVATE_KEY_FILENAME "<your filename>-private.pem.key" // your private key filename
#define AWS_IOT_DEBUG // Enable debug logging. Remove it if you want to disable it.
//===============================================================
// SDK config, DO NOT modify it
#define AWS_IOT_PATH_PREFIX "../certs/"
#define AWS_IOT_ROOT_CA_PATH AWS_IOT_PATH_PREFIX AWS_IOT_ROOT_CA_FILENAME // use this in config call
#define AWS_IOT_CERTIFICATE_PATH AWS_IOT_PATH_PREFIX AWS_IOT_CERTIFICATE_FILENAME // use this in config call
#define AWS_IOT_PRIVATE_KEY_PATH AWS_IOT_PATH_PREFIX AWS_IOT_PRIVATE_KEY_FILENAME // use this in config call
#endif
import logging
import time
import json
import uuid
import datetime
import boto3
client = boto3.client('iot-data')
def get_utc_timestamp(seconds=None):
return time.strftime("%Y-%m-%dT%H:%M:%S.00Z", time.gmtime(seconds))
def light_state(state):
# Change topic, qos and payload
response = client.update_thing_shadow(
thingName = 'Your-Thing-Name',
payload = json.dumps({
'state': {
'desired': {
'light': state
}
}
}
)
)
def get_uuid():
return str(uuid.uuid4())
# Setup logger
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
logger.info("Received v3 directive!")
logger.info(json.dumps(event))
if event['directive']['header']['name'] == "Discover":
logger.info("Discover")
response = handle_discovery(event)
else:
logger.info("Control")
response = handle_control(event, context)
logger.info("response" + json.dumps(response))
return response
def handle_discovery(event):
response = {
"event":
{
"header":
{
"correlationToken": "12345692749237492",
"namespace": "Alexa.Discovery",
"name": "Discover.Response",
"payloadVersion": "3",
"messageId": event['directive']['header']['messageId']
},
"payload":
{
"endpoints":[
{
"endpointId": "your_custom_endpoint",
"manufacturerName": "Manufacturer 1234",
"friendlyName": "Your Light Name",
"description": "Smart Device Switch",
"displayCategories": ["SWITCH"],
"cookie": {
"key1": "arbitrary key/value pairs for skill to reference this endpoint.",
},
"capabilities": [
{
"type": "AlexaInterface",
"interface": "Alexa",
"version": "3"
},
{
"interface": "Alexa.PowerController",
"version": "3",
"type": "AlexaInterface",
"properties": {
"supported": [
{
"name": "powerState"
}
],
"proactivelyReported": True,
"retrievable": True
}
}
]
}
]
}
}
}
logger.info("Response: " +json.dumps(response))
return response
def handle_control(request, context):
request_namespace = request["directive"]["header"]["namespace"]
request_name = request["directive"]["header"]["name"]
if request_namespace == "Alexa.PowerController":
if request_name == "TurnOn":
light_state("on")
value = "ON"
else:
light_state("off")
value = "OFF"
response = {
"context": {
"properties": [
{
"namespace": "Alexa.PowerController",
"name": "powerState",
"value": value,
"timeOfSample": get_utc_timestamp(),
"uncertaintyInMilliseconds": 500
}
]
},
"event": {
"header": {
"namespace": "Alexa",
"name": "Response",
"payloadVersion": "3",
"messageId": get_uuid(),
"correlationToken": request["directive"]["header"]["correlationToken"]
},
"endpoint": {
"scope": {
"type": "BearerToken",
"token": "access-token-from-Amazon"
},
"endpointId": request["directive"]["endpoint"]["endpointId"]
},
"payload": {}
}
}
return response
/*
* Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
#include <aws_iot_mqtt.h>
#include <aws_iot_version.h>
#include "aws_iot_config.h"
#include <string.h>
aws_iot_mqtt_client myClient;
char JSON_buf[100];
int cnt = 0;
int rc = 1;
bool success_connect = false;
//LED Setup
const int NUM_PINS=10;
int ledPins[NUM_PINS] = {4,5,6,7,8,9,10,11,12,13};
int i = 0;
bool print_log(const char* src, int code) {
bool ret = true;
if(code == 0) {
#ifdef AWS_IOT_DEBUG
Serial.print(F("[LOG] command: "));
Serial.print(src);
Serial.println(F(" completed."));
#endif
ret = true;
}
else {
#ifdef AWS_IOT_DEBUG
Serial.print(F("[ERR] command: "));
Serial.print(src);
Serial.print(F(" code: "));
Serial.println(code);
#endif
ret = false;
}
Serial.flush();
return ret;
}
void toggle_light(uint8_t state)
{
int i = 0;
for (i = 0; i < NUM_PINS; i++)
{
digitalWrite(ledPins[i], state);
}
}
void msg_callback_delta(char* src, unsigned int len, Message_status_t flag) {
if(flag == STATUS_NORMAL) {
// Get delta for light key
print_log("getDeltaKeyValue", myClient.getDeltaValueByKey(src, "light", JSON_buf, 100));
Serial.println(JSON_buf);
if (strcmp(JSON_buf, "on") == 0)
toggle_light(HIGH);
else
toggle_light(LOW);
String payload = "{\"state\":{\"reported\":";
payload += "{\"light\":\"";
payload += JSON_buf;
payload += "\"}}}";
payload.toCharArray(JSON_buf, 100);
Serial.println(JSON_buf);
print_log("update thing shadow", myClient.shadow_update(AWS_IOT_MY_THING_NAME, JSON_buf, strlen(JSON_buf), NULL, 5));
}
}
void setup() {
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
int i = 0;
for (i = 0; i < NUM_PINS; i++)
{
pinMode(ledPins[i], OUTPUT);
}
//Disable this line if connected to wall plug!
//while(!Serial);
char curr_version[80];
snprintf_P(curr_version, 80, PSTR("AWS IoT SDK Version(dev) %d.%d.%d-%s\n"), VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG);
Serial.println(curr_version);
if(print_log("setup...", myClient.setup(AWS_IOT_CLIENT_ID, true, MQTTv311, true))) {
if(print_log("config", myClient.config(AWS_IOT_MQTT_HOST, AWS_IOT_MQTT_PORT, AWS_IOT_ROOT_CA_PATH, AWS_IOT_PRIVATE_KEY_PATH, AWS_IOT_CERTIFICATE_PATH))) {
if(print_log("connect", myClient.connect())) {
success_connect = true;
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500);
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
print_log("shadow init", myClient.shadow_init(AWS_IOT_MY_THING_NAME));
print_log("register thing shadow delta function", myClient.shadow_register_delta_func(AWS_IOT_MY_THING_NAME, msg_callback_delta));
}
}
}
}
void loop() {
if(success_connect) {
if(myClient.yield()) {
Serial.println(F("Yield failed."));
}
delay(1000); // check for incoming delta per 100 ms
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment