Last active
June 20, 2020 20:38
-
-
Save kylekyle/25e27775839d2466f40c08bde76c55bb to your computer and use it in GitHub Desktop.
Control a garage door with a Raspberry Pi and Echo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A script that runs a raspberry pi to receive commands from an echo | |
// and control a garage door opener wired to the GPIO | |
// To set up the Echo, follow this guide: | |
// https://read.acloud.guru/how-to-build-your-own-alexa-voice-activated-iot-smart-lamp-for-less-than-35-9820ccd07516 | |
// To compile this script, use the Makefile in the subscribe_publish_sample of the AWS IoT Device SDK. You'll | |
// need to link in the wiringPi library. | |
// If you are having policy issues, you can create a super-permissive policy that will let your device do anything: | |
// | |
// { | |
// "Version": "2020-6-20", | |
// "Statement": [ | |
// { | |
// "Effect": "Allow", | |
// "Action": "iot:*", | |
// "Resource": "arn:aws:iot:<your-region>:<your-id>:*" | |
// } | |
// ] | |
// } | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <ctype.h> | |
#include <unistd.h> | |
#include <limits.h> | |
#include <string.h> | |
#include <wiringPi.h> | |
#include "aws_iot_config.h" | |
#include "aws_iot_log.h" | |
#include "aws_iot_version.h" | |
#include "aws_iot_mqtt_client_interface.h" | |
#define HOST_ADDRESS_SIZE 255 | |
/** | |
* @brief Default cert location | |
*/ | |
char certDirectory[PATH_MAX + 1] = "certs"; | |
/** | |
* @brief Default MQTT HOST URL is pulled from the aws_iot_config.h | |
*/ | |
char HostAddress[HOST_ADDRESS_SIZE] = AWS_IOT_MQTT_HOST; | |
/** | |
* @brief Default MQTT port is pulled from the aws_iot_config.h | |
*/ | |
uint32_t port = AWS_IOT_MQTT_PORT; | |
void iot_subscribe_callback_handler(AWS_IoT_Client *pClient, char *topicName, uint16_t topicNameLen, | |
IoT_Publish_Message_Params *params, void *pData) { | |
IOT_UNUSED(pData); | |
IOT_UNUSED(pClient); | |
IOT_INFO("Subscribe callback"); | |
IOT_INFO("%.*s\t%.*s", topicNameLen, topicName, (int) params->payloadLen, (char *) params->payload); | |
digitalWrite(25, HIGH); | |
sleep(5); | |
digitalWrite(25, LOW); | |
} | |
void disconnectCallbackHandler(AWS_IoT_Client *pClient, void *data) { | |
IOT_WARN("MQTT Disconnect"); | |
IoT_Error_t rc = FAILURE; | |
if(NULL == pClient) { | |
return; | |
} | |
IOT_UNUSED(data); | |
if(aws_iot_is_autoreconnect_enabled(pClient)) { | |
IOT_INFO("Auto Reconnect is enabled, Reconnecting attempt will start now"); | |
} else { | |
IOT_WARN("Auto Reconnect not enabled. Starting manual reconnect..."); | |
rc = aws_iot_mqtt_attempt_reconnect(pClient); | |
if(NETWORK_RECONNECTED == rc) { | |
IOT_WARN("Manual Reconnect Successful"); | |
} else { | |
IOT_WARN("Manual Reconnect Failed - %d", rc); | |
} | |
} | |
} | |
int main(int argc, char **argv) { | |
bool infinitePublishFlag = true; | |
char rootCA[PATH_MAX + 1]; | |
char clientCRT[PATH_MAX + 1]; | |
char clientKey[PATH_MAX + 1]; | |
char CurrentWD[PATH_MAX + 1]; | |
char cPayload[100]; | |
int32_t i = 0; | |
IoT_Error_t rc = FAILURE; | |
AWS_IoT_Client client; | |
IoT_Client_Init_Params mqttInitParams = iotClientInitParamsDefault; | |
IoT_Client_Connect_Params connectParams = iotClientConnectParamsDefault; | |
IOT_INFO("\nAWS IoT SDK Version %d.%d.%d-%s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG); | |
getcwd(CurrentWD, sizeof(CurrentWD)); | |
snprintf(rootCA, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_ROOT_CA_FILENAME); | |
snprintf(clientCRT, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_CERTIFICATE_FILENAME); | |
snprintf(clientKey, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_PRIVATE_KEY_FILENAME); | |
IOT_DEBUG("rootCA %s", rootCA); | |
IOT_DEBUG("clientCRT %s", clientCRT); | |
IOT_DEBUG("clientKey %s", clientKey); | |
mqttInitParams.enableAutoReconnect = false; // We enable this later below | |
mqttInitParams.pHostURL = HostAddress; | |
mqttInitParams.port = port; | |
mqttInitParams.pRootCALocation = rootCA; | |
mqttInitParams.pDeviceCertLocation = clientCRT; | |
mqttInitParams.pDevicePrivateKeyLocation = clientKey; | |
mqttInitParams.mqttCommandTimeout_ms = 20000; | |
mqttInitParams.tlsHandshakeTimeout_ms = 5000; | |
mqttInitParams.isSSLHostnameVerify = true; | |
mqttInitParams.disconnectHandler = disconnectCallbackHandler; | |
mqttInitParams.disconnectHandlerData = NULL; | |
rc = aws_iot_mqtt_init(&client, &mqttInitParams); | |
if(SUCCESS != rc) { | |
IOT_ERROR("aws_iot_mqtt_init returned error : %d ", rc); | |
return rc; | |
} | |
connectParams.keepAliveIntervalInSec = 600; | |
connectParams.isCleanSession = true; | |
connectParams.MQTTVersion = MQTT_3_1_1; | |
connectParams.pClientID = AWS_IOT_MQTT_CLIENT_ID; | |
connectParams.clientIDLen = (uint16_t) strlen(AWS_IOT_MQTT_CLIENT_ID); | |
connectParams.isWillMsgPresent = false; | |
IOT_INFO("Configuring the circuit ..."); | |
wiringPiSetup(); | |
pinMode(25, OUTPUT); | |
IOT_INFO("Connecting..."); | |
rc = aws_iot_mqtt_connect(&client, &connectParams); | |
if(SUCCESS != rc) { | |
IOT_ERROR("Error(%d) connecting to %s:%d", rc, mqttInitParams.pHostURL, mqttInitParams.port); | |
return rc; | |
} | |
/* | |
* Enable Auto Reconnect functionality. Minimum and Maximum time of Exponential backoff are set in aws_iot_config.h | |
* #AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL | |
* #AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL | |
*/ | |
rc = aws_iot_mqtt_autoreconnect_set_status(&client, true); | |
if(SUCCESS != rc) { | |
IOT_ERROR("Unable to set Auto Reconnect to true - %d", rc); | |
return rc; | |
} | |
IOT_INFO("Subscribing to 'garageDoor' ..."); | |
rc = aws_iot_mqtt_subscribe(&client, "garageDoor/+", 12, QOS0, iot_subscribe_callback_handler, NULL); | |
if(SUCCESS != rc) { | |
IOT_ERROR("Error subscribing : %d ", rc); | |
return rc; | |
} | |
while((NETWORK_ATTEMPTING_RECONNECT == rc || NETWORK_RECONNECTED == rc || SUCCESS == rc)) { | |
// Max time the yield function will wait for read messages | |
rc = aws_iot_mqtt_yield(&client, 100); | |
if(NETWORK_ATTEMPTING_RECONNECT == rc) { | |
// If the client is attempting to reconnect we will skip the rest of the loop. | |
continue; | |
} | |
sleep(1); | |
} | |
// Wait for all the messages to be received | |
aws_iot_mqtt_yield(&client, 100); | |
if(SUCCESS != rc) { | |
IOT_ERROR("An error occurred in the loop.\n"); | |
} else { | |
IOT_INFO("Publish done\n"); | |
} | |
return rc; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment