bool ModVArchEl::setValsProc( TValBuf &buf, int64_t beg, int64_t end ) { if(needMeta && (needMeta=!readMeta())) return false; //Check border if(!buf.vOK(beg,end)) return false; beg = vmax(beg, buf.begin()); end = vmin(end, buf.end()); beg = (beg/period())*period(); end = (end/period())*period(); //Table struct init TConfig cfg((archive().valType()==TFld::Real) ? (&mod->vlRealEl()) : (archive().valType()==TFld::String) ? (&mod->vlStrEl()) : &mod->vlIntEl()); AutoHD<TTable> tbl = SYS->db().at().open(archivator().addr()+"."+archTbl(), true); if(tbl.freeStat()) return false; //Write data to table for(int64_t ctm; beg <= end; beg++) { switch(archive().valType()) { case TFld::Boolean: cfg.cfg("VAL").setI(buf.getB(&beg,true)); break; case TFld::Integer: cfg.cfg("VAL").setI(buf.getI(&beg,true)); break; case TFld::Real: cfg.cfg("VAL").setR(buf.getR(&beg,true)); break; case TFld::String: cfg.cfg("VAL").setS(buf.getS(&beg,true)); break; default: break; } ctm = (beg/period())*period(); cfg.cfg("TM").setI(ctm/1000000); cfg.cfg("TMU").setI(ctm%1000000); tbl.at().fieldSet(cfg); //Archive time border update mBeg = mBeg ? vmin(mBeg,ctm) : ctm; mEnd = mEnd ? vmax(mEnd,ctm) : ctm; } //Archive size limit process if((mEnd-mBeg) > (int64_t)(archivator().maxSize()*3600e6)) { int64_t n_end = ((mEnd-(int64_t)(archivator().maxSize()*3600e6))/period())*period(); for(int64_t t_c = vmax(mBeg,n_end-3600ll*period()); t_c < n_end; t_c += period()) { cfg.cfg("TM").setI(t_c/1000000, true); cfg.cfg("TMU").setI(t_c%1000000, true); tbl.at().fieldDel(cfg); } mBeg = n_end; } tbl.free(); SYS->db().at().close(archivator().addr()+"."+archTbl()); //Update archive info cfg.setElem(&mod->archEl()); cfg.cfgViewAll(false); cfg.cfg("TBL").setS(archTbl(), true); cfg.cfg("BEGIN").setS(ll2s(mBeg), true); cfg.cfg("END").setS(ll2s(mEnd), true); cfg.cfg("PRM1").setS(ll2s(mPer), true); return SYS->db().at().dataSet(archivator().addr()+"."+mod->mainTbl(),"",cfg,false,true); }
string TMdContr::modBusReq( string &pdu, bool MC, bool broadCast ) { char buf[1024]; string mbap, rez, err; try { //Transport creation for MC and MR busses and connect AutoHD<TTransportOut> tro = SYS->transport().at().nodeAt(MC?"Serial.out_SMH2Gi_MC":"Serial.out_SMH2Gi_MR", 0, '.', 0, true); if(tro.freeStat()) { SYS->transport().at().at("Serial").at().outAdd(MC?"SMH2Gi_MC":"SMH2Gi_MR"); tro = SYS->transport().at().nodeAt(MC?"Serial.out_SMH2Gi_MC":"Serial.out_SMH2Gi_MR", 0, '.', 0, true); // Typical parameters set tro.at().setDscr(TSYS::strMess(_("Segnetics SMH2Gi automatic created transport for '%s' bus"),MC?"MC":"MR")); tro.at().setAddr(MC?(cfg("MC_DEV").getS()+":230400:8N1"):(cfg("MR_DEV").getS()+":230400:8N2")); } ResAlloc resN(tro.at().nodeRes(), true); //Start stoped transport if(!tro.at().startStat()) tro.at().start(); //Prepare request mbap.reserve(pdu.size()+2); mbap += pdu; uint16_t crc = CRC16(mbap); mbap += (crc>>8); mbap += crc; //Send request for(int i_tr = 0; i_tr < connTry; i_tr++) { if(messLev() == TMess::Debug) mess_debug_(nodePath().c_str(), _("ModBUS REQ -> '%s': %s"), tro.at().id().c_str(), TSYS::strDecode(mbap,TSYS::Bin," ").c_str()); int resp_len = tro.at().messIO(mbap.data(), mbap.size(), (broadCast?NULL:buf), sizeof(buf), 0, true); if(broadCast) { err = ""; break; } rez.assign(buf, resp_len); //Wait tail while(resp_len) { try{ resp_len = tro.at().messIO(NULL, 0, buf, sizeof(buf), 0, true); } catch(TError err){ break; } rez.append(buf, resp_len); } if(rez.size() < 2) { err = _("13:Error respond: Too short."); continue; } if(CRC16(rez.substr(0,rez.size()-2)) != (uint16_t)((rez[rez.size()-2]<<8)+(uint8_t)rez[rez.size()-1])) { err = _("13:Error respond: CRC check error."); continue; } if(messLev() == TMess::Debug) mess_debug_(nodePath().c_str(), _("ModBUS RESP -> '%s': %s"), tro.at().id().c_str(), TSYS::strDecode(rez,TSYS::Bin," ").c_str()); pdu = rez.substr(0, rez.size()-2); err = ""; break; } } catch(TError ierr) { err = "10:"+ierr.mess; } if(messLev() >= TMess::Error && err.size()) mess_err(nodePath().c_str(), "%s", err.c_str()); if(messLev() == TMess::Debug && err.size()) mess_debug_(nodePath().c_str(), _("ModBUS ERR -> %s: %s"), TSYS::strDecode(mbap,TSYS::Bin," ").c_str(), err.c_str()); return err; }
bool ModMArch::put( vector<TMess::SRec> &mess, bool force ) { if(needMeta && (needMeta=!readMeta())) return false; TMArchivator::put(mess, force); //Allow redundancy if(!runSt) throw TError(nodePath().c_str(), _("The archive is not started!")); AutoHD<TTable> tbl = SYS->db().at().open(addr()+"."+archTbl(), true); if(tbl.freeStat()) return false; TConfig cfg(&reqEl); int64_t t_cnt = TSYS::curTime(); for(unsigned i_m = 0; i_m < mess.size(); i_m++) { if(!chkMessOK(mess[i_m].categ,mess[i_m].level)) continue; //Put record to DB cfg.cfg("MIN").setI(mess[i_m].time/60); cfg.cfg("TM").setI(mess[i_m].time); cfg.cfg("TMU").setI(mess[i_m].utime); cfg.cfg("CATEG").setS(mess[i_m].categ); cfg.cfg("MESS").setS(mess[i_m].mess); cfg.cfg("LEV").setI(mess[i_m].level); tbl.at().fieldSet(cfg); //Archive time border update mBeg = mBeg ? vmin(mBeg,mess[i_m].time) : mess[i_m].time; mEnd = mEnd ? vmax(mEnd,mess[i_m].time) : mess[i_m].time; } //Archive size limit process if(maxSize() && (mEnd-mBeg) > (time_t)(maxSize()*86400)) { time_t nEnd = mEnd - (time_t)(maxSize()*86400); cfg.cfg("TM").setKeyUse(false); for(int tC = mBeg/60; tC < nEnd/60; tC++) { cfg.cfg("MIN").setI(tC, true); tbl.at().fieldDel(cfg); } mBeg = nEnd; } tbl.free(); //SYS->db().at().close(addr()+"."+archTbl()); //!!! No close the table manually //Update archive info cfg.setElem(&mod->archEl()); cfg.cfgViewAll(false); cfg.cfg("TBL").setS(archTbl(),true); cfg.cfg("BEGIN").setS(i2s(mBeg),true); cfg.cfg("END").setS(i2s(mEnd),true); bool rez = SYS->db().at().dataSet(addr()+"."+mod->mainTbl(),"",cfg,false,true); tmProc = TSYS::curTime() - t_cnt; tmProcMax = vmax(tmProcMax, tmProc); return rez; }
void TSocketIn::messPut( int sock, string &request, string &answer, string sender, AutoHD<TProtocolIn> &prot_in ) { AutoHD<TProtocol> proto; string n_pr = mod->modId()+"_"+id()+"_"+TSYS::int2str(sock); try { proto = SYS->protocol().at().modAt(protocol()); if( prot_in.freeStat() ) { if( !proto.at().openStat(n_pr) ) proto.at().open( n_pr, workId() ); prot_in = proto.at().at( n_pr ); } if( prot_in.at().mess(request,answer,sender) ) return; prot_in.free(); if( proto.at().openStat(n_pr) ) proto.at().close(n_pr); }catch(TError err) { prot_in.free(); if( !proto.freeStat() && proto.at().openStat(n_pr) ) proto.at().close( n_pr ); mess_err(nodePath().c_str(),"%s",err.mess.c_str() ); mess_err(nodePath().c_str(),_("Error request to protocol.")); } }
bool ModMArch::put( vector<TMess::SRec> &mess ) { if(!run_st) throw TError(nodePath().c_str(), _("Archive is not started!")); AutoHD<TTable> tbl = SYS->db().at().open(addr()+"."+archTbl(), true); if(tbl.freeStat()) return false; TConfig cfg(&mod->messEl()); int64_t t_cnt = TSYS::curTime(); for(unsigned i_m = 0; i_m < mess.size(); i_m++) { if(!chkMessOK(mess[i_m].categ,mess[i_m].level)) continue; //Put record to DB cfg.cfg("TM").setI(mess[i_m].time); cfg.cfg("TMU").setI(mess[i_m].utime); cfg.cfg("CATEG").setS(mess[i_m].categ); cfg.cfg("MESS").setS(mess[i_m].mess); cfg.cfg("LEV").setI(mess[i_m].level); tbl.at().fieldSet(cfg); //Archive time border update mBeg = mBeg ? vmin(mBeg,mess[i_m].time) : mess[i_m].time; mEnd = mEnd ? vmax(mEnd,mess[i_m].time) : mess[i_m].time; } //Archive size limit process if((mEnd-mBeg) > (time_t)(maxSize()*3600)) { time_t n_end = mEnd-(time_t)(maxSize()*3600); for(time_t t_c = vmax(mBeg,n_end-3600); t_c < n_end; t_c++) { cfg.cfg("TM").setI(t_c,true); tbl.at().fieldDel(cfg); } mBeg = n_end; } tbl.free(); SYS->db().at().close(addr()+"."+archTbl()); //Update archive info cfg.setElem(&mod->archEl()); cfg.cfgViewAll(false); cfg.cfg("TBL").setS(archTbl(),true); cfg.cfg("BEGIN").setS(i2s(mBeg),true); cfg.cfg("END").setS(i2s(mEnd),true); bool rez = SYS->db().at().dataSet(addr()+"."+mod->mainTbl(),"",cfg,false,true); tm_calc = 1e-3*(TSYS::curTime()-t_cnt); return rez; }
//************************************************* //* Control request * //************************************************* void xmlCntrReq::calc( TValFunc *val ) { try { XMLNode req; AutoHD<XMLNodeObj> xnd = val->getO(1); if(xnd.freeStat()) { val->setS(0,_("1:Request is not object!")); return; } xnd.at().toXMLNode(req); string path = req.attr("path"); if(val->getS(2).empty()) { req.setAttr("user", val->user()); SYS->cntrCmd(&req); } else { req.setAttr("path", "/"+val->getS(2)+path); SYS->transport().at().cntrIfCmd(req, "xmlCntrReq"); req.setAttr("path", path); } xnd.at().fromXMLNode(req); val->setS(0, "0"); }catch(TError err){ val->setS(0, TSYS::strMess(_("1:Request error: %s"),err.mess.c_str())); } }
int TMdContr::recordCallback( const void *iBuf, void *oBuf, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ) { TMdContr &cntr = *(TMdContr*)userData; cntr.prcSt = true; const char *bptr = (const char*)iBuf; if(cntr.redntUse()) { cntr.prcSt = false; return cntr.endrunReq; } //Set priority for call task if(cntr.firstCall) { int policy = SCHED_OTHER; struct sched_param prior; pthread_getschedparam(pthread_self(), &policy, &prior); #if __GLIBC_PREREQ(2,4) if(cntr.prior() < 0) policy = SCHED_BATCH; #endif if(cntr.prior() > 0) { policy = SCHED_RR; prior.sched_priority = cntr.prior(); } if(pthread_setschedparam(pthread_self(), SCHED_FIFO, &prior) == EPERM) setpriority(PRIO_PROCESS, syscall(SYS_gettid), -cntr.prior()/5); cntr.firstCall = false; } //Check for current time correction int64_t t_sz = (1000000ll*framesPerBuffer)/cntr.sRt; double err = ((timeInfo->inputBufferAdcTime-cntr.inAdcTimePrev)-1e-6*t_sz)/(1e-6*t_sz); //Pass short framesPerBuffer by incorrect cntr.framesPerBufferMax = vmax(cntr.framesPerBufferMax,framesPerBuffer); if(framesPerBuffer < cntr.framesPerBufferMax) { cntr.inAdcTimePrev = timeInfo->inputBufferAdcTime; return paContinue; } // Lost frames process if(cntr.inAdcTimePrev > 0 && err > 0.001) { cntr.wTm += (int64_t)((double)t_sz*err); mess_warning(cntr.nodePath().c_str(), _("CallBack: Lost frames correct: framesPerBuffer=%lu; sRt=%d; t_sz=%lld; err=%g; diff=%lld."), framesPerBuffer, cntr.sRt, t_sz, err, (TSYS::curTime()-cntr.wTm)); cntr.lostFrmsCntr++; } // Sound counter difference from time clock correction else if(cntr.inAdcTimeAdj < 0 || (timeInfo->inputBufferAdcTime-cntr.inAdcTimeAdj) >= 60) { int64_t dTm = TSYS::curTime()-cntr.wTm; if(cntr.inAdcTimeAdj > 0) cntr.sRt -= (dTm-cntr.tmAdj)*cntr.sRt/60000000; if(cntr.messLev() == TMess::Debug) mess_debug_(cntr.nodePath().c_str(), _("CallBack: Sound counter difference fix: sRt=%d; dTm=%lld."), cntr.sRt, dTm); cntr.tmAdj = dTm; cntr.inAdcTimeAdj = timeInfo->inputBufferAdcTime; } cntr.inAdcTimePrev = timeInfo->inputBufferAdcTime; //Input buffer process ResAlloc res(cntr.nodeRes(),false); for(unsigned i_p = 0; i_p < cntr.pHd.size(); i_p++) { int chn = cntr.pHd[i_p].at().iCnl(); AutoHD<TVal> val = cntr.pHd[i_p].at().vlAt("val"); AutoHD<TVArchive> arch = val.at().arch(); bool archAllow = (!arch.freeStat() && arch.at().srcMode() == TVArchive::PassiveAttr); switch(cntr.mSmplType) { case paFloat32: if(archAllow) for(int64_t i_t = 0; i_t < t_sz; i_t += arch.at().period()) arch.at().setR(*(float*)(bptr+cntr.smplSize*((i_t*framesPerBuffer/t_sz)*cntr.numChan+chn)), cntr.wTm+i_t); if(SYS->sysTm() > cntr.cTm) { val.at().setR(*(float*)(bptr+cntr.smplSize*((framesPerBuffer-1)*cntr.numChan+chn)),cntr.wTm+(1000000ll*(framesPerBuffer-1))/cntr.sRt,true); cntr.cTm = SYS->sysTm(); } break; case paInt32: if(archAllow) for(int64_t i_t = 0; i_t < t_sz; i_t += arch.at().period()) arch.at().setI(*(int32_t*)(bptr+cntr.smplSize*((i_t*framesPerBuffer/t_sz)*cntr.numChan+chn)), cntr.wTm+i_t); if(SYS->sysTm() > cntr.cTm) { val.at().setI(*(int32_t*)(bptr+cntr.smplSize*((framesPerBuffer-1)*cntr.numChan+chn)),cntr.wTm+(1000000ll*(framesPerBuffer-1))/cntr.sRt,true); cntr.cTm = SYS->sysTm(); } break; case paInt16: if(archAllow) for(int64_t i_t = 0; i_t < t_sz; i_t += arch.at().period()) arch.at().setI(*(int16_t*)(bptr+cntr.smplSize*((i_t*framesPerBuffer/t_sz)*cntr.numChan+chn)), cntr.wTm+i_t); if(SYS->sysTm() > cntr.cTm) { val.at().setI(*(int16_t*)(bptr+cntr.smplSize*((framesPerBuffer-1)*cntr.numChan+chn)),cntr.wTm+(1000000ll*(framesPerBuffer-1))/cntr.sRt,true); cntr.cTm = SYS->sysTm(); } break; } } cntr.wTm += t_sz; cntr.acqSize += (float)(framesPerBuffer*cntr.smplSize*cntr.numChan)/1048576; cntr.prcSt = false; return cntr.endrunReq; }