#include #include "script.h" //带_INDEX为QTouch中对应的点的内存编号 //光伏总功率 #define GF_TP_INDEX 105 //负荷总功率(需通过计算cal_Total_Load_Power) #define FH_TP_INDEX 1 //市电A相电压 #define SD_AV_INDEX 0 //市电B相电压 #define SD_BV_INDEX 1 //市电C相电压 #define SD_CV_INDEX 2 //柴发A相电压 #define CF_AV_INDEX 31 //柴发B相电压 #define CF_BV_INDEX 32 //柴发C相电压 #define CF_CV_INDEX 33 //电池电量低一级告警 #define BMS_DLOW1_INDEX 767 //电池禁充 #define BMS_JC_INDEX 6 //电池禁放 #define BMS_JF_INDEX 7 //市电进线开关状态 #define SD_JXKGSTATE_INDEX 26 //柴发进线开关状态 #define CF_JXKGSTATE_INDEX 57 //PCS工作模式 #define PCS_RMODE_INDEX 3768 //PCS定时开机时间 #define PCS_START_H 10 //时 #define PCS_START_M 11 //分 //控制点位 //市电进线开关控制点 #define SD_JXKG_INDEX 29 //柴发进线开关控制点 #define CF_JXKG_INDEX 60 //PCS工作模式控制点 #define PCS_RMODEKC_INDEX 582 //光伏调功 //逆变器1的功率 #define PV_PKC1_INDEX 3544 //逆变器2的功率 #define PV_PKC2_INDEX 3633 //逆变器3的功率 #define PV_PKC3_INDEX 3722 int readFile() { char s[] = "/home/ctstor/ctfiles/maxvarindex"; //只读打开文件 int fd = open(s, O_RDONLY); if(fd == -1) { printf("error is %s\n", strerror(errno)); return; } printf("sucess fd = %d\n", fd); char buf[100]; memset(buf, 0, sizeof(buf)); int a=3999; //read返回0表示文件读取完毕 while(read(fd, buf, sizeof(buf) - 1) > 0) { printf("%s\n", buf); char * str=buf; printf("%s-----\n", str); sscanf(str,"%d",&a); memset(buf, 0, sizeof(buf)); } printf("%d---===--\n", a); //别忘记关闭 close(fd); return a; } //变量点定义 //负荷总功率 double dTLoadP=0; //光伏最大功率 double dVMaxP = 0; //市电电压状态 char cSDVN = 2; //柴发电压状态 char cCFVN = 2; //计算负荷总功率 //馈线柜9回路+电源柜其他进出线回路多功能表有功功率之和 double cal_Total_Load_Power() { double dTLoadP = GetItemValue(0,136)+GetItemValue(0,167)+GetItemValue(0,198)+GetItemValue(0,229)+GetItemValue(0,260)+GetItemValue(0,291)+GetItemValue(0,322)+GetItemValue(0,353)+GetItemValue(0,384)+GetItemValue(0,415)+GetItemValue(0,446); ///////////////////////////// //需根据实际进行完善; //添加各个回路有功功率相加计算 ///////////////////////////// return dTLoadP; } //判断市电电压是否正常 //返回结果0,失电,1,正常,2,其它情况 //该结果作为作为并网和离网控制策略的依据 //0、失电,需进行离网逻辑 //1、正常,需进行并网逻辑 char check_SDV_Normal() { //获取市电相电压数据 double dAv = GetItemValue(0,SD_AV_INDEX); double dBv = GetItemValue(0,SD_BV_INDEX); double dCv = GetItemValue(0,SD_CV_INDEX); //相电压>184,正常 if((dAv>184) && (dBv>184) && (dCv>184)) return 1; //相电压<184,失电 if((dAv<184) && (dBv<184) && (dCv<184)) return 0; //其它情况 return 2; } //柴发仅在离网模式下存在 //判断市电电压是否正常 //返回结果0,失电,1,正常,2,其它情况 char check_CFV_Normal() { //获取市电相电压数据 double dAv = GetItemValue(0,CF_AV_INDEX); double dBv = GetItemValue(0,CF_BV_INDEX); double dCv = GetItemValue(0,CF_CV_INDEX); //相电压>184,正常 if((dAv>184) && (dBv>184) && (dCv>184)) return 1; //相电压<184,失电 if((dAv<184) && (dBv<184) && (dCv<184)) return 0; //其它情况 return 2; } //光伏降容逻辑处理 void PVJR_Logic() { //逆变器1、2、3的现功率 double dPv1 = GetItemValue(0, PV_PKC1_INDEX); double dPv2 = GetItemValue(0, PV_PKC2_INDEX); double dPv3 = GetItemValue(0, PV_PKC3_INDEX); //计算当前负荷总功率与光伏最大功率占比; //3组逆变器按照当前占比计算实际需要将功率设定的值; double dFactor = dTLoadP/dVMaxP; int nPv1Set = dPv1*dFactor; int nPv2Set = dPv2*dFactor; int nPv3Set = dPv3*dFactor; char chSend1[200] = {0}; sprintf(chSend1, "%d", nPv1Set); char chSend2[200] = {0}; sprintf(chSend2, "%d", nPv2Set); char chSend3[200] = {0}; sprintf(chSend3, "%d", nPv3Set); while(GetKcFlag(0) == 1){ waitForMillisec(10); } SetKcData(0, PV_PKC1_INDEX, chSend1); SetKcFlag(0,1); while(GetKcFlag(0) == 1){ waitForMillisec(10); } SetKcData(0, PV_PKC2_INDEX, chSend2); SetKcFlag(0,1); while(GetKcFlag(0) == 1){ waitForMillisec(10); } SetKcData(0, PV_PKC3_INDEX, chSend3); SetKcFlag(0,1); } //并网逻辑处理 void BM_Logic() { //获取市电进线开关状态,1合,0分 char cSDJXState = GetItemValue(0, SD_JXKGSTATE_INDEX); if(cSDJXState == 1){ //进线合闸后,需比对光伏最大功率与负荷总功率; if(dVMaxP > dTLoadP){ //光伏超发,需降容 PVJR_Logic(); } } else if(cSDJXState == 0){ while(GetKcFlag(0) == 1){ waitForMillisec(10); } //控制进线合闸 SetKcData(0, SD_JXKG_INDEX, "1 0"); SetKcFlag(0,1); } } //离网逻辑处理 void LM_Logic() { //获取市电进线开关状态,1合,0分 char cSDJXState = GetItemValue(0, SD_JXKGSTATE_INDEX); //获取柴发进线开关状态,1合,0分 char cCFJXState = GetItemValue(0, CF_JXKGSTATE_INDEX); //获取BMS禁充指令 char cBMSJCState = GetItemValue(0, BMS_JC_INDEX); //BMS电池电量低一级告警 char cBMSLow1State = GetItemValue(0, BMS_DLOW1_INDEX); ////////////////////////////////////////////////// //PCS变流器状态; //0:关闭 //1:软启动中 //2:并网充电 //3:并网放电 //4:离网放电 //5:降额并网 //6:待机 //7:离网充电 char cPCSState = GetItemValue(0, PCS_RMODE_INDEX); ////////////////////////////////////////////////// int nCurH = GetSysItem(3); int nCurM = GetSysItem(4); int nPcsStartH = GetItemValue(0, PCS_START_H); int nPcsStartM = GetItemValue(0, PCS_START_M); if(cSDJXState == 0){ printf("cSDJXState==0"); //进线分闸后,需比对光伏最大功率与负荷总功率; if(dVMaxP > dTLoadP){ //当BMS发出禁充指令后,EMS控制光伏降容 if(cBMSJCState == 1){ //实际值? //光伏超发,需降容 PVJR_Logic(); } } else if(dVMaxP < dTLoadP){ //检测柴发进线电压是否正常,如不正常则EMS控制PCS停机;正常则闭合柴发进线开关 if(cCFVN == 0){//柴发电压失压 if(cCFJXState == 0){ //柴发进线处于分闸状态 //当收到BMS发出电池电量低一级告警的时候 //控制PCS停机 if(cBMSLow1State == 1){ if(cPCSState != 0){ while(GetKcFlag(0) == 1){ waitForMillisec(10); } //控制PCS停机 写0xAAAA SetKcData(0, PCS_RMODEKC_INDEX, "43690"); SetKcFlag(0,1); } //PCS停机后,可根据设定的开机时间,进行自动开机; if(cPCSState == 0){ //到时间,控制PCS开机 if(nPcsStartH == nCurH && nPcsStartM == nCurM){ while(GetKcFlag(0) == 1){ waitForMillisec(10); } //控制PCS开机 写0x5555 SetKcData(0, PCS_RMODEKC_INDEX, "21845"); SetKcFlag(0,1); } } } } else if(cCFJXState == 1){//柴发进线处于合闸状态 while(GetKcFlag(0) == 1){ waitForMillisec(10); } //控制柴发进线分闸 SetKcData(0, CF_JXKG_INDEX, "0 1"); SetKcFlag(0,1); } } else if(cCFVN == 1){//柴发电压正常 if(cCFJXState == 0){ while(GetKcFlag(0) == 1){ waitForMillisec(10); } //控制柴发进线合闸 SetKcData(0, CF_JXKG_INDEX, "1 0"); SetKcFlag(0,1); } } } } else if(cSDJXState == 1){ while(GetKcFlag(0) == 1){ waitForMillisec(10); } //控制进线分闸 SetKcData(0, SD_JXKG_INDEX, "0 1"); SetKcFlag(0,1); } } int main( ) { //初始化 printf("start"); //int nMaxIndex= readFile(); if (OpenRamRt()<1) return; while (1) { //获取负荷总功率 dTLoadP = cal_Total_Load_Power(); //获取市电相电压状态 cSDVN = check_SDV_Normal(); //获取柴发相电压状态 cCFVN = check_CFV_Normal(); //获取光伏最大总功率 dVMaxP = GetItemValue(0, GF_TP_INDEX); if(cSDVN == 0){ //离网逻辑 LM_Logic(); printf("aaa"); } else if(cSDVN == 1){ //并网逻辑 BM_Logic(); } waitForMillisec(10); } return 0; }