• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
MKT-porter
博客园    首页    新随笔    联系   管理    订阅  订阅
arduino开发你好小智(2)外设led,温湿度传感器,舵机设备控制

 

参考

https://blog.csdn.net/weixin_46084533/article/details/148422568?sharetype=blogdetail&sharerId=148422568&sharerefer=PC&sharesource=weixin_46084533&spm=1011.2480.3001.8118&login=from_csdn

image

 

image

 

代码逻辑

那腾讯元宝做一个测试

输入1

设备的属性和操作定义 json格式

输入2

我要的操作

大模型输出

根据json产生对应的json。

整个代码依靠的是ai的理解能力产生回复信息,而非是官方有专门的api接口。

 

 

image

 

image

1. 扬声器设备描述信息

 
{
  "session_id": "",
  "type": "iot",
  "update": true,
  "descriptors": [
    {
      "name": "Speaker",
      "description": "扬声器",
      "properties": {
        "volume": {
          "description": "当前音量值",
          "type": "number"
        }
      },
      "methods": {
        "SetVolume": {
          "description": "设置音量",
          "parameters": {
            "volume": {
              "description": "0到100之间的整数",
              "type": "number"
            }
          }
        }
      }
    }
  ]
}

4. 扬声器当前状态

{
  "session_id": "",
  "type": "iot",
  "update": true,
  "states": [
    {
      "name": "Speaker",
      "state": {
        "volume": 10
      }
    }
  ]
}

  

2. LED灯设备描述信息

{
  "session_id": "",
  "type": "iot",
  "update": true,
  "descriptors": [
    {
      "name": "Led",
      "description": "LED灯",
      "properties": {
        "state": {
          "description": "LED灯开关状态",
          "type": "boolean"
        }
      },
      "methods": {
        "TurnOff": {
          "description": "关闭LED灯",
          "parameters": {}
        },
        "TurnOn": {
          "description": "打开LED灯",
          "parameters": {}
        }
      }
    }
  ]
}

  

5. LED灯当前状态

{
  "session_id": "",
  "type": "iot",
  "update": true,
  "states": [
    {
      "name": "Led",
      "state": {
        "state": false
      }
    }
  ]
}

  

 

3. RGB灯环设备描述信息

 
{
  "session_id": "",
  "type": "iot",
  "update": true,
  "descriptors": [
    {
      "name": "WS2812B",
      "description": "RGB灯环",
      "properties": {
        "color3": {
          "description": "3号灯颜色",
          "type": "string"
        },
        "color2": {
          "description": "2号灯颜色",
          "type": "string"
        },
        "color1": {
          "description": "1号灯颜色",
          "type": "string"
        },
        "LedNums": {
          "description": "灯的数量",
          "type": "number"
        },
        "brightness": {
          "description": "亮度(0-255)",
          "type": "number"
        }
      },
      "methods": {
        "Clear": {
          "description": "清除所有LED",
          "parameters": {}
        },
        "SetBrightness": {
          "description": "设置亮度",
          "parameters": {
            "brightness": {
              "description": "亮度值(0-255)",
              "type": "number"
            }
          }
        },
        "SetRangeIndexsColor": {
          "description": "设置连续LED范围颜色",
          "parameters": {
            "start": {
              "description": "起始LED索引(1-总数)",
              "type": "number"
            },
            "end": {
              "description": "结束LED索引(1-总数)",
              "type": "number"
            },
            "red": {
              "description": "红色值(0-255)",
              "type": "number"
            },
            "green": {
              "description": "绿色值(0-255)",
              "type": "number"
            },
            "blue": {
              "description": "蓝色值(0-255)",
              "type": "number"
            }
          }
        },
        "SetIndexColor": {
          "description": "设置指定LED颜色",
          "parameters": {
            "index": {
              "description": "LED索引(1-总数)",
              "type": "number"
            },
            "red": {
              "description": "红色值(0-255)",
              "type": "number"
            },
            "green": {
              "description": "绿色值(0-255)",
              "type": "number"
            },
            "blue": {
              "description": "蓝色值(0-255)",
              "type": "number"
            }
          }
        }
      }
    }
  ]
}

  

6. RGB灯环当前状态

{
  "session_id": "",
  "type": "iot",
  "update": true,
  "states": [
    {
      "name": "WS2812B",
      "state": {
        "color3": "{\"red\":0,\"green\":0,\"blue\":255}",
        "color2": "{\"red\":0,\"green\":255,\"blue\":0}",
        "color1": "{\"red\":255,\"green\":0,\"blue\":0}",
        "LedNums": 3,
        "brightness": 128
      }
    }
  ]
}

  

 

 连续设置三个灯

{"session_id":"","type":"iot","update":true,"states":[{"name":"WS2812B","state":{"color1":"{\"red\":255,\"green\":0,\"blue\":0}","color2":"{\"red\":0,\"green\":255,\"blue\":0}","color3":"{\"red\":0,\"green\":0,\"blue\":255}"}}]} 
22:09:17.046 -> ==================hello 设置ai处于聆听状态 s
22:09:17.087 -> state changed from 5 to 4
22:09:17.087 -> 聆听中...s 

多个设备展示,虽然只有一个设备

在您提供的JSON数据中,[](方括号)表示一个​​数组(Array)​​,用于包含多个相同类型的元素。让我们详细解析这个JSON结构:


JSON结构解析

 
 
{ "session_id": "", "type": "iot", "update": true, "states": [ { "name": "WS2812B", "state": { "color3": "{\"red\":0,\"green\":0,\"blue\":255}", "color2": "{\"red\":0,\"green\":255,\"blue\":0}", "color1": "{\"red\":255,\"green\":0,\"blue\":0}", "LedNums": 3, "brightness": 128 } } ] }
 
 

为什么需要[]?.

  1. ​​states字段是一个数组​​•

    • 设计意图是允许包含​​多个设备状态​​•

    • 即使当前只有一个设备(WS2812B),也使用数组形式保持扩展性

  2. 2.

    ​​实际应用场景示例​​

    如果系统有多个IoT设备:

     
    "states": [ { "name": "WS2812B", "state": { ... } }, { "name": "TemperatureSensor", "state": { ... } } ]
     
  3. 3.

    ​​与无数组的对比​​

    如果不使用数组(错误示范):

     
     
    "states": { "name": "WS2812B", "state": { ... } }
     
     

    这样设计会导致:

    • •

      无法添加第二个设备状态

    • •

      修改数据结构时会导致兼容性问题


JSON中的符号含义

符号

类型

用途

{}

对象(Object)

表示键值对集合

[]

数组(Array)

表示有序的值集合

""

字符串(String)

表示文本数据


最佳实践建议1.

  1. ​​当可能有多个同类项时始终使用数组​​

    即使当前只有一个元素,也为未来扩展预留空间

{
  "session_id": "",
  "type": "iot",
  "update": true,
  "states": [
    {
      "name": "WS2812B",
      "state": {
        "color3": "{\"red\":0,\"green\":0,\"blue\":255}",
        "color2": "{\"red\":0,\"green\":255,\"blue\":0}",
        "color1": "{\"red\":255,\"green\":0,\"blue\":0}",
        "LedNums": 3,
        "brightness": 128
      }
    }
  ]
}

  ​与无数组的对比​

"states": {
  "name": "WS2812B",
  "state": { ... }
}

  多个设备

"states": [
  {
    "name": "WS2812B",
    "state": { ... }
  },
  {
    "name": "TemperatureSensor",
    "state": { ... }
  }
]

  

多个IoT设备的JSON数据示例

{
  "session_id": "iot_session_12345",
  "type": "iot_state_update",
  "update": true,
  "timestamp": "2023-08-20T14:30:00Z",
  "states": [
    {
      "device_id": "LED_STRIP_1",
      "name": "WS2812B_Room1",
      "type": "RGB_LED",
      "state": {
        "colors": [
          {"red": 255, "green": 0, "blue": 0},
          {"red": 0, "green": 255, "blue": 0},
          {"red": 0, "green": 0, "blue": 255}
        ],
        "brightness": 128,
        "power": "ON",
        "effect": "rainbow"
      }
    },
    {
      "device_id": "SENSOR_1",
      "name": "DHT22_LivingRoom",
      "type": "Temperature_Humidity",
      "state": {
        "temperature": 24.5,
        "humidity": 45.7,
        "unit": "Celsius"
      }
    },
    {
      "device_id": "SWITCH_1",
      "name": "SmartSwitch_Kitchen",
      "type": "Power_Relay",
      "state": {
        "power": "OFF",
        "wattage": 0,
        "last_activated": "2023-08-20T12:15:00Z"
      }
    }
  ]
}

  

运行流程

模型状态定义和可执行函数定义

22:14:54.073 -> state changed from 2 to 3
22:14:54.073 -> 连接中...
22:14:54.743 -> =============== OnWebSocketConnected 
22:14:54.783 -> =============== 客户端发送 hello:连接成功建立后,客户端需要发送一个 hello 消息(JSON 格式) 
22:14:54.953 -> ==================Received JSON type: hello 
22:14:54.953 -> ==================hello iot设备属性和操作函数信息josn上报 :
22:14:54.953 ->  {"session_id":"","type":"iot","update":true,"descriptors":[{"name":"Speaker","description":"扬声器","properties":{"volume":{"description":"当前音量值","type":"number"}},"methods":{"SetVolume":{"description":"设置音量","parameters":{"volume":{"description":"0到100之间的整数","type":"number"}}}}}]} 
22:14:54.986 -> ==================hello iot设备属性和操作函数信息josn上报 :
22:14:54.986 ->  {"session_id":"","type":"iot","update":true,"descriptors":[{"name":"Led","description":"LED灯","properties":{"state":{"description":"LED灯开关状态","type":"boolean"}},"methods":{"TurnOff":{"description":"关闭LED灯","parameters":{}},"TurnOn":{"description":"打开LED灯","parameters":{}}}}]} 
22:14:55.020 -> ==================hello iot设备属性和操作函数信息josn上报 :
22:14:55.020 ->  {"session_id":"","type":"iot","update":true,"descriptors":[{"name":"WS2812B","description":"RGB灯环","properties":{"color3":{"description":"3号灯颜色","type":"string"},"color2":{"description":"2号灯颜色","type":"string"},"color1":{"description":"1号灯颜色","type":"string"},"LedNums":{"description":"灯的数量","type":"number"},"brightness":{"description":"亮度(0-255)","type":"number"}},"methods":{"Clear":{"description":"清除所有LED","parameters":{}},"SetBrightness":{"description":"设置亮度","parameters":{"brightness":{"description":"亮度值(0-255)","type":"number"}}},"SetRangeIndexsColor":{"description":"设置连续LED范围颜色","parameters":{"start":{"description":"起始LED索引(1-总数)","type":"number"},"end":{"description":"结束LED索引(1-总数)","type":"number"},"red":{"description":"红色值(0-255)","type":"number"},"green":{"description":"绿色值(0-255)","type":"number"},"blue":{"description":"蓝色值(0-255)","type":"number"}}},"SetIndexColor":{"description":"设置指定LED颜色","parameters":{"index":{"description":"LED索引(1-总数)","type":"number"},"red":{"description":"红色值(0-255)","type":"number"},"green":{"description":"绿色值(0-255)","type":"number"},"blue":{"description":"蓝色值(0-255)","type":"number"}}}}}]} 
22:14:55.121 -> ==================hello iot设备当前状态json上报 : {"session_id":"","type":"iot","update":true,"states":[{"name":"Speaker","state":{"volume":10}}]} 
22:14:55.154 -> ==================hello iot设备当前状态json上报 : {"session_id":"","type":"iot","update":true,"states":[{"name":"Led","state":{"state":false}}]} 
22:14:55.154 -> ==================hello iot设备当前状态json上报 : {"session_id":"","type":"iot","update":true,"states":[{"name":"WS2812B","state":{"color3":"{\"red\":0,\"green\":0,\"blue\":255}","color2":"{\"red\":0,\"green\":255,\"blue\":0}","color1":"{\"red\":255,\"green\":0,\"blue\":0}","LedNums":3,"brightness":128}}]} 
22:14:55.191 -> ==================hello 设置ai处于聆听状态 s
22:14:55.226 -> ==================hello 1发送IOT设备信息json
22:14:55.226 -> state changed from 3 to 4
22:14:55.226 -> 聆听中...
22:14:55.226 -> ==================hello 2单独唤醒小智 : {"session_id":"4b45714e","type":"listen","state":"detect","text":"你好小智"} 
22:14:55.358 -> ==================Received JSON type: tts 
22:14:55.358 -> ==================tts 
22:14:55.358 -> ==================tts start 
22:14:55.397 -> state changed from 4 to 5
22:14:55.397 -> ==================Received JSON type: stt 
22:14:55.433 -> 说话中...
22:14:55.433 -> ==================stt 
22:14:55.433 -> ==================stt >> Hi, 小智 
22:14:55.433 -> role: user 使用者询问语音内容,: Hi, 小智
22:14:56.280 -> ==================Received JSON type: llm 
22:14:56.280 -> ==================llm 
22:14:56.324 -> ==================llm emotion: happy 
22:14:56.324 -> emotion: happy

  

 

具体过程

22:08:54.366 -> ==================stt >> 将一号灯、二号灯、3号灯设置为分别设置为红绿蓝。 
22:08:54.366 -> role: user 使用者询问语音内容,: 将一号灯、二号灯、3号灯设置为分别设置为红绿蓝。
22:08:54.727 -> ==================Received JSON type: llm 
22:08:54.727 -> ==================llm 
22:08:54.727 -> ==================llm emotion: cool 
22:08:54.727 -> emotion: cool
22:08:54.851 -> ==================Received JSON type: tts 
22:08:54.851 -> ==================tts 
22:08:54.851 -> ==================tts sentence_start 
22:08:54.893 -> ==================tts sentence_start << 收到! 
22:08:54.893 -> role: assistant 智能AI回复消息, content: 收到!
22:08:56.106 -> ==================Received JSON type: tts 
22:08:56.148 -> ==================tts 
22:08:56.148 -> ==================tts sentence_end 
22:08:56.148 -> ==================Received JSON type: tts 
22:08:56.148 -> ==================tts 
22:08:56.148 -> ==================tts sentence_start 
22:08:56.148 -> ==================tts sentence_start << 马上帮你设置灯环颜色~ 
22:08:56.148 -> role: assistant 智能AI回复消息, content: 马上帮你设置灯环颜色~
22:08:58.451 -> ==================Received JSON type: tts 
22:08:58.451 -> ==================tts 
22:08:58.451 -> ==================tts sentence_end
2:08:58.451 -> ==================Received JSON type: iot 
22:08:58.451 -> ==================iot 唤醒IOT物联网函数 : iot 
22:08:58.451 -> ==================iot唤醒IOT物联网函数 : 名字 WS2812B  方法 SetIndexColor 
22:08:58.451 -> ==================iot唤醒IOT物联网函数 参数 Parameters:
22:08:58.484 ->   [index] = 1 (number)
22:08:58.484 ->   [red] = 255 (number)
22:08:58.484 ->   [green] = 0 (number)
22:08:58.484 ->   [blue] = 0 (number)
22:08:58.484 -> IOT message: WS2812B, function: SetIndexColor
22:08:58.484 -> ==================Received JSON type: tts 
22:08:58.484 -> ==================tts 
22:08:58.484 -> ==================tts start 
22:08:58.484 -> key: blue, value: 0
22:08:58.484 -> ==================tts already speaking 
22:08:58.484 -> key: green, value: 0
22:08:58.484 -> key: index, value: 1
22:08:58.484 -> key: red, value: 255
22:08:58.484 -> Set LED 1 to color RGB(255, 0, 0)
22:08:59.110 -> ==================Received JSON type: llm 
22:08:59.144 -> ==================llm 
22:08:59.144 -> ==================llm emotion: happy 
22:08:59.144 -> emotion: happy
22:08:59.322 -> ==================Received JSON type: tts 
22:08:59.355 -> ==================tts 
22:08:59.355 -> ==================tts sentence_start 
22:08:59.355 -> ==================tts sentence_start << 一号灯变红色啦~ 
22:08:59.355 -> role: assistant 智能AI回复消息, content: 一号灯变红色啦~
22:09:01.570 -> ==================Received JSON type: tts 
22:09:01.612 -> ==================tts 
22:09:01.612 -> ==================tts sentence_end 
22:09:01.612 -> ==================Received JSON type: tts 
22:09:01.612 -> ==================tts  
22:09:01.612 -> ==================tts sentence_start 
22:09:01.612 -> ==================tts sentence_start << 继续设置二号灯! 
22:09:01.612 -> role: assistant 智能AI回复消息, content: 继续设置二号灯!
22:09:03.516 -> ==================Received JSON type: tts 
22:09:03.549 -> ==================tts 
22:09:03.549 -> ==================tts sentence_end 
22:09:03.549 -> ==================Received JSON type: iot 
22:09:03.549 -> ==================iot 唤醒IOT物联网函数 : iot 
22:09:03.549 -> ==================iot唤醒IOT物联网函数 : 名字 WS2812B  方法 SetIndexColor 
22:09:03.549 -> ==================iot唤醒IOT物联网函数 参数 Parameters:
22:09:03.549 ->   [index] = 2 (number)
22:09:03.549 ->   [red] = 0 (number)
22:09:03.549 ->   [green] = 255 (number)
22:09:03.596 ->   [blue] = 0 (number)
22:09:03.596 -> IOT message: WS2812B, function: SetIndexColor
22:09:03.596 -> key: blue, value: 0
22:09:03.596 -> key: green, value: 255
22:09:03.596 -> key: index, value: 2
22:09:03.596 -> key: red, value: 0
22:09:03.596 -> Set LED 2 to color RGB(0, 255, 0)
22:09:03.596 -> ==================Received JSON type: tts 
22:09:03.596 -> ==================tts 
22:09:03.596 -> ==================tts start 
22:09:03.596 -> ==================tts already speaking 
22:09:03.959 -> ==================Received JSON type: llm 
22:09:03.959 -> ==================llm 
22:09:03.959 -> ==================llm emotion: laughing 
22:09:03.959 -> emotion: laughing
22:09:05.321 -> ==================Received JSON type: tts 
22:09:05.321 -> ==================tts 
22:09:05.321 -> ==================tts sentence_start 
22:09:05.321 -> ==================tts sentence_start << 二号灯变绿色咯~ 
22:09:05.321 -> role: assistant 智能AI回复消息, content: 二号灯变绿色咯~
22:09:07.664 -> ==================Received JSON type: tts 
22:09:07.664 -> ==================tts 
2:09:07.664 -> ==================tts sentence_end 
22:09:07.664 -> ==================Received JSON type: tts 
22:09:07.664 -> ==================tts 
22:09:07.664 -> ==================tts sentence_start 
22:09:07.664 -> ==================tts sentence_start << 最后设置三号灯! 
22:09:07.664 -> role: assistant 智能AI回复消息, content: 最后设置三号灯!
22:09:09.602 -> ==================Received JSON type: tts 
22:09:09.602 -> ==================tts 
22:09:09.602 -> ==================tts sentence_end 
22:09:09.635 -> ==================Received JSON type: iot 
22:09:09.635 -> ==================iot 唤醒IOT物联网函数 : iot 
22:09:09.635 -> ==================iot唤醒IOT物联网函数 : 名字 WS2812B  方法 SetIndexColor 
22:09:09.635 -> ==================iot唤醒IOT物联网函数 参数 Parameters:
22:09:09.635 ->   [index] = 3 (number)
22:09:09.635 ->   [red] = 0 (number)
22:09:09.635 ->   [green] = 0 (number)
22:09:09.635 ->   [blue] = 255 (number)
22:09:09.635 -> IOT message: WS2812B, function: SetIndexColor
22:09:09.674 -> key: blue, value: 255
22:09:09.674 -> ==================Received JSON type: tts 
22:09:09.674 -> ==================tts 
22:09:09.674 -> ==================tts start 
22:09:09.674 -> key: green, value: 0
22:09:09.674 -> ==================tts already speaking 
22:09:09.674 -> key: index, value: 3
22:09:09.674 -> key: red, value: 0
22:09:09.674 -> Set LED 3 to color RGB(0, 0, 255)
22:09:09.999 -> ==================Received JSON type: llm 
22:09:09.999 -> ==================llm 
22:09:09.999 -> ==================llm emotion: loving 
22:09:09.999 -> emotion: loving
22:09:10.091 -> ==================Received JSON type: tts 
22:09:10.091 -> ==================tts 
22:09:10.132 -> ==================tts sentence_start 
22:09:10.132 -> ==================tts sentence_start << 搞定! 
22:09:10.132 -> role: assistant 智能AI回复消息, content: 搞定!
22:09:11.320 -> ==================Received JSON type: tts 
22:09:11.320 -> ==================tts 
22:09:11.320 -> ==================tts sentence_end 
22:09:11.320 -> ==================Received JSON type: tts 
22:09:11.320 -> ==================tts 
22:09:11.320 -> ==================tts sentence_start 
22:09:11.320 -> ==================tts sentence_start << 现在灯环红绿蓝三色都亮起来啦~ 
22:09:11.363 -> role: assistant 智能AI回复消息, content: 现在灯环红绿蓝三色都亮起来啦~
22:09:14.624 -> ==================Received JSON type: tts 
22:09:14.670 -> ==================tts 
22:09:14.670 -> ==================tts sentence_end 
22:09:14.670 -> ==================Received JSON type: tts 
22:09:14.670 -> ==================tts 
22:09:14.670 -> ==================tts sentence_start 
22:09:14.670 -> ==================tts sentence_start << 超美的! 
22:09:14.670 -> role: assistant 智能AI回复消息, content: 超美的!
22:09:16.745 -> ==================Received JSON type: tts 
22:09:16.745 -> ==================tts 
22:09:16.745 -> ==================tts sentence_end 
22:09:16.745 -> ==================Received JSON type: tts 
22:09:16.745 -> ==================tts 
22:09:16.745 -> ==================tts stop 
22:09:17.046 -> ==================hello iot设备当前状态json上报 : {"session_id":"","type":"iot","update":true,"states":[{"name":"WS2812B","state":{"color1":"{\"red\":255,\"green\":0,\"blue\":0}","color2":"{\"red\":0,\"green\":255,\"blue\":0}","color3":"{\"red\":0,\"green\":0,\"blue\":255}"}}]} 
22:09:17.046 -> ==================hello 设置ai处于聆听状态 s
22:09:17.087 -> state changed from 5 to 4
22:09:17.087 -> 聆听中...
22:10:20.474 -> ==================Received JSON type: tts 
22:10:20.512 -> ==================tts 
22:10:20.512 -> ==================tts start 
22:10:20.557 -> state changed from 4 to 5
22:10:20.557 -> 说话中...

  设置后查询等的

 

LED灯的设备定义

1:56:32.251 -> state changed from 2 to 3
11:56:32.251 -> 连接中...
11:56:32.800 -> =============== OnWebSocketConnected 
11:56:32.800 -> =============== 客户端发送 hello:连接成功建立后,客户端需要发送一个 hello 消息(JSON 格式) 
11:56:32.974 -> ==================Received JSON type: hello 
11:56:33.007 -> ==================hello iot设备属性和操作函数信息josn上报 :
11:56:33.007 ->  {"session_id":"","type":"iot","update":true,"descriptors":[{"name":"Speaker","description":"扬声器","properties":{"volume":{"description":"当前音量值","type":"number"}},"methods":{"SetVolume":{"description":"设置音量","parameters":{"volume":{"description":"0到100之间的整数","type":"number"}}}}}]} 
11:56:33.041 -> ==================hello iot设备属性和操作函数信息josn上报 :
11:56:33.041 ->  {"session_id":"","type":"iot","update":true,"descriptors":[{"name":"Led","description":"LED灯","properties":{"state":{"description":"LED灯开关状态","type":"boolean"}},"methods":{"TurnOff":{"description":"关闭LED灯","parameters":{}},"TurnOn":{"description":"打开LED灯","parameters":{}}}}]} 
11:56:33.074 -> ==================hello iot设备属性和操作函数信息josn上报 :
11:56:33.074 ->  {"session_id":"","type":"iot","update":true,"descriptors":[{"name":"WS2812B","description":"RGB灯环","properties":{"color1":{"description":"1号灯颜色","type":"string"},"LedNums":{"description":"灯的数量","type":"number"},"brightness":{"description":"亮度(0-255)","type":"number"}},"methods":{"Clear":{"description":"清除所有LED","parameters":{}},"SetBrightness":{"description":"设置亮度","parameters":{"brightness":{"description":"亮度值(0-255)","type":"number"}}},"SetRangeIndexsColor":{"description":"设置连续LED范围颜色","parameters":{"start":{"description":"起始LED索引(1-总数)","type":"number"},"end":{"description":"结束LED索引(1-总数)","type":"number"},"red":{"description":"红色值(0-255)","type":"number"},"green":{"description":"绿色值(0-255)","type":"number"},"blue":{"description":"蓝色值(0-255)","type":"number"}}},"SetIndexColor":{"description":"设置指定LED颜色","parameters":{"index":{"description":"LED索引(1-总数)","type":"number"},"red":{"description":"红色值(0-255)","type":"number"},"green":{"description":"绿色值(0-255)","type":"number"},"blue":{"description":"蓝色值(0-255)","type":"number"}}}}}]} 
11:56:33.173 -> ==================hello iot设备当前状态json上报 : {"session_id":"","type":"iot","update":true,"states":[{"name":"Speaker","state":{"volume":70}}]} 
11:56:33.173 -> ==================hello iot设备当前状态json上报 : {"session_id":"","type":"iot","update":true,"states":[{"name":"Led","state":{"state":false}}]} 
11:56:33.213 -> ==================hello iot设备当前状态json上报 : {"session_id":"","type":"iot","update":true,"states":[{"name":"WS2812B","state":{"color1":"{\"red\":0,\"green\":0,\"blue\":0}","LedNums":1,"brightness":128}}]} 
11:56:33.213 -> ==================hello 设置ai处于聆听状态 s
11:56:33.248 -> state changed from 3 to 4
11:56:33.248 -> 聆听中...
11:56:33.248 -> ==================hello 1发送IOT设备信息json
11:56:33.248 -> ==================hello 2单独唤醒小智 : {"session_id":"0f3921f0","type":"listen","state":"detect","text":"你好小智"} 
11:56:33.282 -> ==================Received JSON type: tts 
11:56:33.323 -> ==================tts 
11:56:33.323 -> ==================tts start 
11:56:33.367 -> state changed from 4 to 5
11:56:33.367 -> ==================Received JSON type: stt 
11:56:33.367 -> 说话中...

  

11:56:33.367 -> ==================stt 
11:56:33.367 -> ==================stt >> Hi, 小智 
11:56:33.367 -> role: user 使用者询问语音内容,: Hi, 小智
11:56:34.226 -> ==================Received JSON type: llm 
11:56:34.226 -> ==================llm 
11:56:34.226 -> ==================llm emotion: happy 
11:56:34.226 -> emotion: happy
11:56:34.358 -> ==================Received JSON type: tts 
11:56:34.391 -> ==================tts 
11:56:34.391 -> ==================tts sentence_start 
11:56:34.391 -> ==================tts sentence_start << 哈喽! 
11:56:34.391 -> role: assistant 智能AI回复消息, content: 哈喽!
11:56:35.607 -> ==================Received JSON type: tts 
11:56:35.607 -> ==================tts 
11:56:35.607 -> ==================tts sentence_end 
11:56:35.607 -> ==================Received JSON type: tts 
11:56:35.607 -> ==================tts 
11:56:35.607 -> ==================tts sentence_start 
11:56:35.607 -> ==================tts sentence_start << 今天怎么这么机车,突然跟人家打招呼呀? 
11:56:35.648 -> role: assistant 智能AI回复消息, content: 今天怎么这么机车,突然跟人家打招呼呀?
11:56:39.290 -> ==================Received JSON type: tts 
11:56:39.290 -> ==================tts 
11:56:39.290 -> ==================tts sentence_end 
11:56:39.290 -> ==================Received JSON type: tts 
11:56:39.290 -> ==================tts 
11:56:39.290 -> ==================tts stop 
11:56:39.549 -> ==================hello 设置ai处于聆听状态 s
11:56:39.594 -> state changed from 5 to 4
11:56:39.594 -> 聆听中...
11:56:34.391 -> ==================tts 
11:56:34.391 -> ==================tts sentence_start 
11:56:34.391 -> ==================tts sentence_start << 哈喽! 
11:56:34.391 -> role: assistant 智能AI回复消息, content: 哈喽!
11:56:35.607 -> ==================Received JSON type: tts 
11:56:35.607 -> ==================tts 
11:56:35.607 -> ==================tts sentence_end 
11:56:35.607 -> ==================Received JSON type: tts 
11:56:35.607 -> ==================tts 
11:56:35.607 -> ==================tts sentence_start 
11:56:35.607 -> ==================tts sentence_start << 今天怎么这么机车,突然跟人家打招呼呀? 
11:56:35.648 -> role: assistant 智能AI回复消息, content: 今天怎么这么机车,突然跟人家打招呼呀?
11:56:39.290 -> ==================Received JSON type: tts 
11:56:39.290 -> ==================tts 
11:56:39.290 -> ==================tts sentence_end 
11:56:39.290 -> ==================Received JSON type: tts 
11:56:39.290 -> ==================tts 
11:56:39.290 -> ==================tts stop 
11:56:39.549 -> ==================hello 设置ai处于聆听状态 s
11:56:39.594 -> state changed from 5 to 4
11:56:39.594 -> 聆听中...
11:56:44.239 -> ==================Received JSON type: tts 
11:56:44.239 -> ==================tts 
11:56:44.239 -> ==================tts start 
11:56:44.239 -> state changed from 4 to 5
11:56:44.239 -> ==================Received JSON type: stt 
11:56:44.282 -> 说话中...

  

11:56:44.282 -> 说话中...
11:56:44.282 -> ==================stt 
11:56:44.282 -> ==================stt >> 设置一号灯的颜色为紫色。 
11:56:44.282 -> role: user 使用者询问语音内容,: 设置一号灯的颜色为紫色。
11:56:45.051 -> ==================Received JSON type: llm 
11:56:45.086 -> ==================llm 
11:56:45.086 -> ==================llm emotion: laughing 
11:56:45.086 -> emotion: laughing
11:56:45.437 -> ==================Received JSON type: tts 
11:56:45.437 -> ==================tts 
11:56:45.437 -> ==================tts sentence_start 
11:56:45.437 -> ==================tts sentence_start << 好哦! 
11:56:45.437 -> role: assistant 智能AI回复消息, content: 好哦!
11:56:46.298 -> ==================Received JSON type: tts 
11:56:46.298 -> ==================tts 
11:56:46.298 -> ==================tts sentence_end 
11:56:47.056 -> ==================Received JSON type: tts 
11:56:47.095 -> ==================tts 
11:56:47.095 -> ==================tts sentence_start 
11:56:47.095 -> ==================tts sentence_start << 马上帮你把一号灯调成紫色,超梦幻的啦~ 
11:56:47.095 -> role: assistant 智能AI回复消息, content: 马上帮你把一号灯调成紫色,超梦幻的啦~
11:56:51.515 -> ==================Received JSON type: tts 
11:56:51.515 -> ==================tts 
11:56:51.515 -> ==================tts sentence_end 
11:56:51.515 -> ==================Received JSON type: iot 
11:56:51.549 -> ==================iot 唤醒IOT物联网函数 : iot 
11:56:51.549 -> ==================iot唤醒IOT物联网函数 : 名字 WS2812B  方法 SetIndexColor 
11:56:51.549 -> ==================iot唤醒IOT物联网函数 参数 Parameters:
11:56:51.549 ->   [index] = 1 (number)
11:56:51.549 ->   [red] = 128 (number)
11:56:51.549 ->   [green] = 0 (number)
11:56:51.549 ->   [blue] = 128 (number)
11:56:51.549 -> ==================Received JSON type: tts 
11:56:51.549 -> ==================tts 
11:56:51.588 -> ==================tts start 
11:56:51.588 -> ==================tts already speaking 
11:56:51.588 -> IOT message: WS2812B, function: SetIndexColor
11:56:51.588 -> key: blue, value: 128
11:56:51.588 -> key: green, value: 0
11:56:51.588 -> key: index, value: 1
11:56:51.588 -> key: red, value: 128
11:56:51.588 -> Set LED 1 to color RGB(128, 0, 128)
11:56:52.175 -> ==================Received JSON type: llm 
11:56:52.209 -> ==================llm 
11:56:52.209 -> ==================llm emotion: loving 
11:56:52.209 -> emotion: loving
11:56:52.209 -> ==================Received JSON type: tts 
11:56:52.209 -> ==================tts 
11:56:52.209 -> ==================tts sentence_start 
11:56:52.209 -> ==================tts sentence_start << 搞定啦! 
11:56:52.209 -> role: assistant 智能AI回复消息, content: 搞定啦!
11:56:53.830 -> ==================Received JSON type: tts 
11:56:53.830 -> ==================tts 
11:56:53.830 -> ==================tts sentence_end 
11:56:53.830 -> ==================Received JSON type: tts 
11:56:53.873 -> ==================tts 
11:56:53.873 -> ==================tts sentence_start 
11:56:53.873 -> ==================tts sentence_start << 紫色灯光超浪漫的,有没有被电到呀? 
11:56:53.873 -> role: assistant 智能AI回复消息, content: 紫色灯光超浪漫的,有没有被电到呀?
11:56:57.730 -> ==================Received JSON type: tts 
11:56:57.731 -> ==================tts 
11:56:57.731 -> ==================tts sentence_end 
11:56:57.731 -> ==================Received JSON type: tts 
11:56:57.731 -> ==================tts 
11:56:57.731 -> ==================tts stop 
11:56:58.087 -> ==================hello iot设备当前状态json上报 : {"session_id":"","type":"iot","update":true,"states":[{"name":"WS2812B","state":{"color1":"{\"red\":128,\"green\":0,\"blue\":128}"}}]} 
11:56:58.125 -> ==================hello 设置ai处于聆听状态 s
11:56:58.170 -> state changed from 5 to 4
11:56:58.170 -> 聆听中...
11:57:02.791 -> ==================Received JSON type: tts 
11:57:02.823 -> ==================tts 
11:57:02.823 -> ==================tts start 
11:57:02.823 -> state changed from 4 to 5
11:57:02.823 -> 说话中...
11:57:02.823 -> ==================Received JSON type: stt 

  

hello iot设备当前状态json上报 : {"session_id":"","type":"iot","update":true,"states":[{"name":"WS2812B","state":{"color1":"{\"red\":128,\"green\":0,\"blue\":128}"}}]} 

  

 

 核心能力原理基础

【AI大模型应用开发】2.1 Function Calling连接外部世界 - 入门与实战(1)

https://zhuanlan.zhihu.com/p/689858409

 

 

image

 

 Function Calling是大模型连接外部世界的通道,目前出现的插件(Plugins )、OpenAI的Actions、各个大模型平台中出现的tools工具集,其实都是Function Calling的范畴。时下大火的OpenAI的GPTs,原理就是使用了Function Calling,例如联网检索、code interpreter。

 

image

 

 

 

image

 

 

image

 

 

image

 

image

 具体的 

首先语音唤醒触发hello消息,服务器回复这个消息

然后触发

image

 然后自动附加iot数据

image

 并将消息设定为iot类型

image

 

image

 根据控制命令触发回调,判断消息类型,取出控制参数,例如名字,函数,操作

 

image

 主函数控制

image

 

 

image

 

一图搞清:小智AI MCP 控制IoT设备,原理+流程拆解

 

 https://zhuanlan.zhihu.com/p/1921139871113781343

 

image

 

image

 

 

 

 

 

 

 

image

 

教程原理

https://dcnmu33qx4fc.feishu.cn/docx/EcXxdXiuJomKDyxjSoIc6af0nig

代码地址

https://github.com/nulllaborg/ai_vox_engine_iot_examples

 

image

 

image

 

image

 

namespace {
std::shared_ptr<ai_vox::iot::Entity> g_led_iot_entity; 
}

// LED
std::vector<ai_vox::iot::Property> led_properties({
    {
        "state",                       // property name
        "LED灯开关状态",               // property description
        ai_vox::iot::ValueType::kBool  // property type
    },
    // add more properties as needed
});

// 2.Define the functions for the LED entity
std::vector<ai_vox::iot::Function> led_functions({
    {"TurnOn",     // function name
     "打开LED灯",  // function description
     {
         // no parameters
     }},
    {"TurnOff",    // function name
     "关闭LED灯",  // function description
     {
         // no parameters
     }},
    // add more functions as needed
});

// 3.Create the LED entity
g_led_iot_entity = std::make_shared<ai_vox::iot::Entity>("Led",                      // name
                                                         "LED灯",                    // description
                                                         std::move(led_properties),  // properties
                                                         std::move(led_functions)    // functions
);

// 4.Initialize the LED entity with default values
g_led_iot_entity->UpdateState("state", false);

// 5.Register the LED entity with the AI Vox engine
ai_vox::Engine::GetInstance().RegisterIotEntity(g_led_iot_entity);

  

image

 

const auto events = ai_vox::Engine::SetObserver()->PopEvents();

for (auto& event : events) {
  if (auto iot_message_event = std::get_if<ai_vox::Observer::IotMessageEvent>(&event)) {
    printf("IOT message: %s, function: %s\n", iot_message_event->name.c_str(), iot_message_event->function.c_str());
    for (const auto& [key, value] : iot_message_event->parameters) {
      if (std::get_if<bool>(&value)) {
        printf("key: %s, value: %s\n", key.c_str(), std::get<bool>(value) ? "true" : "false");
      } else if (std::get_if<std::string>(&value)) {
        printf("key: %s, value: %s\n", key.c_str(), std::get<std::string>(value).c_str());
      } else if (std::get_if<int64_t>(&value)) {
        printf("key: %s, value: %lld\n", key.c_str(), std::get<int64_t>(value));
      }
    }

    if (iot_message_event->name == "Led") {
      if (iot_message_event->function == "TurnOn") {
        printf("turn on led\n");
        digitalWrite(kLedPin, HIGH);
        g_led_iot_entity->UpdateState("state", true);
      } else if (iot_message_event->function == "TurnOff") {
        printf("turn off led\n");
        digitalWrite(kLedPin, LOW);
        g_led_iot_entity->UpdateState("state", false);
      }
    }
  }
}

  

image

 

const auto events = ai_vox::Engine::SetObserver()->PopEvents();

for (auto& event : events) {
  if (auto iot_message_event = std::get_if<ai_vox::Observer::IotMessageEvent>(&event)) {
    printf("IOT message: %s, function: %s\n", iot_message_event->name.c_str(), iot_message_event->function.c_str());
    for (const auto& [key, value] : iot_message_event->parameters) {
      if (std::get_if<bool>(&value)) {
        printf("key: %s, value: %s\n", key.c_str(), std::get<bool>(value) ? "true" : "false");
      } else if (std::get_if<std::string>(&value)) {
        printf("key: %s, value: %s\n", key.c_str(), std::get<std::string>(value).c_str());
      } else if (std::get_if<int64_t>(&value)) {
        printf("key: %s, value: %lld\n", key.c_str(), std::get<int64_t>(value));
      }
    }

    if (iot_message_event->name == "Led") {
      if (iot_message_event->function == "TurnOn") {
        printf("turn on led\n");
        digitalWrite(kLedPin, HIGH);
        g_led_iot_entity->UpdateState("state", true);
      } else if (iot_message_event->function == "TurnOff") {
        printf("turn off led\n");
        digitalWrite(kLedPin, LOW);
        g_led_iot_entity->UpdateState("state", false);
      }
    }
  }
}

  

image

 

image

 

image

 其他

image

 

image

 拷贝到库目录,添加这个些例子到原来的api库中

image

 可以看到新添加的例子

image

 

image

 

image

 

image

 

image

 

image

 

image

 

其他

使用

Adafruit_NeoPixel库编译ws2812灯(使用)时候可能会有编译错误从而导致上传失败,调整编译输出级别,减少警告报警从而导致的失败上传。

 

 

image

 

image

 

测试例子1 WS2812灯和普通灯

装库

image

 在普通led的例子上我追加了ws2812的例子,虽然官方有ws2812的例子,但是我习惯了这个库,比较简单,且没有oled的代码。

image

 

image

 

1 修改wifi密码

image

 

2修改灯的引脚

我用的板子 48引脚封装了一个ws2812单颗灯珠,直接用这个测试。

image

 

image

 https://esp32io.com/tutorials/esp32-ws2812b-led-strip

image

 

constexpr gpio_num_t kMicPinBclk = GPIO_NUM_5; //麦克风 BCLK (BCK, SCLK, SCK)
constexpr gpio_num_t kMicPinWs = GPIO_NUM_4; //麦克风 WS (LRCK, FS, LRCLK)
constexpr gpio_num_t kMicPinDin = GPIO_NUM_6;//克风 DI (SDATA, SDOUT, SDIN)
//kMicPin_L/R = GND 接地 短接 L/R 左/右声道 此引脚通过高低电平标识当前传输的是左声道还是右声道数据

constexpr gpio_num_t kSpeakerPinBclk = GPIO_NUM_15; //功放喇叭 BCLK (BCK, SCLK, SCK)
constexpr gpio_num_t kSpeakerPinWs = GPIO_NUM_16; // 功放喇叭 WS (LRCK, FS, LRCLK) LRC/WS​​左/右时钟(Word Select)​​,标识当前传输的是左声道(低电平)还是右声道(高电平)。
constexpr gpio_num_t kSpeakerPinDout = GPIO_NUM_7; // 功放喇叭 DOUT (SDATA, SDOUT, SDIN) DOUT/SD ​​数据输出(Serial Data)​​,音频数据通过此引脚输出到扬声器或 DAC。



constexpr gpio_num_t kTriggerPin = GPIO_NUM_0; // 按键(按下为低电平)
constexpr gpio_num_t kLedPin = GPIO_NUM_17; //默认的普通灯 随便给了引脚 pin48 接的是一个w2812b灯珠。 pin35引脚是板载LED,自己不要用,不然程序会挂掉。

  

image

 

 

紫色都可以自动设置

image

 

#include <Arduino.h>
#include <WiFi.h>


#include <Adafruit_NeoPixel.h>



#include "ai_vox_engine.h"
#include "ai_vox_observer.h"
#include "i2s_std_audio_input_device.h"
#include "i2s_std_audio_output_device.h"

#ifndef ARDUINO_ESP32S3_DEV
#error "This example only supports ESP32S3-Dev board."
#endif

#ifndef WIFI_SSID
#define WIFI_SSID "CMCC-yaoyao"
#endif

#ifndef WIFI_PASSWORD
#define WIFI_PASSWORD "love123456"
#endif

namespace {
// constexpr gpio_num_t kMicPinBclk = GPIO_NUM_5;
// constexpr gpio_num_t kMicPinWs = GPIO_NUM_2;
// constexpr gpio_num_t kMicPinDin = GPIO_NUM_4;

// constexpr gpio_num_t kSpeakerPinBclk = GPIO_NUM_13;
// constexpr gpio_num_t kSpeakerPinWs = GPIO_NUM_14;
// constexpr gpio_num_t kSpeakerPinDout = GPIO_NUM_1;

// constexpr gpio_num_t kTriggerPin = GPIO_NUM_0;
// constexpr gpio_num_t kLedPin = GPIO_NUM_6;

constexpr gpio_num_t kMicPinBclk = GPIO_NUM_5; //麦克风 BCLK (BCK, SCLK, SCK)
constexpr gpio_num_t kMicPinWs = GPIO_NUM_4; //麦克风 WS (LRCK, FS, LRCLK)
constexpr gpio_num_t kMicPinDin = GPIO_NUM_6;//克风 DI (SDATA, SDOUT, SDIN)
//kMicPin_L/R = GND 接地 短接 L/R 左/右声道 此引脚通过高低电平标识当前传输的是左声道还是右声道数据

constexpr gpio_num_t kSpeakerPinBclk = GPIO_NUM_15; //功放喇叭 BCLK (BCK, SCLK, SCK)
constexpr gpio_num_t kSpeakerPinWs = GPIO_NUM_16; // 功放喇叭 WS (LRCK, FS, LRCLK) LRC/WS​​左/右时钟(Word Select)​​,标识当前传输的是左声道(低电平)还是右声道(高电平)。
constexpr gpio_num_t kSpeakerPinDout = GPIO_NUM_7; // 功放喇叭 DOUT (SDATA, SDOUT, SDIN) DOUT/SD ​​数据输出(Serial Data)​​,音频数据通过此引脚输出到扬声器或 DAC。



constexpr gpio_num_t kTriggerPin = GPIO_NUM_0; // 按键(按下为低电平)
constexpr gpio_num_t kLedPin = GPIO_NUM_17; // pin48 接的是一个w2812b灯珠。 pin35引脚是板载LED,自己不要用,不然程序会挂掉。



auto g_observer = std::make_shared<ai_vox::Observer>();
// 1 - 定义 IOT 实体:创建ai_vox::iot::Entity,声明属性(如LED灯开关状态)和方法(如打开灯TurnOn)。
std::shared_ptr<ai_vox::iot::Entity> g_led_iot_entity;
std::shared_ptr<ai_vox::iot::Entity> g_speaker_iot_entity;

std::shared_ptr<ai_vox::iot::Entity> g_ws2812b_iot_entity;//WS2812
int kLedNum = 1;  // Led nums

auto g_audio_output_device = std::make_shared<ai_vox::I2sStdAudioOutputDevice>(kSpeakerPinBclk, kSpeakerPinWs, kSpeakerPinDout);




//==============WS2812===================



// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1:
#define LED_PIN    48

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 1

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);


void IntwS2812(){

  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)

}

void colorWipe(uint32_t color, int wait) {
  for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    delay(wait);                           //  Pause for a moment
  }
}
// between frames.
void theaterChase(uint32_t color, int wait) {
  for(int a=0; a<10; a++) {  // Repeat 10 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in steps of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show(); // Update strip with new contents
      delay(wait);  // Pause for a moment
    }
  }
}

void testws2812(){

  colorWipe(strip.Color(255,   0,   0), 20); // Red
  colorWipe(strip.Color(  0, 255,   0), 20); // Green
  colorWipe(strip.Color(  0,   0, 255), 20); // Blue

  // Do a theater marquee effect in various colors...
  theaterChase(strip.Color(127, 127, 127), 20); // White, half brightness
  theaterChase(strip.Color(127,   0,   0), 20); // Red, half brightness
  theaterChase(strip.Color(  0,   0, 127), 20); // Blue, half brightness

  //rainbow(10);             // Flowing rainbow cycle along the whole strip
  //theaterChaseRainbow(50); // Rainbow-enhanced theaterChase variant
}


#include <cJSON.h>
std::string ConvertRGBToJsonString(const int64_t red, const int64_t green, const int64_t blue) {
  cJSON* root = cJSON_CreateObject();
  if (!root) {
    return "{}";
  }

  if (red >= 0 && red <= 255) {
    cJSON_AddNumberToObject(root, "red", static_cast<int>(red));
  } else {
    cJSON_AddNumberToObject(root, "red", 0);
  }

  if (green >= 0 && green <= 255) {
    cJSON_AddNumberToObject(root, "green", static_cast<int>(green));
  } else {
    cJSON_AddNumberToObject(root, "green", 0);
  }

  if (blue >= 0 && blue <= 255) {
    cJSON_AddNumberToObject(root, "blue", static_cast<int>(blue));
  } else {
    cJSON_AddNumberToObject(root, "blue", 0);
  }

  const auto json_str = cJSON_PrintUnformatted(root);
  std::string result;
  if (json_str != nullptr) {
    result = json_str;
    cJSON_free(json_str);
  } else {
    result = "{}";
  }

  cJSON_Delete(root);

  return result;
}


//=================================



void InitIot() {




  printf("InitIot\n");
  auto& ai_vox_engine = ai_vox::Engine::GetInstance();
  
  printf("2222222\n");
  // Speaker
  // 1.Define the properties for the speaker entity
  std::vector<ai_vox::iot::Property> speaker_properties({
      {
          "volume",                        // property name
          "当前音量值",                    // property description
          ai_vox::iot::ValueType::kNumber  // property type: number, string or bool
      },
      // add more properties as needed
  });

  // 2.Define the functions for the speaker entity
  std::vector<ai_vox::iot::Function> speaker_functions({
      {"SetVolume",  // function name
       "设置音量",   // function description
       {
           {
               "volume",                         // parameter name
               "0到100之间的整数",               // parameter description
               ai_vox::iot::ValueType::kNumber,  // parameter type
               true                              // parameter required
           },
           // add more parameters as needed
       }},
      // add more functions as needed
  });
  
  // 3.Create the speaker entity
  g_speaker_iot_entity = std::make_shared<ai_vox::iot::Entity>("Speaker",                      // name
                                                               "扬声器",                       // description
                                                               std::move(speaker_properties),  // properties
                                                               std::move(speaker_functions)    // functions
  );
  
  // 4.Initialize the speaker entity with default values
  g_speaker_iot_entity->UpdateState("volume", g_audio_output_device->volume());
  
  printf("333333\n");
  // 5.Register the speaker entity with the AI Vox engine
  ai_vox_engine.RegisterIotEntity(g_speaker_iot_entity);
   printf("4444444\n");
  // LED
  // 1.Define the properties for the LED entity
  std::vector<ai_vox::iot::Property> led_properties({
      {
          "state",                       // property name
          "LED灯开关状态",               // property description
          ai_vox::iot::ValueType::kBool  // property type
      },
      // add more properties as needed
  });

  // 2.Define the functions for the LED entity
  std::vector<ai_vox::iot::Function> led_functions({
      {"TurnOn",     // function name
       "打开LED灯",  // function description
       {
           // no parameters
       }},
      {"TurnOff",    // function name
       "关闭LED灯",  // function description
       {
           // no parameters
       }},
      // add more functions as needed
  });

  // 3.Create the LED entity
  g_led_iot_entity = std::make_shared<ai_vox::iot::Entity>("Led",                      // name
                                                           "LED灯",                    // description
                                                           std::move(led_properties),  // properties
                                                           std::move(led_functions)    // functions
  );

  // 4.Initialize the LED entity with default values
  g_led_iot_entity->UpdateState("state", false);

  // 5.Register the LED entity with the AI Vox engine
  ai_vox_engine.RegisterIotEntity(g_led_iot_entity);


  // ws2812 
  //1 

    std::vector<ai_vox::iot::Property> ws2812b_properties(
    {
      {
          "brightness",                    // property name
          "亮度(0-255)",                   // property description
          ai_vox::iot::ValueType::kNumber  // property type
      },
      {
          "LedNums",                       // property name
          "灯的数量",                      // property description
          ai_vox::iot::ValueType::kNumber  // property type
      },
    });


  for (uint32_t i = 1; i <= kLedNum; ++i) {
    const std::string property_name = "color" + std::to_string(i);
    const std::string property_describe = std::to_string(i) + "号灯颜色";

    ws2812b_properties.push_back({std::move(property_name), std::move(property_describe), ai_vox::iot::ValueType::kString});
  }



 // 2.Define the functions for the WS2812B RGB LED ring entity
  std::vector<ai_vox::iot::Function> ws2812b_functions({
      {"SetIndexColor",    // function name
       "设置指定LED颜色",  // function description
       {
           {
               "index",                          // parameter name
               "LED索引(1-总数)",                // parameter description
               ai_vox::iot::ValueType::kNumber,  // parameter type
               true                              // parameter required
           },
           {"red", "红色值(0-255)", ai_vox::iot::ValueType::kNumber, true},
           {"green", "绿色值(0-255)", ai_vox::iot::ValueType::kNumber, true},
           {"blue", "蓝色值(0-255)", ai_vox::iot::ValueType::kNumber, true},
           // add more parameters as needed
       }},
      {"SetRangeIndexsColor",
       "设置连续LED范围颜色",
       {
           {"start", "起始LED索引(1-总数)", ai_vox::iot::ValueType::kNumber, true},
           {"end", "结束LED索引(1-总数)", ai_vox::iot::ValueType::kNumber, true},
           {"red", "红色值(0-255)", ai_vox::iot::ValueType::kNumber, true},
           {"green", "绿色值(0-255)", ai_vox::iot::ValueType::kNumber, true},
           {"blue", "蓝色值(0-255)", ai_vox::iot::ValueType::kNumber, true},
           // add more parameters as needed
       }},
      {"SetBrightness",
       "设置亮度",
       {
           {"brightness", "亮度值(0-255)", ai_vox::iot::ValueType::kNumber, true},
           // add more parameters as needed
       }},
      {"Clear", "清除所有LED", {}},
      // add more functions as needed
  });

  // 3.Create the WS2812B RGB LED ring entity
  g_ws2812b_iot_entity = std::make_shared<ai_vox::iot::Entity>("WS2812B",                      // name
                                                               "RGB灯环",                      // description
                                                               std::move(ws2812b_properties),  // properties
                                                               std::move(ws2812b_functions)    // functions
  );

   // 4.Initialize the WS2812B RGB LED ring entity with default values
  g_ws2812b_iot_entity->UpdateState("brightness", 128);
  g_ws2812b_iot_entity->UpdateState("LedNums", kLedNum);

  
  for (uint32_t i = 1; i <= kLedNum; ++i) {
    const std::string property_name = "color" + std::to_string(i);
    g_ws2812b_iot_entity->UpdateState(std::move(property_name), R"({"red":0,"green":0,"blue":0})");
  }
  // 5.Register the WS2812B RGB LED ring entity with the AI Vox engine
  ai_vox_engine.RegisterIotEntity(g_ws2812b_iot_entity);
}

#ifdef PRINT_HEAP_INFO_INTERVAL
void PrintMemInfo() {
  if (heap_caps_get_total_size(MALLOC_CAP_SPIRAM) > 0) {
    const auto total_size = heap_caps_get_total_size(MALLOC_CAP_SPIRAM);
    const auto free_size = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
    const auto min_free_size = heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM);
    printf("SPIRAM total size: %zu B (%zu KB), free size: %zu B (%zu KB), minimum free size: %zu B (%zu KB)\n",
           total_size,
           total_size >> 10,
           free_size,
           free_size >> 10,
           min_free_size,
           min_free_size >> 10);
  }

  if (heap_caps_get_total_size(MALLOC_CAP_INTERNAL) > 0) {
    const auto total_size = heap_caps_get_total_size(MALLOC_CAP_INTERNAL);
    const auto free_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
    const auto min_free_size = heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL);
    printf("IRAM total size: %zu B (%zu KB), free size: %zu B (%zu KB), minimum free size: %zu B (%zu KB)\n",
           total_size,
           total_size >> 10,
           free_size,
           free_size >> 10,
           min_free_size,
           min_free_size >> 10);
  }

  if (heap_caps_get_total_size(MALLOC_CAP_DEFAULT) > 0) {
    const auto total_size = heap_caps_get_total_size(MALLOC_CAP_DEFAULT);
    const auto free_size = heap_caps_get_free_size(MALLOC_CAP_DEFAULT);
    const auto min_free_size = heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT);
    printf("DRAM total size: %zu B (%zu KB), free size: %zu B (%zu KB), minimum free size: %zu B (%zu KB)\n",
           total_size,
           total_size >> 10,
           free_size,
           free_size >> 10,
           min_free_size,
           min_free_size >> 10);
  }
}
#endif
}  // namespace
#include <esp_psram.h>
void setup() {
  Serial.begin(115200);
  printf("Init\n");


   if (psramFound()) {
    Serial.println("PSRAM 已启用,大小: " + String(ESP.getPsramSize() / 1024) + " KB");
  } else {
    Serial.println("PSRAM 未启用!");
  }

  if (heap_caps_get_total_size(MALLOC_CAP_SPIRAM) > 0) {
    WiFi.useStaticBuffers(true);
  } else {
    WiFi.useStaticBuffers(false);
  }

  printf("Connecting to WiFi, ssid: %s, password: %s\n", WIFI_SSID, WIFI_PASSWORD);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    printf("Connecting to WiFi, ssid: %s, password: %s\n", WIFI_SSID, WIFI_PASSWORD);
  }

  printf("WiFi connected, IP address: %s\n", WiFi.localIP().toString().c_str());

  pinMode(kLedPin, OUTPUT);
  digitalWrite(kLedPin, LOW);

  IntwS2812();
  testws2812();

  InitIot();

  auto audio_input_device = std::make_shared<ai_vox::I2sStdAudioInputDevice>(kMicPinBclk, kMicPinWs, kMicPinDin);

  auto& ai_vox_engine = ai_vox::Engine::GetInstance();
  ai_vox_engine.SetObserver(g_observer);
  ai_vox_engine.SetTrigger(kTriggerPin);
  ai_vox_engine.SetOtaUrl("https://api.tenclass.net/xiaozhi/ota/");
  ai_vox_engine.ConfigWebsocket("wss://api.tenclass.net/xiaozhi/v1/",
                                {
                                    {"Authorization", "Bearer test-token"},
                                });
  ai_vox_engine.Start(audio_input_device, g_audio_output_device);
  printf("AI Vox engine started,智能语音助手已经开启\n");
}

void loop() {
#ifdef PRINT_HEAP_INFO_INTERVAL
  static uint32_t s_print_heap_info_time = 0;
  if (s_print_heap_info_time == 0 || millis() - s_print_heap_info_time >= PRINT_HEAP_INFO_INTERVAL) {
    s_print_heap_info_time = millis();
    PrintMemInfo();
  }
#endif

  const auto events = g_observer->PopEvents();
  for (auto& event : events) {
    if (auto activation_event = std::get_if<ai_vox::Observer::ActivationEvent>(&event)) {
      // 初次打印激活码
      printf("activation code: %s, message: %s\n", activation_event->code.c_str(), activation_event->message.c_str());
    } else if (auto state_changed_event = std::get_if<ai_vox::Observer::StateChangedEvent>(&event)) {
      printf("state changed from %" PRIu8 " to %" PRIu8 "\n",
             static_cast<uint8_t>(state_changed_event->old_state),
             static_cast<uint8_t>(state_changed_event->new_state));
      switch (state_changed_event->new_state) {
        case ai_vox::ChatState::kIdle: {
          printf("Idle\n");
          break;
        }
        case ai_vox::ChatState::kIniting: {
          printf("Initing...\n");
          break;
        }
        case ai_vox::ChatState::kStandby: {
          printf("Standby\n");
          break;
        }
        case ai_vox::ChatState::kConnecting: {
          printf("Connecting...\n");
          break;
        }
        case ai_vox::ChatState::kListening: {
          printf("Listening...\n");
          break;
        }
        case ai_vox::ChatState::kSpeaking: {
          printf("Speaking...\n");
          break;
        }
        default: {
          break;
        }
      }
    } else if (auto emotion_event = std::get_if<ai_vox::Observer::EmotionEvent>(&event)) {
      printf("emotion: %s\n", emotion_event->emotion.c_str()); // 状态情绪
    } else if (auto chat_message_event = std::get_if<ai_vox::Observer::ChatMessageEvent>(&event)) {
      switch (chat_message_event->role) {
        case ai_vox::ChatRole::kAssistant: {
          printf("role: assistant 智能AI回复消息, content: %s\n", chat_message_event->content.c_str());// 语音助手回复消息
          break;
        }
        case ai_vox::ChatRole::kUser: {
          printf("role: user 使用者询问语音内容,: %s\n", chat_message_event->content.c_str());// 询问者消息
          break;
        }
      }
    } else if (auto iot_message_event = std::get_if<ai_vox::Observer::IotMessageEvent>(&event)) {
      printf("IOT message: %s, function: %s\n", iot_message_event->name.c_str(), iot_message_event->function.c_str());
      for (const auto& [key, value] : iot_message_event->parameters) {
        if (std::get_if<bool>(&value)) {
          printf("key: %s, value: %s\n", key.c_str(), std::get<bool>(value) ? "true" : "false");
        } else if (std::get_if<std::string>(&value)) {
          printf("key: %s, value: %s\n", key.c_str(), std::get<std::string>(value).c_str());
        } else if (std::get_if<int64_t>(&value)) {
          printf("key: %s, value: %lld\n", key.c_str(), std::get<int64_t>(value));
        }
      }

      if (iot_message_event->name == "Led") {
        if (iot_message_event->function == "TurnOn") {
          printf("turn on led\n");
          digitalWrite(kLedPin, HIGH);
          g_led_iot_entity->UpdateState("state", true);  // Note: Must UpdateState after change the device state
        } else if (iot_message_event->function == "TurnOff") {
          printf("turn off led\n");
          digitalWrite(kLedPin, LOW);
          g_led_iot_entity->UpdateState("state", false);  // Note: Must UpdateState after change the device state
        }
      } else if (iot_message_event->name == "Speaker") {
        if (iot_message_event->function == "SetVolume") {
          if (const auto it = iot_message_event->parameters.find("volume"); it != iot_message_event->parameters.end()) {
            auto volume = it->second;
            if (std::get_if<int64_t>(&volume)) {
              printf("Speaker volume: %lld\n", std::get<int64_t>(volume));
              g_audio_output_device->SetVolume(std::get<int64_t>(volume));
              g_speaker_iot_entity->UpdateState("volume", std::get<int64_t>(volume));  // Note: Must UpdateState after change the device state
            }
          }
        }
      }


      else if (iot_message_event->name == "WS2812B") {
       if (iot_message_event->function == "SetIndexColor") {  // Specify the color of a certain light
          int64_t index = 0;
          int64_t red = 0;
          int64_t green = 0;
          int64_t blue = 0;

          if (const auto it = iot_message_event->parameters.find("index"); it != iot_message_event->parameters.end()) {
            if (std::get_if<int64_t>(&it->second)) {
              index = std::get<int64_t>(it->second);

              if (index < 1 || index > kLedNum) {
              //  printf("Error: lamp number is out of range (1-%d), got: %lld\n", kLedNum, index);
                continue;
              }
            } else {
              printf("Error: lamp number acquisition failed, please check.\n");
              continue;
            }
          } else {
            printf("Error: parameter 'index' not obtained, please check.\n");
            continue;
          }

          if (const auto it = iot_message_event->parameters.find("red"); it != iot_message_event->parameters.end()) {
            if (std::get_if<int64_t>(&it->second)) {
              red = std::get<int64_t>(it->second);

              if (red < 0 || red > 255) {
                printf("Error: 'red' out of range (0-255), got: %lld\n", red);
                continue;
              }
            } else {
              printf("Error: Missing required parameter 'red'.\n");
              continue;
            }
          } else {
            printf("Error: parameter 'red' not obtained, please check.\n");
            continue;
          }

          if (const auto it = iot_message_event->parameters.find("green"); it != iot_message_event->parameters.end()) {
            if (std::get_if<int64_t>(&it->second)) {
              green = std::get<int64_t>(it->second);

              if (green < 0 || green > 255) {
                printf("Error: 'green' out of range (0-255), got: %lld\n", green);
                continue;
              }
            } else {
              printf("Error: Missing required parameter 'green'.\n");
              continue;
            }
          } else {
            printf("Error: parameter 'green' not obtained, please check.\n");
            continue;
          }

          if (const auto it = iot_message_event->parameters.find("blue"); it != iot_message_event->parameters.end()) {
            if (std::get_if<int64_t>(&it->second)) {
              blue = std::get<int64_t>(it->second);

              if (blue < 0 || blue > 255) {
                printf("Error: 'blue' out of range (0-255), got: %lld\n", blue);
                continue;
              }
            } else {
              printf("Error: Missing required parameter 'blue'.\n");
              continue;
            }
          } else {
            printf("Error: parameter 'blue' not obtained, please check.\n");
            continue;
          }

          printf("Set LED %lld to color RGB(%lld, %lld, %lld)\n", index, red, green, blue);

          const std::string property_name = "color" + std::to_string(index);

          const std::string color_str = ConvertRGBToJsonString(red, green, blue);
          g_ws2812b_iot_entity->UpdateState(std::move(property_name), std::move(color_str));


          // g_leds[index - 1] = CRGB(red, green, blue);
          // FastLED.show();
          

          strip.setPixelColor(index-1, strip.Color(red, green, blue));
          strip.show(); // Update strip with new contents
          delay(10);  // Pause for a moment

        } 



         else if (iot_message_event->function == "SetBrightness") {  // Set Brightness
          int64_t brightness = 0;

          if (const auto it = iot_message_event->parameters.find("brightness"); it != iot_message_event->parameters.end()) {
            if (std::get_if<int64_t>(&it->second)) {
              brightness = std::get<int64_t>(it->second);

              if (brightness < 0 || brightness > 255) {
                printf("Error: 'brightness' out of range (0-255), got %lld\n", brightness);
                continue;
              }
            } else {
              printf("Error: Missing required parameter 'brightness'.\n");
              continue;
            }
          } else {
            printf("Error: parameter 'brightness' not obtained, please check.\n");
            continue;
          }
          printf("Set LED brightness: %lld\n", brightness);
          //FastLED.setBrightness(brightness);
          strip.setBrightness(brightness);
          //FastLED.show();
          strip.show();
          delay(10); 
          g_ws2812b_iot_entity->UpdateState("brightness", brightness);

        } else if (iot_message_event->function == "Clear") {  // Turn off all lights
          printf("Clear all LEDs\n");

          // FastLED.clear();
          // FastLED.show();
          strip.clear();  
          strip.show(); 
           delay(10); 

          for (uint32_t i = 1; i <= kLedNum; ++i) {
            std::string property_name = "color" + std::to_string(i);
            g_ws2812b_iot_entity->UpdateState(std::move(property_name), R"({"red":0,"green":0,"blue":0})");
          }
        }



      }//


    }
  }

   



  taskYIELD();
}

  

 

posted on 2025-08-06 18:02  MKT-porter  阅读(71)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3