| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- -- ============================================================
- -- 脚本功能:独立生成光伏电站实测数据 (data_electricity_local)
- -- 修正说明:
- -- 1. 彻底修复所有 ROUND 函数的类型问题。
- -- 2. 所有涉及浮点运算的结果均显式转换为 NUMERIC。
- -- ============================================================
- DO $$
- DECLARE
- -- ================= 配置区域 =================
- v_past_days INTEGER := 30; -- 从过去多少天开始
- v_future_days INTEGER := 10; -- 到未来多少天结束
- v_interval_minutes INTEGER := 15; -- 数据间隔(分钟)
-
- -- 模拟场站配置
- v_station_id BIGINT := 2; -- 光伏场站ID
- v_max_power NUMERIC := 100.0; -- 理论最大发电功率(装机容量 kW)
- -- 循环变量
- v_start_timestamp TIMESTAMP WITH TIME ZONE;
- v_end_timestamp TIMESTAMP WITH TIME ZONE;
- v_current_time TIMESTAMP WITH TIME ZONE;
-
- -- 计算变量
- v_hour_of_day NUMERIC;
- v_solar_noon NUMERIC := 12.5; -- 正午时间(12:30左右)
- v_sunshine_hours NUMERIC := 11.0; -- 日照时长(假设值)
-
- -- 最终插入的字段值
- v_theoretical_power NUMERIC;
- v_actual_power NUMERIC;
- v_curtailment_power NUMERIC;
- v_device_status SMALLINT;
- v_availability NUMERIC;
- v_grid_status SMALLINT;
- BEGIN
- RAISE NOTICE '开始生成光伏实测数据。场站ID: %', v_station_id;
- -- 1. 计算时间范围
- v_start_timestamp := (CURRENT_DATE - INTERVAL '1 day' * v_past_days) AT TIME ZONE 'Asia/Shanghai';
- v_end_timestamp := (CURRENT_DATE + INTERVAL '1 day' * v_future_days) AT TIME ZONE 'Asia/Shanghai';
- v_current_time := v_start_timestamp;
- -- 2. 清理旧数据
- DELETE FROM public.data_electricity_local
- WHERE config_station_id = v_station_id
- AND tm >= v_start_timestamp
- AND tm <= v_end_timestamp;
- -- 3. 循环生成数据
- WHILE v_current_time <= v_end_timestamp LOOP
- -- 获取小时数(带小数,例如 13.25 代表 13:15)
- v_hour_of_day := EXTRACT(HOUR FROM v_current_time) + EXTRACT(MINUTE FROM v_current_time) / 60.0;
-
- -- ================= 核心算法:模拟光伏出力 =================
- IF v_hour_of_day BETWEEN (v_solar_noon - v_sunshine_hours/2) AND (v_solar_noon + v_sunshine_hours/2) THEN
- -- 计算正弦值
- DECLARE
- v_day_factor NUMERIC;
- BEGIN
- v_day_factor := (v_hour_of_day - (v_solar_noon - v_sunshine_hours/2)) / v_sunshine_hours;
- -- 修正点:将 SIN 的结果转换为 NUMERIC
- v_theoretical_power := v_max_power * SIN(PI() * v_day_factor)::NUMERIC;
- -- 增加随机波动(修正点:将 RANDOM() 结果转换为 NUMERIC)
- v_theoretical_power := v_theoretical_power * (0.95::NUMERIC + RANDOM()::NUMERIC * 0.1::NUMERIC);
- v_theoretical_power := ROUND(v_theoretical_power, 2);
- END;
- ELSE
- v_theoretical_power := 0;
- END IF;
- -- ================= 衍生字段逻辑 =================
-
- -- 1. 实际功率(修正点:显式转换)
- v_actual_power := ROUND(v_theoretical_power * 0.98::NUMERIC, 2);
-
- -- 2. 限电功率与设备状态(修正点:显式转换)
- IF RANDOM() > 0.95 AND v_actual_power > 10 THEN
- v_curtailment_power := ROUND(v_actual_power * (0.1::NUMERIC + RANDOM()::NUMERIC * 0.2::NUMERIC), 2);
- v_actual_power := v_actual_power - v_curtailment_power;
- v_device_status := 2; -- 限电
- ELSE
- v_curtailment_power := 0;
- v_device_status := 0; -- 正常
- END IF;
- -- 夜间停机
- IF v_theoretical_power = 0 THEN
- v_device_status := 1;
- END IF;
- -- 3. 并网状态
- IF v_actual_power > 0 OR (v_hour_of_day BETWEEN 6 AND 19) THEN
- v_grid_status := 1;
- ELSE
- v_grid_status := 0;
- END IF;
- -- 4. 可用率
- v_availability := 100.0;
- IF v_device_status = 1 THEN v_availability := 0; END IF;
- IF v_device_status = 2 THEN v_availability := 90; END IF;
- -- 5. 插入数据
- INSERT INTO public.data_electricity_local (
- tm,
- config_station_id,
- actual_power,
- theoretical_power,
- curtailment_power,
- availability,
- device_status,
- grid_status
- ) VALUES (
- v_current_time,
- v_station_id,
- v_actual_power,
- v_theoretical_power,
- v_curtailment_power,
- v_availability,
- v_device_status,
- v_grid_status
- );
- -- 移动到下一个时间点
- v_current_time := v_current_time + INTERVAL '1 minute' * v_interval_minutes;
- END LOOP;
- RAISE NOTICE '光伏实测数据生成完成!范围: % 到 %', v_start_timestamp, v_end_timestamp;
- END $$;
|