当向 Alexa 发出语音命令时,在 Raspberry Pi 上运行命令/脚本。
我希望能够通过向我家里的 Alexa Dots 发出语音命令来在我的 Raspberry Pi 上运行命令。此外,我想通过 Alexa 安排任务,而不是必须将计划任务单独添加到我家里的几个 Pis。
为此,我们需要设置:
Alexa 技能指向 Lambda 函数,根据发出的语音命令取决于将什么消息添加到 SQS 队列,在 Rapsberry Pi 上运行脚本来检查 SQS 队列并根据消息启动作业或脚本树莓派。
AWS 和亚马逊开发账户
如果您还没有 AWS 帐户,则需要设置一个,没有理由认为该项目不属于 AWS“免费套餐”,该套餐允许每月向 Lambda 发出 100 万次免费请求,向 Lambda 发出 100 万次免费请求。 SQS 服务。为了超越免费套餐,您需要每 3 秒发出超过 1 个请求(基于每月 30 天),设置后我将脚本设置为每 15 秒运行一次,但当然如果我有 10 个 RPi 在做那么需要考虑的一个请求。
AWS - 创建用户和组
登录 AWS 并转到 IAM 管理控制台并添加用户:
https://console.aws.amazon.com/iam/home?#/users
由于权限是在组级别设置的,因此我们需要为该用户创建一个新组,如果我们将来创建更多用户,他们也可以使用同一组。该用户将从 Raspberry Pi 登录,因此需要能够查看和更新 AWS SQS 中的队列。
为此,我们可以使用亚马逊预定义策略(预设权限),搜索“sqs”并选择策略“AWSLambdaSQSQueueExecutionRole”,然后单击“创建组”(这将允许用户读取和写入 SQS 队列) .
这会将您带回“将用户添加到组”屏幕,并且将选择新组以将新用户添加到其中,单击“下一步:标签”按钮继续。
在“添加标签”屏幕上,只需单击“下一步:审阅”按钮继续。
在下一个屏幕上,查看新用户的详细信息并单击“创建用户”
在接下来的屏幕上,确保您“下载.csv”,因为这将是您获取此用户凭据的唯一机会。
CSV 中的凭据将添加到 RPi 上的脚本中,以便它可以登录以访问 SQS 队列。
注意:自 2019 年 6 月起,为了让 Alexa 技能运行 Lambda 函数,Lamda 代码必须托管在以下区域之一:
https://developer.amazon.com/docs/custom-skills/host-a-custom-skill-as-an-aws-lambda-function.html
由于我住在英格兰 (UK),我将在爱尔兰地区通过 SQS 队列和 Lambda 函数托管。
找到 SQS 页面并创建一个新的简单队列服务:
输入新名称并使用“快速创建队列”选项创建“标准队列”:
单击新队列并记下我们稍后需要的 ARN 和 URL:
在 AWS 中,在“服务”中搜索“Lambda”并创建一个新函数:
选择“从头开始创作”,添加名称并将“运行时”更改为“Python 2.7”。对于执行角色,选择“从 AWS 策略模板创建新角色”,选择“Amazon SQS 轮询器权限”策略,为角色命名并创建函数。
对于功能的配置,当您在“设计器”面板中单击某些内容时,配置设置将显示在屏幕的下半部分。
从左侧添加“Alexa Skills Kit”触发器,需要配置才能保存此功能。滚动到底部,因为我们还没有 Alexa 技能 ID(我们还没有创建技能)我们暂时“禁用”它,稍后再回来。
选择 Lambda 函数图标(对我来说是“RPi-LED-Function”),在底部我们需要提供自定义 Python 代码,此代码将向 Alexa 技能提供反馈并更新 SQS 队列。
我在下面的代码中添加了一些关于需要更改的注释。
import boto3
# Below you need to add in your access key, access secret, rgion and sqs queue url
access_key = "This can be found in the downloaded .csv file"
access_secret = "This can be found in the downloaded .csv file"
region ="eu-west-1"
queue_url = "This can be found when looking at the SQS queue, https://..."
# you should not need to change the following unless you know what your doing.
def build_speechlet_response(title, output, reprompt_text, should_end_session):
return {
'outputSpeech': {
'type': 'PlainText',
'text': output
},
'card': {
'type': 'Simple',
'title': "SessionSpeechlet - " + title,
'content': "SessionSpeechlet - " + 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 post_message(client, message_body, url):
response = client.send_message(QueueUrl = url, MessageBody= message_body)
def lambda_handler(event, context):
client = boto3.client('sqs', aws_access_key_id = access_key, aws_secret_access_key = access_secret, region_name = region)
intent_name = event['request']['intent']['name']
# The following needs to be customised
# The intent names shown below are linked with intents created in the custom Alexa Skill.
# The 'post_message' relates to the SQS queue
# The 'message' line is the message/response that Alexa will speak back to you
if intent_name == "LightsOn":
post_message(client, 'on', queue_url)
message = "Lounge Lights will now turn on"
elif intent_name == "LightsOff":
post_message(client, 'off', queue_url)
message = "Lounge Lights will now turn off"
elif intent_name == "LightsRed":
post_message(client, 'red', queue_url)
message = "Lounge Lights will change to red"
elif intent_name == "LightsGreen":
post_message(client, 'green', queue_url)
message = "Lounge Lights will now change to green"
elif intent_name == "LightsBlue":
post_message(client, 'blue', queue_url)
message = "Lounge Lights will now change to blue"
elif intent_name == "LightsTest":
post_message(client, 'test', queue_url)
message = "Lounge Lights will now run a test sequence"
else:
message = "Sorry but I do not understand that request"
speechlet = build_speechlet_response("Mirror Status", message, "", "true")
return build_response({}, speechlet)
0
在这里登录并创建一项新技能,选择“自定义”技能和“从头开始:”
https://developer.amazon.com/en-US/alexa/alexa-skills-kit
这里需要配置如下:
Invocation Name - 这是将用于触发技能的名称,我称我的为“lounge lights”。
意图、示例和槽- 对于这个示例,我保持简单并为每个操作创建了一个“意图”,如下所示,您还应该注意到这些意图反映了我在 Lambda 中添加的代码。
这是我的一个意图的例子,你当然可以根据你的要求添加任何你想要的:
所以,为了让这句话起作用,我会说“Alexa,让 Lounge Lights 关掉。”
构建模型- 完成上述操作后,保存并构建模型。
端点- 添加一个端点,这是我们已经创建的 Lambda 函数的 ARN。如果您在保存此端点时遇到任何错误,请确保已检查以下内容:
在 Alexa 技能界面中,单击“测试”选项卡,您可以在此处进行测试以确认 1) 您的意图是正确的,以及 2) lambda 函数已正确配置。测试完成后,您可以继续配置 Raspberry Pi 以从 SQS 队列中读取数据。
根据您的最终目标取决于您需要在 RPi 上做什么,我的第一个测试是打开/关闭我的 Magic Mirror 显示器,并且能够重新启动 RPi。
第二个是与这个项目 writeup 内联的,是能够打开 ws2811/ws2812 LED 灯带连接到我的 RPi。
需要运行以下代码,这将登录到 AWS 并查看 SQS 队列中的条目,并根据存储的消息取决于运行的本地 Python 脚本。要运行 LED,您需要将脚本作为“sudo”运行。
import boto3
import os
import time
access_key = "Access key from the csv file"
access_secret = "Access seret from the csv file"
region = "the region where the SQS queue is - found in the queue url"
queue_url = "SQS Queue URL, https://sqs....."
def pop_message(client, url):
response = client.receive_message(QueueUrl = url, MaxNumberOfMessages = 10)
#last message posted becomes messages
message = response['Messages'][0]['Body']
receipt = response['Messages'][0]['ReceiptHandle']
client.delete_message(QueueUrl = url, ReceiptHandle = receipt)
return message
client = boto3.client('sqs', aws_access_key_id = access_key, aws_secret_access_key = access_secret, region_name = nameOfTheRegion
waittime = 20
client.set_queue_attributes(QueueUrl = queue_url, Attributes = {'ReceiveMessageWaitTimeSeconds': str(waittime)})
time_start = time.time()
while (time.time() - time_start < 30):
print("Checking...")
try:
message = pop_message(client, queue_url)
print(message)
if message == "on":
os.system("python /home/pi/LEDScripts/LED_on.py")
elif message == "off":
os.system("python /home/pi/LEDScripts/LED_off.py")
elif message == "blue":
os.system("python /home/pi/LEDScripts/LED_blue.py")
elif message == "red":
os.system("python /home/pi/LEDScripts/LED_red.py")
elif message == "green":
os.system("python /home/pi/LEDScripts/LED_green.py")
elif message == "test":
os.system("python /home/pi/LEDScripts/LED_test.py")
except:
pass
您会在上面看到使用了包“boto3”(AWS SDK),您可以通过运行以下命令来安装它:
python -m pip install boto3
这是运行的 Python 脚本之一的示例:
from neopixel import *
# LED strip configuration:
LED_COUNT = 12 # Number of LED pixels.
LED_PIN = 19 # GPIO pin connected to the pixels (18 uses PWM!).
LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz)
LED_DMA = 10 # DMA channel to use for generating signal (try 10)
LED_BRIGHTNESS = 30 # Set to 0 for darkest and 255 for brightest
LED_INVERT = False # True to invert the signal
LED_CHANNEL = 1 # set to '1' for GPIOs 13, 19, 41, 45 or 53
strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
strip.begin()
for i in range(strip.numPixels()):
strip.setPixelColor(i, Color(0, 255, 0))
strip.show()
如果在可以运行不同的库之前你还没有运行它们,但是我选择使用这个:https ://github.com/jgarff/rpi_ws281x.git
您需要运行以下命令:
sudo apt-get install build-essential python-dev git scons swig
git clone https://github.com/jgarff/rpi_ws281x.git
然后从 GitHub 下载包中的“python”目录:
sudo python setup.py build
sudo python setup.py install
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !