收藏官网首页
查看: 306|回复: 0

物联网控制模块:通过AI语音指令操控ESP32开发板设备

148

主题

429

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13072
跳转到指定楼层
楼主
 楼主| 发表于 7 天前 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
教您5分钟接入机智云,实现傻瓜式开发
物联网控制模块:通过AI语音指令操控ESP32开发板设备


本模块实现了AI语音聊天机器人的物联网控制功能,使用户可以通过语音指令控制接入到ESP32开发板的各种物联网设备。

工作原理

整个物联网控制模块的工作流程如下:

1、设备注册:在开发板初始化阶段(如在compact_wifi_board.cc中),各种物联网设备通过ThingManager注册到系统中
2、设备描述:系统将设备描述信息(包括名称、属性、方法等)通过通信协议(如MQTT或WebSocket)发送给AI服务器
3、用户交互:用户通过语音与AI对话,表达控制物联网设备的意图
4、命令执行:AI服务器解析用户意图,生成控制命令,通过协议发送回ESP32,由ThingManager分发给对应的设备执行
5、状态更新:设备执行命令后,状态变化会通过ThingManager收集并发送回AI服务器,保持状态同步


核心组件
ThingManager
ThingManager是物联网控制模块的核心管理类,采用单例模式实现:

AddThing:注册物联网设备
GetDescriptorsJson:获取所有设备的描述信息,用于向AI服务器报告设备能力
GetStatesJson:获取所有设备的当前状态,可以选择只返回变化的部分
Invoke:根据AI服务器下发的命令,调用对应设备的方法


Thing


Thing是所有物联网设备的基类,提供了以下核心功能:

属性管理:通过PropertyList定义设备的可查询状态
方法管理:通过MethodList定义设备可执行的操作
JSON序列化:将设备描述和状态转换为JSON格式,便于网络传输
命令执行:解析和执行来自AI服务器的指令


设备设计示例
灯(Lamp)

灯是一个简单的物联网设备示例,通过GPIO控制LED的开关状态:


  1. class Lamp : public Thing {
  2. private:
  3.     gpio_num_t gpio_num_ = GPIO_NUM_18;  // GPIO引脚
  4.     bool power_ = false;                 // 灯的开关状态

  5. public:
  6.     Lamp() : Thing("Lamp", "一个测试用的灯") {
  7.         // 初始化GPIO
  8.         InitializeGpio();

  9.         // 定义属性:power(表示灯的开关状态)
  10.         properties_.AddBooleanProperty("power", "灯是否打开", [this]() -> bool {
  11.             return power_;
  12.         });

  13.         // 定义方法:TurnOn(打开灯)
  14.         methods_.AddMethod("TurnOn", "打开灯", ParameterList(), [this](const ParameterList& parameters) {
  15.             power_ = true;
  16.             gpio_set_level(gpio_num_, 1);
  17.         });

  18.         // 定义方法:TurnOff(关闭灯)
  19.         methods_.AddMethod("TurnOff", "关闭灯", ParameterList(), [this](const ParameterList& parameters) {
  20.             power_ = false;
  21.             gpio_set_level(gpio_num_, 0);
  22.         });
  23.     }
  24. };
复制代码


用户可以通过语音指令如”请打开灯”来控制灯的开关。

扬声器(Speaker)

扬声器控制实现了音量调节功能:



  1. class Speaker : public Thing {
  2. public:
  3.     Speaker() : Thing("Speaker", "扬声器") {
  4.         // 定义属性:volume(当前音量值)
  5.         properties_.AddNumberProperty("volume", "当前音量值", [this]() -> int {
  6.             auto codec = Board::GetInstance().GetAudioCodec();
  7.             return codec->output_volume();
  8.         });

  9.         // 定义方法:SetVolume(设置音量)
  10.         methods_.AddMethod("SetVolume", "设置音量", ParameterList({
  11.             Parameter("volume", "0到100之间的整数", kValueTypeNumber, true)
  12.         }), [this](const ParameterList& parameters) {
  13.             auto codec = Board::GetInstance().GetAudioCodec();
  14.             codec->SetOutputVolume(static_cast<uint8_t>(parameters["volume"].number()));
  15.         });
  16.     }
  17. };
复制代码


用户可以通过语音指令如”把音量调到50”来控制扬声器的音量。

设计自定义物联网设备

要设计一个新的物联网设备,需要以下步骤:

1、创建设备类:继承Thing基类
2、定义属性:使用properties_添加设备的可查询状态
3、定义方法:使用methods_添加设备可执行的操作
4、实现硬件控制:在方法回调中实现对硬件的控制
5、注册设备:注册设备有两种方式(见下文),并在板级初始化中添加设备实例


两种设备注册方式

1、使用DECLARE_THING宏:适合通用设备类型


  1. // 在设备实现文件末尾添加
  2. DECLARE_THING(MyDevice);

  3. // 然后在板级初始化中
  4. thing_manager.AddThing(iot::CreateThing("MyDevice"));
复制代码


2、直接创建设备实例:适合特定于板级的设备

  1. // 在板级初始化中
  2. auto my_device = new iot::MyDevice();
  3. thing_manager.AddThing(my_device);
复制代码


设备实现位置建议


您可以根据设备的通用性选择不同的实现位置:


1、通用设备:放在main/iot/things/目录下,使用DECLARE_THING注册
2、板级特定设备:直接在板级目录(如main/boards/your_board/)中实现,使用直接创建实例的方式注册


这种灵活性允许您为不同的板设计特定的设备实现,同时保持通用设备的可重用性。


属性类型

物联网设备支持以下属性类型:


布尔值(kValueTypeBoolean):开关状态等
数值(kValueTypeNumber):温度、音量等
字符串(kValueTypeString):设备名称、状态描述等


方法参数

设备方法可以定义参数,支持以下参数类型:
布尔值:开关等
数值:温度、音量等
字符串:命令、模式等

使用示例

在板级初始化代码(如compact_wifi_board.cc)中注册物联网设备:



  1. void InitializeIot() {
  2.     auto& thing_manager = iot::ThingManager::GetInstance();
  3.     thing_manager.AddThing(iot::CreateThing("Speaker"));
  4.     thing_manager.AddThing(iot::CreateThing("Lamp"));
  5. }
复制代码



之后,用户可以通过语音指令控制这些设备,例如:
“打开灯”
“我要睡觉了,帮我关灯”
“音量有点太小了”
“把音量设置为80%”
AI服务器会将这些语音指令解析为对应的设备控制命令,通过协议发送给ESP32执行。


注意事项

大模型控制的随机性

由于语音控制由大型语言模型(LLM)处理,控制过程可能存在一定的随机性和不确定性。为了增强安全性和可靠性,请考虑以下建议:


1、关键操作添加警示信息:对于潜在危险或不可逆的操作,在方法描述中添加警示信息


  1. methods_.AddMethod("PowerOff", "关闭系统电源[警告:此操作将导致设备完全关闭,请慎重使用]",
  2.                   ParameterList(), [this](const ParameterList& parameters) {
  3.     // 关闭电源的实现
  4. });
复制代码


2、二次确认机制:重要操作应在描述中明确要求二次确认


  1. methods_.AddMethod("ResetToFactory", "恢复出厂设置[必须要用户二次确认]",
  2.                   ParameterList(), [this](const ParameterList& parameters) {
  3.     // 恢复出厂设置的实现
  4. });
复制代码


通信协议限制

1、当前IoT协议(1.0版本)存在以下限制:
2、单向控制流:大模型只能下发指令,无法立即获取指令执行结果
3、状态更新延迟:设备状态变更需要等到下一轮对话时,通过读取property属性值才能获知
4、异步反馈:如果需要操作结果反馈,必须通过设备属性的方式间接实现

最佳实践

1、使用有意义的属性名称:属性名称应清晰表达其含义,便于大模型理解和使用
2、不产生歧义的方法描述:为每个方法提供明确的自然语言描述,帮助大模型更准确地理解和调用





您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

加入Q群 返回顶部

版权与免责声明 © 2006-2024 Gizwits IoT Technology Co., Ltd. ( 粤ICP备11090211号 )

快速回复 返回顶部 返回列表
在线咨询