def { /*AUTOR: Paweł Kąkol; prawa majątkowe: Solwena Sp. z o.o. aktualizacja 2017-12-29-09:30 DZIALANIE: algorytm obsługuje wyłączenie obecności wirtualnego pomieszczenia RPV0, na podstawie danych o ostatnich wystąpieniach PRS0 i DOS0; jeżeli czas od wyłączenia ostatniego czujnika ruchu PRS0 w pomieszczeniu jest większy niż T2 oraz czas od ostatniego naruszenia jakichkolwiek (w pomieszczeniu) drzwi DOS0 jest większy niż T1 -> wysyła ramkę OBEC0; algorytm cyklicznie sprawdza wszystkie RPV, których OBEC=1; czasy T1 i T2 są atrybutami RPV0; algorytm działa jeżeli w pokoju jest przynajmniej 1 kontaktron drzwiowy lub przynajmniej 1 czujnik ruchu; przed sprawdzaniem warunków T1 i T2, algorytm sprawdza czy w pomieszczeniu nie ma permanentnej obecności (CZLOWEW=1). MOZLIWOSCI ROZWOJU: REWIZJA: 2018-01-03-PK - przerobienie na identifier VIRRPV0 ze względu na błędy w IZE 2018-02-23-PK - przerobienie na docelowe FullIdentifier RPV0, wprowadzenie algorytmu uwzględniającego nowe założenia oraz protest 2018-03-14-PK - przerobienie algorytmu na nową wersję związaną z obliczaniem czasu obecności po stronie IZE 2018-04-11-PK - przerobienie algorytmu na nową wersję search() - która zawsze zwraca wynik jako tablicę - usunięcie ręcznego tworzenia tablic i dodawanie wykonania funkcji first() 2018-06-13-PK - przerobienie alogrytmu, tak, żeby działał w pomieszczeniu bez czujnika ruchu; przerobienie alogrytmu, tak, żeby działał w pomieszczeniu bez kontaktronu drzwiowego; dorobienie blokady wyłączania obecności, jeżeli wewnątrz pokoju jest permanentna obecność (CZLOWEW=1); usunięcie starej wersji (z bugiem) podpisywania kolekcji drzwi pomieszczenia do dwóch tablic, na wykorzystanie funkcji fnBCB2B2ZwrocenieDrzwiPasujacychDoPokoju. DO ZROBIENIA: */ global gsAplikacjaID, /*zmienne funkcji fnBCB2B2ZwrocenieDrzwiPasujacychDoPokoju*/ sObiekt: null, sPietro: null, sPokoj: null, /*zmienne funkcji fnBCB2B2PorownanieCzasow*/ fnCzasPorownywany: null, fnCzasReferencyjny: null, fnPrzesuniecieCzasowe: null, fnRodzajPorownania: '4', /*zmienne lokalne typu string*/ sObiektPietro: null, sObiektPietroStrefa: null, sPokojMnemonic: null, sFullIdentifier: null, sIdentifierPath: null, sTemp: null, sDebug: null, sDebug2: null, /*zmienne lokalne typu int*/ intLiczbaCzujnikow: null, intLiczbaKontaktronow: null, intElementyTablicy: null, intIter: null, intWarunekT1: null, intWarunekT2: parseInt('0'), intTemp: null, /*zmienne lokalne typu kolekcja*/ colWirtualnychPomieszczen: null, colWirtualnychPomieszczenAtrybuty: null, colWirtualnychPomieszczenOBEC1: null, colWirtualnychPomieszczenT1: null, colWirtualnychPomieszczenT2: null, colWirtualnychPomieszczenCZLOWEW1: null, colWitrtualnychPomieszczenPRS0DT1: null, colCzujnikowDrzwi: null, colCzujnikowDrzwiSTAN0: null, colCzujnikowRuchu: null, colCzujnikowRuchuSTAN0: null, colCzujnikowRuchuTemp: null, colTemp: null, colTemp2: null, colZmiennaWywolujaca: null, colDebug: [], /*zmienne lokalne typu datatime*/ dtmCzasInit: datetime('2000','01','01','00','00','00'); dtmRPV0: null, dtmDOS0STAN: null, dtmPRS0STAN0: null, global gcolWykluczenieWylaczaniaOBECNOSCI, intWykluczenie: null, itemWL: null, arrTablica: [], tymczasowa: null, } { /*PRS0DTSTAN1*/ /*wyszukaj w bazie wszystkie wirtualne pomieszczenia*/ set(colWirtualnychPomieszczen, search(Device,[{'Mnemonic','==','RPV0'}])); /*wyszukaj w bazie dla wszystkich witrualnych pomieszczen ich atrybuty*/ set(colWirtualnychPomieszczenAtrybuty, search(colWirtualnychPomieszczen,[{'LastValue','==','true'}],150)); /*wyodrębienie z kolekcji atrybutów OBEC==1*/ set(colWirtualnychPomieszczenOBEC1, search(colWirtualnychPomieszczenAtrybuty,null,[{'Name','==','OBEC'},{'Value','==','1'}])); /*początek algorytmu*/ set(intTemp, count(colWirtualnychPomieszczenOBEC1)); /*sprawdź czy istnieje choć jedno pomieszczenie z atrybutem OBEC=1*/ if(intTemp > 0) { /*zapytanie do bazy o wszystkie czujniki ruchu*/ set(colCzujnikowRuchu, search(Device,[{'Mnemonic','==','PRS0'}])); /*zapytanie do bazy o atrybuty STAN (wszystkich czujników ruchu), ale tylko posiadający wartość 0*/ set(colCzujnikowRuchuSTAN0, search(colCzujnikowRuchu,[{'Name','==','STAN'},{'Value','==','0'}])); /*zapytanie do bazy o atrybuty T1 i T2 do wirtualnego pomieszczenia*/ set(colWirtualnychPomieszczenT1, search(colWirtualnychPomieszczenAtrybuty,null,[{'Name','==','T1'}])); set(colWirtualnychPomieszczenT2, search(colWirtualnychPomieszczenAtrybuty,null,[{'Name','==','T2'}])); set(colWirtualnychPomieszczenCZLOWEW1, search(colWirtualnychPomieszczenAtrybuty,null,[{'Name','==','CZLOWEW'},{'Value','==','1'}])); /*wykonaj dla wszystkich wirtualnych pomieszczeń, które posiadają atrybut OBEC=1*/ foreach(item in colWirtualnychPomieszczenOBEC1) { /*sprawdzanie czy w pokoju jest permanentna obecność RPV0*/ set(colTemp, search(colWirtualnychPomieszczenCZLOWEW1,null,[{'ItemId','==',item.ItemId}])); set(intTemp, count(colTemp)); /*jeżeli nie ma*/ if(intTemp == 0) { set(intWarunekT1, parseInt('0')); set(intWarunekT2, parseInt('0')); /*wyciągnięcie potrzebnych informacji odnośnie lokalizacji obrabianego RPV0*/ set(colTemp, search(colWirtualnychPomieszczen,null,[{'Id','==',item.ItemId}])); set(colTemp, first(colTemp)); set(tymczasowa, new(item.ItemId)); add(arrTablica, tymczasowa); set(sFullIdentifier, colTemp.FullIdentifier); set(intWykluczenie, 0); foreach(itemWL in gcolWykluczenieWylaczaniaOBECNOSCI){ if(itemWL == sFullIdentifier){ set(intWykluczenie, 1); } } if(intWykluczenie == 0){ set(sObiektPietro, substring(sFullIdentifier,0,4)); set(sObiektPietroStrefa, stringFormat("{0}00",[sObiektPietro])); set(sPokoj, substring(sFullIdentifier,6,3)); /*wyszukiwanie wszystkich czujników ruchu PRS0 w pomieszczeniu*/ set(sIdentifierPath, stringFormat("{0}{1}PRS0",[sObiektPietroStrefa,sPokoj])); set(colCzujnikowRuchuTemp, search(colCzujnikowRuchu,null,[{'IdentifierPath','==',sIdentifierPath}])); set(intLiczbaCzujnikow, count(colCzujnikowRuchuTemp)); /*jeżeli w pomieszczeniu jest chociaż jeden czujnik ruchu PRS0*/ if(intLiczbaCzujnikow > 0) { /*skasuj zmienną najświeższego czasu wystąpienia STAN=0 w PRS0 oraz wyzeruj liczbę czujników deaktywnych*/ set(intIter, parseInt('0')); set(dtmPRS0STAN0, dtmCzasInit); /*sprawdź całą kolekcję czujników ruchu PRS0 w poszukiwaniu najświeższego TimeStamp'a oraz w celu sprawdzenia czy wszystkie czujniki PRS0 są wyłączone*/ foreach(czujnikRuchu in colCzujnikowRuchuTemp) { set(colTemp, search(colCzujnikowRuchuSTAN0,null,[{'ItemId','==',czujnikRuchu.Id}])); set(intTemp, count(colTemp)); if(intTemp == 1) { set(colTemp, first(colTemp)); /*jeżeli, obrabiany czujnik ruchu PRS0 przyjął STAN=0 później niż poprzedni (w obrębie pokoju), to przyjmij jego TimeStamp*/ if(dtmPRS0STAN0 < colTemp.TimeStamp) { set(dtmPRS0STAN0, colTemp.TimeStamp); } /*zwiększ liczbę czujników posiadających STAN=0 (w obrębie pokoju)*/ intIter++; } } /*jeżeli wszystkie czujniki ruchu PRS0 (w obrębie pokoju) są nieaktywne - sprawdzaj warunki*/ if(intIter == intLiczbaCzujnikow) { /*sprawdzenie czasu T2 dla obrabianego RPV0*/ set(colTemp, search(colWirtualnychPomieszczenT2,null,[{'ItemId','==',item.ItemId}])); set(colTemp, first(colTemp)); set(fnPrzesuniecieCzasowe, colTemp.Value); set(fnCzasPorownywany, dtmPRS0STAN0); set(sTemp, fnBCB2B2PorownanieCzasow(fnCzasPorownywany,fnPrzesuniecieCzasowe,fnRodzajPorownania)); set(intWarunekT2, parseInt(sTemp)); } } /*wykonaj jeżeli ostatnie wyłączenie czujnika ruchu PRS0 nastąpiło dawniej niż wynosi czas T2 lub jeżeli nie ma żadnego czujnika ruchu*/ if(intWarunekT2 == 1 || intLiczbaCzujnikow == 0) { set(dtmDOS0STAN, dtmCzasInit); set(sObiekt, substring(sFullIdentifier,0,2)); set(sPietro, substring(sFullIdentifier,2,2)); set(colCzujnikowDrzwi, fnBCB2B2ZwrocenieDrzwiPasujacychDoPokoju(sObiekt,sPietro,sPokoj)); set(intLiczbaKontaktronow, count(colCzujnikowDrzwi)); if(intLiczbaKontaktronow > 0) { set(colCzujnikowDrzwiSTAN0, search(colCzujnikowDrzwi,[{'Name','==','STAN'},{'Value','==','0'}])); set(intTemp, count(colCzujnikowDrzwiSTAN0)); if(intTemp > 0) { foreach(wskDrzwi in colCzujnikowDrzwiSTAN0) { if(dtmDOS0STAN < wskDrzwi.TimeStamp) { set(dtmDOS0STAN, wskDrzwi.TimeStamp); } } } } /*sprawdzenie czasu T1 dla obrabianego RPV0*/ set(colTemp, search(colWirtualnychPomieszczenT1,null,[{'ItemId','==',item.ItemId}])); set(colTemp, first(colTemp)); set(fnPrzesuniecieCzasowe, colTemp.Value); set(fnCzasPorownywany, dtmDOS0STAN); set(sTemp, fnBCB2B2PorownanieCzasow(fnCzasPorownywany,fnPrzesuniecieCzasowe,fnRodzajPorownania)); set(intWarunekT1, parseInt(sTemp)); /*sprawdzenie czy ostatnia zmiana stanu drzwi w obrabianym pokoju nastąpiła dawniej niż wynosi czas T1*/ } /*wykonaj jeżeli w pokoju jest albo przynajmniej jeden czujnik ruchu albo przynajmniej jeden kontaktron drzwiowy, dla pomieszczeń bez kontaktronów i czujników ruchu jest harmonogram*/ if(intLiczbaKontaktronow + intLiczbaCzujnikow > 0) { /*jeżeli w pokoju nie ma czujników ruhu, ale są kontaktrony drzwiowe, oraz spełniono warunek od drzwi T1*/ if(intWarunekT1 == 1 && intLiczbaKontaktronow > 0 && intLiczbaCzujnikow == 0) { frame(^,M,BCB0,sFullIdentifier,gsAplikacjaID,OBEC=0,In); } /*jeżeli w pokoju nie ma kontaktronó drzwiowych, ale są czujniki ruhu, oraz spełniono warunek od czujnika ruchu T2*/ if(intWarunekT2 == 1 && intLiczbaCzujnikow > 0 && intLiczbaKontaktronow == 0) { frame(^,M,BCB0,sFullIdentifier,gsAplikacjaID,OBEC=0,In); } /*jeżeli czujnik ruchu był aktywny dawniej niż T2 oraz czujnik drzwi dawniej niż T1*/ if(intWarunekT1 == 1 && intWarunekT2 == 1 && intLiczbaKontaktronow > 0 && intLiczbaCzujnikow > 0) { frame(^,M,BCB0,sFullIdentifier,gsAplikacjaID,OBEC=0,In); } } } } } return(arrTablica); } }