from datetime import datetime, timezone, timedelta, date import pandas as pd import requests import json from matplotlib import pyplot as plt #登录接口认证 def loginAuth(): # 接口地址 global auth_token url = "https://xj-tb.maimaiag.com/api/auth/login" # 请替换为实际地址 # 请求头 headers = { "Content-Type": "application/json" } # 请求体数据 payload = { "username": "read@xj.com", "password": "maimai" } try: # 发送POST请求 response = requests.post( url, headers=headers, data=json.dumps(payload) # 或者直接使用 json=payload ) # 检查响应状态码 if response.status_code == 200: print("登录成功!") print("响应数据:", response.json()) # 通常登录接口会返回token,可以这样获取 response_data = response.json() auth_token = response_data.get("token") # 根据实际返回字段调整 if auth_token: print("获取到的认证Token:", auth_token) else: print(f"登录失败,状态码: {response.status_code}") print("错误信息:", response.text) except requests.exceptions.RequestException as e: print(f"请求发生异常: {str(e)}") except json.JSONDecodeError as e: print(f"JSON解析错误: {str(e)}") return auth_token # 调用数据接口--历史数据 def getWeatherAndSoilData(auth_token,device_id,startTs,endTs,agg,interval,limit,orderBy,keys): # 配置信息 BASE_URL = "https://xj-tb.maimaiag.com/" # 请替换为实际API地址 TOKEN = auth_token # 替换为实际的Bearer token DEVICE_ID = device_id # 替换为实际的设备ID # 构造请求URL endpoint = f"/api/plugins/telemetry/DEVICE/{DEVICE_ID}/values/timeseries" url = BASE_URL + endpoint # 请求头 headers = { "Content-Type": "application/json", "X-Authorization": f"Bearer+{TOKEN}" } # 查询参数 params = { "keys": keys, # 要查询的参数,多个用逗号分隔 "startTs": startTs, # 开始时间戳(毫秒)- 可选 "endTs": endTs, # 结束时间戳(毫秒)- 可选 "agg": agg, # 聚合函数 - 可选 "interval": interval, # 聚合间隔(毫秒)- 可选 "limit": limit, # 返回条数 - 可选 "orderBy": orderBy # 排序方式 - 可选 } try: # 发送GET请求 response = requests.get( url, headers=headers, params=params ) # 检查响应状态码 if response.status_code == 200: # print("请求成功!") data = response.json() # print("响应数据:", json.dumps(data, indent=2)) converted_data = {k: convert_timestamp_to_datetime(v) for k, v in data.items()} return converted_data elif response.status_code == 401: print("认证失败,请检查Token是否正确") elif response.status_code == 404: print("设备不存在或路径错误") else: print(f"请求失败,状态码: {response.status_code}") print("错误信息:", response.text) except requests.exceptions.RequestException as e: print(f"请求发生异常: {str(e)}") except json.JSONDecodeError as e: print(f"JSON解析错误: {str(e)}") print("原始响应:", response.text) def convert_timestamp_to_datetime(data_dict): """ 递归地将字典中的所有'timestamp'字段转换为可读的日期时间格式 保留原始时间戳的同时添加新的'datetime'字段 """ if isinstance(data_dict, dict): if "ts" in data_dict: # 转换毫秒时间戳为datetime对象 timestamp_sec = data_dict["ts"] / 1000 dt = datetime.fromtimestamp(timestamp_sec) # 添加新字段,保留原始时间戳 data_dict["datetime"] = dt.strftime("%Y-%m-%d %H:%M:%S") return data_dict elif isinstance(data_dict, list): return [convert_timestamp_to_datetime(item) for item in data_dict] else: return data_dict def dateToTimestamp(date): # dt = datetime.strptime(date, "%Y-%m-%d %H:%M:%S") if isinstance(date, datetime): # 如果已经是datetime对象,直接使用 dt = date elif isinstance(date, str): # 如果是字符串,解析为datetime对象 dt = datetime.strptime(date, "%Y-%m-%d %H:%M:%S.%f") else: raise TypeError("date参数必须是字符串或datetime对象") timestamp_ms = int(dt.timestamp() * 1000) return timestamp_ms #调用接口获取未来气象数据 def getFutureWeather(monitor_date): base_url_future="https://api.open-meteo.com/" end_point="v1/forecast" current_date = datetime.now().date() params = { "latitude": "41.34252110189814", # 纬度 "longitude": "86.28810755462379", # 经度 "hourly": "temperature_2m,precipitation,precipitation_probability" } # if monitor_date.date()= 22] plt.scatter(night_data['datetime'], night_data['value'], color='red', s=30, label='22:00-06:00 Data') # 设置标题和坐标轴标签 plt.title('Soil Moisture Time Series (2025-06-22 to 2025-06-30)', fontsize=14, pad=15) plt.xlabel('Datetime', fontsize=12, labelpad=10) plt.ylabel('Soil Moisture (%)', fontsize=12, labelpad=10) # 设置x轴刻度旋转,避免重叠 plt.xticks(rotation=45, ha='right', fontsize=10) # 添加网格线 plt.grid(axis='y', linestyle='--', alpha=0.7) # 添加图例 plt.legend(loc='upper right', fontsize=10) # 调整布局 plt.tight_layout() # 显示图表 plt.show() if __name__ == "__main__": auth_token = loginAuth() device_id="18d121f0-561b-11f0-a556-4f10f26fc07f" agg="AVG" interval=21600000 limit="" orderBy="" keys="RAIN_FALL_REALTIME" date_start = "2025-06-25 00:00:00.123" date_end = "2025-07-01 23:59:59.123" startTs=dateToTimestamp(date_start) endTs=dateToTimestamp(date_end) # data=get_soil_data_dk1(auth_token,startTs,endTs) # print(data) data=getWeatherAndSoilData(auth_token,device_id,startTs,endTs,"AVG",3600000,limit,orderBy,keys) print(data['RAIN_FALL']) # get_plot(data['1号传感器']['SOIL_MOISTURE_SURFACE']) get_plot(data['RAIN_FALL_REALTIME'])