I always wanted to automate my home stuff, since I watched Iron Man specially my set top box. Dth operators always keep on changing channel numbers and it is very hard to remember channel numbers.
What Room Service can do right now?1. Room Service can Turn ON/OFF your TV, AC, DTH Box, etc.
2. Room Service can Increase/Decrease Volume of your DTH/TV.
3. Room Service automatically finds a preferred channel for you when you say like - "play music", "play news", "play movies" etc.
4. Room Service can play any channel you want to play, just say like - "change channel to 501 on tata sky"
5. Room Service will automatically finds channel number for you, just say like - "play SONY TV on my tata sky"
Future ScopeRoom Service is designed to extend the skill to any appliance irrespective of the manufacturer. This enables us to automate each and every device (not just IR) in the room.
TutorialFollow these steps can you can build one in no time, you need to have an Amazon Developer Account, AWS Account and Firebase account.
Step1 - Create a Login with Amazon Security Profile.
- Visit here
- Click on "CreateaNewSecurityProfile"
- Fill this form
- Fill this form on WebSettings tab.
- Note down your SecretCredentials,neversharetheminpublic.
Step2-Create Interaction Model
- Visit here
- Click on CreateSkill and follow your instructions, I am using English (India) for skill language.
- Choose a InvocationName
- Click on JSONEditor
- Copy and Paste the following code
Please note that the following code is under licence agreement found here
Make sure you replace {your invocation name here}
The following code is just a sample code and only performs certain features, the complete code for Alexa-Room-Service is available in a private github repo and can be accessed on demand.
{
"languageModel": {
"invocationName": "{your invocation name}",
"intents": [
{
"name": "AMAZON.CancelIntent",
"slots": [],
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"slots": [],
"samples": []
},
{
"name": "AMAZON.StopIntent",
"slots": [],
"samples": []
},
{
"name": "CategoryIntent",
"slots": [
{
"name": "DthDevice",
"type": "DthDevice"
},
{
"name": "Category",
"type": "Category"
},
{
"name": "Language",
"type": "Language"
}
],
"samples": [
"Play {Category} on my {DthDevice}",
"Play some {Category} on my {DthDevice}",
"Please Play {Category} on my {DthDevice}",
"Please Play some {Category} on my {DthDevice}",
"Play a {Category} on my {DthDevice}",
"Please Play a {Category} channel on my {DthDevice}",
"Play a {Category} channel on my {DthDevice}",
"Play {Language} {Category} on my {DthDevice}",
"Play some {Language} {Category} on my {DthDevice}",
"Please Play {Language} {Category} on my {DthDevice}",
"Please Play some {Language} {Category} on my {DthDevice}",
"Play a {Language} {Category} on my {DthDevice}",
"Please Play a {Language} {Category} channel on my {DthDevice}",
"Play a {Language} {Category} channel on my {DthDevice}"
]
}
],
"types": [
{
"name": "Category",
"values": [
{
"id": "",
"name": {
"value": "Knowledge & Kids",
"synonyms": [
"Kids",
"Cartoon",
"Anime",
"Knowledge",
"Educational",
"Baby"
]
}
},
{
"id": "",
"name": {
"value": "Music",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "Regional",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "HD",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "Movies",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "Entertainment",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "Sports",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "News",
"synonyms": []
}
}
]
},
{
"name": "DthDevice",
"values": [
{
"id": "",
"name": {
"value": "tata sky",
"synonyms": []
}
}
]
},
{
"name": "Language",
"values": [
{
"id": "",
"name": {
"value": "Hindi",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "English",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "Tamil",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "Telugu",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "Marathi",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "Kannada",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "Bengali",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "Malayalam",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "Gujarati",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "Punjabi",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "Odia",
"synonyms": []
}
},
{
"id": "",
"name": {
"value": "Regional",
"synonyms": []
}
}
]
}
]
}
}
- Visit here
- Click on Sign in to the Console.
- Click on Lambda
- Click Create New Function
- Fill the details as per below
- Click on Alexa Skills Kit
- Copy ARN
- Paste here
- Fill this form with your Security Profile (Step 1)
- Prepare the zip.
/* Download and save this code as firebase.py
https://gist.github.com/madhurgupta10/62cb8caafd30f56833bbe66726e5a8ce
*/
// Don't forget to install other required packages.
/* Please refer AWS docs for deployment packages -
https://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html
*/
Please note that the following code is under licence agreement foundhere
You need to replace {your firebase url} (STEP 3)
The following code is just a sample code and only performs certain features, the complete code for Alexa-Room-Service is available in a private github repo and can be accessed on demand.
#!/usr/bin/python
# -*- coding: utf-8 -*-
# you need to install these libraries, firebase.py is included in the repo
import firebase
import requests
import json
##################################################################################
# Initialize this with your own firebase, url for example - "room-service-abc123"#
firebase_base_url = '{your firebase url}'
##################################################################################
# You can extend these dicts by any choice of device you want, just remember to add the appropriate HEXCODE for your model
dth_device_channel_dict = {'0': 'C00000', '1': 'C00001', '2': 'C00002',
'3': 'C00003', '4': 'C00004', '5': 'C00005', '6': 'C00006', '7': 'C00007', '8': 'C00008', '9': 'C00009'}
# Writing data to firebase
def add_to_firebase(
user,
task,
status
):
firebase.put(firebase_base_url+"/users/"+user, {'task': { 'status': status, 'taskid': task } })
# Reading data from firebase
def get_firebase_data(user, task):
result = firebase.get('/users')
return result
# Tata sky api to fetch channel numbers by category
def call_tatasky_by_category(user_category, user_language):
response = \
requests.get('http://mobileapp.tatasky.com/hma/api/1.0a/epg/1/genres.json'
)
result = json.loads(response.text)
for categories in result:
for channels in categories['l']:
category = categories['n']
if category == user_category:
for channel in channels['m']:
language = channels['e']
if language == user_language or language == '':
d = str(channel['c'])
return [d]
return [str(100)]
def build_speechlet_response(
title,
output,
reprompt_text,
should_end_session,
):
return {
'outputSpeech': {'type': 'PlainText', 'text': output},
'card': {'type': 'Simple', 'title': 'Room Service',
'content': output},
'reprompt': {'outputSpeech': {'type': 'PlainText',
'text': reprompt_text}},
'shouldEndSession': should_end_session,
}
def build_response(session_attributes, speechlet_response):
return {'version': '1.0', 'sessionAttributes': session_attributes,
'response': speechlet_response}
def get_user_info(access_token):
amazonProfileURL = \
'https://api.amazon.com/user/profile?access_token='
r = requests.get(url=amazonProfileURL + access_token)
if r.status_code == 200:
return r.json()
else:
return False
def handle_end():
return build_response({}, build_speechlet_response('Session ended',
'Goodbye!', '', True))
def launch_request(access_token):
session_attributes = {}
card_title = 'Welcome'
if access_token is None:
speech_output = \
'Your user details are not available at this time. Have you completed account linking via the Alexa app?'
reprompt_text = 'Please link your account in the Alexa app'
should_end_session = True
else:
user_details = get_user_info(access_token)
if user_details is None:
speech_output = \
'There was a problem getting your user details.'
should_end_sesion = True
else:
# Add user info to firebase
firebase.put(firebase_base_url + "/users/" + user_details['user_id'].split('.')[2],
{'task': {'status': False, 'taskid': ['']}})
speech_output = 'Hello ' + user_details['name'].split(' '
)[0] + '! How can I help you?'
reprompt_text = 'What can I do, turn on your TV or AC?'
should_end_session = False
return build_response(session_attributes,
build_speechlet_response(card_title,
speech_output, reprompt_text,
should_end_session))
def intent_request(intent_request, access_token):
intent = intent_request['intent']
intent_name = intent['name']
# CATEGORY INTENT
if intent_name == 'CategoryIntent':
if access_token is not None:
user_details = get_user_info(access_token)
if user_details is None:
device_type = False
category = False
language = False
api_function = False
else:
try:
device_type = intent['slots']['DthDevice'
]['resolutions']['resolutionsPerAuthority'
][0]['values'][0]['value']['name']
category = intent['slots']['Category']['resolutions'
]['resolutionsPerAuthority'][0]['values'
][0]['value']['name']
try:
language = intent['slots']['Language'
]['resolutions'
]['resolutionsPerAuthority'
][0]['values'][0]['value']['name']
# This api_funtion can be changed to your prefered dth operator, but we stick to tata sky, due to api limitations
api_function = \
call_tatasky_by_category(category, language)
except:
language = "Hindi"
# This api_funtion can be changed to your prefered dth operator, but we stick to tata sky, due to api limitations
api_function = \
call_tatasky_by_category(category, language)
except:
device_type = False
category = False
language = False
api_function = False
else:
return handle_end()
if device_type == False or category == False or language \
== False or api_function == False:
speech_output = \
'Sorry, I was not able to process that command, please give me clear instructions, I am not a human after all'
card_title = speech_output
reprompt_text = 'What can I do, turn on your TV or AC?'
should_end_session = False
return build_response({},
build_speechlet_response(card_title,
speech_output, reprompt_text, should_end_session))
else:
# We are checking just for tata sky due to api limitations, but this can be extended in future by creating a dict of all dth operators
if device_type == 'tata sky':
if category != False:
channel_list = list(api_function[0])
task = list()
for x in channel_list:
task.append(dth_device_channel_dict[x])
status = True
# Add task to firebase
add_to_firebase(user_details['user_id'].split('.')[
2], task, status)
speech_output = 'Ok changing channel to ' \
+ api_function[0] + ". Anything else?"
else:
speech_output = \
'Sorry, I can only change channel for tatasky right now'
card_title = speech_output
reprompt_text = 'What can I do, turn on your TV or AC?'
should_end_session = False
return build_response({},
build_speechlet_response(card_title,
speech_output, reprompt_text, should_end_session))
# HELP INTENT
if intent_name == 'AMAZON.HelpIntent':
card_title = \
'Try saying like - Alexa, play STAR PLUS on my tata sky'
speech_output = \
'Try saying like - Alexa, play STAR PLUS on my tata sky'
should_end_session = False
reprompt_text = 'Try saying like - Alexa, play STAR PLUS on my tata sky'
return build_response({}, build_speechlet_response(card_title,
speech_output, should_end_session, should_end_session))
# CANCEL AND STOP INTENTS
if intent_name == 'AMAZON.CancelIntent' or intent_name \
== 'AMAZON.StopIntent':
card_title = 'Session Ended'
speech_output = 'Thank you for using room service. Good bye!'
return build_response({}, build_speechlet_response(card_title,
speech_output, None, True))
def lambda_handler(event, context):
try:
access_token = event['context']['System']['user']['accessToken']
except:
access_token = None
if event['request']['type'] == 'LaunchRequest':
return launch_request(access_token)
elif event['request']['type'] == 'IntentRequest':
return intent_request(event['request'], access_token)
The above code might have some issues due to indentation problem in code editor. You can get the code from this gist - https://gist.github.com/madhurgupta10/1cd902e311b211dc56a948217499c866
- Upload the zip
Step3-Firebase
- Visit here
- Click on Go To Console
- Add new Project
- Change rules (for personal use only, don't share your firebase url)
{
"rules": {
".read": true,
".write": true
}
}
Step 4 - Decode your remote
- Connect your IR Receiver to Arduino on the following pins
/*
GND -> GND ARDUINO
Vs -> 5v Arduino
OUT -> Pin 4 Arduino
*/
Refer the diagram of TSOP
- Deploy the code on Arduino and open Serial Monitor
/*
IR Receiver Demonstration 1
IR-Rcv-Demo1.ino
Demonstrates IR codes with IR Receiver
Displays results on Serial Monitor
DroneBot Workshop 2017
http://dronebotworkshop.com
*/
// Include IR Remote Library by Ken Shirriff
#include <IRremote.h>
// Define sensor pin
const int RECV_PIN = 4;
// Define IR Receiver and Results Objects
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup(){
// Serial Monitor @ 9600 baud
Serial.begin(9600);
// Enable the IR Receiver
irrecv.enableIRIn();
}
void loop(){
if (irrecv.decode(&results)){
// Print Code in HEX
Serial.println(results.value, HEX);
irrecv.resume();
}
}
- Note down IR Code for each button
Step 5-Prepare the Raspberry Pi and Arduino
- Run the following code on Raspberry Pi
import serial
import firebase
URL = "{your firebase url}"
#By Default The Code saves Amazon User Id but you are free to choose any primary key
user = "{your amazon user id or whatever you used to save into firebase}"
ser = serial.Serial('/dev/ttyACM0', 9600)
result = firebase.get(URL + "/users/"+user)
if (result['task']['status'] == True):
try:
for tasks in result['task']['taskid']:
ser.write(tasks)
firebase.put(URL + "/users/" + user, {'task': {'status': False, 'taskid':[]}})
except:
pass
- Run the following code to Arduino
#include <IRremote.h>
IRsend irsend;
void setup(){
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop(){
if (Serial.available()) {
light(Serial.read() – ‘0’);
}
delay(500);
}
void light(int n){
irsend.sendNEC(n, 32);
}
- Connect Arduino and Raspberry Pi via Serial USB Cable
- Connect IRLED to the following pins on Arduino via Resistor
/*
GND -> GND Arduino
+VE -> PIN 3 Arduino via Resistor
*/
Comments