第4次更新

1、优化prompt;
2、解决日程删除错误;
3、iotm demo tool整体更新。
This commit is contained in:
xszyou 2023-12-18 16:52:53 +08:00
parent a27ab9dfba
commit e48b8d8a2d
16 changed files with 341 additions and 114 deletions

View File

@ -4,10 +4,14 @@
<br> <br>
<img src="images/icon.png" alt="Fay"> <img src="images/icon.png" alt="Fay">
<h1>Fay数字人 AI Agent版</h1> <h1>Fay数字人 AI Agent版</h1>
“agent”即代理它能够代替你完成决策规划并执行这一切都依赖目前最强的大语言模型的ReAct能力。 “agent”即代理它能够代替你完成决策规划并执行这一切都依赖目前最强的大语言模型的ReAct能力。不同于助理版的一问一答agent版的Fay可以实现自动代理执行的同时在它认为必要时候会触发数字人或者直接的声音输出。
</div> </div>
**12月迟来的报到Fay数字人 AI Agent版含智慧农业应用demo第3版正式上传**
**12月迟来的报到Fay数字人 AI Agent版含智慧农业箱的操作demo代码如果你需要完整代码可以公众号留言申请获取第4版正式上传**
如果你需要是一个线上线下的销售员,请移步[`带货完整版`](https://github.com/TheRamU/Fay/tree/fay-sales-edition) 如果你需要是一个线上线下的销售员,请移步[`带货完整版`](https://github.com/TheRamU/Fay/tree/fay-sales-edition)
@ -53,6 +57,8 @@ python main.py
+ 启动数字人[xszyou/fay-ue5: 可对接fay数字人的ue5工程 (github.com)](https://github.com/xszyou/fay-ue5) + 启动数字人[xszyou/fay-ue5: 可对接fay数字人的ue5工程 (github.com)](https://github.com/xszyou/fay-ue5)
### **联系** ### **联系**
**商务QQ: 467665317** **商务QQ: 467665317**

65
README_EN.md Normal file
View File

@ -0,0 +1,65 @@
[`中文`](https://github.com/TheRamU/Fay/blob/main/README.md)
<div align="center">
<br>
<img src="images/icon.png" alt="Fay">
<h1>Fay Digital Human AI Agent Version</h1>
An "agent" is a representative that can make decisions and execute plans for you, relying on the powerful ReAct capability of the most advanced large language models.
</div>
**Belated December announcement, the 4th edition of Fay Digital Human AI Agent Version (complete code for smart agriculture box can be requested via our public channel) is officially uploaded!**
If you need an online and offline salesperson, please go to [`Complete Retail Version`](https://github.com/TheRamU/Fay/tree/fay-sales-edition)
If you need a digital human assistant for human-computer interaction (and yes, you can command it to switch devices on and off), please go to [`Complete Assistant Version`](https://github.com/TheRamU/Fay/tree/fay-assistant-edition)
***“Exceptional products deserve to be reimagined with digital humans”***
Highlights: Proactive execution of planned tasks without the need for question-and-answer interactions, automatic planning and use of the agent tool to complete tasks; use of OpenAI TTS; use of a vector database for permanent memory and memory retrieval;
![](images/agent_demo.gif)
(Above image: Testing ReAct capabilities
## **Installation Instructions**
### **System Requirements**
- Python 3.9, 3.10
- Windows, macOS, Linux
### **Installing Dependencies**
```shell
pip install -r requirements.txt
```
### **Configuring Application Keys**
+ Enter your GPT-4 key in `./system.conf`
### **Launching the Controller**
Start the Fay controller
```shell
python main.py
```
### **Launching the Digital Human (Optional)**
+ Launch the digital human[xszyou/fay-ue5: 可对接fay数字人的ue5工程 (github.com)](https://github.com/xszyou/fay-ue5)
### **Contact**
**Business QQ: 467665317**
Join the discussion group by following the public account Fay Digital Human (please star this repository first)
<img src="images/2.jpg" />

View File

@ -1,3 +1,4 @@
#这是与数字人通讯的接口说明
## 消息格式 ## 消息格式
通讯地址: [`ws://127.0.0.1:10002`](ws://127.0.0.1:10002) 通讯地址: [`ws://127.0.0.1:10002`](ws://127.0.0.1:10002)

View File

@ -51,7 +51,7 @@ def parse_repeat_rule(rule, task_time):
# 执行任务 # 执行任务
def execute_task(task_time, id, content): def execute_task(task_time, id, content):
content = content content = "执行任务->现在" + content
agent.run(content) agent.run(content)
del scheduled_tasks[id] del scheduled_tasks[id]
# 如果不重复,执行后删除记录 # 如果不重复,执行后删除记录
@ -96,19 +96,17 @@ def agent_start():
#初始计划 #初始计划
agent.run("""执行任务--> agent.run("""执行任务-->
请为我一个个时间设置初始计划 你是一个智慧农业实验箱里的ai你的责任是陪伴主人生活工作以及协助主人打理好农业种植箱里的农作物
1在每天12:30到13:30安静不影响主人休息; 1在每天早上8点中午12点晚上10点检查农业种植箱的状态是否附合设定的预期执行如果不符合请告知我调整
2每天12点提醒主人吃饭; 2每天12点语音提醒主人吃饭;
3在星期一到星期五13:30提醒主人开始工作; 3在星期一到星期五13:30语音提醒主人开始工作;
4在星期一到星期五15:15提醒主人冲咖啡; 4在星期一到星期五15:15语音提醒主人冲咖啡;
5在星期一星期三的11:15提醒主人开会; 5在星期一星期三的11:15语音提醒主人开会;
6在星期五17:30提醒主人开会; 6在星期五17:30语音提醒主人开会;
7在星期一到星期五18:00提醒主人下班; 7在星期一到星期五18:00语音提醒主人下班;
8在每天21点陪主人聊聊天; 8在每天21点陪主人聊聊天;
9在每天晚上10:30会跟据天气预报信息和前一天的运行情况检查iotm系统当天的控制规则 9在每天晚上10:30会跟据第二天的天气预报信息和当天的运行情况检查iotm系统当天的控制规则
10在每天早上8点中午12点晚上10点检查农业种植箱的状态是否附合设定的预期执行
如果不符合请告知我调整
另外在任何意外的情况需要进一步指导请马联系我
""") """)
def agent_stop(): def agent_stop():

View File

@ -17,6 +17,8 @@ from agent.tools.Knowledge import Knowledge
from agent.tools.Say import Say from agent.tools.Say import Say
from agent.tools.QueryTimerDB import QueryTimerDB from agent.tools.QueryTimerDB import QueryTimerDB
from agent.tools.DeleteTimer import DeleteTimer from agent.tools.DeleteTimer import DeleteTimer
from agent.tools.GetSwitchLog import GetSwitchLog
from agent.tools.getOnRunLinkage import getOnRunLinkage
import utils.config_util as utils import utils.config_util as utils
from core.content_db import Content_Db from core.content_db import Content_Db
@ -35,7 +37,7 @@ class FayAgentCore():
embedding_fn = OpenAIEmbeddings() embedding_fn = OpenAIEmbeddings()
#创建llm #创建llm
llm = ChatOpenAI(verbose=True)#model="gpt-4-1106-preview" llm = ChatOpenAI(model="gpt-4-1106-preview", verbose=True)
#创建向量数据库 #创建向量数据库
vectorstore = FAISS(embedding_fn, index, InMemoryDocstore({}), {}) vectorstore = FAISS(embedding_fn, index, InMemoryDocstore({}), {})
@ -60,6 +62,9 @@ class FayAgentCore():
say_tool = Say() say_tool = Say()
query_timer_db_tool = QueryTimerDB() query_timer_db_tool = QueryTimerDB()
delete_timer_tool = DeleteTimer() delete_timer_tool = DeleteTimer()
get_switch_log = GetSwitchLog()
get_on_run_linkage = getOnRunLinkage()
tools = [ tools = [
Tool( Tool(
name=my_timer.name, name=my_timer.name,
@ -111,6 +116,16 @@ class FayAgentCore():
func=delete_timer_tool.run, func=delete_timer_tool.run,
description=delete_timer_tool.description description=delete_timer_tool.description
), ),
Tool(
name=get_switch_log.name,
func=get_switch_log.run,
description=get_switch_log.description
),
Tool(
name=get_on_run_linkage.name,
func=get_on_run_linkage.run,
description=get_on_run_linkage.description
),
] ]
@ -126,7 +141,7 @@ class FayAgentCore():
wsa_server.get_web_instance().add_cmd({"panelReply": {"type":"member","content":input_text.replace('主人语音说了:', '').replace('主人文字说了:', '')}}) wsa_server.get_web_instance().add_cmd({"panelReply": {"type":"member","content":input_text.replace('主人语音说了:', '').replace('主人文字说了:', '')}})
result = None result = None
try: try:
result = self.agent.run(input_text.replace('执行任务-->', '')) result = self.agent.run(input_text)
except Exception as e: except Exception as e:
print(e) print(e)
result = "执行完毕" if result is None or result == "N/A" else result result = "执行完毕" if result is None or result == "N/A" else result

View File

@ -3,11 +3,13 @@ from typing import Any
import requests import requests
from langchain.tools import BaseTool from langchain.tools import BaseTool
import time
import agent.tools.IotmService as IotmService
from datetime import datetime
class CheckSensor(BaseTool): class CheckSensor(BaseTool):
name = "CheckSensor" name = "CheckSensor"
description = "此工具用于查询农业箱传感器数据及设备开关状态" description = "此工具用于查询农业箱在线状态、传感器数据、设备开关状态"
def __init__(self): def __init__(self):
super().__init__() super().__init__()
@ -18,73 +20,58 @@ class CheckSensor(BaseTool):
def _run(self, para: str) -> str: def _run(self, para: str) -> str:
return """ #箱子信息
{ building_infos = IotmService.get_building_unit()
"result": True, is_online = building_infos.get('isonline', 0)
"ts": "2023-05-09 17:54:31.948", #传感器数据
"data": [ sensor_all_infos = IotmService.get_latest_list()
"co2": sensor_infos = sensor_all_infos['data']
{ desc_list = {
"ts": "2022-05-09 17:54:31.948", 'temperature': '温度',
"val": "1000ppm", 'humidity': '湿度',
"desc":"箱内的二氧化碳含量" 'co2': '二氧化碳',
}, 'light': '箱内的光照强度的值,当箱内光照强度太低时,生长灯会被打开,传感器位置是可以检测到生长灯的亮度的',
'air': '污染气体',
"inside_temperature": 'nh3': '氨气'
{
"ts": "2022-05-09 17:54:31.948",
"val": 28,
"desc":"箱内的温度"
},
"inside_humidity":
{
"ts": "2022-05-09 17:54:31.948",
"val": 80,
"desc":"箱内的湿度"
},
"outside_temperature":
{
"ts": "2022-05-09 17:54:31.948",
"val": 28,
"desc":"箱外的温度"
},
"outside_humidity":
{
"ts": "2022-05-09 17:54:31.948",
"val": 80,
"desc":"箱外的湿度"
},
"inside_illuminance":
{
"ts": "2022-05-09 17:54:31.948",
"val": "300lux"
"desc":"箱内的光照强度的值,当箱内光照强度太低时,生长灯会被打开,传感器位置是可以检测到生长灯的亮度的"
},
"inside_soil":
{
"ts": "2022-05-09 17:54:31.948",
"val": 70
"desc":"箱内土壤的湿度,检测的数所有延迟,水在土壤里有个渗透的过程"
},
],
"制冷":"off",
"加热":"off",
"通风":"off",
"加co2":"off",
"补光":"off",
"浇水":"off"
} }
"""
infos = []
for sensor_type, sensor_data in sensor_infos.items():
for data_point in sensor_data:
if sensor_type == 'temperature':
if data_point['port'] == 'MP14':
description = '箱外温度'
else:
description = '箱内温度'
elif sensor_type == 'humidity':
if data_point['port'] == 'MP14':
description = '箱外湿度'
elif data_point['port'] == 'S34':
description = '箱内土壤的湿度,检测的数所有延迟,水在土壤里有个渗透的过程'
else:
description = '箱内湿度'
else:
description = desc_list.get(sensor_type, 'Unknown') # Get description from desc_list, default to 'Unknown'
timestamp = data_point['ts']
value = data_point['val']
infos.append({'ts': timestamp, 'val': value, 'desc':description })
#开关数据
switch_all_infos = IotmService.get_switch_info()
switch_infos = {}
switch_dict = switch_all_infos[0]
#设备配置
switch_infos['小风扇'] = 'on' if switch_dict.get('onoff1', '') == '1' else 'off'
switch_infos['电热风扇'] = 'on' if switch_dict.get('onoff2', '') == '1' else 'off'
switch_infos['制冷风扇'] = 'on' if switch_dict.get('onoff3', '') == '1' else 'off'
switch_infos['水开关'] = 'on' if switch_dict.get('onoff4', '') == '1' else 'off'
switch_infos['肥料开关'] = 'on' if switch_dict.get('onoff5', '') == '1' else 'off'
switch_infos['植物生长灯'] = 'on' if switch_dict.get('onoff6', '') == '1' else 'off'
switch_infos['二氧化碳'] = 'on' if switch_dict.get('onoff7', '') == '1' else 'off'
current_time = datetime.now()
current_time_str = current_time.strftime("%Y-%m-%d %H:%M:%S")
result = {'sensor_infos': infos, 'switch_infos': switch_infos, 'is_online': is_online, 'ts' : current_time_str}
return result
if __name__ == "__main__": if __name__ == "__main__":
tool = CheckSensor() tool = CheckSensor()

View File

@ -1,36 +1,36 @@
import abc
import sqlite3 import sqlite3
from typing import Any from typing import Any
import ast
from langchain.tools import BaseTool from langchain.tools import BaseTool
from agent import agent_service from agent import agent_service
class DeleteTimer(BaseTool, abc.ABC): class DeleteTimer(BaseTool):
name = "DeleteTimer" name = "DeleteTimer"
description = "用于删除某一个定时任务接受任务id作为参数('2')" description = "用于删除某一个日程接受任务id作为参数2"
def __init__(self): def __init__(self):
super().__init__() super().__init__()
async def _arun(self, *args: Any, **kwargs: Any) -> Any:
# 用例中没有用到 arun 不予具体实现
pass
def _run(self, para) -> str: def _run(self, para) -> str:
para = ast.literal_eval(para) try:
id = int(para)
except ValueError:
return "输入的 ID 无效,必须是数字。"
del agent_service.scheduled_tasks[int(para[0])] if id in agent_service.scheduled_tasks:
conn = sqlite3.connect('timer.db') del agent_service.scheduled_tasks[id]
try:
with sqlite3.connect('timer.db') as conn:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute(f"DELETE FROM timer WHERE id = {id}") cursor.execute("DELETE FROM timer WHERE id = ?", (id,))
conn.commit() conn.commit()
conn.close() except sqlite3.Error as e:
return f"数据库错误: {e}"
return f"{id}任务取消成功" return f"任务 {id} 取消成功。"
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -0,0 +1,27 @@
import os
from typing import Any
from langchain.tools import BaseTool
import agent.tools.IotmService as IotmService
class GetSwitchLog(BaseTool):
name = "GetSwitchLog"
description = "此工具用于查询农业箱的设备开关操作历史记录设备序号小风扇1、电热风扇(2)、制冷风扇(3)、肥料开关(4)、补光设备(5)、植物生长灯(6)、二氧化碳(7)"
def __init__(self):
super().__init__()
async def _arun(self, *args: Any, **kwargs: Any) -> Any:
# 用例中没有用到 arun 不予具体实现
pass
def _run(self, para: str) -> str:
infos = IotmService.get_switch_log()
return infos
if __name__ == "__main__":
tool = GetSwitchLog()
info = tool.run("")
print(info)

View File

@ -0,0 +1,47 @@
#获取传感器状态
def get_latest_list():
info ="""
{'result': True, 'code': 1, 'msg': '查询成功', 'data': {'co2': [{'ts': '2023-12-18 16:07:28.124', 'val': 8, 'istext': False, 'content_des': '', 'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'port': 'S36', 'sensorid': 297}], 'air': [{'ts': '2023-12-18 16:07:28.124', 'val': 15, 'istext': False, 'content_des': '', 'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'port': 'S37', 'sensorid': 298}], 'humidity': [{'ts': '2023-12-18 16:06:20.152', 'val': 49.7, 'istext': False, 'content_des': '', 'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'port': 'MP14', 'sensorid': 302}, {'ts': '2023-12-18 16:06:57.861', 'val': 40.8, 'istext': False, 'content_des': '', 'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'port': 'MP21', 'sensorid': 300}, {'ts': '2023-12-18 16:07:28.124', 'val': 99.41003, 'istext': False, 'content_des': '', 'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'port': 'S34', 'sensorid': 299}], 'light': [{'ts': '2023-12-18 16:07:28.124', 'val': 185, 'istext': False, 'content_des': '', 'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'port': 'bh1', 'sensorid': 301}], 'nh3': [{'ts': '2023-12-18 16:07:28.124', 'val': 14, 'istext': False, 'content_des': '', 'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'port': 'S37', 'sensorid': 303}], 'temperature': [{'ts': '2023-12-18 16:03:58.326', 'val': 18.6, 'istext': False, 'content_des': '', 'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'port': 'MP14', 'sensorid': 304}, {'ts': '2023-12-18 16:07:28.124', 'val': 22.9, 'istext': False, 'content_des': '', 'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'port': 'MP21', 'sensorid': 305}]}}
"""
return info
#获取开关状态
def get_switch_info():
info = """
[{'id': 16, 'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'onoff1': '1', 'onoff2': '0', 'onoff3': '0', 'onoff4': '0', 'onoff5': '0', 'onoff6': '1', 'onoff7': '1', 'onoff8': '0', 'onoff9': '0', 'onoff10': '0', 'onoff11': '0', 'onoff12': '0', 'onoff13': '0', 'onoff14': '0', 'onoff15': '0', 'onoff16': '0', 'updatetime': 1702886988874}]
"""
return info
#设备开关操作
def do_switch_operation(num,onoff):
return True
#获取传感器基本信息
def get_building_unit():
info = """
{'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'lat': '0.0000000000000', 'lng': '0.0000000000000', 'sensor': [{'id': 297, 'title': '二氧化碳传感器', 'label': 'co2'}, {'id': 298, 'title': '空气质量传感器', 'label': 'air'}, {'id': 299, 'title': '土壤湿度传感器', 'label': 'humidity'}, {'id': 300, 'title': '温湿度传感器', 'label': 'humidity'}, {'id': 301, 'title': '光照传感器', 'label': 'light'}, {'id': 302, 'title': '温湿度传感器', 'label': 'humidity'}, {'id': 303, 'title': '氨气传感器', 'label': 'nh3'}, {'id': 304, 'title': '温湿度传感器', 'label': 'temperature'}, {'id': 305, 'title': '温湿度传感器', 'label': 'temperature'}], 'isonline': 1
"""
return info
#获取开关记录日志
def get_switch_log():
info = """
[{'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 3, 'status': 0, 'createTime': 1702732876735, 'timetText': '2023-12-16 21:21:16'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 1, 'status': 1, 'createTime': 1702667478198, 'timetText': '2023-12-16 03:11:18'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 7, 'status': 1, 'createTime': 1702664989048, 'timetText': '2023-12-16 02:29:49'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 7, 'status': 0, 'createTime': 1702657012799, 'timetText': '2023-12-16 00:16:52'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 7, 'status': 1, 'createTime': 1702648220859, 'timetText': '2023-12-15 21:50:20'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 3, 'status': 1, 'createTime': 1702646816090, 'timetText': '2023-12-15 21:26:56'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 3, 'status': 0, 'createTime': 1702646531391, 'timetText': '2023-12-15 21:22:11'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 1, 'status': 0, 'createTime': 1702646530372, 'timetText': '2023-12-15 21:22:10'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 3, 'status': 1, 'createTime': 1702645992974, 'timetText': '2023-12-15 21:13:12'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 1, 'status': 1, 'createTime': 1702644950252, 'timetText': '2023-12-15 20:55:50'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 1, 'status': 0, 'createTime': 1702644949600, 'timetText': '2023-12-15 20:55:49'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 6, 'status': 1, 'createTime': 1702634257442, 'timetText': '2023-12-15 17:57:37'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 6, 'status': 0, 'createTime': 1702633183083, 'timetText': '2023-12-15 17:39:43'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 6, 'status': 1, 'createTime': 1702631382970, 'timetText': '2023-12-15 17:09:42'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 6, 'status': 0, 'createTime': 1702629480618, 'timetText': '2023-12-15 16:38:00'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 6, 'status': 1, 'createTime': 1702628371951, 'timetText': '2023-12-15 16:19:31'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 6, 'status': 0, 'createTime': 1702626695422, 'timetText': '2023-12-15 15:51:35'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 6, 'status': 1, 'createTime': 1702625360795, 'timetText': '2023-12-15 15:29:20'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 6, 'status': 0, 'createTime': 1702624152081, 'timetText': '2023-12-15 15:09:12'}, {'did': 'bbb14d38-2814-11ed-b20a-e45f019833ac', 'number': 6, 'status': 1, 'createTime': 1702622351970, 'timetText': '2023-12-15 14:39:11'}]
"""
return info
#获取联动规则
def get_on_run_linkage():
info = """
{'result': True, 'code': 1, 'msg': '获取成功', 'data': [{'port': 'S34', 'sensorTitle': '土壤湿度传感器', 'label': 'humidity', 'minVal': 0, 'maxVal': 70, 'taskId': 'linkage_135', 'onoff': 1, 'switchNum': 4, 'keeptime': '0.25', 'delaytime': 30}, {'port': 'S36', 'sensorTitle': '二氧化碳传感器', 'label': 'co2', 'minVal': 0, 'maxVal': 8, 'taskId': 'linkage_138', 'onoff': 1, 'switchNum': 7, 'keeptime': '30.00', 'delaytime': 0}, {'port': 'MP14', 'sensorTitle': '温湿度传感器', 'label': 'temperature', 'minVal': 0, 'maxVal': 28, 'taskId': 'linkage_143', 'onoff': 1, 'switchNum': 1, 'keeptime': '0.00', 'delaytime': 0}, {'port': 'MP14', 'sensorTitle': '温湿度传感器', 'label':
'temperature', 'minVal': 30, 'maxVal': 999999, 'taskId': 'linkage_144', 'onoff': 0, 'switchNum': 1, 'keeptime': '0.00', 'delaytime': 0}, {'port': 'MP14', 'sensorTitle': '温湿度传感器', 'label': 'temperature', 'minVal': 30, 'maxVal': 999999, 'taskId': 'linkage_145', 'onoff': 0, 'switchNum': 1, 'keeptime': '0.00', 'delaytime': 0}, {'port': 'bh1', 'sensorTitle': '光照传感器', 'label': 'light', 'minVal': 0, 'maxVal': 100, 'taskId': 'linkage_147', 'onoff': 1, 'switchNum': 6, 'keeptime': '30.00', 'delaytime': 50}]}
[{'port': 'S34', 'sensorTitle': '土壤湿度传感器', 'label': 'humidity', 'minVal': 0, 'maxVal': 70, 'taskId': 'linkage_135', 'onoff': 1, 'switchNum': 4, 'keeptime': '0.25', 'delaytime': 30}, {'port': 'S36', 'sensorTitle': '二氧化碳传感器', 'label': 'co2', 'minVal': 0, 'maxVal': 8, 'taskId': 'linkage_138', 'onoff': 1, 'switchNum': 7, 'keeptime': '30.00', 'delaytime': 0}, {'port': 'MP14', 'sensorTitle': '温湿度传感器', 'label': 'temperature', 'minVal': 0, 'maxVal': 28, 'taskId': 'linkage_143', 'onoff':
1, 'switchNum': 1, 'keeptime': '0.00', 'delaytime': 0}, {'port': 'MP14', 'sensorTitle': '温湿度传感器', 'label': 'temperature', 'minVal': 30, 'maxVal': 999999, 'taskId': 'linkage_144', 'onoff': 0, 'switchNum': 1, 'keeptime': '0.00', 'delaytime': 0}, {'port': 'MP14', 'sensorTitle': '温湿度传感器', 'label': 'temperature', 'minVal': 30,
'maxVal': 999999, 'taskId': 'linkage_145', 'onoff': 0, 'switchNum': 1, 'keeptime': '0.00', 'delaytime': 0}, {'port': 'bh1', 'sensorTitle': '光照传感器', 'label': 'light', 'minVal': 0, 'maxVal': 100, 'taskId': 'linkage_147', 'onoff': 1, 'switchNum': 6, 'keeptime': '30.00', 'delaytime': 50}]
"""
return info
if __name__ == "__main__":
str = get_on_run_linkage()
print(str)

View File

@ -9,7 +9,7 @@ from langchain.tools import BaseTool
class MyTimer(BaseTool, abc.ABC): class MyTimer(BaseTool, abc.ABC):
name = "MyTimer" name = "MyTimer"
description = "用于设置定时任务,每次调用只可以设置一次定时任务.使用的时候需要接受3个参数第1个参数是时间,第2个参数是循环规则如:'1000100'代表星期一和星期五循环,'0000000'代表不循环第3个参数代表要执行的事项,如:('15:15', '0000001', '提醒主人叫咖啡')" description = "用于设置日程,使用的时候需要接受3个参数第1个参数是时间,第2个参数是循环规则如:'1000100'代表星期一和星期五循环,'0000000'代表不循环第3个参数代表要执行的事项,如:('15:15', '0000001', '提醒主人叫咖啡')"
def __init__(self): def __init__(self):
super().__init__() super().__init__()
@ -26,7 +26,7 @@ class MyTimer(BaseTool, abc.ABC):
cursor.execute("INSERT INTO timer (time, repeat_rule, content) VALUES (?, ?, ?)", (para[0], para[1], para[2])) cursor.execute("INSERT INTO timer (time, repeat_rule, content) VALUES (?, ?, ?)", (para[0], para[1], para[2]))
conn.commit() conn.commit()
conn.close() conn.close()
return "定时任务设置成功" return "日程设置成功"
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -9,7 +9,7 @@ from langchain.tools import BaseTool
class QueryTimerDB(BaseTool, abc.ABC): class QueryTimerDB(BaseTool, abc.ABC):
name = "QueryTimerDB" name = "QueryTimerDB"
description = "用于查询所有定时任务返回的数据里包含3个参数:时间、循环规则(如:'1000100'代表星期一和星期五循环,'0000000'代表不循环)、执行的事项" description = "用于查询所有日程返回的数据里包含3个参数:时间、循环规则(如:'1000100'代表星期一和星期五循环,'0000000'代表不循环)、执行的事项"
def __init__(self): def __init__(self):
super().__init__() super().__init__()

View File

@ -9,7 +9,7 @@ from core.interact import Interact
class Say(BaseTool): class Say(BaseTool):
name = "Say" name = "Say"
description = """此工具用于语音输出内容,用于与主人沟通及提醒主人,使用时请传入说话内容作为参数,例如:“该下班了,请注意休息”""" description = """此工具用于沟通及提醒,使用时请传入说话内容作为参数,例如:“该下班了,请注意休息”"""
def __init__(self): def __init__(self):
super().__init__() super().__init__()

View File

@ -1,13 +1,17 @@
import os import os
import ast
from typing import Any from typing import Any
import requests import requests
from langchain.tools import BaseTool from langchain.tools import BaseTool
import json
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
import agent.tools.IotmService as IotmService
class Switch(BaseTool): class Switch(BaseTool):
name = "Switch" name = "Switch"
description = "此工具用于控制箱内制冷设备A、制热设备(B)、内外通风设备(C)、浇水设备(D)、补光设备(E)、二氧化碳设备(F)的开关状态,参数格式:('A':'on')" description = '此工具用于控制小风扇、电热风扇、制冷风扇、水开关、肥料开关、植物生长灯、二氧化碳的开关,参数格式:("小风扇","on"),返回True为成功'
def __init__(self): def __init__(self):
super().__init__() super().__init__()
@ -18,11 +22,34 @@ class Switch(BaseTool):
def _run(self, para: str) -> str: def _run(self, para: str) -> str:
return para try:
if not para:
return "参数不能为空"
para = ast.literal_eval(para)
if not para:
return "参数格式不正确"
switch = para[0]
switch_mapping = {
'小风扇': 1,
'电热风扇': 2,
'制冷风扇': 3,
'水开关': 4,
'肥料开关': 5,
'植物生长灯': 6,
'二氧化碳': 7
}
if switch not in switch_mapping:
return "未知的设备类型,请检查 'switch' 字段值"
num = switch_mapping[switch]
onoff = para[1]
re = IotmService.do_switch_operation(num, onoff)
return re
except json.JSONDecodeError:
return '参数格式不正确,请使用正确的 JSON 格式表示方式,例如 {"switch": "小风扇", "onoff": "on"}'
if __name__ == "__main__": if __name__ == "__main__":
tool = Switch() tool = Switch()
info = tool.run("""{"name":"制热设备","switch":"on"}""") info = tool.run('("小风扇","off")')
print(info) print(info)

View File

@ -3,11 +3,11 @@ from typing import Any
import requests import requests
from langchain.tools import BaseTool from langchain.tools import BaseTool
from urllib.parse import quote
class Weather(BaseTool): class Weather(BaseTool):
name = "weather" name = "weather"
description = "Use for searching weather at a specific location" description = "此工具用于获取天气预报信息需传入英文的城市名参数格式Guangzhou"
def __init__(self): def __init__(self):
super().__init__() super().__init__()
@ -18,10 +18,36 @@ class Weather(BaseTool):
def _run(self, para: str) -> str: def _run(self, para: str) -> str:
return "今天天气晴朗风和日丽气温25度空气十分清新心情美美哒" try:
if not para:
return "参数不能为空"
encoded_city = quote(para)
api_url = f"http://api.openweathermap.org/data/2.5/weather?q={encoded_city}&appid=272fcb70d2c4e6f5134c2dce7d091df6"
response = requests.get(api_url)
if response.status_code == 200:
weather_data = response.json()
# 提取天气信息
temperature_kelvin = weather_data['main']['temp']
temperature_celsius = temperature_kelvin - 273.15
min_temperature_kelvin = weather_data['main']['temp_min']
max_temperature_kelvin = weather_data['main']['temp_max']
min_temperature_celsius = min_temperature_kelvin - 273.15
max_temperature_celsius = max_temperature_kelvin - 273.15
description = weather_data['weather'][0]['description']
wind_speed = weather_data['wind']['speed']
# 构建天气描述
weather_description = f"今天天气:{description},气温:{temperature_celsius:.2f}摄氏度,风速:{wind_speed} m/s。"
return f"天气预报信息:{weather_description}"
else:
return f"无法获取天气预报信息,状态码:{response.status_code}"
except Exception as e:
return f"发生错误:{str(e)}"
if __name__ == "__main__": if __name__ == "__main__":
weather_tool = Weather() weather_tool = Weather()
weather_info = weather_tool.run("成都") weather_info = weather_tool.run("Guangzhou")
print(weather_info) print(weather_info)

View File

@ -0,0 +1,26 @@
import os
from typing import Any
from langchain.tools import BaseTool
import agent.tools.IotmService as IotmService
class getOnRunLinkage(BaseTool):
name = "getOnRunLinkage"
description = "此工具用于查询农业箱当前在运行的联动设备序号小风扇1、电热风扇(2)、制冷风扇(3)、肥料开关(4)、补光设备(5)、植物生长灯(6)、二氧化碳(7)"
def __init__(self):
super().__init__()
async def _arun(self, *args: Any, **kwargs: Any) -> Any:
# 用例中没有用到 arun 不予具体实现
pass
def _run(self, para: str) -> str:
infos = IotmService.get_on_run_linkage()
return infos
if __name__ == "__main__":
tool = getOnRunLinkage()
info = tool.run("")
print(info)

View File

@ -22,3 +22,5 @@ pydub
cemotion cemotion
langchain langchain
faiss-cpu faiss-cpu
openai
tiktoken