Browse Source

[demo] 增加预测相关表mock data脚本

taosj 4 days ago
parent
commit
ccaabf8196
19 changed files with 1622 additions and 0 deletions
  1. 84 0
      doc/数据模拟脚本/短期功率预测/mock_data_short_term_power_forecast_back.sql
  2. 85 0
      doc/数据模拟脚本/短期功率预测/mock_data_short_term_power_forecast_correct.sql
  3. 97 0
      doc/数据模拟脚本/短期功率预测/mock_data_short_term_power_forecast_issued.sql
  4. 160 0
      doc/数据模拟脚本/短期功率预测/mock_data_short_term_power_forecast_raw.sql
  5. 84 0
      doc/数据模拟脚本/短期功率预测/mock_data_short_term_power_forecast_report.sql
  6. 11 0
      doc/数据模拟脚本/短期功率预测/readme.md
  7. 104 0
      doc/数据模拟脚本/短期气象预测/mock_data_short_term_weather_forecast_back.sql
  8. 104 0
      doc/数据模拟脚本/短期气象预测/mock_data_short_term_weather_forecast_correct.sql
  9. 96 0
      doc/数据模拟脚本/短期气象预测/mock_data_short_term_weather_forecast_issued.sql
  10. 157 0
      doc/数据模拟脚本/短期气象预测/mock_data_short_term_weather_forecast_raw.sql
  11. 104 0
      doc/数据模拟脚本/短期气象预测/mock_data_short_term_weather_forecast_report.sql
  12. 11 0
      doc/数据模拟脚本/短期气象预测/readme.md
  13. 65 0
      doc/数据模拟脚本/超短期功率预测/mock_data_super_short_term_forecast_back.sql
  14. 65 0
      doc/数据模拟脚本/超短期功率预测/mock_data_super_short_term_forecast_correct.sql
  15. 65 0
      doc/数据模拟脚本/超短期功率预测/mock_data_super_short_term_forecast_issued.sql
  16. 109 0
      doc/数据模拟脚本/超短期功率预测/mock_data_super_short_term_forecast_raw.sql
  17. 65 0
      doc/数据模拟脚本/超短期功率预测/mock_data_super_short_term_forecast_report.sql
  18. 144 0
      doc/数据模拟脚本/超短期功率预测/mock_data_ultra_short_term_power_forecasting.sql
  19. 12 0
      doc/数据模拟脚本/超短期功率预测/readme.md

+ 84 - 0
doc/数据模拟脚本/短期功率预测/mock_data_short_term_power_forecast_back.sql

@@ -0,0 +1,84 @@
+-- ============================================================
+-- 脚本功能:基于 report 表数据,生成 back 表的回算数据
+-- ============================================================
+DO $$
+DECLARE
+    -- ========== 配置区域 ==========
+    -- 模拟回算时的最终调整范围 (例如:在上报值基础上再浮动 ±0.1%)
+    -- 回算数据是最终版本,调整范围应非常小
+    v_back_adjustment_factor DECIMAL(5,4) := 0.001;
+
+    -- 统计变量
+    v_total_count INTEGER := 0;
+    v_current_time INTEGER := EXTRACT(EPOCH FROM NOW())::INTEGER;
+
+    -- 用于遍历 report 表数据的记录变量
+    rec_report RECORD;
+BEGIN
+    -- 1. 清理 back 表中的旧数据(可选)
+    -- 保持与之前脚本一致的时间范围
+    DELETE FROM data_short_term_power_forecast_back
+    WHERE start_time >= (EXTRACT(EPOCH FROM (NOW() - INTERVAL '30 days')))::INTEGER
+      AND start_time <= (EXTRACT(EPOCH FROM (NOW() + INTERVAL '10 days')))::INTEGER;
+
+    RAISE NOTICE '开始从 report 表生成 back 表数据...';
+
+    -- 2. 遍历 report 表中的数据
+    FOR rec_report IN
+        SELECT * FROM data_short_term_power_forecast_report
+        WHERE start_time >= (EXTRACT(EPOCH FROM (NOW() - INTERVAL '30 days')))::INTEGER
+          AND start_time <= (EXTRACT(EPOCH FROM (NOW() + INTERVAL '10 days')))::INTEGER
+    LOOP
+        -- 3. 模拟回算时的最终调整
+        DECLARE
+            v_back_power DECIMAL(10,4);
+            v_report_power_val DECIMAL(10,4);
+        BEGIN
+            -- 将 report 表的 power (VARCHAR) 转换为数值
+            v_report_power_val := rec_report.power::DECIMAL(10,4);
+
+            IF v_report_power_val IS NOT NULL THEN
+                -- 生成一个 -v_back_adjustment_factor 到 +v_back_adjustment_factor 之间的随机调整系数
+                v_back_power := v_report_power_val * (1 + (random() * (v_back_adjustment_factor * 2) - v_back_adjustment_factor));
+
+                -- 确保回算功率不为负数
+                IF v_back_power < 0 THEN
+                    v_back_power := 0;
+                END IF;
+            ELSE
+                v_back_power := NULL;
+            END IF;
+
+            -- 4. 插入数据到 back 表
+            INSERT INTO data_short_term_power_forecast_back (
+                data_sourcegrab_id,
+                data_sourcegrab_pattern_name,
+                entity_id,
+                entity_type,
+                entity_name,
+                create_time,
+                start_time,
+                forecast_time,
+                predays,
+                power
+            ) VALUES (
+                rec_report.data_sourcegrab_id,
+                rec_report.data_sourcegrab_pattern_name,
+                rec_report.entity_id,
+                rec_report.entity_type,
+                rec_report.entity_name,
+                v_current_time,       -- 使用当前时间作为创建时间
+                rec_report.start_time,
+                rec_report.forecast_time,
+                rec_report.predays,
+                -- 将调整后的功率数值转回 VARCHAR 存储
+                v_back_power::TEXT
+            );
+
+            v_total_count := v_total_count + 1;
+        END;
+    END LOOP;
+
+    RAISE NOTICE '数据生成完成!成功生成 % 条 back 数据。', v_total_count;
+
+END $$;

+ 85 - 0
doc/数据模拟脚本/短期功率预测/mock_data_short_term_power_forecast_correct.sql

@@ -0,0 +1,85 @@
+-- ============================================================
+-- 脚本功能:基于 issued 表数据,生成 correct 表的修正数据
+-- ============================================================
+DO $$
+DECLARE
+    -- ========== 配置区域 ==========
+    -- 模拟修正的波动范围 (例如:在发布值基础上再浮动 ±1%)
+    -- 修正数据通常比发布数据更精确,所以这个波动范围可以比生成 issued 时更小
+    v_correction_factor DECIMAL(5,4) := 0.01;
+
+    -- 统计变量
+    v_total_count INTEGER := 0;
+    v_current_time INTEGER := EXTRACT(EPOCH FROM NOW())::INTEGER;
+
+    -- 用于遍历 issued 表数据的记录变量
+    rec_issued RECORD;
+BEGIN
+    -- 1. 清理 correct 表中的旧数据(可选)
+    -- 保持与之前脚本一致的时间范围
+    DELETE FROM data_short_term_power_forecast_correct
+    WHERE start_time >= (EXTRACT(EPOCH FROM (NOW() - INTERVAL '30 days')))::INTEGER
+      AND start_time <= (EXTRACT(EPOCH FROM (NOW() + INTERVAL '10 days')))::INTEGER;
+
+    RAISE NOTICE '开始从 issued 表生成 correct 表数据...';
+
+    -- 2. 遍历 issued 表中的数据
+    FOR rec_issued IN
+        SELECT * FROM data_short_term_power_forecast_issued
+        WHERE start_time >= (EXTRACT(EPOCH FROM (NOW() - INTERVAL '30 days')))::INTEGER
+          AND start_time <= (EXTRACT(EPOCH FROM (NOW() + INTERVAL '10 days')))::INTEGER
+    LOOP
+        -- 3. 模拟修正
+        -- 对发布的功率值进行更小幅度的扰动,模拟最终的偏差修正
+        DECLARE
+            v_corrected_power DECIMAL(10,4);
+            v_issued_power_val DECIMAL(10,4);
+        BEGIN
+            -- 将 issued 表的 power (VARCHAR) 转换为数值
+            v_issued_power_val := rec_issued.power::DECIMAL(10,4);
+
+            IF v_issued_power_val IS NOT NULL THEN
+                -- 生成一个 -v_correction_factor 到 +v_correction_factor 之间的随机修正系数
+                v_corrected_power := v_issued_power_val * (1 + (random() * (v_correction_factor * 2) - v_correction_factor));
+
+                -- 确保修正后的功率不为负数
+                IF v_corrected_power < 0 THEN
+                    v_corrected_power := 0;
+                END IF;
+            ELSE
+                v_corrected_power := NULL;
+            END IF;
+
+            -- 4. 插入数据到 correct 表
+            INSERT INTO data_short_term_power_forecast_correct (
+                data_sourcegrab_id,
+                data_sourcegrab_pattern_name,
+                entity_id,
+                entity_type,
+                entity_name,
+                create_time,
+                start_time,
+                forecast_time,
+                predays,
+                power
+            ) VALUES (
+                rec_issued.data_sourcegrab_id,
+                rec_issued.data_sourcegrab_pattern_name,
+                rec_issued.entity_id,
+                rec_issued.entity_type,
+                rec_issued.entity_name,
+                v_current_time,       -- 使用当前时间作为创建时间
+                rec_issued.start_time,
+                rec_issued.forecast_time,
+                rec_issued.predays,
+                -- 将修正后的功率数值转回 VARCHAR 存储
+                v_corrected_power::TEXT
+            );
+
+            v_total_count := v_total_count + 1;
+        END;
+    END LOOP;
+
+    RAISE NOTICE '数据生成完成!成功生成 % 条 correct 数据。', v_total_count;
+
+END $$;

+ 97 - 0
doc/数据模拟脚本/短期功率预测/mock_data_short_term_power_forecast_issued.sql

@@ -0,0 +1,97 @@
+-- ============================================================
+-- 脚本功能:基于 raw 表数据,生成 issued 表的发布数据
+-- ============================================================
+DO $$
+DECLARE
+    -- ========== 配置区域 ==========
+    -- 实体类型映射:根据 raw 表中的 entity_type 字符串,映射到 issued 表的整数类型
+    -- 请根据实际业务定义修改这里的映射关系
+    v_pv_type_id INTEGER := 1;   -- 假设 1 代表光伏电站
+    v_wf_type_id INTEGER := 2;   -- 假设 2 代表风电场
+
+    -- 模拟发布修正的波动范围 (例如:在原始值基础上浮动 ±2%)
+    v_correction_factor DECIMAL(5,4) := 0.02;
+
+    -- 统计变量
+    v_total_count INTEGER := 0;
+    v_current_time INTEGER := EXTRACT(EPOCH FROM NOW())::INTEGER;
+
+    -- 用于遍历 raw 表数据的记录变量
+    rec_raw RECORD;
+BEGIN
+    -- 1. 清理 issued 表中的旧数据(可选,根据需要决定是否保留)
+    -- 这里清理最近30天到未来10天的数据,与 raw 表生成逻辑保持一致
+    DELETE FROM data_short_term_power_forecast_issued
+    WHERE start_time >= (EXTRACT(EPOCH FROM (NOW() - INTERVAL '30 days')))::INTEGER
+      AND start_time <= (EXTRACT(EPOCH FROM (NOW() + INTERVAL '10 days')))::INTEGER;
+
+    RAISE NOTICE '开始从 raw 表生成 issued 表数据...';
+
+    -- 2. 遍历 raw 表中的数据
+    -- 只选择我们关心的时间范围内的数据,提高性能
+    FOR rec_raw IN
+        SELECT * FROM data_short_term_power_forecast_raw
+        WHERE start_time >= (EXTRACT(EPOCH FROM (NOW() - INTERVAL '30 days')))::INTEGER
+          AND start_time <= (EXTRACT(EPOCH FROM (NOW() + INTERVAL '10 days')))::INTEGER
+    LOOP
+        -- 3. 模拟发布修正
+        -- 对原始功率值进行轻微扰动,模拟发布前的最终订正
+        -- 如果原始功率为 NULL,则发布功率也为 NULL
+        DECLARE
+            v_issued_power DECIMAL(10,4);
+            v_raw_power_val DECIMAL(10,4);
+        BEGIN
+            -- 将 raw 表的 power (VARCHAR) 转换为数值
+            v_raw_power_val := rec_raw.power::DECIMAL(10,4);
+
+            IF v_raw_power_val IS NOT NULL THEN
+                -- 生成一个 -v_correction_factor 到 +v_correction_factor 之间的随机修正系数
+                -- 例如:1 + (random() * 0.04 - 0.02) 会生成 0.98 到 1.02 之间的数
+                v_issued_power := v_raw_power_val * (1 + (random() * (v_correction_factor * 2) - v_correction_factor));
+
+                -- 确保修正后的功率不为负数
+                IF v_issued_power < 0 THEN
+                    v_issued_power := 0;
+                END IF;
+            ELSE
+                v_issued_power := NULL;
+            END IF;
+
+            -- 4. 插入数据到 issued 表
+            INSERT INTO data_short_term_power_forecast_issued (
+                data_sourcegrab_id,
+                data_sourcegrab_pattern_name,
+                entity_id,
+                entity_type,          -- 注意:这里是 INTEGER 类型
+                entity_name,
+                create_time,
+                start_time,
+                forecast_time,
+                predays,
+                power                 -- 注意:这里仍然是 VARCHAR 类型
+            ) VALUES (
+                rec_raw.data_sourcegrab_id,
+                rec_raw.data_sourcegrab_pattern_name,
+                rec_raw.entity_id,
+                -- 将 entity_type 字符串映射为整数
+                CASE rec_raw.entity_type
+                    WHEN 'pv_station' THEN v_pv_type_id
+                    WHEN 'wind_farm' THEN v_wf_type_id
+                    ELSE 0 -- 未知类型
+                END,
+                rec_raw.station_name, -- 使用 station_name 作为 entity_name
+                v_current_time,       -- 使用当前时间作为创建时间
+                rec_raw.start_time,
+                rec_raw.forecast_time,
+                rec_raw.pre_days,
+                -- 将修正后的功率数值转回 VARCHAR 存储
+                v_issued_power::TEXT
+            );
+
+            v_total_count := v_total_count + 1;
+        END;
+    END LOOP;
+
+    RAISE NOTICE '数据生成完成!成功生成 % 条 issued 数据。', v_total_count;
+
+END $$;

+ 160 - 0
doc/数据模拟脚本/短期功率预测/mock_data_short_term_power_forecast_raw.sql

@@ -0,0 +1,160 @@
+-- 1. 清理数据 (删除指定时间范围内的旧数据,避免重复)
+DELETE FROM data_short_term_power_forecast_raw 
+WHERE start_time >= (EXTRACT(EPOCH FROM (NOW() - INTERVAL '30 days')))::INTEGER
+  AND start_time <= (EXTRACT(EPOCH FROM (NOW() + INTERVAL '10 days')))::INTEGER;
+
+-- ============================================================
+-- 配置区域:修改这里的变量即可控制生成的数据
+-- ============================================================
+DO $$
+DECLARE
+    -- ========== 核心配置(用户可修改) ==========
+    v_entity_id TEXT := '2';           -- 实体ID
+    v_entity_type TEXT := 'pv_station';       -- 实体类型:'wind_farm' 或 'pv_station'
+    v_station_id BIGINT := 2;             -- 场站ID
+    v_station_name TEXT := '渤海一号风电场';   -- 场站名称
+    v_data_source INTEGER := 1;              -- 数据源:1-GFS, 2-ECMWF, 3-CMA
+    v_lat TEXT := '39.904200';               -- 纬度
+    v_lon TEXT := '116.407400';              -- 经度
+    v_installed_capacity DECIMAL(10,4) := 100.0000;  -- 装机容量(MW)
+    
+    -- ========== 时间配置 ==========
+    v_days_back INTEGER := 30;               -- 从多少天前开始生成
+    v_days_forward INTEGER := 10;            -- 生成到未来多少天
+    v_issue_hours INTEGER[] := ARRAY[0, 6, 12, 18]; -- UTC起报时次
+    v_forecast_points INTEGER := 960;        -- 10天 × 24小时 × 4个/小时 = 960个预报点
+    v_fifteen_min_sec INTEGER := 900;        -- 15分钟 = 900秒
+    
+    -- ========== 循环变量 ==========
+    i INTEGER;
+    j INTEGER;
+    v_selected_hour INTEGER;
+    v_base_date TIMESTAMP;
+    v_start_time INTEGER;
+    v_forecast_time INTEGER;
+    v_now_epoch INTEGER := EXTRACT(EPOCH FROM NOW())::INTEGER;
+    v_total_count INTEGER := 0;
+    
+    -- ========== 功率计算相关变量 ==========
+    v_power_val TEXT;
+    v_base_power DECIMAL(10,4);
+    v_error DECIMAL(10,4);
+    v_prev_power DECIMAL(10,4);
+    v_hour_of_day DECIMAL(10,4);
+    v_wind_speed DECIMAL(10,4);
+    v_pi CONSTANT DECIMAL(10,8) := 3.14159265;
+    
+    -- ========== 风电功率曲线参数 ==========
+    v_cut_in_speed DECIMAL(10,2) := 3.0;
+    v_rated_speed DECIMAL(10,2) := 12.0;
+    v_cut_out_speed DECIMAL(10,2) := 25.0;
+BEGIN
+    -- 外层循环:遍历从 v_days_back 天前 到 v_days_forward 天后的每一天
+    FOR i IN -v_days_back..v_days_forward LOOP
+        v_base_date := (NOW()::DATE + (i || ' days')::INTERVAL);
+        
+        -- 中层循环:遍历当天的4个起报时次
+        FOREACH v_selected_hour IN ARRAY v_issue_hours LOOP
+            v_start_time := EXTRACT(EPOCH FROM (v_base_date + (v_selected_hour || ' hours')::INTERVAL))::INTEGER;
+            v_prev_power := 0;
+            
+            -- 内层循环:遍历960个预报点
+            FOR j IN 0..(v_forecast_points - 1) LOOP
+                v_forecast_time := v_start_time + (j * v_fifteen_min_sec);
+                v_hour_of_day := ((v_forecast_time % 86400) / 3600.0);
+                
+                -- 根据实体类型计算基准功率
+                IF v_entity_type = 'pv_station' THEN
+                    IF v_hour_of_day < 6 OR v_hour_of_day > 18 THEN
+                        v_base_power := 0;
+                    ELSE
+                        v_base_power := v_installed_capacity * 
+                            sin((v_hour_of_day - 6) / 12.0 * v_pi) * 
+                            (0.7 + random() * 0.3);
+                    END IF;
+                ELSIF v_entity_type = 'wind_farm' THEN
+                    v_wind_speed := 7.0 
+                        + 2.0 * sin(v_hour_of_day / 24.0 * 2 * v_pi)
+                        + (random() * 2 - 1);
+                    IF v_wind_speed < v_cut_in_speed OR v_wind_speed > v_cut_out_speed THEN
+                        v_base_power := 0;
+                    ELSIF v_wind_speed >= v_rated_speed THEN
+                        v_base_power := v_installed_capacity;
+                    ELSE
+                        v_base_power := v_installed_capacity * 
+                            ((v_wind_speed^3 - v_cut_in_speed^3) / 
+                             (v_rated_speed^3 - v_cut_in_speed^3));
+                    END IF;
+                END IF;
+                
+                -- 叠加预测误差
+                v_error := sqrt(-2 * ln(random())) * cos(2 * v_pi * random()) * (v_installed_capacity * 0.05);
+                v_base_power := v_base_power + v_error;
+                IF v_base_power < 0 THEN v_base_power := 0;
+                ELSIF v_base_power > v_installed_capacity THEN v_base_power := v_installed_capacity;
+                END IF;
+                
+                -- 时序平滑
+                IF j > 0 AND abs(v_base_power - v_prev_power) > (v_installed_capacity * 0.1) THEN
+                    IF v_base_power > v_prev_power THEN
+                        v_base_power := v_prev_power + (v_installed_capacity * 0.1);
+                    ELSE
+                        v_base_power := v_prev_power - (v_installed_capacity * 0.1);
+                    END IF;
+                END IF;
+                
+                v_prev_power := v_base_power;
+                v_power_val := v_base_power::DECIMAL(10,4)::TEXT;
+                
+                INSERT INTO data_short_term_power_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, 
+                    power
+                ) VALUES (
+                    v_lat, v_lon,
+                    'SinglePointTimeSeries',
+                    10,
+                    0,
+                    v_data_source,
+                    floor(random() * 1000)::INTEGER,
+                    'Pattern_Daily_Grab',
+                    101,
+                    'ShortTermModel_v1',
+                    v_data_source,
+                    CASE v_data_source WHEN 1 THEN 'GFS' WHEN 2 THEN 'ECMWF' ELSE 'CMA' END,
+                    v_entity_id,
+                    v_entity_type,
+                    v_now_epoch,
+                    v_start_time,
+                    v_forecast_time,
+                    10,
+                    j * 15,
+                    v_station_id,
+                    v_station_name,
+                    5001,
+                    'PowerTradingCo',
+                    'M_' || floor(random() * 10 + 1)::TEXT,
+                    'Turbine_A',
+                    NULL,
+                    NULL,
+                    v_power_val
+                );
+                
+                v_total_count := v_total_count + 1;
+            END LOOP;
+        END LOOP;
+    END LOOP;
+
+    RAISE NOTICE '成功生成 % 条数据!(实体: %, 类型: %, 装机: % MW, 从 % 天前 到 % 天后)', 
+                 v_total_count, v_entity_id, v_entity_type, v_installed_capacity, v_days_back, v_days_forward;
+END $$;

+ 84 - 0
doc/数据模拟脚本/短期功率预测/mock_data_short_term_power_forecast_report.sql

@@ -0,0 +1,84 @@
+-- ============================================================
+-- 脚本功能:基于 correct 表数据,生成 report 表的上报数据
+-- ============================================================
+DO $$
+DECLARE
+    -- ========== 配置区域 ==========
+    -- 模拟上报时的最终微调范围 (例如:在修正值基础上再浮动 ±0.5%)
+    -- 上报数据通常是最终版本,所以这个波动范围可以设置得非常小
+    v_report_adjustment_factor DECIMAL(5,4) := 0.005;
+
+    -- 统计变量
+    v_total_count INTEGER := 0;
+    v_current_time INTEGER := EXTRACT(EPOCH FROM NOW())::INTEGER;
+
+    -- 用于遍历 correct 表数据的记录变量
+    rec_correct RECORD;
+BEGIN
+    -- 1. 清理 report 表中的旧数据(可选)
+    -- 保持与之前脚本一致的时间范围
+    DELETE FROM data_short_term_power_forecast_report
+    WHERE start_time >= (EXTRACT(EPOCH FROM (NOW() - INTERVAL '30 days')))::INTEGER
+      AND start_time <= (EXTRACT(EPOCH FROM (NOW() + INTERVAL '10 days')))::INTEGER;
+
+    RAISE NOTICE '开始从 correct 表生成 report 表数据...';
+
+    -- 2. 遍历 correct 表中的数据
+    FOR rec_correct IN
+        SELECT * FROM data_short_term_power_forecast_correct
+        WHERE start_time >= (EXTRACT(EPOCH FROM (NOW() - INTERVAL '30 days')))::INTEGER
+          AND start_time <= (EXTRACT(EPOCH FROM (NOW() + INTERVAL '10 days')))::INTEGER
+    LOOP
+        -- 3. 模拟上报前的最终微调
+        DECLARE
+            v_reported_power DECIMAL(10,4);
+            v_correct_power_val DECIMAL(10,4);
+        BEGIN
+            -- 将 correct 表的 power (VARCHAR) 转换为数值
+            v_correct_power_val := rec_correct.power::DECIMAL(10,4);
+
+            IF v_correct_power_val IS NOT NULL THEN
+                -- 生成一个 -v_report_adjustment_factor 到 +v_report_adjustment_factor 之间的随机调整系数
+                v_reported_power := v_correct_power_val * (1 + (random() * (v_report_adjustment_factor * 2) - v_report_adjustment_factor));
+
+                -- 确保上报功率不为负数
+                IF v_reported_power < 0 THEN
+                    v_reported_power := 0;
+                END IF;
+            ELSE
+                v_reported_power := NULL;
+            END IF;
+
+            -- 4. 插入数据到 report 表
+            INSERT INTO data_short_term_power_forecast_report (
+                data_sourcegrab_id,
+                data_sourcegrab_pattern_name,
+                entity_id,
+                entity_type,
+                entity_name,
+                create_time,
+                start_time,
+                forecast_time,
+                predays,
+                power
+            ) VALUES (
+                rec_correct.data_sourcegrab_id,
+                rec_correct.data_sourcegrab_pattern_name,
+                rec_correct.entity_id,
+                rec_correct.entity_type,
+                rec_correct.entity_name,
+                v_current_time,       -- 使用当前时间作为创建时间
+                rec_correct.start_time,
+                rec_correct.forecast_time,
+                rec_correct.predays,
+                -- 将调整后的功率数值转回 VARCHAR 存储
+                v_reported_power::TEXT
+            );
+
+            v_total_count := v_total_count + 1;
+        END;
+    END LOOP;
+
+    RAISE NOTICE '数据生成完成!成功生成 % 条 report 数据。', v_total_count;
+
+END $$;

+ 11 - 0
doc/数据模拟脚本/短期功率预测/readme.md

@@ -0,0 +1,11 @@
+可调整配置参数
+`mock_data_short_term_power_forecast_raw.sql`
+- `v_station_id`
+- `v_station_name`
+
+依次执行生成(-30,10)数据
+`mock_data_short_term_power_forecast_raw.sql`
+`mock_data_short_term_power_forecast_issued.sql`
+`mock_data_short_term_power_forecast_correct.sql`
+`mock_data_short_term_power_forecast_report.sql`
+`mock_data_short_term_power_forecast_back.sql`

+ 104 - 0
doc/数据模拟脚本/短期气象预测/mock_data_short_term_weather_forecast_back.sql

@@ -0,0 +1,104 @@
+-- ============================================================
+-- 脚本功能:基于 report 表生成 back 表数据 (data_short_term_weather_forecast_back)
+-- 逻辑:筛选特定场站和时间范围的数据,并进行微调后插入
+-- ============================================================
+DO $$
+DECLARE
+    -- ================= 配置区域 =================
+    v_station_id       BIGINT := 2;                -- 场站ID
+    v_station_name     VARCHAR := '渤海一号风电场'; -- 场站名称
+    
+    -- 【可配置】时间范围:过去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;
+
+    -- 循环变量
+    rec_report         data_short_term_weather_forecast_report%ROWTYPE;
+    v_create_time_ts   INTEGER := EXTRACT(EPOCH FROM NOW())::INTEGER;
+
+    -- 微调后的数值变量
+    v_tirr_val         DECIMAL;
+    v_ws_hub_val       DECIMAL;
+    v_tsfc_val         DECIMAL;
+BEGIN
+    RAISE NOTICE '开始生成历史备份数据。场站: %, 时间范围: % 至 %', v_station_name, v_date_range_start, v_date_range_end;
+
+    -- 1. 清理旧数据 (可选,根据需求决定)
+    DELETE FROM data_short_term_weather_forecast_back 
+    WHERE entity_id = v_station_id::VARCHAR
+      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 rec_report IN 
+        SELECT * FROM data_short_term_weather_forecast_report
+        WHERE entity_id = v_station_id::VARCHAR
+          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
+        ORDER BY start_time, forecast_time
+    LOOP
+        -- --- 数据微调逻辑 ---
+        
+        -- 1. 总辐照度微调 (在 report 值基础上浮动 +/- 1%)
+        IF rec_report.tirr IS NOT NULL THEN
+            v_tirr_val := rec_report.tirr::DECIMAL * (0.99 + RANDOM() * 0.02);
+            v_tirr_val := GREATEST(0, v_tirr_val);
+        ELSE
+            v_tirr_val := NULL;
+        END IF;
+
+        -- 2. 轮毂高度风速微调 (在 report 值基础上浮动 +/- 0.1 m/s)
+        IF rec_report.ws_hub IS NOT NULL THEN
+            v_ws_hub_val := rec_report.ws_hub::DECIMAL + (RANDOM() * 0.2 - 0.1);
+            v_ws_hub_val := GREATEST(0, v_ws_hub_val);
+        ELSE
+            v_ws_hub_val := NULL;
+        END IF;
+
+        -- 3. 地表气温微调 (在 report 值基础上浮动 +/- 0.1 ℃)
+        IF rec_report.tsfc IS NOT NULL THEN
+            v_tsfc_val := rec_report.tsfc::DECIMAL + (RANDOM() * 0.2 - 0.1);
+        ELSE
+            v_tsfc_val := NULL;
+        END IF;
+
+        -- 3. 插入数据到 back 表
+        INSERT INTO data_short_term_weather_forecast_back (
+            data_sourcegrab_id, data_sourcegrab_pattern_name,
+            entity_id, entity_type, entity_name,
+            create_time, start_time, forecast_time, predays,
+            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 (
+            -- 字段映射
+            rec_report.data_sourcegrab_id, rec_report.data_sourcegrab_pattern_name,
+            rec_report.entity_id, rec_report.entity_type, v_station_name,
+            v_create_time_ts, rec_report.start_time, rec_report.forecast_time, rec_report.predays,
+            -- 云量、气压、湿度 (直接复制)
+            rec_report.tcc, rec_report.hcc, rec_report.lcc, rec_report.mcc,
+            ROUND(v_tsfc_val, 1)::VARCHAR, rec_report.psfc, rec_report.rhsfc,
+            -- 辐照度 (diff/direct 根据 tirr 比例估算,tirr 使用微调后的值)
+            CASE WHEN rec_report.tirr::DECIMAL > 0 THEN (rec_report.diffirr::DECIMAL / rec_report.tirr::DECIMAL) * v_tirr_val ELSE 0 END::VARCHAR,
+            CASE WHEN rec_report.tirr::DECIMAL > 0 THEN (rec_report.directirr::DECIMAL / rec_report.tirr::DECIMAL) * v_tirr_val ELSE 0 END::VARCHAR,
+            ROUND(v_tirr_val)::VARCHAR,
+            -- 风 (wd 直接复制,ws_hub 使用微调后的值,ws 复制)
+            rec_report.wd_hub, ROUND(v_ws_hub_val, 1)::VARCHAR, rec_report.ws,
+            -- 各层风向 (直接复制)
+            rec_report.wd10, rec_report.wd30, rec_report.wd50, rec_report.wd70, rec_report.wd80, rec_report.wd90, 
+            rec_report.wd100, rec_report.wd120, rec_report.wd140, rec_report.wd160, rec_report.wd180, rec_report.wd200,
+            -- 各层风速 (直接复制)
+            rec_report.ws10, rec_report.ws30, rec_report.ws50, rec_report.ws70, rec_report.ws80, rec_report.ws90, 
+            rec_report.ws100, rec_report.ws120, rec_report.ws140, rec_report.ws160, rec_report.ws180, rec_report.ws200
+        );
+    END LOOP;
+
+    RAISE NOTICE '历史备份数据生成完成!';
+
+END $$;

+ 104 - 0
doc/数据模拟脚本/短期气象预测/mock_data_short_term_weather_forecast_correct.sql

@@ -0,0 +1,104 @@
+-- ============================================================
+-- 脚本功能:基于 issued 表生成 correct 表数据 (data_short_term_weather_forecast_correct)
+-- 逻辑:筛选特定场站和时间范围的数据,并进行微调后插入
+-- ============================================================
+DO $$
+DECLARE
+    -- ================= 配置区域 =================
+    v_station_id       BIGINT := 2;                -- 场站ID
+    v_station_name     VARCHAR := '渤海一号风电场'; -- 场站名称
+    
+    -- 【可配置】时间范围:过去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;
+
+    -- 循环变量
+    rec_issued         data_short_term_weather_forecast_issued%ROWTYPE;
+    v_create_time_ts   INTEGER := EXTRACT(EPOCH FROM NOW())::INTEGER;
+
+    -- 微调后的数值变量
+    v_tirr_val         DECIMAL;
+    v_ws_hub_val       DECIMAL;
+    v_tsfc_val         DECIMAL;
+BEGIN
+    RAISE NOTICE '开始生成修正预报数据。场站: %, 时间范围: % 至 %', v_station_name, v_date_range_start, v_date_range_end;
+
+    -- 1. 清理旧数据 (可选,根据需求决定)
+    DELETE FROM data_short_term_weather_forecast_correct 
+    WHERE entity_id = v_station_id::VARCHAR
+      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 rec_issued IN 
+        SELECT * FROM data_short_term_weather_forecast_issued
+        WHERE entity_id = v_station_id::VARCHAR
+          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
+        ORDER BY start_time, forecast_time
+    LOOP
+        -- --- 数据微调逻辑 ---
+        
+        -- 1. 总辐照度微调 (在 issued 值基础上浮动 +/- 3%)
+        IF rec_issued.tirr IS NOT NULL THEN
+            v_tirr_val := rec_issued.tirr::DECIMAL * (0.97 + RANDOM() * 0.06);
+            v_tirr_val := GREATEST(0, v_tirr_val);
+        ELSE
+            v_tirr_val := NULL;
+        END IF;
+
+        -- 2. 轮毂高度风速微调 (在 issued 值基础上浮动 +/- 0.3 m/s)
+        IF rec_issued.ws_hub IS NOT NULL THEN
+            v_ws_hub_val := rec_issued.ws_hub::DECIMAL + (RANDOM() * 0.6 - 0.3);
+            v_ws_hub_val := GREATEST(0, v_ws_hub_val);
+        ELSE
+            v_ws_hub_val := NULL;
+        END IF;
+
+        -- 3. 地表气温微调 (在 issued 值基础上浮动 +/- 0.5 ℃)
+        IF rec_issued.tsfc IS NOT NULL THEN
+            v_tsfc_val := rec_issued.tsfc::DECIMAL + (RANDOM() * 1.0 - 0.5);
+        ELSE
+            v_tsfc_val := NULL;
+        END IF;
+
+        -- 3. 插入数据到 correct 表
+        INSERT INTO data_short_term_weather_forecast_correct (
+            data_sourcegrab_id, data_sourcegrab_pattern_name,
+            entity_id, entity_type, entity_name,
+            create_time, start_time, forecast_time, predays,
+            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 (
+            -- 字段映射
+            rec_issued.data_sourcegrab_id, rec_issued.data_sourcegrab_pattern_name,
+            rec_issued.entity_id, rec_issued.entity_type, v_station_name,
+            v_create_time_ts, rec_issued.start_time, rec_issued.forecast_time, rec_issued.predays,
+            -- 云量、气压、湿度 (直接复制)
+            rec_issued.tcc, rec_issued.hcc, rec_issued.lcc, rec_issued.mcc,
+            ROUND(v_tsfc_val, 1)::VARCHAR, rec_issued.psfc, rec_issued.rhsfc,
+            -- 辐照度 (diff/direct 根据 tirr 比例估算,tirr 使用微调后的值)
+            CASE WHEN rec_issued.tirr::DECIMAL > 0 THEN (rec_issued.diffirr::DECIMAL / rec_issued.tirr::DECIMAL) * v_tirr_val ELSE 0 END::VARCHAR,
+            CASE WHEN rec_issued.tirr::DECIMAL > 0 THEN (rec_issued.directirr::DECIMAL / rec_issued.tirr::DECIMAL) * v_tirr_val ELSE 0 END::VARCHAR,
+            ROUND(v_tirr_val)::VARCHAR,
+            -- 风 (wd 直接复制,ws_hub 使用微调后的值,ws 复制)
+            rec_issued.wd_hub, ROUND(v_ws_hub_val, 1)::VARCHAR, rec_issued.ws,
+            -- 各层风向 (直接复制)
+            rec_issued.wd10, rec_issued.wd30, rec_issued.wd50, rec_issued.wd70, rec_issued.wd80, rec_issued.wd90, 
+            rec_issued.wd100, rec_issued.wd120, rec_issued.wd140, rec_issued.wd160, rec_issued.wd180, rec_issued.wd200,
+            -- 各层风速 (直接复制)
+            rec_issued.ws10, rec_issued.ws30, rec_issued.ws50, rec_issued.ws70, rec_issued.ws80, rec_issued.ws90, 
+            rec_issued.ws100, rec_issued.ws120, rec_issued.ws140, rec_issued.ws160, rec_issued.ws180, rec_issued.ws200
+        );
+    END LOOP;
+
+    RAISE NOTICE '修正预报数据生成完成!';
+
+END $$;

+ 96 - 0
doc/数据模拟脚本/短期气象预测/mock_data_short_term_weather_forecast_issued.sql

@@ -0,0 +1,96 @@
+-- ============================================================
+-- 脚本功能:基于 raw 表生成 issued 表数据 (data_short_term_weather_forecast_issued)
+-- 逻辑:筛选特定场站和时间范围的数据,并进行微调后插入
+-- ============================================================
+DO $$
+DECLARE
+    -- ================= 配置区域 =================
+    v_station_id       BIGINT := 2;                -- 场站ID
+    v_station_name     VARCHAR := '渤海一号风电场'; -- 场站名称
+    
+    -- 【可配置】时间范围:过去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;
+
+    -- 循环变量
+    rec_raw            data_short_term_weather_forecast_raw%ROWTYPE;
+    v_create_time_ts   INTEGER := EXTRACT(EPOCH FROM NOW())::INTEGER;
+
+    -- 微调后的数值变量
+    v_tirr_val         DECIMAL;
+    v_ws_hub_val       DECIMAL;
+BEGIN
+    RAISE NOTICE '开始生成发布预报数据。场站: %, 时间范围: % 至 %', v_station_name, v_date_range_start, v_date_range_end;
+
+    -- 1. 清理旧数据 (可选,根据需求决定)
+    DELETE FROM data_short_term_weather_forecast_issued 
+    WHERE entity_id = v_station_id::VARCHAR
+      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 rec_raw IN 
+        SELECT * 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
+        ORDER BY start_time, forecast_time
+    LOOP
+        -- --- 数据微调逻辑 ---
+        
+        -- 1. 总辐照度微调 (在原始值基础上浮动 +/- 5%)
+        IF rec_raw.tirr IS NOT NULL THEN
+            v_tirr_val := rec_raw.tirr::DECIMAL * (0.95 + RANDOM() * 0.1);
+            v_tirr_val := GREATEST(0, v_tirr_val);
+        ELSE
+            v_tirr_val := NULL;
+        END IF;
+
+        -- 2. 轮毂高度风速微调 (在原始值基础上浮动 +/- 0.5 m/s)
+        IF rec_raw.ws_hub IS NOT NULL THEN
+            v_ws_hub_val := rec_raw.ws_hub::DECIMAL + (RANDOM() * 1.0 - 0.5);
+            v_ws_hub_val := GREATEST(0, v_ws_hub_val);
+        ELSE
+            v_ws_hub_val := NULL;
+        END IF;
+
+        -- 3. 插入数据到 issued 表
+        INSERT INTO data_short_term_weather_forecast_issued (
+            data_sourcegrab_id, data_sourcegrab_pattern_name,
+            entity_id, entity_type, entity_name,
+            create_time, start_time, forecast_time, predays,
+            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 (
+            -- 字段映射
+            rec_raw.data_sourcegrab_id, rec_raw.data_sourcegrab_pattern_name,
+            rec_raw.entity_id, 1, v_station_name, -- entity_type 固定为 1 (场站)
+            v_create_time_ts, rec_raw.start_time, rec_raw.forecast_time, rec_raw.pre_days,
+            -- 云量、温压湿 (直接复制)
+            rec_raw.tcc, rec_raw.hcc, rec_raw.lcc, rec_raw.mcc,
+            rec_raw.tsfc, rec_raw.psfc, rec_raw.rhsfc,
+            -- 辐照度 (diff/direct 根据 tirr 比例估算,tirr 使用微调后的值)
+            CASE WHEN rec_raw.tirr::DECIMAL > 0 THEN (rec_raw.diffirr::DECIMAL / rec_raw.tirr::DECIMAL) * v_tirr_val ELSE 0 END::VARCHAR,
+            CASE WHEN rec_raw.tirr::DECIMAL > 0 THEN (rec_raw.directirr::DECIMAL / rec_raw.tirr::DECIMAL) * v_tirr_val ELSE 0 END::VARCHAR,
+            ROUND(v_tirr_val)::VARCHAR,
+            -- 风 (wd 直接复制,ws_hub 使用微调后的值,ws 复制)
+            rec_raw.wd_hub, ROUND(v_ws_hub_val)::VARCHAR, rec_raw.ws,
+            -- 各层风向 (直接复制)
+            rec_raw.wd10, rec_raw.wd30, rec_raw.wd50, rec_raw.wd70, rec_raw.wd80, rec_raw.wd90, 
+            rec_raw.wd100, rec_raw.wd120, rec_raw.wd140, rec_raw.wd160, rec_raw.wd180, rec_raw.wd200,
+            -- 各层风速 (直接复制)
+            rec_raw.ws10, rec_raw.ws30, rec_raw.ws50, rec_raw.ws70, rec_raw.ws80, rec_raw.ws90, 
+            rec_raw.ws100, rec_raw.ws120, rec_raw.ws140, rec_raw.ws160, rec_raw.ws180, rec_raw.ws200
+        );
+    END LOOP;
+
+    RAISE NOTICE '发布预报数据生成完成!';
+
+END $$;

+ 157 - 0
doc/数据模拟脚本/短期气象预测/mock_data_short_term_weather_forecast_raw.sql

@@ -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 $$;

+ 104 - 0
doc/数据模拟脚本/短期气象预测/mock_data_short_term_weather_forecast_report.sql

@@ -0,0 +1,104 @@
+-- ============================================================
+-- 脚本功能:基于 correct 表生成 report 表数据 (data_short_term_weather_forecast_report)
+-- 逻辑:筛选特定场站和时间范围的数据,并进行微调后插入
+-- ============================================================
+DO $$
+DECLARE
+    -- ================= 配置区域 =================
+    v_station_id       BIGINT := 2;                -- 场站ID
+    v_station_name     VARCHAR := '渤海一号风电场'; -- 场站名称
+    
+    -- 【可配置】时间范围:过去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;
+
+    -- 循环变量
+    rec_correct        data_short_term_weather_forecast_correct%ROWTYPE;
+    v_create_time_ts   INTEGER := EXTRACT(EPOCH FROM NOW())::INTEGER;
+
+    -- 微调后的数值变量
+    v_tirr_val         DECIMAL;
+    v_ws_hub_val       DECIMAL;
+    v_tsfc_val         DECIMAL;
+BEGIN
+    RAISE NOTICE '开始生成最终预报报告数据。场站: %, 时间范围: % 至 %', v_station_name, v_date_range_start, v_date_range_end;
+
+    -- 1. 清理旧数据 (可选,根据需求决定)
+    DELETE FROM data_short_term_weather_forecast_report 
+    WHERE entity_id = v_station_id::VARCHAR
+      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 rec_correct IN 
+        SELECT * FROM data_short_term_weather_forecast_correct
+        WHERE entity_id = v_station_id::VARCHAR
+          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
+        ORDER BY start_time, forecast_time
+    LOOP
+        -- --- 数据微调逻辑 ---
+        
+        -- 1. 总辐照度微调 (在 correct 值基础上浮动 +/- 2%)
+        IF rec_correct.tirr IS NOT NULL THEN
+            v_tirr_val := rec_correct.tirr::DECIMAL * (0.98 + RANDOM() * 0.04);
+            v_tirr_val := GREATEST(0, v_tirr_val);
+        ELSE
+            v_tirr_val := NULL;
+        END IF;
+
+        -- 2. 轮毂高度风速微调 (在 correct 值基础上浮动 +/- 0.2 m/s)
+        IF rec_correct.ws_hub IS NOT NULL THEN
+            v_ws_hub_val := rec_correct.ws_hub::DECIMAL + (RANDOM() * 0.4 - 0.2);
+            v_ws_hub_val := GREATEST(0, v_ws_hub_val);
+        ELSE
+            v_ws_hub_val := NULL;
+        END IF;
+
+        -- 3. 地表气温微调 (在 correct 值基础上浮动 +/- 0.2 ℃)
+        IF rec_correct.tsfc IS NOT NULL THEN
+            v_tsfc_val := rec_correct.tsfc::DECIMAL + (RANDOM() * 0.4 - 0.2);
+        ELSE
+            v_tsfc_val := NULL;
+        END IF;
+
+        -- 3. 插入数据到 report 表
+        INSERT INTO data_short_term_weather_forecast_report (
+            data_sourcegrab_id, data_sourcegrab_pattern_name,
+            entity_id, entity_type, entity_name,
+            create_time, start_time, forecast_time, predays,
+            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 (
+            -- 字段映射
+            rec_correct.data_sourcegrab_id, rec_correct.data_sourcegrab_pattern_name,
+            rec_correct.entity_id, rec_correct.entity_type, v_station_name,
+            v_create_time_ts, rec_correct.start_time, rec_correct.forecast_time, rec_correct.predays,
+            -- 云量、气压、湿度 (直接复制)
+            rec_correct.tcc, rec_correct.hcc, rec_correct.lcc, rec_correct.mcc,
+            ROUND(v_tsfc_val, 1)::VARCHAR, rec_correct.psfc, rec_correct.rhsfc,
+            -- 辐照度 (diff/direct 根据 tirr 比例估算,tirr 使用微调后的值)
+            CASE WHEN rec_correct.tirr::DECIMAL > 0 THEN (rec_correct.diffirr::DECIMAL / rec_correct.tirr::DECIMAL) * v_tirr_val ELSE 0 END::VARCHAR,
+            CASE WHEN rec_correct.tirr::DECIMAL > 0 THEN (rec_correct.directirr::DECIMAL / rec_correct.tirr::DECIMAL) * v_tirr_val ELSE 0 END::VARCHAR,
+            ROUND(v_tirr_val)::VARCHAR,
+            -- 风 (wd 直接复制,ws_hub 使用微调后的值,ws 复制)
+            rec_correct.wd_hub, ROUND(v_ws_hub_val, 1)::VARCHAR, rec_correct.ws,
+            -- 各层风向 (直接复制)
+            rec_correct.wd10, rec_correct.wd30, rec_correct.wd50, rec_correct.wd70, rec_correct.wd80, rec_correct.wd90, 
+            rec_correct.wd100, rec_correct.wd120, rec_correct.wd140, rec_correct.wd160, rec_correct.wd180, rec_correct.wd200,
+            -- 各层风速 (直接复制)
+            rec_correct.ws10, rec_correct.ws30, rec_correct.ws50, rec_correct.ws70, rec_correct.ws80, rec_correct.ws90, 
+            rec_correct.ws100, rec_correct.ws120, rec_correct.ws140, rec_correct.ws160, rec_correct.ws180, rec_correct.ws200
+        );
+    END LOOP;
+
+    RAISE NOTICE '最终预报报告数据生成完成!';
+
+END $$;

+ 11 - 0
doc/数据模拟脚本/短期气象预测/readme.md

@@ -0,0 +1,11 @@
+可调整配置参数
+`mock_data_short_term_weather_forecast_raw`
+- `v_station_id`
+- `v_station_name`
+
+依次执行生成(-30,10)数据
+`mock_data_short_term_weather_forecast_raw.sql`
+`mock_data_short_term_weather_forecast_issued.sql`
+`mock_data_short_term_weather_forecast_correct.sql`
+`mock_data_short_term_weather_forecast_report.sql`
+`mock_data_short_term_weather_forecast_back.sql`

+ 65 - 0
doc/数据模拟脚本/超短期功率预测/mock_data_super_short_term_forecast_back.sql

@@ -0,0 +1,65 @@
+-- ============================================================
+-- 脚本功能:基于 report 表生成 back 表数据 (data_super_short_term_forecast_back)
+-- 逻辑:筛选特定场站和时间范围的数据,并对功率进行微调后插入
+-- ============================================================
+DO $$
+DECLARE
+    -- ================= 配置区域 =================
+    v_past_days        INTEGER := 30;              -- 从过去多少天开始
+    v_future_days      INTEGER := 10;              -- 到未来多少天结束
+    
+    -- 模拟数据配置
+    v_station_id       BIGINT := 2;                -- 场站ID
+    v_station_name     VARCHAR := '渤海一号风电场'; -- 场站名称
+    v_entity_id        VARCHAR := '2';             -- 实体ID
+    v_entity_type      INTEGER := 1;               -- 实体类型 (示例: 1代表场站)
+
+    -- 循环变量
+    rec_report         data_super_short_term_forecast_report%ROWTYPE;
+    v_create_time_ts   INTEGER := EXTRACT(EPOCH FROM NOW())::INTEGER;
+    v_power_val        DECIMAL;                    -- 微调后的功率值
+BEGIN
+    RAISE NOTICE '开始生成超短期功率预测回溯数据。场站: %, 时间范围: % 至 %', v_station_name, CURRENT_DATE - INTERVAL '1 day' * v_past_days, CURRENT_DATE + INTERVAL '1 day' * v_future_days;
+
+    -- 1. 清理旧数据 (可选,根据需求决定)
+    DELETE FROM data_super_short_term_forecast_back 
+    WHERE entity_id = v_entity_id
+      AND start_time >= (EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '1 day' * v_past_days)))::INTEGER
+      AND start_time <= (EXTRACT(EPOCH FROM (CURRENT_DATE + INTERVAL '1 day' * v_future_days + INTERVAL '10 days')))::INTEGER;
+
+    -- 2. 遍历源表数据
+    FOR rec_report IN 
+        SELECT * FROM data_super_short_term_forecast_report
+        WHERE entity_id = v_entity_id
+          AND start_time >= (EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '1 day' * v_past_days)))::INTEGER
+          AND start_time <= (EXTRACT(EPOCH FROM (CURRENT_DATE + INTERVAL '1 day' * v_future_days + INTERVAL '10 days')))::INTEGER
+        ORDER BY start_time, forecast_time
+    LOOP
+        -- --- 数据微调逻辑 ---
+        -- 对预测功率进行小幅度随机扰动 (例如:浮动 +/- 1%)
+        IF rec_report.power IS NOT NULL THEN
+            v_power_val := rec_report.power::DECIMAL * (0.99 + RANDOM() * 0.02);
+            v_power_val := GREATEST(0, v_power_val); -- 确保功率不为负
+        ELSE
+            v_power_val := NULL;
+        END IF;
+
+        -- 3. 插入数据到 back 表
+        INSERT INTO data_super_short_term_forecast_back (
+            data_sourcegrab_id, data_sourcegrab_pattern_name,
+            entity_id, entity_type, entity_name,
+            create_time, start_time, forecast_time, pre_qrts,
+            power
+        ) VALUES (
+            -- 字段映射
+            rec_report.data_sourcegrab_id, rec_report.data_sourcegrab_pattern_name,
+            rec_report.entity_id, v_entity_type, v_station_name,
+            v_create_time_ts, rec_report.start_time, rec_report.forecast_time, rec_report.pre_qrts,
+            -- 功率 (使用微调后的值)
+            ROUND(v_power_val, 2)::VARCHAR
+        );
+    END LOOP;
+
+    RAISE NOTICE '超短期功率预测回溯数据生成完成!';
+
+END $$;

+ 65 - 0
doc/数据模拟脚本/超短期功率预测/mock_data_super_short_term_forecast_correct.sql

@@ -0,0 +1,65 @@
+-- ============================================================
+-- 脚本功能:基于 issued 表生成 correct 表数据 (data_super_short_term_forecast_correct)
+-- 逻辑:筛选特定场站和时间范围的数据,并对功率进行微调后插入
+-- ============================================================
+DO $$
+DECLARE
+    -- ================= 配置区域 =================
+    v_past_days        INTEGER := 30;              -- 从过去多少天开始
+    v_future_days      INTEGER := 10;              -- 到未来多少天结束
+    
+    -- 模拟数据配置
+    v_station_id       BIGINT := 2;                -- 场站ID
+    v_station_name     VARCHAR := '渤海一号风电场'; -- 场站名称
+    v_entity_id        VARCHAR := '2';             -- 实体ID
+    v_entity_type      INTEGER := 1;               -- 实体类型 (示例: 1代表场站)
+
+    -- 循环变量
+    rec_issued         data_super_short_term_forecast_issued%ROWTYPE;
+    v_create_time_ts   INTEGER := EXTRACT(EPOCH FROM NOW())::INTEGER;
+    v_power_val        DECIMAL;                    -- 微调后的功率值
+BEGIN
+    RAISE NOTICE '开始生成超短期功率预测修正数据。场站: %, 时间范围: % 至 %', v_station_name, CURRENT_DATE - INTERVAL '1 day' * v_past_days, CURRENT_DATE + INTERVAL '1 day' * v_future_days;
+
+    -- 1. 清理旧数据 (可选,根据需求决定)
+    DELETE FROM data_super_short_term_forecast_correct 
+    WHERE entity_id = v_entity_id
+      AND start_time >= (EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '1 day' * v_past_days)))::INTEGER
+      AND start_time <= (EXTRACT(EPOCH FROM (CURRENT_DATE + INTERVAL '1 day' * v_future_days + INTERVAL '10 days')))::INTEGER;
+
+    -- 2. 遍历源表数据
+    FOR rec_issued IN 
+        SELECT * FROM data_super_short_term_forecast_issued
+        WHERE entity_id = v_entity_id
+          AND start_time >= (EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '1 day' * v_past_days)))::INTEGER
+          AND start_time <= (EXTRACT(EPOCH FROM (CURRENT_DATE + INTERVAL '1 day' * v_future_days + INTERVAL '10 days')))::INTEGER
+        ORDER BY start_time, forecast_time
+    LOOP
+        -- --- 数据微调逻辑 ---
+        -- 对预测功率进行小幅度随机扰动 (例如:浮动 +/- 1%)
+        IF rec_issued.power IS NOT NULL THEN
+            v_power_val := rec_issued.power::DECIMAL * (0.99 + RANDOM() * 0.02);
+            v_power_val := GREATEST(0, v_power_val); -- 确保功率不为负
+        ELSE
+            v_power_val := NULL;
+        END IF;
+
+        -- 3. 插入数据到 correct 表
+        INSERT INTO data_super_short_term_forecast_correct (
+            data_sourcegrab_id, data_sourcegrab_pattern_name,
+            entity_id, entity_type, entity_name,
+            create_time, start_time, forecast_time, pre_qrts,
+            power
+        ) VALUES (
+            -- 字段映射
+            rec_issued.data_sourcegrab_id, rec_issued.data_sourcegrab_pattern_name,
+            rec_issued.entity_id, v_entity_type, v_station_name,
+            v_create_time_ts, rec_issued.start_time, rec_issued.forecast_time, rec_issued.pre_qrts,
+            -- 功率 (使用微调后的值)
+            ROUND(v_power_val, 2)::VARCHAR
+        );
+    END LOOP;
+
+    RAISE NOTICE '超短期功率预测修正数据生成完成!';
+
+END $$;

+ 65 - 0
doc/数据模拟脚本/超短期功率预测/mock_data_super_short_term_forecast_issued.sql

@@ -0,0 +1,65 @@
+-- ============================================================
+-- 脚本功能:基于 raw 表生成 issued 表数据 (data_super_short_term_forecast_issued)
+-- 逻辑:筛选特定场站和时间范围的数据,并对功率进行微调后插入
+-- ============================================================
+DO $$
+DECLARE
+    -- ================= 配置区域 =================
+    v_past_days        INTEGER := 30;              -- 从过去多少天开始
+    v_future_days      INTEGER := 10;              -- 到未来多少天结束
+    
+    -- 模拟数据配置
+    v_station_id       BIGINT := 2;                -- 场站ID
+    v_station_name     VARCHAR := '渤海一号风电场'; -- 场站名称
+    v_entity_id        VARCHAR := '2';             -- 实体ID
+    v_entity_type      INTEGER := 1;               -- 实体类型 (示例: 1代表场站)
+
+    -- 循环变量
+    rec_raw            data_super_short_term_forecast_raw%ROWTYPE;
+    v_create_time_ts   INTEGER := EXTRACT(EPOCH FROM NOW())::INTEGER;
+    v_power_val        DECIMAL;                    -- 微调后的功率值
+BEGIN
+    RAISE NOTICE '开始生成超短期功率预测发布数据。场站: %, 时间范围: % 至 %', v_station_name, CURRENT_DATE - INTERVAL '1 day' * v_past_days, CURRENT_DATE + INTERVAL '1 day' * v_future_days;
+
+    -- 1. 清理旧数据 (可选,根据需求决定)
+    DELETE FROM data_super_short_term_forecast_issued 
+    WHERE entity_id = v_entity_id
+      AND start_time >= (EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '1 day' * v_past_days)))::INTEGER
+      AND start_time <= (EXTRACT(EPOCH FROM (CURRENT_DATE + INTERVAL '1 day' * v_future_days + INTERVAL '10 days')))::INTEGER;
+
+    -- 2. 遍历源表数据
+    FOR rec_raw IN 
+        SELECT * FROM data_super_short_term_forecast_raw
+        WHERE entity_id = v_entity_id
+          AND start_time >= (EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '1 day' * v_past_days)))::INTEGER
+          AND start_time <= (EXTRACT(EPOCH FROM (CURRENT_DATE + INTERVAL '1 day' * v_future_days + INTERVAL '10 days')))::INTEGER
+        ORDER BY start_time, forecast_time
+    LOOP
+        -- --- 数据微调逻辑 ---
+        -- 对预测功率进行小幅度随机扰动 (例如:浮动 +/- 1%)
+        IF rec_raw.power IS NOT NULL THEN
+            v_power_val := rec_raw.power::DECIMAL * (0.99 + RANDOM() * 0.02);
+            v_power_val := GREATEST(0, v_power_val); -- 确保功率不为负
+        ELSE
+            v_power_val := NULL;
+        END IF;
+
+        -- 3. 插入数据到 issued 表
+        INSERT INTO data_super_short_term_forecast_issued (
+            data_sourcegrab_id, data_sourcegrab_pattern_name,
+            entity_id, entity_type, entity_name,
+            create_time, start_time, forecast_time, pre_qrts,
+            power
+        ) VALUES (
+            -- 字段映射
+            rec_raw.data_sourcegrab_id, rec_raw.data_sourcegrab_pattern_name,
+            rec_raw.entity_id, v_entity_type, v_station_name,
+            v_create_time_ts, rec_raw.start_time, rec_raw.forecast_time, rec_raw.pre_qrts,
+            -- 功率 (使用微调后的值)
+            ROUND(v_power_val, 2)::VARCHAR
+        );
+    END LOOP;
+
+    RAISE NOTICE '超短期功率预测发布数据生成完成!';
+
+END $$;

+ 109 - 0
doc/数据模拟脚本/超短期功率预测/mock_data_super_short_term_forecast_raw.sql

@@ -0,0 +1,109 @@
+-- ============================================================
+-- 脚本功能:生成超短期功率预测原始数据 (data_super_short_term_forecast_raw)
+-- 逻辑:生成过去30天到未来10天,每日UTC 12时起报的超短期预测数据
+-- ============================================================
+DO $$
+DECLARE
+    -- ================= 配置区域 =================
+    v_past_days        INTEGER := 30;              -- 从过去多少天开始
+    v_future_days      INTEGER := 10;              -- 到未来多少天结束
+    v_utc_start_hour   INTEGER := 12;              -- UTC起报小时
+    v_forecast_hours   INTEGER := 4;               -- 预报时长 (小时)
+    v_interval_minutes INTEGER := 15;              -- 预报间隔 (分钟)
+    
+    -- 模拟数据配置
+    v_station_id       BIGINT := 2;                -- 场站ID
+    v_station_name     VARCHAR := '渤海一号风电场'; -- 场站名称
+    v_entity_id        VARCHAR := '2';             -- 实体ID
+    v_entity_type      VARCHAR := 'station';       -- 实体类型
+
+    -- 循环变量
+    v_date_cursor      DATE;                       -- 日期游标
+    v_start_time_ts    INTEGER;                    -- 起报时间戳
+    v_forecast_time_ts INTEGER;                    -- 预报时间戳
+    v_power_val        DECIMAL;                    -- 模拟的预测功率
+    i                  INTEGER;                    -- 循环计数器
+    v_total_steps      INTEGER;                    -- 总步数
+BEGIN
+    -- 1. 计算总步数 (4小时 / 15分钟 = 16步)
+    v_total_steps := (v_forecast_hours * 60) / v_interval_minutes;
+
+    RAISE NOTICE '开始生成超短期功率预测数据。时间范围: % 至 %', 
+                 CURRENT_DATE - INTERVAL '1 day' * v_past_days, 
+                 CURRENT_DATE + INTERVAL '1 day' * v_future_days;
+
+    -- 2. 按天循环生成数据
+    FOR v_date_cursor IN 
+        SELECT generate_series(
+            CURRENT_DATE - INTERVAL '1 day' * v_past_days, 
+            CURRENT_DATE + INTERVAL '1 day' * v_future_days, 
+            '1 day'
+        )::date
+    LOOP
+        -- 2.1 计算当天的起报时间 (UTC 12:00)
+        v_start_time_ts := EXTRACT(EPOCH FROM (
+            v_date_cursor + (v_utc_start_hour || ' hours')::INTERVAL
+        ))::INTEGER;
+
+        -- 2.2 清理当天旧数据 (可选)
+        DELETE FROM data_super_short_term_forecast_raw 
+        WHERE entity_id = v_entity_id
+          AND start_time = v_start_time_ts;
+
+        -- 2.3 循环生成该次起报的16个预报点
+        FOR i IN 0..(v_total_steps - 1) LOOP
+            -- 计算预报时间
+            v_forecast_time_ts := v_start_time_ts + (i * v_interval_minutes * 60);
+            
+            -- 模拟预测功率 (示例:基于正弦波模拟日内变化,并加入随机扰动)
+            v_power_val := 50 + 40 * SIN(RADIANS(EXTRACT(HOUR FROM TO_TIMESTAMP(v_forecast_time_ts)) * 15)) + (RANDOM() * 10 - 5);
+            v_power_val := GREATEST(0, LEAST(100, v_power_val)); -- 限制在0-100之间
+
+            -- 插入数据
+            INSERT INTO data_super_short_term_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, pre_qrts,
+                station_id, station_name,
+                subject_id, subject_name,
+                machine_id, machine_name,
+                analyze_his_id, archive_record_id,
+                power
+            ) VALUES (
+                -- 经纬度 (示例值)
+                '38.5', '121.2',
+                -- 数据元信息
+                '单点时间序列', 2, 1, -- data_type: 短期气象, business_process_type: 原始
+                1, 101, 'pattern_001',
+                1001, 'model_super_short_term',
+                1, 'source_001',
+                -- 实体信息
+                v_entity_id, v_entity_type,
+                -- 时间信息
+                EXTRACT(EPOCH FROM NOW())::INTEGER, v_start_time_ts, v_forecast_time_ts,
+                -- 预报参数
+                0, -- pre_days: 超短期通常为0
+                i * v_interval_minutes, -- lead_time: 预报时效 (分钟)
+                i + 1, -- pre_qrts: 预报刻数
+                -- 场站信息
+                v_station_id, v_station_name,
+                -- 交易主题 (示例)
+                NULL, NULL,
+                -- 风机信息 (示例)
+                NULL, NULL,
+                -- 文件解析信息 (示例)
+                NULL, NULL,
+                -- 预测功率
+                ROUND(v_power_val, 2)::VARCHAR
+            );
+        END LOOP;
+    END LOOP;
+
+    RAISE NOTICE '超短期功率预测数据生成完成!';
+
+END $$;

+ 65 - 0
doc/数据模拟脚本/超短期功率预测/mock_data_super_short_term_forecast_report.sql

@@ -0,0 +1,65 @@
+-- ============================================================
+-- 脚本功能:基于 correct 表生成 report 表数据 (data_super_short_term_forecast_report)
+-- 逻辑:筛选特定场站和时间范围的数据,并对功率进行微调后插入
+-- ============================================================
+DO $$
+DECLARE
+    -- ================= 配置区域 =================
+    v_past_days        INTEGER := 30;              -- 从过去多少天开始
+    v_future_days      INTEGER := 10;              -- 到未来多少天结束
+    
+    -- 模拟数据配置
+    v_station_id       BIGINT := 2;                -- 场站ID
+    v_station_name     VARCHAR := '渤海一号风电场'; -- 场站名称
+    v_entity_id        VARCHAR := '2';             -- 实体ID
+    v_entity_type      INTEGER := 1;               -- 实体类型 (示例: 1代表场站)
+
+    -- 循环变量
+    rec_correct        data_super_short_term_forecast_correct%ROWTYPE;
+    v_create_time_ts   INTEGER := EXTRACT(EPOCH FROM NOW())::INTEGER;
+    v_power_val        DECIMAL;                    -- 微调后的功率值
+BEGIN
+    RAISE NOTICE '开始生成超短期功率预测上报数据。场站: %, 时间范围: % 至 %', v_station_name, CURRENT_DATE - INTERVAL '1 day' * v_past_days, CURRENT_DATE + INTERVAL '1 day' * v_future_days;
+
+    -- 1. 清理旧数据 (可选,根据需求决定)
+    DELETE FROM data_super_short_term_forecast_report 
+    WHERE entity_id = v_entity_id
+      AND start_time >= (EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '1 day' * v_past_days)))::INTEGER
+      AND start_time <= (EXTRACT(EPOCH FROM (CURRENT_DATE + INTERVAL '1 day' * v_future_days + INTERVAL '10 days')))::INTEGER;
+
+    -- 2. 遍历源表数据
+    FOR rec_correct IN 
+        SELECT * FROM data_super_short_term_forecast_correct
+        WHERE entity_id = v_entity_id
+          AND start_time >= (EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '1 day' * v_past_days)))::INTEGER
+          AND start_time <= (EXTRACT(EPOCH FROM (CURRENT_DATE + INTERVAL '1 day' * v_future_days + INTERVAL '10 days')))::INTEGER
+        ORDER BY start_time, forecast_time
+    LOOP
+        -- --- 数据微调逻辑 ---
+        -- 对预测功率进行小幅度随机扰动 (例如:浮动 +/- 1%)
+        IF rec_correct.power IS NOT NULL THEN
+            v_power_val := rec_correct.power::DECIMAL * (0.99 + RANDOM() * 0.02);
+            v_power_val := GREATEST(0, v_power_val); -- 确保功率不为负
+        ELSE
+            v_power_val := NULL;
+        END IF;
+
+        -- 3. 插入数据到 report 表
+        INSERT INTO data_super_short_term_forecast_report (
+            data_sourcegrab_id, data_sourcegrab_pattern_name,
+            entity_id, entity_type, entity_name,
+            create_time, start_time, forecast_time, pre_qrts,
+            power
+        ) VALUES (
+            -- 字段映射
+            rec_correct.data_sourcegrab_id, rec_correct.data_sourcegrab_pattern_name,
+            rec_correct.entity_id, v_entity_type, v_station_name,
+            v_create_time_ts, rec_correct.start_time, rec_correct.forecast_time, rec_correct.pre_qrts,
+            -- 功率 (使用微调后的值)
+            ROUND(v_power_val, 2)::VARCHAR
+        );
+    END LOOP;
+
+    RAISE NOTICE '超短期功率预测上报数据生成完成!';
+
+END $$;

+ 144 - 0
doc/数据模拟脚本/超短期功率预测/mock_data_ultra_short_term_power_forecasting.sql

@@ -0,0 +1,144 @@
+-- ============================================================
+-- 脚本功能:独立生成模拟的超短期功率预测数据
+-- 说明:
+--   1. 不依赖任何源表,直接生成数据。
+--   2. 使用正弦函数模拟风电出力曲线,数据更合理。
+--   3. 可配置生成过去30天到未来10天的数据。
+-- ============================================================
+DO $$
+DECLARE
+    -- ================= 配置区域 =================
+    v_past_days        INTEGER := 30;              -- 从过去多少天开始
+    v_future_days      INTEGER := 10;              -- 到未来多少天结束
+    v_interval_minutes INTEGER := 15;              -- 数据间隔(分钟)
+    v_forecast_hours   INTEGER := 4;               -- 预测时长(小时)
+    v_max_power        NUMERIC := 100.0;           -- 模拟的最大功率(装机容量)
+
+    -- 模拟数据配置
+    v_station_id       BIGINT := 2;                -- 场站ID
+    v_station_name     VARCHAR := '渤海一号风电场'; -- 场站名称
+    v_entity_id        VARCHAR := '2';             -- 实体ID
+    v_entity_type      INTEGER := 1;               -- 实体类型
+
+    -- 循环变量
+    v_start_timestamp  TIMESTAMP;
+    v_end_timestamp    TIMESTAMP;
+    v_current_start    TIMESTAMP;
+    v_current_forecast TIMESTAMP;
+    v_start_time       INTEGER;
+    v_forecast_time    INTEGER;
+    v_create_time      INTEGER;
+    v_data_source_id   INTEGER;
+    v_pattern_name     VARCHAR := '模拟生成';
+    
+    -- 用于存储聚合后的宽表字段值
+    v_power            VARCHAR;
+    v_p15 VARCHAR; v_p30 VARCHAR; v_p45 VARCHAR; v_p60 VARCHAR;
+    v_p75 VARCHAR; v_p90 VARCHAR; v_p105 VARCHAR; v_p120 VARCHAR;
+    v_p135 VARCHAR; v_p150 VARCHAR; v_p165 VARCHAR; v_p180 VARCHAR;
+    v_p195 VARCHAR; v_p210 VARCHAR; v_p225 VARCHAR; v_p240 VARCHAR;
+    
+    -- 计数器
+    v_insert_count     INTEGER := 0;
+
+BEGIN
+    RAISE NOTICE '开始独立生成超短期功率预测数据。场站: %', v_station_name;
+
+    -- 1. 计算时间范围
+    v_start_timestamp := CURRENT_DATE - INTERVAL '1 day' * v_past_days;
+    v_end_timestamp := CURRENT_DATE + INTERVAL '1 day' * v_future_days;
+    v_current_start := v_start_timestamp;
+
+    -- 2. 清理旧数据
+    DELETE FROM public.data_ultra_short_term_power_forecasting 
+    WHERE entity_id = v_entity_id
+      AND start_time >= EXTRACT(EPOCH FROM v_start_timestamp)::INTEGER
+      AND start_time <= EXTRACT(EPOCH FROM v_end_timestamp)::INTEGER;
+
+    -- 3. 循环生成数据(按15分钟间隔)
+    WHILE v_current_start <= v_end_timestamp LOOP
+        v_start_time := EXTRACT(EPOCH FROM v_current_start)::INTEGER;
+        v_create_time := EXTRACT(EPOCH FROM NOW())::INTEGER;
+        v_data_source_id := v_start_time; -- 使用起报时间作为ID
+        
+        -- 重置宽表字段
+        v_power := NULL; v_p15 := NULL; v_p30 := NULL; v_p45 := NULL; v_p60 := NULL;
+        v_p75 := NULL; v_p90 := NULL; v_p105 := NULL; v_p120 := NULL;
+        v_p135 := NULL; v_p150 := NULL; v_p165 := NULL; v_p180 := NULL;
+        v_p195 := NULL; v_p210 := NULL; v_p225 := NULL; v_p240 := NULL;
+
+        -- 4. 生成预测曲线(0-4小时,每15分钟一个点)
+        FOR i IN 0..(v_forecast_hours * 60 / v_interval_minutes) LOOP
+            v_current_forecast := v_current_start + INTERVAL '1 minute' * (i * v_interval_minutes);
+            v_forecast_time := EXTRACT(EPOCH FROM v_current_forecast)::INTEGER;
+            
+            -- 使用正弦函数模拟风电出力曲线
+            -- 曲线从0开始,在2小时(120分钟)达到峰值,4小时(240分钟)回到0
+            DECLARE
+                v_diff_minutes INTEGER;
+                v_simulated_power NUMERIC;
+            BEGIN
+                v_diff_minutes := i * v_interval_minutes;
+                
+                IF v_diff_minutes BETWEEN 0 AND 240 THEN
+                    v_simulated_power := v_max_power * SIN(PI() * v_diff_minutes / 240.0);
+                    v_simulated_power := ROUND(v_simulated_power, 2);
+                ELSE
+                    v_simulated_power := 0;
+                END IF;
+
+                -- 根据时间点填充对应的字段
+                CASE v_diff_minutes
+                    WHEN 0 THEN v_power := v_simulated_power::VARCHAR;
+                    WHEN 15 THEN v_p15 := v_simulated_power::VARCHAR;
+                    WHEN 30 THEN v_p30 := v_simulated_power::VARCHAR;
+                    WHEN 45 THEN v_p45 := v_simulated_power::VARCHAR;
+                    WHEN 60 THEN v_p60 := v_simulated_power::VARCHAR;
+                    WHEN 75 THEN v_p75 := v_simulated_power::VARCHAR;
+                    WHEN 90 THEN v_p90 := v_simulated_power::VARCHAR;
+                    WHEN 105 THEN v_p105 := v_simulated_power::VARCHAR;
+                    WHEN 120 THEN v_p120 := v_simulated_power::VARCHAR;
+                    WHEN 135 THEN v_p135 := v_simulated_power::VARCHAR;
+                    WHEN 150 THEN v_p150 := v_simulated_power::VARCHAR;
+                    WHEN 165 THEN v_p165 := v_simulated_power::VARCHAR;
+                    WHEN 180 THEN v_p180 := v_simulated_power::VARCHAR;
+                    WHEN 195 THEN v_p195 := v_simulated_power::VARCHAR;
+                    WHEN 210 THEN v_p210 := v_simulated_power::VARCHAR;
+                    WHEN 225 THEN v_p225 := v_simulated_power::VARCHAR;
+                    WHEN 240 THEN v_p240 := v_simulated_power::VARCHAR;
+                    ELSE NULL;
+                END CASE;
+            END;
+        END LOOP;
+
+        -- 5. 插入宽表数据
+        INSERT INTO public.data_ultra_short_term_power_forecasting (
+            data_sourcegrab_id, data_sourcegrab_pattern_name,
+            entity_id, entity_type, entity_name,
+            create_time, start_time,
+            power, power15, power30, power45, power60,
+            power75, power90, power105, power120,
+            power135, power150, power165, power180,
+            power195, power210, power225, power240,
+            forecast_time
+        ) VALUES (
+            v_data_source_id, v_pattern_name,
+            v_entity_id, v_entity_type, v_station_name,
+            v_create_time,
+            v_start_time,
+            v_power, v_p15, v_p30, v_p45, v_p60,
+            v_p75, v_p90, v_p105, v_p120,
+            v_p135, v_p150, v_p165, v_p180,
+            v_p195, v_p210, v_p225, v_p240,
+            v_start_time + 240 * 60
+        );
+        
+        v_insert_count := v_insert_count + 1;
+        
+        -- 移动到下一个15分钟
+        v_current_start := v_current_start + INTERVAL '1 minute' * v_interval_minutes;
+    END LOOP;
+
+    RAISE NOTICE '超短期功率预测数据生成完成!共插入 % 条记录。', v_insert_count;
+
+END $$;

+ 12 - 0
doc/数据模拟脚本/超短期功率预测/readme.md

@@ -0,0 +1,12 @@
+可调整配置参数
+`mock_data_super_short_term_forecast_raw.sql`
+- `v_station_id`
+- `v_station_name`
+
+依次执行生成(-30,10)数据
+`mock_data_super_short_term_forecast_raw.sql`
+`mock_data_super_short_term_forecast_issued.sql`
+`mock_data_super_short_term_forecast_correct.sql`
+`mock_data_super_short_term_forecast_report.sql`
+`mock_data_super_short_term_forecast_back.sql`
+`mock_data_ultra_short_term_power_forecasting.sql`