#include "n9.h" #include "plt.h" struct n9_t n9[N9_NBR_MAX + 1]; int n9_reset_bsytikchk(int idx) { n9[idx].bsytik.timer = 0; n9[idx].bsytik.timeout = 0; n9[idx].bsytik.chkcnt = 0; return 0; } // 0 : not timeout // 1 : timeout int n9_is_bsytikchk_timeout(int idx) { struct n9_t *dev = &n9[idx]; if (dev->bsytik.chken == 1) { return dev->bsytik.timeout; } else { return 0; } } int n9_set_bsytik_from_host(int idx) { n9[idx].bsytik.from_host++; return 0; } int n9_get_bsytikchk_from_host(int idx) { return n9[idx].bsytik.from_host++; } int n9_get_bsytikchk_en(int idx) { return n9[idx].bsytik.chken; } int n9_set_bsytikchk_en(int idx, int val) { n9[idx].bsytik.chken = val; return 0; } int n9_set_dac_param_en(int idx, int val) { struct n9_t *dev = &n9[1]; struct comm_t *comm = &dev->comm; comm_set_dac_param_en(comm, val); return 0; } static int n9_dbcb_0(void *para, int ncolumn, char **columnvalue, char *columnname[]) { int i; struct dbcbparam_t *pcbparam = (struct dbcbparam_t *)para; struct n9_t *dev = &n9[1]; pcbparam->nrow++; log_dbg("%s, ++, row:%d, col:%d", __func__, pcbparam->nrow, ncolumn); for (i = 0; i < ncolumn; i++) { if (strcmp("info", columnname[i]) == 0) { strcpy(dev->szinfo, columnvalue[i]); } else if (strcmp("adr", columnname[i]) == 0) { dev->comm.adr = atoi(columnvalue[i]); } else if (strcmp("chan_idx", columnname[i]) == 0) { dev->comm.chanidx = atoi(columnvalue[i]); } else if (strcmp("idx", columnname[i]) == 0) { dev->idx = atoi(columnvalue[i]); } else if (strcmp("devid", columnname[i]) == 0) { if (columnvalue[i] != NULL && strcmp(columnvalue[i], "") != 0) { strcpy(dev->szdev_id, columnvalue[i]); } else { log_dbg("%s, devid is null", __func__); } } } pcbparam->ret = 0; log_dbg("%s, --,ret:%d", __func__, pcbparam->ret); return 0; } int n9_get_cmd(int idx) { return n9[idx].cmd; } int n9_get_comm_st(int idx) { struct n9_t *dev = &n9[idx]; struct comm_t *comm = &dev->comm; return comm_get_state(comm); } void n9_reset_cmd(int idx) { n9[idx].cmd = CMD_SM_DONE; } int n9_get_state(int idx) { static int s = 0; if (n9[idx].sm.state != s) { // log_dbg("pcs new state : %d", n9[idx].sm.state); s = n9[idx].sm.state; } return n9[idx].sm.state; } char *n9_get_state_str(int idx) { return n9[idx].sm.szState; } int n9_get_step(int idx) { return n9[idx].sm.step; } int n9_get_tick(int idx) { return n9[idx].sm.tick; } double n9_get_tick_ave(int idx) { return n9[idx].sm.timing_ave; } double n9_get_tick_cur(int idx) { return n9[idx].sm.timing_cur; } double n9_get_tick_max(int idx) { return n9[idx].sm.timing_max; } char *n9_get_err_str(int idx) { return n9[idx].sm.szerr; } int n9_chk_state(int idx, int stat) { return n9_get_state(idx) == stat ? 0 : -1; } int n9_get_ap(int idx) { return n9[idx].pow.ap; } double n9_get_dcv(int idx) { return n9[idx].dc_v; } double n9_get_dcc(int idx) { return n9[idx].dc_c; } int n9_get_errstat(int idx) { return n9[idx].fault; } double n9_get_uab(int idx) { return n9[idx].Uab; } double n9_get_ubc(int idx) { return n9[idx].Ubc; } double n9_get_uac(int idx) { return n9[idx].Uca; } double n9_get_ua(int idx) { return n9[idx].Ua; } double n9_get_ub(int idx) { return n9[idx].Ub; } double n9_get_uc(int idx) { return n9[idx].Uc; } double n9_get_ia(int idx) { return n9[idx].Ia; } double n9_get_ib(int idx) { return n9[idx].Ib; } double n9_get_ic(int idx) { return n9[idx].Ic; } double n9_get_temp_igbt(int idx) { return n9[idx].t_igbt; } double n9_get_temp_env(int idx) { return n9[idx].t_env; } double n9_get_grid_freq(int idx) { return n9[idx].gridf; } char *n9_get_info_str(int idx) { return n9[idx].szinfo; } // char* n9_get_state_str( int idx) //{ // return n9[idx].sm.szstate; // } // int n9_get_state( int idx) //{ // return n9[idx].sm.state; // } int n9_get_dev_aps(int idx) { return n9[idx].Pset; } static void n9_update(int idx) { struct n9_t *dev = &n9[idx]; dev->pow.ap = dev->ap; } static void *n9_thrd_main(void *param) { struct n9_t *dev = &n9[1]; log_dbg("%s, idx:%d, ++", __func__, 1); n9_set_bsytikchk_en(1, 1); n9_sm_init(1); n9_comm_init(1); while (1) { n9_comm_dac(1); n9_sm(1); n9_update(1); usleep(10000); /* 10ms */ } log_dbg("%s, --", __func__); } static void *n9_thrd_aux(void *param) { int idx = 1; struct n9_t *dev = &n9[idx]; struct statemachine_t *sm = &dev->sm; log_dbg("%s, ++", __func__); while (1) { if (dev->bsytik.timer++ >= 10) { // chk every 1 second dev->bsytik.timer = 0; if (dev->bsytik.last_from_host != dev->bsytik.from_host) { // refresh dev->bsytik.last_from_host = dev->bsytik.from_host; dev->bsytik.chkcnt = 0; } else { // counting if (dev->bsytik.chkcnt++ >= 2) { // 5s dev->bsytik.timeout = 1; dev->bsytik.chkcnt = 0; } } } static int cnt = 0; if (cnt < 1 && mqtt_get_state() == SMST_READY) { cnt++; if (idx == 1) { cloud.pcs_init = 0; } char buf[4096] = {0}; n9_get_init_data(ctn_get_idx_in_ess(), 1, buf); cloud_send_init(buf); } usleep(100000); /* 100ms */ } log_dbg("%s, --", __func__); } int n9_init() { pthread_t thrd; int ret = 0; int result; char *errmsg = NULL; char sql[1024]; struct dbcbparam_t cbparam; sqlite3 *db = NULL; struct n9_t *dev = &n9[1]; log_dbg("%s, ++", __func__); plt_lock_ctndb(); db = plt_get_ctndb(); sprintf(sql, "select * from n9"); cbparam.nrow = 0; result = sqlite3_exec(db, sql, n9_dbcb_0, (void *)&cbparam, &errmsg); plt_unlock_ctndb(); if (result != SQLITE_OK) { log_dbg("%s, result != SQLITE_OK, result:%d", __func__, result); ret = -1; } else if (cbparam.ret != 0) { log_dbg("%s, cbparam.ret != 0, %d", __func__, cbparam.ret); ret = -2; } else if (cbparam.nrow != 1) { log_dbg("%s, cbparam.nrow != 1, %d", __func__, cbparam.nrow); ret = -3; } else { db = plt_get_devdb(); cbparam.nrow = 0; plt_lock_devdb(); sprintf(sql, "select * from n9"); result = sqlite3_exec(db, sql, n9_dbcb_0, (void *)&cbparam, &errmsg); plt_unlock_devdb(); if (strcmp(n9[1].szdev_id, "") == 0) { if (get_snow_id(n9[1].szdev_id) != 0) { ret = -4; } else { char sql[1024]; char *errmsg = NULL; sprintf(sql, "update n9 set devid=\"%s\" where idx=%d", n9[1].szdev_id, n9[1].idx); plt_lock_devdb(); int rc = sqlite3_exec(db, sql, NULL, NULL, &errmsg); plt_unlock_devdb(); if (rc != SQLITE_OK) { log_dbg("%s, failed to update level device id:%s", __func__, errmsg); ret = -4; goto leave; } else { log_dbg("%s, update device id:%s", __func__, gt[1].szdev_id); } } } if (pthread_create(&thrd, NULL, n9_thrd_main, NULL) != 0) { log_dbg("%s, create n9 thrd main fail", __func__); ret = -1; } else if (pthread_create(&thrd, NULL, n9_thrd_aux, NULL) != 0) { log_dbg("%s, create n9 thrd aux fail", __func__); ret = -1; } } leave: log_dbg("%s, --, ret:%d", __func__, ret); return ret; } int n9_send_sm_cmd(int idx, int val) { // print_stack(); int ret = 0; struct n9_t *dev = &n9[idx]; dev->cmd = val; log_dbg("%s, idx:%d, cmd:%d, ret:%d", __func__, idx, val, ret); return ret; } int n9_get_runmod(int idx) { return n9[idx].module_run_mode; } int n9_get_runstat(int idx) { return n9[idx].runstate; } char *n9_get_runstat_str(int idx) { return n9[idx].runstate_str; } int n9_set_aps(int idx, int aps) { struct n9_t *dev = &n9[idx]; int ret = 0; dev->pow.last_aps = dev->pow.aps; dev->pow.aps = aps; log_dbg("%s, idx:%d, aps:%d, last_aps:%d", __func__, idx, dev->pow.aps, dev->pow.last_aps); return ret; } int n9_reset_aps(int idx) { struct n9_t *dev = &n9[idx]; int ret = 0; dev->pow.last_aps = 0; dev->pow.aps = 0; // log_dbg( "%s, idx:%d, val:%d, ret:%d", __func__, idx, aps, ret); return ret; } int n9_get_aps(int idx) { return n9[idx].pow.aps; } int n9_get_last_aps(int idx) { return n9[idx].pow.last_aps; } int n9_is_aps_changed(int idx) { return (n9[idx].pow.aps != n9[idx].pow.last_aps) ? 1 : 0; } int n9_get_chan_idx(int idx) { return n9[idx].comm.chanidx; } int n9_get_adr(int idx) { return n9[idx].comm.adr; } char *n9_get_comm_state_str(int idx) { return n9[idx].comm.szState; } double n9_get_dac_ave(int idx) { return n9[idx].comm.dac.timing_ave; } double n9_get_dac_cur(int idx) { return n9[idx].comm.dac.timing_cur; } double n9_get_dac_max(int idx) { return n9[idx].comm.dac.timing_max; } unsigned short *n9_get_faults(int idx) { return n9[idx].faults; } int n9_get_dac_param_en(int idx) { return n9[idx].comm.dac.param_en; } // char* n9_get_info_str(int idx) //{ // return n9[idx].szinfo; // } double n9_get_chg_e_total(int idx) { return n9[idx].chg_power_total_ac; } double n9_get_dhg_e_total(int idx) { return n9[idx].dhg_power_total_ac; } struct n9_t *n9_get_all_data_ptr() { return n9; } int n9_get_tool_data(int idx, char *buf) { if (idx < 1 || idx > N9_NBR_MAX || buf == NULL) { return -1; } struct n9_t *dev = &n9[idx]; struct statemachine_t *sm = &dev->sm; struct comm_t *comm = &dev->comm; char temp_buf[8192]; int i = 0; sm_get_summary(sm, temp_buf, sizeof(temp_buf)); sprintf(buf, "%s ", temp_buf); comm_get_summary(comm, temp_buf, sizeof(temp_buf)); strcat(buf, temp_buf); sprintf(temp_buf, "bsytik_from_host:%03d timeout:%d en:%d\n", dev->bsytik.from_host, dev->bsytik.timeout, dev->bsytik.chken); strcat(buf, temp_buf); // 0xED00 sprintf(temp_buf, "dev id :%s runstat:" L_GREEN "%s" NONE " dc_v:" L_GREEN "%.1f" NONE ", dc_c:%.1f, grid_freq:%.2f, ua:%.1f ub:%.1f uc:%.1f ia:%.1f ib:%.1f ic:%.1f,\ ap:" L_GREEN "%.1f" NONE " dc_ap:%.1f, day_chg:%d dhg:%d, total_chg:%d dhg:%d, igbt_temp :%.1f env:%.1f, errstatus:" L_GREEN "%d" NONE "\n", dev->szdev_id, dev->runstate_str, dev->dc_v, dev->dc_c, dev->gridf, dev->Ua, dev->Ub, dev->Uc, dev->Ia, dev->Ib, dev->Ic, dev->ap, dev->dc_ap, dev->chg_power_day_sum_ac, dev->dhg_power_day_sum_ac, dev->chg_power_total_ac, dev->dhg_power_total_ac, dev->t_igbt, dev->t_env, dev->fault); strcat(buf, temp_buf); // 0x0E14 and 0x0F14 strcat(buf, L_GREEN "Faults: " NONE); for (i = 0; i < 8; i++) { if (dev->faults[i] != 0) { sprintf(temp_buf, L_GREEN "%d:" BYTE_TO_BINARY_PATTERN " ", i + 1, BYTE_TO_BINARY(dev->faults[i])); } else { sprintf(temp_buf, "%d:" BYTE_TO_BINARY_PATTERN " ", i + 1, BYTE_TO_BINARY(dev->faults[i])); } strcat(buf, temp_buf); } strcat(buf, "\n"); sprintf(temp_buf, " DC ovp:%.1f,uvp:%.1f,ocp:%.1f AC ovp:%.1f,uvp:%.1f,ocp:%.1f\n", dev->Ubus_ovp, dev->Ubus_uvp, dev->Ubus_ocp, dev->AC_ovp, dev->AC_uvp, dev->AC_ocp); strcat(buf, temp_buf); } void printBits(size_t const size, void const *const ptr, char *prefix, char *buf) { unsigned char *b = (unsigned char *)ptr; unsigned char byte; int i, j; char temp[4096] = {0}; for (i = size - 1; i >= 0; i--) { for (j = 7; j >= 0; j--) { byte = (b[i] >> j) & 1; sprintf(temp, "'%sbit_%d' : %u", prefix, i * 8 + (j + 1), byte); if (j != 0) strcat(temp, ","); strcat(buf, temp); } } } int n9_get_tbmqtt_data_inteval_30s(int idx, char *buf) { sprintf(buf, "'pcs_runstat':'%s','pcs_errstat':%d,'pcs_state':'%s'," "'pcs_fault1':'" BYTE_TO_BINARY_PATTERN "','pcs_fault2':'" BYTE_TO_BINARY_PATTERN "','pcs_fault3':'" BYTE_TO_BINARY_PATTERN "','pcs_fault4':'" BYTE_TO_BINARY_PATTERN "','pcs_fault5':'" BYTE_TO_BINARY_PATTERN "','pcs_fault6':'" BYTE_TO_BINARY_PATTERN "','pcs_fault7':'" BYTE_TO_BINARY_PATTERN "','pcs_fault8':'" BYTE_TO_BINARY_PATTERN "'", n9_get_runstat_str(idx), n9_get_errstat(idx), n9_get_state_str(idx), BYTE_TO_BINARY(n9[idx].faults[0]), BYTE_TO_BINARY(n9[idx].faults[1]), BYTE_TO_BINARY(n9[idx].faults[2]), BYTE_TO_BINARY(n9[idx].faults[3]), BYTE_TO_BINARY(n9[idx].faults[4]), BYTE_TO_BINARY(n9[idx].faults[5]), BYTE_TO_BINARY(n9[idx].faults[6]), BYTE_TO_BINARY(n9[idx].faults[7])); } int n9_get_tbmqtt_data_inteval_60s(int idx, char *buf) { struct n9_t *dev = &n9[idx]; sprintf(buf, "'pcs_ua':%.1f, 'pcs_ub':%.1f, 'pcs_uc':%.1f,\ 'pcs_uab':%.1f, 'pcs_ubc':%.1f, 'pcs_uca':%.1f,\ 'pcs_ia':%.1f, 'pcs_ib':%.1f, 'pcs_ic':%.1f,\ 'pcs_ap':%.1f,'pcs_rap':%.1f,'pcs_pf':%.1f,\ 'pcs_dcv':%.1f,'pcs_dcc':%.1f,'pcs_gf':%.1f,\ 'pcs_t_igbt':%.1f, 'pcs_t_env':%.1f, \ 'pcs_pos_bus_v':%.1f, 'pcs_neg_bus_v':%.1f, 'pcs_bat_v':%.1f, 'pcs_bat_c':%.1f, 'pcs_dcp':%.1f", n9_get_ua(idx), n9_get_ub(idx), n9_get_uc(idx), dev->Uab, dev->Ubc, dev->Uca, n9_get_ia(idx), n9_get_ib(idx), n9_get_ic(idx), dev->ap, dev->Qsum, dev->Pfactor, dev->dc_v, dev->dc_c, dev->gridf, n9_get_temp_igbt(idx), n9_get_temp_env(idx), dev->dc_v_pos, dev->dc_v_neg, dev->bat_v, dev->bat_c, dev->dc_ap); } int n9_get_tbmqtt_data_half_hour(int idx, char *buf) { sprintf(buf, "'pcs_chg_day_ac':%d, 'pcs_dhg_day_ac':%d, 'pcs_chg_total_ac':%d, 'pcs_dhg_total_ac':%d," "'pcs_chg_day_dc':%d, 'pcs_dhg_day_dc':%d, 'pcs_chg_total_dc':%d, 'pcs_dhg_total_dc':%d", n9[idx].chg_power_day_sum_ac, n9[idx].dhg_power_day_sum_ac, n9[idx].chg_power_total_ac, n9[idx].dhg_power_total_ac, n9[idx].chg_power_day_sum_dc, n9[idx].dhg_power_day_sum_dc, n9[idx].chg_power_total_dc, n9[idx].dhg_power_total_dc); } int n9_get_init_data(int ctn_idx, int idx, char *buf) { sprintf(buf, "{\"device_id\":\"%s\", \"type\":2, \"idx\":%d, \"pid\":\"%s\", \"config\":{ \ \"chan_idx\":%d, \"adr\":%d}}", n9[idx].szdev_id, idx, ctn_get_dev_id(), n9[idx].comm.chanidx, n9[idx].comm.adr); return 0; } int n9_get_cloud_data_5_seconds(int ctn_idx, int idx, char *buf) { sprintf(buf, "{\"device_id\":\"%s\", \"type\":2, \"state\":\"%d\", \"runstat\":%d, \"dcv\":%.1f, \"dcc\":%.1f,\ \"errstat\":%d, \"ap\":%d}", n9[idx].szdev_id, n9_get_state(idx), n9_get_runstat(idx), n9_get_dcv(idx), n9_get_dcc(idx), n9_get_errstat(idx), n9_get_ap(idx)); } int n9_get_cloud_data_60_seconds(int cnt_idx, int idx, char *buf) { struct n9_t *dev = &n9[idx]; sprintf(buf, "{\"device_id\":\"%s\", \"type\":2, \"state\":\"%d\", \"uab\":%.1f, \"ubc\":%.1f, \"uca\":%.1f, \"ua\":%.1f, \"ub\":%.1f, \"uc\":%.1f,\ \"ia\":%.1f, \"ib\":%.1f, \"ic\":%.1f,\"t_a\":%.1f, \"t_env\":%.1f, \"rap\":%.1f, \"gf\":%.1f, \"pf\":%.1f}", dev->szdev_id, n9_get_state(idx), dev->Uab, dev->Ubc, dev->Uca, n9_get_ua(idx), n9_get_ub(idx), n9_get_uc(idx), n9_get_ia(idx), n9_get_ib(idx), n9_get_ic(idx), n9_get_temp_igbt(idx), n9_get_temp_env(idx), dev->Ssum, n9_get_grid_freq(idx), dev->Pfactor); } int n9_get_modbus_data(int idx, unsigned short *data) { struct n9_t *dev = &n9[idx]; data[0] = (unsigned short)DEVM_N9; data[1] = (unsigned short)1; data[2] = (unsigned short)dev->sm.state; data[3] = (unsigned short)dev->sm.step; data[4] = (unsigned short)dev->sm.err; data[5] = (unsigned short)dev->comm.adr; data[6] = (unsigned short)dev->comm.state; data[7] = (unsigned short)dev->dsp_ver[0]; data[8] = (unsigned short)dev->dsp_ver[1]; data[9] = (unsigned short)dev->dsp_ver[2]; data[10] = (unsigned short)dev->cpld_ver[0]; data[11] = (unsigned short)dev->cpld_ver[1]; data[12] = (unsigned short)dev->cpld_ver[2]; data[13] = (unsigned short)dev->workmode; data[14] = (unsigned short)dev->Ua * 10; data[15] = (unsigned short)dev->Ub * 10; data[16] = (unsigned short)dev->Uc * 10; data[17] = (unsigned short)dev->Ia * 10; data[18] = (unsigned short)dev->Ib * 10; data[19] = (unsigned short)dev->Ic * 10; data[20] = (unsigned short)dev->dc_v * 10; data[21] = (unsigned short)dev->bat_v * 10; data[22] = (unsigned short)dev->bat_c * 10; data[23] = (unsigned short)dev->gridf * 100; data[24] = (unsigned short)dev->ap * 10; data[25] = (unsigned short)dev->dc_ap * 10; data[26] = (unsigned short)dev->c_dhg_mode; data[27] = (unsigned short)dev->bat_ovp * 10; data[28] = (unsigned short)dev->bat_uvp * 10; data[29] = (unsigned short)dev->Ubus_ovp * 10; data[30] = (unsigned short)dev->Ubus_uvp * 10; data[31] = (unsigned short)dev->t_igbt * 10; data[32] = (unsigned short)dev->faults[0]; data[33] = (unsigned short)dev->faults[1]; data[34] = (unsigned short)dev->faults[2]; data[35] = (unsigned short)dev->faults[3]; data[36] = (unsigned short)dev->faults[4]; data[37] = (unsigned short)dev->faults[5]; data[38] = (unsigned short)dev->faults[6]; data[39] = (unsigned short)dev->faults[7]; data[40] = (unsigned short)dev->Pset; data[41] = (unsigned short)dev->Ila * 10; data[42] = (unsigned short)dev->Ilb * 10; data[43] = (unsigned short)dev->Ilc * 10; data[44] = (unsigned short)dev->Pa * 10; data[45] = (unsigned short)dev->Pb * 10; data[46] = (unsigned short)dev->Pc * 10; data[47] = (unsigned short)dev->Sa * 10; data[48] = (unsigned short)dev->Sb * 10; data[49] = (unsigned short)dev->Sc * 10; data[50] = (unsigned short)dev->Qa * 10; data[51] = (unsigned short)dev->Qb * 10; data[52] = (unsigned short)dev->Qc * 10; data[53] = (unsigned short)dev->ap * 10; data[54] = (unsigned short)dev->Ssum * 10; data[55] = (unsigned short)dev->Qsum * 10; data[56] = (unsigned short)dev->Pfactor * 100; data[57] = (unsigned short)dev->dc_v_pos * 10; data[58] = (unsigned short)dev->dc_v_neg * 10; data[59] = (unsigned short)dev->dc_ap * 10; data[60] = (unsigned short)dev->dc_c * 10; data[61] = (unsigned short)dev->Uab * 10; data[62] = (unsigned short)dev->Ubc * 10; data[63] = (unsigned short)dev->Uca * 10; data[64] = (unsigned short)dev->t_env * 10; return 0; } int n9_is_run(int idx) { return (n9[idx].runstate == N9_RUNSTAT_RUN); } int n9_sync_clock(int idx, int year, int month, int day, int hour, int minute, int second) { int ret = 0; struct n9_t *dev = &n9[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start = 0x1020; int quantity = 6; unsigned short values[6] = {0}; values[0] = year; values[1] = month; values[2] = day; values[3] = hour; values[4] = minute; values[5] = second; chan_lock(chanidx); ret = chan_write_multi_registers(chanidx, addr, start, quantity, values); chan_unlock(chanidx); if (ret < 0) { log_dbg("%s, idx:%d, fail", __func__, idx); } else { log_dbg("%s, idx:%d, success", __func__, idx); } return ret; }