#include "plt.h" int ies1000_comm_init(int idx) { struct ies1000_t* dev = &ies1000[idx]; struct comm_t* comm = &dev->comm; comm_set_state( comm, COMMST_ERR ); } int ies1000_comm_reset(int idx) { struct ies1000_t* dev = &ies1000[idx]; struct comm_t* comm = &dev->comm; comm_set_state( comm, COMMST_NORMAL ); comm_set_dac_param_en(comm, 1); } int ies1000_set_dev_aps(int idx, int aps) { int ret = 0; struct ies1000_t* dev = &ies1000[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 0xF007; int nb = 1; short val = aps*10; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register_with_retry(chanidx, addr, regaddr, val); chan_unlock(chanidx); if( ret < 0 ){ log_dbg("%s, idx:%d, aps:%d, fail", __func__, idx, aps); } return ret; } int ies1000_set_dev_startcmd( int idx ) { int ret = 0; struct ies1000_t* dev = &ies1000[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 0xF400; int nb = 1; int trycnt = 0; int val = 1; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register_with_retry(chanidx, addr, regaddr, val); chan_unlock(chanidx); if( ret < 0 ){ log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } int ies1000_set_dev_stopcmd( int idx ) { int ret = 0; struct ies1000_t* dev = &ies1000[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 0xF401; int nb = 1; int trycnt = 0; int val = 1; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register_with_retry(chanidx, addr, regaddr, val); chan_unlock(chanidx); if( ret < 0 ){ log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } int ies1000_set_dev_idlecmd( int idx ) { int ret = 0; struct ies1000_t* dev = &ies1000[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 0xF402; int nb = 1; int trycnt = 0; int val = 1; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register_with_retry(chanidx, addr, regaddr, val); chan_unlock(chanidx); if( ret < 0 ){ log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } // send fault reset cmd to pcs // 0:invalid 1:reset int ies1000_set_dev_resetcmd( int idx ) { int ret = 0; struct ies1000_t* dev = &ies1000[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 0xF40A; int nb = 1; int trycnt = 0; int val = 1; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register_with_retry(chanidx, addr, regaddr, val); chan_unlock(chanidx); if( ret < 0 ){ log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } int ies1000_set_dev_runmod( int idx, int val ) { int ret = 0; struct ies1000_t* dev = &ies1000[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 0xF001; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register_with_retry(chanidx, addr, regaddr, val); chan_unlock(chanidx); if( ret < 0 ){ log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } int ies1000_set_dev_offgird_voltage( int idx, double val ) { int ret = 0; struct ies1000_t* dev = &ies1000[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 0xF005; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register_with_retry(chanidx, addr, regaddr, val*10); chan_unlock(chanidx); if( ret < 0 ){ log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } int ies1000_set_dev_mid_bal_ctrl_en( int idx, int val ) { int ret = 0; struct ies1000_t* dev = &ies1000[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 0xF51B; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register_with_retry(chanidx, addr, regaddr, val); chan_unlock(chanidx); if( ret < 0 ){ log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } int ies1000_set_dev_mid_bal_ctrl_start_point( int idx, double dval) { int ret = 0; struct ies1000_t* dev = &ies1000[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 0xF51C; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register_with_retry(chanidx, addr, regaddr, dval*100); chan_unlock(chanidx); if( ret < 0 ){ log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } // 0xF000 static void ies1000_comm_dac_0xF000(int idx) { unsigned short tab_us[128]={0}; struct ies1000_t* dev = &ies1000[idx]; struct comm_t* comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if( comm_get_state(comm) != COMMST_NORMAL ){ return; } nb = 34; start = 0xF000; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry( chanidx, addr, start, nb, tab_us); if( rc < 0){ comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if( rc == 0){ /* read ok */ dev->cmdsrc = tab_us[0xF000 - start]; if(dev->cmdsrc == 0){ strcpy(dev->szcmdsrc, "HMI"); }else if(dev->cmdsrc == 1){ strcpy(dev->szcmdsrc, "EMS"); }else if(dev->cmdsrc == 2){ strcpy(dev->szcmdsrc, "Backend"); }else{ strcpy(dev->szcmdsrc, "unknown"); } dev->runmod = tab_us[0xF001 - start]; if(dev->runmod == IES1000_RUNMOD_ONGRID){ strcpy(dev->szrunmod, "ongrid"); }else if(dev->runmod == IES1000_RUNMOD_OFFGRID){ strcpy(dev->szrunmod, "offgrid"); }else if(dev->runmod == IES1000_RUNMOD_ONOFFGRID){ strcpy(dev->szrunmod, "onoffgrid"); }else{ strcpy(dev->szrunmod, "unknown"); } dev->workmod = tab_us[0xF002 - start]; if(dev->workmod == 0){ strcpy(dev->szworkmod, "ac_power"); }else if(dev->workmod == 1){ strcpy(dev->szworkmod, "voltage"); }else if(dev->workmod == 2){ strcpy(dev->szworkmod, "current"); }else if(dev->workmod == 3){ strcpy(dev->szworkmod, "3-seg chg"); }else{ strcpy(dev->szworkmod, "na"); } dev->switch_initmod = tab_us[0xF003 - start]; if(dev->switch_initmod == 0){ strcpy(dev->szswitch_initmod, "ongrid"); }else if(dev->switch_initmod == 1){ strcpy(dev->szswitch_initmod, "offgrid"); }else{ strcpy(dev->szswitch_initmod, "unkown"); } dev->offgrid_freq = tab_us[0xF004 - start]; if(dev->offgrid_freq == 0){ strcpy(dev->szoffgrid_freq, "50Hz"); }else if(dev->offgrid_freq == 1){ strcpy(dev->szoffgrid_freq, "60Hz"); }else{ strcpy(dev->szworkmod, "unkown"); } dev->offgrid_vol_set = tab_us[0xF005 - start]/10.0; dev->reactive_p_set_mod = tab_us[0xF006 - start]; if(dev->reactive_p_set_mod == 0){ strcpy(dev->szreactive_p_set_mod, "by pow"); }else if(dev->reactive_p_set_mod == 1){ strcpy(dev->szreactive_p_set_mod, "by factor"); }else{ strcpy(dev->szreactive_p_set_mod, "unkown"); } dev->active_p_set = ((short)(tab_us[0xF007 - start]))/10; dev->reactive_p_set = ((short)(tab_us[0xF008 - start]))/10; dev->cv_v_set = tab_us[0xF00A - start]/10.0; dev->cc_c_set = tab_us[0xF00B - start]/10.0; dev->pow_set_src = tab_us[0xF012 - start]; if(dev->pow_set_src == 0){ strcpy(dev->szpow_set_src, "comm"); }else if(dev->pow_set_src == 1){ strcpy(dev->szpow_set_src, "AI"); }else{ strcpy(dev->szpow_set_src, "unkown"); } dev->ins_det = tab_us[0xF021 - start]; } } // 0xF100 PCS internal config static void ies1000_comm_dac_0xF100( int idx ) { unsigned short tab_us[128]={0}; struct ies1000_t* dev = &ies1000[idx]; struct comm_t* comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if( comm_get_state(comm) != COMMST_NORMAL ){ return; } /* system info */ nb = 30; start = 0xF100; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry( chanidx, addr, start, nb, tab_us); if( rc < 0){ comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if( rc == 0){ /* read ok */ dev->dc_ovp = tab_us[0xF108 - start]/10.0; dev->dc_uvp = tab_us[0xF109 - start]/10.0; dev->dc_dfp = tab_us[0xF10A - start]/10.0; dev->dc_ocp = tab_us[0xF10B - start]/10.0; dev->env_otp = tab_us[0xF10C - start]; dev->reactor_otp = tab_us[0xF10D - start]; dev->igbt_otp = tab_us[0xF10E - start]; } } /* F5 IES1000 control param */ static void ies1000_comm_dac_0xF509( int idx ) { unsigned short tab_us[128]={0}; struct ies1000_t* dev = &ies1000[idx]; struct comm_t* comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if( comm_get_state(comm) != COMMST_NORMAL ){ return; } nb = 60; start = 0xF509; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry( chanidx, addr, start, nb, tab_us); if( rc < 0){ comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if( rc == 0){ /* read ok */ dev->gridfreq_autoadj = tab_us[0xF509 - start]; dev->pow_adjrate_en = tab_us[0xF524 - start]; dev->pow_adjrate_set = tab_us[0xF525 - start]; dev->isl_det = tab_us[0xF544 - start]; } } // 0xEB37 time sync static void ies1000_comm_dac_0xEB37( int idx ) { unsigned short tab_us[256]={0}; struct ies1000_t* dev = &ies1000[idx]; struct comm_t* comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if( comm_get_state(comm) != COMMST_NORMAL ){ return; } nb = 60; start = 0xEB00; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry( chanidx, addr, start, nb, tab_us); if( rc < 0){ comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if( rc == 0){ /* read ok */ dev->sync_year = tab_us[0xEB37 - start]; dev->sync_month = tab_us[0xEB38 - start]/100; dev->sync_day = tab_us[0xEB38 - start] - dev->sync_month*100; dev->sync_hour = tab_us[0xEB39 - start]/100; dev->sync_min = tab_us[0xEB39 - start] - dev->sync_hour*100; dev->sync_sec = tab_us[0xEB3A - start]; } } // 0xED00 static void ies1000_comm_dac_0xED00( int idx ) { unsigned short tab_us[128]={0}; struct ies1000_t* dev = &ies1000[idx]; struct comm_t* comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if( comm_get_state(comm) != COMMST_NORMAL ){ return; } nb = 93; start = 0xED00; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry( chanidx, addr, start, nb, tab_us); if( rc < 0){ comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if( rc == 0){ /* read ok */ comm_stop_cal_dac_timing(comm); dev->runstatus = tab_us[0xED00 - start]; if(dev->runstatus == 0){ strcpy(dev->szrunstatus,"stop"); }else if(dev->runstatus == 1){ strcpy(dev->szrunstatus,"idle"); }else if(dev->runstatus == 2){ strcpy(dev->szrunstatus,"dhg"); }else if(dev->runstatus == 3){ strcpy(dev->szrunstatus,"chg"); }else{ strcpy(dev->szrunstatus,"na"); } dev->dc_v = ((short)tab_us[0xED0A - start])/10.0; dev->dc_c = ((short)tab_us[0xED0B - start])/10.0; dev->grid_freq = tab_us[0xED12 - start]/100.0; dev->grid_v = tab_us[0xED14 - start]/10.0; dev->ac_c = tab_us[0xED15 - start]/10.0; dev->ua = tab_us[0xED1E - start]/10.0; dev->ub = tab_us[0xED1F - start]/10.0; dev->uc = tab_us[0xED20 - start]/10.0; dev->ia = tab_us[0xED21 - start]/10.0; dev->ib = tab_us[0xED22 - start]/10.0; dev->ic = tab_us[0xED23 - start]/10.0; dev->ap = ((short)tab_us[0xED2A - start])/10.0; dev->dc_p = ((short)tab_us[0xED2B - start])/10.0; dev->ac_breaker = tab_us[0xED36 - start];//ie1000_100kW 无此寄存器 dev->dc_breaker = tab_us[0xED38 - start]; dev->dcbuf_cont = tab_us[0xED3C - start];//ie1000_100kW 无此寄存器 dev->emg_btn = tab_us[0xED3E - start]; dev->chg_e_day = tab_us[0xED45 - start]; dev->dhg_e_day = tab_us[0xED46 - start]; dev->chg_e_total = tab_us[0xED48 -start]<<16|tab_us[0xED47 - start]; dev->dhg_e_total = tab_us[0xED4A - start]<<16|tab_us[0xED49 - start]; dev->temp_igbt_a = ((short)tab_us[0xED4B - start])/10.0; dev->temp_igbt_b = ((short)tab_us[0xED4C - start])/10.0; dev->temp_igbt_c = ((short)tab_us[0xED4D - start])/10.0; dev->temp_reactor = ((short)tab_us[0xED4E - start])/10.0;//ie1000_100kW 无此寄存器 dev->temp_env = ((short)tab_us[0xED4F - start])/10.0; dev->errstatus = tab_us[0xED5C - start]; } } // 0x0E14 fault state word static void ies1000_comm_dac_0x0E14( int idx ) { unsigned short tab_us[128]={0}; struct ies1000_t* dev = &ies1000[idx]; struct comm_t* comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if( comm_get_state(comm) != COMMST_NORMAL ){ return; } nb = 6; start = 0x0E14; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry( chanidx, addr, start, nb, tab_us); if( rc < 0){ comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if( rc == 0){ // read ok dev->faults[1] = tab_us[0x0E14 - start]; dev->faults[2] = tab_us[0x0E15 - start]; dev->faults[3] = tab_us[0x0E16 - start]; dev->faults[4] = tab_us[0x0E17 - start]; dev->faults[5] = tab_us[0x0E18 - start]; dev->faults[6] = tab_us[0x0E19 - start]; } } // 0x0F14 warning state word static void ies1000_comm_dac_0x0F14( int idx ) { unsigned short tab_us[128]={0}; struct ies1000_t* dev = &ies1000[idx]; struct comm_t* comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if( comm_get_state(comm) != COMMST_NORMAL ){ return; } nb = 6; start = 0x0F14; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry( chanidx, addr, start, nb, tab_us); if( rc < 0){ comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if( rc == 0){ // read ok dev->warns[1] = tab_us[0x0F14 - start]; dev->warns[2] = tab_us[0x0F15 - start]; dev->warns[3] = tab_us[0x0F16 - start]; dev->warns[4] = tab_us[0x0F17 - start]; dev->warns[5] = tab_us[0x0F18 - start]; dev->warns[6] = tab_us[0x0F19 - start]; comm_stop_cal_dac_timing(comm); } } void ies1000_comm_dac( int idx ) { struct ies1000_t* dev = &ies1000[idx]; struct comm_t* comm = &dev->comm; unsigned short tab_us[128]={0}; int start, nb; int chan_idx = dev->comm.chanidx; int addr = dev->comm.adr; int ret = 0; if( comm_get_state(comm) != COMMST_NORMAL ){ return; } comm_start_cal_dac_timing(comm); if( comm_get_dac_param_en(comm) == 1 ){ comm_set_dac_param_en(comm, 0); ies1000_comm_dac_0xF100(idx); ies1000_comm_dac_0xF509(idx); ies1000_comm_dac_0xEB37(idx); //misc_gen_datetimestr( dev->comm.szpollparam_datetime, sizeof(dev->comm.szpollparam_datetime) ); } ies1000_comm_dac_0xF000(idx); ies1000_comm_dac_0xED00(idx); ies1000_comm_dac_0x0E14(idx); ies1000_comm_dac_0x0F14(idx); } int ies1000_set_dev_datetime( int idx, int year, int month, int day, int hour, int minute, int second ) { int rc, ret = 0; struct ies1000_t* dev = &ies1000[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 0xEB37; int val = 1; // set year regaddr = 0xEB37; val = year; chan_lock(chanidx); rc = chan_write_single_register_with_retry(chanidx, addr, regaddr, val); chan_unlock(chanidx); if( rc != 0 ){ log_dbg("%s, idx:%d, set year fail", __func__, idx); ret = -1; goto leave; } // set month and day regaddr = 0xEB38; val = month*100 + day; chan_lock(chanidx); rc = chan_write_single_register_with_retry(chanidx, addr, regaddr, val); chan_unlock(chanidx); if( rc != 0 ){ log_dbg("%s, idx:%d, set month and day fail", __func__, idx); ret = -1; goto leave; } // set hour and minute regaddr = 0xEB39; val = hour*100 + minute; chan_lock(chanidx); rc = chan_write_single_register_with_retry(chanidx, addr, regaddr, val); chan_unlock(chanidx); if( rc != 0 ){ log_dbg("%s, idx:%d, set hour and minute fail", __func__, idx); ret = -1; goto leave; } // set second regaddr = 0xEB3A; val = second; chan_lock(chanidx); rc = chan_write_single_register_with_retry(chanidx, addr, regaddr, val); chan_unlock(chanidx); if( rc != 0 ){ log_dbg("%s, idx:%d, set second fail", __func__, idx); ret = -1; goto leave; } leave: return ret; }