Beetle ESP32 C6试用评测【2】AIGC大爆发
本帖最后由 kylinpoet 于 2024-4-15 19:00 编辑一、前言
各位大佬的评测文章陆续上传,屏幕显示、传感器、执行件等陆续上阵,满目琳琅,但好像没有看到声音处理的相关帖子(或者是我没发现?)本来想接个麦克风,用API搞个网络语音识别。但翻遍家里仓库,没有找到可用设备,只好作罢。还是按照原思路,把esp32和现在流行的AIGC做个联结。
笔者在 前文 最后的内容中提到的ESP32 Web Server,就是为本文准备的。
https://mc.dfrobot.com.cn/data/attachment/forum/202404/11/013358tuuzcwzoo747aq1w.png
二、AIGC平台和智谱清言
现在市面上的AIGC平台很多,有开源也有商用的。由清华智谱研发的 ChatGLM 效果是较理性的。正好这几天在本地搭建了白嫖glm4的API服务,正好拿来试手,当然大家有兴趣也可以使用 ChatGLM智谱清言 的网络端进行试用(选择glm4效果更佳,可绘图)。
确定好平台后,就可以使用现成的工具来生成板子的python代码了,我们可以看到,生成的代码逻辑比较准确,基本上可以无损使用:
配置好,相关参数,就可以愉快玩耍了。
在thonny选择主板执行,访问打印的IP地址:
当然,怎么能只有文字呢,要图片也是可以可以顺手捏来的。
三、几个坑点
1. 万恶的Python 2过去了,以为在Python 3里不会有编码问题了,很不幸,因为在mpy里用socket创建Web服务的时候,是用字节字符串进行数据传输的,因此在处理 html 的 form post 传过来的数据时,需要进行编码处理:
当然这个函数,是用GLM4 在线生成的,毕竟mpy 自带的 url 处理函数还不是很完整:
2. 在进行数据post时,要进行data的字节化处理,这里被耽搁了下,主要是要使用:data.encode()这个方法。
3. 当然,还有生成图片时,返回数据的解析处理等,必须使用AIGC来完成,使用起来相当丝滑:
四、完整代码
import socket
import urequests
import json
# WiFi设置
SSID = 'ssid'
PASSWORD = 'pass'
# OpenAI API设置
API_URL = 'http://*.*.*.*:8000/v1/chat/completions'
API_KEY = 'eyJhbG......'
def connect_wifi(ssid, password):
import network
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
print('Connecting to WiFi...')
sta_if.active(True)
sta_if.connect(ssid, password)
while not sta_if.isconnected():
pass
print('WiFi connected')
print('ip:{}'.format(sta_if.ifconfig()))
def decode_html_entities(encoded_str):
import re
# 正则表达式用于找到形式为 %26%23<数字>%3B 的编码实体
pattern = re.compile(r'%26%23(\d+)%3B')
# 函数用于替换每个匹配的实体
def replace_entity(match):
# 提取数字部分,并转换为整数
code_point = int(match.group(1))
# 将整数转换为对应的Unicode字符
return chr(code_point)
# 使用正则表达式的sub方法替换所有匹配的实体
return pattern.sub(replace_entity, encoded_str)
def start_server():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)
while True:
conn, addr = s.accept()
request = str(conn.recv(1024))
print(request)
# 检查是否是POST请求
if 'POST /' in request:
# 解析用户输入
# request = request.decode()
start_index = request.find('prompt=') + len('prompt=')
input_text = request.replace('%20', ' ')
input_text = decode_html_entities(input_text)
print(input_text)
# 使用OpenAI API获取结果
response = use_openai_api(input_text)
# 发送HTTP响应
conn.send('HTTP/1.1 200 OK\n')
conn.send('Content-Type: text/html\n')
conn.send('Connection: close\n\n')
conn.sendall(html_page(response))
else:
# 发送HTML表单
conn.send('HTTP/1.1 200 OK\n')
conn.send('Content-Type: text/html\n')
conn.send('Connection: close\n\n')
conn.sendall(html_page(None))
conn.close()
def use_openai_api(prompt):
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + API_KEY
}
data = json.dumps(
{
"model": "glm4",
"messages": [{
"role": "user",
"content": prompt}],
"stream": False}
)
# try:
print(data)
response = urequests.post(API_URL, headers=headers, data=data.encode())
response = response.json()
print(response)
return response['choices']['message']['content']
# except Exception as e:
# print(str(e))
def extract_image_url(text):
# 使用正则表达式匹配图片链接
import re
image_url_match = re.search(r'!\[.*?\]\((https://.*?\.(png|jpg|jpeg|gif))\)', text)
if image_url_match:
return image_url_match.group(1)
return None
def html_page(result):
# image_url = extract_image_url(result)
if result:
image_url = extract_image_url(result)
if image_url:
response_html = f"<p><img src='{image_url}' alt='OpenAI Response' width='500px'></br >{result}</p>"
else:
response_html = f"<p>{result}</p>"
else:
response_html = ""
return f"""
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<h2>OpenAI Input:</h2>
<form action="/" method="post">
<textarea style="width: 500px; height: 100px;" name="prompt" rows="4" cols="50"></textarea>
<br>
<input type="submit" value="Submit">
</form>
<h2>OpenAI Response:</h2>
{response_html}
</body>
</html>
"""
# 连接到WiFi
connect_wifi(SSID, PASSWORD)
# 启动服务器
start_server()
以上!
页:
[1]