|
|
@@ -0,0 +1,157 @@
|
|
|
+-- ============================================================
|
|
|
+-- 脚本功能:生成短期气象预报原始数据 (data_short_term_weather_forecast_raw)
|
|
|
+-- 规则:模拟过去N天至未来M天内,每天UTC 12:00的起报任务
|
|
|
+-- 场站:渤海一号风电场 (ID: 2)
|
|
|
+-- ============================================================
|
|
|
+DO $$
|
|
|
+DECLARE
|
|
|
+ -- ================= 配置区域 =================
|
|
|
+ v_station_id BIGINT := 2; -- 场站ID
|
|
|
+ v_station_name VARCHAR := '渤海一号风电场'; -- 场站名称
|
|
|
+ v_latitude VARCHAR := '38.5000'; -- 纬度 (示例)
|
|
|
+ v_longitude VARCHAR := '120.5000'; -- 经度 (示例)
|
|
|
+ v_data_source INTEGER := 101; -- 数据源ID
|
|
|
+ v_data_model_id INTEGER := 201; -- 模型ID
|
|
|
+
|
|
|
+ v_forecast_days INTEGER := 10; -- 单次预报天数
|
|
|
+ v_interval_min INTEGER := 15; -- 间隔分钟数
|
|
|
+ v_total_steps INTEGER := (v_forecast_days * 24 * 60) / v_interval_min; -- 单次预报总步数 (960)
|
|
|
+
|
|
|
+ -- 【可配置】时间范围:过去30天 到 未来10天
|
|
|
+ v_past_days INTEGER := 30; -- 从过去多少天开始
|
|
|
+ v_future_days INTEGER := 10; -- 到未来多少天结束
|
|
|
+
|
|
|
+ v_date_range_start DATE := CURRENT_DATE - INTERVAL '1 day' * v_past_days;
|
|
|
+ v_date_range_end DATE := CURRENT_DATE + INTERVAL '1 day' * v_future_days;
|
|
|
+
|
|
|
+ -- 基础气象参数 (用于模拟自然规律)
|
|
|
+ v_base_temp DECIMAL := 15.0; -- 基础气温
|
|
|
+ v_base_wind_speed DECIMAL := 7.0; -- 基础风速
|
|
|
+ v_base_wind_dir DECIMAL := 220.0; -- 基础风向
|
|
|
+ v_max_solar DECIMAL := 900.0; -- 最大辐照度
|
|
|
+
|
|
|
+ -- 循环变量
|
|
|
+ i INTEGER;
|
|
|
+ d INTEGER; -- 日期循环变量
|
|
|
+ v_current_day DATE;
|
|
|
+
|
|
|
+ v_start_time_utc TIMESTAMP;
|
|
|
+ v_forecast_time_utc TIMESTAMP;
|
|
|
+ v_hour_of_day DECIMAL;
|
|
|
+
|
|
|
+ -- 模拟计算值
|
|
|
+ v_temp_val DECIMAL;
|
|
|
+ v_wind_speed_val DECIMAL;
|
|
|
+ v_wind_dir_val DECIMAL;
|
|
|
+ v_solar_val DECIMAL;
|
|
|
+ v_cloud_val DECIMAL;
|
|
|
+ v_pressure_val DECIMAL;
|
|
|
+
|
|
|
+ -- 时间戳转换 (Unix Epoch)
|
|
|
+ v_start_time_ts INTEGER;
|
|
|
+ v_forecast_time_ts INTEGER;
|
|
|
+ v_create_time_ts INTEGER;
|
|
|
+BEGIN
|
|
|
+ RAISE NOTICE '开始生成气象数据。场站: %, 时间范围: % 至 %', v_station_name, v_date_range_start, v_date_range_end;
|
|
|
+
|
|
|
+ -- 1. 清理旧数据 (可选)
|
|
|
+ DELETE FROM data_short_term_weather_forecast_raw
|
|
|
+ WHERE station_id = v_station_id
|
|
|
+ AND start_time >= (EXTRACT(EPOCH FROM v_date_range_start))::INTEGER
|
|
|
+ AND start_time <= (EXTRACT(EPOCH FROM v_date_range_end + INTERVAL '10 days'))::INTEGER;
|
|
|
+
|
|
|
+ -- 2. 外层循环:遍历每一天
|
|
|
+ FOR d IN 0..(v_date_range_end - v_date_range_start) LOOP
|
|
|
+ v_current_day := v_date_range_start + d;
|
|
|
+
|
|
|
+ -- 设置当天的起报时间为 UTC 12:00
|
|
|
+ v_start_time_utc := v_current_day + INTERVAL '12 hours';
|
|
|
+ v_start_time_ts := EXTRACT(EPOCH FROM v_start_time_utc)::INTEGER;
|
|
|
+ v_create_time_ts := EXTRACT(EPOCH FROM NOW())::INTEGER;
|
|
|
+
|
|
|
+ -- 3. 内层循环:生成单次起报的10天预报数据
|
|
|
+ FOR i IN 0..v_total_steps - 1 LOOP
|
|
|
+ -- 计算当前预报时间点
|
|
|
+ v_forecast_time_utc := v_start_time_utc + (i * v_interval_min * INTERVAL '1 minute');
|
|
|
+ v_forecast_time_ts := EXTRACT(EPOCH FROM v_forecast_time_utc)::INTEGER;
|
|
|
+
|
|
|
+ -- 获取一天中的小时数 (带小数,用于计算辐照度等)
|
|
|
+ v_hour_of_day := EXTRACT(HOUR FROM v_forecast_time_utc) + (EXTRACT(MINUTE FROM v_forecast_time_utc) / 60.0);
|
|
|
+
|
|
|
+ -- --- 模拟自然规律算法 ---
|
|
|
+
|
|
|
+ -- 1. 辐照度模拟 (简单正弦波,假设 6点-18点有光照)
|
|
|
+ IF v_hour_of_day >= 6 AND v_hour_of_day <= 18 THEN
|
|
|
+ -- 正弦函数模拟太阳高度角,12点为峰值
|
|
|
+ v_solar_val := v_max_solar * SIN(RADIANS((v_hour_of_day - 6) * 15));
|
|
|
+ ELSE
|
|
|
+ v_solar_val := 0;
|
|
|
+ END IF;
|
|
|
+ -- 添加少量随机波动
|
|
|
+ v_solar_val := GREATEST(0, v_solar_val * (0.9 + RANDOM() * 0.2));
|
|
|
+
|
|
|
+ -- 2. 气温模拟 (滞后于辐照度,假设 14:00 最高,04:00 最低)
|
|
|
+ -- 振幅 10度
|
|
|
+ v_temp_val := v_base_temp + 10 * SIN(RADIANS((v_hour_of_day - 4) * 15));
|
|
|
+ v_temp_val := v_temp_val + (RANDOM() * 2 - 1); -- 随机扰动
|
|
|
+
|
|
|
+ -- 3. 风速模拟 (随机游走)
|
|
|
+ v_wind_speed_val := v_base_wind_speed + (RANDOM() * 4 - 2);
|
|
|
+ v_wind_speed_val := GREATEST(0.5, v_wind_speed_val); -- 最小风速
|
|
|
+
|
|
|
+ -- 4. 风向模拟
|
|
|
+ v_wind_dir_val := v_base_wind_dir + (RANDOM() * 40 - 20);
|
|
|
+ IF v_wind_dir_val > 360 THEN v_wind_dir_val := v_wind_dir_val - 360; END IF;
|
|
|
+ IF v_wind_dir_val < 0 THEN v_wind_dir_val := v_wind_dir_val + 360; END IF;
|
|
|
+
|
|
|
+ -- 5. 其他参数
|
|
|
+ v_cloud_val := 20 + RANDOM() * 60; -- 云量 20-80%
|
|
|
+ v_pressure_val := 1013.25 + (RANDOM() * 20 - 10); -- 气压
|
|
|
+
|
|
|
+ -- 6. 插入数据
|
|
|
+ INSERT INTO data_short_term_weather_forecast_raw (
|
|
|
+ latitude, longitude, data_org_type, data_type, business_process_type,
|
|
|
+ data_source, data_sourcegrab_id, data_sourcegrab_pattern_name,
|
|
|
+ data_model_id, data_model_name, source_id, source_name,
|
|
|
+ entity_id, entity_type, create_time, start_time, forecast_time,
|
|
|
+ pre_days, lead_time, station_id, station_name,
|
|
|
+ subject_id, subject_name, machine_id, machine_name,
|
|
|
+ analyze_his_id, archive_record_id,
|
|
|
+ tcc, hcc, lcc, mcc,
|
|
|
+ tsfc, psfc, rhsfc,
|
|
|
+ diffirr, directirr, tirr,
|
|
|
+ wd_hub, ws_hub, ws,
|
|
|
+ wd10, wd30, wd50, wd70, wd80, wd90, wd100, wd120, wd140, wd160, wd180, wd200,
|
|
|
+ ws10, ws30, ws50, ws70, ws80, ws90, ws100, ws120, ws140, ws160, ws180, ws200
|
|
|
+ ) VALUES (
|
|
|
+ v_latitude, v_longitude, 'TimeSeries', 1, 1, -- 基础信息
|
|
|
+ v_data_source, 9999, 'AutoGen_Pattern', -- 数据源信息
|
|
|
+ v_data_model_id, 'ECMWF_Model', v_data_source, 'ECMWF', -- 模型信息
|
|
|
+ v_station_id::VARCHAR, 'Station', v_create_time_ts, v_start_time_ts, v_forecast_time_ts, -- 实体与时间
|
|
|
+ v_forecast_days, i * v_interval_min, v_station_id, v_station_name, -- 预报信息
|
|
|
+ NULL, NULL, NULL, NULL, -- 交易/风机主体 (空)
|
|
|
+ NULL, NULL, -- 归档ID (空)
|
|
|
+ -- 气象数值 (转为 VARCHAR)
|
|
|
+ ROUND(v_cloud_val)::VARCHAR, NULL, NULL, NULL, -- 云量 (仅填总云量)
|
|
|
+ ROUND(v_temp_val, 1)::VARCHAR, ROUND(v_pressure_val, 1)::VARCHAR, ROUND(50 + RANDOM()*40)::VARCHAR, -- 温压湿
|
|
|
+ ROUND(v_solar_val * 0.2)::VARCHAR, ROUND(v_solar_val * 0.8)::VARCHAR, ROUND(v_solar_val)::VARCHAR, -- 辐照度
|
|
|
+ ROUND(v_wind_dir_val)::VARCHAR, ROUND(v_wind_speed_val, 1)::VARCHAR, ROUND(v_wind_speed_val, 1)::VARCHAR, -- 轮毂风
|
|
|
+ -- 各层风向 (假设随高度变化不大,加一点偏移)
|
|
|
+ ROUND(v_wind_dir_val + 5)::VARCHAR, ROUND(v_wind_dir_val + 4)::VARCHAR, ROUND(v_wind_dir_val + 3)::VARCHAR,
|
|
|
+ ROUND(v_wind_dir_val + 2)::VARCHAR, ROUND(v_wind_dir_val + 1)::VARCHAR, ROUND(v_wind_dir_val)::VARCHAR,
|
|
|
+ ROUND(v_wind_dir_val - 1)::VARCHAR, ROUND(v_wind_dir_val - 2)::VARCHAR, ROUND(v_wind_dir_val - 3)::VARCHAR,
|
|
|
+ ROUND(v_wind_dir_val - 4)::VARCHAR, ROUND(v_wind_dir_val - 5)::VARCHAR, ROUND(v_wind_dir_val - 6)::VARCHAR,
|
|
|
+ -- 各层风速 (假设随高度增加而增加 - 风切变)
|
|
|
+ ROUND(v_wind_speed_val * 0.8, 1)::VARCHAR, ROUND(v_wind_speed_val * 0.85, 1)::VARCHAR, ROUND(v_wind_speed_val * 0.9, 1)::VARCHAR,
|
|
|
+ ROUND(v_wind_speed_val * 0.95, 1)::VARCHAR, ROUND(v_wind_speed_val * 0.98, 1)::VARCHAR, ROUND(v_wind_speed_val, 1)::VARCHAR,
|
|
|
+ ROUND(v_wind_speed_val * 1.02, 1)::VARCHAR, ROUND(v_wind_speed_val * 1.05, 1)::VARCHAR, ROUND(v_wind_speed_val * 1.08, 1)::VARCHAR,
|
|
|
+ ROUND(v_wind_speed_val * 1.1, 1)::VARCHAR, ROUND(v_wind_speed_val * 1.12, 1)::VARCHAR, ROUND(v_wind_speed_val * 1.15, 1)::VARCHAR
|
|
|
+ );
|
|
|
+ END LOOP;
|
|
|
+
|
|
|
+ RAISE NOTICE '已生成 % 的预报数据', v_current_day;
|
|
|
+ END LOOP;
|
|
|
+
|
|
|
+ RAISE NOTICE '所有气象数据生成完成!';
|
|
|
+
|
|
|
+END $$;
|