621 lines
26 KiB
Python
621 lines
26 KiB
Python
import statistics
|
||
import uuid
|
||
|
||
from collections import defaultdict
|
||
from datetime import datetime, timedelta
|
||
|
||
import pandas as pd
|
||
|
||
from irrgiation.db_connect import query_postgresql_to_dataframe, dataframe_to_postgresql_batch,update_irrigation_data
|
||
|
||
from irrgiation.weatherAndSoilDataRequest import getWeatherAndSoilData, loginAuth, dateToTimestamp, get_soil_data_dk1, \
|
||
getFutureWeather, weather_params, get_soil_data_dk2
|
||
from irrgiation.dailyEvaporation import get_daily_kc, cal_et0_List, calculate_etc_List, export_etc_et0_date, \
|
||
cal_soil_fc_wp, estimate_mad_from_et, cal_stagebyDate, calculate_average_root_length,calculate_etc_List_new
|
||
from irrgiation.mathuntils import day_of_year
|
||
from irrgiation.soil_Ke import calculate_ke,calculate_D_ei
|
||
from irrgiation.crop_growth_stages import crop_growth_stages
|
||
|
||
#解析数据接口,计算均值、最大、最小值
|
||
def analy_soil_data(data):
|
||
soil_result = {}
|
||
for key in data:
|
||
daily_data = defaultdict(lambda: defaultdict(list))
|
||
for metric, entries in data[key].items():
|
||
for entry in entries:
|
||
dt = datetime.strptime(entry["datetime"], "%Y-%m-%d %H:%M:%S")
|
||
date_key = dt.date() # 按日期分组
|
||
value = float(entry["value"])
|
||
daily_data[date_key][metric].append(value)
|
||
result = {}
|
||
for date, metrics in daily_data.items():
|
||
date_stats = {}
|
||
for metric, values in metrics.items():
|
||
date_stats[metric] = {
|
||
"max": max(values),
|
||
"min": min(values),
|
||
"mean": statistics.mean(values),
|
||
'count': len(values),
|
||
'sum': sum(values)
|
||
}
|
||
result[str(date)] = date_stats # 将日期转为字符串作为键
|
||
soil_result[key] = result
|
||
return soil_result
|
||
|
||
|
||
#获取地块6个传感器的土壤湿度均值
|
||
def analy_soil_data_mean(soil_data):
|
||
result = defaultdict(lambda: {
|
||
"SOIL_MOISTURE_SURFACE": [],
|
||
"SOIL_MOISTURE_MIDDLE": [],
|
||
"SOIL_MOISTURE_BOTTOM": []
|
||
|
||
})
|
||
# 填充数据
|
||
for sensor, dates in soil_data.items():
|
||
for date, layers in dates.items():
|
||
result[date]["SOIL_MOISTURE_SURFACE"].append(layers["SOIL_MOISTURE_SURFACE"]["mean"])
|
||
result[date]["SOIL_MOISTURE_MIDDLE"].append(layers["SOIL_MOISTURE_MIDDLE"]["mean"])
|
||
result[date]["SOIL_MOISTURE_BOTTOM"].append(layers["SOIL_MOISTURE_BOTTOM"]["mean"])
|
||
# 转换为普通字典
|
||
final_result = dict(result)
|
||
result_soil = {}
|
||
for date, layers in final_result.items():
|
||
result_soil[date] = {
|
||
"SOIL_MOISTURE_SURFACE_MEAN": sum(layers["SOIL_MOISTURE_SURFACE"]) / len(layers["SOIL_MOISTURE_SURFACE"]),
|
||
"SOIL_MOISTURE_MIDDLE_MEAN": sum(layers["SOIL_MOISTURE_MIDDLE"]) / len(layers["SOIL_MOISTURE_MIDDLE"]),
|
||
"SOIL_MOISTURE_BOTTOM_MEAN": sum(layers["SOIL_MOISTURE_BOTTOM"]) / len(layers["SOIL_MOISTURE_BOTTOM"])
|
||
}
|
||
|
||
return final_result, result_soil
|
||
|
||
|
||
def analy_soil_dataNight_mean(soil_data):
|
||
daily_means = defaultdict(lambda: defaultdict(list))
|
||
# 计算平均值
|
||
for sensor, measurements in soil_data.items():
|
||
for measure_type, dates in measurements.items():
|
||
for date, value in dates.items():
|
||
daily_means[date][measure_type].append(float(value))
|
||
|
||
# 计算并格式化结果
|
||
result = {}
|
||
for date, measures in daily_means.items():
|
||
result[date] = {
|
||
f"{measure_type}_MEAN": round(sum(values) / len(values), 2)
|
||
for measure_type, values in measures.items()
|
||
}
|
||
|
||
return result
|
||
|
||
|
||
#获取地块6个传感器中土壤湿度最大值
|
||
def analy_soil_data_max(soil_data):
|
||
result = defaultdict(lambda: {
|
||
"SOIL_MOISTURE_SURFACE": [],
|
||
"SOIL_MOISTURE_MIDDLE": [],
|
||
"SOIL_MOISTURE_BOTTOM": []
|
||
|
||
})
|
||
# 填充数据
|
||
for sensor, dates in soil_data.items():
|
||
for date, layers in dates.items():
|
||
result[date]["SOIL_MOISTURE_SURFACE"].append(layers["SOIL_MOISTURE_SURFACE"]["mean"])
|
||
result[date]["SOIL_MOISTURE_MIDDLE"].append(layers["SOIL_MOISTURE_MIDDLE"]["mean"])
|
||
result[date]["SOIL_MOISTURE_BOTTOM"].append(layers["SOIL_MOISTURE_BOTTOM"]["mean"])
|
||
# 转换为普通字典
|
||
final_result = dict(result)
|
||
result_soil = {}
|
||
for date, layers in final_result.items():
|
||
result_soil[date] = {
|
||
"SOIL_MOISTURE_SURFACE_MEAN": max(layers["SOIL_MOISTURE_SURFACE"]),
|
||
"SOIL_MOISTURE_MIDDLE_MEAN": max(layers["SOIL_MOISTURE_MIDDLE"]),
|
||
"SOIL_MOISTURE_BOTTOM_MEAN": max(layers["SOIL_MOISTURE_BOTTOM"])
|
||
}
|
||
|
||
return final_result, result_soil
|
||
|
||
|
||
def get_soil_data_night_eyveryDay(data):
|
||
daily_data = {}
|
||
for sersor in data:
|
||
data_depth = {}
|
||
for key in data[sersor]:
|
||
target_time = (21, 59, 59)
|
||
result = {} # 时、分、秒元组
|
||
daily_records = {} # 临时存储每天的所有记录,用于找不到22点数据时获取最新记录
|
||
for record in data[sersor][key]:
|
||
try:
|
||
dt = datetime.strptime(record["datetime"], "%Y-%m-%d %H:%M:%S")
|
||
date_str = record["datetime"].split(" ")[0] # 提取日期部分
|
||
# 严格匹配 02:00:00
|
||
# 提取时间部分(时、分、秒)
|
||
current_time = (dt.hour, dt.minute, dt.second)
|
||
# 存储每天的所有记录(按时间排序)
|
||
if date_str not in daily_records:
|
||
daily_records[date_str] = []
|
||
daily_records[date_str].append((dt, record['value']))
|
||
# 比较时间部分
|
||
if current_time >= target_time:
|
||
if date_str not in result:
|
||
result[date_str] = record['value']
|
||
except:
|
||
continue
|
||
# 对于没有22点数据的日期,取当天最新的一条数据
|
||
for date_str in daily_records:
|
||
if date_str not in result and daily_records[date_str]:
|
||
daily_records[date_str].sort(key=lambda x: x[0]) # 按datetime排序
|
||
result[date_str] = daily_records[date_str][-1][1] # 取最后一个值
|
||
data_depth[key] = result
|
||
daily_data[sersor] = data_depth
|
||
return daily_data
|
||
|
||
|
||
def analyze_weather_data1(data):
|
||
# 1. 按日期分组数据
|
||
daily_data = defaultdict(lambda: defaultdict(list))
|
||
for metric, entries in data.items():
|
||
for entry in entries:
|
||
dt = datetime.strptime(entry["datetime"], "%Y-%m-%d %H:%M:%S")
|
||
date_key = dt.date() # 按日期分组
|
||
if metric == "AIR_LUX":
|
||
value = float(entry["value_solar"])
|
||
else:
|
||
value = float(entry["value"])
|
||
daily_data[date_key][metric].append(value)
|
||
# 2. 计算每日统计值
|
||
result = {}
|
||
for date, metrics in daily_data.items():
|
||
date_stats = {}
|
||
for metric, values in metrics.items():
|
||
date_stats[metric] = {
|
||
"max": max(values),
|
||
"min": min(values),
|
||
"mean": statistics.mean(values),
|
||
'count': len(values),
|
||
'sum': sum(values)
|
||
}
|
||
result[str(date)] = date_stats # 将日期转为字符串作为键
|
||
|
||
return result
|
||
|
||
|
||
# 获取彭曼公式的入参
|
||
def get_params(start_date, monitor_date, data):
|
||
delta = monitor_date - start_date
|
||
days = delta.days
|
||
dates = [start_date + timedelta(days=i) for i in range(days)]
|
||
date_strings = [date.strftime("%Y-%m-%d") for date in dates]
|
||
date_params = {}
|
||
for date in date_strings:
|
||
result_params = get_weather_params(data, date)
|
||
date_params[date] = result_params
|
||
return date_params
|
||
|
||
|
||
def get_weather_params(data, date):
|
||
result = {}
|
||
elevation = 865 # 海拔(m)
|
||
lat = 41.34252110189814 # 纬度(度)
|
||
#计算当前日期位于当年的多少天
|
||
doy = day_of_year(date)
|
||
|
||
for item in data['AIR_LUX']:
|
||
item['value_solar'] = float(item['value']) * 0.0081 * 3600
|
||
data_tj = analyze_weather_data1(data)
|
||
data_tj_date = data_tj[date];
|
||
tmax = data_tj_date['AIR_TEMPERATURE']['max']
|
||
tmin = data_tj_date['AIR_TEMPERATURE']['min']
|
||
tmean = data_tj_date['AIR_TEMPERATURE']['mean']
|
||
rh_mean = data_tj_date['AIR_HUMIDITY']['mean']
|
||
wind_speed = data_tj_date['WIND_SPEED']['mean']
|
||
solar = data_tj_date['AIR_LUX']['sum'] / 1000000
|
||
result['tmax'] = round(tmax, 3)
|
||
result['tmin'] = round(tmin, 3)
|
||
result['tmean'] = round(tmean, 3)
|
||
result['rh_mean'] = round(rh_mean, 3)
|
||
result['wind_speed'] = round(wind_speed, 3)*0.94
|
||
result['solar_rad'] = round(solar, 3)
|
||
result['elevation'] = elevation
|
||
result['lat'] = round(lat, 3)
|
||
result['doy'] = doy
|
||
return result
|
||
|
||
|
||
# 判断是否需要灌溉
|
||
def isNeedirrigate(df, qx_coff, soil_coff,Di_1,zwlx_growth_stages):
|
||
df['RD'] = 0.0
|
||
df['Di'] = 0.0
|
||
df['Di-1'] = Di_1
|
||
df['mad'] = 0.0
|
||
df['irrigation_depth'] = 0.0
|
||
df['irrigation_acre'] = 0.0
|
||
df['isNeedirrigate'] = False
|
||
df['Reset_Flag'] = False
|
||
# df['irrigate_sd_predict'] = 0.0
|
||
df['f_t'] = 0.0
|
||
df['f_js'] = 0.0
|
||
df['f_soil'] = 0.0
|
||
for i in range(len(df)):
|
||
# 设置Di-1(前一天累计值)
|
||
if i > 0:
|
||
df.at[i, 'Di-1'] = df.at[i - 1, 'Di']
|
||
# 计算当前累计值(Di-1 + 当天ETc)
|
||
raw, rd, mad, k_rain = cal_raw(df.at[i, 'ETc'], df.at[i, 'Date'],zwlx_growth_stages)
|
||
if df.at[i, 'rain_effective']<5:
|
||
df.at[i, 'rain_effective'] = 0
|
||
else:
|
||
df.at[i, 'rain_effective'] = df.at[i, 'rain_effective'] * k_rain
|
||
current_cum = df.at[i, 'Di-1'] + df.at[i, 'ETc']- df.at[i, 'rain_effective']
|
||
df['RD'] = rd
|
||
df.at[i,'mad'] = mad
|
||
df.at[i, 'raw'] = round(raw, 3)
|
||
f_t = qx_coff[df.at[i, 'Date']]['qw']
|
||
f_js = qx_coff[df.at[i, 'Date']]['js']
|
||
f_soil = soil_coff[df.at[i, 'Date']]
|
||
raw_adj = cal_raw_adjust(raw, f_t, f_js, f_soil)
|
||
df.at[i, 'f_t'] = f_t
|
||
df.at[i, 'f_js'] = f_js
|
||
df.at[i, 'f_soil'] = f_soil
|
||
df.at[i, 'raw_adjust'] = round(raw_adj, 3)
|
||
# 判断是否需要重置
|
||
if current_cum > raw_adj:
|
||
df.at[i, 'Reset_Flag'] = True
|
||
df.at[i, 'irrigation_depth'] = round(current_cum, 3)
|
||
df.at[i, 'isNeedirrigate'] = True
|
||
df.at[i, 'Di'] = 0 # 保留当天ETc值
|
||
df.at[i, 'irrigation_acre'] = round((current_cum*667/1000),3)
|
||
else:
|
||
df.at[i, 'Di'] = round(current_cum, 3) # 正常累加
|
||
return df
|
||
|
||
|
||
def cal_raw(etc, monitor_date,zwlx_growth_stages):
|
||
theta_fc, theta_wp = cal_soil_fc_wp()
|
||
stage, details,hight,k_rain= cal_stagebyDate(monitor_date,zwlx_growth_stages)
|
||
rd = calculate_average_root_length(details)
|
||
mad = estimate_mad_from_et(etc)
|
||
raw = mad * (theta_fc - theta_wp) * rd * 10
|
||
return raw, rd,mad,k_rain
|
||
|
||
|
||
def cal_raw_adjust(raw, f_t, f_rain, f_soil):
|
||
raw_adjust = raw * f_soil * f_t * f_rain
|
||
return raw_adjust
|
||
|
||
|
||
def cal_qxcoefficient_adjust(start_date, monitor_date, qx_data):
|
||
|
||
qx_coefficient = {}
|
||
current_date = start_date
|
||
qxData_filter = {}
|
||
for key in qx_data:
|
||
if key == "AIR_TEMPERATURE" or key == "RAIN_FALL_REALTIME":
|
||
qxData_filter[key] = qx_data[key]
|
||
qxData_filter_tj = analyze_weather_data1(qxData_filter)
|
||
now_date = datetime.now().date()
|
||
while current_date < monitor_date:
|
||
qx_futureData = []
|
||
result = {}
|
||
if (current_date + timedelta(days=3)).date() < now_date:
|
||
start = datetime.strptime((current_date + timedelta(days=1)).strftime("%Y-%m-%d"), "%Y-%m-%d")
|
||
end = datetime.strptime((current_date + timedelta(days=3)).strftime("%Y-%m-%d"), "%Y-%m-%d")
|
||
# 筛选日期范围内的数据
|
||
filter = {
|
||
date: values
|
||
for date, values in qxData_filter_tj.items()
|
||
if start <= datetime.strptime(date, "%Y-%m-%d") <= end
|
||
}
|
||
qx_futureData = transform_data(filter)
|
||
else:
|
||
try:
|
||
# print(f"进入else分支: {current_date}")
|
||
qx_futureData = getFutureWeather(current_date)
|
||
except Exception as e:
|
||
# print(f"else分支异常: {e}")
|
||
raise # 保留异常以便调试
|
||
qw_mean = (qx_futureData['qw_day1']['mean'] + qx_futureData['qw_day2']['mean'] + qx_futureData['qw_day3']['mean']) / 3
|
||
js_sum = qx_futureData['js_day1']['max'] + qx_futureData['js_day2']['max'] + qx_futureData['js_day3']['max']
|
||
qw_coff = 1.0
|
||
js_coff = 1.0
|
||
if qw_mean < 10:
|
||
qw_coff = 1.1
|
||
elif 10 < qw_mean <= 25:
|
||
qw_coff = 1
|
||
elif 25 < qw_mean <= 30:
|
||
qw_coff = 0.85
|
||
else:
|
||
qw_coff = 0.75
|
||
if js_sum <= 5:
|
||
js_coff = 1.0 # 少雨
|
||
elif 5 < js_sum <= 10:
|
||
js_coff = 1.2 # 中雨
|
||
elif 10 < js_sum <= 20:
|
||
js_coff = 1.4 # 大雨
|
||
else:
|
||
js_coff = 1.6 # 暴雨
|
||
result['qw'] = qw_coff
|
||
result['js'] = js_coff
|
||
qx_coefficient[current_date.strftime("%Y-%m-%d")] = result
|
||
current_date = current_date + timedelta(days=1)
|
||
return qx_coefficient
|
||
|
||
|
||
def transform_data(original_data):
|
||
transformed = {}
|
||
# 处理温度数据 (qw_day)
|
||
for i, (date, metrics) in enumerate(original_data.items(), 1):
|
||
temp_data = metrics["AIR_TEMPERATURE"]
|
||
transformed[f"qw_day{i}"] = {
|
||
"max": round(temp_data["max"], 2),
|
||
"min": round(temp_data["min"], 2),
|
||
"mean": round(temp_data["mean"], 2),
|
||
"sum": round(temp_data["sum"], 2)
|
||
}
|
||
|
||
# 处理降雨数据 (js_day)
|
||
for i, (date, metrics) in enumerate(original_data.items(), 1):
|
||
rain_data = metrics["RAIN_FALL_REALTIME"]
|
||
transformed[f"js_day{i}"] = {
|
||
"max": round(rain_data["max"], 2),
|
||
"min": round(rain_data["min"], 2),
|
||
"mean": round(rain_data["mean"], 2),
|
||
"sum": round(rain_data["sum"], 2)
|
||
}
|
||
|
||
return transformed
|
||
|
||
|
||
def cal_soil_coff(soil_data):
|
||
soil_data_coff = {}
|
||
for sensor in soil_data:
|
||
for date in soil_data[sensor]:
|
||
soil_cof = 1.0
|
||
sd_surf = float(soil_data['SOIL_MOISTURE_SURFACE'][date])
|
||
sd_mid = float(soil_data['SOIL_MOISTURE_MIDDLE'][date])
|
||
if sd_surf < 10:
|
||
soil_cof = 0.5
|
||
if 10 <sd_surf < 15:
|
||
soil_cof = 0.75
|
||
elif 15<sd_surf < 20:
|
||
soil_cof = 1.0
|
||
else:
|
||
soil_cof = 1.2
|
||
soil_data_coff[date] = soil_cof
|
||
return soil_data_coff
|
||
|
||
|
||
#将两块地的传感器数据分隔开
|
||
def get_soil_data_bydk(soil_data):
|
||
target_key = 7
|
||
dk1_soildata = {}
|
||
dk2_soildata = {}
|
||
|
||
for key, value in soil_data.items():
|
||
parts = key.split("号传感器")
|
||
if int(parts[0]) < target_key:
|
||
dk1_soildata[key] = value
|
||
else:
|
||
dk2_soildata[key] = value
|
||
return dk1_soildata, dk2_soildata
|
||
# 整生育期监测
|
||
def cal_dk_isNeegirrigate(zwlx_name,dk_name,start_date, monitor_date,Di_1):
|
||
auth_token = loginAuth()
|
||
date_start = start_date.strftime("%Y-%m-%d") + " 00:00:00.123"
|
||
date_end_qx=monitor_date
|
||
if (monitor_date + timedelta(days=3)).date()<= datetime.now().date():
|
||
date_end_qx=(monitor_date + timedelta(days=3)).strftime("%Y-%m-%d") + " 23:59:59.123"
|
||
else:
|
||
date_end_qx=datetime.now().date().strftime("%Y-%m-%d") + " 23:59:59.123"
|
||
date_end = monitor_date.strftime("%Y-%m-%d") + " 23:59:59.123"
|
||
startTs = dateToTimestamp(date_start)
|
||
endTs = dateToTimestamp(date_end)
|
||
zwlx_growth_stages = crop_growth_stages[zwlx_name]
|
||
kc_daily = get_daily_kc(zwlx_growth_stages)
|
||
# #获取气象数据
|
||
qxdata = getWeatherAndSoilData(auth_token, weather_params['device_id'], startTs, dateToTimestamp(date_end_qx), weather_params['agg'],
|
||
weather_params['interval'], weather_params['limit'], weather_params['orderBy'],
|
||
weather_params['keys'])
|
||
# # #彭曼公式气象入参
|
||
qx_params = get_params(start_date, monitor_date, qxdata)
|
||
# #获取土壤传感器数据
|
||
data = get_soil_data_dk1(auth_token, startTs, endTs)
|
||
soil_data = get_soil_data_night_eyveryDay(data)
|
||
dk1_soildata, dk2_soildata = get_soil_data_bydk(soil_data)
|
||
# 膜边探头优先原则,1号和7号传感器分别为1号地和5号地的膜边探头
|
||
dk1_soil_mean = dk1_soildata['1号传感器']
|
||
dk2_soil_mean = dk2_soildata['7号传感器']
|
||
# #计算参考蒸散量
|
||
et0_list = cal_et0_List(start_date, monitor_date, qx_params)
|
||
#计算土壤蒸发系数
|
||
ke_data = cal_ke_daily_list(start_date, monitor_date, et0_list, kc_daily, qxdata)
|
||
ke_daily = []
|
||
rain_daily=[]
|
||
irrigate_daily=[]
|
||
for date in sorted(ke_data.keys()):
|
||
ke_value = round(ke_data[date]['ke'],3)
|
||
rain_value= round(ke_data[date]['rain'],3)
|
||
irrigate_value = ke_data[date]['irrigation']
|
||
ke_daily.append(ke_value)
|
||
rain_daily.append(rain_value)
|
||
irrigate_daily.append(irrigate_value)
|
||
|
||
# #获取作物蒸散量
|
||
etc_list, date_strings, kc_list = calculate_etc_List_new(et0_list, start_date, monitor_date, kc_daily,ke_daily)
|
||
# # 获取未来3天气象数据
|
||
qx_coff = cal_qxcoefficient_adjust(start_date, monitor_date, qxdata)
|
||
if "1" in dk_name:
|
||
df = export_etc_et0_date(et0_list, etc_list, date_strings, kc_list,ke_daily, dk1_soil_mean,rain_daily,irrigate_daily,dk_name)
|
||
# 基于每天实测土壤相对湿度计算土壤系数
|
||
soil_coff = cal_soil_coff(dk1_soil_mean)
|
||
elif "5" in dk_name:
|
||
df = export_etc_et0_date(et0_list, etc_list, date_strings, kc_list,ke_daily, dk2_soil_mean,rain_daily,irrigate_daily,dk_name)
|
||
# 基于每天实测土壤相对湿度计算土壤系数
|
||
soil_coff = cal_soil_coff(dk2_soil_mean)
|
||
else:
|
||
return "该地块数据不存在"
|
||
# 判断是否需要灌溉
|
||
dataframe = isNeedirrigate(df, qx_coff, soil_coff,Di_1,zwlx_growth_stages)
|
||
random_uuid = uuid.uuid4()
|
||
uuid_str = str(random_uuid)
|
||
# df.to_csv(
|
||
# 'D:/悦柠/遥感/甘草/ceshi/' + dk_name + "_" + start_date.strftime("%Y-%m-%d") + "-" + monitor_date.strftime(
|
||
# "%Y-%m-%d")+"_"+uuid_str + ".csv", index=False) # CSV 文件
|
||
return dataframe
|
||
def cal_dk_isNeegirrigate_Day(zwlx_name,dk_name,soil_key,start_date, monitor_date,Di_1,weather_key):
|
||
auth_token = loginAuth()
|
||
date_start = start_date.strftime("%Y-%m-%d") + " 00:00:00.123"
|
||
date_end_qx=monitor_date
|
||
if (monitor_date + timedelta(days=3)).date()<= datetime.now().date():
|
||
date_end_qx=(monitor_date + timedelta(days=3)).strftime("%Y-%m-%d") + " 23:59:59.123"
|
||
else:
|
||
date_end_qx=datetime.now().date().strftime("%Y-%m-%d") + " 23:59:59.123"
|
||
date_end = monitor_date.strftime("%Y-%m-%d") + " 23:59:59.123"
|
||
startTs = dateToTimestamp(date_start)
|
||
endTs = dateToTimestamp(date_end)
|
||
zwlx_growth_stages=crop_growth_stages[zwlx_name]
|
||
kc_daily = get_daily_kc(zwlx_growth_stages)
|
||
# #获取气象数据
|
||
qxdata = getWeatherAndSoilData(auth_token, weather_key, startTs, dateToTimestamp(date_end_qx), weather_params['agg'],
|
||
weather_params['interval'], weather_params['limit'], weather_params['orderBy'],
|
||
weather_params['keys'])
|
||
# 获取土壤传感器数据
|
||
data = get_soil_data_dk2(auth_token, soil_key, startTs, endTs)
|
||
soil_data = get_soil_data_night_eyveryDay(data)
|
||
# dk1_soildata, dk2_soildata = get_soil_data_bydk(soil_data)
|
||
# 膜边探头优先原则,1号和7号传感器分别为1号地和5号地的膜边探头
|
||
dk_soil_mean = soil_data[soil_key]
|
||
if len(qxdata) !=0 and len(dk_soil_mean) !=0:
|
||
# # #彭曼公式气象入参
|
||
qx_params = get_params(start_date, monitor_date, qxdata)
|
||
# #计算参考蒸散量
|
||
et0_list = cal_et0_List(start_date, monitor_date, qx_params)
|
||
# 计算土壤蒸发系数
|
||
ke_data = cal_ke_daily_list(start_date, monitor_date, et0_list, kc_daily, qxdata, zwlx_growth_stages)
|
||
ke_daily = []
|
||
rain_daily = []
|
||
irrigate_daily = []
|
||
for date in sorted(ke_data.keys()):
|
||
ke_value = round(ke_data[date]['ke'], 3)
|
||
rain_value = round(ke_data[date]['rain'], 3)
|
||
irrigate_value = ke_data[date]['irrigation']
|
||
ke_daily.append(ke_value)
|
||
rain_daily.append(rain_value)
|
||
irrigate_daily.append(irrigate_value)
|
||
# #获取作物蒸散量
|
||
etc_list, date_strings, kc_list = calculate_etc_List_new(et0_list, start_date, monitor_date, kc_daily,
|
||
ke_daily)
|
||
# # 获取未来3天气象数据
|
||
qx_coff = cal_qxcoefficient_adjust(start_date, monitor_date, qxdata)
|
||
|
||
df = export_etc_et0_date(et0_list, etc_list, date_strings, kc_list, ke_daily, dk_soil_mean, rain_daily,
|
||
irrigate_daily, dk_name)
|
||
# 基于每天实测土壤相对湿度计算土壤系数
|
||
soil_coff = cal_soil_coff(dk_soil_mean)
|
||
# 判断是否需要灌溉
|
||
dataframe = isNeedirrigate(df, qx_coff, soil_coff, Di_1, zwlx_growth_stages)
|
||
return dataframe
|
||
elif len(qxdata) ==0 and len(dk_soil_mean) !=0:
|
||
raise ValueError("未查询到气象数据")
|
||
elif len(qxdata) !=0 and len(dk_soil_mean) ==0:
|
||
raise ValueError("未查询到土壤数据")
|
||
else:
|
||
raise ValueError("未查询到气象和土壤数据")
|
||
|
||
|
||
#计算土壤蒸发系数
|
||
def cal_ke_daily_list(start_date,monitor_date,et0_list,kc_list,qx_data,zwlx_growth_stages):
|
||
stage, details, hight ,k_rain= cal_stagebyDate(monitor_date,zwlx_growth_stages)
|
||
REW=9
|
||
I=0.0
|
||
theta_fc=0.2884
|
||
theta_wp=0.1086
|
||
current_date=start_date
|
||
qxData_tj = analyze_weather_data1(qx_data)
|
||
ke_data= {}
|
||
i=0
|
||
while current_date< monitor_date:
|
||
date_key = str(current_date.date())
|
||
u2=qxData_tj[date_key]['WIND_SPEED']['mean']
|
||
rain=qxData_tj[date_key]['RAIN_FALL_REALTIME']['max']
|
||
rh_min=qxData_tj[date_key]['AIR_HUMIDITY']['min']
|
||
if current_date == start_date:
|
||
DE_i_1 = 0
|
||
fw=0.35
|
||
else:
|
||
# 从上一天的数据中获取DE_i(如果存在)
|
||
prev_date = current_date - timedelta(days=1)
|
||
prev_date_key = str(prev_date.date())
|
||
if prev_date_key in ke_data:
|
||
DE_i_1 = ke_data[prev_date_key]['DE_i']
|
||
else:
|
||
DE_i_1 = 0 # 处理特殊情况(如start_date等于monitor_date)
|
||
if I > 0 and rain < 4:
|
||
fw = 0.35
|
||
elif I > 0 and rain < 4:
|
||
fw = 1
|
||
elif rain > 4 and I == 0:
|
||
fw = 1
|
||
else:
|
||
fw = ke_data[prev_date_key]['fw']
|
||
et0 = 0.0
|
||
kc = 0.0
|
||
if i < len(et0_list):
|
||
et0 = et0_list[i]
|
||
kc = kc_list[i]
|
||
ke,few=calculate_ke(hight, u2, rh_min, kc, DE_i_1, REW, fw, theta_fc,theta_wp)
|
||
et_soil=ke*et0
|
||
DE_i = calculate_D_ei(DE_i_1, rain, I,et_soil, fw,few)
|
||
#创建当天的数据字典
|
||
daily_data = {
|
||
'ke': ke,
|
||
'DE_i': DE_i,
|
||
'et0': et0,
|
||
'et_soil': et_soil,
|
||
'fw':fw,
|
||
"rain":rain,
|
||
"irrigation":I
|
||
}
|
||
ke_data[date_key]=daily_data
|
||
current_date = current_date + timedelta(days=1)
|
||
i=i+1
|
||
return ke_data
|
||
# 单天监测
|
||
def cal_irrigationByDay(zwlx_name,dkname,start_date,end_date,soil_key,weather_key,irrigation_really):
|
||
yesterday_date=(start_date - timedelta(days=1)).strftime("%Y-%m-%d")
|
||
condition = {"Date": yesterday_date,"dkbm":dkname}
|
||
df=query_postgresql_to_dataframe(condition)
|
||
Di_1 = 0
|
||
if irrigation_really>0:
|
||
Di_1 = 0
|
||
update_irrigation_data(yesterday_date,dkname,"irrigation_really",irrigation_really)
|
||
else:
|
||
# 将Date列转换为日期时间类型
|
||
df['Date'] = pd.to_datetime(df['Date'])
|
||
if len(df[df.Date == (start_date - timedelta(days=1))])!=0:
|
||
isNeedjg=df[df.Date == (start_date- timedelta(days=1))]['isNeedirrigate'].values[0]
|
||
if isNeedjg:
|
||
Di_1 = df[df.Date == (start_date - timedelta(days=1))]['Di-1'].values[0]+df[df.Date == (start_date - timedelta(days=1))]['ETc'].values[0]
|
||
else:
|
||
Di_1 = df[df.Date == (start_date - timedelta(days=1))]['Di'].values[0]
|
||
dataframe=cal_dk_isNeegirrigate_Day(zwlx_name,dkname,soil_key,start_date,end_date,Di_1,weather_key)
|
||
condition_new = {"Date": start_date.strftime("%Y-%m-%d"), "dkbm": dkname}
|
||
df_query=query_postgresql_to_dataframe(condition_new)
|
||
if len(df_query)==0:
|
||
dataframe_to_postgresql_batch(dataframe)
|
||
else:
|
||
print("库表中已存在该数据")
|
||
return dataframe
|
||
if __name__ == "__main__":
|
||
#调用气象数据接口--获取具体日期的气象数据(气象)
|
||
# auth_token = loginAuth()
|
||
start_date = datetime(2025, 7, 16)
|
||
monitor_date = datetime(2025, 7, 17)
|
||
dk_name = "5"
|
||
zwlx_name="甘草"
|
||
soil_key = "8637b970-561b-11f0-a556-4f10f26fc07f"
|
||
weather_key="18d121f0-561b-11f0-a556-4f10f26fc07f"
|
||
irrigation_really=5
|
||
cal_irrigationByDay(zwlx_name,dk_name,start_date,monitor_date,soil_key,weather_key,irrigation_really)
|
||
# cal_dk_isNeegirrigate(dk_name, planting_date, monitor_date,0)
|