Joel Urtubia Ugarte
Created February 24, 2018 © GPL3+

Alexa + home energy efficiency + big data

This project is based on a network sensor for weight the house's energy efficiency and send it to Splunk and also read data with Alexa.

IntermediateFull instructions provided20 hours149
Alexa + home energy efficiency + big data

Things used in this project

Hardware components

DHT11 Temperature & Humidity Sensor (4 pins)
DHT11 Temperature & Humidity Sensor (4 pins)
×1
Arduino UNO
Arduino UNO
×1
Arduino Ethernet shield
×1
Arduino Co2
×1

Software apps and online services

splunk
splunk sdk python
Flask-Ask
Amazon Alexa service
IFTTT Amazon Alexa service

Story

Read more

Schematics

Sensor

Diagram ... how is working?

How is working

Splunk Dashboard

Dashboard Splunk

Code

SDK Splunk

Python
SDK for get all data from Splunk software
#!/usr/local/bin/python2.7
import sys
from time import sleep
import splunklib.results as results
import splunklib.client as client
service = client.connect(host='localhost', port=8089,
                   username='admin', password='telsur')
#assert isinstance(service, client.Service)
searchquery_normal = "search * | head 1"
kwargs_normalsearch = {"exec_mode": "blocking"}
job = service.jobs.create(searchquery_normal, **kwargs_normalsearch)

# A normal search returns the job's SID right away, so we need to poll for completion
while True:
    while not job.is_ready():
        pass
    stats = {"isDone": job["isDone"],
             "doneProgress": float(job["doneProgress"])*100,
              "scanCount": int(job["scanCount"]),
              "eventCount": int(job["eventCount"]),
              "resultCount": int(job["resultCount"])}

    status = ("\r%(doneProgress)03.1f%%   %(scanCount)d scanned   "
              "%(eventCount)d matched   %(resultCount)d results") % stats

    #sys.stdout.write(status)
    #sys.stdout.flush()
    if stats["isDone"] == "1":
        #sys.stdout.write("\n\nDone!\n\n")
        break
    sleep(2)

# Get the results and display them
for result in results.ResultsReader(job.results()):
	results = result['_raw']
	data = results.split() 
	findValues = data[7].split('7c') 
	temp = findValues[1].decode("hex")
	#print temp
	print(temp)
	
job.cancel()   
#sys.stdout.write('\n')

Yaml for Flask ASK

YAML
YAML used by Flask ASk
welcome: |
    Welcome to the Alexa Skills Kit sample. Please tell what do you need by
    saying, give me a report of valdivia

send_report: |
    I now know that you need a report of {{ city }}. let me check it
    
welcome_reprompt: Please tell me your favorite city by saying, my favorite city is red

known_city: |
    I now know that your favorite city is {{ city }}. You can ask me your favorite city
    by saying, what's my favorite city?

known_city_reprompt: You can ask me your favorite city by saying, what's my favorite city?

known_temp: |
    the temperature in {{ city }} is {{ temp }} degrees celsius. do you need other information?
    
#all_temp_report
all_temp_report: |  
    {% for row in DataAll %}
        the temperature in {{ row[1] }} is {{ row[2] }} degrees celsius.
        the Co2 in {{ row[1] }} is {{ row[3] }} data.
        the humidity in {{ row[1] }} is {{ row[4] }} data.
        report at {{ row[5] }}.
    {% endfor %}
    this is all resume, do you need other information?
all_temp_report_splunk: |
        the temperature in Valdivia detected by Arduino is {{ DataAll[0] }} degrees celsius.
        the Co2 is {{ DataAll[1] }} percent.
        the humidity is {{ DataAll[2] }} percent.
        the heat index is {{ DataAll[3] }} percent.
        this is all resume, do you need other information?
    
known_temp_reprompt: You can ask me your favorite color by saying, what's my favorite color?

known_city_bye: Your favorite city is {{ city }}. Goodbye

unknown_city: I'm not sure what your favorite city is, please try again

unknown_city_reprompt: |
    I'm not sure what your favorite city is. You can tell me your favorite city by saying,
    my favorite city is red
card_title: Session    
round: Can you give me the number?

win: Good job Joel, have you found the key!

lose: Sorry, that's the wrong answer.

Arduino Code Sensor

Arduino
this is the Arduino code for upload the information each 5 seconds
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>


#include <DHT.h>
 
// Definimos el pin digital donde se conecta el sensor
#define DHTPIN 7
// Dependiendo del tipo de sensor
#define DHTTYPE DHT11
 
// Inicializamos el sensor DHT11
DHT dht(DHTPIN, DHTTYPE);

 
// ------------------------------------------------------------------
// Configuration
 
// The mac address is the physical address associated with the
// Ethernet port on the your device. It should be globally unique if
// the board is connected to a public network, or at least locally
// unique if the board is connected to a private network.
byte MacAddress[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
 
// The IP address is the internet protocol address for the board. Again
// it should be globally unique if connected to a public network or
// locally unique if connected to a private network. To communicate
// successfully, it should also be on the same sub-net as your PC.
// In practice that means the first three numbers should be the same
// as your PC's IP address. And the last number should be different to
// all devices on your network. Use ipconfig to find out your PC's IP address
IPAddress MyIPAddress(192, 168, 5, 97);
unsigned int LocalPort = 8888;
 
 
// The destination address is the IP address of the computer you want to send
// messages to. It would normally be on the same sub-net as the Arduino. In practice
// this means the first three numbers of MyIPAddress and DestinationAddress should
// be the same.
IPAddress DestinationAddress(192, 168, 5, 210);
unsigned int DestinationPort = 8888;
 
// ------------------------------------------------------------------
// Communications
EthernetUDP Udp; // To send & receive packets using UDP
 
char PacketBuffer[UDP_TX_PACKET_MAX_SIZE]; // Space to hold messages we receive.
 
unsigned long LastSend = 0; // Last time we sent a message
const long SendPeriod = 5000; // Time between sending messages [milliseconds]
 
// ------------------------------------------------------------------
// Data
bool EnableADCSend[] = { true, false, false, false, false, false, false, false };


// Functions
void ProcessUDPTraffic()
{
  // See if there is any data available and read it. 
  int nPacketSize = Udp.parsePacket();
  if (nPacketSize > 0)
  {
    int nRead = Udp.read(PacketBuffer, sizeof(PacketBuffer));
    if (nRead >= 1)
    {
      int nPort = PacketBuffer[0] - '0';
      if (nPort >= 0 && nPort < sizeof(EnableADCSend))
      {
        // Toggle sending data from the specified port. 
        EnableADCSend[nPort] = !EnableADCSend[nPort];
        
        Serial.print("Sending adc data for channel ");
        Serial.print(nPort);
        Serial.print(" is ");
        Serial.println(EnableADCSend[nPort] ? "on" : "off");
      }
    }
  } 
}

void SendADCData()
{
  if (millis() - LastSend < SendPeriod)
    return;
  
  LastSend = millis();
  
  for(int iPort = 0; iPort < sizeof(EnableADCSend); ++iPort)
  {
    if (EnableADCSend[iPort])
    {
		int Co2 = analogRead(iPort);

		// Leemos la humedad relativa
		int h = dht.readHumidity();
		// Leemos la temperatura en grados centígrados (por defecto)
		int t = dht.readTemperature();
		// Leemos la temperatura en grados Fahreheit
		float f = dht.readTemperature(true);

		// Comprobamos si ha habido algún error en la lectura
		if (isnan(h) || isnan(t) || isnan(f)) {
			Serial.println("Error obteniendo los datos del sensor DHT11");
			return;
		}


		// Calcular el índice de calor en Fahreheit
		float hif = dht.computeHeatIndex(f, h);
		// Calcular el índice de calor en grados centígrados
		float hic = dht.computeHeatIndex(t, h, false);
	
      Udp.beginPacket(DestinationAddress, DestinationPort);
      Udp.print("Temp:|");
      Udp.print(t);
      Udp.print("|Humedad:|");
      Udp.print(h);
      Udp.print("|Co2:|");
      Udp.print(Co2);
      Udp.print("|IndiceCalor:|");
      Udp.print(hic);	
      Udp.println('|');
      Udp.endPacket();
    }
  }
}
 
 
// ------------------------------------------------------------------
// Setup
void setup()
{

	
  // Start ethernet and udp
  Ethernet.begin(MacAddress, MyIPAddress);
  Udp.begin(LocalPort);
  
  // Start RS232 comms
  Serial.begin(9600);
  dht.begin();  
}
 
// ------------------------------------------------------------------
// Loop
void loop()
{
  //ProcessUDPTraffic();
  SendADCData();
}

Execute Bash SDK for python 3.4

BatchFile
Link SDK for use in Python 3.4 version
#!/bin/bash 
# Descripcion: Script para capturar informacion
/usr/local/bin/python2.7 /opt/splunk/bin/scripts/sdk.py

Flask ASK for Alexa

Python
Web Service for Amazon Echo
import logging
import mysql.connector
import subprocess
from subprocess import Popen, PIPE

from random import randint

from flask import Flask, render_template

from flask_ask import Ask, statement, question, session


app = Flask(__name__)

ask = Ask(app, "/")

logging.getLogger("flask_ask").setLevel(logging.DEBUG)


def connectDB(city):

		conn = mysql.connector.connect(
				 user='root',
				 password='telsur',
				 host='127.0.0.1',
				 database='alexa')

		cur = conn.cursor()

		query = ("SELECT * FROM dataArduino where city ='%s'") % (city)

		cur.execute(query)

		# fetch all of the rows from the query
		data = cur.fetchall ()

		# print the rows
		for row in data :
			temp = row[2]

		cur.close()
		conn.close()

		return temp

def connectDBAll():

		conn = mysql.connector.connect(
				 user='root',
				 password='telsur',
				 host='127.0.0.1',
				 database='alexa')

		cur = conn.cursor()

		query = ("SELECT * FROM dataArduino") 

		cur.execute(query)

		# fetch all of the rows from the query
		data = cur.fetchall ()

		cur.close()
		conn.close()

		return data		

def connectSplunk():

	s = Popen(['/opt/splunk/bin/scripts/shellScript.sh'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
	input = 'España'
	output, errs = s.communicate(input.encode())
	output, errs = output.decode(), errs.decode()
	output = output.replace("\n", " ")
	return output
		
		
CITY_KEY = "CITY"


@ask.launch

def new_game():

    welcome_msg = render_template('welcome')

    return question(welcome_msg)


@ask.intent('MyCityIsIntent', mapping={'city': 'City'})
def my_city_is(city):
	card_title = render_template('card_title')
	if city is not None:
		session.attributes[CITY_KEY] = city
		temp = connectDB(city)
		question_text = render_template('known_temp',city=city, temp=temp)
		reprompt_text = render_template('known_temp_reprompt')
	else:
		question_text = render_template('unknown_city')
		reprompt_text = render_template('unknown_city_reprompt')
	return question(question_text).reprompt(reprompt_text).simple_card(card_title, question_text)
	
'''
@ask.intent("YesIntent")

def YesIntent():

	#winning_numbers = session.attributes['numbers']
	DataAll = connectDBAll()
	question_text = render_template('all_temp_report',DataAll=DataAll)
	# print the rows
	return statement(question_text)
'''	
@ask.intent("YesIntent")

def YesIntent():

	#winning_numbers = session.attributes['numbers']
	DataAll = connectSplunk()
	DataAll = DataAll.replace("[", "")
	DataAll = DataAll.replace("]", "")
	DataAll = DataAll.replace(" ' ", "")
	DataAll = DataAll.split(",")
	question_text = render_template('all_temp_report_splunk',DataAll=DataAll)
	# print the rows
	return statement(question_text)
	
@ask.intent('WhatsMyColorIntent')
def whats_my_color():
    card_title = render_template('card_title')
    color = session.attributes.get(COLOR_KEY)
    if color is not None:
        statement_text = render_template('known_color_bye', color=color)
        return statement(statement_text).simple_card(card_title, statement_text)
    else:
        question_text = render_template('unknown_color_reprompt')
        return question(question_text).reprompt(question_text).simple_card(card_title, question_text)	

@ask.intent("AnswerIntent" , convert={'first': int})

def answer(first):

    #winning_numbers = session.attributes['numbers']

    if first == 2:

        msg = render_template('win')

    else:

        msg = render_template('lose')

    return statement(msg)



	
if __name__ == '__main__':

    app.run(debug=True)

Interaction code Alexa

ActionScript
{
  "intents": [
    {
      "slots": [
        {
          "name": "City",
          "type": "LIST_OF_CITY"
        },
        {
          "name": "temp",
          "type": "AMAZON.NUMBER"
        }
      ],
      "intent": "MyCityIsIntent"
    },
    {
      "intent": "WhatsMyCityIntent"
    },
    {
      "intent": "YesIntent"
    }
  ]
}

Credits

Joel Urtubia Ugarte

Joel Urtubia Ugarte

3 projects • 3 followers
I'm electronic engineer, apassionated for developer things that can make easy to people live.

Comments