init
This commit is contained in:
351
script/start/start_moss_ai.bat
Normal file
351
script/start/start_moss_ai.bat
Normal file
@@ -0,0 +1,351 @@
|
||||
@echo off
|
||||
REM 智能家居代理系统启动脚本 (Windows)
|
||||
REM Smart Home Agent System Startup Script (Windows)
|
||||
REM
|
||||
REM 架构设计:
|
||||
REM - 环境检查模块:统一检查所有运行环境
|
||||
REM - 配置管理模块:集中处理配置文件读取
|
||||
REM - 服务管理模块:统一启动/停止服务
|
||||
REM - 工具函数模块:提供可复用的通用功能
|
||||
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
REM 设置编码为UTF-8
|
||||
chcp 65001 >nul
|
||||
|
||||
echo ========================================
|
||||
echo 智能家居代理系统启动脚本
|
||||
echo Smart Home Agent System Startup Script
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
REM ========================================
|
||||
REM 主流程
|
||||
REM ========================================
|
||||
call :CheckEnvironment
|
||||
call :LocateProjectRoot
|
||||
call :LoadConfiguration
|
||||
call :PrepareDirectories
|
||||
call :CheckDependencies
|
||||
call :StartAllServices
|
||||
call :DisplayServiceInfo
|
||||
call :WaitForExit
|
||||
goto :eof
|
||||
|
||||
REM ========================================
|
||||
REM 环境检查模块 - 统一检查所有必要的运行环境
|
||||
REM ========================================
|
||||
:CheckEnvironment
|
||||
echo 检查运行环境...
|
||||
echo Checking runtime environment...
|
||||
echo.
|
||||
|
||||
call :CheckCommand "python" "Python" "Python 3.8+" "pythonVer"
|
||||
call :CheckCommand "node" "Node.js" "Node.js 16+" "nodeVer"
|
||||
call :CheckCommand "pnpm" "pnpm" "npm install -g pnpm" "pnpmVer"
|
||||
call :CheckCommand "uv" "uv" "pip install uv" "uvVer"
|
||||
echo.
|
||||
goto :eof
|
||||
|
||||
REM 通用命令检查函数
|
||||
REM 参数: %1=命令名 %2=显示名 %3=安装提示 %4=版本变量名
|
||||
:CheckCommand
|
||||
set "cmd=%~1"
|
||||
set "name=%~2"
|
||||
set "install=%~3"
|
||||
set "verVar=%~4"
|
||||
|
||||
%cmd% --version >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo ✗ 错误: 未找到%name%
|
||||
echo ✗ Error: %name% not found
|
||||
echo 请安装: %install%
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
for /f "tokens=*" %%i in ('%cmd% --version 2^>^&1') do (
|
||||
set "%verVar%=%%i"
|
||||
goto :version_found
|
||||
)
|
||||
:version_found
|
||||
call echo ✓ %name%: %%%verVar%%%
|
||||
goto :eof
|
||||
|
||||
REM ========================================
|
||||
REM 项目定位模块 - 自动定位项目根目录
|
||||
REM ========================================
|
||||
:LocateProjectRoot
|
||||
echo 定位项目根目录...
|
||||
echo Locating project root directory...
|
||||
|
||||
set "paths=. .. ..\.."
|
||||
set "found=0"
|
||||
|
||||
for %%p in (%paths%) do (
|
||||
if exist "%%p\config.yaml" (
|
||||
cd /d "%%p" 2>nul
|
||||
set "found=1"
|
||||
goto :root_found
|
||||
)
|
||||
)
|
||||
|
||||
:root_found
|
||||
if "%found%"=="0" (
|
||||
echo ✗ 错误: 未找到配置文件 config.yaml
|
||||
echo ✗ Error: Configuration file config.yaml not found
|
||||
echo 当前目录: %CD%
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo ✓ 配置文件已找到
|
||||
echo ✓ Configuration file found: %CD%
|
||||
echo.
|
||||
goto :eof
|
||||
|
||||
REM ========================================
|
||||
REM 配置管理模块 - 集中处理配置读取和默认值
|
||||
REM ========================================
|
||||
:LoadConfiguration
|
||||
echo 读取配置文件...
|
||||
echo Reading configuration file...
|
||||
|
||||
REM 定义配置项映射:YAML路径|变量名|默认值
|
||||
set "configs=backend.python.port|backendPort|3000"
|
||||
set "configs=%configs% frontend.dev_server.port|frontendPort|1420"
|
||||
set "configs=%configs% agents.conductor.port|conductorPort|12000"
|
||||
set "configs=%configs% agents.air_conditioner.port|airCondPort|12001"
|
||||
set "configs=%configs% agents.air_cleaner.port|airCleanPort|12002"
|
||||
set "configs=%configs% agents.bedside_lamp.port|bedsideLampPort|12004"
|
||||
|
||||
REM 检查PyYAML是否可用
|
||||
python -c "import yaml" >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo 注意: PyYAML 未安装,使用默认端口配置
|
||||
echo Note: PyYAML not installed, using default port configuration
|
||||
call :SetDefaultPorts
|
||||
goto :config_loaded
|
||||
)
|
||||
|
||||
REM 批量读取配置
|
||||
for %%c in (%configs%) do (
|
||||
for /f "tokens=1,2,3 delims=|" %%a in ("%%c") do (
|
||||
call :ReadConfigValue "%%a" "%%b" "%%c"
|
||||
)
|
||||
)
|
||||
|
||||
:config_loaded
|
||||
echo ✓ 配置读取完成
|
||||
echo - 后端端口 / Backend Port: %backendPort%
|
||||
echo - 前端端口 / Frontend Port: %frontendPort%
|
||||
echo - Conductor端口: %conductorPort%
|
||||
echo.
|
||||
goto :eof
|
||||
|
||||
REM 读取单个配置值
|
||||
REM 参数: %1=YAML路径 %2=变量名 %3=默认值
|
||||
:ReadConfigValue
|
||||
set "yamlPath=%~1"
|
||||
set "varName=%~2"
|
||||
set "defaultVal=%~3"
|
||||
|
||||
REM 构建Python代码,逐层访问YAML配置
|
||||
set "pythonCmd=import yaml; c=yaml.safe_load(open('config.yaml')); "
|
||||
set "accessCode=c"
|
||||
for %%k in (%yamlPath:.= %) do (
|
||||
set "accessCode=!accessCode!['%%k']"
|
||||
)
|
||||
set "pythonCmd=!pythonCmd! print(!accessCode!)"
|
||||
|
||||
REM 执行Python代码并验证结果
|
||||
for /f "delims=" %%i in ('python -c "!pythonCmd!" 2^>nul') do (
|
||||
echo %%i | findstr /r "^[0-9][0-9]*$" >nul
|
||||
if not errorlevel 1 (
|
||||
set "%varName%=%%i"
|
||||
goto :value_set
|
||||
)
|
||||
)
|
||||
:value_set
|
||||
REM 如果读取失败,使用默认值
|
||||
if not defined %varName% set "%varName%=%defaultVal%"
|
||||
goto :eof
|
||||
|
||||
REM 设置默认端口值
|
||||
:SetDefaultPorts
|
||||
set "backendPort=3000"
|
||||
set "frontendPort=1420"
|
||||
set "conductorPort=12000"
|
||||
set "airCondPort=12001"
|
||||
set "airCleanPort=12002"
|
||||
set "bedsideLampPort=12004"
|
||||
goto :eof
|
||||
|
||||
REM ========================================
|
||||
REM 目录准备模块 - 创建必要的目录
|
||||
REM ========================================
|
||||
:PrepareDirectories
|
||||
if not exist "logs" mkdir logs
|
||||
if not exist "temp" mkdir temp
|
||||
goto :eof
|
||||
|
||||
REM ========================================
|
||||
REM 依赖检查模块 - 检查并安装前端依赖
|
||||
REM ========================================
|
||||
:CheckDependencies
|
||||
echo 检查前端依赖...
|
||||
echo Checking frontend dependencies...
|
||||
|
||||
if not exist "app\node_modules" (
|
||||
echo ✗ 前端依赖未安装,正在安装...
|
||||
echo ✗ Frontend dependencies not installed, installing...
|
||||
echo.
|
||||
|
||||
pushd app
|
||||
echo 执行: pnpm install
|
||||
call pnpm install
|
||||
|
||||
if errorlevel 1 (
|
||||
echo ✗ 依赖安装失败!
|
||||
echo ✗ Dependency installation failed!
|
||||
popd
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
popd
|
||||
echo ✓ 依赖安装完成
|
||||
) else (
|
||||
echo ✓ 前端依赖已安装
|
||||
)
|
||||
echo.
|
||||
goto :eof
|
||||
|
||||
REM ========================================
|
||||
REM 服务启动模块 - 统一管理所有服务启动
|
||||
REM ========================================
|
||||
:StartAllServices
|
||||
|
||||
echo 正在启动 Moss AI 本地开发环境...
|
||||
echo Starting Moss AI Local Development Environment...
|
||||
echo.
|
||||
|
||||
REM 定义服务配置:序号|显示名|英文名|目录|启动命令|端口变量|延迟秒数
|
||||
set "services=1|后端服务|Backend Service|app\backend-python|uv run .|backendPort|3"
|
||||
set "services=%services% 2|总管理代理|Conductor Agent|agents\conductor_agent|uv run .|conductorPort|3"
|
||||
set "services=%services% 3|空调代理|Air Conditioner Agent|agents\air_conditioner_agent|uv run .|airCondPort|2"
|
||||
set "services=%services% 4|空气净化器代理|Air Cleaner Agent|agents\air_cleaner_agent|uv run .|airCleanPort|2"
|
||||
set "services=%services% 5|床头灯代理|Bedside Lamp Agent|agents\bedside_lamp_agent|uv run .|bedsideLampPort|2"
|
||||
set "services=%services% 6|前端开发服务器|Frontend Dev Server|app|pnpm dev|frontendPort|3"
|
||||
|
||||
REM 批量启动所有服务
|
||||
for %%s in (%services%) do (
|
||||
for /f "tokens=1-7 delims=|" %%a in ("%%s") do (
|
||||
call :StartService "%%a" "%%b" "%%c" "%%d" "%%e" "%%f" "%%g"
|
||||
)
|
||||
)
|
||||
|
||||
echo 提示: 所有服务窗口已最小化到任务栏
|
||||
echo Note: All service windows are minimized to taskbar
|
||||
echo.
|
||||
goto :eof
|
||||
|
||||
REM 启动单个服务
|
||||
REM 参数: %1=序号 %2=显示名 %3=英文名 %4=目录 %5=命令 %6=端口变量 %7=延迟
|
||||
:StartService
|
||||
set "idx=%~1"
|
||||
set "nameCN=%~2"
|
||||
set "nameEN=%~3"
|
||||
set "dir=%~4"
|
||||
set "cmd=%~5"
|
||||
set "portVar=%~6"
|
||||
set "delay=%~7"
|
||||
|
||||
call set "port=%%%portVar%%%"
|
||||
|
||||
echo [%idx%/6] 启动%nameCN% (端口 %port%)...
|
||||
echo [%idx%/6] Starting %nameEN% (Port %port%)...
|
||||
start "%nameEN%" /min cmd /k "cd /d %CD%\%dir% && %cmd%"
|
||||
timeout /t %delay% /nobreak >nul
|
||||
echo ✓ %nameCN%已启动
|
||||
echo ✓ %nameEN% started
|
||||
echo.
|
||||
goto :eof
|
||||
|
||||
REM ========================================
|
||||
REM 信息显示模块 - 显示服务地址和使用说明
|
||||
REM ========================================
|
||||
:DisplayServiceInfo
|
||||
echo ========================================
|
||||
echo 所有服务已启动完成!
|
||||
echo All services started successfully!
|
||||
echo ========================================
|
||||
echo.
|
||||
echo ╔════════════════════════════════════════════════════════════╗
|
||||
echo ║ 服务地址 / Service URLs ║
|
||||
echo ╠════════════════════════════════════════════════════════════╣
|
||||
echo ║ ║
|
||||
echo ║ 【前端应用 / Frontend】 ║
|
||||
echo ║ http://localhost:%frontendPort%
|
||||
echo ║ ★ 请在浏览器中打开此地址使用应用 ║
|
||||
echo ║ ║
|
||||
echo ║ 【后端服务 / Backend】 ║
|
||||
echo ║ http://localhost:%backendPort%
|
||||
echo ║ ║
|
||||
echo ║ 【智能代理 / Agents】 ║
|
||||
echo ║ 总管理代理 / Conductor: http://localhost:%conductorPort%
|
||||
echo ║ 空调代理 / Air Conditioner: http://localhost:%airCondPort%
|
||||
echo ║ 空气净化器 / Air Cleaner: http://localhost:%airCleanPort%
|
||||
echo ║ 床头灯 / Bedside Lamp: http://localhost:%bedsideLampPort%
|
||||
echo ║ ║
|
||||
echo ╚════════════════════════════════════════════════════════════╝
|
||||
echo.
|
||||
echo ========================================
|
||||
echo.
|
||||
goto :eof
|
||||
|
||||
REM ========================================
|
||||
REM 退出处理模块 - 等待用户操作并清理资源
|
||||
REM ========================================
|
||||
:WaitForExit
|
||||
echo 提示:关闭此窗口将自动停止所有服务
|
||||
echo Note: Closing this window will stop all services
|
||||
echo.
|
||||
echo 按任意键停止所有服务并退出...
|
||||
echo Press any key to stop all services and exit...
|
||||
pause >nul
|
||||
call :StopAllServices
|
||||
goto :eof
|
||||
|
||||
REM ========================================
|
||||
REM 服务停止模块 - 统一停止所有服务
|
||||
REM ========================================
|
||||
:StopAllServices
|
||||
echo.
|
||||
echo 正在停止所有代理服务...
|
||||
echo Stopping all agent services...
|
||||
echo.
|
||||
|
||||
REM 获取所有需要停止的端口
|
||||
set "ports=%frontendPort% %backendPort% %conductorPort% %airCondPort% %airCleanPort% %bedsideLampPort%"
|
||||
|
||||
REM 批量停止端口对应的进程
|
||||
for %%p in (%ports%) do (
|
||||
call :StopPortProcess %%p
|
||||
)
|
||||
|
||||
echo.
|
||||
echo ✓ 所有服务已停止
|
||||
echo ✓ All services stopped
|
||||
timeout /t 2 /nobreak >nul
|
||||
goto :eof
|
||||
|
||||
REM 停止指定端口的进程
|
||||
REM 参数: %1=端口号
|
||||
:StopPortProcess
|
||||
set "port=%~1"
|
||||
for /f "tokens=5" %%a in ('netstat -ano ^| findstr ":%port% " ^| findstr "LISTENING" 2^>nul') do (
|
||||
echo 停止端口 %port% 的进程 (PID: %%a)
|
||||
echo Stopping process on port %port% (PID: %%a)
|
||||
taskkill /PID %%a /F >nul 2>&1
|
||||
)
|
||||
goto :eof
|
||||
408
script/start/start_moss_ai.ps1
Normal file
408
script/start/start_moss_ai.ps1
Normal file
@@ -0,0 +1,408 @@
|
||||
#!/usr/bin/env pwsh
|
||||
# -*- coding: utf-8 -*-
|
||||
# 智能家居代理系统启动脚本 (PowerShell)
|
||||
# Smart Home Agent System Startup Script (PowerShell)
|
||||
#
|
||||
# 架构设计:
|
||||
# - 环境检查模块:统一检查所有运行环境
|
||||
# - 配置管理模块:集中处理配置文件读取
|
||||
# - 服务管理模块:统一启动/停止服务
|
||||
# - 工具函数模块:提供可复用的通用功能
|
||||
|
||||
# ========================================
|
||||
# 初始化设置
|
||||
# ========================================
|
||||
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
|
||||
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||
[Console]::InputEncoding = [System.Text.Encoding]::UTF8
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
try { chcp 65001 > $null } catch { }
|
||||
|
||||
# ========================================
|
||||
# 全局变量
|
||||
# ========================================
|
||||
$script:Config = @{}
|
||||
$script:Jobs = @()
|
||||
$script:ProjectRoot = ""
|
||||
|
||||
# ========================================
|
||||
# 工具函数模块
|
||||
# ========================================
|
||||
function Write-ColorText {
|
||||
param(
|
||||
[string]$Text,
|
||||
[string]$Color = "White"
|
||||
)
|
||||
Write-Host $Text -ForegroundColor $Color
|
||||
}
|
||||
|
||||
function Write-Section {
|
||||
param([string]$Title)
|
||||
Write-Host ""
|
||||
Write-ColorText "========================================" "Cyan"
|
||||
Write-ColorText $Title "Cyan"
|
||||
Write-ColorText "========================================" "Cyan"
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
function Write-Step {
|
||||
param(
|
||||
[string]$TextCN,
|
||||
[string]$TextEN
|
||||
)
|
||||
Write-ColorText $TextCN "Yellow"
|
||||
Write-ColorText $TextEN "Yellow"
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 环境检查模块 - 统一检查所有必要的运行环境
|
||||
# ========================================
|
||||
function Test-CommandExists {
|
||||
param(
|
||||
[string]$Command,
|
||||
[string]$DisplayName,
|
||||
[string]$InstallHint
|
||||
)
|
||||
|
||||
try {
|
||||
$version = & $Command --version 2>&1
|
||||
if ($LASTEXITCODE -ne 0) { throw }
|
||||
Write-ColorText "✓ $DisplayName`: $version" "Green"
|
||||
return $true
|
||||
}
|
||||
catch {
|
||||
Write-ColorText "✗ 错误: 未找到 $DisplayName" "Red"
|
||||
Write-ColorText "✗ Error: $DisplayName not found" "Red"
|
||||
Write-ColorText " $InstallHint" "Yellow"
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Test-Environment {
|
||||
Write-Step "检查运行环境..." "Checking runtime environment..."
|
||||
|
||||
$checks = @(
|
||||
@{ Command = "python"; Name = "Python"; Hint = "请安装 Python 3.8+ / Please install Python 3.8+" },
|
||||
@{ Command = "node"; Name = "Node.js"; Hint = "请安装 Node.js 16+ / Please install Node.js 16+" },
|
||||
@{ Command = "pnpm"; Name = "pnpm"; Hint = "请运行: npm install -g pnpm" },
|
||||
@{ Command = "uv"; Name = "uv"; Hint = "请运行: pip install uv 或访问 https://docs.astral.sh/uv/" }
|
||||
)
|
||||
|
||||
$allPassed = $true
|
||||
foreach ($check in $checks) {
|
||||
if (-not (Test-CommandExists -Command $check.Command -DisplayName $check.Name -InstallHint $check.Hint)) {
|
||||
$allPassed = $false
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $allPassed) {
|
||||
Read-Host "按Enter键退出 / Press Enter to exit"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 项目定位模块 - 自动定位项目根目录
|
||||
# ========================================
|
||||
function Find-ProjectRoot {
|
||||
Write-Step "定位项目根目录..." "Locating project root directory..."
|
||||
|
||||
$paths = @(".", "..", "..\..")
|
||||
|
||||
foreach ($path in $paths) {
|
||||
$configPath = Join-Path $path "config.yaml"
|
||||
if (Test-Path $configPath) {
|
||||
Set-Location $path
|
||||
$script:ProjectRoot = (Get-Location).Path
|
||||
Write-ColorText "✓ 配置文件已找到: $script:ProjectRoot" "Green"
|
||||
Write-ColorText "✓ Configuration file found: $script:ProjectRoot" "Green"
|
||||
return $true
|
||||
}
|
||||
}
|
||||
|
||||
Write-ColorText "✗ 错误: 未找到配置文件 config.yaml" "Red"
|
||||
Write-ColorText "✗ Error: Configuration file config.yaml not found" "Red"
|
||||
Write-ColorText " 当前目录: $PWD" "Yellow"
|
||||
Read-Host "按Enter键退出 / Press Enter to exit"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 配置管理模块 - 集中处理配置读取和默认值
|
||||
# ========================================
|
||||
function Read-YamlConfig {
|
||||
param([string]$Pattern, [int]$DefaultValue)
|
||||
|
||||
$yamlContent = Get-Content "config.yaml" -Raw
|
||||
if ($yamlContent -match $Pattern) {
|
||||
return [int]$matches[1]
|
||||
}
|
||||
return $DefaultValue
|
||||
}
|
||||
|
||||
function Initialize-Config {
|
||||
Write-Step "读取配置文件..." "Reading configuration file..."
|
||||
|
||||
# 定义配置映射:Pattern, Key, DefaultValue
|
||||
$configMappings = @(
|
||||
@{ Pattern = "backend:[\s\S]*?python:[\s\S]*?port:\s*(\d+)"; Key = "BackendPort"; Default = 3000 },
|
||||
@{ Pattern = "frontend:[\s\S]*?dev_server:[\s\S]*?port:\s*(\d+)"; Key = "FrontendPort"; Default = 1420 },
|
||||
@{ Pattern = "conductor:[\s\S]*?port:\s*(\d+)"; Key = "ConductorPort"; Default = 12000 },
|
||||
@{ Pattern = "air_conditioner:[\s\S]*?port:\s*(\d+)"; Key = "AirCondPort"; Default = 12001 },
|
||||
@{ Pattern = "air_cleaner:[\s\S]*?port:\s*(\d+)"; Key = "AirCleanPort"; Default = 12002 },
|
||||
@{ Pattern = "bedside_lamp:[\s\S]*?port:\s*(\d+)"; Key = "BedsideLampPort"; Default = 12004 }
|
||||
)
|
||||
|
||||
foreach ($mapping in $configMappings) {
|
||||
$script:Config[$mapping.Key] = Read-YamlConfig -Pattern $mapping.Pattern -DefaultValue $mapping.Default
|
||||
}
|
||||
|
||||
Write-ColorText "✓ 配置读取完成" "Green"
|
||||
Write-ColorText " - 后端端口 / Backend Port: $($script:Config.BackendPort)" "Gray"
|
||||
Write-ColorText " - 前端端口 / Frontend Port: $($script:Config.FrontendPort)" "Gray"
|
||||
Write-ColorText " - Conductor端口: $($script:Config.ConductorPort)" "Gray"
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 目录准备模块 - 创建必要的目录
|
||||
# ========================================
|
||||
function Initialize-Directories {
|
||||
Write-Step "创建必要的目录..." "Creating necessary directories..."
|
||||
|
||||
$directories = @("logs", "temp")
|
||||
foreach ($dir in $directories) {
|
||||
if (-not (Test-Path $dir)) {
|
||||
New-Item -ItemType Directory -Path $dir | Out-Null
|
||||
Write-ColorText "✓ 创建目录: $dir" "Green"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 环境准备模块 - Python虚拟环境和依赖
|
||||
# ========================================
|
||||
function Initialize-PythonEnvironment {
|
||||
Write-Step "检查 Python 虚拟环境..." "Checking Python virtual environment..."
|
||||
|
||||
if (-not (Test-Path ".venv")) {
|
||||
Write-ColorText "✗ 虚拟环境不存在,正在创建..." "Yellow"
|
||||
Write-ColorText " 执行: uv venv" "Gray"
|
||||
& uv venv
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-ColorText "✗ 虚拟环境创建失败!" "Red"
|
||||
throw "Virtual environment creation failed"
|
||||
}
|
||||
Write-ColorText "✓ 虚拟环境创建完成" "Green"
|
||||
}
|
||||
else {
|
||||
Write-ColorText "✓ 虚拟环境已存在" "Green"
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Step "安装 Python 依赖..." "Installing Python dependencies..."
|
||||
Write-ColorText " 执行: uv sync" "Gray"
|
||||
& uv sync
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-ColorText "✗ Python 依赖安装失败!" "Red"
|
||||
throw "Python dependencies installation failed"
|
||||
}
|
||||
Write-ColorText "✓ Python 依赖已安装" "Green"
|
||||
}
|
||||
|
||||
function Initialize-FrontendDependencies {
|
||||
Write-Step "检查前端依赖..." "Checking frontend dependencies..."
|
||||
|
||||
if (-not (Test-Path "app\node_modules")) {
|
||||
Write-ColorText "✗ 前端依赖未安装,正在安装..." "Yellow"
|
||||
Write-Host ""
|
||||
|
||||
Push-Location "app"
|
||||
Write-ColorText " 执行: pnpm install" "Gray"
|
||||
& pnpm install
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Pop-Location
|
||||
Write-ColorText "✗ 依赖安装失败!" "Red"
|
||||
throw "Frontend dependencies installation failed"
|
||||
}
|
||||
Pop-Location
|
||||
Write-ColorText "✓ 依赖安装完成" "Green"
|
||||
}
|
||||
else {
|
||||
Write-ColorText "✓ 前端依赖已安装" "Green"
|
||||
}
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 服务启动模块 - 统一管理所有服务启动
|
||||
# ========================================
|
||||
function Start-ServiceProcess {
|
||||
param(
|
||||
[int]$Index,
|
||||
[string]$NameCN,
|
||||
[string]$NameEN,
|
||||
[string]$Directory,
|
||||
[string]$Command,
|
||||
[int]$Port,
|
||||
[int]$Delay
|
||||
)
|
||||
|
||||
Write-ColorText "[$Index/6] 启动$NameCN (端口 $Port)..." "Cyan"
|
||||
Write-ColorText "[$Index/6] Starting $NameEN (Port $Port)..." "Cyan"
|
||||
|
||||
$fullPath = Join-Path $script:ProjectRoot $Directory
|
||||
|
||||
$job = Start-Job -ScriptBlock {
|
||||
param($Path, $Cmd)
|
||||
Set-Location $Path
|
||||
Invoke-Expression $Cmd
|
||||
} -ArgumentList $fullPath, $Command -Name $NameEN
|
||||
|
||||
$script:Jobs += @{
|
||||
Job = $job
|
||||
Name = $NameEN
|
||||
Port = $Port
|
||||
}
|
||||
|
||||
Start-Sleep -Seconds $Delay
|
||||
Write-ColorText " ✓ $NameCN`已启动" "Green"
|
||||
Write-ColorText " ✓ $NameEN started" "Green"
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
function Start-AllServices {
|
||||
Write-Section "正在启动 Moss AI 本地开发环境...`nStarting Moss AI Local Development Environment..."
|
||||
|
||||
# 定义服务配置:Index, NameCN, NameEN, Directory, Command, PortKey, Delay
|
||||
$services = @(
|
||||
@{Index=1; NameCN="后端服务"; NameEN="Backend Service"; Dir="app\backend-python"; Cmd="python __main__.py"; PortKey="BackendPort"; Delay=3},
|
||||
@{Index=2; NameCN="总管理代理"; NameEN="Conductor Agent"; Dir="agents\conductor_agent"; Cmd="python __main__.py"; PortKey="ConductorPort"; Delay=3},
|
||||
@{Index=3; NameCN="空调代理"; NameEN="Air Conditioner Agent"; Dir="agents\air_conditioner_agent"; Cmd="python __main__.py"; PortKey="AirCondPort"; Delay=2},
|
||||
@{Index=4; NameCN="空气净化器代理"; NameEN="Air Cleaner Agent"; Dir="agents\air_cleaner_agent"; Cmd="python __main__.py"; PortKey="AirCleanPort"; Delay=2},
|
||||
@{Index=5; NameCN="床头灯代理"; NameEN="Bedside Lamp Agent"; Dir="agents\bedside_lamp_agent"; Cmd="python __main__.py"; PortKey="BedsideLampPort"; Delay=2},
|
||||
@{Index=6; NameCN="前端开发服务器"; NameEN="Frontend Dev Server"; Dir="app"; Cmd="pnpm dev"; PortKey="FrontendPort"; Delay=3}
|
||||
)
|
||||
|
||||
foreach ($service in $services) {
|
||||
Start-ServiceProcess -Index $service.Index -NameCN $service.NameCN -NameEN $service.NameEN `
|
||||
-Directory $service.Dir -Command $service.Cmd -Port $script:Config[$service.PortKey] -Delay $service.Delay
|
||||
}
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 信息显示模块 - 显示服务地址和使用说明
|
||||
# ========================================
|
||||
function Show-ServiceInfo {
|
||||
Write-Section "所有服务已启动完成!`nAll services started successfully!"
|
||||
|
||||
Write-ColorText "╔════════════════════════════════════════════════════════════╗" "Cyan"
|
||||
Write-ColorText "║ 服务地址 / Service URLs ║" "Cyan"
|
||||
Write-ColorText "╠════════════════════════════════════════════════════════════╣" "Cyan"
|
||||
Write-ColorText "║ ║" "Cyan"
|
||||
Write-ColorText "║ 【前端应用 / Frontend】 ║" "Cyan"
|
||||
Write-ColorText "║ http://localhost:$($script:Config.FrontendPort)" "Yellow"
|
||||
Write-ColorText "║ ★ 请在浏览器中打开此地址使用应用 ║" "Cyan"
|
||||
Write-ColorText "║ ║" "Cyan"
|
||||
Write-ColorText "║ 【后端服务 / Backend】 ║" "Cyan"
|
||||
Write-ColorText "║ http://localhost:$($script:Config.BackendPort)" "White"
|
||||
Write-ColorText "║ ║" "Cyan"
|
||||
Write-ColorText "║ 【智能代理 / Agents】 ║" "Cyan"
|
||||
Write-ColorText "║ 总管理代理 / Conductor: http://localhost:$($script:Config.ConductorPort)" "White"
|
||||
Write-ColorText "║ 空调代理 / Air Conditioner: http://localhost:$($script:Config.AirCondPort)" "White"
|
||||
Write-ColorText "║ 空气净化器 / Air Cleaner: http://localhost:$($script:Config.AirCleanPort)" "White"
|
||||
Write-ColorText "║ 床头灯 / Bedside Lamp: http://localhost:$($script:Config.BedsideLampPort)" "White"
|
||||
Write-ColorText "║ ║" "Cyan"
|
||||
Write-ColorText "╚════════════════════════════════════════════════════════════╝" "Cyan"
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 服务停止模块 - 统一停止所有服务
|
||||
# ========================================
|
||||
function Stop-AllServices {
|
||||
Write-Host ""
|
||||
Write-ColorText "正在停止所有服务..." "Yellow"
|
||||
Write-ColorText "Stopping all services..." "Yellow"
|
||||
Write-Host ""
|
||||
|
||||
# 停止所有后台任务
|
||||
foreach ($jobInfo in $script:Jobs) {
|
||||
if ($jobInfo.Job.State -eq 'Running') {
|
||||
Write-ColorText "停止服务: $($jobInfo.Name)" "Gray"
|
||||
Stop-Job -Job $jobInfo.Job
|
||||
Remove-Job -Job $jobInfo.Job -Force
|
||||
}
|
||||
}
|
||||
|
||||
# 停止端口占用的进程
|
||||
$ports = @(
|
||||
$script:Config.FrontendPort,
|
||||
$script:Config.BackendPort,
|
||||
$script:Config.ConductorPort,
|
||||
$script:Config.AirCondPort,
|
||||
$script:Config.AirCleanPort,
|
||||
$script:Config.BedsideLampPort
|
||||
)
|
||||
|
||||
foreach ($port in $ports) {
|
||||
$connections = Get-NetTCPConnection -LocalPort $port -ErrorAction SilentlyContinue
|
||||
foreach ($conn in $connections) {
|
||||
$process = Get-Process -Id $conn.OwningProcess -ErrorAction SilentlyContinue
|
||||
if ($process) {
|
||||
Write-ColorText "停止端口 $port 的进程: $($process.Name) (PID: $($process.Id))" "Gray"
|
||||
Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-ColorText "✓ 所有服务已停止" "Green"
|
||||
Write-ColorText "✓ All services stopped" "Green"
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 主流程
|
||||
# ========================================
|
||||
function Main {
|
||||
try {
|
||||
Clear-Host
|
||||
Write-Section "智能家居代理系统启动脚本`nSmart Home Agent System Startup Script"
|
||||
|
||||
Test-Environment
|
||||
Find-ProjectRoot
|
||||
Initialize-Config
|
||||
Initialize-Directories
|
||||
Initialize-PythonEnvironment
|
||||
Initialize-FrontendDependencies
|
||||
Start-AllServices
|
||||
Show-ServiceInfo
|
||||
|
||||
Write-ColorText "提示:按 Ctrl+C 停止所有服务并退出" "Yellow"
|
||||
Write-ColorText "Note: Press Ctrl+C to stop all services and exit" "Yellow"
|
||||
Write-Host ""
|
||||
|
||||
# 等待用户中断
|
||||
try {
|
||||
while ($true) {
|
||||
Start-Sleep -Seconds 1
|
||||
}
|
||||
}
|
||||
catch {
|
||||
# Ctrl+C 被按下
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-ColorText "`n✗ 发生错误: $_" "Red"
|
||||
Write-ColorText "✗ Error occurred: $_" "Red"
|
||||
}
|
||||
finally {
|
||||
Stop-AllServices
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
}
|
||||
|
||||
# 运行主程序
|
||||
Main
|
||||
391
script/start/start_moss_ai.sh
Normal file
391
script/start/start_moss_ai.sh
Normal file
@@ -0,0 +1,391 @@
|
||||
#!/bin/bash
|
||||
# 智能家居代理系统启动脚本 (Linux/macOS)
|
||||
# Smart Home Agent System Startup Script (Linux/macOS)
|
||||
#
|
||||
# 架构设计:
|
||||
# - 环境检查模块:统一检查所有运行环境
|
||||
# - 配置管理模块:集中处理配置文件读取
|
||||
# - 服务管理模块:统一启动/停止服务
|
||||
# - 工具函数模块:提供可复用的通用功能
|
||||
|
||||
# ========================================
|
||||
# 初始化设置
|
||||
# ========================================
|
||||
set -e # 遇到错误立即退出
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
GRAY='\033[0;90m'
|
||||
NC='\033[0m'
|
||||
|
||||
# 全局变量
|
||||
declare -A CONFIG
|
||||
declare -a PIDS
|
||||
PROJECT_ROOT=""
|
||||
|
||||
# ========================================
|
||||
# 工具函数模块
|
||||
# ========================================
|
||||
print_section() {
|
||||
echo
|
||||
echo -e "${CYAN}========================================${NC}"
|
||||
echo -e "${CYAN}$1${NC}"
|
||||
echo -e "${CYAN}========================================${NC}"
|
||||
echo
|
||||
}
|
||||
|
||||
print_step() {
|
||||
echo -e "${YELLOW}$1${NC}"
|
||||
echo -e "${YELLOW}$2${NC}"
|
||||
echo
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✓ $1${NC}"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}✗ $1${NC}"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${GRAY} $1${NC}"
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 环境检查模块 - 统一检查所有必要的运行环境
|
||||
# ========================================
|
||||
check_command() {
|
||||
local cmd=$1
|
||||
local name=$2
|
||||
local hint=$3
|
||||
|
||||
if ! command -v "$cmd" &> /dev/null; then
|
||||
print_error "错误: 未找到 $name"
|
||||
print_error "Error: $name not found"
|
||||
echo -e "${YELLOW} $hint${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local version=$("$cmd" --version 2>&1 | head -1)
|
||||
print_success "$name: $version"
|
||||
return 0
|
||||
}
|
||||
|
||||
check_environment() {
|
||||
print_step "检查运行环境..." "Checking runtime environment..."
|
||||
|
||||
local all_passed=1
|
||||
|
||||
check_command "python3" "Python" "请安装 Python 3.8+ / Please install Python 3.8+" || all_passed=0
|
||||
check_command "node" "Node.js" "请安装 Node.js 16+ / Please install Node.js 16+" || all_passed=0
|
||||
check_command "pnpm" "pnpm" "请运行: npm install -g pnpm" || all_passed=0
|
||||
check_command "uv" "uv" "请运行: pip install uv 或访问 https://docs.astral.sh/uv/" || all_passed=0
|
||||
|
||||
echo
|
||||
|
||||
if [ $all_passed -eq 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 项目定位模块 - 自动定位项目根目录
|
||||
# ========================================
|
||||
find_project_root() {
|
||||
print_step "定位项目根目录..." "Locating project root directory..."
|
||||
|
||||
local paths=("." ".." "../..")
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
if [ -f "$path/config.yaml" ]; then
|
||||
cd "$path" || exit 1
|
||||
PROJECT_ROOT=$(pwd)
|
||||
print_success "配置文件已找到: $PROJECT_ROOT"
|
||||
print_success "Configuration file found: $PROJECT_ROOT"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
print_error "错误: 未找到配置文件 config.yaml"
|
||||
print_error "Error: Configuration file config.yaml not found"
|
||||
print_error "当前目录: $PWD"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 配置管理模块 - 集中处理配置读取和默认值
|
||||
# ========================================
|
||||
read_yaml_port() {
|
||||
local pattern=$1
|
||||
local default=$2
|
||||
|
||||
local port=$(grep -E "$pattern" config.yaml | head -1 | sed 's/.*port: *\([0-9]*\).*/\1/')
|
||||
echo "${port:-$default}"
|
||||
}
|
||||
|
||||
initialize_config() {
|
||||
print_step "读取配置文件..." "Reading configuration file..."
|
||||
|
||||
# 定义配置映射:pattern|key|default
|
||||
local configs=(
|
||||
"backend:.*python:.*port:|BackendPort|3000"
|
||||
"frontend:.*dev_server:.*port:|FrontendPort|1420"
|
||||
"conductor:.*port:|ConductorPort|12000"
|
||||
"air_conditioner:.*port:|AirCondPort|12001"
|
||||
"air_cleaner:.*port:|AirCleanPort|12002"
|
||||
"bedside_lamp:.*port:|BedsideLampPort|12004"
|
||||
)
|
||||
|
||||
for config_line in "${configs[@]}"; do
|
||||
IFS='|' read -r pattern key default <<< "$config_line"
|
||||
CONFIG[$key]=$(read_yaml_port "$pattern" "$default")
|
||||
done
|
||||
|
||||
print_success "配置读取完成"
|
||||
print_info "后端端口 / Backend Port: ${CONFIG[BackendPort]}"
|
||||
print_info "前端端口 / Frontend Port: ${CONFIG[FrontendPort]}"
|
||||
print_info "Conductor端口: ${CONFIG[ConductorPort]}"
|
||||
echo
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 目录准备模块 - 创建必要的目录
|
||||
# ========================================
|
||||
initialize_directories() {
|
||||
mkdir -p logs temp
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 环境准备模块 - Python虚拟环境和依赖
|
||||
# ========================================
|
||||
initialize_python_environment() {
|
||||
print_step "检查 Python 虚拟环境..." "Checking Python virtual environment..."
|
||||
|
||||
if [ ! -d ".venv" ]; then
|
||||
print_error "虚拟环境不存在,正在创建..."
|
||||
print_error "Virtual environment not found, creating..."
|
||||
print_info "执行: uv venv"
|
||||
uv venv
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
print_error "虚拟环境创建失败!"
|
||||
print_error "Virtual environment creation failed!"
|
||||
exit 1
|
||||
fi
|
||||
print_success "虚拟环境创建完成"
|
||||
else
|
||||
print_success "虚拟环境已存在"
|
||||
fi
|
||||
|
||||
echo
|
||||
print_step "安装 Python 依赖..." "Installing Python dependencies..."
|
||||
print_info "执行: uv sync"
|
||||
uv sync
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
print_error "Python 依赖安装失败!"
|
||||
print_error "Python dependencies installation failed!"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Python 依赖已安装"
|
||||
}
|
||||
|
||||
initialize_frontend_dependencies() {
|
||||
print_step "检查前端依赖..." "Checking frontend dependencies..."
|
||||
|
||||
if [ ! -d "app/node_modules" ]; then
|
||||
print_error "前端依赖未安装,正在安装..."
|
||||
print_error "Frontend dependencies not installed, installing..."
|
||||
echo
|
||||
|
||||
cd app || exit 1
|
||||
print_info "执行: pnpm install"
|
||||
pnpm install
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
cd ..
|
||||
print_error "依赖安装失败!"
|
||||
print_error "Dependency installation failed!"
|
||||
exit 1
|
||||
fi
|
||||
cd ..
|
||||
print_success "依赖安装完成"
|
||||
else
|
||||
print_success "前端依赖已安装"
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 服务启动模块 - 统一管理所有服务启动
|
||||
# ========================================
|
||||
start_service() {
|
||||
local index=$1
|
||||
local name_cn=$2
|
||||
local name_en=$3
|
||||
local directory=$4
|
||||
local command=$5
|
||||
local port_key=$6
|
||||
local delay=$7
|
||||
|
||||
local port=${CONFIG[$port_key]}
|
||||
|
||||
echo -e "${CYAN}[$index/6] 启动$name_cn (端口 $port)...${NC}"
|
||||
echo -e "${CYAN}[$index/6] Starting $name_en (Port $port)...${NC}"
|
||||
|
||||
cd "$PROJECT_ROOT/$directory" || exit 1
|
||||
|
||||
# 启动服务并重定向输出到日志
|
||||
eval "$command" >> "$PROJECT_ROOT/logs/${name_en// /_}.log" 2>&1 &
|
||||
local pid=$!
|
||||
PIDS+=($pid)
|
||||
|
||||
cd "$PROJECT_ROOT" || exit 1
|
||||
sleep "$delay"
|
||||
|
||||
print_success "$name_cn 已启动"
|
||||
print_success "$name_en started"
|
||||
echo
|
||||
}
|
||||
|
||||
start_all_services() {
|
||||
print_section "正在启动 Moss AI 本地开发环境...
|
||||
Starting Moss AI Local Development Environment..."
|
||||
|
||||
# 定义服务配置:index|name_cn|name_en|directory|command|port_key|delay
|
||||
local services=(
|
||||
"1|后端服务|Backend Service|app/backend-python|uv run .|BackendPort|3"
|
||||
"2|总管理代理|Conductor Agent|agents/conductor_agent|uv run .|ConductorPort|3"
|
||||
"3|空调代理|Air Conditioner Agent|agents/air_conditioner_agent|uv run .|AirCondPort|2"
|
||||
"4|空气净化器|Air Cleaner Agent|agents/air_cleaner_agent|uv run .|AirCleanPort|2"
|
||||
"5|床头灯代理|Bedside Lamp Agent|agents/bedside_lamp_agent|uv run .|BedsideLampPort|2"
|
||||
"6|前端开发服务器|Frontend Dev Server|app|pnpm dev|FrontendPort|3"
|
||||
)
|
||||
|
||||
for service_config in "${services[@]}"; do
|
||||
IFS='|' read -r idx name_cn name_en dir cmd port_key delay <<< "$service_config"
|
||||
start_service "$idx" "$name_cn" "$name_en" "$dir" "$cmd" "$port_key" "$delay"
|
||||
done
|
||||
|
||||
print_info "所有服务窗口正在后台运行"
|
||||
print_info "All services are running in background"
|
||||
echo
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 信息显示模块 - 显示服务地址和使用说明
|
||||
# ========================================
|
||||
show_service_info() {
|
||||
print_section "所有服务已启动完成!
|
||||
All services started successfully!"
|
||||
|
||||
echo -e "${CYAN}╔════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${CYAN}║ 服务地址 / Service URLs ║${NC}"
|
||||
echo -e "${CYAN}╠════════════════════════════════════════════════════════════╣${NC}"
|
||||
echo -e "${CYAN}║ ║${NC}"
|
||||
echo -e "${CYAN}║ 【前端应用 / Frontend】 ║${NC}"
|
||||
echo -e "${YELLOW}║ http://localhost:${CONFIG[FrontendPort]}${NC}"
|
||||
echo -e "${CYAN}║ ★ 请在浏览器中打开此地址使用应用 ║${NC}"
|
||||
echo -e "${CYAN}║ ║${NC}"
|
||||
echo -e "${CYAN}║ 【后端服务 / Backend】 ║${NC}"
|
||||
echo -e "${NC}║ http://localhost:${CONFIG[BackendPort]}${NC}"
|
||||
echo -e "${CYAN}║ ║${NC}"
|
||||
echo -e "${CYAN}║ 【智能代理 / Agents】 ║${NC}"
|
||||
echo -e "${NC}║ 总管理代理 / Conductor: http://localhost:${CONFIG[ConductorPort]}${NC}"
|
||||
echo -e "${NC}║ 空调代理 / Air Conditioner: http://localhost:${CONFIG[AirCondPort]}${NC}"
|
||||
echo -e "${NC}║ 空气净化器 / Air Cleaner: http://localhost:${CONFIG[AirCleanPort]}${NC}"
|
||||
echo -e "${NC}║ 床头灯 / Bedside Lamp: http://localhost:${CONFIG[BedsideLampPort]}${NC}"
|
||||
echo -e "${CYAN}║ ║${NC}"
|
||||
echo -e "${CYAN}╚════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 服务停止模块 - 统一停止所有服务
|
||||
# ========================================
|
||||
stop_all_services() {
|
||||
echo
|
||||
print_step "正在停止所有服务..." "Stopping all services..."
|
||||
|
||||
# 停止所有启动的进程
|
||||
for pid in "${PIDS[@]}"; do
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
print_info "停止进程 PID: $pid"
|
||||
kill "$pid" 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
|
||||
# 停止端口占用的进程
|
||||
local ports=(
|
||||
"${CONFIG[FrontendPort]}"
|
||||
"${CONFIG[BackendPort]}"
|
||||
"${CONFIG[ConductorPort]}"
|
||||
"${CONFIG[AirCondPort]}"
|
||||
"${CONFIG[AirCleanPort]}"
|
||||
"${CONFIG[BedsideLampPort]}"
|
||||
)
|
||||
|
||||
for port in "${ports[@]}"; do
|
||||
# Linux
|
||||
if command -v lsof &> /dev/null; then
|
||||
local pid=$(lsof -ti:"$port" 2>/dev/null || true)
|
||||
if [ -n "$pid" ]; then
|
||||
print_info "停止端口 $port 的进程 (PID: $pid)"
|
||||
kill "$pid" 2>/dev/null || true
|
||||
fi
|
||||
# macOS alternative
|
||||
elif command -v netstat &> /dev/null; then
|
||||
local pid=$(netstat -vanp tcp 2>/dev/null | grep "\.$port " | awk '{print $9}' | head -1)
|
||||
if [ -n "$pid" ]; then
|
||||
print_info "停止端口 $port 的进程 (PID: $pid)"
|
||||
kill "$pid" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
print_success "所有服务已停止"
|
||||
print_success "All services stopped"
|
||||
}
|
||||
|
||||
# ========================================
|
||||
# 信号处理 - 捕获 Ctrl+C 等中断信号
|
||||
# ========================================
|
||||
cleanup() {
|
||||
stop_all_services
|
||||
exit 0
|
||||
}
|
||||
|
||||
trap cleanup SIGINT SIGTERM
|
||||
|
||||
# ========================================
|
||||
# 主流程
|
||||
# ========================================
|
||||
main() {
|
||||
clear
|
||||
print_section "智能家居代理系统启动脚本
|
||||
Smart Home Agent System Startup Script"
|
||||
|
||||
check_environment
|
||||
find_project_root
|
||||
initialize_config
|
||||
initialize_directories
|
||||
initialize_python_environment
|
||||
initialize_frontend_dependencies
|
||||
start_all_services
|
||||
show_service_info
|
||||
|
||||
echo -e "${YELLOW}提示:按 Ctrl+C 停止所有服务并退出${NC}"
|
||||
echo -e "${YELLOW}Note: Press Ctrl+C to stop all services and exit${NC}"
|
||||
echo
|
||||
|
||||
# 等待用户中断
|
||||
wait
|
||||
}
|
||||
|
||||
# 运行主程序
|
||||
main
|
||||
Reference in New Issue
Block a user