Sistem Distribuit de Monitorizare Si Control a Unui Proces
SISTEM DISTRIBUIT DE MONITORIZARE SI CONTROL A UNUI PROCES
SINTEZA PROIECTULUI DE DIPLOMĂ
Enunțul temei:
Sistem distribuit de monitorizare si control a unui proces
Lucrarea de față își propune să realizeze o aplicație de interfațare grafică pentru un sistem distribuit de monitorizare și control a unui proces. Acest proiect conține o dezvoltare pentru un proces simulat cu o funcție oarecare care este preluat de un server și apoi este transmis intr-o rețea de unde este preluat, afișat și modificat de o aplicație client. Această implementare este realizată prin limbajul JAVA din pachetul de programe JAVA DEVELOPMENT KIT. Comunicarea între server si client se face prin socket și conexiunea se face cu ajutorul introducerii la client a aderesei IP a serverului.
Acest program face mai ușor accesul utilizatorului, cu această interfață grafică fiindcă JAVA DEVELOPMENT KIT are această facilitate.
Obiective
Evident, trebuie facută distincție între monitorizare si diagnosticare. Monitorizarea înseamnă achiziție de date, condiționarea semnalelor de la senzori și dezvoltarea modelelor pentru determinarea stării procesului. Diagnosticarea este pasul următor monitorizării și cuprinde interpretarea datelor măsurate „off-line” și „on-line”. Monitorizarea stă la baza diagnosticării, dar, fară diagnosticare, datele măsurate nu au nici o valoare. in prezent, astfel de metode și sisteme de monitorizare sunt dezvoltate de institutele specializate de cercetare, de fabricile constructoare si chiar de utilizatori.
Un sistem de monitorizare a unui proces trebuie să satisfacă anumite cerinte. in primul rând sistemul de monitorizare trebuie proiectat pentru o functionare de lungă durată și pentru o sigurantă sporită, în concordantă cu durata de viată a procesului monitorizat. Bineințeles, trebuie asigurată o relație rezonabilă intre costurile instalării și eficiența monitorizării. În al doilea rând, monitorizarea trebuie să asigure informații pentru o estimare foarte sigură a duratei de viața, ramasă, a procesului respectiv. Obicetivele urmărite prin proiectarea, realizarea și implementarea unui sistem de monitorizare si diagnosticare sunt:
a. Monitorizarea „on-line” a unui proces sau a mai multor procese cu functionare în regim permanent.
b. Monitorizarea „off-line” a procesului în scopul determinării stării acestuia în exploatare, prin introducerea rezultatelor măsurărilor efectuate off-line.
c. Predeterminarea rezervei de viata a procesului urmărit, inspectarea regimurilor de funcționare, reprezentarea variatiei in timp a marimilor măsurate și analizei evoluției parametrilor procesului.
e. Supravegherea permanentă a funcționarii procesului, precum și a aparaturii de comanda și control.
f. Avertizarea și, eventual, transmiterea unor comenzi corespunzătoare de schimbare a regimului de funcționare, în cazul în care valorile limită admisibile sunt depăsite.
g. Stabilirea comenzilor pentru modificarea parametrilor, în funcție de regimul de lucru al procesului.
Arhitectura sistemului
În acest proiect am realizat un sistem distribuit de monitorizare și control cu caracteristici generale care nu se referă la un proces anume și care poate fi modificat ulterior după cerințele utilizatorului concret, așa că în acest proiect am introdus minimul de informații, informații care ar fi utile oricui si de la care s-ar putea porni si dezvolta un adevarat si real sistem distribuit de monitorizare si control.
1. Memoriu tehnic
1.1 Prezentare generală
Crearea unor entități de tip întreprindere virtuală și monitorizarea eficientă a activității în cadrul acestor entități constituie, pentru majoritatea domeniilor de activitate, una dintre cele mai moderne abordări. Infrastructura informatică, necesară pentru buna functionare a întregului ansamblu, se caracterizează printr-o arhitectură complexă, întreprinderea virtuală fiind, în esentă, un sistem distribuit eterogen. Din acest punct de vedere, este esențială folosirea unor soluții standardizate, de integrare a echipamentelor și a aplicațiilor care să ofere caracteristici de scalabilitate, interoperabilitate, flexibilitate. O opțiune profesională, care asigură toate aceste deziderate, este utilizarea unei tehnologii de integrare de tip orientat obiect, așa cum este limbajul de programare JAVA.
Deoarece problemele legate de interacțiunea diverselor componente ale unei întreprinderi virtuale sunt multiple, în cadrul acestui proiect am abordat doar unul dintre aspectele posibile: integrarea unui proces astfel încât el să poată fi supravegheat și monitorizat din orice punct al întreprinderii, indiferent că acesta este situat în aceeași încăpere sau într-o altă localitate. Noul sistem de monitorizare are o arhitectură client/server bine organizată, păstreaza toate caracteristicile impuse de functionarea în timp real al procesului, oferă utilizatorului uman o interfață grafică cu performanțe ergonomice și de vizualizare și permite monitorizarea si controlarea, manuala sau automata, eficientă a funcționarii procesului din orice punct al unei rețele bazată pe protocolul TCP/IP.
1.2 Sisteme distribuite
Pînă în prezent au avut loc o serie de schimbări importante în lumea informaticii. Una dintre ele a fost trecerea de pe mainframe-uri pe PC. Astăzi asistăm la o nouă schimbare majoră – impunerea rețelelor de calculatoare. Dar acest lucru înseamnă printre altele si procesare distribuită.
Cercetările și experimentările întreprinse în timp au condus la delimitarea problematicii sistemelor cu prelucrare distribuită, la fundamentarea conceptului de distribuire a prelucrării și a datelor. Cu toate că în literatura de specialitate se întânesc numeroase definiții, mai mult sau mai putin complete, există o acceptiune cvasi-unanimă în cercurile stiintifice de specialitate că apartenenta unui sistem de calcul la o clasă sau alta de sisteme denumite în general "distribuite" trebuie apreciată prin prisma următoarelor criterii:
1. multitudinea resurselor fizice si logice care să satisfacă cerintele de prelucrare ale sistemului
2.distribuirea fizică a componentelor sistemului
3. viziunea globală, unitară asupra sistemului
4. independenta relativă (cooperantă) a componentelor sistemului
5. transparenta structurii fată de interfata de utilizare a acestuia
Primul criteriu enuntat se referă la faptul că sistemul distribuit trebuie să posede un ansamblu de resurse care să coopereze la atingerea scopului declarat al sistemului. Un aspect foarte important se referă la modularizarea sistemului distribuit. Mai clar spus, reconfigurarea unor componente impusă a un moment dat de diverse conditii de functionare, trebuie să aibă loc fără afectarea functionalității celorlalte resurse.
În general resursele sistemului pot fi de ordin general sau resurse specializate. Caracterul general al resurselor poate conduce la o proiectare mai facilă a acestuia si la o flexibilitate mărită. Specializarea unor resurse impune introducerea unor mecanisme adecvate de partajare a acestora.
Criteriul al doilea impune existenta unui suport de comunicatie care să permită distribuirea fizică între componentele sistemului. Un lucru important de amintit în acest context priveste faptul că nu se stabilesc limite stricte pentru aria geografică de interconectare dar, în unele cazuri, apar limitări din punct de vedere al vitezei de comunicare. Arhitecturile rezultate pe baza acestui criteriu se încadrează în categoria retelelor locale.
Cel mai important aspect privitor la distribuirea fizică si intercomunicarea dintre componente îl constituie transferul explicit de mesaje, pe bază de protocoale de comunicatie, unitatea de transfer fiind mesajul. O consecintă importantă a acestei ipoteze o constituie caracterul variabil al întîrzierilor de transfer al mesajelor cu consecinte directe asupra observabilitătii cronologiei evenimentelor. Elementele de prelucrare au spatii de prelucrare disjuncte, memoria partajată fiind exclusă ca mecanism de comunicatie (memoria partajată nu este practică în sistemele distribuite).
Criteriul al treilea exprimă faptul că sistemul distribuit trebuie să fie unitar din punct de vedere al prelucrării, componentele participînd la realizarea scopului propus. O astfel de strategie se poate materializa prin componente logice de control care la rîndul lor trebuie să dispună de informatiile de stare necesare. Informatiile de stare reprezintă în general evolutia sistemului în cursul tratării lucrărilor care îi sînt prezentate.
În momentul în care ne referim la informatiile de stare trebuie să avem la dispozitie si un model de reprezentare al evolutiei sistemului în timp. Aceste modele se bazează pe ipoteza că este posibilă descrierea completă a stării în anumite momente determinate. În acest caz o stare mai poate fi referită si prin intermediul sintagmei "punct observabil" (evolutia sistemului se materializează prin parcurgerea punctelor observabile).
În cazul unui sistem cu elemente multiple de prelucrare, functionînd de o manieră asincronă, nu există un ceas comun si în consecintă secventa punctelor observabile este diferită de la element la element. Durata transmisiei unui mesaj între două procese care se execută pe componente de prelucrare diferite este mare în raport cu intervalul care separă două puncte observabile ale aceleiasi componente. Aici intervine problema controlului sistemului distribuit. Se ajunge la concluzia că nu este foarte potrivit nici un control centralizat si nici un control distribuit (ultimul din cauza eterogenitătii componentelor sistemului). Practic se apelează la serviciile unui nucleu integrator distribuit. Nucleul integrator este replicat în fiecare componentă, fără să fie impuse relatii de tip master-slave între componentele fizice si/sau logice ale sistemului. Se apreciază că descentralizarea controlului, realizată de sistemele cu prelucrare distribuită, reprezintă aspectul esential care distinge aceste sisteme de arhitecturile clasice.
Criteriul al patrulea exprimă independenta componentelor sistemului si, în acelasi timp, interactiunea lor la nivel fizic si logic. Coexistenta celor două notiuni, relativ contradictorii, este asigurată de strategiile utilizate la proiectarea nucleului integrator.
Criteriul al cincilea priveste interfata dintre utilizator si sistem presupunînd transparenta structurii în raport cu cererile utilizatorului. Mai clar spus, identificarea componentei sau componentelor în satisfacerea unui anumit serviciu nu trebuie să intre în competenta utilizatorului solicitant. Acest criteriu presupune existenta unei interfete de acces la facilitătile sistemului care să facă posibilă abstractizarea de tip "procesor unic".
Ca o concluzie a criteriilor prezentate putem spune că un sistem cu prelucrare distribuită se defineste ca fiind un ansamblu de resurse fizice si logice de calcul autonome, interconectate care cooperează în mod transparent pentru realizarea functiunilor de control si prelucrare.
De-acum încolo putem afirma că Internetul este o prezentă zilnică în viața noastră. Cînd ajungi dimineața la locul de muncă, pe lîngă servirea cafelei bine meritate, verifici dacă ai primit scrisori electronice în cutia postală (electronică și ea). Or, nu mai este un secret pentru nimeni faptul că în acest proces intervine cel putin un server si un client. Ce exemplu poate fi mai nimerit daca vrem să ne referim la procesarea distribuită.
Dacă jocurile pe calculator implicau pînă acum existența unui nucleu grafic performant, în prezent iau amploare jocurile distribuite (iarăși Internetul) care acceptă mai multi participanți. Stând în fața calculatorului de acasă te conectezi prin modem la un calculator gazdă pe care rulează respectivul joc. Pe ecranul tău cît și pe ecranul celorlalți jucători vor apărea pozițiile actualizate ale tuturor participanților. Ceea ce trebuie relevat în acest context este existența unui nucleu pentru susținerea comunicațiilor între modulele jocului (pe lînga nucleul de graflui, realizată de sistemele cu prelucrare distribuită, reprezintă aspectul esential care distinge aceste sisteme de arhitecturile clasice.
Criteriul al patrulea exprimă independenta componentelor sistemului si, în acelasi timp, interactiunea lor la nivel fizic si logic. Coexistenta celor două notiuni, relativ contradictorii, este asigurată de strategiile utilizate la proiectarea nucleului integrator.
Criteriul al cincilea priveste interfata dintre utilizator si sistem presupunînd transparenta structurii în raport cu cererile utilizatorului. Mai clar spus, identificarea componentei sau componentelor în satisfacerea unui anumit serviciu nu trebuie să intre în competenta utilizatorului solicitant. Acest criteriu presupune existenta unei interfete de acces la facilitătile sistemului care să facă posibilă abstractizarea de tip "procesor unic".
Ca o concluzie a criteriilor prezentate putem spune că un sistem cu prelucrare distribuită se defineste ca fiind un ansamblu de resurse fizice si logice de calcul autonome, interconectate care cooperează în mod transparent pentru realizarea functiunilor de control si prelucrare.
De-acum încolo putem afirma că Internetul este o prezentă zilnică în viața noastră. Cînd ajungi dimineața la locul de muncă, pe lîngă servirea cafelei bine meritate, verifici dacă ai primit scrisori electronice în cutia postală (electronică și ea). Or, nu mai este un secret pentru nimeni faptul că în acest proces intervine cel putin un server si un client. Ce exemplu poate fi mai nimerit daca vrem să ne referim la procesarea distribuită.
Dacă jocurile pe calculator implicau pînă acum existența unui nucleu grafic performant, în prezent iau amploare jocurile distribuite (iarăși Internetul) care acceptă mai multi participanți. Stând în fața calculatorului de acasă te conectezi prin modem la un calculator gazdă pe care rulează respectivul joc. Pe ecranul tău cît și pe ecranul celorlalți jucători vor apărea pozițiile actualizate ale tuturor participanților. Ceea ce trebuie relevat în acest context este existența unui nucleu pentru susținerea comunicațiilor între modulele jocului (pe lînga nucleul de grafică). Raportându-ne la domeniul militar, aceste "jocuri distribuite" devin adevarate medii de simulare ale unor situații de luptă.
Tot un domeniu al procesării distribuite este și controlul proceselor – altfel spus controlul cu ajutorul calculatorului a modulelor instalațiilor industriale. Programe pentru controlul proceselor sînt utilizate în uzinele chimice, în rafinării, în complexele pentru producerea energiei nucleare și în alte situații când se cere urmărirea și organizarea unor procese complexe.
1.3 Limbajul JAVA
Java a fost denumit initial Oak, si dezvoltat pentru a fi folosit in aplicati care tinteau de piata bunurilor electronice de larg consum de catre James Gosling. Dupa o perioada de citiva ani de experimentari cu noul limbaj si dupa ce si-au adus contributia o serie de persoane, din care-i amintim pe: Ed Frank, Patrick Naughton, Jonathan Payne si pe Chris Warth, limbjul a fost reorientat catre Internet, redenumit Java si revizuit substantial. Forma final a limbajului a fost definita de catre James Gosling, Bill Joy, Guy Steele, Richard Tuck, Frank Yellin si Artur van Hoff ajutat de catre Graham Hamilton, Tim Lindholm si alti. Aceasta a fost povestea pe scurt, in realitate totul a pornit in anul 1994 cind James Gosling facea parte dintr-o echipa de cercetare izolata in cadrul companiei Sun, echipa care avea ca scop determinarea unor metode de a introduce informatica si calculatoarele in dispozitivele de larga folosinta. Echipa dorea sa realizeze dispozitive cu un grad mai ridicat de interactiune cu utilizatorul uman dar care sa fie capabile sa interactioneze si intre ele. Pentru a-si crea o idee realista despre cum ar trebui sa functioneze si sa comunice aceste dispozitive Green a construit un dispozitiv prototip numit Star7. Acest dispozitiv era o telecomanda operata prin atingerea unor obiecte animate de pe ecranul acesteia. Un utilizator a lui Star7 putea naviga prin atingeri printr-un univers de camere si obiecte, de altfel eroul principal al universului era un omulet (Duke) imortalizat mai tirziu ca mascota limbajului.
Facilitatea cea mai remarcabila a lui Star7 a fost capacitatea lui de a comunica cu alte dispozitive Star7. Un obiect de pe displayul unui Star7 putea fi pasat de la un dispozitiv la altul. Prototipul era un sistem de operare distribuit in care fiecare dispozitiv facea parte dintr-un tot unitar, exact genul de sistem necesar pentru ca un frigider sa-I comunice, de exemplu, aspiratorului ca acesta sa-I comunice operatorului uman ca daca nu este decongelat si curatat nu i-si va mai putea exersa functiile de congelare.
Planul initial a fost ca sistemul de operare pentru Star7 sa fie dezvoltat in C++. Dar dupa cum a afirmat Goshling la conferinta JavaOne din May 1996:
“The tools kept breaking. It was at a fairy early breaking point when I was so disgusted that I went to my office and started typing.”
Asadar, astfel s-a inceput scrierea unui limbaj nou de programare care era mai adaptat acestui tel decit C++, limbajul primind numele de Oak, in cinstea copacului din fata ferestrei sale.
Din start acest limbaj de programare a fost conceput in asa fel incit sa permita crearea de programele mici, fara erori si cu facilitati de comunicare prin retele de dispozitive si calculatoare. Asemanator C++, Oak era orientat pe obiecte, o metoda deosebit de puternica de a crea programe de calculator, si care ofera o multime de avantaje fata de metodele conventionale, dar si impedimentul ca este mult mai dificil de stapinit, dar spre deosebire de acesta a fost conceput tocmai in a facilita o invatare mai usoara fata de restul limbajelor orientate pe obiecte.
Programele Oak, trebuiau de asemenea sa ruleze de o maniera independenta de platforma, deoarece producatori dispozitivelor de larg consum care urmau sa-l foloseasca trebuiau sa aiba abilitatea de a modifica un procesor sau microcontroler mai scump cu unul mai ieftin de cite ori piata le cere sa reduca costul produselor. Iar in contrast cu un posesor de calculator personal, un utilizator al unui produs casnic va fi mai putin dispus sa cumpere un coprocesor pentru a mari puterea de calcul, sa zicem a unei risnite. Pe de alta parte un astfel de consumator va fi mai putin tolerant cu erorile de programare, care ar putea sa-I faca prajitorul de piine inutilizabil. In aceiasi perioada Marc Andersen, un student care lucra la National Center for Supercomputing Applications, crea primul browser pentru World Wide Web, Mosaic 1.0. Pe la mijlocul anului 1994, au gasit World Wide Webul ca fiind foarte promitator din punctul de vedere al limbajului pe care i-l dezvoltau, desi era un servicii mai cunoscut doar in restrinsa comunitate a fizicienilor, oricum browserul grafic a lui Andersen a stirnit un fenomen international, iar Web-ul a devenit rapid un mediu mas-media . Tehnologia dezvoltata de Oak, era perfect pregatita pentru acest mediu, in special datorita capacitatilor sale de a rula pe mai multe platforme si facilitatilor de comunicare prin retele, dar cel mai important a introdus ceva ce nu mai fusese posibil pina atuncea, posibilitatea de a rula aplicatii de pe serverele Web pe calculatoarele utilizatorilor in siguranta.
Patrick Naughton si Jonathan Payne, au terminat WebRunner, un browser de Web care a adus din nou la lumina vedeta proiectului Star7, Duke. Sun realizind ca are ceva promitator in mina se pregateste de lansarea produsului, doar ca numele de Oak era deja patentat. Astfel dupa o sedinta de brainstorming din Januarie 1995 de a inlocui numele de Oak, numele de Java a fost votat in locul lui Oak si HotJava in locul lui WebRunner, iar in Noiembrie 1995 prima versiune de Java (beta) a fost facuta disponibila pentru oricine pe site-urile, firmei, fiind cautat de zeci de mii de persoane si sute de firme.
E adevarat ca cuptoarele cu microunde nu au devenit mai destepte, dar partea de control nu a fost neglijata cu toate ca versiunea principala nu este conceputa pentru uz industrial sau in dispozitive cu capacitati restrinse, Sun a lansat doua linii paralele de Java, PersonalJava, pentru dispozitive limitate ca si capacitati dar cu posibilitati de afisare, si Embedded Java pentru dispozitive limitate ca si capacitati sau resurse si fara nici un mijloc de afisare.
Evoluția tehnologică din ultima perioadă, in mod evident datorată mediului atât economic cât și universitar puternic concurential din lumea capitalistă, a dus la o fantastică explozie a industriei electronice, a tehnicii de calcul și informatice. Concurenta acerbă împreuna cu cantitatea și nu în ultimul rând calitatea persoanelor implicate în activitațile de cercetare și producție atât în domeniul hardwarelui cât și a softwarelui au determinat salturi tehnologice regulate și la intervale scurte de timp, astfel cei care au fost de fată la nașterea calculatoarelor și la primi pași în domeniul informatic vor recunoaște cu greu urmașii uriașilor, mari consumatoare de energie si lentelor calculatoare, și cu atit mai greu metodele de programare avansate pe acea vreme în stilurile și filozofiile programarii din ziua de azi.
Cu toate acestea, desi domeniul automatizărilor nu a fost neglijat, performanțele dispozitivelor implicate în procesul de automatizare, dublându-se în fiecare an, în domeniul programării acestor dispozitive au intervenit foarte puține modificări, folosindu-se în continuare limbaje în cod masina sau asamblare, foarte modeste din punct de vedere a resurselor necesare, și foarte performante ca timpi de execuție, dar foarte frustrate la utilizare și mari consumatoare de resurse umane. Unele îmbunătățiri, au apărut pe parcursul timpului, cum ar fi compilatoarele de C, care generau codul masină pentru diverse platforme, dar la nivel de microdispoztive per ansamblu lucrurile se desfasoară in aceiași manieră de o perioada lungă de vreme. La un nivel superior, și mă refer la cel al conducerii proceselor, lucrurile stau cu o idee mai bine, o serie de limbaje de mare calitate si conținând tehnologiile de ultimă oră au fost dezvoltate și utilizate, și a-și aminti aici ADA, un limbaj care deși conceput in anii 70, încă este viabil și la moda.
Totusi, deși având tangențe cu limbajele utilizate în mod curent la dezvoltarea aplicațiilor comerciale, ele erau subseturi specializate pe diferite taskuri sau tipuri de taskuri, și diferite platforme. Ei, toate acestea începând cu anul 1996 tind să se schimbe, mulțumită companiei Sun, care deși nu era activă pe piața echipamentelor de automatizare a sprijinit cercetările unui inginer în elaborarea unui limbaj de programare destinat echipamentelor de uz casnic. Recunoscând potențialul unui asemenea limbaj, echipa managerială a companiei a hotărât ca e momentul să se canalizeze mai multe resurse în această direcție, și împreună cu o strategie de marketing briliant să î-l impună în timp scurt pe piața. Piața sesizând potențialul imens al, limbajului de programare propus de Sun, limbaj care între timp a fost extins în direcții deosebite (mă refer la orientarea puternică către Internet și rețele de calculatoare în special, precum și la faptul că este printre foarte puținele limbaje de programare care au fost gândite în vederea portabilități totale a codului generat pe diferite platforme) l-a adoptat cu frenezie, ajungând ca firme de renume precum IBM Novel sau Havlet-Packard să pună o mare baza pe el în planurile lor de viitor.
Obiectul proiectului de față, este prezentarea limbajului Java și în special a acelor facilități ale limbajului, care au o importanță mai mare pentru domeniul Informatici Industriale și a Automatici în general. Pentru a demonstra adecvarea limbajului, acestui mediu de problematici, proiectul i-și propune demonstrarea avantajului tehnicilor moderne de programare, programarea orientată pe obiecte, avantaje pe care le aduce din punct de vedere al structurari aplicației, al reutilizări codului, și al flexibilități și extensibilității codului astfel scris. Totodată, proiectul i-și mai propune, demonstrarea facilităților aduse de limbajul Java, cum ar fi tratarea exceptiilor, faptul ca este interpretat, si multitasking, facilitățile sale legate de Internet si comunicația de date în general. Toate acesta, prin implementarea unor instrumente virtuale, capabile de comunicație prin medii eterogene, bazate pe rețele de calculatoare și deci capabile de a distribui semnalul. Bazat pe aceste instrumente virtuale se prezintă un simulator de proces, simulație care tocmai din cauza ca folosește instrumentele virtuale este foarte aproape de o implementare realistă a procesului. Totodată se prezintă o metodă, deosebit de usoară, bazată pe metode vizuale, de a implementa o interfață, a procesului, și de a face procesul public, utilizând o rețea locală de calculatore sau internetul.
Un programator bun este capabil sa implementeze o specificatie in orice limbaj de programare. Problema se pune insa, cu cite resurse irosite, timp, bani, nervi. Astfel un limbaj de programare trebuie sa ajute programatorul in munca sa, oferindu-i metodologii, tehnici si librarii de functii bine organizate si acoperitoare pentru o multitudine de domenii. Limbajul Java, face parte din acele limbaje de programare care sa asigure suport puternic pentru implementarea aplicatilor din cele mai diverse domenii, asigurind in acelasi timp o serie de tehnologii de ultima ora, printre care putem aminti: programarea orientata pe obiecte, independenta de platforma, suport pentru programarea distribuita si pentru multitasking, mecanisme deosebite de tratare a exceptiilor, suport pentru aplicati multilingve, suport pentru baze de date, mecanisme de securitate si criptografie puternice, si multe, multe altele.
Controlul proceselor de la distanta si instrumentatia virtuala sunt doua dintre domeniile automatici in curs de dezvoltare, si care vor avea un impact destul de puternic asupra ei si in speta asupra informaticii industriale, de acea sa decis, ca partea practica a acestui proiect, sa demonstreze beneficiile pe care le aduc aceste tehnologii. Prin intermediul instrumentelor virtuale, dezvoltate sa reusit implementarea unui simulator de proces in doar citeva sute de lini, si citeva ore de munca. Bineinteles proiectul poate fi dezvoltat in continuare, el reprezentind momentan mai degraba un proiect pedagogic decit o implementare orientata spre performante. Ca o prima directie de dezvoltare se poate implementa mecanisme de securitate si autorizari, canale de comunicatie criptate si suport pentru baze de date.
In momentul de fata, in urma cercetarilor facute de autor, asemenea proiecte de aplicatii sunt in curs de dezvoltare doar in cadrul a doua organizatii sau companii, este vorba de NASA si de Wizcon, ambele din Statele Unite ale Americi.
.
1.4 Arhitectura sistemului
"Sistemul distribuit de monitorizare și control" are o dezvoltare teritorială pe o suprafață depinzând de cerințele utilizatorului. Din punct de vedere al arhitecturii sistemului, aceasta este de tip distribuit pe nivele ierarhice;
– nivel central:
· aplicația server care preia informațiile de la proces și de la clienti
· pachet software de aplicație realizat sub mediu de programare JAVA
– nivel zonal:
· in acest nivel se incadreaza clientii care monitoriezeaza si si controleaza procesul
· software implementat in JAVA
· avertizare si semnalizare locală optică, prin schimbarea pe panoul de afisaj al serverului, respectiv al clientului, a culorii cu care este afisată valoarea primită de la proces;
· comunicația cu nivelul central
– nivel local in acest nivel se incadreaza procesul în sine reprezentat in cazul nostru tot de server deoarece cum am spus în cazul nostru procesul este unul simulat de către server printr-un thread.
Aplicația este implementată dupa cum am spus în limbajul de programare JAVA și rulează numai cu ajutorul pachetului JAVA DEVELOPMENT KIT versiunea 1.4.
1.5 Caracteristici tehnice principale
1.5.1 Serverul
DATE TEHNICE DESPRE LIMBAJUL FOLOSIT
Serverul este o aplicație implementată în JAVA prin modelul de SWING. În modelul SWING o componenetă poate iniția un eveniment. Fiecare tip de eveniment este reprezentat de o clasă distinctă. Când un eveniment este lansat, acesta este recepționat de unul sau mai mulți "ascultători" care acționează asupra acelui eveniment. Astfel sursa unui eveniment și locul unde evenimentul este tratat poate fi diferită. Despre partea de programare ar mai fi de menționat că fișierele aplicației server au fost impachetate într-un fișier JAR pentru o mai bună și rapidă execuție a aplicației și pentru o minimizare a dimensiuii fizice a aplicației.
DATE TEHNICE DESPRE FUNCȚIILE APLICAȚIEI
Serverul este o aplicație multiplă care indeplinește mai multe funcții după cum am spus serverul produce și semnalul, care simulează procesul, pe care îl transmite în rețea, tot serverul este acela care verifică dacă acel client care vrea să se conecteze se află în baza sa de date și dacă să îi permită conectarea sau nu, serverul mai poate modifica parola unui utilizator care deja se află în baza sa de date, adaugă un utilizator nou cu parola aferentă în baza sa de date și poate să și afișeze toți utilizatorii care sunt înregistrati în baza sa de date. Tot serverul se ocupă și cu transmiterea către client și recepționarea de la proces a informațiilor aferente.
Mai jos este prezentată fereastra principală a serverului , iar în continuare vom prezenta funcția fiecărui menu în parte.
fig.1 Server: Fereastra principală
La apăsarea butonului menu-lui "proces" apare un sub menu care arată ca în figura de mai jos și care prezintă două butoane care, după cum se vede scris și pe ele, pornesc si opresc procesul simulat.
fig.2 Sub-meniul proces
La apăsarea butonului menu-lui "utilizator" apare un sub meniu care este prezentat și în figura de mai jos și care are funcția de a modifica parola unui utilizator existent, adaugare a unui utilizator nou la baza de date și respectiv de a afișa utlizatorii care se afla deja în baza de date a serverului.
fig.3 Sub meniul Utilizatori
La apăsarea butonului "modifica parola " din sub menu-ul utilizatori iși face apariția un nou submeniu care cere numele utilizatorului parola veche și parola nouă cea din urma cu confirmare desigur, cum bine se vede și in figura de mai jos. Noile date fiind introduse se va apăsa butonul "ok" si noua parola va fi schimbată în baza de date a serverului.
fig.4 Submenu-ul de modificare a parolei
La apasarea butonului " adăugare utilizator" va aparea submenu-ul "adaugă utilizator" care cere numele și parola, respectiv confirmarea parolei pentru a elimina orice risc de a introduce parola greșit noului utilizator după cum se vede și în figura de mai jos. Odata apăsat butonul "ok" noul utilizator va fi introdus în baza de date a serverului. La apăsarea butonului "Abandon" operația de adaugare de nou utilizator va fi anulată.
fig. 5 Submenu-ul de adaugare a unui utilizator nou
La apăsarea butonului "afisează utilizatorii" apare un sub menu ca în figura de mai jos care ne afisează utilizatorii înregistrati în baza de date a serverului la momentul respectiv. La apăsarea butonului "ok" se va ieși din acest sub menu.
fig 6 Sub menu-ul utilizatori aplicație
La apăsarea butonului din meniul "aplicatie" va aparea un sub menu "închide" care la apasarea sa va închide aplicația.
fig7 Sub menu-ul "închide"
În această prezentare a aplicației Server am arătat funcțiile fiecarui buton din panoul de control al serverului. Asupra menu-lui proces vom mai reveni când voi explica functionarea aplicatiei in ansamblu.
1.5.2 Clientul
Aplicația client este mult mai simplă decât cea a serverului aceasta avand rolul numai de a se conecta la server, de a prelua informațiile de la sever, de a le viziona și de a le optimiza dacă este cazul.
Când rulam aplicația client ne apare meniul de mai jos în care trebuie să introducem numele de utilizator cu parola aferentă și adresa de IP a calculatorului pe care se află serverul și apoi apăsăm butonul "ok" pentru a ne conecta la server sau "abandon" dacă nu vrem să ne mai conectăm la server.
fig.8 Meniul de conectare a clientului la server
După ce am introdus user-ul si parola corect apasăm butonul "ok" și aplicația client va porni și va astepta până serverul îi va trimite informații, aplicația va arăta ca în figura de mai jos. Observăm că în colțul stânga sus ne este afișat clientul care este conectat la server. Mai oservăm și de existența menu-lui "aplicație " ,care are același rol ca și la server și anume acela de a închide aplicația, și a butonului optimizare care optimizează procesul atunci când acesta rulează,dar despre funcția acestuia voi fi mai explicit când voi explica funcționabilitatea aplicației în anasamblu.
fig. 9 Aplcația "Client" fereastra principală
Mai sunt câteva aspecte de remarcat și anume că:
-aplicația client nu pornește dacă serverul nu este pornit returnând un mesaj de eroare ca cel prezentat în figura de mai jos.
fig 10 Aplicația client returnează eroare deoarece nu a fost pornit serverul
– la introducerea greșită a parolei sau a user-ului aplicația client nu pornește și returnează mesajul de eroare prezentat în figura de mai jos
fig.11 Aplicatia client returnează eroare deoarece nu a fost introdusă corect parola sau numele user-ului
1.5.3 Procesul
După cum am mai spus procesul din această aplicatie respectiv proiect, este unul simulat printr-un thread pentru ca nu se știe cum se va face legătura dintre server si proces, informația se trimite obișnuit la server, fără a se mai face o legatură externă prin Soket.
Threadurile Java sunt pre-emptive, și depinde de platforma pe care masina Java ruleaza, astfel ele pot fi si de tip time-sharing. Pe cind celelalte limbaje asigura facilitati de multithreading de obicei prin intermediul unor librarii, de thread-uri, suportul inglobat chiar in miezul limbajului asigura programatorii cu unelte mult mai puternice si facile pentru crearea aplicatiilor cu afinitate pentru mai multe fire de executie sau chiar cu mai multe fire de executie. Un alt avantaj al multithreading-ului este un mai bun raspuns, sau o mai mare interactivitate si comportament de timp real bun.
Procesul in sine va fi vizualizat mai bine cand voi explica functionabilitatea in ansamblu. Dupa cum am mentionat si mai sus procesul se porneste si se opreste la apasarea butoanelor "Porneste proces" si respectiv "Opreste proces" prezente in submeniul " simulare proces", prezentat si in figura de mai jos, din meniul "proces" din fereastra principala a serverului.
fig.12 Pornirea si oprirea unui proces
1.5.4 Comunicarea Server/Client
Comunicarea server/client se face prin socket și mai jos fac o scurta prezentare a ceea ce reprezinta comunicarea prin socket.
Socketul este o abstracție software folosita ca să reprezinte „capetele” conexiunii dintre doua calculatoare. Pentru o conexiune dată exista există un socket pe fiecare calculator. Și astfel ne putem imagina un “cablu” ipotetic care face legătura între cele două calculatoare având fiecare dintre capetele sale introdus într-un socket. Desigur, piesele hardware si legatura între cele doua calculatoare este total necunoscută.
In ultima decada, aplicatiile client-server au devenit cele mai raspindite tipuri de aplicatii folosite acolo unde deja exista retele de calculatoare functionale. Ideea care sta la baza tehnologiei client-server este ca un calculator specializat are functia de stocare a datelor, precum si de prelucrare a lor, iar unul sau mai multe calculatoare cu resurse mai mici, au rolul de a prezenta informatia procesata pe server. Cele mai multe aplicatii cunoscute si care sunt legate intr-un fel de la o retea de calculatoare au o arhitectura client-server.
Deci pentru a putea discuta despre o aplicatie client-server, in primul rind avem nevoie de un server, crearea unui server in limbajul Java este cea mai simpla metoda pusa la dispozitie posibile. Clasa de baza este denumita serverSocket si are functia de a crea un server care asculta la un port specificat si asteapta clienti care sa se conecteze. Metoda care realizeaza conectarea efectiva este accept()din cadrul clasei aceasta blocind blocul curent al aplicatiei pina cind un client nu se conecteaza. Datorita modului cum au fost concepute aceste metode in cadrul limbajului Java, operatiile executate de un client sau de un server sunt aproape identice. Diferente apar numai in cazul in care serverul are de tratat mai multi clienti iar clienti doar un singur server.
Motivul principal al vinzarilor puternice pe care le-a inregistrat limbajul Java, masina virtuala, este de asemenea motivul principal pentru care dezvoltatori de aplicatii client-server au investit imens in acest limbaj. Cu portabilitatea codului greu de atins in alte limbaje Java permite programatorilor sa scrie codul o singura data independent de platforma, si sa-l distribuie pe masinile client. Dar in afara independentei de arhitectura Java asigura de asemenea o puternica biblioteca care permit aplicatiilor sa acceseze in mod rapid resursele unei retele in maniera adresarii traditionale TCP si localizarii prin intermediul URL-urilor a resurselor. Un alt avantaj devastator fata de alte limbaje de programare este incarcarea de la distanta a aplicatiilor. Pe cind in mod conventional, aplicatiile client sunt nevoite sa fie instalate fizic local pe fiecare terminal client, limbajul Java permite pe linga incarcarea aplicatiei direct de pe retea permite si rularea ei pe alt calculator. Astfel pe linga economiile de resurse, atit umane cit si financiare datorate eliminarii necesitati instalarii fizice pe fiecare calculator, se obtine avantajul ca se va lucra tot timpul cu cea mai curenta versiune de aplicatie.
Pachetul de aplicatii Java apeleaza accesul la suportul de retea prin intermediul unui set de nivel superior, de functii si streamuri. O aplicatie poate folosi aceste streamuri pentru a permite datele de intrare si iesire din retea sa poata fi manipulata intr-o multitudine de moduri.
1.6 Functionare Sistemului distribuit
In continuare voi prezenta modul de funcționare si functiile pe care le are aplicațiia prezentată mai sus.Astfel voi prezenta cât mai concludent posibil functiile și funcționabilitatea acestei aplicații, respectiv acestui Sistem distribuit de monitorizare si control.
1.6.1 Serverul
Serverul are rolul de a colectiona, afisa și trimite mai departe in rețea a datelor receptionate de la procesul supravegheat. Astfel pornim serverul si din menu-ul principal si prezentat mai sus. O dată pornit procesul fereastra principală rezervată procesului din aplicatia server se activează și incep să se afișeze valorile primite de la proces și indexate in ordine crescătoare, dupa cum se vede si în imaginea de mai jos. După cum se observa unele valori au culoare neagră unele au culoare roz și unele au culoare roșie și asta deoarece programul a fost proiectat ca să considere anumite limite de lucru optime, a procesului, de valori și anume cele negre, adică cele optime între valorile 40 și 60, cele roz reprezintă limite de sub-critic si se încadează între 30 și 40 și respectiv 60 și 70, iar cele cu roșu reprezintă valori critice la care procesul nostru nu functionează corect și anume între 0 si 30 și respectiv 70 și 100. de precizat este faptul că serverul nu poate modifica aceste valori, aceasta funcție o contine doar aplicația client.
fig.13 Vizualizarea procesului pe panoul serverului
1.6.2 Clientul
După cum am mai spus clientul are funcția de monitorizare si control a procesului. După cum am spus și mai sus procesul a fost pornit și clientul se conectează la server. După cum se observă din imaginile de mai jos, figura 14 respectiv figura 15, aplicația clientul odată conectata la server și procesul pornit incepe să afișeze valorile procesului trimise de la server. Dupa cum se observă și in imaginile de mai jos procesul a fost lasat sa meargă liber fară a se aplica optimizarea, ceea ce duce la afișarea maimultor valori critice, de culoare roșie.
fig.14 Serverul care afiseză informatiile primite de la proces și le transmite mai departe
fig. 15 Clientul care primește informatiile de la server si le afișează
Optimizarea procesului
În cazul de față optimizarea procesului se face prin simpla apasare a butonului “optimizare” din aplicatia client și, cum se observă si in figurile de mai jos, valorile imediat urmatoare apasăsării butonului de optimizare revin la valori optime pentru o perioadă nedeterminată de timp până când procesul simulează o noua dereglare care poate fi remediată printr-o nouă apăsare a butonului de optimizare. După cum se observă acest procedeu de optimizare este unul manual si unul dintre cele mai simple, unul general după cum am spus la începutul lucrării. Avertizarea utilizatorului de apariția unor valori critice se face doar prin schimbarea culorii a valorilor respective pe panoul de afișare, dar acesta tip de avertizare poate fi modificat sau mai poate fi introdus un buton care să optimizeze automat procesul printr-o singură apasare a sa și utilizatorul să aibă astfel doar un rol de supraveghere.
fig. 16 Afișarea de catre server a optimizării procesului
fig. 17 Optimizarea si afișarea procesului de către client
1.7 Arhitectură distribuită – comparație
În paralel am incercat sa prezint o alta arhitectura pentru control distribuit bazata pe implementarea software cu ajutorul programului LabView. Am luat spre exemplificare numai solutionarea software a problemei pentru a face comparatie intre cele doua modele.
O data cu cresterea costurilor combustibililor si energiei electrice, la marii consumatori a devenit critica optimizarea consumului. In majoritatea activitatilor productive, consumul energetic are o influenta importanta asupra costurilor, deci este imperios necesara cunoasterea situatiei reale a consumurilor si eficienta acestora. Sistemul trebuie sa indeplineasca urmatoarele cerintele:
-monitorizeaza cateva sute sau mii de marimi analogice (electrice: curenti, tensiuni, factor de putere si neelectrice: temperaturi, presiuni, viteze, debite); valorile analogice provin fie de la senzori sau traductoare, fie de la buclele de reglaj locale;
-urmareste zeci sau sute de marimi digitale (starea comutatoarelor electrice);
-baleiaza canalele de intrare cu o frecventa cat mai mare, respectiv achizitioneaza marimile energetice la interval de maxim o secunda si parametrii de proces la circa 3-5 secunde;
-stocheaza valorile marimilor de intrare pe o perioada de cel putin trei zile;
-alarmeaza operatorul in caz de avarie sau de depasirea unor limite prestabilite;
-prelucreaza, formateaza si afiseaza marimile monitorizate intr-un mod cit mai avantajos, usor de interpretat (tabele de valori, desene, grafice plane si tridimensionale, histograme etc.)
Solutionarea problemei
Pentru automatizarea si optimizarea activitatilor de productie, s-a dovedit necesar un sistem de monitorizare global, cu caracter distribuit, care sa cuprinda intreg ansamblul uzinei. Un astfel de sistem are inevitabil o structura ierarhica (mai multe sisteme de calcul, cu diferite functii, cuplate in retea) si un caracter distribuit (dispozitivele de masura si de control se intind pe o suprafata considerabila). Printre modulele folosite de sistem se numara dispozitivele de achizitie distribuita din familia ICP-CON I-7000 si subansamblul denumit "contor energetic industrial".
Hardware
Sistemul de monitorizare completa a intreprinderii este realizat in principal cu hardware si software de la firma National Instruments. Echipamentul include senzorii, transformatoarele de masura si traductoarele, rack-uri SCXI de conditionare a semnalelor (placi cu 32 de intrari analogice si placi cu 32 de intrari de tensiune inalta), bucle de reglaj locale, placi de achizitie, module de achizitie si control distribuite si cel putin doua sisteme de calcul compatibile IBM PC legate in retea, un calculator industrial in hala de productie si un calculator de birou standard la dispecerat (centrul de calcul).
Semnalele de intrare provin de la de senzorii de tensiune si curent, traductoarele de temperatura, presiune, debit etc. amplasate pe utilajele principale. Datorita numarului mare de parametrii ce trebuiesc supravegheati (sute – mii de intrari analogice, sute de intrari digitale), se utilizeaza o arhitectura distribuita, cu mai multe sisteme de calcul si automate programabile (controlere, PLC-uri). De asemenea, se folosesc multiplexoare, atat analogice (pentru marimile electrice si parametrii de proces) cat si digitale (pentru intrarile de tip On/Off, concentratoare de date). Un subansamblu important il reprezinta buclele locale de reglaj (controlere PID), ce pot fi folosite fie doar pentru culegerea de date, fie chiar pentru executie (primesc comenzi de la sistemul de monitorizare, respectiv li se modifica parametrii de reglaj si valorile pentru limite).
Software
Aplicatia software de baza, realizata in LabVIEW, ruleaza pe calculatorul industrial, asigura citirea datelor de intrare, prelucrarea lor si salvarea acestora pe harddiskul local (datele sunt organizate sub forma unei memorii FIFO). Se asigura in plus o centralizare periodica a situatiei (alarme si consumuri).
Prin intermediul protocolului TCP/IP, datele prelucrate sunt trimise la calculatorul de la dispecerat si mai departe, in reteaua locala a firmei. Pe sistemul de calcul de la dispecerat ruleaza software-ul de afisare, de asemenea pus la punct in LabVIEW, care are doua regimuri de lucru: monitorizare si istoric. In functie de optiunea operatorului, datele transferate prin retea (consumuri energetice, parametrii de proces tehnologic) pot fi vizualizate in timp real (valorile curente) sau sub forma de istoric (evolutia pe o perioada de timp specificata). Pentru a asigura o utilizare usoara si o intelegerea rapida a volumului mare de date prezentate, programul de afisare lucreaza interactiv, prietenos, iar interfata cu operatorul este in intregime grafica, dupa cum se poate vedea in imaginea alaturata.
Operatorul poate selecta fie afisarea datelor curente pentru un anumit element, fie vizualizarea istoricului (evolutia in timp a consumurilor energetice si a parametrilor de proces). Selectarea echipamentului, instalatiei sau sectiei de afisat se face intr-un mod foarte simplu, se lucreaza grafic interactiv, intr-o ierarhie logica. Astfel, mai intai se specifica despre care din "arterele" intreprinderii este vorba: reteaua de distributie a curentului electric, magistralele de aer comprimat, de apa, de gaze, abur industrial, energie termica etc. Pe ecran apare apoi harta uzinei, avand marcate punctele de supraveghere si se face pur si simplu "click cu mouse"-ul pe reprezentarea dorita.
Daca, de exemplu, a fost selectata reteaua de distributie energia electrica, pe ecran se afiseaza schema de distributie, cu sursele (puncte de transformare, grupuri electrogene), comutatoarele, panourile de distributie si consumatorii. Sunt prezentate in timp real valorile curente ale marimilor de intrare (curenti si tensiuni trifazice) si a celor calculate (cos , putere activa si reactiva, energie activa si reactiva), precum si starea intrerupatoarelor (v. imaginea alaturata: rosu = circuit deschis, verde = inchis). Mai departe, se selecteaza de pe schema electrica utilajul de supravegheat. Pe ecran apare denumirea completa a utilajului, se afiseaza starea de functionare si parametrii curenti. Contorul energetic aferent echipamentului masoara intensitatea curentului electric si tensiunea electrica prin intermediul traductoarelor specializate si calculeaza celelalte marimi energetice ale consumatorului. Alte elemente selectabile de pe schema de distributie sunt tablourile de forta, ce afiseaza sinoptic starea comutatoarelor, a sigurantelor, casetelor, sub-circuitelor etc. Interfata permite de asemenea determinarea bascularii intrerupatoarelor, alegerea un anumit circuit si vizualizarea intr-un tabel a valorilor curente ale curentilor, tensiunilor, puterilor etc., pentru linia respectiva. Schema electrica poate avea oricate nivele ierarhice se considera necesar.
Structura ierarhica a programului este pusa in evidenta de utilajele principale. Astfel, la Stirom, unul din consumatorii cei mai importanti, cu o structura complexa, este cuptorul principal de topire a sticlei, cu doua bazine. Cuptorul are in "subordine" numeroase motoare pentru ventilatoare, prevazute cu variatoare de turatie, agitatoare, ventilatoare de racire, panouri de forta, panouri de iluminat, vane prevazute cu bucle locale de reglaj (PID) etc. Toate acestea figureaza in fereastra aferenta cuptorului. Printr-un "click" pe unul din subansamblele cuptorului, acesta poate fi accesat pentru afisarea parametrilor curenti (curent, putere consumata, energie, temperatura), respectiv comandat, pentru a-i modifica starea (pornit/oprit, deschis/inchis, viteza de rotatie, parametrii de reglaj PID). De asemenea, se poate afisa si istoricul aferent unui anumit agregat, respectiv, variatia in timp a parametrilor de lucru, pe intervalul de timp dorit.
Pentru celelalte circuite ale uzinei, de exemplu pentru reteaua de aer comprimat, se procedeaza in mod similar: mai intai se alege din meniul principal optiunea corespunzatoare, pentru a afisa pe ecran schema de distributie a aerului, cu compresoare, robinete si consumatori si se face "click" pe elementul de vizualizat sau de comandat. Se remarca faptul ca se afiseaza grafic, foarte intuitiv, nu numai starea de functionare a utilajului, ci si aspectele cantitative. Astfel, se poate urmari propagarea fluidelor pe conducte, si, in functie de viteza de rotatie a pompelor sau ventilatoarelor, se afiseaza codificat, in culori, parametrii precum sunt debitul sau temperatura.
Realizarea practica a unui sistem de monitorizare
Un astfel de sistem reprezinta intotdeauna un caz particular, care trebuie sa corespunda cerintelor efective ale fabricii de supravegheat. Pentru implementarea la beneficiar a aplicatiei, se porneste de la un sistem de monitorizare "standard", ce contine numeroase module de baza, hardware si software, si se realizeaza la fata locului echipamentul concret, specific fiecarui mare consumator de energie.Principalele etape de realizare sunt:
-Initial, sunt monitorizati un numar relativ redus de parametri (de exemplu, 2-300 de intrari analogice), de la utilajul cel mai important, sau care are consumul cel mai mare.
-Pe baza rezultatelor preliminare, se reproiecteaza modulele software pentru a corespunde cerintelor efective ale procesului monitorizat. De asemenea, se adapteaza interfata grafica cu utilizatorul.
-Sunt identificate problemele aparute, pentru a fi solutionate.
-Se extinde treptat reteaua de senzori si traductoare si la alte utilaje sau sectii de productie, cu modificarea corespunzatoare a hardware-ului si a programelor de aplicatie.
-In fazele urmatoare, sistemul se dezvolta in functie de necesitatile concrete ale beneficiarului, atat cantitativ (se mareste numarul de intrari, pentru a putea supraveghea toate utilajele din intreprindere), cat si in privinta functionalitatii (de la un sistem cu functii numai de supraveghere se poate face extinderea la un sistem complet de comanda si control).
În concluze la aceasta comparație as putea spune ca și această arhitectură oferă multe posibilități de creeare și dezvoltare ,dar limbajul pe care il folosește este mult prea greoi si maleabil spre deosebire de limbajul Java care oricand se pot aduce îmbunatațiri la un soft deja creat, pe cand la acest limbaj și anume LabView este mult mai complicat sa se faca modificari la program dupa ce acesta a fost definitivat.
1.8 CONCLUZII
Atat din considerente tehnice, cat si din considerente economice este indicata modernizarea unor aparaturi si procese, prin instalarea unor sisteme de monitorizare si diagnosticare, care pun la dispozitie informatiile necesare pentru luarea la timp a masurilor necesare pentru cresterea duratei de utilizare a acestora în exploatare. Costul unui sistem de monitorizare capabil sa masoare parametrii care influenteaza vital functionarea acestor aparate si procese este relativ redus si este in continua scadere datorita reducerii continue a costului creearii unuiastfel de sistem de monitorizare si control a unui proces.
Pentru monitorizarea proceselor, pe langa masurarile „on-line”, se folosesc si masurarile „off-line”. Evidentierea masurarilor „on-line” se face prin utilizarea valorilor furnizate de senzori, prelucrate cu ajutorul interfetei grafice create cu ajutorul limbajului JAva, care ofera avand posibilitati multiple de prelucrare si vizualizare a datelor . in cadrul masuratorilor „off-line” se folosesc valorile parametrilor masurati cu ajutorul instrumentelor de masura si inregistrare directa sau grafica a datelor caracteristice, pentru evaluarea starii functionale a procesului. Pentru obiectivitatea rezultatelor, precum si pentru masurarea cu precizie a parametrilor este necesara utilizarea unor instrumente de masura performante, mai ales pentru determinarea parametrilor vitali, precum si a parametrilor uzuali ai unor procese anume.
Prin intermediul aplicatiei software pentru monitorizarea unui proces se poate determina cu precizie starea procesului si rezerva duratei de viata, realizandu-se o baza de date pentru beneficiar, asigurand cunoasterea (vizualizarea) starii procesului monitorizat in orice moment . De asemenea, se pot prelucra datele achizitionate in scopul stabilirii tendintei de evolutie in timp a parametrilor procesului.
Activitatea descrisa în cadrul acestui proiect, a avut drept scop realizarea modulelor software necesare pentru supervizarea si controlul de la distanta a procesului simulat. S-a avut în vedere construirea unui sistem de supervizare/control distribuit eterogen, care sa permita utilizarea sistemului de operare de tip Windows pentru modulele client si, respectiv server, ca instrument de integrare fiind folosita tehnologia JAVA. Pentru testarea aplicatiei client cu rol de panou de comanda a procesului, s-a utilizat un modul server provizoriu, special conceput, care sa înlocuiasca prezenta fizica a procesului si sa usureze munca de testare a modulului client, executându-se sub acelasi sistem de operare ca si clientul. Serverul provizoriu poate fi usor înlocuit cu modulul server real, care realizeaza efectiv transmiterea comenzilor catre driver-ul celulei procesului deoarece, în implementarea ambelor servere, s-a folosit aceeasi interfata .
În cadrul proiectului, a fost conceput si implementat un modul cu rol de panou de comanda, care permite vizualizarea starilor procesului si controlarea acestor stari prin intermediul unor comenzi. S-au avut în vedere atât aspectele legate de operarea în timp real, cât si cele legate de functionalitatea interfetei cu utilizatorul, conceputa ca panou de comanda, ergonomi și intuitiv. Prin modalitatea de proiectare aleasa si prin utilizarea protocolului TCP/IP ca suport de comunicatie JAVA s-a asigurat functionarea corecta si performanta a aplicatiei în situatia în care serverul si clientul se afla în aceeasi retea locala (LAN).
Deoarece functionalitatea celulei procesului poate presupune ca, în afara de aplicatia cu rol de panou de comanda, pot exista si alte tipuri de aplicatii client, se poate propune ca, în viitor, sa se creeze module software suplimentare pentru îmbogatirea optiunilor oferite utilizatorilor. De exemplu, se poate avea in vedere construirea unei baze de date, care sa stocheze în timp real si sa actualizeze informatii despre functionarea diverselor componente ale celulei proces, despre starile în care se afla aceste componente, despre operatiile realizate pe anumite perioade de timp, despre materialele consumate, despre utilizatorii celulei etc. Aceasta baza de date va fi folosita prin intermediul unui server dedicat, care sa poata interactiona cu modulul server ce supervizeaza si comanda functionarea celulei flexibile. Pentru implementare, se poate folosi MySQL si PHP, luând în considerare atât criterii de performanta, cât si pe cele legate de posibilitatea utilizarii gratuite a acestor instrumente software.
În ansamblu, aplicatia proiectata constituie un instrument util în studierea mecanismelor ce stau la baza functionarii unei întreprinderi virtuale, poate fi utilizata cu succes ca suport pentru implementarea unor solutii practice.
Controlul proceselor de la distanta si instrumentatia virtuala sunt doua dintre domeniile automatici in curs de dezvoltare, si care vor avea un impact destul de puternic asupra ei si in speta asupra informaticii industriale, de acea sa decis, ca partea practica a acestui proiect, sa demonstreze beneficiile pe care le aduc aceste tehnologii. Prin intermediul instrumentelor virtuale, dezvoltate sa reusit implementarea unui simulator de proces in doar citeva sute de lini, si citeva ore de munca. Bineinteles proiectul poate fi dezvoltat in continuare, el reprezentind momentan mai degraba un proiect pedagogic decit o implementare orientata spre performante. Ca o prima directie de dezvoltare se poate implementa mecanisme de securitate si autorizari, canale de comunicatie criptate si suport pentru baze de date.
2. Anexe – Codurile sursă a aplicatiei
2.1 Serverul
Main
package ro.sdmcp.server;
import ro.sdmcp.icon.IconLoader;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window;
/**
* Clasa Server
* @version 1.0
*/
public class Main {
protected static UtilizatoriDB utilizatori = null;
private ServerFrame serverFrame = null;
/**
*
* constructor.
*
*/
public Main() {
/* incarca imaginile */
IconLoader.loadIcons();
/* incarc utilizatorii */
Main.utilizatori = UtilizatoriDB.getInstance();
/* initzializeaza fereastra */
this.serverFrame = new ServerFrame();
this.serverFrame.pack();
Main.setPosition(this.serverFrame);
this.serverFrame.setVisible(true);
}
/**
* Functia Main
* @param args
*/
public static void main(String[] args) {
new Main();
}
/**
* pozitioneaza fereastra in centrul ecranului
*/
public static void setPosition(Window pWindow) {
final int divisor = 2;
/* Dimenisunea ecranului */
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
/* build Position */
Dimension frameSize = pWindow.getSize();
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
/* set Position */
pWindow.setLocation((screenSize.width – frameSize.width) / divisor, (screenSize.height – frameSize.height) / divisor);
}
}
MenuFile
package ro.sdmcp.server;
import ro.sdmcp.icon.IconLoader;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
/**
* Clasa pentru Meniul File
* @version 1.0
*/
public class MenuFile extends JMenu implements ServerFrameInterface {
private ServerFrame serverFrame = null;
private JMenuItem itemExit = null;
/**
*
* Constructor.
* @param pServerFrame Fereastra Server
*/
public MenuFile(ServerFrame pServerFrame) {
super(MenuFile.MENU_FILE_LABEL);
this.serverFrame = pServerFrame;
this.setMnemonic(MenuFile.MENU_FILE_MNEMONIC);
/* init Menu Exit*/
this.itemExit = new JMenuItem(MenuFile.MENU_EXIT_LABEL);
this.itemExit.setMnemonic(MenuFile.MENU_EXIT_MNEMONIC);
this.itemExit.setIcon(IconLoader.EXIT);
this.itemExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
exit();
}
});
this.add(this.itemExit);
}
private void exit() {
this.serverFrame.getCommunicatzion().stopCommunication();
System.exit(-1);
}
}
MenuUser
package ro.sdmcp.server;
import ro.sdmcp.icon.IconLoader;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
/**
* Clasa pentru Meniul User
* @version 1.0
*/
public class MenuUser extends JMenu implements ServerFrameInterface {
private ServerFrame serverFrame = null;
private JMenuItem itemChangePassword = null;
private JMenuItem itemNewUser = null;
private JMenuItem itemListUser = null;
/**
*
* Constructor.
* @param pServerFrame Fereastra Server
*/
public MenuUser(ServerFrame pServerFrame) {
super(MenuFile.MENU_CLIENT_LABEL);
this.serverFrame = pServerFrame;
this.setMnemonic(MenuFile.MENU_CLIENT_MNEMONIC);
/* init Menu Change Password */
this.itemChangePassword = new JMenuItem(MenuUser.MENU_CHANGE_PASSWORD_LABEL);
this.itemChangePassword.setMnemonic(MenuUser.MENU_CHANGE_PASSWORD_MNEMONIC);
this.itemChangePassword.setIcon(IconLoader.NEW);
this.itemChangePassword.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
do_change_password();
}
});
/* init Menu Add new */
this.itemNewUser = new JMenuItem(MenuUser.MENU_NEW_USER_LABEL);
this.itemNewUser.setMnemonic(MenuUser.MENU_NEW_USER_MNEMONIC);
this.itemNewUser.setIcon(IconLoader.NEW_USER);
this.itemNewUser.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
do_add_new_user();
}
});
/* init Menu List user */
this.itemListUser = new JMenuItem(MenuUser.MENU_LIST_USER_LABEL);
this.itemListUser.setMnemonic(MenuUser.MENU_LIST_USER_MNEMONIC);
this.itemListUser.setIcon(IconLoader.RAPORT);
this.itemListUser.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
do_list_users();
}
});
this.add(this.itemChangePassword);
this.add(this.itemNewUser);
this.add(this.itemListUser);
}
private void do_change_password() {
ChangePasswordFrame userFrame = new ChangePasswordFrame(this.serverFrame);
/* initzializeaza fereastra */
userFrame.pack();
Main.setPosition(userFrame);
userFrame.setVisible(true);
}
private void do_add_new_user() {
NewUserFrame userFrame = new NewUserFrame(this.serverFrame);
/* initzializeaza fereastra */
userFrame.pack();
Main.setPosition(userFrame);
userFrame.setVisible(true);
}
private void do_list_users() {
ListFrame userFrame = new ListFrame(this.serverFrame);
/* initzializeaza fereastra */
userFrame.pack();
Main.setPosition(userFrame);
userFrame.setVisible(true);
}
}
MenuProces
package ro.sdmcp.server;
import ro.sdmcp.icon.IconLoader;
import ro.sdmcp.proces.SimulareProcess;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
/**
* Clasa pentru Meniul File
* @version 1.0
*/
public class MenuProcess extends JMenu implements ServerFrameInterface {
private ServerFrame serverFrame = null;
private JMenuItem itemStartProcess = null;
/**
*
* Constructor.
* @param pServerFrame Fereastra Server
*/
public MenuProcess(ServerFrame pServerFrame) {
super(MenuFile.MENU_PROCES_LABEL);
this.serverFrame = pServerFrame;
this.setMnemonic(MenuFile.MENU_PROCES_MNEMONIC);
/* init Menu Process */
this.itemStartProcess = new JMenuItem(MenuProcess.MENU_STRAT_PROCES_LABEL); this.itemStartProcess.setMnemonic(MenuProcess.MENU_START_PROCES_MNEMONIC);
this.itemStartProcess.setIcon(IconLoader.CONECTARE);
this.itemStartProcess.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
startProcess();
}
});
this.add(this.itemStartProcess);
}
/**
* Porneste un proces
*
*/
private void startProcess() {
SimulareProcess process = new SimulareProcess(this.serverFrame);
process.start();
this.setStartProcessEnabled(false);
}
/**
* Seteaza statusul submeniului StartProcess
* @param pStatus
*/
public void setStartProcessEnabled(boolean pStatus) {
this.itemStartProcess.setEnabled(pStatus);
}
}
Comunication
package ro.sdmcp.server;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import ro.sdmcp.proces.Process;
/**
* Clasa pentru comunicarea din partea serverului
* @version 1.0
*/
public class Communication extends Thread {
public static final int PORT = 1313;
/* Socketul server */
private ServerSocket serverSocket = null;
/* Socketul pt client */
private Socket clientSocket = null;
/* Bufferul de citire */
private BufferedReader read = null;
/* Bufferul de scriere */
private PrintWriter write = null;
private boolean cauta = true;
/**
*
* Porneste comunicarea de la Server;
*
*/
public void startCommunication() {
try {
/* Pregatim serverul pentru comunicatie */
this.serverSocket = new ServerSocket(Communication.PORT);
/* astept client */
while (this.cauta) {
this.read();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void astept_si_aprob_client() throws Exception {
/* Blocam comunicatzia pana la aparitzia unui client */
this.clientSocket = serverSocket.accept();
this.read = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
this.write = new PrintWriter(new OutputStreamWriter(this.clientSocket.getOutputStream()), true);
boolean utilizator_valid = false;
while (!utilizator_valid) {
String user = this.read.readLine();
String password = this.read.readLine();
if (userValid(user, password)) {
this.write("true");
utilizator_valid = true;
} else {
this.write("false");
}
}
}
/**
* opreste Comunicarea
*/
public void stopCommunication() {
this.cauta = false;
try {
if (this.serverSocket != null) {
this.serverSocket.close();
}
} catch (Exception e) {
}
try {
if (this.clientSocket != null) {
this.clientSocket.close();
}
} catch (Exception e) {
}
}
/**
* Scrie text in retzea
* @param pText
*/
public void write(String pText) {
if (this.write != null) {
this.write.println(pText);
}
}
/**
* Citeste text din retzea
* @return
*/
public String read() {
String citit = null;
try {
citit = this.read.readLine();
if(citit.equals("optimizeaza"))
Process.optimizeazaProcess();
} catch (Exception e) {
try {
System.out.println("astept");
astept_si_aprob_client();
System.out.println("am client");
} catch (Exception e1) {
e1.printStackTrace();
}
}
return citit;
}
private boolean userValid(String pUser, String pPassword) {
String parola = Main.utilizatori.getParola(pUser);
if ((parola == null) || (pPassword == null)) {
return false;
}
if (parola.equals(pPassword)) {
return true;
}
return false;
}
/**
*
* @see java.lang.Runnable#run()
*/
public void run() {
this.startCommunication();
}
}
ServerFrame
package ro.sdmcp.server;
import ro.sdmcp.icon.IconLoader;
import java.awt.BorderLayout;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
/**
* Fereastra Server
* @version 1.0
*/
public class ServerFrame extends JFrame implements ServerFrameInterface {
/* Componenta MenuBar */
private JMenuBar menuBar = new JMenuBar();
/* Meniurile */
private MenuFile menuFile = null;
private MenuUser menuUser = null;
private MenuProcess menuProcess = null;
private InfoTable infoTable = new InfoTable();
private JScrollPane pnlInfo = new JScrollPane(infoTable);
private Communication communicatzion = new Communication();
/**
*
* Constructor pentru fereastra de server.
*
*/
public ServerFrame() {
try {
this.enableEvents(WindowEvent.WINDOW_CLOSING);
/* initzializarea Interfetzei grafice */
initUI();
this.communicatzion.start();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Metoda care initzializeaza interfatza grafica pentru server
* @throws Exception
*/
private void initUI() throws Exception {
/* seteaza titlul ferestrei */
this.setTitle(ServerFrame.FRAME_SERVER_TITLE);
/* seteaza imaginea ferestrei */
this.setIconImage(IconLoader.SERVER.getImage());
/* adauga meniurile */
this.menuBar.add(this.menuFile = new MenuFile(this));
this.menuBar.add(this.menuUser = new MenuUser(this));
this.menuBar.add(this.menuProcess = new MenuProcess(this));
/* adauga Bara de meniu la Fereastra */
this.setJMenuBar(menuBar);
/* add listener */
this.infoTable.getModel().addTableModelListener(new MyTableListener(this.communicatzion));
/* adauga componentele */
this.getContentPane().add(this.pnlInfo, BorderLayout.CENTER);
}
/**
* Inchide Ferestra
* @see java.awt.Window#processWindowEvent(java.awt.event.WindowEvent)
*/
protected void processWindowEvent(WindowEvent e) {
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
this.communicatzion.stopCommunication();
System.exit(1);
}
}
/**
* seteaza statusul meniului StartProcess
* @param pStatus
*/
public void setStausEnabled4MenuStartProcess(boolean pStatus) {
this.menuProcess.setStartProcessEnabled(pStatus);
}
public void addInfo(String pIndex, String pValoare) {
this.infoTable.addInfoInTabel(pIndex, pValoare);
}
/**
* @return
*/
public Communication getCommunicatzion() {
return communicatzion;
}
private class MyTableListener implements TableModelListener {
private Communication communicatzion = null;
public MyTableListener(Communication pCommunic) {
this.communicatzion = pCommunic;
}
/**
* @see javax.swing.event.TableModelListener#tableChanged(javax.swing.event.TableModelEvent)
*/
public void tableChanged(TableModelEvent arg0) {
String index = "";
String valoare = "";
/* culeg informatzii */
int row = arg0.getFirstRow();
if (arg0.getSource() instanceof TableModel){
index = (String) ((TableModel)arg0.getSource()).getValueAt(row, 0);
valoare = (String) ((TableModel)arg0.getSource()).getValueAt(row, 1);
}
this.communicatzion.write("start");
this.communicatzion.write(index);
this.communicatzion.write(valoare);
this.communicatzion.write("end");
}
}
}
NewUserFrame
package ro.sdmcp.server;
import ro.sdmcp.client.MsgBox;
import ro.sdmcp.icon.IconLoader;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
/**
* @version 1.0
*/
public class NewUserFrame extends JDialog implements UserFrameInterface {
JPanel pnlInfo = new JPanel(new GridLayout(3, 2, 10, 5));
JLabel lblUser = new JLabel();
JTextField txfUser = new JTextField();
JLabel lblNewPassword = new JLabel();
JPasswordField txfNewPassword = new JPasswordField();
JLabel lblConfirmPassword = new JLabel();
JPasswordField txfConfirmPassword = new JPasswordField();
JPanel pnlButtons = new JPanel();
JButton btnOk = new JButton();
JButton btnCancel = new JButton();
public NewUserFrame(Frame pParent) {
super(pParent, true);
try {
initUI();
} catch (Exception e) {
e.printStackTrace();
}
}
private void initUI() throws Exception {
this.setTitle(ChangePasswordFrame.FRAME_ADDNEWUSER_TITLE);
this.getContentPane().setLayout(new BorderLayout());
/* init informatzie */
this.lblUser.setText(ChangePasswordFrame.LABEL_USER);
this.lblNewPassword.setText(ChangePasswordFrame.LABEL_NEW_PASSWORD); this.lblConfirmPassword.setText(ChangePasswordFrame.LABEL_CONFIRM_PASSWORD);
/* init Buttons */
this.btnOk.setText(ChangePasswordFrame.BUTTON_OK_TEXT);
this.btnOk.setMnemonic(ChangePasswordFrame.BUTTON_OK_MNEMONIC);
this.btnOk.setIcon(IconLoader.CONECTARE);
this.btnOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
action_OK();
}
});
this.btnCancel.setText(ChangePasswordFrame.BUTTON_CANCEL_TEXT);
this.btnCancel.setMnemonic(ChangePasswordFrame.BUTTON_CANCEL_MNEMONIC);
this.btnCancel.setIcon(IconLoader.EXIT);
this.btnCancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
action_cancel();
}
});
/* init panel Buttons */
this.pnlButtons.setLayout(new FlowLayout());
this.pnlButtons.setBorder(BorderFactory.createEtchedBorder());
this.pnlButtons.setBackground(Color.DARK_GRAY);
/* add components */
this.pnlInfo.add(this.lblUser);
this.pnlInfo.add(this.txfUser);
this.pnlInfo.add(this.lblNewPassword);
this.pnlInfo.add(this.txfNewPassword);
this.pnlInfo.add(this.lblConfirmPassword);
this.pnlInfo.add(this.txfConfirmPassword);
this.pnlButtons.add(this.btnOk);
this.pnlButtons.add(this.btnCancel);
this.getContentPane().add(this.pnlInfo, BorderLayout.CENTER);
this.getContentPane().add(this.pnlButtons, BorderLayout.SOUTH);
}
private void action_cancel() {
this.dispose();
}
private void action_OK() {
/* Colecate informatii */
String user = this.txfUser.getText();
String newPassword = String.valueOf(this.txfNewPassword.getPassword());
String confirmPassword = String.valueOf(this.txfConfirmPassword.getPassword());
/* verificarile necesare */
String parola = Main.utilizatori.getParola(user);
if (parola != null) {
/* User gresit sau nu exista */
(new MsgBox()).showWarning("Eroare", ChangePasswordFrame.ERROR_USER);
} else if ((newPassword == null) || newPassword.equals("")) {
/* Noua parola e gresita */
(new MsgBox()).showWarning("Eroare", ChangePasswordFrame.ERROR_USER);
} else if (!newPassword.equals(confirmPassword)) {
/* Confirmarea parolei e gresita */
(new MsgBox()).showWarning("Eroare", ChangePasswordFrame.ERROR_PASSWORD);
} else {
/* se face modificare */
Main.utilizatori.setParola(user, newPassword);
Main.utilizatori.storeProperties();
this.dispose();
}
}
}
ListFrame
package ro.sdmcp.server;
import ro.sdmcp.icon.IconLoader;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
/**
* @version 1.0
*/
public class ListFrame extends JDialog implements UserFrameInterface {
JList lstUser = new JList(Main.utilizatori.getUsers());
JScrollPane pnlInfo = new JScrollPane(this.lstUser);
JPanel pnlButtons = new JPanel();
JButton btnOk = new JButton();
public ListFrame(Frame pParent) {
super(pParent, true);
try {
initUI();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Initzializeaza interfatza grafica
* @throws Exception
*/
private void initUI() throws Exception {
/* Titlul mastii */
this.setTitle(ChangePasswordFrame.FRAME_LISTUSER_TITLE);
this.getContentPane().setLayout(new BorderLayout());
/* init Buttons */
this.btnOk.setText(ChangePasswordFrame.BUTTON_OK_TEXT);
this.btnOk.setMnemonic(ChangePasswordFrame.BUTTON_OK_MNEMONIC);
this.btnOk.setIcon(IconLoader.OK);
this.btnOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
action_OK();
}
});
/* init panel Buttons */
this.pnlButtons.setLayout(new FlowLayout());
this.pnlButtons.setBorder(BorderFactory.createEtchedBorder());
this.pnlButtons.setBackground(Color.DARK_GRAY);
this.pnlButtons.add(this.btnOk);
this.getContentPane().add(this.pnlInfo, BorderLayout.CENTER);
this.getContentPane().add(this.pnlButtons, BorderLayout.SOUTH);
}
private void action_OK() {
this.dispose();
}
}
ChangePasseordFrame
package ro.sdmcp.server;
import ro.sdmcp.client.MsgBox;
import ro.sdmcp.icon.IconLoader;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
/**
* @version 1.0
*/
public class ChangePasswordFrame extends JDialog implements UserFrameInterface {
JPanel pnlInfo = new JPanel(new GridLayout(4, 2, 10, 5));
JLabel lblUser = new JLabel();
JTextField txfUser = new JTextField();
JLabel lblOldPassword = new JLabel();
JPasswordField txfOldPassword = new JPasswordField();
JLabel lblNewPassword = new JLabel();
JPasswordField txfNewPassword = new JPasswordField();
JLabel lblConfirmPassword = new JLabel();
JPasswordField txfConfirmPassword = new JPasswordField();
JPanel pnlButtons = new JPanel();
JButton btnOk = new JButton();
JButton btnCancel = new JButton();
Public ChangePasswordFrame(Frame pParent) {
super(pParent, true);
try {
initUI();
} catch (Exception e) {
e.printStackTrace();
}
}
private void initUI() throws Exception {
this.setTitle(ChangePasswordFrame.FRAME_CHANGEPASSWORD_TITLE);
this.getContentPane().setLayout(new BorderLayout());
/* init informatzie */
this.lblUser.setText(ChangePasswordFrame.LABEL_USER);
this.lblOldPassword.setText(ChangePasswordFrame.LABEL_OLD_PASSWORD);
this.lblNewPassword.setText(ChangePasswordFrame.LABEL_NEW_PASSWORD); this.lblConfirmPassword.setText(ChangePasswordFrame.LABEL_CONFIRM_PASSWORD);
/* init Buttons */
this.btnOk.setText(ChangePasswordFrame.BUTTON_OK_TEXT);
this.btnOk.setMnemonic(ChangePasswordFrame.BUTTON_OK_MNEMONIC);
this.btnOk.setIcon(IconLoader.CONECTARE);
this.btnOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
action_OK();
}
});
this.btnCancel.setText(ChangePasswordFrame.BUTTON_CANCEL_TEXT);
this.btnCancel.setMnemonic(ChangePasswordFrame.BUTTON_CANCEL_MNEMONIC);
this.btnCancel.setIcon(IconLoader.EXIT);
this.btnCancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
action_cancel();
}
});
/* init panel Buttons */
this.pnlButtons.setLayout(new FlowLayout());
this.pnlButtons.setBorder(BorderFactory.createEtchedBorder());
this.pnlButtons.setBackground(Color.DARK_GRAY);
/* add components */
this.pnlInfo.add(this.lblUser);
this.pnlInfo.add(this.txfUser);
this.pnlInfo.add(this.lblOldPassword);
this.pnlInfo.add(this.txfOldPassword);
this.pnlInfo.add(this.lblNewPassword);
this.pnlInfo.add(this.txfNewPassword);
this.pnlInfo.add(this.lblConfirmPassword);
this.pnlInfo.add(this.txfConfirmPassword);
this.pnlButtons.add(this.btnOk);
this.pnlButtons.add(this.btnCancel);
this.getContentPane().add(this.pnlInfo, BorderLayout.CENTER);
this.getContentPane().add(this.pnlButtons, BorderLayout.SOUTH);
}
private void action_cancel() {
this.dispose();
}
private void action_OK() {
/* Colecate informatii */
String user = this.txfUser.getText();
String oldPassword = String.valueOf(this.txfOldPassword.getPassword());
String newPassword = String.valueOf(this.txfNewPassword.getPassword());
String confirmPassword = String.valueOf(this.txfConfirmPassword.getPassword());
/* verificarile necesare */
String parola = Main.utilizatori.getParola(user);
if (parola == null) {
/* User gresit sau nu exista */
(new MsgBox()).showWarning("Eroare", ChangePasswordFrame.ERROR_USER);
} else if (!parola.equals(oldPassword)) {
/* Vechea parola nu corespunde */
(new MsgBox()).showWarning("Eroare", ChangePasswordFrame.ERROR_PASSWORD);
} else if ((newPassword == null) || newPassword.equals("")) {
/* Noua parola e gresita */
(new MsgBox()).showWarning("Eroare", ChangePasswordFrame.ERROR_USER);
} else if (newPassword.equals(oldPassword)) {
/* Parola noue e identica cu cea veche */
(new MsgBox()).showWarning("Eroare", ChangePasswordFrame.ERROR_PASSWORD);
} else if (!newPassword.equals(confirmPassword)) {
/* Confirmarea parolei e gresita */
(new MsgBox()).showWarning("Eroare", ChangePasswordFrame.ERROR_PASSWORD);
} else {
/* se face modificare */
Main.utilizatori.setParola(user, newPassword);
Main.utilizatori.storeProperties();
this.dispose();
}
}
}
InfoTable
package ro.sdmcp.server;
import java.awt.Color;
import java.awt.Component;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
/**
* @version 1.0
*/
public class InfoTable extends JTable {
public static final String[] head = new String[] { "Index", "Valoare" };
/**
*
* Constructor.
*
*/
public InfoTable() {
this.setModel(new InfoTableModel());
MyTableRenderer renderer = null;
TableColumn column = null;
/* Fur Jeden Spalte ein eigene Renderer */
final int size = this.getColumnCount();
for (int i = 0; i < size; i++) {
column = this.getColumnModel().getColumn(i);
renderer = new MyTableRenderer();
column.setCellRenderer(renderer);
}
}
public void addInfoInTabel(String pIndex, String pValoare) {
String[] row = new String[2];
row[0] = pIndex;
row[1] = pValoare;
((InfoTableModel) this.getModel()).addRow(row);
}
/**
* Modelul Tabelei
* @version 1.0
*/
private class InfoTableModel extends DefaultTableModel {
public InfoTableModel() {
this.setColumnIdentifiers(head);
}
/**
* Tabelul nu e editabil
* @see javax.swing.table.TableModel#isCellEditable(int, int)
*/
public boolean isCellEditable(int x, int y) {
return false;
}
}
private class MyTableRenderer extends DefaultTableCellRenderer {
/**
* @see javax.swing.table.TableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
*/
public Component getTableCellRendererComponent(JTable arg0, Object arg1, boolean arg2, boolean arg3, int arg4, int arg5) {
JLabel label = new JLabel(arg1.toString());
int val = Integer.parseInt(arg0.getValueAt(arg4, 1).toString());
try {
if ((val >= 40) && (val <= 60)) {
label.setForeground(Color.BLACK);
} else if ((val >= 30) && (val <= 39)) {
label.setForeground(Color.MAGENTA);
} else if ((val >= 61) && (val <= 80)) {
label.setForeground(Color.MAGENTA);
} else {
label.setForeground(Color.RED);
}
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return label;
}
}
}
UtilizatoriDB
package ro.sdmcp.server;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
/**
* Baza de date
* @version 1.0
*/
public class UtilizatoriDB {
private static UtilizatoriDB instance = null;
/* Properties-Key */
private static final String FILENAME = "user.properties";
/* Properties */
private Properties properties = null;
/**
* Genereaza o noua baza de date
*/
protected UtilizatoriDB() {
this.loadProperties();
}
/**
* Returneaza o instantza a clasei.
*
*/
public static UtilizatoriDB getInstance() {
if (UtilizatoriDB.instance == null) {
UtilizatoriDB.instance = new UtilizatoriDB();
}
return instance;
}
/**
* Incarca Utilizatorii
*
*/
protected void loadProperties() {
try {
ResourceLoader resl = null;
String packageName = null;
InputStream in = null;
/* generate Inputstream */
resl = new ResourceLoader();
in = resl.getResourceAsStream(UtilizatoriDB.FILENAME);
this.properties = new Properties();
/* load Properties */
this.properties.load(in);
in.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
/**
* Salveaza Utilizatorii
*
*/
protected void storeProperties() {
try {
ResourceLoader resl = null;
String packageName = null;
OutputStream out = null;
/* generate OutputStream */
resl = new ResourceLoader();
out = resl.getResourceAsOutputStream(UtilizatoriDB.FILENAME);
/* load Properties */
this.properties.store(out, "Utilizatori");
out.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
/**
* Returneaza parola pentru un utilizator
*
* @return Parola
*/
public String getParola(String pUtilizator) {
return this.properties.getProperty(pUtilizator);
}
/**
* Seteaza o parola
* @param pUtilizator Utilizatorul
* @param pPaswword Noua Parola
*/
public void setParola(String pUtilizator, String pPaswword) {
this.properties.put(pUtilizator, pPaswword);
}
public Object[] getUsers() {
return this.properties.keySet().toArray();
}
}
ResourceLoader
package ro.sdmcp.server;
import java.io.*;
/**
* Classe pentru incarcarea Utilizatorilor
*
* @version 1.0
*/
public class ResourceLoader {
private StringBuffer resourceName = null;
private StringBuffer res = null;
private boolean path = false;
/**
* Genereaza un nou obiect
*/
public ResourceLoader() {
}
/**
* Returneaza un Outputstream pentru Baza de Date
*
* @param pPackageName PackageName
* @param pResourceName ResourceName
*
* @return OutputStream
*/
public OutputStream getResourceAsOutputStream(String pResourceName) {
FileOutputStream fileOutputStream = null;
File file = getFile(pResourceName);
try {
/* create new file when not there */
if (!file.exists()) {
// remove the resource name
String strName = file.getAbsolutePath();
int endPos = strName.length() – pResourceName.length();
File dirFile = new File(strName.substring(0, endPos));
dirFile.mkdirs();
file.createNewFile();
}
fileOutputStream = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return fileOutputStream;
}
/**
* Returneaza un obiect File pentru package si numele resursei
*
* @param pPackageName PackageName
* @param pResourceName ResourceName
*
* @return File-Object
*/
public File getFile(String pResourceName) {
File file = null;
if (pResourceName == null) {
return null;
}
this.init(pResourceName);
this.checkName();
file = new File(this.res.toString());
return file;
}
/**
* Returneaza resource ca InputStream
*
* @param pPackageName packageName
* @param pResourceName resourceName
*
* @return Inputstream
*/
public InputStream getResourceAsStream(String pResourceName) {
InputStream retInputStream = null;
if (pResourceName == null) {
return null;
}
this.init(pResourceName);
this.checkName();
/* Calea */
try {
File file = new File(this.res.toString());
retInputStream = new FileInputStream(file);
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
}
return retInputStream;
}
/**
* Initilisarea
*
* @param pPackageName packageName
* @param pResourceName resourceName
*/
private void init(String pResourceName) {
this.resourceName = new StringBuffer(pResourceName);
}
/**
* Verifiacri
*/
private void checkName() {
if (this.resourceName.length() == 0) {
return;
}
this.res = new StringBuffer("");
this.res.append(this.resourceName);
}
}
ServerFrameInterface
package ro.sdmcp.server;
/**
* Fisier cu informatzii generale pt Server
* @version 1.0
*/
public interface ServerFrameInterface {
/* Titlu Server */
public static final String FRAME_SERVER_TITLE = "Sistem distribuit de monitorizare si control a unui proces";
/* Eticheta meniului File */
public static final String MENU_FILE_LABEL = "Aplicatie";
/* Cheia meniului File */
public static final char MENU_FILE_MNEMONIC = 'A';
/* Eticheta meniului Exit */
public static final String MENU_EXIT_LABEL = "Inchide";
/* Cheia meniului EXIT */
public static final char MENU_EXIT_MNEMONIC = 'I';
/* Eticheta meniului Client */
public static final String MENU_CLIENT_LABEL = "Utilizator";
/* Cheia meniului Client */
public static final char MENU_CLIENT_MNEMONIC = 'U';
/* Eticheta meniului Change password */
public static final String MENU_CHANGE_PASSWORD_LABEL = "Modifica parola";
/* Cheia meniului Change password */
public static final char MENU_CHANGE_PASSWORD_MNEMONIC = 'M';
/* Eticheta meniului New User */
public static final String MENU_NEW_USER_LABEL = "Utilizator nou";
/* Cheia meniului New User */
public static final char MENU_NEW_USER_MNEMONIC = 'U';
/* Eticheta meniului List User */
public static final String MENU_LIST_USER_LABEL = "Afiseaza utilizatorii";
/* Cheia meniului List User */
public static final char MENU_LIST_USER_MNEMONIC = 'A';
/* Eticheta meniului Proces */
public static final String MENU_PROCES_LABEL = "Proces";
/* Cheia meniului Proces */
public static final char MENU_PROCES_MNEMONIC = 'P';
/* Eticheta meniului Start Proces */
public static final String MENU_STRAT_PROCES_LABEL = "Porneste Process";
/* Cheia meniului Start Proces */
public static final char MENU_START_PROCES_MNEMONIC = 'S';
}
UserFrameInterface
package ro.sdmcp.server;
/**
* @version 1.0
*/
public interface UserFrameInterface {
/* Titlu ferestrei */
public static final String FRAME_CHANGEPASSWORD_TITLE = "Modifica parola";
public static final String FRAME_ADDNEWUSER_TITLE = "Adauga utilizator";
public static final String FRAME_LISTUSER_TITLE = "Utilizatorii aplicatzie";
/* text pt nume client */
public static final String LABEL_USER = "Nume";
/* text pt parola veche client */
public static final String LABEL_OLD_PASSWORD = "Parola veche";
/* text pt parola noua client */
public static final String LABEL_NEW_PASSWORD = "Parola noua";
/* text pt confirmarea parolei client */
public static final String LABEL_CONFIRM_PASSWORD = "Confirma noua parola";
/* Eticheta butonului OK */
public static final String BUTTON_OK_TEXT = "Ok";
/* Cheia buronului OK */
public static final char BUTTON_OK_MNEMONIC = 'O';
/* Eticheta butonului Cancel */
public static final String BUTTON_CANCEL_TEXT = "Abandon";
/* Cheia buronului Cancel */
public static final char BUTTON_CANCEL_MNEMONIC = 'A';
/* eroare */
public static final String ERROR_USER = "Utilizatorul sau parola au fost introduse gresit! Verificati.";
/* eroare */
public static final String ERROR_PASSWORD = "Parola a fost introdusa gresit. Verificatzi.";
}
Client
Main
package ro.sdmcp.client;
import ro.sdmcp.icon.IconLoader;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window;
/**
* Clasa Client
* @version 1.0
*/
public class Main {
private LoginFrame loginFrame = null;
private Communication communicatzion = new Communication();
/**
*
* Constructor.
*
*/
public Main() {
/* incarca imaginile */
IconLoader.loadIcons();
this.loginFrame = new LoginFrame(communicatzion);
/* initzializeaza fereastra */
this.loginFrame.pack();
this.loginFrame.setResizable(false);
Main.setPosition(this.loginFrame);
this.loginFrame.setVisible(true);
}
/**
* Functia Main
* @param args
*/
public static void main(String[] args) {
new Main();
}
/**
* pozitioneaza fereastra in centrul ecranului
*/
public static void setPosition(Window pWindow) {
final int divisor = 2;
/* Dimenisunea ecranului */
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
/* build Position */
Dimension frameSize = pWindow.getSize();
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
/* set Position */
pWindow.setLocation((screenSize.width – frameSize.width) / divisor, (screenSize.height – frameSize.height) / divisor);
}
}
MenuFile
package ro.sdmcp.client;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import ro.sdmcp.icon.IconLoader;
/**
* Clasa pentru Meniul File
* @version 1.0
*/
public class MenuFile extends JMenu implements LoginFrameInterface {
private ClientFrame clientFrame = null;
private JMenuItem itemExit = null;
/**
*
* Constructor.
* @param pServerFrame Fereastra Server
*/
public MenuFile(ClientFrame pClientFrame){
super(MenuFile.MENU_FILE_LABEL);
this.clientFrame = pClientFrame;
this.setMnemonic(MenuFile.MENU_FILE_MNEMONIC);
/* init Menu Exit*/
this.itemExit = new JMenuItem(MenuFile.MENU_EXIT_LABEL);
this.itemExit.setMnemonic(MenuFile.MENU_EXIT_MNEMONIC);
this.itemExit.setIcon(IconLoader.EXIT);
this.itemExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
exit();
}
});
this.add(this.itemExit);
}
private void exit(){
System.exit(-1);
}
}
Comunication
package ro.sdmcp.client;
import ro.sdmcp.server.InfoTable;
import java.io.*;
import java.net.Socket;
/**
* @version 1.0
*/
public class Communication extends Thread {
public static final int PORT = 1313;
/* Socketul pt client */
private Socket clientSocket = null;
/* Bufferul de citire */
private BufferedReader read = null;
/* Bufferul de scriere */
private PrintWriter write = null;
private InfoTable infoTable = null;
/**
* @see java.lang.Runnable#run()
*/
public void run() {
while (true) {
String start = this.read();
String index = this.read();
String valoare = this.read();
String end = this.read();
this.infoTable.addInfoInTabel(index, valoare);
}
}
/**
*
* Porneste comunicarea de la Server;
*
*/
public void startCommunication(String pIP) throws Exception {
/* Blocam comunicatzia pana la aparitzia unui client */
this.clientSocket = new Socket(pIP, Communication.PORT);
this.read = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
this.write = new PrintWriter(new OutputStreamWriter(this.clientSocket.getOutputStream()), true);
}
/**
* opreste Comunicarea
*/
public void stopCommunication() {
try {
if (this.clientSocket != null) {
this.clientSocket.close();
}
} catch (Exception e) {
}
}
/**
* Scrie text in retzea
* @param pText
*/
public void write(String pText) {
if (this.write != null) {
this.write.println(pText);
}
}
/**
* Citeste text din retzea
* @return
*/
public String read() {
String citit = null;
try {
citit = this.read.readLine();
} catch (Exception e) {
e.printStackTrace();
}
return citit;
}
/**
* @param area
*/
public void setInfoTable(InfoTable pArea) {
this.infoTable = pArea;
}
/**
* @return
*/
public Socket getClientSocket() {
return this.clientSocket;
}
/**
* @param socket
*/
public void setClientSocket(Socket pSocket) {
this.clientSocket = pSocket;
}
}
MsgBox
package ro.sdmcp.client;
import java.awt.*;
import java.rmi.*;
import javax.swing.*;
public class MsgBox {
private static final boolean DEBUG = true;
private Component parent;
public MsgBox(Component parent) {
this.parent = parent;
}
public MsgBox() {
this(null);
}
private String getExceptionMessage(Throwable e) {
String ret = null;
if (e instanceof ServerException) {
ServerException server = (ServerException) e;
ret = getExceptionMessage(server.detail);
} else {
ret = getExceptionMessageString(e.getMessage());
}
return ret;
}
private String getExceptionMessageString(String s) {
return s;
}
private void showMessage(Object title, int type, Object message) {
String mes = checkMessage(message);
JOptionPane.showMessageDialog(parent, mes, title.toString(), type);
}
private String checkMessage(Object message) {
String mes = "NULL";
if (message != null) {
mes = message.toString();
if (message instanceof Throwable) {
mes = getExceptionMessage((Throwable) message);
if (mes == null) {
mes = "NULL";
}
if (DEBUG) {
System.out.println(mes);
((Throwable) message).printStackTrace();
}
}
StringBuffer buf = new StringBuffer(mes);
for (int i = 100; i < mes.length(); i += 100) {
buf.insert(i, '\n');
}
}
return mes;
}
public void showWarning(Object title, Object message) {
showMessage(title, JOptionPane.WARNING_MESSAGE, message);
}
}
ClientFrame
package ro.sdmcp.client;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import ro.sdmcp.icon.IconLoader;
import ro.sdmcp.server.InfoTable;
/**
* @version 1.0
*/
public class ClientFrame extends JFrame implements LoginFrameInterface {
/* Componenta MenuBar */
private JMenuBar menuBar = new JMenuBar();
/* Meniurile */
private MenuFile menuFile = null;
InfoTable infoTable = new InfoTable();
JScrollPane pnlInfo = new JScrollPane(infoTable);
JPanel pnlButtons = new JPanel();
JButton btnOk = new JButton();
private Communication communicatzion = null;
private String client = null;
/**
*
* constructor.
* @param pCommunication
*/
public ClientFrame(Communication pCommunication, String pClient) {
this.communicatzion = pCommunication;
this.client = pClient;
this.enableEvents(WindowEvent.WINDOW_CLOSING);
try {
initUI();
this.communicatzion.setInfoTable(this.infoTable);
this.communicatzion.start();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Initzializeaza interfata grafica
*
*/
private void initUI() {
/* seteaza titlul ferestrei */
this.setTitle(ClientFrame.FRAME_CLIENT_TITLE + ": " + this.client);
/* seteaza iconul ferestrei */
this.setIconImage(IconLoader.CLIENT.getImage());
/* adauga meniurile */
this.menuBar.add(this.menuFile = new MenuFile(this));
/* adauga Bara de meniu la Fereastra */
this.setJMenuBar(menuBar);
/* init Buttons */
this.btnOk.setText(ClientFrame.BUTTON_OPTIMIZEAZA_TEXT);
this.btnOk.setMnemonic(ClientFrame.BUTTON_OPTIMIZEAZA_MNEMONIC);
this.btnOk.setIcon(IconLoader.OK);
this.btnOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
action_Optimizeaza();
}
});
/* init panel Buttons */
this.pnlButtons.setLayout(new FlowLayout());
this.pnlButtons.setBorder(BorderFactory.createEtchedBorder());
this.pnlButtons.setBackground(Color.DARK_GRAY);
this.pnlButtons.add(this.btnOk);
/* adauga componentele */
this.getContentPane().add(this.pnlInfo, BorderLayout.CENTER);
this.getContentPane().add(this.pnlButtons, BorderLayout.SOUTH);
}
/**
* Actiune pt inchiderea ferestrei
* @see java.awt.Window#processWindowEvent(java.awt.event.WindowEvent)
*/
protected void processWindowEvent(WindowEvent e) {
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
System.exit(-1);
}
super.processWindowEvent(e);
}
private void action_Optimizeaza(){
this.communicatzion.write("optimizeaza");
}
/**
* @return
*/
public Communication getCommunicatzion() {
return communicatzion;
}
}
LoginFrame
package ro.sdmcp.client;
import ro.sdmcp.icon.IconLoader;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.ConnectException;
import java.net.UnknownHostException;
import javax.swing.*;
/**
* Ferestra Logare Client
* @version 1.0
*/
public class LoginFrame extends JFrame implements LoginFrameInterface {
JPanel pnlDate = new JPanel(new GridLayout(3, 2, 10, 5));
JLabel lblUser = new JLabel();
JTextField txfUser = new JTextField();
JLabel lblPassword = new JLabel();
JPasswordField txfPassword = new JPasswordField();
JLabel lblIP = new JLabel();
JTextField txfIp = new JTextField();
JPanel pnlButtons = new JPanel();
JButton btnOk = new JButton();
JButton btnCancel = new JButton();
private Communication communicatzion = null;
/**
*
* constructor.
* @param pCommunicatzion
*/
public LoginFrame(Communication pCommunicatzion) {
this.communicatzion = pCommunicatzion;
try {
initUI();
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* init Interfata
*/
private void initUI() throws Exception {
/* seteaza titlul ferestrei */
this.setTitle(LoginFrame.FRAME_CLIENT_TITLE);
/* seteaza iconul ferestrei */
this.setIconImage(IconLoader.IP.getImage());
/* init Data */
this.lblUser.setText(LoginFrame.LABEL_USER);
this.lblUser.setIcon(IconLoader.UTILIZATOR);
this.lblPassword.setText(LoginFrame.LABEL_PASSWORD);
this.lblPassword.setIcon(IconLoader.PAROLA);
this.lblIP.setText(LoginFrame.LABEL_IP);
this.txfIp.setText(LoginFrame.TEXTFIELD_IP_TEXT);
this.lblIP.setIcon(IconLoader.IP);
/* init Buttons */
this.btnOk.setText(LoginFrame.BUTTON_OK_TEXT);
this.btnOk.setMnemonic(LoginFrame.BUTTON_OK_MNEMONIC);
this.btnOk.setIcon(IconLoader.OK);
this.btnOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
actiuneButonOK();
}
});
this.btnCancel.setText(LoginFrame.BUTTON_CANCEL_TEXT);
this.btnCancel.setMnemonic(LoginFrame.BUTTON_CANCEL_MNEMONIC);
this.btnCancel.setIcon(IconLoader.EXIT);
this.btnCancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(-1);
}
});
/* init panel Buttons */
this.pnlButtons.setLayout(new FlowLayout());
this.pnlButtons.setBorder(BorderFactory.createEtchedBorder());
this.pnlButtons.setBackground(Color.DARK_GRAY);
/* add components */
this.pnlDate.add(this.lblUser);
this.pnlDate.add(this.txfUser);
this.pnlDate.add(this.lblPassword);
this.pnlDate.add(this.txfPassword);
this.pnlDate.add(this.lblIP);
this.pnlDate.add(this.txfIp);
this.pnlButtons.add(this.btnOk);
this.pnlButtons.add(this.btnCancel);
this.getContentPane().add(this.pnlDate, BorderLayout.CENTER);
this.getContentPane().add(this.pnlButtons, BorderLayout.SOUTH);
}
/**
* Actiunea de la butonul OK.
*
*/
private void actiuneButonOK() {
/* Culege informatile introduse de utilizator */
String client = this.txfUser.getText();
String password = String.valueOf(this.txfPassword.getPassword());
String ip = this.txfIp.getText();
try {
if (this.communicatzion.getClientSocket() == null) {
/* initzializeaza comunicatzia */
this.communicatzion.startCommunication(ip);
}
/* trimite user si parola pt autentificare */
this.communicatzion.write(client);
this.communicatzion.write(password);
/* Citeste raspuns de la server */
String raspuns = this.communicatzion.read();
if (raspuns.equals("true")) {
/* user corect */
this.dispose();
/* initializeaza fereastra client */
ClientFrame clientFrame = new ClientFrame(communicatzion, client);
clientFrame.pack();
clientFrame.setResizable(false);
Main.setPosition(clientFrame);
clientFrame.setVisible(true);
} else {
this.communicatzion.getClientSocket().close();
this.communicatzion.setClientSocket(null);
/* User sau parola gresite */
(new MsgBox()).showWarning("Eroare", LoginFrame.EROARE_UTILIZATOR);
}
} catch (ConnectException ex) {
/* eroare la conectare */
(new MsgBox()).showWarning("Eroare", LoginFrame.EROARE_CONECTARE);
} catch (UnknownHostException e) {
/* eroare la conectare */
(new MsgBox()).showWarning("Eroare", LoginFrame.EROARE_CONECTARE);
} catch (Exception e) {
e.printStackTrace();
}
}
}
LoginFrameInterface
package ro.sdmcp.client;
/**
* @version 1.0
*/
public interface LoginFrameInterface {
/* Titlu Client */
public static final String FRAME_CLIENT_TITLE = "Client";
/* text pt Nume Client */
public static final String LABEL_USER = "Nume";
/* text pt Parola Client */
public static final String LABEL_PASSWORD = "Parola";
/* text pt Ip Server */
public static final String LABEL_IP = "Adresa IP";
/* text pt IpTextfield */
public static final String TEXTFIELD_IP_TEXT = "localhost";
/* Eticheta butonului OK */
public static final String BUTTON_OK_TEXT = "Ok";
/* Cheia buronului OK */
public static final char BUTTON_OK_MNEMONIC = 'O';
/* Eticheta butonului Cancel */
public static final String BUTTON_CANCEL_TEXT = "Abandon";
/* Cheia buronului Cancel */
public static final char BUTTON_CANCEL_MNEMONIC = 'A';
/* Eticheta meniului File */
public static final String MENU_FILE_LABEL = "Aplicatie";
/* Cheia meniului File */
public static final char MENU_FILE_MNEMONIC = 'A';
/* Eticheta meniului Exit */
public static final String MENU_EXIT_LABEL = "Inchide";
/* Eticheta butonului Optimizeaza */
public static final String BUTTON_OPTIMIZEAZA_TEXT = "Optimizeaza";
/* Cheia buronului Optimizeaza */
public static final char BUTTON_OPTIMIZEAZA_MNEMONIC = 'O';
/* Cheia meniului EXIT */
public static final char MENU_EXIT_MNEMONIC = 'I';
public static final String EROARE_UTILIZATOR = "Utilizatorul sau parola au fost gresit introduse";
public static final String EROARE_CONECTARE = "Adresa IP nu e corecta sau nu e pornit servarul";
}
Proces
Process
package ro.sdmcp.proces;
import ro.sdmcp.server.ServerFrame;
import java.util.Random;
import java.util.TimerTask;
/**
* Clasa pentru process
* @version 1.0
*/
public class Process extends TimerTask {
public static final int LIMITA_INFERIOARA = 0;
public static final int LIMITA_SUPERIOARA = 100;
public static final long INTERVAL_DE_ASTEPTARE = 3000;
public static final int LIMITA_OPTIMA_INFERIOARA = 40;
public static final int LIMITA_OPTIMA_SUPERIOARA = 20;
public static final int DURATA_DE_CORECTARE_MINIMA = 5;
private static boolean optim = false;
public static int cat_mai_e_optim = 0;
private static Random rand = new Random();
private ServerFrame serverFrame = null;
private long count = 0;
public Process(ServerFrame pServerFrame) {
super();
this.serverFrame = pServerFrame;
}
/**
* Porneste procesul
* @see java.lang.Runnable#run()
*/
public void run() {
/* urmatorul index */
count++;
int de_trimis = 0;
if (!Process.optim) {
de_trimis = rand.nextInt(Process.LIMITA_SUPERIOARA);
} else {
de_trimis = Process.LIMITA_OPTIMA_INFERIOARA +
rand.nextInt(Process.LIMITA_OPTIMA_SUPERIOARA);
Process.cat_mai_e_optim–;
if (cat_mai_e_optim == 0) {
Process.optim = false;
}
}
/* trimit la server */
this.serverFrame.addInfo(String.valueOf(count), String.valueOf(de_trimis));
}
public static void optimizeazaProcess() {
Process.cat_mai_e_optim = Process.DURATA_DE_CORECTARE_MINIMA +
rand.nextInt(20);
Process.optim = true;
}
}
SimulareProcess
package ro.sdmcp.proces;
import ro.sdmcp.server.Main;
import ro.sdmcp.server.ServerFrame;
/**
* Clasa pentru simularea unui process
* @version 1.0
*/
public class SimulareProcess extends Thread {
private ServerFrame serverFrame = null;
public SimulareProcess(ServerFrame pServerFrame) {
this.serverFrame = pServerFrame;
}
/**
* Porneste procesul
* @see java.lang.Runnable#run()
*/
public void run() {
FrameProcess frameProcess = new FrameProcess(serverFrame);
frameProcess.pack();
Main.setPosition(frameProcess);
frameProcess.setVisible(true);
}
}
FrameProcess
package ro.sdmcp.proces;
import ro.sdmcp.icon.IconLoader;
import ro.sdmcp.server.ServerFrame;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.util.Timer;
import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* Fereastra Process
* @version 1.0
*/
public class FrameProcess extends JFrame implements FrameProcessInterface {
private ServerFrame serverFrame = null;
JPanel pnlButtons = new JPanel();
JButton btnOk = new JButton();
JButton btnCancel = new JButton();
Timer timerProcess = new Timer(true);
/**
*
* Constructor.
*
*/
public FrameProcess(ServerFrame pServerFrame) {
this.serverFrame = pServerFrame;
try {
this.enableEvents(WindowEvent.WINDOW_CLOSING);
initUI();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* init User Interface pt process
* @throws Exception
*/
private void initUI() throws Exception {
this.setTitle(FrameProcess.FRAME_PROCESS_TITLE);
this.setIconImage(IconLoader.CONECTARE.getImage());
this.getContentPane().setLayout(new BorderLayout());
/* init Buttons */
this.btnOk.setText(FrameProcess.BUTTON_SEND_TEXT);
this.btnOk.setMnemonic(FrameProcess.BUTTON_SEND_MNEMONIC);
this.btnOk.setIcon(IconLoader.CONECTARE);
this.btnOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
startServer();
}
});
this.btnCancel.setText(FrameProcess.BUTTON_CANCEL_TEXT);
this.btnCancel.setMnemonic(FrameProcess.BUTTON_CANCEL_MNEMONIC);
this.btnCancel.setIcon(IconLoader.EXIT);
this.btnCancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
opresteProces();
}
});
/* init panel Buttons */
this.pnlButtons.setLayout(new FlowLayout());
this.pnlButtons.setBorder(BorderFactory.createEtchedBorder());
this.pnlButtons.setBackground(Color.DARK_GRAY);
this.pnlButtons.add(this.btnOk);
this.pnlButtons.add(this.btnCancel);
this.getContentPane().add(this.pnlButtons, BorderLayout.SOUTH);
}
/**
* Inchide Ferestra
* @see java.awt.Window#processWindowEvent(java.awt.event.WindowEvent)
*/
protected void processWindowEvent(WindowEvent e) {
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
this.serverFrame.setStausEnabled4MenuStartProcess(true);
}
super.processWindowEvent(e);
}
/**
* Opreste procesul si inchide fereastra
*
*/
public void opresteProces() {
this.serverFrame.setStausEnabled4MenuStartProcess(true);
this.timerProcess.cancel();
this.dispose();
}
/**
* Trimite informatzia le server.
* Pentru ca Procesul este simulat printr-un Thread si pentru ca habar n-am cum
* se va face legatura dintre server si proces, informatzia se trimite
* obisnuit la server. fara a se mai face o legatura externa prin Soket.
*
*/
public void startServer() {
this.btnOk.setEnabled(false);
this.timerProcess.schedule(new Process(this.serverFrame), 0, Process.INTERVAL_DE_ASTEPTARE);
}
}
FrameProcessInterface
package ro.sdmcp.proces;
/**
* @version 1.0
*/
public interface FrameProcessInterface {
/* Titlu process */
public static final String FRAME_PROCESS_TITLE = "Simulare process …";
/* Eticheta Campului pt date */
public static final String LABEL_TEXT = "Informatia";
/* Eticheta butonului Send */
public static final String BUTTON_SEND_TEXT = "Porneste proces";
/* Cheia buronului Send */
public static final char BUTTON_SEND_MNEMONIC = 'P';
/* Eticheta butonului Cancel */
public static final String BUTTON_CANCEL_TEXT = "Opreste proces";
/* Cheia buronului Cancel */
public static final char BUTTON_CANCEL_MNEMONIC = 'O';
}
IconLoader
package ro.sdmcp.icon;
import javax.swing.*;
/**
* Clasa pentru incarcarea imaginilor
* @version 1.0
*/
public class IconLoader {
private static IconLoader loader = null;
public static ImageIcon CONECTARE = null;
public static ImageIcon EXIT = null;
public static ImageIcon NEW = null;
public static ImageIcon OK = null;
public static ImageIcon SERVER = null;
public static ImageIcon CLIENT = null;
public static ImageIcon UTILIZATOR = null;
public static ImageIcon PAROLA = null;
public static ImageIcon IP = null;
public static ImageIcon RAPORT = null;
public static ImageIcon NEW_USER = null;
/**
*
* Constructor.
*
*/
private IconLoader() {
try {
/* incarca imaginile */
CONECTARE = new ImageIcon(IconLoader.class.getResource("conectare.gif"));
EXIT = new ImageIcon(IconLoader.class.getResource("exit.gif"));
NEW = new ImageIcon(IconLoader.class.getResource("new.gif"));
OK = new ImageIcon(IconLoader.class.getResource("ok.gif"));
SERVER = new ImageIcon(IconLoader.class.getResource("server.gif"));
CLIENT = new ImageIcon(IconLoader.class.getResource("client.gif"));
UTILIZATOR = new ImageIcon(IconLoader.class.getResource("utilizator.gif"));
PAROLA = new ImageIcon(IconLoader.class.getResource("parola.gif"));
IP = new ImageIcon(IconLoader.class.getResource("ip.gif"));
RAPORT = new ImageIcon(IconLoader.class.getResource("report.gif"));
NEW_USER = new ImageIcon(IconLoader.class.getResource("newuser.gif"));
} catch (Exception e) {
System.err.println("Eroare : O imagine nu a putut fi incarcata : " + e);
}
}
/**
* Returneaza o instanta a clasei
* @return Instanta a calsei
*/
public static IconLoader getInstance() {
if (loader == null) {
loader = new IconLoader();
}
return loader;
}
/**
* Incarca toate imaginile
*
*/
public static void loadIcons() {
getInstance();
}
}
Bibliografie:
[1] Bruce Eckel – Thinking in Java – Second edition
[2] Dr.ing. Daniela Sararu – SISTEM SOFTWARE DE MONITORIZARE ÎN TIMP REAL
[3] Florin Păunescu – Sisteme cu prelucrare distribuită si aplicatiile lor
[4] SISTEM COMPLEX DE SUPRAVEGHERE A MEDIILOR – documentatii internet
[5] Limbajul Java in aplicatii industriale- documentatii internet
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Sistem Distribuit de Monitorizare Si Control a Unui Proces (ID: 149191)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
