24、物联网设备的第三方集成与智能风扇开发

物联网设备的第三方集成与智能风扇开发

在物联网的世界里,设备与第三方服务的集成能够极大地提升产品的功能和价值。本文将详细介绍如何将ESP32设备与亚马逊AVS以及IFTTT服务进行集成,最后还会探讨如何开发一个语音控制的智能风扇。

1. 与亚马逊AVS集成及故障排除

与亚马逊AVS集成需要完成多个步骤,当完成整个开发周期后,如果要将技能分享给用户,就需要通过Alexa认证流程。具体认证方法可参考 Alexa文档

在集成过程中,很容易因为遗漏某个步骤而导致问题。以下是一些故障排除的建议:
- 遵循步骤顺序 :如果没有AWS云开发经验,务必严格按照文档中的步骤顺序进行操作。当有一个可运行的示例后,再尝试其他配置选项。
- 准确复制文本 :过程中有很多复制粘贴操作,确保复制的是准确的文本,不包含多余的空格或其他前后字符。
- 正确输入参数 :在UI表单中输入参数时,要确保输入正确的值。AWS和Alexa控制台在操作或配置后会提供反馈,但输入错误的值可能难以定位问题。
- 测试Lambda函数 :Lambda函数的测试相对容易,可以在Web UI上查看测试运行的即时输出,也可以查看CloudWatch日志。Lambda函数的完整代码可在GitHub仓库中找到,如果不熟悉Python开发,可直接使用提供的代码。
- 下载加密密钥文件 :创建设备时,要下载加密密钥文件,并在ESP32应用中使用相同的密钥,否则ESP32无法连接到AWS云。如果ESP32无法更新设备影子,可以修改应用代码添加更多日志消息,并在串口控制台查看。
- 检查设备发现问题 :如果设备发现失败,检查CloudWatch日志。如果日志中没有信息,可以尝试不同的AWS区域来托管Lambda函数,更多关于AWS区域的信息可参考 此处

2. 使用IFTTT定义规则

IFTTT是一个适用于各种应用(包括物联网项目)的在线规则引擎。在这个例子中,我们将创建一个IFTTT的Webhook,让ESP32设备发布温度读数,IFTTT服务将这些读数记录在Google表格中。

2.1 准备规则

以下是准备规则的步骤:
1. 如果没有Google账户,先创建一个,然后访问 Google Drive
2. 在Google Drive上创建一个名为 ifttt 的新文件夹,并在其中创建一个名为 temperature_log 的电子表格。
3. 访问 IFTTT 并登录,然后导航到 创建新applet 。在免费计划中,最多可以创建三个applet。
4. 点击 If This 添加触发器,在下一页搜索 webhook ,并将触发器设置为 Receive a web request
5. 在配置页面,将事件名称写为 temperature_received ,然后点击 Create trigger 按钮。
6. 点击 Then That 添加动作,选择 Google Sheets 作为服务, Add row to spreadsheet 作为动作。
7. 在动作配置页面,提供以下信息并点击 Create action
- 电子表格名称: temperature_log
- 格式化行: {{OccurredAt}} ||| {{Value1}}
- 驱动器文件夹路径: ifttt
8. 设置applet标题为 If temperature_received, then log ,然后点击 Finish 按钮完成配置。
9. 访问 IFTTT Webhook文档 ,点击 Documentation 按钮,记录下Webhook密钥,开发固件时会用到。
10. 在开发固件之前,使用 curl 工具测试applet,确保一切配置正确:

$ curl -X POST -H "Content-Type: application/json" -d '{"value1":"0"}' https://maker.ifttt.com/trigger/temperature_received/with/key/<your_key>
2.2 开发固件

在固件中,我们将从DHT11传感器读取温度数据,并向IFTTT端点发送POST请求。以下是创建新PlatformIO项目的步骤:
1. 创建一个新项目,使用以下 platformio.ini 文件:

[env:az-delivery-devkit-v4]
platform = espressif32
board = az-delivery-devkit-v4
framework = espidf
monitor_speed = 115200
lib_extra_dirs = 
    ../../common/esp-idf-lib/components
    ../common
build_flags =
    -DWIFI_SSID=${sysenv.WIFI_SSID}
    -DWIFI_PASS=${sysenv.WIFI_PASS}
    -DIFTTT_KEY=${sysenv.IFTTT_KEY}
board_build.embed_txtfiles = 
    src/server_cert.pem
  1. 下载IFTTT服务器证书并保存到 src/server_cert.pem 文件中:
$ openssl s_client -showcerts -connect maker.ifttt.com:443
  1. 编辑 src/CMakeList.txt ,告知ESP-IDF将服务器证书嵌入固件:
FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*)
idf_component_register(SRCS ${app_sources})
target_add_binary_data(${COMPONENT_TARGET} "./server_cert.pem" TEXT)
  1. 激活虚拟环境并定义环境变量:
$ source ~/.platformio/penv/bin/activate
(penv)$ export WIFI_SSID='\"<ssid>\"'
(penv)$ export WIFI_PASS='\"<passwd>\"'
(penv)$ export IFTTT_KEY='\"<your_key>\"'

以下是 src/main.c 中的应用代码:

#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "private_include/esp_tls_mbedtls.h"
#include "app_temp.h"
#include "app_wifi.h"

#define TAG "app"
#define IFTTT_MAKER_URL "https://maker.ifttt.com"
#define QUEUE_SIZE 10
static QueueHandle_t temp_queue;
static const char REQUEST[] = "POST /trigger/temperature_received/with/key/" IFTTT_KEY " HTTP/1.1\r\n"
                              "Host: maker.ifttt.com\r\n"
                              "Content-Type: application/json\r\n"
                              "Content-Length: %d\r\n"
                              "\r\n"
                              "%s";
static const char JSON_DATA[] = "{\"value1\":\"%d\"}";
extern const uint8_t server_root_cert_pem_start[] asm("_binary_server_cert_pem_start");
extern const uint8_t server_root_cert_pem_end[] asm("_binary_server_cert_pem_end");

static void handle_wifi_connect(void)
{
    xTaskCreate(do_post, "post_task", 15 * configMINIMAL_STACK_SIZE, NULL, 5, NULL);
    apptemp_init(publish_reading);
}

static void handle_wifi_failed(void)
{
    ESP_LOGE(TAG, "wifi failed");
}

void app_main()
{
    temp_queue = xQueueCreate(QUEUE_SIZE, sizeof(int16_t));
    connect_wifi_params_t cbs = {
        .on_connected = handle_wifi_connect,
        .on_failed = handle_wifi_failed};
    appwifi_connect(cbs);
}

static void publish_reading(int temp, int hum)
{
    if (xQueueSendToBack(temp_queue, (void *)&temp, (TickType_t)0) != pdPASS)
    {
        ESP_LOGW(TAG, "queue is full");
        xQueueReset(temp_queue);
    }
}

static void do_post(void *arg)
{
    esp_tls_cfg_t cfg = {
        .cacert_buf = server_root_cert_pem_start,
        .cacert_bytes = server_root_cert_pem_end - server_root_cert_pem_start,
    };
    int16_t temp;
    char json_data[32];
    char request[256];
    char reply[512];

    while (1)
    {
        if (xQueueReceive(temp_queue, &(temp), (TickType_t)10) == pdFALSE)
        {
            ESP_LOGI(TAG, "nothing in the queue");
            vTaskDelay(1000);
            continue;
        }

        struct esp_tls *tls = esp_tls_conn_http_new(IFTTT_MAKER_URL, &cfg);
        if (tls == NULL)
        {
            ESP_LOGE(TAG, "tls connection failed");
            continue;
        }

        memset(json_data, 0, sizeof(json_data));
        sprintf(json_data, JSON_DATA, temp);
        memset(request, 0, sizeof(request));
        sprintf(request, REQUEST, strlen(json_data), json_data);
        int ret = esp_mbedtls_write(tls, request, strlen(request));

        if (ret > 0)
        {
            while (1)
            {
                ret = esp_mbedtls_read(tls, (char *)reply, sizeof(reply) - 1);
                if (ret > 0)
                {
                    reply[ret] = 0;
                    ESP_LOGI(TAG, "%s", reply);
                }
                else
                {
                    break;
                }
            }
        }
        esp_tls_conn_delete(tls);
    }
    vTaskDelete(NULL);
}

完成应用开发后,可以使用以下命令烧录开发板并进行测试:

(penv)$ pio run -t upload && pio device monitor

测试发现IFTTT服务会对Web请求进行限流,虽然每2秒从DHT11传感器读取一次数据,但每分钟只能在Google表格中看到2条温度记录。IFTTT提供了超过600种服务的更多功能,可参考 文档 了解更多。

3. 开发语音控制的智能风扇

接下来将开发一个语音控制的智能风扇。普通风扇通过机械按钮控制风速,我们要将其改造成不仅可以通过按钮,还能通过语音设置风速的智能风扇。

这个风扇有四个按钮,一个用于停止风扇,另外三个用于三种不同的风速模式(从慢到快)。实现思路是将风扇的速度按钮连接到ESP32的GPIO引脚,当检测到按钮按下时,通过继电器控制风速。同时,它还能通过改变继电器状态来响应语音命令。语音助手将使用亚马逊Alexa,后端服务使用亚马逊IoT Core和Lambda来处理语音命令。

以下是开发智能风扇的大致流程:
1. 硬件连接 :将风扇的速度按钮连接到ESP32的GPIO引脚。
2. 开发后端服务 :使用亚马逊IoT Core和Lambda处理语音命令。
3. 编写ESP32代码 :实现按钮检测和继电器控制。
4. 集成语音助手 :将亚马逊Alexa与后端服务集成,实现语音控制功能。

通过以上步骤,我们可以将普通风扇改造成一个功能强大的智能风扇,提升用户的使用体验。

综上所述,物联网设备与第三方服务的集成以及智能设备的开发为我们带来了更多的可能性和便利。在实际应用中,我们可以根据需求选择合适的服务和技术,不断创新和优化产品。

物联网设备的第三方集成与智能风扇开发

4. 智能风扇开发详细步骤
4.1 硬件连接

将风扇的四个按钮(一个停止按钮和三个速度模式按钮)分别连接到ESP32的不同GPIO引脚。可以参考以下表格进行连接:
| 风扇按钮功能 | ESP32 GPIO引脚 |
| ---- | ---- |
| 停止按钮 | GPIOX |
| 低速模式按钮 | GPIOY |
| 中速模式按钮 | GPIOZ |
| 高速模式按钮 | GPIOA |

注:X、Y、Z、A 需根据实际情况选择合适的GPIO引脚。

4.2 开发后端服务
  • 创建Lambda函数 :在AWS Lambda控制台创建一个新的函数,选择合适的运行环境(如Python)。编写代码来处理来自Alexa的语音命令,并根据命令控制风扇的状态。以下是一个简单的Python示例代码:
import json

def lambda_handler(event, context):
    # 解析Alexa请求
    intent = event['request']['intent']['name']

    if intent == 'StopFan':
        # 停止风扇的逻辑
        response = {
            "version": "1.0",
            "response": {
                "outputSpeech": {
                    "type": "PlainText",
                    "text": "风扇已停止"
                }
            }
        }
    elif intent == 'SetFanSpeed':
        speed = event['request']['intent']['slots']['Speed']['value']
        # 根据速度设置风扇状态的逻辑
        response = {
            "version": "1.0",
            "response": {
                "outputSpeech": {
                    "type": "PlainText",
                    "text": f"风扇已设置为{speed}档"
                }
            }
        }

    return response
  • 配置亚马逊IoT Core
    1. 在AWS IoT Core控制台创建一个新的事物(Thing),代表我们的智能风扇。
    2. 为事物创建证书和策略,确保设备可以安全地连接到AWS IoT Core。
    3. 配置规则,将Lambda函数与IoT Core关联起来,以便在接收到Alexa命令时触发相应的操作。

以下是配置规则的mermaid流程图:

graph LR
    A[Alexa命令] --> B[AWS IoT Core]
    B --> C{规则匹配}
    C -->|匹配成功| D[触发Lambda函数]
    D --> E[控制风扇状态]
    C -->|匹配失败| F[无操作]
4.3 编写ESP32代码

在ESP32上编写代码,实现按钮检测和继电器控制。以下是一个简单的示例代码:

#include <Arduino.h>

// 定义GPIO引脚
const int stopButtonPin = GPIOX;
const int lowSpeedButtonPin = GPIOY;
const int mediumSpeedButtonPin = GPIOZ;
const int highSpeedButtonPin = GPIOA;

// 定义继电器控制引脚
const int relayPin = GPIOB;

void setup() {
    // 初始化GPIO引脚
    pinMode(stopButtonPin, INPUT_PULLUP);
    pinMode(lowSpeedButtonPin, INPUT_PULLUP);
    pinMode(mediumSpeedButtonPin, INPUT_PULLUP);
    pinMode(highSpeedButtonPin, INPUT_PULLUP);
    pinMode(relayPin, OUTPUT);

    // 初始化串口通信
    Serial.begin(115200);
}

void loop() {
    // 检测停止按钮
    if (digitalRead(stopButtonPin) == LOW) {
        digitalWrite(relayPin, LOW);
        Serial.println("风扇已停止");
        delay(200); // 消抖
    }

    // 检测低速模式按钮
    if (digitalRead(lowSpeedButtonPin) == LOW) {
        // 设置低速模式的逻辑
        digitalWrite(relayPin, HIGH);
        Serial.println("风扇已设置为低速模式");
        delay(200); // 消抖
    }

    // 检测中速模式按钮
    if (digitalRead(mediumSpeedButtonPin) == LOW) {
        // 设置中速模式的逻辑
        digitalWrite(relayPin, HIGH);
        Serial.println("风扇已设置为中速模式");
        delay(200); // 消抖
    }

    // 检测高速模式按钮
    if (digitalRead(highSpeedButtonPin) == LOW) {
        // 设置高速模式的逻辑
        digitalWrite(relayPin, HIGH);
        Serial.println("风扇已设置为高速模式");
        delay(200); // 消抖
    }
}
4.4 集成语音助手
  • 创建Alexa技能 :在Alexa开发者控制台创建一个新的技能,配置意图(Intent)和槽位(Slot),例如 StopFan 意图和 SetFanSpeed 意图,以及 Speed 槽位(值可以是低速、中速、高速)。
  • 关联技能与后端服务 :将Alexa技能与之前创建的Lambda函数关联起来,确保语音命令可以正确传递到后端进行处理。

以下是集成语音助手的步骤列表:
1. 登录Alexa开发者控制台,创建新技能。
2. 定义意图和槽位,编写交互模型。
3. 配置技能的端点,指向Lambda函数的ARN。
4. 测试技能,确保语音命令可以正常触发相应的操作。

5. 总结

通过将ESP32设备与亚马逊AVS和IFTTT服务集成,以及开发语音控制的智能风扇,我们展示了物联网设备与第三方服务集成的强大功能和潜力。与亚马逊AVS集成可以为设备添加语音交互功能,提升用户体验;IFTTT服务则提供了一种简单而强大的方式来实现设备之间的自动化规则。

在开发智能风扇的过程中,我们结合了硬件连接、后端服务开发、ESP32代码编写和语音助手集成等多个方面的知识和技能。通过合理的设计和实现,我们可以将普通的风扇改造成一个具有语音控制功能的智能设备。

在实际应用中,我们可以根据需求进一步扩展和优化这些项目。例如,可以添加更多的传感器来实现智能调速,或者与其他智能家居设备进行联动。物联网的发展为我们带来了无限的可能性,让我们可以创造出更加智能、便捷的生活环境。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值