Класс SEESGroup

#include <SEESGroup.h>

Граф связей класса SEESGroup:

Collaboration graph
[см. легенду]

Полный список членов класса

Классы

struct  ReservInfo

Открытые типы

typedef std::list< ReservInfoRList

Открытые члены

 SEESGroup (int num, const std::string &name="")
int getNumber ()
std::string getName ()
long getP ()
long getU ()
long getF ()
bool isUdev ()
bool isFdev ()
long getReservPower ()
void step ()
void update ()
void updatePowerInfo ()
void requiredReserv (bool set)
bool isNoReserv ()
bool isReadyForLoading ()
void addGroup (SEESGroup *gr)
bool add (SEES *ses)
bool del (SEES *ses)
void clear ()
bool isProtection ()
int acceptQG (int num) throw (UniSetTypes::NameNotFound)
void releaseQG (int num) throw (UniSetTypes::NameNotFound)
bool canRun (int num) throw (UniSetTypes::NameNotFound)
SEESget (int num)
SESList getSESList ()
void setReservStatePause (int s)
void setCommandTimeout (int s)
void setReservTime (int s)
void setMaxWorkingDG (int s)
int getWorkingDG ()
void setFdev (int f_min_, int f_max_, int f_msec)
void setUdev (int u_min_, int u_max_, int U_msec)

Открытые статические члены

static void init_dlog (DebugStream &dlog)

Статические открытые данные

static DebugStream dlog

Защищенные члены

void reserv (bool set)
void checkReserv ()
bool resetReserv ()
void makeReservList ()
void checkAloneWorking ()
void updateCounters ()

Защищенные статические члены

static void update (RList &rlist, ReservInfo &ri)

Защищенные данные

UniSetTypes::uniset_mutex lstMutex
int gnum
std::string myname
int qf_locked
SESList lst
SEESleader
RList rlst
int maxWorkingDG
int countWorkingDG
UniSetTypes::uniset_mutex maxrunMutex
int reservStatePause
int reservCommandTimeout
int checkReservTime
PassiveTimer ptCheckReserv
int f_min
int f_max
int U_min
int U_max
SandClock sc_Fdev
SandClock sc_Udev
bool U_dev
bool f_dev

Друзья

std::ostream & operator<< (std::ostream &os, SEESGroup &g)
std::ostream & operator<< (std::ostream &os, SEESGroup *g)
std::ostream & print_chain (std::ostream &os, SEESGroup *g)


Подробное описание

Реализация управления группой СЭС

Методы

int SEESGroup::acceptQG ( int  num  )  throw (UniSetTypes::NameNotFound)

захват приоритета включения генераторного автомата

Возвращает:
Номер текущего держателя. Если захват удаётся. То возвращаемое значение будет равно num.
00576 {
00577     { // lock
00578         UniSetTypes::uniset_mutex_lock lock(lstMutex, 5000);
00579 
00580         if( qf_locked != 0 )
00581         {
00582             if( qf_locked == num )
00583             {
00584                 if( SEESGroup::dlog.debugging(Debug::INFO) )
00585                     SEESGroup::dlog[Debug::INFO] << myname << "(acceptQG): QG" << num << " ALREADY ACCEPTED..." << endl;
00586                 return qf_locked;
00587             }
00588 
00589             if( SEESGroup::dlog.debugging(Debug::INFO) )
00590                 SEESGroup::dlog[Debug::INFO] << myname << "(acceptQG): NOT ACCEPT QG" << num << " qf locked..." << endl;
00591             return qf_locked;
00592         }
00593 
00594         for( SESList::iterator it=lst.begin(); it!=lst.end(); ++it )
00595         {
00596             SEES* s(*it);
00597             if( s->isHaveQGLock() )
00598             {
00599                 if( (*it)->getNumber() == num )
00600                 {
00601                     if( SEESGroup::dlog.debugging(Debug::INFO) )
00602                         SEESGroup::dlog[Debug::INFO] << myname << "(acceptQG): REPEAT ACCEPT QG" << num << endl;
00603                     qf_locked = num;
00604                     return qf_locked;
00605                 }
00606 
00607                 if( SEESGroup::dlog.debugging(Debug::INFO) )
00608                     SEESGroup::dlog[Debug::INFO] << myname << "(acceptQG): NOT ACCEPT QG" << num
00609                         << " but blocked ses" << (*it)->getNumber() << endl;
00610                 s->setQGLock(true);
00611                 qf_locked = (*it)->getNumber();
00612                 return qf_locked;
00613             }
00614         }
00615     }
00616 
00617     ostringstream err;
00618     err <<  myname << "(acceptQG): Not found ses" + num;
00619     throw NameNotFound(err.str());
00620 }

void SEESGroup::checkAloneWorking (  )  [protected]

обновление информации о том "один ли ДГ на шинах"

Перекрестные ссылки lst.

00692 {
00693   { // lock
00694         UniSetTypes::uniset_mutex_lock lock(lstMutex, 4000);
00695         int count = getWorkingDG();
00696         if( count > 0 )
00697         {
00698             for( SESList::iterator it=lst.begin(); it!=lst.end(); ++it )
00699             {
00700                 if( (*it)->isOnMode() )
00701                 {
00702                     if( count == 1 )
00703                         (*it)->setAloneWorking(true);
00704                     else
00705                         (*it)->setAloneWorking(false);
00706                 }
00707                 else
00708                     (*it)->setAloneWorking(false);
00709             }
00710         }
00711         else
00712         {
00713             for( SESList::iterator it=lst.begin(); it!=lst.end(); ++it )
00714                 (*it)->setAloneWorking(true);
00715         }
00716   }// unlock
00717 }

void SEESGroup::checkReserv (  )  [protected]

проверка необходимости запуска/остановки резерва

Перекрестные ссылки leader, myname, reserv(), resetReserv() и rlst.

00191 {
00192     UniSetTypes::uniset_mutex_lock lock(lstMutex, 5000);
00193     bool needCheck = false;
00194 
00195     if( !leader )
00196     {
00197         if( SEESGroup::dlog.debugging(Debug::LEVEL4) )
00198             SEESGroup::dlog[Debug::LEVEL4] << myname << "(checkReserv): ignore.. no leader.." << endl;
00199         return;
00200     }
00201 
00202     if( leader->isReservOnNeeded() )
00203     {
00204         if( SEESGroup::dlog.debugging(Debug::LEVEL4) )
00205             SEESGroup::dlog[Debug::LEVEL4] << myname << "(checkReserv): needON for "
00206                 << leader->getName() << endl;
00207 
00208         reserv(true);
00209         needCheck = true;
00210     }
00211     else if( leader->isReservOffNeeded() )
00212     {
00213         if( SEESGroup::dlog.debugging(Debug::LEVEL4) )
00214             SEESGroup::dlog[Debug::LEVEL4] << myname << "(checkReserv): needOFF for "
00215                 << leader->getName() << endl;
00216 
00217         reserv(false);
00218         needCheck = true;
00219     }
00220     else
00221     {
00222         // Сбрасываем все таймеры и тригеры
00223         // т.к. резерв никому не требуется
00224         for( RList::iterator it=rlst.begin(); it!=rlst.end(); ++it )
00225         {
00226             it->ptPause.setTiming(0);
00227             it->trChangeState.hi(true);
00228             it->waitRunning = false;
00229             it->waitStopping = false;
00230         }
00231         
00232         resetReserv();
00233     }
00234 
00235     if( !needCheck )
00236         ptCheckReserv.setTiming(UniSetTimer::WaitUpTime);
00237 }

long SEESGroup::getF (  ) 

частота

Перекрестные ссылки lst.

Используется в UnionGroups::updateF() и updatePowerInfo().

00750 {
00751     // при параллельном включении:
00752     // частоты одинаковые
00753     { // lock
00754         UniSetTypes::uniset_mutex_lock lock(lstMutex, 3000);
00755         for( SESList::iterator it=lst.begin(); it!=lst.end(); ++it )
00756         {
00757             if( (*it)->getF() > 0 )
00758                 return (*it)->getF();
00759         }
00760     } // unlock
00761 
00762     return 0;
00763 }

long SEESGroup::getP (  ) 

суммарная мощность

Перекрестные ссылки lst.

Используется в UnionGroups::updateP().

00720 {
00721     // при параллельном включении:
00722     // мощности складываются..
00723     long P=0;
00724     { // lock 
00725         UniSetTypes::uniset_mutex_lock lock(lstMutex, 3000);
00726         for( SESList::iterator it=lst.begin(); it!=lst.end(); ++it )
00727             P += (*it)->getP();
00728     } // unlock
00729 
00730     return P;
00731 }

long SEESGroup::getReservPower (  ) 

резерв мощности

Перекрестные ссылки lst.

Используется в UnionGroups::updateReservPower().

00766 {
00767     long Pres=0;
00768 
00769     { // lock
00770         UniSetTypes::uniset_mutex_lock lock(lstMutex, 3000);    
00771         for( SESList::iterator it=lst.begin(); it!=lst.end(); ++it )
00772             Pres += (*it)->getReservPower();
00773     } // unlock
00774 
00775     return Pres;
00776 }

long SEESGroup::getU (  ) 

напряжение

Перекрестные ссылки lst.

Используется в updatePowerInfo() и UnionGroups::updateU().

00734 {
00735     // при параллельном включении:
00736     // напряжения одинаковые
00737     { // lock
00738         UniSetTypes::uniset_mutex_lock lock(lstMutex, 3000);
00739         for( SESList::iterator it=lst.begin(); it!=lst.end(); ++it )
00740         {
00741             if( (*it)->getU() > 0 )
00742                 return (*it)->getU();
00743         }
00744     } // unlock
00745 
00746     return 0;
00747 }

bool SEESGroup::isFdev (  ) 

отклонение частоты от нормы

Перекрестные ссылки f_dev.

Используется в UnionGroups::updateFdev().

00793 {
00794     return f_dev;
00795 }

bool SEESGroup::isProtection (  ) 

Есть ли хоть одна сработавшая защита

Перекрестные ссылки lst.

00647 {
00648     UniSetTypes::uniset_mutex_lock lock(lstMutex, 4000);
00649     for( SESList::iterator it=lst.begin(); it!=lst.end(); ++it )
00650     {
00651         if( (*it)->isProtection() )
00652             return true;
00653     }
00654 
00655     return false;
00656 }

bool SEESGroup::isReadyForLoading (  ) 

готова ли группа к приёму нагрузки

Перекрестные ссылки lst.

Используется в UnionGroups::updateReadyForLoading().

00166 {
00167     // если есть хоть один работющий ДГ и он не перегружен (не требует резерва), то СЭС готова.
00168     UniSetTypes::uniset_mutex_lock lock(lstMutex, 5000);
00169     for( SESList::iterator it=lst.begin(); it!=lst.end(); ++it )
00170     {
00171         if( (*it)->isOnMode() && !(*it)->isReservOnNeeded() )
00172             return true;
00173     }
00174 
00175     return false;
00176 }

bool SEESGroup::isUdev (  ) 

отклонение напряжения от нормы

Перекрестные ссылки U_dev.

Используется в UnionGroups::updateUdev().

00788 {
00789     return U_dev;
00790 }

void SEESGroup::makeReservList (  )  [protected]

обновление списка резервных ДГ

Перекрестные ссылки SEES::isAutoControl(), SEES::isOnMode(), leader, lst, myname и rlst.

00421 {
00422     UniSetTypes::uniset_mutex_lock lock(lstMutex, 5000);
00423 
00424     // проходим по списку СЭС в группе
00425     // определяем главный ДГ (он должен быть один)
00426     // и какие есть резервные ДГ
00427     SEES* main = 0;
00428     RList rlist;
00429 
00430     // Т.к. самым приоритетным считается ДГ с наименьшим заданным приоритетом,
00431     // то строим список резервных так: делаем map, сортируем по возрастанию приоритета
00432     // и строим уже список резервных
00433     // в map - добавляем только те ДГ, которые находятся в режиме "авто"
00434     typedef std::map<int,SEES*> PriorityMap;
00435     PriorityMap prmap;
00436     
00437     for( SESList::iterator it=lst.begin(); it!=lst.end(); ++it )
00438     {
00439         SEES* ses(*it);
00440 
00441         if( ses->isAutoControl() && ses->getPriority()>0 )
00442             prmap[ses->getPriority()] = ses;
00443         else
00444             ses->setLeader(false); // просто на всякий сбрасываем флаг
00445             
00446         // если ГДГ не в режиме автомат, сбрасываем команды управления резервом
00447         if( !ses->isAutoControl() )
00448             ses->resetReservCommand();
00449     }
00450 
00451     // формируем список резервных на основе "карты приоритетов"
00452     if( !prmap.empty() )
00453     {
00454         PriorityMap::iterator it=prmap.begin();
00455         // первый в списке, это самый приоритетный
00456         main = it->second;
00457         it++;
00458         // остальные добавляем в список в соответсвии с приоритетом
00459         while( it!=prmap.end() )
00460         {
00461             rlist.push_back(it->second);
00462             it++;
00463         }
00464     }
00465 
00466     // -------------------
00467     // Есть особый случай:
00468     // Допустим, что НЕ приоритетный дизель, до перевода в "автомат"
00469     // был в ручную запущен. А переключателем "приоритета пуска"
00470     // выставлен приоритетным другой дизель. То после перевода обоих ДГ
00471     // в режим "автомат" будет противоречивое состояние:
00472     // Тот дизель который должен быть основным (и по идее начать автоматически запускаться)
00473     // не запущен, а тот который должен быть резервным (и должен быть остановлен),
00474     // оказывается запущенным (уже на шинах).
00475     // Для решения этого вопроса, здесь реализована следующая логика:
00476     // Если найденный "потенциальный" лидер, не запущен, то мы смотрим,
00477     // нет ли среди списка резервных уже запущенного. Если есть, то находим,
00478     // среди запущенных (резервных), ДГ с наименьшим приоритетом  и делаем его лидером.
00479     // А нашего "потенциального" лидера (если был до этого найден),
00480     // переводим в список резервных.
00481     if( !main || (main && !main->isOnMode()) )
00482     {
00483         RList::iterator rit = rlist.end();
00484         for( RList::iterator it=rlist.begin(); it!=rlist.end(); ++it )
00485         {
00486             if( !it->ses->isOnMode() )
00487                 continue;
00488 
00489             long prior = it->ses->getPriority();
00490             if( rit == rlist.end() || ( prior>0 && prior < rit->ses->getPriority() ))
00491                 rit = it;
00492         }
00493 
00494         // если нашли среди резервных "запущенный"
00495         if( rit != rlist.end() )
00496         {
00497             if( main )
00498             {
00499                 // сперва добавляем "бывшего" лидера в список резервных
00500                 ReservInfo ri(main);
00501                 rlist.push_back(ri);
00502             }
00503 
00504             // запоминаем нового лидера
00505             main = rit->ses;
00506             // удаляем его из списка резервных
00507             rlist.erase(rit);
00508         }
00509     }
00510     
00511     // -------------------
00512     if( !main )
00513     {
00514         // Если не нашли (явного) приоритетного лидера (например у всех одинаковый приоритет)
00515         // а список резервных не пустой
00516         // то берём из резервных с наименьшим номером
00517         // и делаем его лидером (удалив из списка резервных)
00518         RList::iterator rit = rlist.end();
00519         if( !rlist.empty() )
00520         {
00521             for( RList::iterator it=rlist.begin(); it!=rlist.end(); ++it )
00522             {
00523                 long num = it->ses->getNumber();
00524                 if( rit == rlist.end() || num < rit->ses->getNumber() )
00525                     rit = it;
00526             }
00527 
00528             if( rit != rlist.end() )
00529             {
00530                 main = rit->ses;
00531                 rlist.erase(rit);
00532             }
00533         }
00534     }
00535 
00536     // ------------------
00537     if( main )
00538     {
00539         // чтобы сохранить работу внутренних таймеров структуры ReservInfo 
00540         // надо в новом списке обновить информацию взяв из старого
00541         for( RList::iterator it=rlst.begin(); it!=rlst.end(); ++it )
00542             update( rlist, (*it) );
00543 
00544         leader  = main;
00545         rlst    = rlist;
00546         if( SEESGroup::dlog.debugging(Debug::LEVEL4) )
00547         {
00548             SEESGroup::dlog[Debug::LEVEL4] << myname << "(makeReservList): For leader='ses" << main->getNumber()
00549             << "' reserv(" << rlist.size() << "): [";
00550             for( RList::iterator it=rlst.begin(); it!=rlst.end(); ++it )
00551                SEESGroup::dlog(Debug::LEVEL4) << " ses" << it->ses->getNumber(); // << ")" << it->ses->getName();
00552             SEESGroup::dlog(Debug::LEVEL4) <<  " ]" << endl;
00553         }
00554 
00555         // выставляем у всех признак, что они в резерве (не лидеры)
00556         for( RList::iterator it=rlst.begin(); it!=rlst.end(); ++it )
00557         {
00558             try
00559             {
00560                 it->ses->setLeader(false);
00561             }
00562             catch(...){}
00563         }
00564         // и выставляем режим у "ведущего"
00565         leader->setLeader(true);
00566     }
00567     else
00568     {
00569         SEESGroup::dlog[Debug::LEVEL4] << myname << "(makeReservList): LEADER not found..." << endl;
00570         leader = 0;
00571         rlst.clear();
00572     }
00573 }

void SEESGroup::releaseQG ( int  num  )  throw (UniSetTypes::NameNotFound)

освобождение приоритета включения генераторного автомата Проверка можно ли запускать указанный СЭС например ограничение по максимльному разрешенному количеству одновременно работющих ДГ на шинах

00623 {
00624     { // lock
00625         UniSetTypes::uniset_mutex_lock lock(lstMutex, 4000);
00626         for( SESList::iterator it=lst.begin(); it!=lst.end(); ++it )
00627         {
00628             SEES* s(*it);
00629             if( s->getNumber() == num )
00630             {
00631                 if( s->isHaveQGLock() )
00632                     SEESGroup::dlog[Debug::INFO] << myname << "(releaseQG): RELEASE QG" << num << endl;
00633 
00634                 s->setQGLock(false);
00635                 qf_locked = 0;
00636                 return;
00637             }
00638         }
00639     }
00640 
00641     ostringstream err;
00642     err <<  myname << "(acceptQG): Not found ses" + num;
00643     throw NameNotFound(err.str());
00644 }

void SEESGroup::requiredReserv ( bool  set  ) 

выставление признака требуется резерв

Перекрестные ссылки lst.

00779 {
00780     { // lock
00781         UniSetTypes::uniset_mutex_lock lock(lstMutex, 3000);
00782         for( SESList::iterator it=lst.begin(); it!=lst.end(); ++it )
00783             (*it)->requiredReserv(set);
00784     } // unlock
00785 }

void SEESGroup::reserv ( bool  set  )  [protected]

функция запуска или остановки резерва

Перекрестные ссылки SEES::isProtection(), myname, rlst, SEESGroup::ReservInfo::waitRunning и SEESGroup::ReservInfo::waitStopping.

Используется в checkReserv().

00240 {
00241     // UniSetTypes::uniset_mutex_lock lock(lstMutex, 5000);
00242     if( SEESGroup::dlog.debugging(Debug::LEVEL4) )
00243     {
00244         SEESGroup::dlog[Debug::LEVEL4] << myname << "(reserv):"
00245                     << " set=" << set
00246                     << " rlist=" << rlst.size() << endl;
00247     }
00248     
00249     if( rlst.empty() )
00250     {
00251         SEESGroup::dlog[Debug::LEVEL4] << myname
00252             << "(reserv): rlst=0 RESERV NOT FOUND" << endl;
00253         
00254         ptCheckReserv.setTiming(UniSetTimer::WaitUpTime);
00255         return;
00256     }
00257 
00258     // Проходим по списку резервных 
00259     // и ищем кто готов запускатся..
00260     // Т.к. список выстроен в соответсвии с приоритетом
00261     // то можно остановиться на первом подходящем
00262     
00263     // Если нам нужно запускать ищем в прямом порядке,
00264     // если останавливать, то в обратном.
00265     typedef list<ReservInfo*> TMPList;
00266     TMPList tmplist;
00267     if( set )
00268     {
00269         for( RList::iterator it=rlst.begin(); it!=rlst.end(); ++it )
00270             tmplist.push_back( &(*it) );
00271     }
00272     else
00273     {
00274         for( RList::iterator it=rlst.begin(); it!=rlst.end(); ++it )
00275             tmplist.push_front( &(*it) );
00276     }
00277 
00278     ReservInfo* rses = 0;
00279     for( TMPList::iterator it=tmplist.begin(); it!=tmplist.end(); ++it )
00280     {
00281         ReservInfo* ri(*it);
00282         // Ловим момент, если резервный только что, запустился/остановился 
00283         // и засекаем таймер на "паузу"
00284         // необходимую для прихода системы в устойчивое состояние
00285         // после пуска/остановки резерва 
00286         // (например распределение нагрузки и т.п.)
00287         // а то может начать запускатся следующий резервный
00288         // если распределитель ещё не успел "поработать"
00289         // и основной(leader) остался загружен
00290         // несмотря на то, что уже запустился резервный
00291         if( set && ri->trChangeState.hi(ri->ses->getOMode()==mON) )
00292         {
00293             ri->ptPause.setTiming(reservStatePause);
00294             ri->waitRunning = false;
00295             ri->waitStopping = false;
00296         }
00297         else if( !set && ri->trChangeState.hi(ri->ses->getOMode()==mOFF) )
00298         {
00299             ri->ptPause.setTiming(reservStatePause);
00300             ri->waitRunning = false;
00301             ri->waitStopping = false;
00302         }
00303 
00304         // ничего не делаем, пока резервный ses исполняет команду
00305         // либо он её выполнит, либо timeout, либо у него сработает защита
00306         if( (set && ri->waitRunning) || (!set && ri->waitStopping) )
00307         {
00308             if( !ri->ptPause.checkTime() && !ri->ses->isProtection() )
00309             {
00310                 if( SEESGroup::dlog.debugging(Debug::LEVEL4) )
00311                 {
00312                     int wmsec = ri->ptPause.getInterval() - ri->ptPause.getCurrent();
00313                     SEESGroup::dlog[Debug::LEVEL4] << myname << "(reserv):"
00314                         << " IGNORE. Wait processing command for ses" 
00315                         << ri->ses->getNumber()
00316                         << " (sec=" << wmsec/1000 << " msec=" << wmsec%1000 << ")"
00317                         << endl;
00318                 }
00319                 ptCheckReserv.setTiming(checkReservTime);
00320                 return;
00321             }
00322 
00323             ri->waitRunning = false;
00324             ri->waitStopping = false;
00325             ri->ptPause.setTiming(0);
00326         }
00327 
00328         // Если пауза ещё не прошла, ждём...
00329         // либо признак нужности/ненужности резерва
00330         // снимется у leader, либо мы начнём 
00331         // запускатся/останавливать следующий в списке
00332         if( !ri->ptPause.checkTime() && !ri->waitRunning && !ri->waitStopping )
00333         {
00334             if( SEESGroup::dlog.debugging(Debug::LEVEL4) )
00335             {
00336                 int wmsec = ri->ptPause.getInterval() - ri->ptPause.getCurrent();
00337                 SEESGroup::dlog[Debug::LEVEL4] << myname << "(reserv):"
00338                     << " IGNORE. Wait state pause for ses" 
00339                     << ri->ses->getNumber()
00340                     << " (sec=" << wmsec/1000 << " msec=" << wmsec%1000 << ")"
00341                     << endl;
00342             }
00343             ptCheckReserv.setTiming(checkReservTime);
00344             return;
00345         }
00346 
00347         // Эти условия должны проверятся ОБЯЗАТЕЛЬНО после ptStatePause
00348         // т.к. canReservRunning или canReservStopping вернут false
00349         // как только, резерв запустится/остановится.
00350         // а нам ведь надо ещё и паузу выждать,
00351         // прежде чем пытатся запускать/останавливать
00352         // следующий резервный в списке..
00353         if( set && !ri->ses->canReservRunning() ) // требуется запуск, а не может
00354             continue;
00355         
00356         if( !set && !ri->ses->canReservStopping() ) // требуется остановка, а не может
00357             continue;
00358 
00359         rses = ri; 
00360         break;
00361     }
00362 
00363     if( !rses )
00364     {
00365         SEESGroup::dlog[Debug::LEVEL4] << myname << "(reserv):"
00366             << " FREE RESERV NOT FOUND" << endl;
00367         ptCheckReserv.setTiming(UniSetTimer::WaitUpTime);
00368         return;
00369     }
00370 
00371     if( set )
00372     {
00373         if( SEESGroup::dlog.debugging(Debug::LEVEL4) )
00374         {
00375             SEESGroup::dlog[Debug::LEVEL4] << myname << "(reserv):"
00376                 << " SELECT RUN ses" << rses->ses->getNumber() << endl;
00377         }
00378         rses->ses->onReservCommand();
00379         rses->waitRunning = true;
00380         rses->waitStopping = false;
00381     }
00382     else
00383     {
00384         if( SEESGroup::dlog.debugging(Debug::LEVEL4) )
00385         {
00386             SEESGroup::dlog[Debug::LEVEL4] << myname << "(reserv):"
00387                 << " SELECT STOP ses" << rses->ses->getNumber() << endl;
00388         }
00389         rses->ses->offReservCommand();
00390         rses->waitRunning = false;
00391         rses->waitStopping = true;
00392     }
00393 
00394     ptCheckReserv.setTiming(checkReservTime);
00395     rses->trChangeState.hi(false);
00396     rses->ptPause.setTiming(reservCommandTimeout);
00397 }

bool SEESGroup::resetReserv (  )  [protected]

сброс команд управления резерва

Перекрестные ссылки lst, myname и rlst.

Используется в checkReserv().

00400 {
00401 //  SEESGroup::dlog[Debug::LEVEL4] << myname << "(resetReserv): ..." << endl;
00402     for( SESList::iterator it=lst.begin(); it!=lst.end(); ++it )
00403     {
00404         // если есть хоть один СЭС требущий резерв,
00405         // то сбрасывать команды нельзя...
00406         if( (*it)->isReservOnNeeded() || (*it)->isReservOffNeeded() )
00407             return false;
00408     }
00409 
00410     // сбрасываем команды
00411     for( RList::iterator it=rlst.begin(); it!=rlst.end(); ++it )
00412     {
00413         SEESGroup::dlog[Debug::LEVEL4] << myname << "(resetReserv): сбрасываем команды резерва для ses" << it->ses->getNumber() << endl;
00414         it->ses->resetReservCommand();
00415     }
00416 
00417     return true;
00418 }

void SEESGroup::update ( RList &  rlist,
ReservInfo ri 
) [static, protected]

функция копирующая в список rlst, информацию из ri, если там есть такой ДГ

00153 {
00154     //UniSetTypes::uniset_mutex_lock lock(lstMutex, 5000);
00155     for( RList::iterator it=rlist.begin(); it!=rlist.end(); ++it )
00156     {
00157         if( it->ses->getNumber() == ri.ses->getNumber() )
00158         {
00159             (*it) = ri;
00160             return;
00161         }
00162     }  
00163 }

void SEESGroup::updateCounters (  )  [protected]

Обновление различных счётчиков

Перекрестные ссылки countWorkingDG и lst.

00673 {
00674     int count = 0;
00675     { // lock
00676         UniSetTypes::uniset_mutex_lock lock(lstMutex, 4000);
00677         for( SESList::iterator it=lst.begin(); it!=lst.end(); ++it )
00678         {
00679             if( (*it)->isOnMode() )
00680                 count++;
00681         }
00682     }
00683 
00684     // Обновляем информацию о текущем количестве работающих ДГ
00685     {
00686         uniset_mutex_lock l(maxrunMutex,200);
00687         countWorkingDG = count;
00688     }
00689 }

void SEESGroup::updatePowerInfo (  ) 

Обновление расчётных параметров сети

Перекрестные ссылки getF(), getU(), sc_Fdev и sc_Udev.

00798 {
00799     bool u_res = false;
00800     // Фомирование сигнала по отклонению напряжения
00801     if( U_min > 0 )
00802     {
00803         long u = getU();
00804         if( u > 0 )
00805         {
00806             if( u < U_min || u > U_max  )
00807                 u_res = true;
00808         }
00809     }
00810 
00811     // устанавливаем (или отключаем) таймер
00812     sc_Udev.rotate(u_res);
00813 
00814     bool f_res = false;
00815     // Фомирование сигнала по отклонению напряжения
00816     if( f_min > 0 )
00817     {
00818         long f = getF();
00819         if( f > 0 )
00820         {
00821             if( f < f_min || f > f_max  )
00822                 f_res = true;
00823         }
00824     }
00825 
00826     // устанавливаем (или отключаем) таймер
00827     sc_Fdev.rotate(f_res);
00828 }


Данные класса

int SEESGroup::countWorkingDG [protected]

текущее количество работающих ДГ

Используется в updateCounters().

bool SEESGroup::f_dev [protected]

флаг отклонение частоты от нормы

Используется в isFdev().

int SEESGroup::gnum [protected]

номер данной группы

SEES* SEESGroup::leader [protected]

указатель на "ведущий" ДГ в группе

Используется в checkReserv() и makeReservList().

SESList SEESGroup::lst [protected]

номер СЭС заблокировавшей включение автомата список СЭС в группе

Используется в checkAloneWorking(), getF(), getP(), getReservPower(), getU(), isProtection(), isReadyForLoading(), makeReservList(), requiredReserv(), resetReserv() и updateCounters().

int SEESGroup::maxWorkingDG [protected]

максимальное разрешённое количество одновременно работающих ДГ

std::string SEESGroup::myname [protected]

исключительно для логов

Используется в checkReserv(), makeReservList(), reserv() и resetReserv().

RList SEESGroup::rlst [protected]

список доступных резервных ДГ

Используется в checkReserv(), makeReservList(), reserv() и resetReserv().

SandClock SEESGroup::sc_Fdev [protected]

специальная задержка на срабатывание по сигналу "отклонение частоты"

Используется в updatePowerInfo().

SandClock SEESGroup::sc_Udev [protected]

специальная задержка на срабатывание по сигналу "отклонение напряжения"

Используется в updatePowerInfo().

bool SEESGroup::U_dev [protected]

флаг отклонение напряжения от нормы

Используется в isUdev().


Объявления и описания членов классов находятся в файлах:

Документация по uniset-algorithms. Последние изменения: Fri Dec 12 14:27:17 2014. Создано системой  doxygen 1.5.9