chore(xiaozhi): 更新配置文件
This commit is contained in:
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"editor.tabSize": 2,
|
||||
"editor.insertSpaces": true,
|
||||
"editor.formatOnSave": true,
|
||||
"python.languageServer": "Pylance",
|
||||
"python.analysis.autoImportCompletions": true,
|
||||
"ruff.organizeImports": true,
|
||||
"[python]": {
|
||||
"editor.defaultFormatter": "charliermarsh.ruff",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.organizeImports": "explicit",
|
||||
"source.fixAll": "explicit"
|
||||
}
|
||||
},
|
||||
"files.exclude": {
|
||||
"**/.git": true,
|
||||
"**/node_modules": true,
|
||||
"**/__pycache__": true,
|
||||
"*.egg-info": true,
|
||||
".venv": true,
|
||||
".mypy_cache": true
|
||||
}
|
||||
}
|
||||
Generated
+3
-3
@@ -335,6 +335,7 @@ name = "open-xiaoai"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
@@ -519,13 +520,12 @@ checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.0"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
|
||||
checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"
|
||||
dependencies = [
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
XIAOZHI_CONFIG = {
|
||||
"OTA_URL": "https://api.tenclass.net/xiaozhi/ota/",
|
||||
"WEBSOCKET_URL": "wss://api.tenclass.net/xiaozhi/v1/",
|
||||
"WEBSOCKET_ACCESS_TOKEN": "xxxxxxxxxxxxx",
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Dict, Any, Optional
|
||||
import threading
|
||||
import requests
|
||||
import socket
|
||||
import threading
|
||||
import uuid
|
||||
from typing import Any, Optional
|
||||
|
||||
from config import XIAOZHI_CONFIG
|
||||
|
||||
logger = logging.getLogger("ConfigManager")
|
||||
|
||||
@@ -16,19 +14,6 @@ class ConfigManager:
|
||||
|
||||
_instance = None
|
||||
_lock = threading.Lock()
|
||||
CONFIG_FILE = Path(os.getcwd()) / "xiaozhi.json"
|
||||
|
||||
# 默认配置
|
||||
DEFAULT_CONFIG = {
|
||||
"CLIENT_ID": None,
|
||||
"DEVICE_ID": None,
|
||||
"NETWORK": {
|
||||
"OTA_VERSION_URL": "https://api.tenclass.net/xiaozhi/ota/",
|
||||
"WEBSOCKET_URL": "wss://api.tenclass.net/xiaozhi/v1/",
|
||||
"WEBSOCKET_ACCESS_TOKEN": "test-token",
|
||||
},
|
||||
"MQTT_INFO": None,
|
||||
}
|
||||
|
||||
def __new__(cls):
|
||||
"""确保单例模式"""
|
||||
@@ -44,49 +29,14 @@ class ConfigManager:
|
||||
self._initialized = True
|
||||
|
||||
# 加载配置
|
||||
self._config = self._load_config()
|
||||
self._config = {
|
||||
"CLIENT_ID": None,
|
||||
"DEVICE_ID": None,
|
||||
"NETWORK": XIAOZHI_CONFIG,
|
||||
}
|
||||
|
||||
self._initialize_client_id()
|
||||
self._initialize_device_id()
|
||||
self._initialize_mqtt_info()
|
||||
|
||||
def _load_config(self) -> Dict[str, Any]:
|
||||
"""加载配置文件,如果不存在则创建"""
|
||||
try:
|
||||
if self.CONFIG_FILE.exists():
|
||||
config = json.loads(self.CONFIG_FILE.read_text(encoding="utf-8"))
|
||||
return self._merge_configs(self.DEFAULT_CONFIG, config)
|
||||
else:
|
||||
self._save_config(self.DEFAULT_CONFIG)
|
||||
return self.DEFAULT_CONFIG.copy()
|
||||
except Exception as e:
|
||||
logger.error(f"Error loading config: {e}")
|
||||
return self.DEFAULT_CONFIG.copy()
|
||||
|
||||
def _save_config(self, config: dict) -> bool:
|
||||
"""保存配置到文件"""
|
||||
try:
|
||||
self.CONFIG_FILE.write_text(
|
||||
json.dumps(config, indent=2, ensure_ascii=False), encoding="utf-8"
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Error saving config: {e}")
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _merge_configs(default: dict, custom: dict) -> dict:
|
||||
"""递归合并配置字典"""
|
||||
result = default.copy()
|
||||
for key, value in custom.items():
|
||||
if (
|
||||
key in result
|
||||
and isinstance(result[key], dict)
|
||||
and isinstance(value, dict)
|
||||
):
|
||||
result[key] = ConfigManager._merge_configs(result[key], value)
|
||||
else:
|
||||
result[key] = value
|
||||
return result
|
||||
|
||||
def get_client_id(self) -> str:
|
||||
"""获取客户端ID"""
|
||||
@@ -122,7 +72,7 @@ class ConfigManager:
|
||||
for part in parts:
|
||||
current = current.setdefault(part, {})
|
||||
current[last] = value
|
||||
return self._save_config(self._config)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating config {path}: {e}")
|
||||
return False
|
||||
@@ -174,83 +124,4 @@ class ConfigManager:
|
||||
logger.error("Failed to save new DEVICE_ID")
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating DEVICE_ID: {e}")
|
||||
|
||||
def _initialize_mqtt_info(self):
|
||||
try:
|
||||
mqtt_info = self._get_ota_version()
|
||||
if mqtt_info:
|
||||
self.update_config("MQTT_INFO", mqtt_info)
|
||||
self.logger.info("MQTT信息已成功更新")
|
||||
return mqtt_info
|
||||
else:
|
||||
self.logger.warning("获取MQTT信息失败,使用已保存的配置")
|
||||
return self.get_config("MQTT_INFO")
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"初始化MQTT信息失败: {e}")
|
||||
return self.get_config("MQTT_INFO")
|
||||
|
||||
def _get_ota_version(self):
|
||||
"""获取OTA服务器的MQTT信息"""
|
||||
MAC_ADDR = self.get_device_id()
|
||||
OTA_VERSION_URL = self.get_config("NETWORK.OTA_VERSION_URL")
|
||||
headers = {"Device-Id": MAC_ADDR, "Content-Type": "application/json"}
|
||||
|
||||
# 构建设备信息payload
|
||||
payload = {
|
||||
"flash_size": 16777216, # 闪存大小 (16MB)
|
||||
"minimum_free_heap_size": 8318916, # 最小可用堆内存
|
||||
"mac_address": MAC_ADDR, # 设备MAC地址
|
||||
"chip_model_name": "esp32s3", # 芯片型号
|
||||
"chip_info": {"model": 9, "cores": 2, "revision": 2, "features": 18},
|
||||
"application": {
|
||||
"name": "xiaozhi",
|
||||
"version": "1.1.2",
|
||||
"idf_version": "v5.3.2-dirty",
|
||||
},
|
||||
"partition_table": [],
|
||||
"ota": {"label": "factory"},
|
||||
"board": {
|
||||
"type": "bread-compact-wifi",
|
||||
"ip": self.get_local_ip(),
|
||||
"mac": MAC_ADDR,
|
||||
},
|
||||
}
|
||||
|
||||
try:
|
||||
# 发送请求到OTA服务器
|
||||
response = requests.post(
|
||||
OTA_VERSION_URL,
|
||||
headers=headers,
|
||||
json=payload,
|
||||
timeout=10,
|
||||
)
|
||||
|
||||
# 检查HTTP状态码
|
||||
if response.status_code != 200:
|
||||
self.logger.error(f"OTA服务器错误: HTTP {response.status_code}")
|
||||
raise ValueError(f"OTA服务器返回错误状态码: {response.status_code}")
|
||||
|
||||
# 解析JSON数据
|
||||
response_data = response.json()
|
||||
|
||||
# 调试信息:打印完整的OTA响应
|
||||
self.logger.debug(
|
||||
f"OTA服务器返回数据: {json.dumps(response_data, indent=4, ensure_ascii=False)}"
|
||||
)
|
||||
|
||||
# 确保"mqtt"信息存在
|
||||
if "mqtt" in response_data:
|
||||
self.logger.info(f"MQTT服务器信息已更新")
|
||||
return response_data["mqtt"]
|
||||
else:
|
||||
self.logger.error("OTA服务器返回的数据无效: MQTT信息缺失")
|
||||
raise ValueError("OTA服务器返回的数据无效,请检查服务器状态或MAC地址!")
|
||||
|
||||
except requests.Timeout:
|
||||
self.logger.error("OTA请求超时,请检查网络或服务器状态")
|
||||
raise ValueError("OTA请求超时!请稍后重试。")
|
||||
|
||||
except requests.RequestException as e:
|
||||
self.logger.error(f"OTA请求失败: {e}")
|
||||
raise ValueError("无法连接到OTA服务器,请检查网络连接!")
|
||||
logger.error(f"Error generating DEVICE_ID: {e}")
|
||||
|
||||
Reference in New Issue
Block a user