#include "plt.h" int pws1_comm_init(int idx) { struct pws1_t *dev = &pws1[idx]; struct comm_t *comm = &dev->comm; comm_set_state(comm, COMMST_ERR); } int pws1_comm_reset(int idx) { struct pws1_t *dev = &pws1[idx]; struct comm_t *comm = &dev->comm; comm_set_state(comm, COMMST_NORMAL); comm_set_dac_param_en(comm, 1); } int pws1_comm_set_dev_startcmd(int idx) { int ret = 0; struct pws1_t *dev = &pws1[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 53900; int nb = 1; int trycnt = 0; unsigned short val; val = 1; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register(chanidx, addr, regaddr, val); chan_unlock(chanidx); if (ret < 0) { log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } int pws1_comm_set_dev_stopcmd(int idx) { int ret = 0; struct pws1_t *dev = &pws1[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 53901; int nb = 1; int trycnt = 0; unsigned short val; val = 1; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register(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 pws1_comm_set_dev_resetcmd(int idx) { int ret = 0; struct pws1_t *dev = &pws1[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 53903; int nb = 1; int trycnt = 0; unsigned short val; val = 1; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register(chanidx, addr, regaddr, val); chan_unlock(chanidx); if (ret < 0) { log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } // 0 on grid // 1 off grid int pws1_comm_set_grid_mode(int idx, signed short mode) { int ret = 0; struct pws1_t *dev = &pws1[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 53600; int nb = 1; int trycnt = 0; unsigned short val; val = (unsigned short)mode; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register(chanidx, addr, regaddr, val); chan_unlock(chanidx); if (ret < 0) { log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } // 0:ac dispatching // 1:dc dispatching // 2:String dispatching(active power) int pws1_comm_set_dispatching_mode(int idx, signed short mode) { int ret = 0; struct pws1_t *dev = &pws1[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 53601; int nb = 1; int trycnt = 0; unsigned short val; val = *((unsigned short *)&mode); // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register(chanidx, addr, regaddr, val); chan_unlock(chanidx); if (ret < 0) { log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } // 0:fixed active power // 1:Volt-watt // 2:freq-watt // 3:v-w&F-W int pws1_comm_set_active_power_control_mode(int idx, signed short mode) { int ret = 0; struct pws1_t *dev = &pws1[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 53636; int nb = 1; int trycnt = 0; unsigned short val; val = (unsigned short)mode; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register(chanidx, addr, regaddr, val); chan_unlock(chanidx); if (ret < 0) { log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } //+:chg //-:dhg int pws1_comm_set_active_power(int idx, double p) { int ret = 0; struct pws1_t *dev = &pws1[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 53622; int nb = 1; int trycnt = 0; short val; val = p * 10.0; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register(chanidx, addr, regaddr, *((unsigned short *)&val)); chan_unlock(chanidx); if (ret < 0) { log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } // status and faults static void pws1_comm_dac_53000(int idx) { unsigned short tab_us[128] = {0}; struct pws1_t *dev = &pws1[idx]; struct comm_t *comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; float *temp_f; int temp_i; if (comm_get_state(comm) != COMMST_NORMAL) { return; } nb = 32; start = 53000; 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 */ // fault alarm dev->status0.value = tab_us[53000 - start]; dev->status1.value = tab_us[53001 - start]; dev->status2.value = tab_us[53002 - start]; dev->status3.value = tab_us[53003 - start]; dev->status4.value = tab_us[53004 - start]; dev->status9.value = tab_us[53009 - start]; dev->status10.value = tab_us[53010 - start]; dev->status11.value = tab_us[53011 - start]; dev->status13.value = tab_us[53013 - start]; dev->status25.value = tab_us[53025 - start]; dev->status27.value = tab_us[53027 - start]; dev->status29.value = tab_us[53029 - start]; dev->status31.value = tab_us[53031 - start]; if (dev->status11.bits_val.pcs_init_status == 0) { dev->runState = PWS1_RUNSTAT_PCS_INIT; sprintf(dev->szrunState, "%s", "PCS init unfinished"); } else if (dev->status10.bits_val.on_off_status == 0) { dev->runState = PWS1_RUNSTAT_STOP; sprintf(dev->szrunState, "%s", "stop"); } else if (dev->status10.bits_val.on_off_status == 1 && dev->status13.bits_val.string1_dhg == 0 && dev->status13.bits_val.string1_chg == 0) { dev->runState = PWS1_RUNSTAT_IDLE; sprintf(dev->szrunState, "%s", "idle"); } else if (dev->status10.bits_val.on_off_status == 1 && dev->status13.bits_val.string1_dhg == 1 && dev->status13.bits_val.string1_chg == 0) { dev->runState = PWS1_RUNSTAT_DHG; sprintf(dev->szrunState, "%s", "dhg"); } else if (dev->status10.bits_val.on_off_status == 1 && dev->status13.bits_val.string1_dhg == 0 && dev->status13.bits_val.string1_chg == 1) { dev->runState = PWS1_RUNSTAT_CHG; sprintf(dev->szrunState, "%s", "chg"); } else { dev->runState = PWS1_RUNSTAT_UNKOWNING; sprintf(dev->szrunState, "%s", "unkowning"); } if (dev->status10.bits_val.on_grid_status == 1 && dev->status10.bits_val.off_grid_status == 0) { dev->runMode = PWS1_RUNMOD_ONGRID; sprintf(dev->szrunMode, "%s", "on grid"); } else if (dev->status10.bits_val.on_grid_status == 0 && dev->status10.bits_val.off_grid_status == 1) { dev->runMode = PWS1_RUNMOD_OFFGRID; sprintf(dev->szrunMode, "%s", "off grid"); } else { dev->runMode = PWS1_RUNMOD_UNKOWNING; sprintf(dev->szrunMode, "%s", "unkown"); } if (dev->status10.bits_val.local_manual_ctl == 1 && dev->status10.bits_val.local_auto_ctl == 0 && dev->status10.bits_val.remote_control == 0) { dev->cmdSrc = PWS1_CMD_SRC_LOCAL_MAN; sprintf(dev->szcmdSrc, "%s", "Local manual"); } else if (dev->status10.bits_val.local_manual_ctl == 0 && dev->status10.bits_val.local_auto_ctl == 1 && dev->status10.bits_val.remote_control == 0) { dev->cmdSrc = PWS1_CMD_SRC_LOCAL_AUTO; sprintf(dev->szcmdSrc, "%s", "Local manual"); } else if (dev->status10.bits_val.local_manual_ctl == 0 && dev->status10.bits_val.local_auto_ctl == 0 && dev->status10.bits_val.remote_control == 1) { dev->cmdSrc = PWS1_CMD_SRC_REMOTE; sprintf(dev->szcmdSrc, "%s", "remote EMS"); } else { dev->cmdSrc = PWS1_CMD_SRC_UNKOWNING; sprintf(dev->szcmdSrc, "%s", "unkowning"); } if (dev->status11.bits_val.ac_switch_closed == 1) { dev->DCbrokerState = 1; sprintf(dev->szDCbrokerState, "%s", "DC broker on"); } else { dev->DCbrokerState = 0; sprintf(dev->szDCbrokerState, "%s", "DC broker off"); } if (dev->status11.bits_val.alarm_status == 0) { dev->alarmstatus = 0; } else { dev->alarmstatus = 1; } if (dev->status11.bits_val.faults_status == 0) { dev->errstatus = 0; } else { dev->errstatus = 1; } } } // 0xF100 PCS internal config static void pws1_comm_dac_53200(int idx) { unsigned short tab_us[128] = {0}; struct pws1_t *dev = &pws1[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 = 57; start = 53200; 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 */ // Ul dev->Uab = (double)tab_us[53200 - start] * 0.1; dev->Ubc = (double)tab_us[53201 - start] * 0.1; dev->Uca = (double)tab_us[53202 - start] * 0.1; dev->Ia = (double)tab_us[53203 - start] * 0.1 - 1500.0; dev->Ib = (double)tab_us[53204 - start] * 0.1 - 1500.0; dev->Ib = (double)tab_us[53205 - start] * 0.1 - 1500.0; dev->grid_freq = (double)tab_us[53206 - start] * 0.01; dev->Pa = (double)tab_us[53209 - start] * 0.1 - 400.0; dev->Pb = (double)tab_us[53210 - start] * 0.1 - 400.0; dev->Pc = (double)tab_us[53211 - start] * 0.1 - 400.0; dev->Qa = (double)tab_us[53212 - start] * 0.1 - 400.0; dev->Qb = (double)tab_us[53213 - start] * 0.1 - 400.0; dev->Qc = (double)tab_us[53214 - start] * 0.1 - 400.0; dev->Sa = (double)tab_us[53215 - start] * 0.1 - 400.0; dev->Sb = (double)tab_us[53216 - start] * 0.1 - 400.0; dev->Sc = (double)tab_us[53217 - start] * 0.1 - 400.0; dev->Pfa = (double)tab_us[53218 - start] * 0.01 - 1.0; dev->Pfb = (double)tab_us[53219 - start] * 0.01 - 1.0; dev->Pfc = (double)tab_us[53220 - start] * 0.01 - 1.0; dev->module_temp = (double)tab_us[53221 - start] * 0.1 - 20.0; dev->ambient_temp = (double)tab_us[53223 - start] * 0.1 - 20.0; dev->Ps = (double)tab_us[53235 - start] * 0.1 - 1200.0; dev->Qs = (double)tab_us[53236 - start] * 0.1 - 1200.0; dev->Ss = (double)tab_us[53237 - start] * 0.1 - 1200.0; dev->Pfs = (double)tab_us[53238 - start] * 0.01 - 1.0; dev->chg_accu_energy_ac = (unsigned int)tab_us[53239 - start] << 16 + (unsigned int)tab_us[53240 - start]; dev->dhg_accu_energy_ac = (unsigned int)tab_us[53241 - start] << 16 + (unsigned int)tab_us[53242 - start]; dev->operate_capacity_max = (double)tab_us[53247 - start] * 0.01; dev->chg_daily_energy_ac = (double)tab_us[53248 - start]; dev->dhg_daily_energy_ac = (double)tab_us[53249 - start]; dev->Pdc = (double)tab_us[53250 - start] * 0.1 - 1500.0; dev->Udc = (double)(tab_us[53251 - start]) * 0.1; dev->Idc = (double)tab_us[53252 - start] * 0.1 - 2000.0; dev->chg_accu_energy_dc = (unsigned int)tab_us[53253 - start] << 16 + (unsigned int)tab_us[53254 - start]; dev->dhg_accu_energy_dc = (unsigned int)tab_us[53255 - start] << 16 + (unsigned int)tab_us[53256 - start]; } } static void pws1_comm_dac_53579(int idx) { unsigned short tab_us[128] = {0}; struct pws1_t *dev = &pws1[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 = 47; start = 53579; 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 */ memcpy((void *)dev->CabSN, (void *)&tab_us[53579 - start], 22); dev->MonitorSoftInerCode = tab_us[53590 - start]; dev->ACsoftInerCode = tab_us[53591 - start]; dev->U2softInerCode = tab_us[53593 - start]; dev->softwareV = tab_us[53593 - start]; } } const int reactive_p_set = 53623 - 53600; static void pws1_comm_dac_53600(int idx) { unsigned short tab_us[128] = {0}; struct pws1_t *dev = &pws1[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 = 65; start = 53600; 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->energy_dispatching_mode = *((signed short *)(&tab_us[53601 - start])); if (dev->energy_dispatching_mode == 0) { sprintf(dev->szEnergy_dispatching_mode, "%s", "AC dispatching"); } else if (dev->energy_dispatching_mode == 1) { sprintf(dev->szEnergy_dispatching_mode, "%s", "DC dispatching"); } else if (dev->energy_dispatching_mode == 2) { sprintf(dev->szEnergy_dispatching_mode, "%s", "String dispatching"); } else { sprintf(dev->szEnergy_dispatching_mode, "%s", "unkown dispatching"); } dev->start_up_mode = *((signed short *)(&tab_us[53602 - start])); if (dev->start_up_mode == 0) { sprintf(dev->szStart_up_mode, "%s", "auto startup"); } else if (dev->start_up_mode == 1) { sprintf(dev->szStart_up_mode, "%s", "manual startup"); } else { sprintf(dev->szStart_up_mode, "%s", "unkown startup"); } dev->reactive_power_cotrol_mode = *((signed short *)(&tab_us[53620 - start])); dev->Pf_setpoint = (double)(*((signed short *)(&tab_us[53621 - start]))) * 0.01; dev->active_p_set = (double)(*((signed short *)&tab_us[53622 - start])) * 0.1; // active power set dev->reactive_p_set = (double)(*((signed short *)&tab_us[reactive_p_set])) * 0.1; dev->power_change_mode = (signed short)(tab_us[53626 - start]); if (dev->power_change_mode == 0) { sprintf(dev->szPower_change_mode, "%s", "step"); } else if (dev->power_change_mode == 1) { sprintf(dev->szPower_change_mode, "%s", "ramp"); } else { sprintf(dev->szPower_change_mode, "%s", "unkown power change mode"); } dev->grid_reconnect_delay = *((signed short *)(&tab_us[53627 - start])); dev->offgrid_ac_voltage_regulation = (double)(*((signed short *)(&tab_us[53628 - start]))) * 0.01; dev->offgrid_ac_freq_regulation = (double)(*((signed short *)(&tab_us[53630 - start]))) * 0.01; dev->FVRT_limit_fun = *((signed short *)(&tab_us[53631 - start])); dev->FVRT_fun_enable = *((signed short *)(&tab_us[53632 - start])); dev->anti_islanding_enable = *((signed short *)(&tab_us[53633 - start])); dev->offgrid_ac_vol_startup_mode = *((signed short *)(&tab_us[53635 - start])); if (dev->offgrid_ac_vol_startup_mode == 0) { sprintf(dev->szOffgrid_ac_vol_startup_mode, "%s", "step"); } else if (dev->offgrid_ac_vol_startup_mode == 1) { sprintf(dev->szOffgrid_ac_vol_startup_mode, "%s", "soft-start"); } else { sprintf(dev->szOffgrid_ac_vol_startup_mode, "%s", "unkown"); } dev->active_power_control_mode = *((signed short *)(&tab_us[53636 - start])); if (dev->active_power_control_mode == 0) { sprintf(dev->szActive_power_control_mode, "%s", "fixed active power"); } else if (dev->active_power_control_mode == 1) { sprintf(dev->szActive_power_control_mode, "%s", "Volt-watt"); } else if (dev->active_power_control_mode == 2) { sprintf(dev->szActive_power_control_mode, "%s", "Freq-watt"); } else if (dev->active_power_control_mode == 3) { sprintf(dev->szActive_power_control_mode, "%s", "V-W&F-W"); } else { sprintf(dev->szActive_power_control_mode, "%s", "unkown"); } dev->RR_normal_ramp_rate = (double)tab_us[53638 - start] * 0.001; dev->SS_soft_start_ramp_rate = (double)tab_us[53639 - start] * 0.001; dev->dc_control_mode = *((signed short *)(&tab_us[53650 - start])); if (dev->dc_control_mode == 0) { sprintf(dev->szDc_control_mode, "%s", "fix current"); } else if (dev->dc_control_mode == 1) { sprintf(dev->szDc_control_mode, "%s", "fix power"); } else { sprintf(dev->szDc_control_mode, "%s", "unkown"); } dev->dc_current_set = (double)(*((signed short *)(&tab_us[53651 - start]))) * 0.1; dev->dc_pset = (double)(*((signed short *)(&tab_us[53652 - start]))) * 0.1; dev->dc_lower_v_threshold = (double)(*((signed short *)(&tab_us[53653 - start]))) * 0.1; dev->dc_end_of_dhg_v = (double)(*((signed short *)(&tab_us[53655 - start]))) * 0.1; dev->top_chg_v = (double)(*((signed short *)(&tab_us[53660 - start]))) * 0.1; dev->end_of_chg_current = (double)(*((signed short *)(&tab_us[53662 - start]))) * 0.1; dev->max_chg_current = (double)(*((signed short *)(&tab_us[53663 - start]))) * 0.1; dev->max_dhg_current = (double)(*((signed short *)(&tab_us[53664 - start]))) * 0.1; } } // power up one time static void pws1_comm_dac_53670(int idx) { unsigned short tab_us[128] = {0}; struct pws1_t *dev = &pws1[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 = 38; start = 53670; 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->ov_region1_boundary = (double)(*((signed short *)(&tab_us[53670 - start]))) * 0.01; dev->ov_region1_trip_time = (double)(*((signed short *)(&tab_us[53671 - start]))) * 0.01; dev->ov_region2_boundary = (double)(*((signed short *)(&tab_us[53672 - start]))) * 0.01; dev->ov_region2_trip_time = (double)(*((signed short *)(&tab_us[53673 - start]))) * 0.01; dev->uv_region1_boundary = (double)(*((signed short *)(&tab_us[53674 - start]))) * 0.01; dev->uv_region1_trip_time = (double)(*((signed short *)(&tab_us[53675 - start]))) * 0.01; dev->uv_region2_boundary = (double)(*((signed short *)(&tab_us[53676 - start]))) * 0.01; dev->uv_region2_trip_time = (double)(*((signed short *)(&tab_us[53677 - start]))) * 0.01; dev->of_region1_boundary = (double)(*((signed short *)(&tab_us[53700 - start]))) * 0.01; dev->of_region1_trip_time = (double)tab_us[53701 - start] * 0.01; dev->of_region2_boundary = (double)(*((signed short *)(&tab_us[53702 - start]))) * 0.01; dev->of_region2_trip_time = (double)tab_us[53703 - start] * 0.01; dev->uf_region1_boundary = (double)(*((signed short *)(&tab_us[53704 - start]))) * 0.01; dev->uf_region1_trip_time = (double)tab_us[53705 - start] * 0.01; dev->uf_region2_boundary = (double)(*((signed short *)(&tab_us[53706 - start]))) * 0.01; dev->uf_region2_trip_time = (double)tab_us[53707 - start] * 0.01; } } static void pws1_comm_dac_56000(int idx) { unsigned short tab_us[128] = {0}; struct pws1_t *dev = &pws1[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 = 38; start = 56000; 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->year = tab_us[56000 - start]; dev->month = tab_us[56001 - start]; dev->day = tab_us[56002 - start]; dev->hour = tab_us[56003 - start]; dev->minute = tab_us[56004 - start]; dev->second = tab_us[56005 - start]; dev->bms_comm_time_out = tab_us[56006 - start]; dev->rs485_comm_time_out = tab_us[56007 - start]; dev->tcp_comm_time_out = tab_us[56008 - start]; } } void pws1_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); pws1_comm_dac_53670(idx); } pws1_comm_dac_53000(idx); pws1_comm_dac_53200(idx); pws1_comm_dac_53579(idx); pws1_comm_dac_53600(idx); pws1_comm_dac_56000(idx); }