kylinpoet 发表于 2024-4-15 18:49:31

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]
查看完整版本: Beetle ESP32 C6试用评测【2】AIGC大爆发