参考
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


代码逻辑
那腾讯元宝做一个测试
输入1
设备的属性和操作定义 json格式
输入2
我要的操作
大模型输出
根据json产生对应的json。
整个代码依靠的是ai的理解能力产生回复信息,而非是官方有专门的api接口。


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结构解析
为什么需要[]?.
-
states字段是一个数组•-
设计意图是允许包含多个设备状态•
-
即使当前只有一个设备(WS2812B),也使用数组形式保持扩展性
-
- 2.
实际应用场景示例
如果系统有多个IoT设备:
- 3.
与无数组的对比
如果不使用数组(错误示范):
这样设计会导致:
- •
无法添加第二个设备状态
- •
修改数据结构时会导致兼容性问题
- •
JSON中的符号含义
|
符号 |
类型 |
用途 |
|---|---|---|
|
|
对象(Object) |
表示键值对集合 |
|
|
数组(Array) |
表示有序的值集合 |
|
|
字符串(String) |
表示文本数据 |
最佳实践建议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

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





具体的
首先语音唤醒触发hello消息,服务器回复这个消息
然后触发

然后自动附加iot数据

并将消息设定为iot类型


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

主函数控制


一图搞清:小智AI MCP 控制IoT设备,原理+流程拆解
https://zhuanlan.zhihu.com/p/1921139871113781343



教程原理
https://dcnmu33qx4fc.feishu.cn/docx/EcXxdXiuJomKDyxjSoIc6af0nig
代码地址
https://github.com/nulllaborg/ai_vox_engine_iot_examples



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);

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);
}
}
}
}

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);
}
}
}
}



其他


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

可以看到新添加的例子







其他
使用


测试例子1 WS2812灯和普通灯
装库

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


1 修改wifi密码

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


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

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,自己不要用,不然程序会挂掉。

紫色都可以自动设置

#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();
}
浙公网安备 33010602011771号