From b0b4f878484f2a6637d57c2b181a769c9b73274b Mon Sep 17 00:00:00 2001 From: hrz <1710360675@qq.com> Date: Thu, 24 Apr 2025 14:58:35 +0800 Subject: [PATCH] =?UTF-8?q?update:=E5=A4=A9=E6=B0=94=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/xiaozhi-server/core/connection.py | 7 - .../plugins_func/functions/get_weather.py | 125 +++++++++++++----- 2 files changed, 89 insertions(+), 43 deletions(-) diff --git a/main/xiaozhi-server/core/connection.py b/main/xiaozhi-server/core/connection.py index 8fa09318..df751e7c 100644 --- a/main/xiaozhi-server/core/connection.py +++ b/main/xiaozhi-server/core/connection.py @@ -225,13 +225,6 @@ class ConnectionHandler: self._initialize_memory() """加载意图识别""" self._initialize_intent() - """加载位置信息""" - # self.client_ip_info = get_ip_info(self.client_ip, self.logger) - # if self.client_ip_info is not None and "city" in self.client_ip_info: - # self.logger.bind(tag=TAG).info(f"Client ip info: {self.client_ip_info}") - # self.prompt = self.prompt + f"\nuser location:{self.client_ip_info}" - # - # self.dialogue.update_system_message(self.prompt) def _initialize_private_config(self): read_config_from_api = self.config.get("read_config_from_api", False) diff --git a/main/xiaozhi-server/plugins_func/functions/get_weather.py b/main/xiaozhi-server/plugins_func/functions/get_weather.py index 3764401e..b17755a2 100644 --- a/main/xiaozhi-server/plugins_func/functions/get_weather.py +++ b/main/xiaozhi-server/plugins_func/functions/get_weather.py @@ -12,60 +12,105 @@ GET_WEATHER_FUNCTION_DESC = { "function": { "name": "get_weather", "description": ( - "获取某个地点的天气信息。当用户询问与天气相关的问题(例如'今天的天气怎么样?'、'明天会下雨吗?'、'广州天气如何?'等)," - "或对话中包含'天气'字眼时,调用此功能。用户可以提供具体位置(如城市名)," - "如果未提供位置,则自动获取用户当前位置查询天气。" - "如果用户说的是省份,默认用省会城市。如果用户说的不是省份或城市而是一个地名," - "默认用该地所在省份的省会城市。" - "当IP解析失败会使用默认地址" + "获取某个地点的天气,用户应提供一个位置,比如用户说杭州天气,参数为:杭州。" + "如果用户说的是省份,默认用省会城市。如果用户说的不是省份或城市而是一个地名,默认用该地所在省份的省会城市。" + "如果用户没有指明地点,说“天气怎么样”,”今天天气如何“,location参数为空" ), "parameters": { "type": "object", "properties": { "location": { "type": "string", - "description": "地点名,例如杭州。可选参数,如果不提供则不传" + "description": "地点名,例如杭州。可选参数,如果不提供则不传", }, "lang": { "type": "string", - "description": "返回用户使用的语言code,例如zh_CN/zh_HK/en_US/ja_JP等,默认zh_CN" - } + "description": "返回用户使用的语言code,例如zh_CN/zh_HK/en_US/ja_JP等,默认zh_CN", + }, }, - "required": ["lang"] - } - } + "required": ["lang"], + }, + }, } HEADERS = { - 'User-Agent': ( - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' - '(KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36' + "User-Agent": ( + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " + "(KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36" ) } # 天气代码 https://dev.qweather.com/docs/resource/icons/#weather-icons WEATHER_CODE_MAP = { - "100": "晴", "101": "多云", "102": "少云", "103": "晴间多云", "104": "阴", - "150": "晴", "151": "多云", "152": "少云", "153": "晴间多云", - "300": "阵雨", "301": "强阵雨", "302": "雷阵雨", "303": "强雷阵雨", "304": "雷阵雨伴有冰雹", - "305": "小雨", "306": "中雨", "307": "大雨", "308": "极端降雨", "309": "毛毛雨/细雨", - "310": "暴雨", "311": "大暴雨", "312": "特大暴雨", "313": "冻雨", "314": "小到中雨", - "315": "中到大雨", "316": "大到暴雨", "317": "暴雨到大暴雨", "318": "大暴雨到特大暴雨", - "350": "阵雨", "351": "强阵雨", "399": "雨", - "400": "小雪", "401": "中雪", "402": "大雪", "403": "暴雪", "404": "雨夹雪", - "405": "雨雪天气", "406": "阵雨夹雪", "407": "阵雪", "408": "小到中雪", "409": "中到大雪", "410": "大到暴雪", - "456": "阵雨夹雪", "457": "阵雪", "499": "雪", - "500": "薄雾", "501": "雾", "502": "霾", "503": "扬沙", "504": "浮尘", - "507": "沙尘暴", "508": "强沙尘暴", - "509": "浓雾", "510": "强浓雾", "511": "中度霾", "512": "重度霾", "513": "严重霾", "514": "大雾", "515": "特强浓雾", - "900": "热", "901": "冷", "999": "未知" + "100": "晴", + "101": "多云", + "102": "少云", + "103": "晴间多云", + "104": "阴", + "150": "晴", + "151": "多云", + "152": "少云", + "153": "晴间多云", + "300": "阵雨", + "301": "强阵雨", + "302": "雷阵雨", + "303": "强雷阵雨", + "304": "雷阵雨伴有冰雹", + "305": "小雨", + "306": "中雨", + "307": "大雨", + "308": "极端降雨", + "309": "毛毛雨/细雨", + "310": "暴雨", + "311": "大暴雨", + "312": "特大暴雨", + "313": "冻雨", + "314": "小到中雨", + "315": "中到大雨", + "316": "大到暴雨", + "317": "暴雨到大暴雨", + "318": "大暴雨到特大暴雨", + "350": "阵雨", + "351": "强阵雨", + "399": "雨", + "400": "小雪", + "401": "中雪", + "402": "大雪", + "403": "暴雪", + "404": "雨夹雪", + "405": "雨雪天气", + "406": "阵雨夹雪", + "407": "阵雪", + "408": "小到中雪", + "409": "中到大雪", + "410": "大到暴雪", + "456": "阵雨夹雪", + "457": "阵雪", + "499": "雪", + "500": "薄雾", + "501": "雾", + "502": "霾", + "503": "扬沙", + "504": "浮尘", + "507": "沙尘暴", + "508": "强沙尘暴", + "509": "浓雾", + "510": "强浓雾", + "511": "中度霾", + "512": "重度霾", + "513": "严重霾", + "514": "大雾", + "515": "特强浓雾", + "900": "热", + "901": "冷", + "999": "未知", } def fetch_city_info(location, api_key): url = f"https://geoapi.qweather.com/v2/city/lookup?key={api_key}&location={location}&lang=zh" response = requests.get(url, headers=HEADERS).json() - return response.get('location', [])[0] if response.get('location') else None + return response.get("location", [])[0] if response.get("location") else None def fetch_weather_page(url): @@ -77,10 +122,14 @@ def parse_weather_info(soup): city_name = soup.select_one("h1.c-submenu__location").get_text(strip=True) current_abstract = soup.select_one(".c-city-weather-current .current-abstract") - current_abstract = current_abstract.get_text(strip=True) if current_abstract else "未知" + current_abstract = ( + current_abstract.get_text(strip=True) if current_abstract else "未知" + ) current_basic = {} - for item in soup.select(".c-city-weather-current .current-basic .current-basic___item"): + for item in soup.select( + ".c-city-weather-current .current-basic .current-basic___item" + ): parts = item.get_text(strip=True, separator=" ").split(" ") if len(parts) == 2: key, value = parts[1], parts[0] @@ -89,7 +138,9 @@ def parse_weather_info(soup): temps_list = [] for row in soup.select(".city-forecast-tabs__row")[:7]: # 取前7天的数据 date = row.select_one(".date-bg .date").get_text(strip=True) - weather_code = row.select_one(".date-bg .icon")["src"].split("/")[-1].split(".")[0] + weather_code = ( + row.select_one(".date-bg .icon")["src"].split("/")[-1].split(".")[0] + ) weather = WEATHER_CODE_MAP.get(weather_code, "未知") temps = [span.get_text(strip=True) for span in row.select(".tmp-cont .temp")] high_temp, low_temp = (temps[0], temps[-1]) if len(temps) >= 2 else (None, None) @@ -98,7 +149,7 @@ def parse_weather_info(soup): return city_name, current_abstract, current_basic, temps_list -@register_function('get_weather', GET_WEATHER_FUNCTION_DESC, ToolType.SYSTEM_CTL) +@register_function("get_weather", GET_WEATHER_FUNCTION_DESC, ToolType.SYSTEM_CTL) def get_weather(conn, location: str = None, lang: str = "zh_CN"): api_key = conn.config["plugins"]["get_weather"]["api_key"] default_location = conn.config["plugins"]["get_weather"]["default_location"] @@ -120,8 +171,10 @@ def get_weather(conn, location: str = None, lang: str = "zh_CN"): city_info = fetch_city_info(location, api_key) if not city_info: - return ActionResponse(Action.REQLLM, f"未找到相关的城市: {location},请确认地点是否正确", None) - soup = fetch_weather_page(city_info['fxLink']) + return ActionResponse( + Action.REQLLM, f"未找到相关的城市: {location},请确认地点是否正确", None + ) + soup = fetch_weather_page(city_info["fxLink"]) if not soup: return ActionResponse(Action.REQLLM, None, "请求失败") city_name, current_abstract, current_basic, temps_list = parse_weather_info(soup)