第4次更新
1、优化prompt; 2、解决日程删除错误; 3、iotm demo tool整体更新。
This commit is contained in:
parent
a27ab9dfba
commit
e48b8d8a2d
10
README.md
10
README.md
@ -4,10 +4,14 @@
|
||||
<br>
|
||||
<img src="images/icon.png" alt="Fay">
|
||||
<h1>Fay数字人 AI Agent版</h1>
|
||||
“agent”即代理,它能够代替你完成决策规划并执行,这一切都依赖目前最强的大语言模型的ReAct能力。
|
||||
“agent”即代理,它能够代替你完成决策规划并执行,这一切都依赖目前最强的大语言模型的ReAct能力。不同于助理版的一问一答,agent版的Fay可以实现自动代理执行的同时,在它认为必要时候会触发数字人或者直接的声音输出。
|
||||
</div>
|
||||
|
||||
**12月迟来的报到,Fay数字人 AI Agent版(含智慧农业应用demo)第3版正式上传!**
|
||||
|
||||
|
||||
|
||||
|
||||
**12月迟来的报到,Fay数字人 AI Agent版(含智慧农业箱的操作demo代码,如果你需要完整代码可以公众号留言申请获取)第4版正式上传!**
|
||||
|
||||
如果你需要是一个线上线下的销售员,请移步[`带货完整版`](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)
|
||||
|
||||
|
||||
|
||||
### **联系**
|
||||
|
||||
**商务QQ: 467665317**
|
||||
|
65
README_EN.md
Normal file
65
README_EN.md
Normal 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" />
|
@ -1,3 +1,4 @@
|
||||
#这是与数字人通讯的接口说明
|
||||
## 消息格式
|
||||
|
||||
通讯地址: [`ws://127.0.0.1:10002`](ws://127.0.0.1:10002)
|
||||
|
@ -51,7 +51,7 @@ def parse_repeat_rule(rule, task_time):
|
||||
|
||||
# 执行任务
|
||||
def execute_task(task_time, id, content):
|
||||
content = content
|
||||
content = "执行任务->现在" + content
|
||||
agent.run(content)
|
||||
del scheduled_tasks[id]
|
||||
# 如果不重复,执行后删除记录
|
||||
@ -96,19 +96,17 @@ def agent_start():
|
||||
|
||||
#初始计划
|
||||
agent.run("""执行任务-->
|
||||
请为我一个个时间设置初始计划:
|
||||
1、在每天12:30到13:30安静不影响主人休息;
|
||||
2、每天12点提醒主人吃饭;
|
||||
3、在星期一到星期五13:30提醒主人开始工作;
|
||||
4、在星期一到星期五15:15提醒主人冲咖啡;
|
||||
5、在星期一、星期三的11:15提醒主人开会;
|
||||
6、在星期五17:30提醒主人开会;
|
||||
7、在星期一到星期五18:00提醒主人下班;
|
||||
你是一个智慧农业实验箱里的ai,你的责任是陪伴主人生活、工作,以及协助主人打理好农业种植箱里的农作物:
|
||||
1、在每天早上8点、中午12点、晚上10点检查农业种植箱的状态是否附合设定的预期执行,如果不符合请告知我调整。
|
||||
2、每天12点“语音提醒主人吃饭”;
|
||||
3、在星期一到星期五13:30“语音提醒主人开始工作”;
|
||||
4、在星期一到星期五15:15“语音提醒主人冲咖啡”;
|
||||
5、在星期一、星期三的11:15“语音提醒主人开会”;
|
||||
6、在星期五17:30“语音提醒主人开会”;
|
||||
7、在星期一到星期五18:00“语音提醒主人下班”;
|
||||
8、在每天21点陪主人聊聊天;
|
||||
9、在每天晚上10:30会跟据天气预报信息和前一天的运行情况,检查iotm系统当天的控制规则;
|
||||
10、在每天早上8点、中午12点、晚上10点检查农业种植箱的状态是否附合设定的预期执行,
|
||||
如果不符合请告知我调整。
|
||||
另外:在任何意外的情况需要进一步指导请马联系我。
|
||||
9、在每天晚上10:30会跟据第二天的天气预报信息和当天的运行情况,检查iotm系统当天的控制规则;
|
||||
|
||||
""")
|
||||
|
||||
def agent_stop():
|
||||
|
@ -17,6 +17,8 @@ from agent.tools.Knowledge import Knowledge
|
||||
from agent.tools.Say import Say
|
||||
from agent.tools.QueryTimerDB import QueryTimerDB
|
||||
from agent.tools.DeleteTimer import DeleteTimer
|
||||
from agent.tools.GetSwitchLog import GetSwitchLog
|
||||
from agent.tools.getOnRunLinkage import getOnRunLinkage
|
||||
|
||||
import utils.config_util as utils
|
||||
from core.content_db import Content_Db
|
||||
@ -35,7 +37,7 @@ class FayAgentCore():
|
||||
embedding_fn = OpenAIEmbeddings()
|
||||
|
||||
#创建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({}), {})
|
||||
@ -60,6 +62,9 @@ class FayAgentCore():
|
||||
say_tool = Say()
|
||||
query_timer_db_tool = QueryTimerDB()
|
||||
delete_timer_tool = DeleteTimer()
|
||||
get_switch_log = GetSwitchLog()
|
||||
get_on_run_linkage = getOnRunLinkage()
|
||||
|
||||
tools = [
|
||||
Tool(
|
||||
name=my_timer.name,
|
||||
@ -111,6 +116,16 @@ class FayAgentCore():
|
||||
func=delete_timer_tool.run,
|
||||
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('主人文字说了:', '')}})
|
||||
result = None
|
||||
try:
|
||||
result = self.agent.run(input_text.replace('执行任务-->', ''))
|
||||
result = self.agent.run(input_text)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
result = "执行完毕" if result is None or result == "N/A" else result
|
||||
|
@ -3,11 +3,13 @@ from typing import Any
|
||||
|
||||
import requests
|
||||
from langchain.tools import BaseTool
|
||||
|
||||
import time
|
||||
import agent.tools.IotmService as IotmService
|
||||
from datetime import datetime
|
||||
|
||||
class CheckSensor(BaseTool):
|
||||
name = "CheckSensor"
|
||||
description = "此工具用于查询农业箱传感器数据及设备开关状态"
|
||||
description = "此工具用于查询农业箱在线状态、传感器数据、设备开关状态"
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@ -18,73 +20,58 @@ class CheckSensor(BaseTool):
|
||||
|
||||
|
||||
def _run(self, para: str) -> str:
|
||||
return """
|
||||
{
|
||||
"result": True,
|
||||
"ts": "2023-05-09 17:54:31.948",
|
||||
"data": [
|
||||
"co2":
|
||||
{
|
||||
"ts": "2022-05-09 17:54:31.948",
|
||||
"val": "1000ppm",
|
||||
"desc":"箱内的二氧化碳含量"
|
||||
},
|
||||
|
||||
"inside_temperature":
|
||||
{
|
||||
"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"
|
||||
}
|
||||
"""
|
||||
#箱子信息
|
||||
building_infos = IotmService.get_building_unit()
|
||||
is_online = building_infos.get('isonline', 0)
|
||||
#传感器数据
|
||||
sensor_all_infos = IotmService.get_latest_list()
|
||||
sensor_infos = sensor_all_infos['data']
|
||||
desc_list = {
|
||||
'temperature': '温度',
|
||||
'humidity': '湿度',
|
||||
'co2': '二氧化碳',
|
||||
'light': '箱内的光照强度的值,当箱内光照强度太低时,生长灯会被打开,传感器位置是可以检测到生长灯的亮度的',
|
||||
'air': '污染气体',
|
||||
'nh3': '氨气'
|
||||
}
|
||||
|
||||
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__":
|
||||
tool = CheckSensor()
|
||||
|
@ -1,36 +1,36 @@
|
||||
import abc
|
||||
import sqlite3
|
||||
from typing import Any
|
||||
import ast
|
||||
|
||||
from langchain.tools import BaseTool
|
||||
|
||||
from agent import agent_service
|
||||
|
||||
|
||||
class DeleteTimer(BaseTool, abc.ABC):
|
||||
class DeleteTimer(BaseTool):
|
||||
name = "DeleteTimer"
|
||||
description = "用于删除某一个定时任务,接受任务id作为参数,如:('2')"
|
||||
description = "用于删除某一个日程,接受任务id作为参数,如:2"
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
async def _arun(self, *args: Any, **kwargs: Any) -> Any:
|
||||
# 用例中没有用到 arun 不予具体实现
|
||||
pass
|
||||
|
||||
|
||||
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])]
|
||||
conn = sqlite3.connect('timer.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(f"DELETE FROM timer WHERE id = {id}")
|
||||
conn.commit()
|
||||
conn.close()
|
||||
if id in agent_service.scheduled_tasks:
|
||||
del agent_service.scheduled_tasks[id]
|
||||
|
||||
return f"{id}任务取消成功"
|
||||
try:
|
||||
with sqlite3.connect('timer.db') as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("DELETE FROM timer WHERE id = ?", (id,))
|
||||
conn.commit()
|
||||
except sqlite3.Error as e:
|
||||
return f"数据库错误: {e}"
|
||||
|
||||
return f"任务 {id} 取消成功。"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
27
agent/tools/GetSwitchLog.py
Normal file
27
agent/tools/GetSwitchLog.py
Normal 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)
|
47
agent/tools/IotmService.py
Normal file
47
agent/tools/IotmService.py
Normal 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)
|
@ -9,7 +9,7 @@ from langchain.tools import BaseTool
|
||||
|
||||
class MyTimer(BaseTool, abc.ABC):
|
||||
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):
|
||||
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]))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return "定时任务设置成功"
|
||||
return "日程设置成功"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -9,7 +9,7 @@ from langchain.tools import BaseTool
|
||||
|
||||
class QueryTimerDB(BaseTool, abc.ABC):
|
||||
name = "QueryTimerDB"
|
||||
description = "用于查询所有定时任务,返回的数据里包含3个参数:时间、循环规则(如:'1000100'代表星期一和星期五循环,'0000000'代表不循环)、执行的事项"
|
||||
description = "用于查询所有日程,返回的数据里包含3个参数:时间、循环规则(如:'1000100'代表星期一和星期五循环,'0000000'代表不循环)、执行的事项"
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
@ -9,7 +9,7 @@ from core.interact import Interact
|
||||
|
||||
class Say(BaseTool):
|
||||
name = "Say"
|
||||
description = """此工具用于语音输出内容,用于与主人沟通及提醒主人,使用时请传入说话内容作为参数,例如:“该下班了,请注意休息”"""
|
||||
description = """此工具用于沟通及提醒,使用时请传入说话内容作为参数,例如:“该下班了,请注意休息”"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
@ -1,13 +1,17 @@
|
||||
import os
|
||||
import ast
|
||||
from typing import Any
|
||||
|
||||
import requests
|
||||
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):
|
||||
name = "Switch"
|
||||
description = "此工具用于控制箱内制冷设备(A)、制热设备(B)、内外通风设备(C)、浇水设备(D)、补光设备(E)、二氧化碳设备(F)的开关状态,参数格式:('A':'on')"
|
||||
description = '此工具用于控制小风扇、电热风扇、制冷风扇、水开关、肥料开关、植物生长灯、二氧化碳的开关,参数格式:("小风扇","on"),返回True为成功'
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@ -18,11 +22,34 @@ class Switch(BaseTool):
|
||||
|
||||
|
||||
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__":
|
||||
tool = Switch()
|
||||
info = tool.run("""{"name":"制热设备","switch":"on"}""")
|
||||
info = tool.run('("小风扇","off")')
|
||||
print(info)
|
||||
|
@ -3,11 +3,11 @@ from typing import Any
|
||||
|
||||
import requests
|
||||
from langchain.tools import BaseTool
|
||||
|
||||
from urllib.parse import quote
|
||||
|
||||
class Weather(BaseTool):
|
||||
name = "weather"
|
||||
description = "Use for searching weather at a specific location"
|
||||
description = "此工具用于获取天气预报信息,需传入英文的城市名,参数格式:Guangzhou"
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@ -18,10 +18,36 @@ class Weather(BaseTool):
|
||||
|
||||
|
||||
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__":
|
||||
weather_tool = Weather()
|
||||
weather_info = weather_tool.run("成都")
|
||||
weather_info = weather_tool.run("Guangzhou")
|
||||
print(weather_info)
|
||||
|
26
agent/tools/getOnRunLinkage.py
Normal file
26
agent/tools/getOnRunLinkage.py
Normal 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)
|
@ -21,4 +21,6 @@ ultralytics~=8.0.2
|
||||
pydub
|
||||
cemotion
|
||||
langchain
|
||||
faiss-cpu
|
||||
faiss-cpu
|
||||
openai
|
||||
tiktoken
|
Loading…
Reference in New Issue
Block a user