Hackster is hosting Hackster Holidays, Ep. 7: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 7 on Friday!
Jack Jiang
Published © GPL3+

Restaurant Wait Timer Powered By AWS

Restaurants can use a simple IOT Button to let customers know what the current wait time is by checking their websites.

IntermediateFull instructions provided1,437
Restaurant Wait Timer Powered By AWS

Things used in this project

Story

Read more

Schematics

button breadboard schematic

edison mini breakout schematic

solder wires to vcc_1p8, gp165 and gnd and bring to the breadboard

Code

web page javascript

JavaScript
show the wait time to customers
<!DOCTYPE html> 
<html> 
    <body> 
        <div class="container"> 
         Current Wait Time is  <span id='time' style="font-size: 20px; font-weight: bold"></span> Minutes!!            
        </div> 
   </body> 

<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script> 
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.2.32.min.js"></script> 
    <!-- AWS SDK info from http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/index.html --> 
    <script> 
        $(document).ready(function() { 
        //this is read only user id
            AWS.config.update({ accessKeyId: 'xxxxx',  
                                secretAccessKey: 'xxxx' }); 

            AWS.config.region = 'us-west-2'; 
            var dynamodb = new AWS.DynamoDB(); 

            var params = {  TableName: 'waitTime', 
                            AttributesToGet: ['Wait'], 
                            Key : {Id : {N : '1' }} 
}; 

            dynamodb.getItem(params, function(err, data) { 
             if (err) { return console.log(err); } 
             console.log(data);      

             var s = data.Item.Wait.N; 
             $("#time").text(s); 
            }); 

            // Create auto update timer to run once a minute. 
            //var timer = window.setInterval(function() { 
            //    {                  
            //    } 
            //}, 5000); 
        }); 
    </script> 
</html> 

AWS Lambda Function

JavaScript
To process MQTT message and update DynamoDB
var doc = require('dynamodb-doc');
var dynamo = new doc.DynamoDB();

exports.handler = function(event, context) {
    console.log(event.localtime);
    console.log(event.delta);
    var dt = new Date(event.localtime);
    console.log(dt);
    var newdate = dt.getDate();
    
    var params = {};
    params.TableName = "waitTime";
    params.Key = {Id : 1};


    dynamo.getItem(params, function(err,d) {
    if (err)
    {
       console.log(err);
       context.fail(err);
    }
    else
    {
        var d2 = new Date(d.Item.LastUpdate);
        var olddate = d2.getDate();
        var w = parseInt(d.Item.Wait);
        console.log(w);
        
        if (newdate == olddate)
        {
            w = w + parseInt(event.delta);
        }
        else
        {
            w = event.delta;
        }
        if (w<0) 
        {
            w = 0;
        }
        params = {};
        params.TableName = "waitTime";
        
        console.log(w);

       params.Item = {Id : 1, LastUpdate : dt.toString(), Wait: w};
       dynamo.putItem(params, function(err,dat2) {
       if (err)
       {
       console.log(err);
       context.fail(err);
       }
       else
       {
           context.succeed('update ok');
       }
       });
        
    }
});

};

IOT Button Code

C/C++
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <memory.h>
#include <sys/time.h>
#include <limits.h>

#include "aws_iot_log.h"
#include "aws_iot_version.h"
#include "aws_iot_mqtt_interface.h"
#include "aws_iot_config.h"
#include "mraa.h"
#define N 10
#define step 5

static volatile int counter = 0;
static volatile int oldcounter = 0;
mraa_gpio_context x;

char certDirectory[PATH_MAX + 1] = "../../certs";
char HostAddress[255] = AWS_IOT_MQTT_HOST;
uint32_t port = AWS_IOT_MQTT_PORT;


send_iot_command(int delta) {
	IoT_Error_t rc = NONE_ERROR;
	int32_t i = 0;

	char rootCA[PATH_MAX + 1];
	char clientCRT[PATH_MAX + 1];
	char clientKey[PATH_MAX + 1];
	char CurrentWD[PATH_MAX + 1];
	char cafileName[] = AWS_IOT_ROOT_CA_FILENAME;
	char clientCRTName[] = AWS_IOT_CERTIFICATE_FILENAME;
	char clientKeyName[] = AWS_IOT_PRIVATE_KEY_FILENAME;
	char buffer [20];
  	time_t rawtime;
  	struct tm * timeinfo;

  	time (&rawtime);
 	timeinfo = localtime (&rawtime);
  	strftime(buffer,20,"%D",timeinfo);

	getcwd(CurrentWD, sizeof(CurrentWD));
	sprintf(rootCA, "%s/%s/%s", CurrentWD, certDirectory, cafileName);
	sprintf(clientCRT, "%s/%s/%s", CurrentWD, certDirectory, clientCRTName);
	sprintf(clientKey, "%s/%s/%s", CurrentWD, certDirectory, clientKeyName);

	MQTTConnectParams connectParams = MQTTConnectParamsDefault;

	connectParams.KeepAliveInterval_sec = 10;
	connectParams.isCleansession = true;
	connectParams.MQTTVersion = MQTT_3_1_1;
	connectParams.pClientID = "iot_button";
	connectParams.pHostURL = HostAddress;
	connectParams.port = port;
	connectParams.isWillMsgPresent = false;
	connectParams.pRootCALocation = rootCA;
	connectParams.pDeviceCertLocation = clientCRT;
	connectParams.pDevicePrivateKeyLocation = clientKey;
	connectParams.mqttCommandTimeout_ms = 2000;
	connectParams.tlsHandshakeTimeout_ms = 5000;
	connectParams.isSSLHostnameVerify = true;// ensure this is set to true for production
	rc = aws_iot_mqtt_connect(&connectParams);
	if (NONE_ERROR != rc) {
		ERROR("Error(%d) connecting to %s:%d", rc, connectParams.pHostURL, connectParams.port);
	}


	MQTTMessageParams Msg = MQTTMessageParamsDefault;
	Msg.qos = QOS_0;
	char cPayload[100];
	sprintf(cPayload, "{\"delta\":\"%d\", \"localtime\":\"%s\"}",delta, buffer);

	MQTTPublishParams Params = MQTTPublishParamsDefault;
	Params.pTopic = "topic/wait";
	Msg.pPayload = (void *) cPayload;
	Msg.PayloadLen = strlen(cPayload) + 1;
	Params.MessageParams = Msg;
	rc = aws_iot_mqtt_publish(&Params);
	rc = aws_iot_mqtt_disconnect();
	return rc;
}


void singleclick(void) {
    	printf("single click - increase wait time by %d minutes\n", step);
	send_iot_command(step);
}

void doubleclick() {
    printf("double click - decrease wait time by %d minutes\n", step);
    send_iot_command(-step);
}

int timer_running = 0; 
static volatile int ps[N]; 

void detectDoubleClick(void) {
    //looking for 1 ... 0 ..
    int i = 0;
//    for (i= 0; i<N; i++) printf("%d ", ps[i]);
//    printf("\n");
    int first1 = 0;
    while (ps[first1] ==0 && first1 < N )
    {
	first1++;
    }
    int anyzero = 1;
    for (i = first1; i<N; i++)
        anyzero = ps[i]*anyzero;
    if (anyzero == 0)
   	doubleclick();
    else
	singleclick();
}

void timer_handler(void) {
      ps[counter] = mraa_gpio_read(x);
      //printf("timer tick; gpio=%d\n", ps[counter]);
      ++counter;
      if (counter >= N )
      {
        stop_timer();
        timer_running = 0;
	counter=0;
 	detectDoubleClick();
      } 
}
void interrupt(void* args) {
    if (timer_running == 0)
    {
       //printf("isr - start timer\n");
       if(start_timer(50, &timer_handler))
       {
            printf("\n timer error\n");
            return;
       }
       timer_running = 1;
    }
}


int main() {
    mraa_init(); // mraa_gpio_context x;
    x = mraa_gpio_init(15);
    if (x == NULL) {
        return 1;
    }
    mraa_gpio_dir(x, MRAA_GPIO_IN);
    mraa_gpio_edge_t edge = MRAA_GPIO_EDGE_RISING;
	//BOTH, FALLING, or RISING
    mraa_gpio_isr(x, edge, &interrupt, NULL);
    for (;;) {
        if (counter != oldcounter) {
            //fprintf(stdout, "timeout counter == %d\n", counter);
	    oldcounter = counter;
        }
        sleep(1);
    }
    mraa_gpio_close(x);
    return MRAA_SUCCESS;
}

iot button to update wait time

Credits

Jack Jiang
1 project • 2 followers
chip designer; hardware designer; software design.

Comments