#include "zh200.h" #include "plt.h" struct zh200_t zh200[ZH200_NBR_MAX + 1]; int zh200_enable_pcs_bsytiksnd(int idx) { zh200[idx].pcstik.en = 1; return 0; } int zh200_disable_pcs_bsytiksnd(int idx) { zh200[idx].pcstik.en = 0; return 0; } int zh200_get_pcs_bsytiksnd_en(int idx) { return zh200[idx].pcstik.en; } int zh200_enable_bms_bsytiksnd(int idx) { zh200[idx].bmstik.en = 1; return 0; } int zh200_disable_bms_bsytiksnd(int idx) { zh200[idx].bmstik.en = 0; return 0; } int zh200_get_bms_bsytiksnd_en(int idx) { return zh200[idx].bmstik.en; } int zh200_reset_bsytikchk(int idx) { zh200[idx].bsytik.timer = 0; zh200[idx].bsytik.timeout = 0; zh200[idx].bsytik.chkcnt = 0; return 0; } int zh200_enable_bsytikchk(int idx) { zh200[idx].bsytik.en = 1; return 0; } int zh200_disable_bsytikchk(int idx) { zh200[idx].bsytik.en = 0; return 0; } int zh200_get_bsytikchk_en(int idx) { return zh200[idx].bsytik.en; } int zh200_get_bsytikchk_from_host(int idx) { return zh200[idx].bsytik.from_host; } int zh200_get_bsytikchk_timeout(int idx) { return zh200[idx].bsytik.timeout; } int zh200_is_enable_bsytikchk(int idx) { return zh200[idx].bsytik.en; } static double zh200_get_timeofday() { struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); return (double)tv.tv_sec * 1000 + (double)tv.tv_usec / 1000; } static int zh200_dbcb_0(void *para, int ncolumn, char **columnvalue, char *columnname[]) { int i; struct dbcbparam_t *pcbparam = (struct dbcbparam_t *)para; struct zh200_t *dev = &zh200[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("chan_idx", columnname[i]) == 0) { dev->chan_idx = atoi(columnvalue[i]); } else if (strcmp("norm_cap", columnname[i]) == 0) { dev->pow.norm_cap = atoi(columnvalue[i]); } else if (strcmp("norm_pow", columnname[i]) == 0) { dev->pow.norm_pow = atoi(columnvalue[i]); } else if (strcmp("min_pow", columnname[i]) == 0) { dev->pow.min_pow = atoi(columnvalue[i]); } else if (strcmp("socc", columnname[i]) == 0) { dev->socc = atof(columnvalue[i]); } else if (strcmp("socd", columnname[i]) == 0) { dev->socd = atof(columnvalue[i]); } else if (strcmp("max_v", columnname[i]) == 0) { dev->max_v = atof(columnvalue[i]); } else if (strcmp("min_v", columnname[i]) == 0) { dev->min_v = atof(columnvalue[i]); } else if (strcmp("cell_otp", columnname[i]) == 0) { dev->cell_otp = atoi(columnvalue[i]); } else if (strcmp("cell_utp", columnname[i]) == 0) { dev->cell_utp = atoi(columnvalue[i]); } else if (strcmp("modbus_tcp_slave_port", columnname[i]) == 0) { dev->modbus_tcp_slave_port = atoi(columnvalue[i]); } else if (strcmp("modbus_tcp_slave_port_EMA", columnname[i]) == 0) { dev->modbus_tcp_slave_port_EMA = 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 { dev->szdev_id[0] = 0; log_dbg("%s, devid is null", __func__); } } } pcbparam->ret = 0; log_dbg("%s, --,ret:%d", __func__, pcbparam->ret); return 0; } void zh200_set_state(int idx, int state, int err) { sm_set_state(&zh200[idx].sm, state, err); } int zh200_get_state(int idx) { return zh200[idx].sm.state; } int zh200_get_step(int idx) { return zh200[idx].sm.step; } int zh200_get_tick(int idx) { return zh200[idx].sm.tick; } double zh200_get_tick_ave(int idx) { return zh200[idx].sm.timing_ave; } double zh200_get_tick_cur(int idx) { return zh200[idx].sm.timing_cur; } double zh200_get_tick_max(int idx) { return zh200[idx].sm.timing_max; } char *zh200_get_state_str(int idx) { return zh200[idx].sm.szState; } char *zh200_get_err_str(int idx) { return zh200[idx].sm.szerr; } int zh200_get_err(int idx) { return zh200[idx].sm.err; } int zh200_set_aps(int idx, int aps) { struct zh200_t *dev = &zh200[idx]; int ret = 0; dev->pow.last_aps = dev->pow.aps; dev->pow.aps = aps; log_dbg("%s, idx:%d, val:%d, ret:%d", __func__, idx, aps, ret); return ret; } int zh200_reset_aps(int idx) { struct zh200_t *dev = &zh200[idx]; int ret = 0; dev->pow.last_aps = 0; dev->pow.aps = 0; return ret; } int zh200_get_ap(int idx) { return zh200[idx].pow.ap; } int zh200_get_dhgable(int idx) { return zh200[idx].pow.bdhgable; } void zh200_set_dhgable(int idx, int val) { zh200[idx].pow.bdhgable = val; } int zh200_get_chgable(int idx) { return zh200[idx].pow.bchgable; } void zh200_set_chgable(int idx, int val) { zh200[idx].pow.bchgable = val; } int zh200_get_aps(int idx) { return zh200[idx].pow.aps; } int zh200_get_last_aps(int idx) { return zh200[idx].pow.last_aps; } double zh200_get_soc(int idx) { return zh200[idx].pow.soc; } double zh200_get_soh(int idx) { return zh200[idx].pow.soh; } int zh200_get_norm_cap(int idx) { return zh200[idx].pow.norm_cap; } int zh200_get_norm_pow(int idx) { return zh200[idx].pow.norm_pow; } int zh200_get_min_pow(int idx) { return zh200[idx].pow.min_pow; } int zh200_send_cmd(int idx, int cmd) { int ret = 0; zh200[idx].cmd = cmd; log_dbg("%s, idx:%d, cmd:%d, ret:%d", __func__, idx, cmd, ret); return ret; } /************************************* static void zh200_usleep(unsigned int nusecs) { struct timeval tval; tval.tv_sec = nusecs / 1000000; tval.tv_usec = nusecs % 1000000; select(0, NULL, NULL, NULL, &tval); } *************************************/ static void zh200_update(int idx) { struct zh200_t *dev = &zh200[idx]; struct statemachine_t *sm = &dev->sm; dev->pow.ap = pcs_get_ap(); dev->pow.soc = pack_get_soc(); dev->pow.soh = pack_get_soh(); } static void zh200_aux(int idx) { struct zh200_t *dev = &zh200[idx]; struct statemachine_t *sm = &dev->sm; if (dev->bsytik.timer++ >= 100) { dev->bsytik.timer = 0; // log_dbg("%s, idx:%d, from_host:%d, last_from_host:%d", __func__, idx, dev->bsytik.from_host, dev->bsytik.last_from_host); if (dev->bsytik.last_from_host != dev->bsytik.from_host) { dev->bsytik.last_from_host = dev->bsytik.from_host; dev->bsytik.chkcnt = 0; } else { if (dev->bsytik.chkcnt++ >= 10) { dev->bsytik.timeout = 1; } } // log_dbg("%s, idx:%d, from_host:%d, last_from_host:%d, chk count:%d, timeout:%d", __func__, idx, dev->bsytik.from_host, dev->bsytik.last_from_host, dev->bsytik.chkcnt, dev->bsytik.timeout); } if (zh200_get_pcs_bsytiksnd_en(idx)) { if (dev->pcstik.timer++ >= 100) { // 1s dev->pcstik.timer = 0; pcs_set_bsytik(); } } if (zh200_get_bms_bsytiksnd_en(idx)) { if (dev->bmstik.timer++ >= 100) { // 1s dev->bmstik.timer = 0; pack_set_bsytik(); } } static int cnt = 0; if (cnt < 1 && mqtt_get_state() == SMST_READY) { cnt++; if (idx == 1) { cloud.sys_init = 0; } char buf[4096] = {0}; zh200_get_init_data(1, buf); cloud_send_init(buf); } } static void *zh200_thrd_main(void *param) { struct zh200_t *dev = &zh200[1]; log_dbg("%s, ++", __func__); zh200_set_dhgable(1, 1); zh200_set_chgable(1, 1); zh200_disable_bsytikchk(1); // cyx : 默认不开启,只有当 9527 端口连上时 zh200_disable_pcs_bsytiksnd(1); zh200_disable_bms_bsytiksnd(1); pack_set_bsytikchk_en(1); zh200_sm_init(1); while (1) { zh200_sm(1); zh200_update(1); zh200_aux(1); usleep(10000); /* 10ms */ } log_dbg("%s, --", __func__); return NULL; } // static void zh200_task(int signo){ // zh200_sm( 1 ); // } // static void zh200_init_sigaction(){ // struct sigaction act; // act.sa_handler = zh200_task; // act.sa_flags = 0; // sigemptyset(&act.sa_mask); // sigaction(SIGPROF,&act,NULL); //设置信号 SIGPROF 的处理函数为 print_info // } // static void zh200_init_timer() //{ // struct itimerval value; // value.it_value.tv_sec = 0; // value.it_value.tv_usec = 10000; // value.it_interval=value.it_value; // setitimer(ITIMER_PROF,&value,NULL); // } /******************************************** static int zh200_init_timer2() { struct sigevent evp; struct itimerspec ts; timer_t timer; int ret; memset(&evp, 0, sizeof(evp)); evp.sigev_value.sival_ptr = &timer; evp.sigev_notify = SIGEV_THREAD; evp.sigev_notify_function = zh200_task; evp.sigev_value.sival_int = 3; //作为handle()的参数 ret = timer_create(CLOCK_REALTIME, &evp, &timer); if( ret){ perror("timer_create"); } ts.it_interval.tv_sec = 0; ts.it_interval.tv_nsec = 10000000; ts.it_value.tv_sec = 0; ts.it_value.tv_nsec = 10000000; ret = timer_settime(timer, TIMER_ABSTIME, &ts, NULL); if( ret ) { perror("timer_settime"); } } *************************************************/ int zh200_get_cmd(int idx) { return zh200[idx].cmd; } void zh200_reset_cmd(int idx) { zh200[idx].cmd = CMD_SM_DONE; } int zh200_init(void) { pthread_t thrd; char buf[32]; int result; char *errmsg = NULL; sqlite3 *db = NULL; char sql[1024]; struct dbcbparam_t cbparam; int ret = 0; struct zh200_t *dev = &zh200[1]; log_dbg("%s, ++", __func__); plt_lock_ctndb(); db = plt_get_ctndb(); sprintf(sql, "select * from zh200"); cbparam.nrow = 0; result = sqlite3_exec(db, sql, zh200_dbcb_0, (void *)&cbparam, &errmsg); plt_unlock_ctndb(); if (result != SQLITE_OK) { log_dbg("%s, result != SQLITE_OK : %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 zh200"); result = sqlite3_exec(db, sql, zh200_dbcb_0, (void *)&cbparam, &errmsg); plt_unlock_devdb(); for (int i = 1; i <= 1; ++i) { if (strcmp(zh200[i].szdev_id, "") == 0) { if (get_snow_id(zh200[i].szdev_id) != 0) { ret = -4; } else { char sql[1024]; char *errmsg = NULL; sprintf(sql, "update zh200 set devid=\"%s\" where idx=%d", zh200[i].szdev_id, zh200[i].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__, zh200[i].szdev_id); } } } } // chan_set_mbs(dev->chan_idx, DEVM_ZH200, 1); // chan_set_en(dev->chan_idx, 1); if (pthread_create(&thrd, NULL, zh200_thrd_main, NULL) != 0) { log_dbg("%s, create zh200 thrd main fail", __func__); ret = -1; } } leave: log_dbg("%s, --, ret:%d", __func__, ret); return ret; } int zh200_is_aps_changed(int idx) { return (zh200[idx].pow.aps != zh200[idx].pow.last_aps) ? 1 : 0; } int zh200_set_socd(int idx, double val) { zh200[idx].socd = val; return 0; } int zh200_set_socc(int idx, double val) { zh200[idx].socc = val; return 0; } double zh200_get_socd(int idx) { return zh200[idx].socd; } double zh200_get_socc(int idx) { return zh200[idx].socc; } int zh200_get_cell_otp(int idx) { return zh200[idx].cell_otp; } int zh200_get_cell_utp(int idx) { return zh200[idx].cell_utp; } int zh200_cfg_save_socc(int idx) { sqlite3 *db = NULL; char sql[1024]; int result = 0; plt_lock_ctndb(); db = plt_get_ctndb(); sprintf(sql, "update zh200 set socc=%d where idx=1", (int)zh200_get_socc(idx)); result = sqlite3_exec(db, sql, NULL, NULL, NULL); plt_unlock_ctndb(); if (result == SQLITE_OK) { return 0; } else { return -1; } } int zh200_cfg_save_socd(int idx) { sqlite3 *db = NULL; char sql[1024]; int result = 0; plt_lock_ctndb(); db = plt_get_ctndb(); sprintf(sql, "update zh200 set socd=%d where idx=1", (int)zh200_get_socd(idx)); result = sqlite3_exec(db, sql, NULL, NULL, NULL); plt_unlock_ctndb(); if (result == SQLITE_OK) { return 0; } else { return -1; } } int zh200_get_tool_data(int idx, char *buf) { struct zh200_t *dev = &zh200[idx]; struct statemachine_t *sm = &dev->sm; char buf_temp[1024]; if (idx < 1 || idx > ZH200_NBR_MAX) return -1; sprintf(buf, "dev id :%s norm_cap:%d norm_pow:%d min_pow:%d\n", dev->szdev_id, dev->pow.norm_cap, dev->pow.norm_pow, dev->pow.min_pow); sm_get_summary(sm, buf_temp, sizeof(buf_temp)); strcat(buf, buf_temp); sprintf(buf_temp, " ap:" L_GREEN "%d" NONE " aps:%d soc:" L_GREEN "%.1f" NONE " dhgable:%d chgable:%d socd:%.1f socc:%.1f cell_otp:%d utp:%d min_v:%.1f max_v:%.1f\n", dev->pow.ap, dev->pow.aps, dev->pow.soc, dev->pow.bdhgable, dev->pow.bchgable, dev->socd, dev->socc, dev->cell_otp, dev->cell_utp, dev->min_v, dev->max_v); strcat(buf, buf_temp); sprintf(buf_temp, " bsytik_en:%d from_host:%03d tiemout:%d pcs_bsytik_en:%d\n", dev->bsytik.en, dev->bsytik.from_host, dev->bsytik.timeout, dev->pcstik.en); strcat(buf, buf_temp); return 0; } unsigned short zh200_get_cmd_param1(int idx) { return zh200[idx].cmdpara[0]; } unsigned short zh200_get_cmd_param2(int idx) { return zh200[idx].cmdpara[1]; } unsigned short zh200_get_cmd_param3(int idx) { return zh200[idx].cmdpara[2]; } unsigned short zh200_get_cmd_param4(int idx) { return zh200[idx].cmdpara[3]; } int zh200_set_cmd(int idx, int cmd) { zh200[idx].cmd = cmd; return 0; } int zh200_set_cmd_param1(int idx, unsigned short param) { zh200[idx].cmdpara[0] = param; return 0; } int zh200_set_cmd_param2(int idx, unsigned short param) { zh200[idx].cmdpara[1] = param; return 0; } int zh200_set_cmd_param3(int idx, unsigned short param) { zh200[idx].cmdpara[2] = param; return 0; } int zh200_set_cmd_param4(int idx, unsigned short param) { zh200[idx].cmdpara[3] = param; return 0; } int zh200_set_bsytikchk_from_host(int idx, unsigned char tick) { zh200[idx].bsytik.from_host = tick; return 0; } char *zh200_get_devid(int idx) { return zh200[idx].szdev_id; } int zh200_get_init_data(int idx, char *buf) { sprintf(buf, "{\"device_id\":\"%s\", \"type\":1, \"idx\":%d, \"config\":{ \ \"norm_cap\":%d, \"norm_pow\":%d, \"min_pow\":%d, \"socd\":%.1f, \"socc\":%.1f, \ \"cell_otp\":%d, \"cell_utp\":%d, \"min_v\":%.1f, \"max_v\":%.1f }}", zh200[idx].szdev_id, ctn_get_idx_in_ess(), zh200[idx].pow.norm_cap, zh200[idx].pow.norm_pow, zh200[idx].pow.min_pow, zh200[idx].socd, zh200[idx].socc, zh200[idx].cell_otp, zh200[idx].cell_utp, zh200[idx].min_v, zh200[idx].max_v); return 0; } int zh200_get_tbmqtt_data(int idx, char *buff) { struct zh200_t *dev = &zh200[idx]; if (strcmp(dev->szRunInfo, "ok") != 0) { sprintf(buff, "'ctn_stop_info':'%s'", dev->szRunInfo); return 0; } return -1; }