-- ============================================================ -- 脚本功能:独立生成光伏电站实测数据 (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 $$;