from pathlib import Path
from openai import OpenAI
import os

client = OpenAI(
    api_key='sk-f01744b2801344b1a72f89ec7e290cad',
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",  # 填写DashScope服务base_url
)

file_csv = client.files.create(file=Path("./data.csv"), purpose="file-extract")

# 新文件上传后需要等待模型解析，首轮响应时间可能较长
completion = client.chat.completions.create(
    model="qwen-long",
    messages=[
        {
            'role': 'system',
            'content':
                '你是一名擅长调试和控制智慧住宅能源系统的大模型和强化学习专家，可根据当前的环境状态给出最优的动作决策。'
                '目前的能源系统结构主要由太阳能发电站、风能发电站、发电机和电池模块通过电力网与住宅相连接。以下是中文和符号的对照：'
                'As：电池的充电状态动作；Ag1：发电机1的功率动作；Ag2：发电机2的功率动作；Ag3：发电机3的功率动作；Av：太阳能的电压动作；'
                'Sp：电价状态；Sc：电池荷电状态；Sl：住宅负载状态；Sg1：发电机1功率状态；Sg2：发电机2功率状态；Sg3：发电机3功率状态；St：温度状态；Si：太阳辐射度状态；Sw：风速状态；'
                'Pc：电池充放电量；Pg1：发电机1发电量；Pg2：发电机2发电量；Pg3：发电机3发电量；Pso：太阳能发电量；Pw：风能发电量；'
                'Cb：电池成本；Cg1：发电机1成本；Cg2：发电机2成本；Cg3：发电机3成本；Cs：太阳能成本；Cw：风能成本；'
                'Rs：销售收入；Cp：购买成本；Ee：过剩能源；Es：短缺能源；Pe：过剩惩罚；Ps：短缺惩罚。'
                '一、控制方案和目标：'
                '1、优先使用太阳能和风能发电，当无法满足满负荷时，请使用发电机和电池供电。'
                '2、在供电时考虑多种供电来源（太阳能、风能、发电机和电池），综合每个发电模块的成本，需满足下一时刻的住宅用电负载，且使供需差异最小化。'
                '3、减少超过公网交易限额的交易，以避免公共电网波动影响住宅用电的稳定性。'
                '4、最大化奖励函数并最小化能源不平衡。'
                '二、连续状态空间：是一个长度为9的向量，包含以下部分：'
                'Sp：由数据提供；Sc：初始为0.4，始终介于0.2和0.8；Sl：由数据提供；'
                'Sg1：初始功率为0；Sg2：初始功率为0；Sg3：初始功率为0；'
                'St：由数据提供；Si：由数据提供；Sw：由数据提供。'
                '其中Sc，Sg1、Sg2和Sg3始终不小于0。'
                '三、连续动作空间：一个长度为5的向量，x表示当前时间的取值, 其范围从-1到1，'
                '每个时刻的值都是在上一时刻基础上进行变化的，Ag1、Ag2和Ag3分别表示相对于各自最大瞬时功率100、100和200的变化值。'
                '1、Ac：电池总容量为500，初始电池容量为500*0.4=200，电池容量变化100*x；'
                '2、Ag1：发电量变化100*x；'
                '3、Ag2：发电量变化100*x；'
                '4、Ag3：发电量变化200*x；'
                '5、Av：太阳能电压变为(1+x)倍。'
                '可根据需求通过改变功率控制发电机的开关，当关闭时保持Sg=0，当打开时需满足Pg约束。'
                '根据成本，通常前一台发电机的最大功率不足以满足剩余负荷时，才开启后续发电机。'
                '四、发电量计算公式'
                '1、Pc = max(0.2, min(0.8, Sc + 0.2 * action[0] * 0.9))，其中0.8和0.2为电池荷电状态上下限；'
                '2、Pg1 = max(0, min(150, 100 * action[1] + Sg1))，其中150和0为发电机1开启时发电量上下限；'
                '3、Pg2 = max(0, min(375, 100 * action[2] + Sg2))，其中375和0为发电机2开启时发电量上下限；'
                '4、Pg3 = max(0, min(500, 200 * action[3] + Sg3))，其中500和0为发电机2开启时发电量上下限；'
                '5、Pso = max(0, (0.2 * Si + 0.05 * St - 9.25) * (1 + action[4]))，其中太阳能发电功率不小于0。'
                '6、Pw：与Ws有关'
                'if 3 <= Ws < 8, Pw = Ws^3 * 172.2625 / 1000'
                'elif 8 <= Ws < 12, Pw = 64 * 172.2625 / 125'
                'else Pw = 0'
                '五、成本和能源平衡计算'
                'P = Pc + Pg1 + Pg2 + Pg3 + Pso + Pw'
                'if P >= Sl , Ee = P – Sl, else Es = Sl - P'
                '1、Cb = 0.01 * Asoc + 0.1 * Sc'
                '2、Cg1 = 0.0034 * Pg1^2 + 3 * Pg1 + 30'
                '3、Cg2 = 0.001 * Pg2^2 + 10 * Pg2 + 40'
                '4、Cg3 = 0.001 * Pg3^2 + 15 * Pg3 + 70'
                '5、Cs = 0.01 * Pso'
                '6、Cw = 0.01 * Pw'
                '7、Rs = 0.5 * Sp * Ee'
                '8、Cp = Sp * Es'
                '9、Pe = (Ee - 100) * 50'
                '10、Ps = (Es - 100) * 50'
                '因为Rs、Pe和Cp、Ps对应能源过剩和能源短缺情况，只能同时存在一组。'
                '六、奖励函数'
                'Reward = - (Cb + Cg1 + Cg2 + Cg3 + Cs + Cw + Pe + Ps - Rs + Cp) / 1000'
        },
        {
            'role': 'system',
            'content': f'fileid://{file_csv.id}'
        },
        {
            'role': 'user',
            'content':
                '读取数据并使用上述公式计算每个时刻的状态，请你使用最合适的优化方法，给出每个时刻的动作控制方案，'
                '每小时计算一次并生成一个长度为5的数组，表示Ac、Ag1、Ag2、Ag3和Av的动作决策。'
                '返回的数据应为以下Json格式：[{x1, x2, x3, x4, x5}, {x1, x2, x3, x4, x5}, ..., {x1, x2, x3, x4, x5}]'
                '只需要json数据，不需要其他任何分析。'
        }
    ],
    stream=False
)

print(completion.choices[0].message.model_dump())  # 非流式输出
