This commit is contained in:
2026-01-21 09:58:58 +08:00
parent 87c5a07219
commit 9e06e68a15
4 changed files with 326 additions and 6 deletions

152
mcp/router.py Normal file
View File

@@ -0,0 +1,152 @@
from fastmcp import FastMCP, Context
from typing import Optional, Dict, Any
from ..postgresql.database import get_database_instance
from ..postgresql.scada_info import ScadaRepository
from ..postgresql.scheme import SchemeRepository
# 创建 MCP 服务器实例
mcp = FastMCP("TJWater PostgreSQL Service", description="访问水务系统 PostgreSQL 数据库操作")
# 数据库连接辅助函数
async def get_database_connection(db_name: Optional[str] = None, ctx: Context = None):
"""获取数据库连接,支持通过参数指定数据库名称"""
if ctx:
await ctx.info(f"连接到数据库: {db_name or '默认数据库'}")
instance = await get_database_instance(db_name)
async with instance.get_connection() as conn:
yield conn
@mcp.tool
async def get_scada_info(db_name: Optional[str] = None, ctx: Context = None) -> Dict[str, Any]:
"""
查询所有 SCADA 信息
Args:
db_name: 可选的数据库名称,为空时使用默认数据库
ctx: MCP 上下文,用于日志记录
"""
try:
if ctx:
await ctx.info("查询 SCADA 信息...")
async for conn in get_database_connection(db_name, ctx):
scada_data = await ScadaRepository.get_scadas(conn)
if ctx:
await ctx.info(f"检索到 {len(scada_data)} 条 SCADA 记录")
return {"success": True, "data": scada_data, "count": len(scada_data)}
except Exception as e:
error_msg = f"查询 SCADA 信息时发生错误: {str(e)}"
if ctx:
await ctx.error(error_msg)
return {"success": False, "error": error_msg}
@mcp.tool
async def get_scheme_list(db_name: Optional[str] = None, ctx: Context = None) -> Dict[str, Any]:
"""
查询所有方案信息
Args:
db_name: 可选的数据库名称,为空时使用默认数据库
ctx: MCP 上下文,用于日志记录
"""
try:
if ctx:
await ctx.info("查询方案信息...")
async for conn in get_database_connection(db_name, ctx):
scheme_data = await SchemeRepository.get_schemes(conn)
if ctx:
await ctx.info(f"检索到 {len(scheme_data)} 条方案记录")
return {"success": True, "data": scheme_data, "count": len(scheme_data)}
except Exception as e:
error_msg = f"查询方案信息时发生错误: {str(e)}"
if ctx:
await ctx.error(error_msg)
return {"success": False, "error": error_msg}
@mcp.tool
async def get_burst_locate_results(db_name: Optional[str] = None, ctx: Context = None) -> Dict[str, Any]:
"""
查询所有爆管定位结果
Args:
db_name: 可选的数据库名称,为空时使用默认数据库
ctx: MCP 上下文,用于日志记录
"""
try:
if ctx:
await ctx.info("查询爆管定位结果...")
async for conn in get_database_connection(db_name, ctx):
burst_data = await SchemeRepository.get_burst_locate_results(conn)
if ctx:
await ctx.info(f"检索到 {len(burst_data)} 条爆管记录")
return {"success": True, "data": burst_data, "count": len(burst_data)}
except Exception as e:
error_msg = f"查询爆管定位结果时发生错误: {str(e)}"
if ctx:
await ctx.error(error_msg)
return {"success": False, "error": error_msg}
@mcp.tool
async def get_burst_locate_result_by_incident(
burst_incident: str,
db_name: Optional[str] = None,
ctx: Context = None
) -> Dict[str, Any]:
"""
根据 burst_incident 查询爆管定位结果
Args:
burst_incident: 爆管事件标识符
db_name: 可选的数据库名称,为空时使用默认数据库
ctx: MCP 上下文,用于日志记录
"""
try:
if ctx:
await ctx.info(f"查询爆管事件 {burst_incident} 的结果...")
async for conn in get_database_connection(db_name, ctx):
result = await SchemeRepository.get_burst_locate_result_by_incident(
conn, burst_incident
)
if ctx:
await ctx.info("检索到爆管事件数据")
return result
except Exception as e:
error_msg = f"根据 burst_incident 查询爆管定位结果时发生错误: {str(e)}"
if ctx:
await ctx.error(error_msg)
return {"success": False, "error": error_msg}
# 添加静态配置资源
@mcp.resource("config://database/supported_databases")
def get_supported_databases():
"""列出支持的数据库配置"""
return ["default", "backup", "analytics"]
@mcp.resource("config://api/version")
def get_api_version():
"""获取 API 版本"""
return "1.0.0"
if __name__ == "__main__":
mcp.run()

View File

@@ -412,11 +412,11 @@ def flushing_analysis(
############################################################
def contaminant_simulation(
name: str,
modify_pattern_start_time: str,
modify_total_duration: int = 900,
source: str = None,
concentration: float = None,
source_pattern: str = None,
modify_pattern_start_time: str, # 模拟开始时间,格式为'2024-11-25T09:00:00+08:00'
modify_total_duration: int = 900, # 模拟总历时,秒
source: str = None,# 污染源节点ID
concentration: float = None, # 污染源浓度单位mg/L
source_pattern: str = None, # 污染源时间变化模式名称
scheme_Name: str = None,
) -> None:
"""
@@ -425,7 +425,7 @@ def contaminant_simulation(
:param modify_pattern_start_time: 模拟开始时间,格式为'2024-11-25T09:00:00+08:00'
:param modify_total_duration: 模拟总历时,秒
:param source: 污染源所在的节点ID
:param concentration: 污染源位置处的浓度单位mg/L即默认的污染模拟setting为concentration
:param concentration: 污染源位置处的浓度单位mg/L即默认的污染模拟setting为concentration(应改为 Set point booster
:param source_pattern: 污染源的时间变化模式若不传入则默认以恒定浓度持续模拟时间长度等于duration;
若传入,则格式为{1.0,0.5,1.1}等系数列表pattern_step模拟等于模型的hydraulic time step
:param scheme_Name: 方案名称

Binary file not shown.

168
requirements2.txt Normal file
View File

@@ -0,0 +1,168 @@
annotated-doc==0.0.4
annotated-types==0.7.0
anyio==4.8.0
attrs==25.4.0
Authlib==1.6.6
beartype==0.22.9
beautifulsoup4==4.13.4
cachetools==6.2.4
certifi==2024.8.30
cffi==2.0.0
chardet==5.2.0
charset-normalizer==3.4.0
click==8.1.8
cloudpickle==3.1.2
colorama==0.4.6
contourpy==1.3.2
cryptography==46.0.3
cycler==0.12.1
cyclopts==4.5.0
Cython==3.0.12
diskcache==5.6.3
distro==1.9.0
dnspython==2.8.0
docstring_parser==0.17.0
docutils==0.21.2
dotenv==0.9.9
ecos==2.0.14
email-validator==2.3.0
esda==2.7.0
et_xmlfile==2.0.0
exceptiongroup==1.3.1
fakeredis==2.33.0
fastapi==0.128.0
fastmcp==2.9.2
fonttools==4.58.0
future==0.18.3
GeoAlchemy2==0.17.1
geopandas==1.0.1
greenlet==3.1.1
h11==0.14.0
httpcore==1.0.7
httpx==0.28.1
httpx-sse==0.4.3
idna==3.10
importlib_metadata==8.7.1
influxdb-client==1.48.0
iniconfig==2.0.0
jaraco.classes==3.4.0
jaraco.context==6.1.0
jaraco.functools==4.4.0
jeepney==0.9.0
Jinja2==3.1.6
jiter==0.8.2
joblib==1.5.0
jsonschema==4.26.0
jsonschema-path==0.3.4
jsonschema-specifications==2025.9.1
keyring==25.7.0
Kivy==2.3.0
Kivy-Garden==0.1.5
kiwisolver==1.4.8
libpysal==4.13.0
lupa==2.6
mapclassify==2.8.1
markdown-it-py==3.0.0
MarkupSafe==3.0.3
matplotlib==3.10.3
mcp==1.9.4
mdurl==0.1.2
more-itertools==10.8.0
msgpack==1.1.0
networkx==3.4.2
numexpr==2.14.1
numpy==1.26.2
openai==1.63.0
openapi-pydantic==0.5.1
openpyxl==3.1.5
opentelemetry-api==1.39.1
opentelemetry-exporter-prometheus==0.60b1
opentelemetry-instrumentation==0.60b1
opentelemetry-sdk==1.39.1
opentelemetry-semantic-conventions==0.60b1
osqp==1.0.5
packaging==25.0
pandas==2.2.3
pathable==0.4.4
pathvalidate==3.3.1
pillow==11.2.1
pipdeptree==2.30.0
platformdirs==4.3.8
pluggy==1.5.0
pointpats==2.5.1
prometheus_client==0.24.1
psycopg==3.2.5
psycopg-binary==3.2.5
psycopg-pool==3.3.0
psycopg2==2.9.10
PuLP==3.1.1
py-key-value-aio==0.3.0
py-key-value-shared==0.3.0
py-linq==1.4.0
pyarmor==9.0.7
pyarmor.cli.core==7.6.4
pybind11-stubgen==2.5.1
pycparser==2.23
pydantic==2.10.6
pydantic-settings==2.12.0
pydantic_core==2.27.2
pydevd-pycharm==243.16718.36
pydocket==0.16.6
Pygments==2.18.0
PyJWT==2.10.1
pykalman==0.10.2
# pymetis @ file:///D:/bld/pymetis_1762455149640/work 通过 conda 安装 pymetis,避免编译问题 conda install -c conda-forge pymetis
pynvim==0.5.0
pyogrio==0.11.0
pyparsing==3.2.3
pyperclip==1.11.0
pyproj==3.7.1
pytest==8.3.5
python-dateutil==2.9.0.post0
python-dotenv==1.2.1
python-json-logger==4.0.0
python-multipart==0.0.20
pytz==2025.2
PyYAML==6.0.3
pyzmq==26.2.1
reactivex==4.0.4
redis==5.2.1
referencing==0.36.2
requests==2.32.3
rich==14.2.0
rich-rst==1.3.2
rpds-py==0.30.0
rtree==1.4.0
schedule==1.2.2
scikit-base==0.12.6
scikit-fuzzy==0.5.0
scikit-learn==1.6.1
scikit-survival==0.26.0
scipy==1.15.2
SecretStorage==3.5.0
setuptools==80.7.1
shapely==2.1.0
shellingham==1.5.4
six==1.17.0
sniffio==1.3.1
sortedcontainers==2.4.0
soupsieve==2.7
spaghetti==1.7.6
spopt==0.6.1
SQLAlchemy==2.0.41
sse-starlette==3.0.4
starlette==0.50.0
threadpoolctl==3.6.0
tqdm==4.67.1
typer==0.21.1
typing-inspection==0.4.0
typing_extensions==4.12.2
tzdata==2025.2
urllib3==2.2.3
uvicorn==0.34.0
websockets==16.0
wheel==0.45.1
wntr==1.3.2
wrapt==1.17.3
zipp==3.23.0
zmq==0.0.0