feat: ✨ http简单上报异常以及对话
This commit is contained in:
parent
3b49a8d776
commit
91efe70da0
246
k230/agent_client_http.py
Normal file
246
k230/agent_client_http.py
Normal file
@ -0,0 +1,246 @@
|
||||
import socket
|
||||
import json
|
||||
import time
|
||||
import os
|
||||
import network
|
||||
import struct
|
||||
import gc
|
||||
from audio_module import AudioPlayer
|
||||
|
||||
# Try importing wave, handle different environments
|
||||
try:
|
||||
import media.wave as wave
|
||||
except ImportError:
|
||||
try:
|
||||
import wave
|
||||
except ImportError:
|
||||
wave = None
|
||||
|
||||
|
||||
class AgentClientHTTP:
|
||||
"""
|
||||
K230 Agent Client (HTTP)
|
||||
"""
|
||||
|
||||
def __init__(self, server_host, server_port=8000):
|
||||
self._server_host = server_host
|
||||
self._server_port = server_port
|
||||
self._sta = None
|
||||
self._is_connected = False
|
||||
|
||||
def connect_wifi(self, ssid, password=None, timeout=15):
|
||||
"""
|
||||
Connect to WiFi
|
||||
"""
|
||||
self._sta = network.WLAN(network.STA_IF)
|
||||
self._sta.active(True)
|
||||
|
||||
if password:
|
||||
self._sta.connect(ssid, password)
|
||||
else:
|
||||
self._sta.connect(ssid)
|
||||
|
||||
print("正在连接WiFi: " + ssid + "...")
|
||||
|
||||
start_time = time.time()
|
||||
while not self._sta.isconnected():
|
||||
if time.time() - start_time > timeout:
|
||||
raise RuntimeError("WiFi连接超时: " + ssid)
|
||||
time.sleep(1)
|
||||
try:
|
||||
os.exitpoint()
|
||||
except BaseException:
|
||||
pass
|
||||
|
||||
ip = self._sta.ifconfig()[0]
|
||||
print("WiFi连接成功! IP: " + ip)
|
||||
self._is_connected = True
|
||||
return ip
|
||||
|
||||
def disconnect(self):
|
||||
"""断开网络连接"""
|
||||
if self._sta:
|
||||
if self._sta.isconnected():
|
||||
self._sta.disconnect()
|
||||
self._sta.active(False)
|
||||
print("WiFi已断开,网卡已关闭。")
|
||||
self._is_connected = False
|
||||
|
||||
def trigger_abnormal_state(self, reason, context_data=None):
|
||||
"""
|
||||
Trigger abnormal state and save response as WAV.
|
||||
"""
|
||||
url_path = "/abnormal_trigger"
|
||||
|
||||
payload = {
|
||||
"type": "abnormal_trigger",
|
||||
"trigger_reason": reason,
|
||||
"enable_streaming": True,
|
||||
"context_data": context_data or {}
|
||||
}
|
||||
|
||||
body_json = json.dumps(payload)
|
||||
print(f"[AgentHTTP] 请求服务器: {self._server_host}:{self._server_port}...")
|
||||
|
||||
try:
|
||||
# Send Request
|
||||
response_data = self._send_http_request(url_path, body_json)
|
||||
|
||||
# Parse Header/Body
|
||||
header_end = response_data.find(b"\r\n\r\n")
|
||||
if header_end == -1:
|
||||
print("[AgentHTTP] 响应格式错误")
|
||||
return None
|
||||
|
||||
body_bytes = response_data[header_end + 4:]
|
||||
|
||||
if len(body_bytes) == 0:
|
||||
print("[AgentHTTP] 响应正文为空")
|
||||
return None
|
||||
|
||||
print(f"[AgentHTTP] 成功接收音频数据: {len(body_bytes)} 字节")
|
||||
|
||||
# Save as WAV file
|
||||
# TTS server returns 24000Hz, 1 channel, 16bit (2 bytes) PCM
|
||||
wav_file = "/sdcard/agent_response.wav"
|
||||
self._save_wav(wav_file, body_bytes, rate=24000, channels=1, sampwidth=2)
|
||||
|
||||
return wav_file
|
||||
|
||||
except Exception as e:
|
||||
print(f"[AgentHTTP] 请求失败: {e}")
|
||||
return None
|
||||
|
||||
def _save_wav(self, filename, pcm_data, rate=24000, channels=1, sampwidth=2):
|
||||
"""
|
||||
Save PCM data with WAV header
|
||||
"""
|
||||
print(f"[AgentHTTP] 保存 WAV 文件: {filename} (Rate: {rate}, Ch: {channels})")
|
||||
try:
|
||||
if wave:
|
||||
# Use wave module if available
|
||||
wf = wave.open(filename, 'wb')
|
||||
wf.set_channels(channels)
|
||||
wf.set_sampwidth(sampwidth)
|
||||
wf.set_framerate(rate)
|
||||
wf.write_frames(pcm_data)
|
||||
wf.close()
|
||||
else:
|
||||
# Manual WAV header creation
|
||||
total_len = len(pcm_data) + 36
|
||||
header = struct.pack(
|
||||
'<4sI4s4sIHHIIHH4sI',
|
||||
b'RIFF',
|
||||
total_len,
|
||||
b'WAVE',
|
||||
b'fmt ',
|
||||
16,
|
||||
1,
|
||||
channels,
|
||||
rate,
|
||||
rate * channels * sampwidth,
|
||||
channels * sampwidth,
|
||||
sampwidth * 8,
|
||||
b'data',
|
||||
len(pcm_data))
|
||||
with open(filename, 'wb') as f:
|
||||
f.write(header)
|
||||
f.write(pcm_data)
|
||||
|
||||
except Exception as e:
|
||||
print(f"[AgentHTTP] 保存 WAV 失败: {e}")
|
||||
|
||||
def play_audio_file(self, file_path):
|
||||
"""
|
||||
Play audio file using AudioPlayer.play_file (handles WAV)
|
||||
"""
|
||||
if not file_path:
|
||||
return
|
||||
|
||||
print(f"[AgentHTTP] 正在播放: {file_path}...")
|
||||
|
||||
player = None
|
||||
try:
|
||||
player = AudioPlayer()
|
||||
# play_file will init and start stream, write frames, and then deinit in
|
||||
# finally block
|
||||
player.play_file(file_path)
|
||||
|
||||
print("[AgentHTTP] 播放完成。")
|
||||
|
||||
except Exception as e:
|
||||
print(f"[AgentHTTP] 播放出错: {e}")
|
||||
finally:
|
||||
# Double check deinit to prevent noise/resource leak
|
||||
if player:
|
||||
try:
|
||||
if player.is_running: # Check if flag exists
|
||||
player.deinit()
|
||||
except BaseException:
|
||||
pass
|
||||
|
||||
def _send_http_request(self, path, body_json):
|
||||
"""
|
||||
Send HTTP POST
|
||||
"""
|
||||
addr_info = socket.getaddrinfo(self._server_host, self._server_port)
|
||||
addr = addr_info[0][-1]
|
||||
|
||||
s = socket.socket()
|
||||
s.settimeout(10)
|
||||
|
||||
try:
|
||||
s.connect(addr)
|
||||
body_bytes = body_json.encode('utf-8')
|
||||
|
||||
req = f"POST {path} HTTP/1.1\r\n"
|
||||
req += f"Host: {self._server_host}:{self._server_port}\r\n"
|
||||
req += "Content-Type: application/json\r\n"
|
||||
req += f"Content-Length: {len(body_bytes)}\r\n"
|
||||
req += "Connection: close\r\n\r\n"
|
||||
|
||||
s.send(req.encode('utf-8'))
|
||||
s.send(body_bytes)
|
||||
|
||||
response = bytearray()
|
||||
while True:
|
||||
chunk = s.recv(4096)
|
||||
if not chunk:
|
||||
break
|
||||
response.extend(chunk)
|
||||
|
||||
return response
|
||||
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# ========== CONFIG ==========
|
||||
WIFI_SSID = "dongshengwu"
|
||||
WIFI_PASSWORD = "wds666666"
|
||||
SERVER_HOST = "172.20.10.2"
|
||||
SERVER_PORT = 8000
|
||||
# ============================
|
||||
|
||||
client = AgentClientHTTP(server_host=SERVER_HOST, server_port=SERVER_PORT)
|
||||
|
||||
try:
|
||||
# 1. Connect
|
||||
client.connect_wifi(WIFI_SSID, WIFI_PASSWORD)
|
||||
|
||||
# 2. Trigger & Save
|
||||
print("\n[测试] 触发皮肤状态异常提示...")
|
||||
wav_file = client.trigger_abnormal_state("poor_skin")
|
||||
|
||||
# 3. Play
|
||||
if wav_file:
|
||||
client.play_audio_file(wav_file)
|
||||
|
||||
except Exception as e:
|
||||
print("程序异常: " + str(e))
|
||||
finally:
|
||||
# 4. Clean up resources
|
||||
print("\n[资源清理] 断开 WiFi 并回收资源...")
|
||||
gc.collect()
|
||||
print("测试结束,已安全退出。")
|
||||
Loading…
x
Reference in New Issue
Block a user