Things used in this project

Schematics

servo and relay connection to raspberry pi
raspberry pi servo connection.fzz
servo and relay connection to raspberry pi
Capture
sum it up
Untitled 1

Code

fishtank.pyPython
#!/usr/bin/python

import time;
import paho.mqtt.client as mqtt
import json, time, sys, ssl
import RPi.GPIO as GPIO  

lights = 13
feeder = 11


GPIO.setmode(GPIO.BOARD)

GPIO.setup(feeder, GPIO.OUT)
GPIO.setup(lights, GPIO.OUT)

#GPIO.output(feeder, GPIO.HIGH)
#GPIO.output(lights, GPIO.HIGH)


cert_path = "/home/pi/Desktop/certs/"
host = "ENDPOINT.amazonaws.com"
topic = "$aws/things/fishtank/shadow/update"
root_cert = cert_path + "rootCA.key"
cert_file = cert_path + "cert.pem.crt"
key_file = cert_path + "private.pem.key"

globalmessage = ""  # to send status back to MQTT
isConnected = False

def feedcommand(data):  #   {"name":"FeedIntent","slots":{"Task":{"name":"Task","value":"feed the fish"}}}
    task = str(data["slots"]["Task"]["value"])
    global globalmessage

    if task == "feed the fish":
        globalmessage = "now the fish is no longer hungry"
        print globalmessage
        toggle(feeder)

def lightscommand(data):  #   {"name":"LightsIntent","slots":{"Task":{"name":"Task","value":"on"}}}
    try:
        state = str(data["slots"]["state"]["value"])
        global globalmessage

        globalmessage = "Turning lights " + state
        print globalmessage

        if state == "on":
         GPIO.output(lights, GPIO.HIGH)
        elif state == "off":
         GPIO.output(lights, GPIO.LOW)      
    except (ValueError):
        print "lights Error"
    
def toggle(gpio):
	
	p =GPIO.PWM(11,50)
	p.start(12.5)
	count=0
	try:
		while count<=3:
			p.ChangeDutyCycle(12.5)
			time.sleep(1)
			p.ChangeDutyCycle(2.5)
			time.sleep(1)
			count+=1	
	except KeyboardInterrupt:
					
			p.stop()
			GPIO.cleanup()	
  #  GPIO.output(gpio, cmd)   call servo motor
        
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    isConnected = True
    # Subscribing in on_connect() means that if we lose the connection and      
    # reconnect then subscriptions will be renewed.    
    client.subscribe(topic)

# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    data = json.loads(str(msg.payload))
    # INTENT
    if "name" in data:
        if data["name"] == "FeedIntent":
            feedcommand(data)
        elif data["name"] == "LightsIntent":
            lightscommand(data)
        


client = mqtt.Client(client_id="fishtank.py")
client.on_connect = on_connect
client.on_message = on_message
client.on_log = on_log
client.tls_set(root_cert,
               certfile = cert_file,
               keyfile = key_file,
               cert_reqs=ssl.CERT_REQUIRED,
               tls_version=ssl.PROTOCOL_TLSv1_2,
               ciphers=None)

client.connect(host, 8883, 60)

run = True

try:
    while run:
        client.loop()
        time.sleep(1)

        try:
            mypayload = '''{
                "StatusMessage": "%s"
            }''' % (globalmessage)

            if globalmessage != "":
                client.publish(topic, mypayload)
                globalmessage = ""

        except (TypeError):
            pass
    
except KeyboardInterrupt:
    print "Bye Bye!"
    GPIO.cleanup()    
Intent SchemaJSON
{
   "intents":[
      {
         "intent":"FeedIntent",
         "slots":[
            {
               "name":"Task",
               "type":"LITERAL"
            }
         ]
      },
      {
         "intent":"LightsIntent",
         "slots":[
            {
               "name":"state",
               "type":"LITERAL"
            }
         ]
      }
   ]
}
Sample UtterancesJSON
FeedIntent {feed the fish | Task} 
LightsIntent turn lights {on|state} 
LightsIntent turn lights {off| state}
LightsIntent lights {on| state}
LightsIntent lights {off| state}
index.jsJavaScript
/**
 * Control your fish tank with your voice, using Amazon Alexa, Lambda, IOT, MQTT.
 */

var awsIot = require('aws-iot-device-sdk');

var host = "EndPOINT.amazonaws.com";
var topic = "$aws/things/fishtank/shadow/update";
var app_id = "YOUR APP ID"
var deviceName = "FishTank";

var mqtt_config = {
    "keyPath": "./certs/private.pem.key",
    "certPath": "./certs/cert.pem.crt",
    "caPath": "./certs/rootCA.key",
    "host": host,
    "port": 8883,
    "clientId": deviceName, 
    "region":"us-east-1",
    "debug":true
};

var ctx = null;
var client = null;

// Route the incoming request based on type (LaunchRequest, IntentRequest, etc.) The JSON body of the request is provided in the event parameter.
exports.handler = function (event, context) {
    try {
        console.log("event.session.application.applicationId=" + event.session.application.applicationId);
        ctx = context;

        if (event.session.application.applicationId !== app_id) {
             ctx.fail("Invalid Application ID");
         }

        client = awsIot.device(mqtt_config);

        client.on("connect",function(){
            console.log("Connected to AWS IoT");
        });


        if (event.session.new) {
            onSessionStarted({requestId: event.request.requestId}, event.session);
        }

        if (event.request.type === "LaunchRequest") {
            onLaunch(event.request, event.session);
        }  else if (event.request.type === "IntentRequest") {
            onIntent(event.request, event.session);
        } else if (event.request.type === "SessionEndedRequest") {
            onSessionEnded(event.request, event.session);
            ctx.succeed();
        }
    } catch (e) {
        console.log("EXCEPTION in handler:  " + e);
        ctx.fail("Exception: " + e);
    }
};

/**
 * Called when the session starts.
 */
function onSessionStarted(sessionStartedRequest, session) {
    console.log("onSessionStarted requestId=" + sessionStartedRequest.requestId + ", sessionId=" + session.sessionId);
}


/**
 * Called when the user launches the skill without specifying what they want.
 */
function onLaunch(launchRequest, session, callback) {
    console.log("onLaunch requestId=" + launchRequest.requestId + ", sessionId=" + session.sessionId);

    // Dispatch to your skill's launch.
    getWelcomeResponse(callback);
}

/**
 * Called when the user specifies an intent for this skill.
 */
function onIntent(intentRequest, session ) {
    console.log("onIntent requestId=" + intentRequest.requestId + ", sessionId=" + session.sessionId);

    var intent = intentRequest.intent,
    intentName = intentRequest.intent.name;

    console.log("REQUEST to string =" + JSON.stringify(intentRequest));

    var callback = null;
    // Dispatch to your skill's intent handlers
    if ("FeedIntent" === intentName) {
        feedIntent(intent, session);
    }
    else if ("LightsIntent" === intentName) {
        ligthsIntent(intent, session);
    } else {
        throw "Invalid intent";
    }

}

/**
 * Called when the user ends the session.
 * Is not called when the skill returns shouldEndSession=true.
 */
function onSessionEnded(sessionEndedRequest, session) {
    console.log("onSessionEnded requestId=" + sessionEndedRequest.requestId + ", sessionId=" + session.sessionId);
    // Add cleanup logic here
}

// --------------- Functions that control the skill's behavior -----------------------

function getWelcomeResponse() {
    // If we wanted to initialize the session to have some attributes we could add those here.
    var sessionAttributes = {};
    var cardTitle = "Welcome";
    var speechOutput = "Welcome to the Fish Tank.";

    var repromptText = "Fish Tank  is ready for command.";
    var shouldEndSession = false;

    ctx.succeed(buildResponse(sessionAttributes, buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession)));
}


function feedIntent(intent, session, callback) {
    var repromptText = null;
    var sessionAttributes = {};
    var shouldEndSession = true;
    var speechOutput = "";

    repromptText = "Tell me what to do with the fish tank.";

    var task = intent.slots.Task.value;
    var validTasks = [ "feed the fish"];

    if (validTasks.indexOf(task) == -1)
    {
        speechOutput = "I couldn't understand the command.  ";
        ctx.succeed(buildResponse(sessionAttributes, buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession)));
    }
    else
    {
        var cardTitle = "Feeding the Fish"  ;
        speechOutput = "Feeding the Fish" ;
        mqttPublish(intent, sessionAttributes, cardTitle, speechOutput, repromptText, shouldEndSession);
    }
}

function ligthsIntent(intent, session, callback) {

    var repromptText = null;
    var sessionAttributes = {};
    var shouldEndSession = false;
    var speechOutput = "";

    repromptText = "Tell me how you want the fish tank lights.  ";

    var state = intent.slots.state.value;
    var validstates = [ "on", "off" ];

    if (validstates.indexOf(state) == -1)
    {
        speechOutput = "I couldn't understand the state of the lights. ";
        ctx.succeed(buildResponse(sessionAttributes, buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession)));
    }
    else
    {
        var cardTitle = "fish tank lights turning " + state;
        speechOutput = "Turning lights " + state;
        mqttPublish(intent, sessionAttributes, cardTitle, speechOutput, repromptText, shouldEndSession);
    }
}

function mqttPublish(intent, sessionAttributes, cardTitle, speechOutput, repromptText, shouldEndSession)
{
    var strIntent = JSON.stringify(intent);
    console.log("mqttPublish:  INTENT text = " + strIntent);
    
    client.publish(topic, strIntent, function() {
        client.end();
    });
    
    client.on("close", (function () {
        console.log("MQTT CLIENT CLOSE - thinks it's done, successfully. ");
        ctx.succeed(buildResponse(sessionAttributes, buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession)));
    }));

    client.on("error", (function (err, granted) {
        console.log("MQTT CLIENT ERROR!!  " + err);
    }));
}


// --------------- Helpers that build all of the responses -----------------------

function buildSpeechletResponse(title, output, repromptText, shouldEndSession) {
    return {
        outputSpeech: {
            type: "PlainText",
            text: output
        },
        card: {
            type: "Simple",
            title: title,
            content: output
        },
        reprompt: {
            outputSpeech: {
                type: "PlainText",
                text: repromptText
            }
        },
        shouldEndSession: shouldEndSession
    }
}

function buildResponse(sessionAttributes, speechletResponse) {
    return {
        version: "1.0",
        sessionAttributes: sessionAttributes,
        response: speechletResponse
    }
}

Credits

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

Open Source, Connected Robot Arm
Advanced
  • 940
  • 11

Work in progress

hRobot is an open source, connected, 3D-printable robotic arm, powered by ROS, with 500g lift capacity

Add A Google Home Ligh Indicator for Voice Activated Google
Advanced
  • 449
  • 4

Full instructions

Give your Google Assistant in Google Home on Raspberry Pi a light indicator.

Run Commands on Your Computers With an Old Remote Control
Advanced
  • 335
  • 3

If you have an old remote control laying around, don't throw it away! You can use it to run commands on your computers over the Internet.

Wildlife Detector
Advanced
  • 1,221
  • 14

Device detects motion, then takes a picture of triggering wildlife. Uses a neural net to identify the wildlife species and does something.

Detecting Older Irrigation Lines
Advanced
  • 649
  • 6

Work in progress

Irrigation pipelines are everywhere and some irrigation lines are 30-40 old.People have no idea where the line is?so we can use this device.

Tracking TV Stand
Advanced
  • 894
  • 10

Full instructions

The Tracking TV Stand uses a Walabot to angle a monitor in the optimal angle for viewing depending on the audience in the field of view.

ProjectsCommunitiesTopicsContestsLiveAppsBetaFree StoreBlogAdd projectSign up / Login