-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsuunnittelu.tex
60 lines (37 loc) · 11.4 KB
/
suunnittelu.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
\chapter{Tuotantoversion suunnittelu}
\label{ch:suunnittelu}
\section{Kokonaiskuva}
% Aikaisempaa arkkitehtuuria tarkennetaan teknisesti ja rcb_sub nimetään.
Luvun \ref{ch:architecture-planning} arkkitehtuurin suunnittelun ja luvun \ref{ch:demo-analysis} demon analyysin pohjalta päädyttiin kuvassa \ref{fig:planned-system-architecture} esitettyyn systeemin arkkitehtuuriin. Kuva tarkentaa aikaisemmin suunniteltua arkkitehtuuria, joka esiteltiin kuvassa \ref{fig:high-level-system-architecture}. AMQP-välittäjäpalvelin päädyttiin toteuttamaan RabbitMQ-ohjelmistolla, joka on AMQP-stan\-dar\-diin perustuva välittäjäohjelmisto \cite{rabbitmq-homepage}. Väliohjelmistolle annettiin nimeksi rcb\_sub ja on merkitty kuvaan katkoviivalla. Tätä nimeä käytetään tästä eteenpäin tekstissä viittaamaan kyseiseen komponenttiin.
% TODO: Lisää kuvaan tai tekstiin tietoa missä käyttöliittymä järjestelmässä on.
\begin{figure}[ht!]
\includegraphics[width=1\textwidth]{pictures/planned-system-architecture.png}
\caption{Suunnitellun järjestelmän arkkitehtuuri sekä viestin kulku ja muoto sen osapuolten läpi.}
\label{fig:planned-system-architecture}
\end{figure}
% Viestin kulku pääpiirteittäin järjestelmän läpi.
Kuvassa vasemmalla on IED-laite, josta rcb\_sub tilaa viestit MMS-protokollan avulla. Rcb\_sub prosessoi saapuneet viestit JSON-muotoon ja uudelleenjulkaisee ne RabbitMQ-palvelimelle. Järjestelmän muut komponentit tilaavat JSON-viestejä välittäjäpalvelimelta tarpeidensa mukaan.
Rcb\_sub päädyttiin toteuttamaan C-kielellä komentorivipohjaiseksi ohjelmistoksi. Muu järjestelmä ohjaa komponentin suoritusta ja syöttää tilaukseen tarvittavat tiedot sille komentoriviparametreinä. Rcb\_sub pystyi tilaamaan yhden IED-laitteen halutun määrän RCB-instansseja. AMQP-stan\-dar\-dis\-ta on olemassa eri versioita ja valittu RabbitMQ-ohjelmisto käytti versiota 0.9.1. Rcb\_sub käytti demosta tuttua libIEC61850-kirjastoa hoitamaan matalan tason IEC 61850 -stan\-dar\-din toiminnallisuuden.
% Yleiskuva tilauksen orkesteroinnista.
\section{AMQP-välittäjäpalvelin}
AMQP-pohjaisen välittäjäpalvelimen toteutukseen löytyy erilaisia ohjelmistoja mm. RabbitMQ, Apache Qpid ja StormMQ. Työssä AMQP-pohjaisen palvelimen toteuttamiseen valittiin RabbitMQ. RabbitMQ on ilmainen avoimen lähdekoodin välittäjäpalvelin ja sille on olemassa kattava tuki monelle eri kielelle asiakasohjelmiston toteuttamiseen \cite{rabbitmq-supported-languages}. Vertailun perusteella se vaikutti toteutukseen hyvältä vaihtoehdolta.
AMQP-standardista on julkaistu monta eri versiota, ja työn tekohetkellä viimeisin versio oli 1.0. RabbitMQ-ohjelmisto on suunniteltu käytettäväksi standardin version 0.9.1 kanssa, ilman asennettuja lisäosia. Versioiden välinen ero on suuri ja siirto uuteen ei ollut mahdollista, koska standardin versiot eivät olleet keskenään yhteensopivat. RabbitMQ tuki versiota 0.9.1 ja sen kehittäjät mieltävät standardin version 1.0 kokonaan eri protokollaksi \cite{RabbitMQ-Compatibility-and-Conformance}. Tämä ei kuitenkaan sen käyttöä haitannut, koska versio 0.9.1 kattaa kaikki suunnitellut hajautetun järjestelmän paradigmat. Paradigmoja olivat viestijono ja julkaisija-tilaaja. RabbitMQ:ta voi käyttää AMQP version 1.0 kanssa erillisellä lisäosalla. RabbitMQ lupaa jatkaa version 0.9.1 tukemista, jolloin sitä on myös mahdollista käyttää jatkossakin \cite{RabbitMQ-Compatibility-and-Conformance}.
\section{Tilauksen orkestrointi ja tiedon välitys}
Muun järjestelmän on tarkoitus ohjata rcb\_sub-ohjelman suoritusta. IED-laitteilta viestien tilauksia käyttäjä voi ohjata järjestelmän käyttöliittymästä. Tilauksen aloittaessa järjestelmä käynnistää rcb\_sub-ohjelmiston omana prosessinaan yhtä IED-laitetta kohti. Tilauksen loputtua järjestelmä lopettaa rcb\_sub-prosessin suorituksen. Suorituksen aikana tulevat virheet ohjataan järjestelmälle, joka voi toimia tarvittaessa niiden mukaan, esimerkiksi käynnistää prosessin uudestaan. Kaikkien rcb\_sub-prosessien on tarkoitus ohjata JSON-viestit saman RabbitMQ-palvelimen läpi muulle järjestelmälle.
Rcb\_sub-ohjelmaa oli tarkoitus ajaa taustaprosessina, jolloin siihen ei tarvittu käyttöliittymää. Tämän takia se päätettiin toteuttaa komentorivipohjaisena ohjelmana. Muu järjestelmä oli rakennettu suoritettavaksi Linux-käyttöjärjestelmän päällä, joten rcb\_sub toteutettiin myös samalle käyttöjärjestelmälle. Jotta rcb\_sub voi tehdä tilauksen IED-laitteelle ja tietää mitkä RCB-instanssit tilataan, täytyy järjestelmän tarjota tämä tieto. Tarvittavaa tietoa ovat IED-laitteen ja AMQP-palvelimen IP-osoitteet, tilattavien RCB-instanssien viitteet ja arvot, viestien julkaisuun välittäjäpalvelimelle tarvittavat tiedot. RCB-instanssille kirjoitettavat arvot sisältävät vaihtoehtoiset kentät ja liipaisimet. Julkaisuun tarvittavia tietoja ovat käytettävän \emph{vaihteen} (\emph{exchange}) nimi ja \emph{reititysavain} (\emph{routing key}). Vaihde on AMQP-palvelimella käsite, johon tilaajat tekevät tilauksia ja on vastuussa viestien reitittämisestä oikeille tilaajille. Reititysavain on viestin tunniste millä se julkaistaan. Tämän ja tilaajan tekemän tilauksen mukaan vaihde reitittää viestit oikeille tilaajille. Toisin sanoen reititysavain sisältää IED-laitteen tunnisteen. Tämän perusteella tilaaja voi tilata haluamansa IED-laitteen viestit.
Tiedon välittämiseen prosessien välillä on olemassa monia eri tapoja. Jos tieto on pysyvää ja siinä ei ole muutoksia, yksi vaihtoehto olisi ollut konfiguraatiotiedosto. Järjestelmässä kuitenkin tilattavien RCB-instanssien määrä ja IED-laitteen tiedot voivat muuttua. Tämän takia päädyttiin käynnistyksen yhteyteen annettuihin komentoriviparametreihin. Muu järjestelmän osa, joka rcb\_sub-prosessin käynnistää, voi kaiken tarvittavan tiedon antaa prosessille parametreillä käynnistyksen yhteydessä. Vaikka tieto tilauksien välillä muuttuu, prosessi käynnistetään aina viimeisimmillä tiedoilla. Ohjelmalle ei ollut asetettu vaatimusta, että tietoja pystyisi muuttamaan tilauksen aikana. Jos tietoja tarvitsee muuttaa, lopetetaan edellinen tilaus ja käynnistetään uusi prosessi uusilla parametreilla. Sama periaate on myös järjestelmän käyttöliittymässä. Myöhemmin tulevaisuudessa tarpeen vaatiessa voidaan siirtyä dynaamisen tilauksen muutokseen, mutta tällä hetkellä sille ei ollut tarvetta.
AMQP ei tarjoa mahdollisuutta julkaisujen mainostukseen, kuten käsiteltiin julkaisija-tilaaja-paradigman yhteydessä \cite{AMQP-specification}. Järjestelmän komponenttien pitää saada tieto olemassa olevista julkaisijoista muulta järjestelmältä. Tämä tieto järjestelmässä siirretään komponenteille tietokannan kautta. Kuvassa \ref{fig:example-use-case} on esitetty käyttötapausesimerkki, jossa mittaustietoa käyttävä komponentti tilaa viestejä ja lähettää sen käyttäjän selaimen käyttöliittymään web-pistoketta pitkin \cite{websocket}. Selaimessa JavaScript-koodi päivittää käyttöliittymän komponentteja saadun tiedon mukaan.
\begin{figure}[ht!]
\includegraphics[width=1\textwidth]{pictures/example-use-case.png}
\caption{Esimerkkikäyttötapaus, jossa mittaustietoa tilaava komponentti lähettää tietoa selaimen käyttöliittymään web-pistokkeen avulla.}
\label{fig:example-use-case}
\end{figure}
\section{Suorituskyky ja kielen valinta}
Ennen koko ohjelman uudelleenkirjoitusta, kokeiltiin demoa korjata vaihtamalla Ruby-tulkkia. Ruby:n oletustulkki yritettiin vaihtaa \emph{JRuby}-tulkkiin \cite{jruby-homepage}. Tavoitteena vaihdossa oli saada Ruby-ohjelma toimimaan ilman globaalia tulkkilukitusta (GIL). JRuby on Ruby-tulkki, joka suorittaa Ruby-koodia \emph{Java-virtuaalikoneen} (\emph{Java Virtual Machine}, \emph{JVM}) päällä. JRuby mahdollistaa säikeiden suorituksen rinnakkain JVM:n omilla säikeillä ja näin ollen suorituksen pitäisi olla nopeampaa \mbox{\cite{Youssef2013}}. Aidolla rinnakkaisuudella ohjelman suoritus ei olisi pysähtynyt viestin saapuessa takaisinkutsufunktion suorituksen ajaksi. Tämä ei vielä olisi kuitenkaan ratkaissut kaikkia ohjelmassa olevia ongelmia, kuten muistivuotoa ja hitaampaa suorituskykyä verrattuna käännettävään kieleen. Tämä toteutus ei kuitenkaan toiminut, ja yrityksen jälkeen päätettiin palata suunnitelmaan kirjoittaa koko ohjelma uudestaan. JRuby ei tukenut kaikkia projektin käyttämiä kirjastoja. Seurauksena olisi ollut saman projektin ylläpitäminen kahdelle eri tulkille tai asennettavien kirjastojen erottaminen. Kaikkiaan oli helpompaa kirjoittaa ohjelma alusta toisella tekniikalla.
Uuden toteutuksen kieleksi valittiin C-kieli. Isona syynä kielen valintaan oli sen suorituskyky. C-koodi käännetään alustalle suoraan konekäskyiksi, joiden suoritus on nopeampaa kuin tulkattavan kielen, kuten Ruby ja Python. Valintaan vaikutti myös tekijän iso mieltymys matalan tason ohjelmointiin ja C-kieleen. Kielen valinnan yhteydessä varmistettiin kaikkien suunniteltujen liitosten mahdollisuus. C-kielelle löytyi kirjastoja RabbitMQ-välittäjäpalvelimen käyttämiseen ja lisäksi JSON-rakenteen muodostamiseen. Hyötynä vielä C-kielen valinnasta oli, että demossa käytettyä libIEC61850-kirjastoa pystyttiin käyttämään suoraan ilman erillistä liitosta, koska kirjasto oli myös toteutettu C-kielellä.
\section{JSON-viestin rakenne}
IED-laitteelta saapuva viesti päädyttiin muuntamaan JSON-muotoon helpompaa luettavuutta varten. Liitteessä \ref{ch:report-json-format} on esitetty viestin rakenne. JSON:n noudattaa pääosin standardin mukaista viestin rakennetta. Erona standardin malliin on, että muuttujiin päätettiin lisätä viite, tyyppi ja koko bitteinä. Nämä tiedot todettiin tarpeellisiksi, koska niiden avulla tilaajan on helpompi ymmärtää viestin sisältöä. Tarvittavat lisätiedot luetaan IED-laitteelta erillisellä palvelukutsulla ennen tilauksen aloittamista. Nämä tiedot yhdistetään saapuneen viestin kanssa ja sijoitetaan JSON-rakenteeseen.
% Viestiin lisätään kaikki mahdolliset kentät ja puuttuvat arvot korvattiin null-arvolla.
Standardin mukainen viesti sisältää vaihtoehtoisia kenttiä, joita tilaaja voi konfiguroida RCB-instanssille ennen tilauksen aloittamista. Tällä tilaaja voi poistaa viestistä tarpeettomaksi koettua tietoa. Kuitenkin JSON-viestiin haluttiin lisätä kaikki mahdolliset kentät selkeyden takia. Jos kenttä puuttui IED-laitteelta saapuneesta viestistä, asetettiin sen arvoksi JSON-viestiin null-arvo. Esimerkkinä tästä on liitteen \ref{ch:report-json-format} rivillä 4 oleva \emph{confRevision}-kenttä, jonka arvoksi on asetettu null.
% Poikkeuksia JSON-viestin muuttujien välillä.
Lisätyt kentät sisältävät joitakin poikkeuksia. Kokoa bitteinä ei ole lisätty \emph{boolean} ja \emph{utc-time} tyyppisille muuttujille, koska tätä tietoa ei saa IED-laitteelta. \emph{Bit-string} tyypille lisättiin kaksi arvo-kenttää \emph{valueLittleEndian} ja \emph{valueBigEndian} yhden sijaan, koska se on mahdollista lukea eri bittijärjestyksellä (little ja big endian). Aikayksiköt päätettiin antaa suoraan samassa formaatissa kuin alkuperäisessä viestissä. Viestin päätason aikaleima (rivi 5) on millisekunteja \emph{UNIX}-ajanlaskun alusta 1. tammikuuta 1970 klo 00:00:00 UTC (epoch) tähän hetkeen. Muissa muuttujissa tyypiltään \emph{utc-time}, luku on sekunteja samasta UNIX-ajanlaskusta tähän hetkeen \mbox{\cite[s.~26--27]{IEC61850-7-2}}.