#include "cascade.h" #include "common.h" #include "elog.h" #include "cfg.h" #include "lock.h" #include "thread.h" #include "switch_ctrl.h" #include "modbus_handle.h" #include "sqlite_handle.h" #include "paras.h" #include "cascade_slave_tcp.h" #include "sys.h" #if 1 #define LOGD log_d #define LOGE log_e #define LOGW log_w #else #define LOGD printf #define LOGE printf #define LOGW printf #endif #define MB_MAX_LEN 250 typedef struct { int inited; pthread_mutex_t mutex; //used for list lock pthread_mutex_t mutex2; //used for extern call pthread_mutex_t mutex3; //used for mb_write and mb_read_write Modbus_Manger m; int addr; slave_t slaves[CASCADE_MAX+1]; ModbusInfo_t mInfo; modbus_mapping_t *map; cmd_data_t cmd; int scanAddr; slave_info_t sInfo; //current slave infomation breaker_info_t sBreaker; }cascade_handle_t; int cur_dev_addr=0; static cascade_handle_t casHandle={.inited=0}; static cascade_handle_t casHandle_breaker={.inited=0}; static void* cmd_thread(void *arg); static void* cmd_NF_thread(void *arg); ////////////////////////////////////////////////// static inline GlobalDeviceManager* get_dm(void) { return &__globalDeviceManage; } static inline GlobalDeviceManager* get_dm2(void) { return &__globalDeviceManage2; } static inline ModbusInfo_t *get_mb(void) { return &get_dm()->_globalDevInfo.cascade; } static int slave_init(cascade_handle_t *cas) { int i; for(i=0; i<=CASCADE_MAX; i++) { cas->slaves[i].addr = -1; cas->slaves[i].err = 0; } return 0; } static int slave_add(cascade_handle_t *cas, int addr) { if(addr<0 || addr>CASCADE_MAX) { return -1; } cas->slaves[addr].addr = addr; cas->slaves[addr].err = 0; return 0; } static int slave_rm(cascade_handle_t *cas, int addr) { if(addr<0 || addr>CASCADE_MAX) { return -1; } cas->slaves[addr].addr = -1; cas->slaves[addr].err = 0; return 0; } static int slave_cnt(cascade_handle_t *cas) { int i,cnt=0; for(i=0; i<=CASCADE_MAX; i++) { if(cas->slaves[i].addr>0) { cnt++; } } return cnt; } static slave_t* slave_get(cascade_handle_t *cas, int addr) { return &cas->slaves[addr]; } static int slave_find(cascade_handle_t *cas, int addr) { if(cas->slaves[addr].addr>0) { return 1; } return 0; } static int slave_get_info(cascade_handle_t *cas) { int cnt=0,cnt2; netswitch_info_t swInfo; GlobalDeviceManager *dm=get_dm(); GlobalPowerManger *tmp=NULL; GlobalTreeACManager* tmp3=NULL; slave_info_t *info=&cas->sInfo; info->cnt=0; info->prod.product_type = dm->_globalDevInfo.product.type; info->prod.product_pwr_type = dm->_globalDevInfo.product.pwr_type; info->prod.product_id = dm->_globalDevInfo.product.id; if(!list_empty(&dm->_globalPowerManger.list_Tree_AC)) { cnt2 = 0; list_for_each_entry(tmp3, &dm->_globalPowerManger.list_Tree_AC, list_Tree_AC) { if(tmp3->product_ph_type<0 || tmp3->product_ph_type>3) { continue; } if(cnt2<3) { info->all.power[cnt2++] = tmp3->_PowerInfo; } } } if(!list_empty(&dm->_globalPowerManger.list)) { cnt = 0; netswitch_get(&swInfo); list_for_each_entry(tmp, &dm->_globalPowerManger.list, list) { if(tmp->product_saddr==0) { continue; } tmp->_PowerInfo.port = swInfo.port[cnt]; info->ch[cnt].product_saddr = tmp->product_saddr; info->ch[cnt].product_ch_type = tmp->product_ch_type; info->ch[cnt].product_ch_addr = tmp->product_ch_addr; info->ch[cnt].product_ch_id = tmp->product_ch_id; info->ch[cnt].product_ch_status = tmp->product_ch_status; info->ch[cnt].product_ch_NF_status = tmp->product_ch_NF_status; info->ch[cnt].start_delay = tmp->product_ch_start_delay; info->ch[cnt].stop_delay = tmp->product_ch_stop_delay; info->ch[cnt].chinfo = tmp->_PowerInfo; if (tmp->product_ch_type==TREE_AC_TYPE||dm->_globalDevInfo.product.pwr_type == SmartPDU_Tree_AC_One_B) { cnt2 = 0; list_for_each_entry(tmp3, &tmp->list_Tree_AC, list_Tree_AC) { info->ch[cnt].pinfo[cnt2].power = tmp3->_PowerInfo; info->ch[cnt].pinfo[cnt2].phase.product_ph_id = tmp3->product_ph_id; info->ch[cnt].pinfo[cnt2].phase.product_ph_type = tmp3->product_ph_type; info->ch[cnt].pinfo[cnt2].phase.product_ph_outputType = tmp3->product_ph_outputType; info->ch[cnt].pinfo[cnt2].phase.product_ph_outputStatus = tmp3->product_ph_outputStatus; cnt2++; } } cnt++; } } info->cnt = cnt; LOGD("___ slave_get_info, cnt: %d\n", info->cnt); return 0; } static int slave_breaker_info(cascade_handle_t *cas) { GlobalDeviceManager *dm=get_dm(); GlobalBreakerManager *temp = NULL; breaker_info_t *breaker=&cas->sBreaker; int cnt = 0; //list_for_each_entry(temp, &__globalDeviceManage.g_new_global_breaker.list, list) lock_s_hold(LOCK_ID_BREAKER); if(!list_empty(&dm->g_new_global_breaker.list)) { printf("isnot empty!!!!!\n"); list_for_each_entry(temp,&dm->g_new_global_breaker.list, list) { // printf("temp addr %ld temp->next = %ld temp->prev = %ld\n",tmp,tmp->list.prev,tmp->list.next); breaker ->breaker_chn[cnt].product_id = temp->product_id; breaker->breaker_chn[cnt].breaker_addrs = temp->breaker_gather_addr; breaker->breaker_chn[cnt].breaker_status = temp->breaker_status; breaker->breaker_chn[cnt].breaker_chn = temp->breaker_chn; breaker->breaker_chn[cnt].breaker_id = temp->breaker_id; strcpy(breaker->breaker_chn[cnt].breaker_gather_type, temp->breaker_gather_type); strcpy(breaker->breaker_chn[cnt].breaker_com, temp->breaker_com); strcpy(breaker->breaker_chn[cnt].breaker_switch_name, temp->breaker_switch_name); strcpy(breaker->breaker_chn[cnt].breaker_chns_name, temp->breaker_chns_name); cnt++; } } breaker->cnt = cnt; lock_s_release(LOCK_ID_BREAKER); LOGD("___ slave_breaker_info, breaker_all: saddr=0x%x %d\n",(uint32_t)dm,breaker->cnt); return 0; } static int get_pwr_info(int chId, GlobalPowerManger *power) { int i; GlobalPowerManger *tmp=NULL; GlobalDeviceManager *dm=get_dm(); list_for_each_entry(tmp, &dm->_globalPowerManger.list, list) { if(tmp->product_ch_id==chId) { power->product_id = dm->_globalDevInfo.product.id; power->product_ch_id = tmp->product_ch_id; strcpy(power->product_ch_name, tmp->product_ch_name); power->product_ch_type = tmp->product_ch_type; power->product_ch_status = tmp->product_ch_status; power->product_ch_NF_status = tmp->product_ch_NF_status; power->product_ch_start_delay = tmp->product_ch_start_delay; power->product_ch_stop_delay = tmp->product_ch_stop_delay; return 0; } } return -1; } static int slave_breaker_update(cascade_breaker_update_t *data) { int ret = -1; if(data) { GlobalDeviceManager *dm=get_dm(); GlobalBreakerManager *temp= NULL; GlobalBreakerManager *pos= NULL; lock_s_hold(LOCK_ID_BREAKER); if(!list_empty(&dm->g_new_global_breaker.list)) { list_for_each_entry_safe(temp,pos,&dm->g_new_global_breaker.list,list) { if(temp->breaker_id == data->switch_id) { strcpy(temp->breaker_switch_name,data->switch_name); strcpy(temp->breaker_chns_name,data->breaker_chns); dev_update_breaker_genera_manage(dm->db, dm->_globalDevInfo.product.id,data->switch_id,temp); ret = 0; break; } } } lock_s_release(LOCK_ID_BREAKER); } return ret; } static int slave_breaker_delete(cascade_braeker_delete_t *data) { int ret = -1; if(data) { GlobalDeviceManager *dm=get_dm(); GlobalBreakerManager *temp= NULL; GlobalBreakerManager *pos= NULL; lock_s_hold(LOCK_ID_BREAKER); if(!list_empty(&dm->g_new_global_breaker.list)) { list_for_each_entry_safe(temp,pos,&dm->g_new_global_breaker.list,list) { printf("new data !!!!\n"); if(temp == NULL) { continue; } if(temp->breaker_id == data->switch_id) { dev_delete_breaker_manage(dm->db,dm->_globalDevInfo.product.id,data->switch_id); list_del(&temp->list); free(temp); if(!list_empty(&dm->g_new_global_breaker.list)) { printf("hellosda\n"); } ret = 0; break; } } } lock_s_release(LOCK_ID_BREAKER); } return ret; } static int slave_breaker_add(cascade_breaker_add_t *data) { int r = -1; if(!data) { goto quit; } GlobalDeviceManager *dm=get_dm(); char buff[124] = {0}; char id[MAX_BREAKER_ID] = {0}; //bianli shujujiegou GlobalBreakerManager *temp = NULL; int i = 1; lock_s_hold(LOCK_ID_BREAKER); list_for_each_entry(temp, &dm->g_new_global_breaker.list, list) { id[temp->breaker_id] = 1; } lock_s_release(LOCK_ID_BREAKER); for(;i < MAX_BREAKER_ID;i++) { if(id[i] == 0) break; } if(i > MAX_BREAKER_ID) { goto quit; } GlobalBreakerManager *breakerManager = (GlobalBreakerManager*) malloc(sizeof(GlobalBreakerManager)); memset(breakerManager,0,sizeof(GlobalBreakerManager)); breakerManager->product_id = __globalDeviceManage._globalDevInfo.product.id; breakerManager->breaker_gather_addr = data->cjdz; strcpy(breakerManager->breaker_com,data->com); strcpy(breakerManager->breaker_gather_type,data->cjfs); strcpy(breakerManager->breaker_chns_name,data->breaker_chns); breakerManager->breaker_id = i; sprintf(buff,"Breaker_%d",breakerManager->breaker_id); strcpy(breakerManager->breaker_switch_name,buff); uint32_t jdh = data->jdh; if(jdh > MAX_BREAKER_CHN) { goto quit2; } char jdh_flag = 0; char chn[MAX_BREAKER_CHN] = {0}; lock_s_hold(LOCK_ID_BREAKER); list_for_each_entry(temp, &dm->g_new_global_breaker.list, list) { if(temp->breaker_gather_addr == breakerManager->breaker_gather_addr) { chn[temp->breaker_chn-1] = 1; } } lock_s_release(LOCK_ID_BREAKER); if(chn[jdh-1] != 1) { breakerManager->breaker_chn = jdh; }else { jdh_flag = 1; } if(jdh_flag == 1) { goto quit2; }else{ dev_insert_breaker_genera_manage(dm->db,breakerManager); lock_s_hold(LOCK_ID_BREAKER); list_add_tail(&breakerManager->list,&dm->g_new_global_breaker.list); lock_s_release(LOCK_ID_BREAKER); r = 0; } return r; quit2: free(breakerManager); breakerManager = NULL; quit: return r; } static int slave_save(cascade_handle_t *cas) { int r; GlobalPowerManger power; GlobalDeviceManager *dm=get_dm(); if(cas->cmd.obj!=OBJ_CHANNEL) { return -1; } r = get_pwr_info(cas->cmd.chId, &power); if(r) { LOGE("____ get_pwr_info failed\n"); return -1; } r = dev_update_power_manage_genera_info(dm->db, dm->_globalDevInfo.product.id, cas->cmd.chId, &power); return r; } ///////////////////////////////////////////////////////////////////////////////////////// static int mb_init(cascade_handle_t *cas, char *path, int mode, int addr, uint32_t baud) { int r=0; r = g_modbus_init(&cas->m, path, baud, mode, addr, (mode==MODBUS_MASTER)?"master":"slave", 1); if(r==0) { if(mode==MODBUS_SLAVE) { LOGD("___ set slave addr: %d\n", addr); cas->addr = addr; g_modbus_set_slave(&cas->m, addr); cascade_slave_init(); } else { cas->addr = 0; } cas->inited = 1; } else { LOGE("___ mb init failed, %s\n", modbus_strerror(errno)); } return r; } static int mb_deinit(cascade_handle_t *cas) { g_modbus_deinit(&cas->m); cas->inited = 0; return 0; } static int _mb_scan(cascade_handle_t *cas, int addr) { int r; uint16_t tmp; r = g_modbus_read_x_reg(&cas->m, addr, CASCADE_REG_SCAN, 1, &tmp); return r; } static int _mb_read(cascade_handle_t *cas, int addr, uint16_t reg, uint16_t *data, int cnt) { int r; r = g_modbus_read_x_reg(&cas->m, addr, reg, cnt, data); if(r<0) { cas->slaves[addr].err++; if(cas->slaves[addr].err>ERR_MAX) { slave_rm(cas, addr); } } else { cas->slaves[addr].err = 0; } return r; } static int _mb_write(cascade_handle_t *cas, int addr, uint16_t reg, uint16_t *data, int cnt) { int r; r = g_modbus_write_x_reg(&cas->m, addr, reg, cnt, data); if(r<0) { cas->slaves[addr].err++; if(cas->slaves[addr].err>ERR_MAX) { slave_rm(cas, addr); } } else { cas->slaves[addr].err = 0; } return r; } static int _mb_recv(cascade_handle_t *cas, uint8_t *buf) { return g_modbus_receive(&cas->m, buf); } static int _mb_reply(cascade_handle_t *cas, uint8_t *buff, int reqlen, modbus_mapping_t *map) { return g_modbus_reply(&cas->m, buff, reqlen, map); } static int _mb_get_timeout(cascade_handle_t *cas) { int r,ms=0; r = g_modbus_get_timeout(&cas->m, &ms); return ms; } static int _mb_set_timeout(cascade_handle_t *cas, int ms) { return g_modbus_set_timeout(&cas->m, ms); } //////////////////////////////////////////////////////////// static void print_data(uint8_t *data, int len) { int i; for(i=0; iobj); LOGD("__%s__ cmd.cmd: %d\n", s, cmd->cmd); LOGD("__%s__ cmd.chId: %d\n", s, cmd->chId); //LOGD("__%s__ cmd.time_s: %s\n", s, cmd->time_s); //LOGD("__%s__ cmd.time_e: %s\n", s, cmd->time_e); LOGD("\n"); } static void memswap(uint8_t *buf, int len) { int i; uint8_t tmp; for(i=0; iaddr); LOGD("____%s___ h.func: %d\n", s, h->func); LOGD("____%s___ h.reg: %d\n", s, h->reg); LOGD("____%s___ h.regcnt: %d\n", s, h->regcnt); LOGD("____%s___ h.dlen: %d\n", s, h->dlen); LOGD("____%s___ h.data: %d\n", s, (int)h->data); LOGD("\n"); return 0; } static int mb_hdr(uint8_t *data, int datalen, mb_hdr_t *h) { h->addr = data[0]; h->func = data[1]; h->reg = data[2]<<8 | data[3]; h->regcnt = data[4]<<8 | data[5]; h->dlen = 0; h->data = NULL; if(datalen>8) { h->dlen = data[6]; h->data = data+7; memswap(h->data, h->dlen+h->dlen%2); } //print_hdr("sss", h); return 0; } #define SCAN_TIMEOUT_MS 200 #define RW_TIMEOUT_MS 100 static int mb_scan(cascade_handle_t *cas, int addr) { int r,timeout=0; uint16_t tmp; pthread_mutex_lock(&cas->mutex3); timeout = _mb_get_timeout(cas); _mb_set_timeout(cas, SCAN_TIMEOUT_MS); r = _mb_scan(cas, addr); _mb_set_timeout(cas, timeout); pthread_mutex_unlock(&cas->mutex3); return r; } static int mb_read(cascade_handle_t *cas, int addr, data_t *d) { int i,r=0,finish=0,timeout=0; int rl,xlen,rlen=0,oncelen=MB_MAX_LEN; uint16_t buff[MODBUS_RTU_MAX_ADU_LENGTH]; if(d->dlen<=0) { return -1; } for(i=0; i<10; i++) { pthread_mutex_lock(&cas->mutex3); timeout = _mb_get_timeout(cas); _mb_set_timeout(cas, RW_TIMEOUT_MS); r = 0; rlen = 0; while(1) { if(rlen+oncelen>d->dlen) { xlen = d->dlen-rlen; } else { xlen = oncelen; } xlen += xlen%2; rl = _mb_read(cas, addr, CASCADE_REG_READ, buff, xlen/2); if(rl<0) { LOGE("___ _mb_read failed, %s, rlen: %d, retry: %d\n", modbus_strerror(errno), rlen, i); r = -1; break; } if(rlen+rl*2>=d->dlen) { xlen = d->dlen-rlen; finish = 1; } else { xlen = rl*2; } memcpy((char*)d->data+rlen, buff, xlen); rlen += xlen; if(finish) { break; } } _mb_set_timeout(cas, timeout); pthread_mutex_unlock(&cas->mutex3); if(r==0) { break; } } return r; } static int mb_write(cascade_handle_t *cas, int addr, data_t *d) { int i,r=0,timeout=0; int wl,xlen,wlen=0,oncelen=MB_MAX_LEN; uint16_t buff[MODBUS_RTU_MAX_ADU_LENGTH]; if(d->dlen<=0) { return -1; } for(i=0; i<10; i++) { pthread_mutex_lock(&cas->mutex3); timeout = _mb_get_timeout(cas); _mb_set_timeout(cas, RW_TIMEOUT_MS); r = 0; wlen = 0; while(1) { if(wlen+oncelen>d->dlen) { xlen = d->dlen-wlen; } else { xlen = oncelen; } xlen += xlen%2; memcpy(buff, d->data+wlen, xlen); wl = _mb_write(cas, addr, CASCADE_REG_WRITE, buff, xlen/2); if(wl<0) { LOGE("___ _mb_write failed, addr: %d, reg: %d, cnt: %d, %s, retry: %d\n", addr, CASCADE_REG_WRITE, xlen/2, modbus_strerror(errno), i); r = -1; break; } if(wlen+wl*2>=d->dlen) { break; } else { xlen = wl*2; } wlen += xlen; } _mb_set_timeout(cas, timeout); pthread_mutex_unlock(&cas->mutex3); if(r==0) { break; } } return r; } static int mb_write_read(cascade_handle_t *cas, int addr, data_t *wd, data_t *rd) { int r=0; r = mb_write(cas, addr, wd); if(r==0) { r = mb_read(cas, addr, rd); } return r; } static int mb_receive(cascade_handle_t *cas) { int r=-1,rc,rlen=0; mb_hdr_t h; uint8_t buff[MODBUS_RTU_MAX_ADU_LENGTH]; static int sendlen=0; cmd_data_t *cmd=NULL; rc = _mb_recv(cas, buff); if(rc<0) { return -1; } mb_hdr(buff, rc, &h); #if 1 //do not know why slave can receive all address data //LOGD("____mb_receive, %d, %d\n", h.addr, cas->addr); if(h.addr>0 && h.addr!=cas->addr) { return -1; } #endif //LOGD("____mb_receive, reg: %d, rc: %d\n", h.reg, rc); switch(h.reg) { case CASCADE_REG_SCAN: { r = _mb_reply(cas, buff, rc, cas->map); } break; case CASCADE_REG_WRITE: { if(h.data) { cmd = (cmd_data_t*)h.data; if(cmd->cmd>=CASCADE_CMD_GET_INFO) { cas->cmd = *cmd; } sendlen = 0; } else { return -1; } switch(cmd->cmd) { case CASCADE_CMD_OPEN: case CASCADE_CMD_CLOSE: { cmd_data_t *pcmd=malloc(sizeof(cmd_data_t)); if(pcmd) { *pcmd = *cmd; thread_start_simp(cmd_thread, pcmd, 4*MB); } } break; case CASCADE_CMD_OPEN_NF: case CASCADE_CMD_CLOSE_NF: { cmd_data_t *pcmd=malloc(sizeof(cmd_data_t)); if(pcmd) { *pcmd = *cmd; thread_start_simp(cmd_NF_thread, pcmd, 4*MB); } } break; case CASCADE_CMD_SAVE: case CASCADE_CMD_SAVE3: { slave_save(cas); } break; case CASCADE_CMD_BREAKER_SAVE_ADD: { LOGD("_____ slave CASCADE_CMD_BREAKER_SAVE_ADD\n"); LOGD("%d %d %s %s %s\n",cmd->datas.data.jdh,cmd->datas.data.cjdz,cmd->datas.data.cjfs,cmd->datas.data.com,cmd->datas.data.breaker_chns); slave_breaker_add(&cmd->datas.data); } break; case CASCADE_CMD_BREAKER_SAVE_UPDATE: { LOGD("_____ slave CASCADE_CMD_BREAKER_SAVE_UPDATE\n"); LOGD("%d %s %s\n",cmd->datas.data1.switch_id,cmd->datas.data1.switch_name,cmd->datas.data1.breaker_chns); slave_breaker_update(&cmd->datas.data1); } break; case CASCADE_CMD_BREAKER_SAVE_DELETE: { LOGD("_____ slave CASCADE_CMD_BREAKER_SAVE_DELETE\n"); slave_breaker_delete(&cmd->datas.data2); } } r = _mb_reply(cas, buff, rc, cas->map); } break; case CASCADE_REG_READ: { cmd = &cas->cmd; //LOGD("____ CASCADE_REG_READ %d\n", cmd->cmd); switch(cmd->cmd) { case CASCADE_CMD_GET_INFO: { LOGD("_____ slave CASCADE_CMD_GET_INFO\n"); slave_get_info(cas); memcpy(cas->map->tab_registers+(h.reg-CASCADE_REG_OFFSET), (char*)&cas->sInfo+sendlen, h.regcnt*2); } break; case CASCADE_CMD_BREAKER_QUERY: { LOGD("_____ slave CASCADE_CMD_GET_INFO\n"); slave_breaker_info(cas); memcpy(cas->map->tab_registers+(h.reg-CASCADE_REG_OFFSET), ((char*)&cas->sBreaker)+sendlen, h.regcnt*2); } break; case CASCADE_CMD_QUERY_CH: { LOGD("___ slave CASCADE_CMD_QUERY_CH\n"); slave_get_info(cas); memcpy(cas->map->tab_registers+(h.reg-CASCADE_REG_OFFSET), ((char*)&cas->sInfo)+sendlen, h.regcnt*2); } break; case CASCADE_CMD_QUERY_VOL:break; case CASCADE_CMD_QUERY_CUR:break; case CASCADE_CMD_QUERY_PWR:break; case CASCADE_CMD_QUERY_PWRQ:break; case CASCADE_CMD_QUERY_HIS:break; case CASCADE_CMD_QUERY_TOTAL:break; case CASCADE_CMD_QUERY_TOTAL_PWR:break; case CASCADE_CMD_BREAKER_GET_INFO: { LOGD("_____ slave breaker CASCADE_CMD_GET_INFO\n"); slave_breaker_info(cas); memcpy(cas->map->tab_registers+(h.reg-CASCADE_REG_OFFSET), ((char*)&cas->sBreaker)+sendlen, h.regcnt*2); } break; } r = _mb_reply(cas, buff, rc, cas->map); if(r>0) { sendlen += h.regcnt*2; //LOGD("____ slave sendlen: %d, h.dlen: %d, r: %d\n", sendlen, h.dlen, r); } } break; default: { Modbus_Manger *mm=&get_dm()->_globalRelaySampManger; LOGD("___ slave XXXXXXXXXXX\n"); if(h.func==MODBUS_FC_READ_HOLDING_REGISTERS) { cascade_slave_read(h.reg, h.regcnt); } else if(h.func==MODBUS_FC_WRITE_SINGLE_REGISTER) { cascade_slave_write(h.reg, h.regcnt); } r = _mb_reply(cas, buff, rc,cascade_slave_map()); } } return r; } ///////////////////////////////////////////////////////////////////////// static int master_scan(cascade_handle_t *cas) { int i,r=0; uint16_t tmp[10]; if(cas->scanAddr>CASCADE_MAX) { cas->scanAddr = 1; } if(!slave_find(cas, cas->scanAddr)) { r = mb_scan(cas, cas->scanAddr); if(r>0) { LOGD("____ find a slave, addr: %d\n", cas->scanAddr); slave_add(cas, cas->scanAddr); } else { LOGW("____ scan %d fail, %s\n", cas->scanAddr, modbus_strerror(errno)); } } cas->scanAddr++; //print_slave(cas); return 0; } /////////////////////////////////////////////////////////////////////////////////////// static int power_clear(cascade_handle_t *cas); static int power_init(cascade_handle_t *cas) { GlobalDeviceManager *dm=get_dm(); GlobalDeviceManager *dm2=get_dm2(); dm2->_globalDevInfo.product.pwr_type = dm->_globalDevInfo.product.pwr_type; dm2->_globalDevInfo.product.id = dm->_globalDevInfo.product.id; strcpy(dm2->_globalDevInfo.product.name, dm->_globalDevInfo.product.name); strcpy(dm2->_globalDevInfo.product.number, dm->_globalDevInfo.product.number); strcpy(dm2->_globalDevInfo.product.status, dm->_globalDevInfo.product.status); INIT_LIST_HEAD(&dm2->_globalPowerManger.list); INIT_LIST_HEAD(&dm2->_globalPowerManger.list_Tree_AC); return 0; } static int breaker_slave_init(void) { //GlobalDeviceManager *dm=get_dm(); GlobalDeviceManager *dm2=get_dm2(); INIT_LIST_HEAD(&dm2->g_new_global_breaker.list); pthread_mutex_init(&dm2->_breaker_mutex,NULL); return 0; } static int power_deinit(cascade_handle_t *cas) { GlobalDeviceManager *dm2=get_dm2(); power_clear(cas); return 0; } static int power_clear(cascade_handle_t *cas) { GlobalPowerManger *tmp,*pos; GlobalTreeACManager *tmp3,*pos3; GlobalDeviceManager *dm2=get_dm2(); if(!list_empty(&dm2->_globalPowerManger.list_Tree_AC)) { list_for_each_entry_safe(tmp3,pos3,&dm2->_globalPowerManger.list_Tree_AC,list_Tree_AC) { if(tmp3==NULL) { continue; } list_del(&tmp3->list_Tree_AC); free(tmp3); } } if(!list_empty(&dm2->_globalPowerManger.list)) { list_for_each_entry_safe(tmp,pos,&dm2->_globalPowerManger.list,list) { if(tmp==NULL) { continue; } if (tmp->product_ch_type==TREE_AC_TYPE||__globalDeviceManage._globalDevInfo.product.pwr_type == SmartPDU_Tree_AC_One_B) { if(list_empty(&tmp->list_Tree_AC)) { continue; } list_for_each_entry_safe(tmp3,pos3,&tmp->list_Tree_AC,list_Tree_AC) { if(tmp3==NULL) { continue; } list_del(&tmp3->list_Tree_AC); free(tmp3); } } list_del(&tmp->list); free(tmp); } } return 0; } static int breaker_clear(cascade_handle_t *cas) { GlobalDeviceManager *dm2=get_dm2(); GlobalBreakerManager *temp = NULL; GlobalBreakerManager *pos = NULL; pthread_mutex_lock(&dm2->_breaker_mutex); if(!list_empty(&dm2->g_new_global_breaker.list)) { list_for_each_entry_safe(temp,pos,&dm2->g_new_global_breaker.list,list) { if(temp == NULL) { continue; } list_del(&temp->list); free(temp); } } INIT_LIST_HEAD(&dm2->g_new_global_breaker.list); pthread_mutex_unlock(&dm2->_breaker_mutex); return 0; } static int power_add(cascade_handle_t *cas) { int i,j,nTac_chn=0,r=-1; GlobalDeviceManager *dm1=get_dm(); GlobalDeviceManager *dm2=get_dm2(); GlobalPowerManger *tmp=NULL; GlobalTreeACManager *tmp3=NULL; slave_info_t *info=&cas->sInfo; LOGD("____ master add channel to the list, cnt: %d\n", info->cnt); cascade_lock(); power_clear(cas); dm2->_globalDevInfo.product.id = cur_dev_addr; //插入总数据 if(info->prod.product_pwr_type==SmartPDU_Tree_AC_Tree || info->prod.product_pwr_type==SmartPDU_Tree_AC_One || info->prod.product_pwr_type==SmartPDU_Tree_AC_One_B) { for (int TreeACindex = 0; TreeACindex < 3; TreeACindex++) { tmp3 = (GlobalTreeACManager*)malloc(sizeof(GlobalTreeACManager)); if (tmp3 == NULL) { LOGE("tmp3 malloc error.\n"); goto quit; } memset(tmp3, 0, sizeof(GlobalTreeACManager)); tmp3->product_ch_addr = TreeACindex + 1; tmp3->product_id = info->prod.product_id; tmp3->product_saddr = 0; tmp3->product_ch_id = 0; tmp3->product_ch_addr = TreeACindex + 1; tmp3->product_ph_id = nTac_chn; tmp3->product_ph_type = (TreeACindex + 3) % 3; list_add_tail(&tmp3->list_Tree_AC, &dm2->_globalPowerManger.list_Tree_AC); nTac_chn++; } } for(i=0; icnt; i++) { tmp = (GlobalPowerManger*)malloc(sizeof(GlobalPowerManger)); if(!tmp) { LOGE("tmp malloc error.\n"); goto quit; } memset(tmp, 0, sizeof(GlobalPowerManger)); tmp->product_id = info->prod.product_id; tmp->product_saddr = info->ch[i].product_saddr; tmp->product_ch_id = info->ch[i].product_ch_id; tmp->product_ch_addr = info->ch[i].product_ch_addr; sprintf(tmp->product_ch_name, "CH%d", tmp->product_ch_id); tmp->product_ch_type = info->ch[i].product_ch_type; tmp->product_ch_status = info->ch[i].product_ch_status; tmp->product_ch_NF_status = info->ch[i].product_ch_NF_status; tmp->product_ch_start_delay = info->ch[i].start_delay; tmp->product_ch_stop_delay = info->ch[i].stop_delay; tmp->_PowerInfo = info->ch[i].chinfo; if(info->ch[i].product_ch_type==TREE_AC_TYPE||info->prod.product_pwr_type==SmartPDU_Tree_AC_One_B) { INIT_LIST_HEAD(&tmp->list_Tree_AC); for (j=0; j<3; j++) { tmp3 = (GlobalTreeACManager *)malloc(sizeof(GlobalTreeACManager)); if (tmp3 == NULL) { LOGE("tmp3 malloc error.\n"); goto quit; } memset(tmp3, 0, sizeof(GlobalTreeACManager)); tmp3->product_id = info->prod.product_id; tmp3->product_saddr = info->ch[i].product_saddr; tmp3->product_ch_id = tmp->product_ch_id; tmp3->product_ch_addr = info->ch[i].product_ch_addr; tmp3->product_ph_id = info->ch[i].pinfo[j].phase.product_ph_id; tmp3->product_ph_type = info->ch[i].pinfo[j].phase.product_ph_type; tmp3->product_ph_outputType = info->ch[i].pinfo[j].phase.product_ph_outputType; tmp3->product_ph_outputStatus = info->ch[i].pinfo[j].phase.product_ph_outputStatus; tmp3->_PowerInfo = info->ch[i].pinfo[j].power; list_add_tail(&tmp3->list_Tree_AC, &tmp->list_Tree_AC); } } list_add_tail(&tmp->list,&dm2->_globalPowerManger.list); } cascade_unlock(); r = 0; quit: return r; } static int breaker_add(cascade_handle_t *cas) { int i,j,r=-1; //GlobalDeviceManager *dm1=get_dm(); GlobalDeviceManager *dm2=get_dm2(); GlobalBreakerManager *tmp=NULL; breaker_info_t *info=&cas->sBreaker; //cascade_lock(); breaker_clear(cas); pthread_mutex_lock(&dm2->_breaker_mutex); for(i=0; icnt; i++) { tmp = (GlobalBreakerManager*) malloc(sizeof(GlobalBreakerManager)); if(!tmp) { LOGE("tmp malloc error.\n"); goto quit; } memset(tmp, 0, sizeof(GlobalBreakerManager)); tmp->product_id = cur_dev_addr; tmp->breaker_chn = info->breaker_chn[i].breaker_chn; tmp->breaker_status = info->breaker_chn[i].breaker_status; tmp->breaker_gather_addr = info->breaker_chn[i].breaker_addrs; tmp->breaker_id = info->breaker_chn[i].breaker_id; strcpy(tmp->breaker_gather_type, info->breaker_chn[i].breaker_gather_type); strcpy(tmp->breaker_com, info->breaker_chn[i].breaker_com); strcpy(tmp->breaker_chns_name, info->breaker_chn[i].breaker_chns_name); strcpy(tmp->breaker_switch_name, info->breaker_chn[i].breaker_switch_name); list_add_tail(&tmp->list,&dm2->g_new_global_breaker.list); } pthread_mutex_unlock(&dm2->_breaker_mutex); //cascade_unlock(); r = 0; quit: return r; } static int breaker_update(cascade_handle_t *cas) { GlobalBreakerManager *tmp=NULL; GlobalBreakerManager *tmp3=NULL; GlobalDeviceManager *dm2=get_dm2(); breaker_info_t *info=&cas->sBreaker; int cnt = 0; LOGD("______ breaker_update, %d\n", info->cnt); if(info->cnt==0) { LOGE("___ sBreaker.cnt is 0\n"); return -1; } if(!list_empty(&dm2->g_new_global_breaker.list)) { cnt = 0; pthread_mutex_lock(&dm2->_breaker_mutex); list_for_each_entry_safe(tmp,tmp3,&dm2->g_new_global_breaker.list,list) { tmp->breaker_id = info->breaker_chn[cnt].breaker_id; tmp->breaker_status = info->breaker_chn[cnt].breaker_status; tmp->breaker_gather_addr = info->breaker_chn[cnt].breaker_addrs; strcpy(tmp->breaker_gather_type, info->breaker_chn[cnt].breaker_gather_type); strcpy(tmp->breaker_com, info->breaker_chn[cnt].breaker_com); strcpy(tmp->breaker_chns_name, info->breaker_chn[cnt].breaker_chns_name); strcpy(tmp->breaker_switch_name, info->breaker_chn[cnt].breaker_switch_name); cnt++; } pthread_mutex_unlock(&dm2->_breaker_mutex); } return 0; } static int power_update(cascade_handle_t *cas) { int cnt=0; GlobalPowerManger *tmp=NULL; GlobalTreeACManager *tmp3=NULL; GlobalDeviceManager *dm2=get_dm2(); slave_info_t *info=&cas->sInfo; LOGD("______ power_update, %d\n", info->cnt); if(info->cnt==0) { LOGE("___ sInfo.cnt is 0\n"); return -1; } if(!list_empty(&dm2->_globalPowerManger.list_Tree_AC)) { cnt = 0; list_for_each_entry(tmp3,&dm2->_globalPowerManger.list_Tree_AC,list_Tree_AC) { if(tmp3==NULL) { continue; } if(cnt<3) { tmp3->_PowerInfo = info->all.power[cnt++]; } } } if(!list_empty(&dm2->_globalPowerManger.list)) { cnt = 0; list_for_each_entry(tmp, &dm2->_globalPowerManger.list, list) { tmp->_PowerInfo = info->ch[cnt].chinfo; if(tmp->product_ch_type==TREE_AC_TYPE||info->prod.product_pwr_type==SmartPDU_Tree_AC_One_B) { if(list_empty(&tmp->list_Tree_AC)) { continue; } int cnt2=0; list_for_each_entry(tmp3,&tmp->list_Tree_AC,list_Tree_AC) { tmp3->_PowerInfo = info->ch[cnt].pinfo[cnt2++].power; } } cnt++; } } return 0; } static void print_sensor(char *s, sensor_data_t *ss) { LOGD("__%s__ ss.type: %d\n", s, ss->type); LOGD("__%s__ ss.addr: %d\n", s, ss->addr); LOGD("__%s__ ss.voltage: %f\n", s, ss->pwr.voltage); LOGD("__%s__ ss.current: %f\n", s, ss->pwr.current); LOGD("__%s__ ss.power: %f\n", s, ss->pwr.power); LOGD("__%s__ ss.consumption: %f\n", s, ss->pwr.consumption); LOGD("__%s__ ss.freq: %f\n", s, ss->pwr.freq); LOGD("__%s__ ss.factor: %f\n", s, ss->pwr.factor); LOGD("__%s__ ss.status: %d\n", s, ss->pwr.status); LOGD("__%s__ ss.temprature: %f\n", s, ss->temprature); LOGD("__%s__ ss.humidity: %f\n", s, ss->humidity); LOGD("__%s__ ss.warning: %d\n", s, ss->warning); LOGD("__%s__ ss.power_status: %d\n", s, ss->power_status); LOGD("__%s__ ss.sensor_status: %d\n", s, ss->sensor_status); LOGD("\n"); } #define VALUE_OF(m,a,b) ((m[a]<<16)+m[b]) static int sensor_get(cascade_handle_t *cas, int addr, sensor_data_t *ss) { uint32_t offset = 6000; uint32_t value = 0 ; uint16_t temp[100]; int r,cnt = sizeof(sensor_ori_t)/2; r = _mb_read(cas, addr, offset, temp, cnt); if(r!=cnt) { LOGE("___mbus_read slave %d failed, %s\n", addr, modbus_strerror(errno)); return -1; } ss->type = temp[0]; ss->addr = temp[1]; ss->pwr.voltage = VALUE_OF(temp,3,2)/1000.0; ss->pwr.current = VALUE_OF(temp,5,4)/1000.0; ss->pwr.power = VALUE_OF(temp,7,6)/1000.0; ss->pwr.consumption = VALUE_OF(temp,9,8)/1000.0; ss->pwr.freq = VALUE_OF(temp,11,10)/1000.0; ss->pwr.factor = VALUE_OF(temp,13,12)/1000.0; ss->pwr.status = temp[20]; ss->temprature = VALUE_OF(temp,15,14)/1000.0; ss->humidity = VALUE_OF(temp,17,16)/1000.0; ss->warning = VALUE_OF(temp,19,18)/1000.0; ss->sensor_status = temp[21]; //print_sensor("11", ss); return 0; } #define REGS(x) (((x)+(x)%2)/2) static int master_cmd(cascade_handle_t *cas, cmd_data_t *cmd) { int i,r; GlobalPowerManger *tmp=NULL; GlobalDeviceManager *dm=get_dm(); GlobalDeviceManager *dm2=get_dm2(); GlobalDeviceInfo *dev=&dm2->_globalDevInfo; data_t rdata,wdata; if(cur_dev_addr==0) { return -1; } switch(cmd->cmd) { case CASCADE_CMD_OPEN: case CASCADE_CMD_CLOSE: case CASCADE_CMD_SAVE: case CASCADE_CMD_SAVE3: case CASCADE_CMD_OPEN_NF: case CASCADE_CMD_CLOSE_NF: { LOGD("____ master CMD: %d\n", cmd->cmd); wdata.dlen = sizeof(cmd_data_t); wdata.data = (uint8_t*)cmd; r = mb_write(cas, cur_dev_addr, &wdata); } break; case CASCADE_CMD_GET_INFO: { wdata.dlen = sizeof(cmd_data_t); wdata.data = (uint8_t*)cmd; rdata.dlen = sizeof(slave_info_t)-sizeof(channel_info_t)*CH_MAX; rdata.data = (uint8_t*)&cas->sInfo; LOGD("_____ master send CASCADE_CMD_GET_INFO\n"); r = mb_write_read(cas, cur_dev_addr, &wdata, &rdata); if(r==0) { LOGD("______cas->info.cnt: %d\n", cas->sInfo.cnt); rdata.dlen = sizeof(slave_info_t)-sizeof(channel_info_t)*(CH_MAX-cas->sInfo.cnt); rdata.data = (uint8_t*)&cas->sInfo; r = mb_write_read(cas, cur_dev_addr, &wdata, &rdata); if(r==0) { power_add(cas); } } else { LOGE("_____ master CASCADE_CMD_GET_INFO failed\n"); } } break; case CASCADE_CMD_BREAKER_GET_INFO: { wdata.dlen = sizeof(cmd_data_t); wdata.data = (uint8_t*)cmd; rdata.dlen = sizeof(breaker_info_t)-sizeof(breaker_channel_info_t)*CH_MAX; rdata.data = (uint8_t*)&cas->sBreaker; LOGD("_____ master send CASCADE_CMD_BREAKER_GET_INFO\n"); r = mb_write_read(cas, cur_dev_addr, &wdata, &rdata); if(r==0) { LOGD("______cas->info.cnt: %d\n", cas->sBreaker.cnt); rdata.dlen = sizeof(breaker_info_t)-sizeof(breaker_channel_info_t)*(CH_MAX-cas->sBreaker.cnt); rdata.data = (uint8_t*)&cas->sBreaker; r = mb_write_read(cas, cur_dev_addr, &wdata, &rdata); if(r==0) { breaker_add(cas); } } } break; case CASCADE_CMD_BREAKER_SAVE_UPDATE: case CASCADE_CMD_BREAKER_SAVE_DELETE: case CASCADE_CMD_BREAKER_SAVE_ADD: { wdata.dlen = sizeof(cmd_data_t); wdata.data = (uint8_t*)cmd; r = mb_write(cas, cur_dev_addr, &wdata); } break; default: cas->cmd = *cmd; r = 0; } return r; } static int master_query(cascade_handle_t *cas) { int i,r; GlobalPowerManger *tmp=NULL; GlobalDeviceManager *dm2=get_dm2(); GlobalDeviceInfo *dev=&dm2->_globalDevInfo; cmd_data_t *cmd=&cas->cmd; data_t rdata,wdata; if(cur_dev_addr==0) { return -1; } wdata.dlen = sizeof(cmd_data_t); wdata.data = (uint8_t*)cmd; switch(cmd->cmd) { case CASCADE_CMD_QUERY_CH: { //LOGD("__00__ master query CASCADE_CMD_QUERY_CH, cnt: %d\n", cas->sInfo.cnt); if(cas->sInfo.cnt==0 || cas->sInfo.cnt>CH_MAX) { return -1; } rdata.dlen = sizeof(slave_info_t)-sizeof(channel_info_t)*(CH_MAX-cas->sInfo.cnt); rdata.data = (uint8_t*)&cas->sInfo; r = mb_write_read(cas, cur_dev_addr, &wdata, &rdata); if(r==0) { power_update(cas); cmd->cmd = CASCADE_CMD_BREAKER_QUERY; } else { LOGE("____ master query CASCADE_CMD_QUERY_CH failed\n"); } //LOGD("__11__ master query CASCADE_CMD_QUERY_CH, cnt: %d\n", cas->sInfo.cnt); } break; case CASCADE_CMD_BREAKER_QUERY: { wdata.dlen = sizeof(cmd_data_t); wdata.data = (uint8_t*)cmd; rdata.dlen = sizeof(breaker_info_t)-sizeof(breaker_channel_info_t)*CH_MAX; rdata.data = (uint8_t*)&cas->sBreaker; r = mb_write_read(cas, cur_dev_addr, &wdata, &rdata); LOGD("____ master query CASCADE_CMD_BREAKER_QUERY, cnt: %d\n", cas->sBreaker.cnt); if(cas->sBreaker.cnt==0 || cas->sBreaker.cnt>CH_MAX) { breaker_clear(cas); cmd->cmd = CASCADE_CMD_QUERY_CH; return -1; } rdata.dlen = sizeof(breaker_info_t)-sizeof(breaker_channel_info_t)*(CH_MAX-cas->sBreaker.cnt); rdata.data = (uint8_t*)&cas->sBreaker; r = mb_write_read(cas, cur_dev_addr, &wdata, &rdata); if(r == 0) { breaker_add(cas); cmd->cmd = CASCADE_CMD_QUERY_CH; }else { LOGE("____ master query CASCADE_CMD_BREAKER_QUERY failed\n"); } } break; case CASCADE_CMD_QUERY_VOL: { if(cmd->obj==OBJ_CHANNEL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else if(cmd->obj==OBJ_OVERALL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else { return -1; } } break; case CASCADE_CMD_QUERY_CUR: { if(cmd->obj==OBJ_CHANNEL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else if(cmd->obj==OBJ_OVERALL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else { return -1; } } break; case CASCADE_CMD_QUERY_PWR: { if(cmd->obj==OBJ_CHANNEL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else if(cmd->obj==OBJ_OVERALL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else { return -1; } } break; case CASCADE_CMD_QUERY_PWRQ: { if(cmd->obj==OBJ_CHANNEL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else if(cmd->obj==OBJ_OVERALL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else { return -1; } } break; case CASCADE_CMD_QUERY_HIS: { if(cmd->obj==OBJ_CHANNEL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else if(cmd->obj==OBJ_OVERALL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else { return -1; } } break; case CASCADE_CMD_QUERY_TOTAL: { if(cmd->obj==OBJ_CHANNEL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else if(cmd->obj==OBJ_OVERALL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else { return -1; } } break; case CASCADE_CMD_QUERY_TOTAL_PWR: { if(cmd->obj==OBJ_CHANNEL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else if(cmd->obj==OBJ_OVERALL) { //rdata.dlen = sizeof(chInfo); //rdata.data = (uint8_t*)&chInfo; } else { return -1; } } break; default: //LOGD("____ master query cmd: %d\n", cmd->cmd); return -1; } return r; } static int slave_receive(cascade_handle_t *cas) { return mb_receive(cas); } static void* cascade_thread(void *arg) { int r; thread_handle_t *h=(thread_handle_t*)arg; cascade_handle_t *cas=(cascade_handle_t*)h->arg; ModbusInfo_t *info=&cas->mInfo; LOGD("__ cascade %s\n", (info->mode==MODBUS_MASTER)?"master":"slave"); while(h->quit==0) { if(info->mode==MODBUS_MASTER) { //主模 r = master_query(cas); sleep(1); } else { //从模式,等待主设备发起数据请�? r = slave_receive(cas); } } pthread_exit(NULL); } static void* cascade_scan_thread(void *arg) { int r; thread_handle_t *h=(thread_handle_t*)arg; cascade_handle_t *cas=(cascade_handle_t*)h->arg; ModbusInfo_t *info=&cas->mInfo; while(h->quit==0) { if(info->mode==MODBUS_MASTER) { //master r = master_scan(cas); } sleep(1); } pthread_exit(NULL); } static void* cmd_thread(void *arg) { int i,t=0; char temp[100]; cascade_handle_t *cas=&casHandle; slave_info_t *info=&cas->sInfo; GlobalDeviceManager *dm=get_dm(); cmd_data_t *pcmd=(cmd_data_t*)arg; if(pcmd->cmd==CASCADE_CMD_OPEN) { LOGD("____ slave CASCADE_CMD_OPEN\n"); } else { LOGD("____ slave CASCADE_CMD_CLOSE\n"); } int flag=((pcmd->cmd==CASCADE_CMD_OPEN)?1:0); if(pcmd->chId == 0xff) { int sendAddr = 0; for(i=0; icnt; i++) { if(info->ch[i].product_ch_addr>0) { if(info->ch[i].product_ch_addr==sendAddr) { continue; } else { sendAddr = info->ch[i].product_ch_addr; } t = g_switch_set_all_ctrl(&dm->_globalRelaySampManger, info->ch[i].product_ch_type, info->ch[i].product_ch_addr, flag); if(t<0) { LOGE("___ %d %s failed\n", info->ch[i].product_ch_addr, (pcmd->cmd==CASCADE_CMD_OPEN)?"open":"close"); } } } } else { GlobalPowerManger *tmp=NULL; list_for_each_entry(tmp, &dm->_globalPowerManger.list, list) { if(tmp->product_ch_id==pcmd->chId) { t = g_switch_set_all_chn_ctrl(&dm->_globalRelaySampManger, tmp, tmp->product_saddr, tmp->product_ch_addr, flag, false); break; } } } if(pcmd->cmd==CASCADE_CMD_OPEN) { sprintf(temp,"$开启$|$所有$|$通道$"); } else { sprintf(temp,"$关闭$|$所有$|$通道$"); } dev_insert_alarm_ctrl(dm->db, dm->_globalDevInfo.product.id,ALARM_TYPE_OPRATION,temp); free(pcmd); pthread_exit(NULL); } static void* cmd_NF_thread(void *arg) { int i,t=0; char temp[256]; cascade_handle_t *cas=&casHandle; slave_info_t *info=&cas->sInfo; GlobalDeviceManager *dm=get_dm(); cmd_data_t *pcmd=(cmd_data_t*)arg; if(pcmd->cmd==CASCADE_CMD_OPEN_NF) { LOGD("____ slave CASCADE_CMD_OPEN_NF\n"); } else { LOGD("____ slave CASCADE_CMD_CLOSE_NF\n"); } int flag=(pcmd->cmd==CASCADE_CMD_OPEN_NF)?1:0; if(pcmd->obj == OBJ_CHANNEL) { GlobalPowerManger *tmp=NULL; list_for_each_entry(tmp, &dm->_globalPowerManger.list, list) { if(tmp->product_ch_id==pcmd->chId) { t = g_switch_set_t_ac_chn_NF_ctrl(&dm->_globalRelaySampManger, tmp->product_saddr, tmp->product_ch_addr, flag); break; } } } if(pcmd->cmd==CASCADE_CMD_OPEN_NF) { sprintf(temp, "$开启$|$通道$|%d Naught wire!", pcmd->chId); } else { sprintf(temp, "$关闭$|$通道$|%d Naught wire!", pcmd->chId); } dev_insert_alarm_ctrl(dm->db, dm->_globalDevInfo.product.id,ALARM_TYPE_OPRATION,temp); free(pcmd); pthread_exit(NULL); } static int set_modbus(cascade_handle_t *cas, ModbusInfo_t *info) { int r; if(cas->inited) { mb_deinit(cas); } cas->mInfo = *info; //LOGD("master init modbus: port: %s, type: %d, baud: %d\n", CASCADE_MODBUS_PORT, info->mode, info->baudrate); r = mb_init(cas, CASCADE_MODBUS_PORT, info->mode, info->addr, info->baudrate); if(r!=0) { LOGE("cascade modbus init error.\n"); return -1; } if (cas->mInfo.mode==MODBUS_SLAVE) { for (size_t i = 1; i < CASCADE_MAX; i++) { slave_rm(cas,i); } } return 0; } int cascade_init(void) { int r=0; cascade_handle_t *cas=&casHandle; memset(cas, 0, sizeof(casHandle)); power_init(cas); breaker_slave_init(); slave_init(cas); r = pthread_mutex_init(&cas->mutex, NULL); if(r) { LOGE("___ cascade mutex init failed\n"); } r = pthread_mutex_init(&cas->mutex2, NULL); if(r) { LOGE("___ cascade mutex2 init failed\n"); } r = pthread_mutex_init(&cas->mutex3, NULL); if(r) { LOGE("___ cascade mutex3 init failed\n"); } cas->scanAddr = 1; cas->map = modbus_mapping_new_start_address(0,0,0,0, CASCADE_REG_READ, MAX_READ_REGS2, CASCADE_REG_WRITE, MAX_WRITE_REGS2); set_modbus(cas, get_mb()); cascade_slave_init(); slave_add(cas, 0); thread_start(THREAD_ID_CASCADE, cascade_thread, cas); thread_start(THREAD_ID_CASCADE_SCAN, cascade_scan_thread, cas); GlobalDeviceManager* dm =get_dm(); NetworkInfo_t net = {0}; sys_get_net(&net,IP_V4); uint8_t addr = 0; if(!dm->_globalDevInfo.cascade.mode) { addr = 0XFF; }else { addr = dm->_globalDevInfo.cascade.addr; } dm->md_tcp = tcp_modbus_init(net.ip_address,CASCADE_SLAVE_PORT,addr,dm->_globalDevInfo.product.pwr_type); thread_start(THREAD_ID_TCP, tcp_modbus_thread, NULL); return 0; } int cascade_deinit(void) { cascade_handle_t *cas=&casHandle; thread_stop(THREAD_ID_CASCADE); thread_stop(THREAD_ID_CASCADE_SCAN); pthread_mutex_destroy(&cas->mutex); pthread_mutex_destroy(&cas->mutex2); pthread_mutex_destroy(&cas->mutex3); modbus_mapping_free(cas->map); mb_deinit(cas); power_deinit(cas); return 0; } int cascade_set_modbus(ModbusInfo_t *info) { cascade_handle_t *cas=&casHandle; if(!info || info->addr>CASCADE_MAX) { return -1; } return set_modbus(cas, info); } int cascade_get_dlist(dev_list_t *dl) { int i,cnt=0; slave_t *sl=NULL; cascade_handle_t *cas=&casHandle; if(!dl) { return -1; } sl = (slave_t*)malloc(sizeof(slave_t)*(CASCADE_MAX+1)); if(!sl) { return -1; } for(i=0; i<=CASCADE_MAX; i++) { if(cas->slaves[i].addr>=0) { sl[cnt++] = cas->slaves[i]; } } dl->slave = sl; dl->cnt = cnt; LOGD("____dev cnt: %d\n", cnt); return 0; } /** * @brief 释放级联设备列表 * * 释放给定的级联设备列表(dev_list_t)中的 slave 成员所指向的内存。 * * @param dl 级联设备列表指针 * * @return 成功返回 0,失败返回 -1 */ int cascade_free_dlist(dev_list_t *dl) { if(!dl) { return -1; } free(dl->slave); return 0; } /** * @brief 级联请求 * * 根据给定的命令数据执行级联请求,并返回执行结果。 * * @param cmd 命令数据指针 * * @return 执行结果,成功返回0,失败返回-1 */ int cascade_request(cmd_data_t *cmd) { int r=0; cascade_handle_t *cas=&casHandle; if(!cmd) { return -1; } pthread_mutex_lock(&cas->mutex2); r = master_cmd(cas, cmd); pthread_mutex_unlock(&cas->mutex2); return r; } int cascade_get_all(_OverAllPwrAckInfo *all) { return 0; } int cascade_get_ch(_OverChnPwrAckInfo *ch) { GlobalPowerManger *tmp=NULL; GlobalTreeACManager *tmp3=NULL; _OverChnPwrAckInfo *pch=NULL; GlobalDeviceManager* dm2=get_dm2(); list_for_each_entry(tmp, &dm2->_globalPowerManger.list, list) { if (tmp->product_ch_type==TREE_AC_TYPE||dm2->_globalDevInfo.product.pwr_type == SmartPDU_Tree_AC_One_B){ int nStatus=-1;//-1则状态不变,0、1则是子状态 //判断是否三相单输出情况下 if(tmp->product_ch_type==TREE_AC_TYPE||dm2->_globalDevInfo.product.pwr_type == SmartPDU_Tree_AC_One_B) { list_for_each_entry(tmp3, &tmp->list_Tree_AC, list_Tree_AC) { if (2 == tmp3->product_ph_outputType &&1==tmp3->product_ph_outputStatus) {//单项并且状态为输出 nStatus = tmp3->_PowerInfo.status; } } } list_for_each_entry(tmp3, &tmp->list_Tree_AC, list_Tree_AC) { pch = (_OverChnPwrAckInfo *)malloc(sizeof(_OverChnPwrAckInfo)); if (pch == NULL) { LOGE("pch malloc err.\n"); return -1; } pch->product_name = dm2->_globalDevInfo.product.name; pch->product_number = dm2->_globalDevInfo.product.number; pch->product_id = dm2->_globalDevInfo.product.id; pch->productChName = tmp->product_ch_name; pch->productChId = tmp->product_ch_id; pch->status = tmp->_PowerInfo.status; pch->voltage = tmp->_PowerInfo.voltage; pch->current = tmp->_PowerInfo.current; pch->power = tmp->_PowerInfo.power; pch->freq = tmp->_PowerInfo.freq; pch->consumption = tmp->_PowerInfo.consumption; pch->factor = tmp->_PowerInfo.factor; pch->product_ch_start_delay = tmp->product_ch_start_delay; pch->product_ch_stop_delay = tmp->product_ch_stop_delay; pch->product_type=tmp->product_ch_type; pch->product_phType = tmp3->product_ph_type; pch->ph_voltage = tmp3->_PowerInfo.voltage; pch->ph_current = tmp3->_PowerInfo.current; pch->ph_power = tmp3->_PowerInfo.power; pch->ph_consumption = tmp3->_PowerInfo.consumption; pch->ph_outputType = tmp3->product_ph_outputType; pch->ph_outputStatus = tmp3->product_ph_outputStatus; if ((dm2->_globalDevInfo.product.pwr_type == SmartPDU_Tree_AC_One||dm2->_globalDevInfo.product.pwr_type == SmartPDU_Tree_AC_One_B) && tmp3->product_ph_outputType == 2 && tmp3->product_ph_outputStatus == 2) // 如果是单项输出并且则非输出通道数据为0 { // 3-1模式 单项状态,不输出则数据为空 pch->ph_voltage = 0.0; pch->ph_current = 0.0; pch->ph_power = 0.0; pch->ph_consumption = 0.0; } if (nStatus>=0) { pch->status = nStatus; }else { pch->status = tmp->_PowerInfo.status; } list_add_tail(&pch->list, &ch->list); } } else { pch = (_OverChnPwrAckInfo *)malloc(sizeof(_OverChnPwrAckInfo)); if (pch == NULL) { log_e("_overChnPwrBackInfoTemp malloc err."); return -1; } // 填数据 pch->product_name = dm2->_globalDevInfo.product.name; pch->product_number = dm2->_globalDevInfo.product.number; pch->product_id = dm2->_globalDevInfo.product.id; pch->productChName = tmp->product_ch_name; pch->productChId = tmp->product_ch_id; pch->status = tmp->_PowerInfo.status; pch->voltage = tmp->_PowerInfo.voltage; pch->current = tmp->_PowerInfo.current; pch->power = tmp->_PowerInfo.power; pch->freq = tmp->_PowerInfo.freq; pch->consumption = tmp->_PowerInfo.consumption; pch->factor = tmp->_PowerInfo.factor; pch->product_ch_start_delay = tmp->product_ch_start_delay; pch->product_ch_stop_delay = tmp->product_ch_stop_delay; list_add_tail(&pch->list, &ch->list); } } return 0; } int cascade_lock(void) { cascade_handle_t *cas=&casHandle; return pthread_mutex_lock(&cas->mutex); } int cascade_unlock(void) { cascade_handle_t *cas=&casHandle; return pthread_mutex_unlock(&cas->mutex); }