Commit 031dfa1e by tinywell

1设备传感器数量查询接口接入;问题类型识别参数说明优化;工具返回数据结构精简

parent a086b59c
......@@ -161,7 +161,7 @@ class MonitorClient(BaseHttpClient):
"deviceType": device_type
}
)
return BaseResponse[List](**data)
return BaseResponse[Dict](**data)
# 示例:添加新的数据接口客户端
class RateClient(BaseHttpClient):
......
......@@ -5,7 +5,9 @@ from langchain_core.tools import BaseTool
from .http_tools import MonitorClient, RateClient
from typing import Type
from ..utils.logger import get_logger
from .code import AreaCodeTool
code_tool = AreaCodeTool()
class MonitorPointResponse():
"""监测点查询结果"""
status: str = Field(..., description="状态")
......@@ -15,15 +17,17 @@ class MonitorPointResponse():
class MonitorPointArgs(BaseModel):
"""监测点查询参数"""
key: str = Field(..., description="行政区划名称(省/市级别均可,只需要最后一级,如长沙市,不需要湖南省)")
year: str = Field("", description="年份,未提及则为空")
disaster_type: str = Field("", description="灾害类型,如崩塌、滑坡、泥石流、地面塌陷、地面沉降、地裂缝等,未提及则为空")
start_time: str = Field("", description="可选参数:仅当需要查询特定时间区间的监测点数据时才需要指定,默认为空")
end_time: str = Field("", description="可选参数:仅当需要查询特定时间区间的监测点数据时才需要指定,默认为空")
disaster_type: str = Field("", description="需要查询的灾害类型,如崩塌、滑坡、泥石流、地面塌陷、地面沉降、地裂缝等,默认为空")
three_d_model: str = Field("", description="是否需要三维模型,需要为有,不需要为无,默认为空")
ortho_image: str = Field("", description="是否需要正射影像,需要为有,不需要为无,默认为空")
disaster_threat_people_range_start: str = Field("", description="灾害威胁人数范围起始值,如100,未提及则为空")
disaster_threat_people_range_end: str = Field("", description="灾害威胁人数范围结束值,如200,未提及则为空")
disaster_scale_start: str = Field("", description="灾害规模范围起始值,灾害为崩塌、滑坡、泥石流时表示体积,灾害为地面塌陷、地面沉降时表示面积,为地裂缝时表示长度,未提及则为空")
disaster_scale_end: str = Field("", description="灾害规模范围结束值,灾害为崩塌、滑坡、泥石流时表示体积,灾害为地面塌陷、地面沉降时表示面积,为地裂缝时表示长度,未提及则为空")
device_type: str = Field("", description="设备类型(例如 加速度、位移、温度、湿度、裂缝计等),默认为空")
disaster_threat_people_range_start: str = Field("", description="灾害威胁人数范围起始值,如100,默认为空")
disaster_threat_people_range_end: str = Field("", description="灾害威胁人数范围结束值,如200,默认为空")
disaster_scale_start: str = Field("", description="灾害规模范围起始值,灾害为崩塌、滑坡、泥石流时表示体积,灾害为地面塌陷、地面沉降时表示面积,为地裂缝时表示长度,默认为空")
disaster_scale_end: str = Field("", description="灾害规模范围结束值,灾害为崩塌、滑坡、泥石流时表示体积,灾害为地面塌陷、地面沉降时表示面积,为地裂缝时表示长度,默认为空")
device_type: str = Field("", description="设备类型或者传感器类型,当查询设备或传感器信息时需要(例如 加速度、位移、温度、湿度、裂缝计、雨量等),默认为空")
class MonitorPointTool(BaseTool):
"""查询监测点信息的工具"""
......@@ -32,7 +36,7 @@ class MonitorPointTool(BaseTool):
可以查询任意省/市/区县级别的监测点数据,也可以通过灾害类型、灾害规模、灾害威胁人数范围、设备类型等条件查询。
输入参数为行政区划名称,如:湖南省、长沙市、岳麓区等。
返回该区域内的监测点列表,包含位置、经纬度等详细信息。
还可以查询监测点下相关监测设备信息,比如设备数量等。
还可以查询监测点下相关监测设备、传感器信息,比如设备数量、传感器数量等。
"""
args_schema: Type[BaseModel] = MonitorPointArgs
client: Any = Field(None, exclude=True)
......@@ -50,16 +54,18 @@ class MonitorPointTool(BaseTool):
self.client = MonitorClient(base_url=base_url)
self.logger = get_logger("MonitorPointTool")
def _run(self, key: str, year: str = "", disaster_type: str = "",
def _run(self, key: str, start_time: str = "", end_time: str = "", disaster_type: str = "",
three_d_model: str = "", ortho_image: str = "",
disaster_threat_people_range_start: str = "", disaster_threat_people_range_end: str = "",
disaster_scale_start: str = "", disaster_scale_end: str = "", device_type: str = "") -> Dict[str, Any]:
disaster_scale_start: str = "", disaster_scale_end: str = "", device_type: str = "",
query_type: str = "points") -> Dict[str, Any]:
"""
执行监测点查询
Args:
key: 行政区划名称
year: 年份
start_time: 开始时间
end_time: 结束时间
disaster_type: 灾害类型
three_d_model: 是否需要三维模型
ortho_image: 是否需要正射影像
......@@ -67,23 +73,97 @@ class MonitorPointTool(BaseTool):
disaster_threat_people_range_end: 灾害威胁人数范围结束值
disaster_scale_start: 灾害规模范围起始值
disaster_scale_end: 灾害规模范围结束值
device_required: 是否需要设备相关信息
device_type: 设备类型
query_type: 查询类型
Returns:
Dict: 包含查询结果的字典
"""
if len(device_type) > 0:
query_type = "2"
if query_type == "2":
return self._get_device_info(key, start_time, end_time, device_type)
else:
year = start_time.split("-")[0]
return self._get_points_info(key, year, disaster_type, three_d_model, ortho_image, disaster_threat_people_range_start, disaster_threat_people_range_end, disaster_scale_start, disaster_scale_end, device_type)
def _get_device_info(self, key: str, start_time: str = "", end_time: str = "", device_type: str = ""):
self.logger.info(f"开始查询设备信息,区域: {key}")
code = ""
if key != "":
self.logger.debug(f"查找区域代码: {key}")
codes = code_tool.find_code(key)
if codes is None or len(codes) == 0:
error_msg = f'未找到匹配的区域代码: {key}'
self.logger.warning(error_msg)
return {'code': 400, 'message': error_msg}
code = codes[0][1]
self.logger.debug(f"找到区域代码: {code}")
try:
response = self.client.query_device_and_sensor(code, start_time, end_time, device_type)
self.logger.debug(f"API响应: {response}")
if response.type != 1 or len(response.resultdata) == 0:
error_msg = f"查询失败: {response.message},请检查是否有相关数据权限"
self.logger.warning(error_msg)
return {
'code': 400,
'message': error_msg
}
self.logger.info(f"查询设备信息成功,设备数量: {len(response.resultdata['DeviceList'])}")
devices_info = []
for device in response.resultdata["DeviceList"]:
devices_info.append({
"设备编号": device["DEVICECODE"],
"设备名称": device["DEVICETYPENAME"],
# "GUID": device["GUID"]
})
self.logger.debug(f"处理设备数据: {devices_info}")
sensors_info = []
for sensor in response.resultdata["SensorList"]:
sensors_info.append({
"传感器编号": sensor["SENSORCODE"],
"传感器名称": sensor["DEVICETYPENAME"],
# "GUID": sensor["GUID"]
})
self.logger.debug(f"处理传感器数据: {sensors_info}")
device_table_header = list(devices_info[0].keys())
device_table_data = []
for item in devices_info:
device_table_data.append(list(item.values()))
sensor_table_header = list(sensors_info[0].keys())
sensor_table_data = []
for item in sensors_info:
sensor_table_data.append(list(item.values()))
result = {
'code': 200,
'message': f"在{key}找到{len(devices_info)}个设备信息, {len(sensors_info)}个传感器信息",
# 'devices': {
# 'table_header': device_table_header,
# 'table_data': device_table_data
# },
# 'sensors': {
# 'table_header': sensor_table_header,
# 'table_data': sensor_table_data
# }
}
return result
except Exception as e:
error_msg = f"查询失败: {str(e)}"
self.logger.error(error_msg, exc_info=True)
return {
'code': 400,
'message': error_msg
}
def _get_points_info(self, key: str, year: str = "", disaster_type: str = "",
three_d_model: str = "", ortho_image: str = "",
disaster_threat_people_range_start: str = "", disaster_threat_people_range_end: str = "",
disaster_scale_start: str = "", disaster_scale_end: str = "", device_type: str = ""):
try:
self.logger.info(f"开始查询监测点信息,区域: {key}")
# code = ""
# if key != "":
# self.logger.debug(f"查找区域代码: {key}")
# codes = code_tool.find_code(key)
# if codes is None or len(codes) == 0:
# error_msg = f'未找到匹配的区域代码: {key}'
# self.logger.warning(error_msg)
# return {'code': 400, 'message': error_msg}
# code = codes[0][1]
# self.logger.debug(f"找到区域代码: {code}")
response = self.client.query_points_sync(key, year,
disaster_type, three_d_model, ortho_image,
......@@ -130,10 +210,18 @@ class MonitorPointTool(BaseTool):
self.logger.info(f"成功获取 {len(points_info)} 个监测点数据")
# markdown = self.to_markdown(points_info)
table_header = list(points_info[0].keys())
table_data = []
for item in points_info:
table_data.append(list(item.values()))
result = {
'code': 200,
'message': f"在{key}找到{len(points_info)}个监测点信息",
'points': points_info,
'points': {
'table_header': table_header,
'table_data': table_data
},
# 'markdown': markdown
}
self.logger.info("数据处理完成,返回结果")
......
......@@ -124,11 +124,25 @@ class RegionRateTool(BaseRateTool):
for item in df.resultdata:
rate_date = self._extract_rate_data(item)
result_data.append(rate_date)
sorted_data = [rate_date[0]]
if len(result_data) > 1:
sorted_data.extend(sorted(result_data[1:], key=lambda x: x['在线率']))
# 将数据改成表格形式,表头提取之后,数据一行行显示
table_header = list(result_data[0].keys())
table_data = []
for item in result_data:
table_data.append(list(item.values()))
result_data = {
'table_header': table_header,
'table_data': table_data
}
data = {
'region': region_name,
'region_code': code,
'rate_data': result_data,
'region': region_name,
'region_code': code,
'rate_data': result_data,
}
total_time = time.time() - agent_start
......@@ -160,6 +174,16 @@ class RegionRateTool(BaseRateTool):
self.logger.debug(f"查询结果: {df.resultdata}")
# markdown = self.to_markdown(df.resultdata)
table_header = list(result_data[0].keys())
table_data = []
for item in result_data:
table_data.append(list(item.values()))
result_data = {
'table_header': table_header,
'table_data': table_data
}
data = {
'region': region_name,
......
......@@ -26,7 +26,7 @@ DEFAULT_CONFIG = {
"API_BASE": "http://192.168.10.14:8000/v1",
"TOOL_BASE_URL": "http://localhost:5001",
"API_KEY": "xxxxxxxxxxxxx",
"LOG_LEVEL": "DEBUG"
"LOG_LEVEL": "INFO"
}
def get_config(key: str, args: Optional[argparse.Namespace] = None) -> str:
......
......@@ -80,10 +80,20 @@ def run_examples():
"expected": {
"tool": "monitor_points_query",
"params": {
"key": "甘肃省陇南市"
"key": "甘肃省"
}
}
},
},{
"query": "贵阳市的雨量传感器有多少",
"expected": {
"tool": "monitor_points_query",
"params": {
"key": "贵阳市",
"device_type": "雨量",
"query_type": "2",
}
}
}
]
# 为每个测试案例创建一个表格
......@@ -120,10 +130,10 @@ def run_examples():
"✓" if expected_value == actual_value else "✗"
)
# run tool
tool = tools_dict[actual_tool]
result = tool.invoke(result["params"])
print(result)
# # run tool
# tool = tools_dict[actual_tool]
# result = tool.invoke(result["params"])
# print(result)
except Exception as e:
table.add_row("错误", "", str(e), "✗")
......
......@@ -44,6 +44,7 @@ def run_examples():
"start_time": "2024-04-01 00:00:00",
"end_time": "2024-05-31 23:59:59",
"region_name": "甘肃省",
"query_type": "1",
}
}
},{
......@@ -64,6 +65,7 @@ def run_examples():
"start_time": "2024-01-01 00:00:00",
"end_time": "2024-12-31 23:59:59",
"region_name": "甘肃省",
"query_type": "2",
}
}
},{
......@@ -74,6 +76,7 @@ def run_examples():
"start_time": "2024-01-01 00:00:00",
"end_time": "2024-06-30 23:59:59",
"region_name": "甘肃省",
"query_type": "1",
}
}
}
......@@ -113,11 +116,11 @@ def run_examples():
"✓" if expected_value == actual_value else "✗"
)
tool = tool_dict[result["tool"]]
params = result["params"]
# tool = tool_dict[result["tool"]]
# params = result["params"]
result = tool.invoke(params)
print(result)
# result = tool.invoke(params)
# print(result)
except Exception as e:
table.add_row("错误", "", str(e), "✗")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment