1793 lines
90 KiB
HTML
1793 lines
90 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||
<html><head><title>LeonardoPlatform Simulator - Reference Manual</title>
|
||
|
||
<style title="" media="" type="text/css">
|
||
body {
|
||
border-top-style: none;
|
||
border-right-style: none;
|
||
border-bottom-style: none;
|
||
border-left-style: none;
|
||
font-family: Arial, Helvetica, sans-serif;
|
||
list-style-type: upper-alpha;
|
||
background-color: white;
|
||
counter-reset: h1counter;
|
||
}
|
||
h1::before {
|
||
counter-increment: h1counter;
|
||
content: counter(h1counter, decimal) ". ";
|
||
}
|
||
h2::before {
|
||
counter-increment: h2counter;
|
||
content: counter(h1counter, decimal) "." counter(h2counter, decimal) ". ";
|
||
}
|
||
h3::before {
|
||
counter-increment: h3counter;
|
||
content: counter(h1counter, decimal) "." counter(h2counter, decimal) "." counter(h3counter, decimal) ". ";
|
||
}
|
||
h4::before {
|
||
counter-increment: h4counter;
|
||
content: counter(h1counter, decimal) "." counter(h2counter, decimal) "." counter(h3counter, decimal) "." counter(h4counter, decimal) ". ";
|
||
}
|
||
h5::before {
|
||
counter-increment: h5counter;
|
||
content: counter(h1counter, decimal) "." counter(h2counter, decimal) "." counter(h3counter, decimal) "." counter(h4counter, decimal) "." counter(h5counter, decimal) ". ";
|
||
}
|
||
h1 {
|
||
counter-reset: h2counter;
|
||
}
|
||
h2 {
|
||
counter-reset: h3counter;
|
||
}
|
||
h3 {
|
||
counter-reset: h4counter;
|
||
}
|
||
h4 {
|
||
counter-reset: h5counter;
|
||
}
|
||
h1, h2, h3, h4, h5 {
|
||
-webkit-text-decoration-color: currentcolor;
|
||
text-decoration-color: currentcolor;
|
||
-webkit-text-decoration-line: underline;
|
||
text-decoration-line: underline;
|
||
-webkit-text-decoration-style: solid;
|
||
text-decoration-style: solid;
|
||
list-style-type: decimal;
|
||
font-weight: bold;
|
||
text-align: left;
|
||
text-transform: capitalize;
|
||
}
|
||
h5 {
|
||
-webkit-text-decoration-color: currentcolor;
|
||
text-decoration-color: currentcolor;
|
||
-webkit-text-decoration-line: underline;
|
||
text-decoration-line: underline;
|
||
-webkit-text-decoration-style: solid;
|
||
text-decoration-style: solid;
|
||
list-style-type: decimal;
|
||
font-weight: bold;
|
||
font-style: italic;
|
||
text-align: left;
|
||
}
|
||
code, div.notes {
|
||
border-top-style: groove;
|
||
border-right-style: groove;
|
||
border-bottom-style: groove;
|
||
border-left-style: groove;
|
||
border-top-width: thin;
|
||
border-right-width: thin;
|
||
border-bottom-width: thin;
|
||
border-left-width: thin;
|
||
background-color: #f8f8f8;
|
||
display: block;
|
||
}
|
||
table, th, tr, td {
|
||
border-top-style: groove;
|
||
border-right-style: groove;
|
||
border-bottom-style: groove;
|
||
border-left-style: groove;
|
||
border-top-width: thin;
|
||
border-right-width: thin;
|
||
border-bottom-width: thin;
|
||
border-left-width: thin;
|
||
}
|
||
th {
|
||
border-top-style: groove;
|
||
border-right-style: groove;
|
||
border-bottom-style: groove;
|
||
border-left-style: groove;
|
||
border-top-width: thin;
|
||
border-right-width: thin;
|
||
border-bottom-width: thin;
|
||
border-left-width: thin;
|
||
background-color: #f8f8f8;
|
||
font-weight: bold;
|
||
font-style: italic;
|
||
}
|
||
@media print {
|
||
h1 {
|
||
page-break-before: always;
|
||
}
|
||
code {
|
||
page-break-inside: avoid;
|
||
}
|
||
}
|
||
code {
|
||
line-height: normal;
|
||
font-size: smaller;
|
||
font-family: "Courier New", "Courier", "monospace";
|
||
}
|
||
div.example {
|
||
border: thin ridge #666666;
|
||
background-color: silver;
|
||
font-family: Arial monospaced for SAP;
|
||
font-size: small;
|
||
opacity: 0.821;
|
||
min-height: 50px;
|
||
display: block;
|
||
max-height: 400px;
|
||
overflow: auto;
|
||
margin-left: 40px;
|
||
width: 90%;
|
||
}
|
||
</style></head>
|
||
<body style="list-style-type: upper-alpha; background-color: white;">
|
||
<p style="text-align: center;"> <img style="width: 373px; height: 85px;" alt="logo leonardo" src="refman_files/logo.png"> </p>
|
||
<p style="font-weight: bold; text-align: center;"><big><big><big>Leonardo
|
||
Platform Simulator Reference Manual</big></big></big>
|
||
</p>
|
||
<p style="page-break-after: always;"> </p>
|
||
|
||
<br><ol id="mozToc"><!--mozToc h1 1 h2 2 h3 3 h4 4 h5 5 h6 6--><li><a href="#mozTocId732286">Introduzione </a></li><li><a href="#mozTocId926570">
|
||
Configurazione </a><ol><li><a href="#mozTocId463901">
|
||
File INI </a><ol><li><a href="#mozTocId605704">ConfigFile</a></li><li><a href="#mozTocId794984">
|
||
BusDriver </a></li><li><a href="#mozTocId437925">
|
||
UiFile </a></li><li><a href="#mozTocId620990">
|
||
Plugin </a></li><li><a href="#mozTocId852574">
|
||
IniScript </a></li></ol></li></ol></li><li><a href="#mozTocId198944">
|
||
Caratteristiche</a></li><li><a href="#mozTocId689606">Funzionalita`
|
||
di Base</a><ol><li><a href="#mozTocId214044">Argomenti
|
||
globali</a><ol><li><a href="#mozTocId398862">Session</a></li><li><a href="#mozTocId624687">appdata</a></li><li><a href="#mozTocId312810">Ini</a></li><li><a href="#mozTocId683131">Python</a></li></ol></li><li><a href="#mozTocId96513">Modalita'
|
||
grafica </a><ol><li><a href="#mozTocId75966">GUI
|
||
Mode</a><ol><li><a href="#mozTocId73236">comando
|
||
e controllo { controllo interfaccia / bus }</a></li><li><a href="#mozTocId3675">indicatore
|
||
messaggi</a></li><li><a href="#mozTocId334611">iniettore
|
||
errori di protocollo</a></li><li><a href="#mozTocId957256">gestione
|
||
scrittura ed invio dei dati</a><ol><li><a href="#mozTocId82468">Commit
|
||
Changes</a></li><li><a href="#mozTocId203014">Revert
|
||
Changes</a></li><li><a href="#mozTocId367825">Commit
|
||
on the Fly</a></li><li><a href="#mozTocId570965">Invio
|
||
di messaggi non modificati</a></li><li><a href="#mozTocId534388">richiesta
|
||
ricezione messaggio</a></li></ol></li></ol></li><li><a href="#mozTocId89906">Python
|
||
Mode</a><ol><li><a href="#mozTocId122903">controlli
|
||
Python</a></li><li><a href="#mozTocId621043">Python
|
||
Script #0</a></li><li><a href="#mozTocId523292">Terminal
|
||
#(n)</a></li></ol></li></ol></li><li><a href="#mozTocId725560">
|
||
CLI
|
||
( Command Line Interpreter ) </a></li><li><a href="#mozTocId188823">Batch </a></li><li><a href="#mozTocId138808">Log di un traffico dati </a><ol><li><a href="#mozTocId56048">Contenuto del file di log </a></li></ol></li><li><a href="#mozTocId9522">Plugins</a></li></ol></li><li><a href="#mozTocId892472">Funzionalita`
|
||
avanzate</a><ol><li><a href="#mozTocId357140">Modificare
|
||
layout di interfaccia </a></li><li><a href="#mozTocId457542">Utilizzare
|
||
uno script Python come Bus</a><ol><li><a href="#mozTocId379714">Esempio</a></li></ol></li><li><a href="#mozTocId589281">Utilizzare
|
||
uno script Python come Plugin</a><ol><li><a href="#mozTocId450787">addAction</a></li><li><a href="#mozTocId986824">onPluginAction</a></li><li><a href="#mozTocId33149">consumeICDEvent</a></li><li><a href="#mozTocId557041">Esempio</a></li></ol></li></ol></li><li><a href="#mozTocId733406">Risoluzione
|
||
dei Problemi</a></li></ol>
|
||
<div style="margin-left: 40px;">
|
||
<h1><a class="mozTocH1" name="mozTocId732286"></a>Introduzione </h1>
|
||
'Leonardo Platform Simulator' e' un' applicazione destinata
|
||
alle attivita' di test e qualifica di apparati che utilizzano
|
||
protocolli di comunicazione dati.<br>
|
||
<p> Poiche' tali attivita' sono spesso effettuate utilizzando
|
||
medesime tipologie di bus o metodologie di comunicazione, si e' cercato
|
||
di realizzare un ambiente software atto a soddisfare tali esigenze con
|
||
il proposito di minimizzare la scrittura di nuovo codice. </p>
|
||
<p> Lo scopo di questo documento <20> definire una guida
|
||
all'utilizzo del software 'Leonardo Platform Simulator'. </p>
|
||
<br>
|
||
'Leonardo Platform Simulator' ha le seguenti caratteristiche:<br>
|
||
<ol>
|
||
<li>Generazione automatica della GUI </li>
|
||
<li>Generazione automatica del protocollo di comunicazione
|
||
tramite ICD espresso in linguaggio formale (es. file XML ) </li>
|
||
<li>Facilit<EFBFBD> di utilizzo e impiego su hardware di produttori
|
||
differenti </li>
|
||
<li>Accesso remoto dellinterfaccia </li>
|
||
<li>Automatizzazione delle operazioni sulle interfacce (test) </li>
|
||
<li>Personalizzazione delle logiche di simulazione attraverso
|
||
il meccanismo dei plugin </li>
|
||
<li>Interfaccia Python e meccanismo di scripting integrato </li>
|
||
<li>Multipiattaforma (Windows, Linux, & ) </li>
|
||
<li>Costi di licenza nulli tramite utilizzo SW factory open
|
||
sourc </li>
|
||
<li>Sistema di diagnostica evoluto e personalizzabile (eg.
|
||
ERROR, WARNING, INFO ) </li>
|
||
</ol>
|
||
<br>
|
||
L' interfaccia grafica del simulatore di piattaforma, come anche i
|
||
protocolli di comunicazione, sono gestiti automaticamente interpretando
|
||
un file di inizializzazione che ne descrive le caratteristiche in
|
||
termine di:
|
||
<ul style="margin-left: 40px;">
|
||
<li>Numero di interfacce gestite </li>
|
||
<li>Descrizione della singola interfaccia per mezzo di un
|
||
documento (ICD) che dettaglia la codifica dei dati ossia:
|
||
<ul>
|
||
<li>Messaggio: </li>
|
||
<li>velocit<EFBFBD> </li>
|
||
<li>trasmissione/ricezione </li>
|
||
<li>lunghezza </li>
|
||
<li>periodicit<EFBFBD> </li>
|
||
</ul>
|
||
</li>
|
||
<li>Campi costituenti il messaggio:
|
||
<ul>
|
||
<li>tipo di dato ( numero, stringa, booleano,& ) </li>
|
||
<li>dimensione </li>
|
||
<li>range operativo </li>
|
||
<li>tipo di codifica </li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<p style="margin-left: 40px;"> L'
|
||
applicativo implementa il concetto di Model/View/Controller
|
||
(MVC),disaccoppiando linterfaccia grafica e la gestione dei dati in
|
||
modo da aumentarne la flessibilit<69> ed il riuso.<br>
|
||
Permette, ad esempio, di poter utilizzare diverse piattaforme di
|
||
protocollo proprietario aggiungendo librerie senza intervenire sull
|
||
interfaccia grafica.<br>
|
||
Il framework <20> dotato di un motore di scripting integrato ( Python ).<br>
|
||
Tale motore <20> mirato ad offrire la possibilit<69>, da parte
|
||
dellutilizzatore, di elaborare algoritmi ed operazioni che
|
||
interagiscano con linterfaccia di comunicazione e descrivano sequenze
|
||
operative ripetibili per mezzo di script.<br>
|
||
E inoltre possibile accedere al simulatore tramite connessione remota,
|
||
utilizzando un servizio basato su un sistema di RPC (Remote Procedure
|
||
Call), esportando gli oggetti Python propri del simulatore. </p>
|
||
<p style="margin-left: 40px;"> I possibili campi di
|
||
utilizzo sono svariati grazie alle sue caratteristiche. </p>
|
||
<ul style="margin-left: 40px;">
|
||
<li>Accesso al simulatore da remoto (via GUI o command line) </li>
|
||
<li>Scalabilit<EFBFBD> multidirezionale fra i diversi moduli </li>
|
||
<li>La tracciabilit<69> del traffico dati dellinterfaccia <20>
|
||
flessibile adattandosi alle esigenze dell` operatore in termini di
|
||
livello di accuratezza. </li>
|
||
<li>Modalit<EFBFBD> di preparazione del test comune ed indipendente
|
||
dal programma specifico grazie alle API in Python </li>
|
||
<li>E possibile aggiungere, rimuovere, modificare le interfacce
|
||
di piattaforma semplicemente intervenendo su file di configurazione,
|
||
senza intervenire sul codice sorgente </li>
|
||
<li>Eventuali personalizzazioni dedicate alla singola
|
||
interfaccia, per esempio:
|
||
<ul>
|
||
<li>meccanismi automatici di trasmissione/ricezione </li>
|
||
<li>menu/funzionalit<69> specifiche di un apparato </li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h1><a class="mozTocH1" name="mozTocId926570"></a>
|
||
Configurazione </h1>
|
||
Leonardo Platform Simulator e' configurabile attraverso files
|
||
che ne descrivono le caratteristiche ed il
|
||
comportamento in termini di:<br>
|
||
<ol>
|
||
<li>caratteristiche globali </li>
|
||
<li>descrizione del numero di interfacce a cui l'applicazione
|
||
deve connettersi </li>
|
||
<li>caratteristiche della singola interfaccia </li>
|
||
<li>definizione del vocabolario di comunicazione </li>
|
||
</ol>
|
||
<h2><a class="mozTocH2" name="mozTocId463901"></a>
|
||
File INI </h2>
|
||
Il file che definisce globalmente l'operativita' ( sessione )
|
||
dell'applicativo verso un dato sistema e' un file
|
||
<session name>.INI.<br>
|
||
Il file .INI utilizza il seguente formalismo:</div>
|
||
<div style="margin-left: 40px;"> <br>
|
||
<code>[Globals]<br>
|
||
(IniScript=<path_to_file>{.py})<br>
|
||
(StyleSheet=<path_to_file>)<br>
|
||
(Icon=<path_to_file>)<br>
|
||
(LegacyName=<legacy_code_string>)<br>
|
||
(Font=<string>)<br>
|
||
(Geometry=<string>)<br>
|
||
InterfaceSize=<n><br>
|
||
<br>
|
||
[Interface_(i=0..n-1)]<br>
|
||
Name=First Interface<br>
|
||
ConfigFile=<path_to_file>{.xml}<br>
|
||
BusDriver=<path_to_file>{(.dll|.so)|.py}<br>
|
||
UiFile=<path_to_file>{.ui}<br>
|
||
(Plugin=<path_to_file>{(.dll|.so)|.py})<br>
|
||
(CurrentLogPath=<path>)<br>
|
||
(IniScript=<path_to_file>{.py} )<br>
|
||
<br>
|
||
[Tools]<br>
|
||
(Plugin_0=<path_to_file>{(.dll|.so)|.py}</code><br>
|
||
L'applicativo, una volta determinata la sessione,
|
||
in fase di inizializzazione carica per ogni interfaccia una serie di
|
||
files:<br>
|
||
<ul>
|
||
<li>database ICD [ConfigFile] </li>
|
||
<li>driver di comunicazione [BusDriver] </li>
|
||
<li>interfaccia grafica [UiFile] </li>
|
||
<li>plugin [Plugin] </li>
|
||
<li>script python [IniScript] </li>
|
||
</ul>
|
||
I Plugin opzionali *plugin raccolti nella cartella
|
||
$(LeoPlatSimHomeDir)/options vengono automaticamente inclusi nella
|
||
sessione, altri possono essere specificati nella sezione Tools del file
|
||
.INI.<br>
|
||
Per essere riconosciuti tali plugin devono, oltre a rispettare
|
||
la struttura software basata su SDK dedicato, avere la dicitura <span style="font-weight: bold;">"<nome>Plugin.<estensione>"</span><br>
|
||
con: <br>
|
||
<ul>
|
||
<li><nome> : testo libero</li>
|
||
<li><estensione> : py ( plugin Python )
|
||
oppure dll ( Windows ) o so ( Linux ) </li>
|
||
</ul>
|
||
<h3><a class="mozTocH3" name="mozTocId605704"></a>ConfigFile</h3>
|
||
<p> E' un file che descrive la composizione dei messaggi di
|
||
interscambio tra il simulatore ed il target.<br>
|
||
Utilizza un formalismo XML le cui regole di composizione sono tracciate
|
||
dal documento DTD:<br>
|
||
<br>
|
||
<code><?xml version='1.0' encoding='utf-8' ?><br>
|
||
<!DOCTYPE ICDHandler [<!ELEMENT ICDHandler
|
||
(HiLevel,LowLevel,Mapping)><br>
|
||
<!ELEMENT HiLevel (Message+)><br>
|
||
<!ELEMENT Message (Field+)><br>
|
||
<!ELEMENT Field (Values*)><br>
|
||
<!ELEMENT Values (Value+)><br>
|
||
<!ELEMENT Value (#PCDATA)><br>
|
||
<!ATTLIST ICDHandler<br>
|
||
Name CDATA #REQUIRED<br>
|
||
Version CDATA
|
||
#REQUIRED<br>
|
||
Endianness
|
||
(rawbyte|bigendian16|bigendian32|littleendian16|littleendian32)
|
||
"rawbyte"<br>
|
||
Ui
|
||
(all_tab|all_vertical|all_horizontal|by_iotype) "by_iotype"<br>
|
||
><br>
|
||
<!ATTLIST Message<br>
|
||
Id CDATA #REQUIRED<br>
|
||
Name CDATA #REQUIRED<br>
|
||
Width CDATA #REQUIRED<br>
|
||
IOType (tx|rx)
|
||
#REQUIRED<br>
|
||
uSecPeriodTime CDATA
|
||
#IMPLIED<br>
|
||
><br>
|
||
<!ATTLIST Field<br>
|
||
Name CDATA #REQUIRED<br>
|
||
Width CDATA #REQUIRED<br>
|
||
Offset CDATA
|
||
#REQUIRED<br>
|
||
Min CDATA #IMPLIED<br>
|
||
Max CDATA
|
||
#IMPLIED <br>
|
||
Weight CDATA "1"<br>
|
||
OffsetValue CDATA "0"<br>
|
||
Type
|
||
(spare|boolean|short|ushort|int|uint|long|ulong|double|float|string|enum)
|
||
#REQUIRED<br>
|
||
Unit CDATA #IMPLIED<br>
|
||
Display
|
||
(binary|decimal|hexadecimal) "decimal"<br>
|
||
Default CDATA
|
||
#IMPLIED<br>
|
||
Encoding
|
||
(sign_module|bcd|binary|=<formula>) "binary"<br>
|
||
Resolution CDATA
|
||
"0.000001"<br>
|
||
Ui
|
||
(default|entry|spinbox|combobox|radiobox|checkbox|listbox|slider|progressbar|knob)
|
||
"default"<br>
|
||
><br>
|
||
<!ATTLIST Value<br>
|
||
Name CDATA #REQUIRED<br>
|
||
><br>
|
||
]> </code> </p>
|
||
<code> </code>
|
||
<p> <u><b>Notes:</b></u> </p>
|
||
<p> <u><b><em>Encoding Formula</em></b></u>
|
||
</p>
|
||
<p> The string must contains a mathematic expresion. </p>
|
||
<p> The followings variables can be used: </p>
|
||
<ul>
|
||
<li>min : Field Min </li>
|
||
<li>max : Field Max </li>
|
||
<li>lsb : Field Weight </li>
|
||
<li>off : Field OffsetValue </li>
|
||
<li>len : Field Width </li>
|
||
</ul>
|
||
<p> The following C math functions are also supported: </p>
|
||
<ul>
|
||
<li>abs (calls to fabs) </li>
|
||
<li>acos, asin, atan, atan2, cos, cosh, sin, sinh, tan, tanh </li>
|
||
<li>ceil, exp, floor </li>
|
||
<li>ln (calls to log) </li>
|
||
<li>log (calls to log10 by default, see below), log10 </li>
|
||
<li>pow, sqrt </li>
|
||
</ul>
|
||
<p> Also, the following constants are available: </p>
|
||
<ul>
|
||
<li>pi, e </li>
|
||
</ul>
|
||
<h3><a class="mozTocH3" name="mozTocId794984"></a>
|
||
BusDriver </h3>
|
||
<p> E' un file, tipicamente una libreria dinamica
|
||
(.dll, .so,... ), con il quale si construisce un canale di
|
||
comunicazione tra l'applicativo ed il target.<br>
|
||
E' dipendente dal protocollo utilizzato ( RS232, Socket , GPIB, Arinc
|
||
429, MIL 1553 ....)<br>
|
||
Puo' far riferimento a file di configurazione esterni.<br>
|
||
Puo' ottenere informazioni relazionate al database ICD tramite
|
||
i nodi XML `<span style="font-style: italic;">LowLevel` e `Mapping</span>
|
||
`, i quali sono lasciati a libera implementazione. </p>
|
||
<h3><a class="mozTocH3" name="mozTocId437925"></a>
|
||
UiFile </h3>
|
||
<p> E' un file testuale con il quale di definisce l'interfaccia
|
||
grafica dell'interfaccia. E' un file con sintassi xml derivante dal
|
||
framework Qt. Puo' essere modificato sia manualmente che tramite
|
||
strumenti della toolchain Qt ( per es. Designer ).</p>
|
||
<h3><a class="mozTocH3" name="mozTocId620990"></a>
|
||
Plugin </h3>
|
||
<p> E' un file, tipicamente una libreria dinamica
|
||
(.dll, .so,... ), con il quale vengono definite azioni
|
||
specifiche dell' interfaccia come automatismi , sincronizzazione tra
|
||
messaggi, extra funzionalita'. Si basa su una struttuta definita e
|
||
riconoscibile dall'applicativo ( vedi SDK e tecniche Plugin )
|
||
</p>
|
||
<h3><a class="mozTocH3" name="mozTocId852574"></a>
|
||
IniScript </h3>
|
||
<p> E' uno script python che viene eseguito
|
||
in fase di inizializzazione dell'interfaccia </p>
|
||
<h1><a class="mozTocH1" name="mozTocId198944"></a>
|
||
Caratteristiche</h1>
|
||
Per
|
||
quanto concerne le caratteristiche funzionali del simulatore, esse sono
|
||
soggette alle versioni rilasciate nel tempo per fissare problemi o
|
||
introdurre funzionalita' richieste dal cliente.<br>
|
||
Attualmente sono implementate le seguenti:<br>
|
||
<br>
|
||
<table style="text-align: left; width: 100%;" border="1" cellpadding="2" cellspacing="2">
|
||
<tbody>
|
||
<tr>
|
||
<td style="font-weight: bold;">Resivione</td>
|
||
<td style="font-weight: bold;">Nota</td>
|
||
</tr>
|
||
<tr>
|
||
<td>103017</td>
|
||
<td>Possibilita' di configurare il BusDrver e i Plugin
|
||
direttamente con file python</td>
|
||
</tr>
|
||
<tr>
|
||
<td>102810</td>
|
||
<td>Portabilita' verso python 3.x.</td>
|
||
</tr>
|
||
<tr>
|
||
<td>49055</td>
|
||
<td>Aggiunta gestione expressioni matematiche sull encoder</td>
|
||
</tr>
|
||
<tr>
|
||
<td>47733</td>
|
||
<td>Implementato iniScript</td>
|
||
</tr>
|
||
<tr>
|
||
<td>47207</td>
|
||
<td>Allo startup LeoPlatSim carica, sottoforma di plugin,
|
||
tuttle le librerie presenti nei seguenti path:<br>
|
||
<ul>
|
||
<li><installation path></li>
|
||
<li><appdata>/LeonardoCompany/<build>/options/</li>
|
||
</ul>
|
||
seguendo la regole <name>Plugin.<suffix>
|
||
( es "plotterPlugin.dll" )</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p> </p>
|
||
<h1><a class="mozTocH1" name="mozTocId689606"></a>Funzionalita`
|
||
di Base</h1>
|
||
<p><code>uPlatSim.exe --help<br>
|
||
Usage: uPlatSim.exe [options]<br>
|
||
LeonardoCompany Platform Simulator<br>
|
||
<br>
|
||
Options:<br>
|
||
-?, -h,
|
||
--help
|
||
Displays this help.<br>
|
||
-v,
|
||
--version
|
||
Displays version information.<br>
|
||
-s, --session <name> Set the
|
||
platform application session to run<br>
|
||
-a, --appdata <dir> Set
|
||
the application data to dir<br>
|
||
-b, --batch
|
||
<file> Run python script in
|
||
batch mode<br>
|
||
-d, --debug
|
||
<file> Log debug
|
||
information into file<br>
|
||
-i,
|
||
--cli
|
||
Run interactive cli python console instead of gui<br>
|
||
-I, --ini <inifile> Manage
|
||
session by using ini file<br>
|
||
-P, --python
|
||
<dir> Set python home
|
||
environment</code></p>
|
||
<p>L'applicativo puo essere utilizzato fondamentamente in 3
|
||
diversi modi:</p>
|
||
<ol>
|
||
<li>Attraverso l'interfaccia grafica ( normale utilizzo
|
||
dell'ambiente da parte di un utilizzatore )</li>
|
||
<li>Eseguendo uno script da riga di comando ( utilizzabile per
|
||
es. all'interno di procedure shell/DOS ) </li>
|
||
<li>Command line ( attivazione della sola modalita' python
|
||
senza ambiente grafico [ <i>per smanettoni</i> ] )</li>
|
||
</ol>
|
||
<h2><a class="mozTocH2" name="mozTocId214044"></a>Argomenti
|
||
globali</h2>
|
||
<p>Tutte le modalita' di utilizzo prescindono dalla definizione
|
||
di alcuni argomenti globali di seguito descritti</p>
|
||
<h3><a class="mozTocH3" name="mozTocId398862"></a>Session</h3>
|
||
<p>Una sessione e' il modo con cui si identifica un'
|
||
implementazione del simulatore di piattaforma.</p>
|
||
<p>Leonardo Platform Simulator e' pensato per avere una singola
|
||
installazione core ( eseguibile e librerie ) e una o piu' sessioni
|
||
dispobili. Genericamente l'applicativo cerca tale sessione /
|
||
identificativo in una determinata area applicativa dell' utente gestita
|
||
da sistema operativo </p>
|
||
<table style="width: 100%;" border="1">
|
||
<thead style="background-color: rgb(204, 204, 204);"> <tr>
|
||
<th>Sistema Operativo</th>
|
||
<th>Variabile</th>
|
||
</tr>
|
||
</thead> <tbody>
|
||
<tr>
|
||
<td>Windows</td>
|
||
<td>%APPDATA%\LeonardoCompany</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Linux</td>
|
||
<td>$HOME/.config/LeonardoCompany</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>L'identificativo passato come valore dell'argomento <b><i>--session
|
||
o in forma abbreviata -s </i></b>individua il file .ini
|
||
avente tale nome.</p>
|
||
<h3><a class="mozTocH3" name="mozTocId624687"></a>appdata</h3>
|
||
<p>Con questo argomento opzionale si indica, attraverso il suo
|
||
valore, l'area applicativo nella quale cercare il file .ini con nome
|
||
passato dall'argomento session. </p>
|
||
<p><i>Utile per diversificare/versionare distribuzioni di
|
||
implementazioni o nel caso di versione portable.</i></p>
|
||
<h3><a class="mozTocH3" name="mozTocId312810"></a>Ini</h3>
|
||
<p>Analogamente alla sessione il valore dell'argomento <i><b>--ini
|
||
o in forma abbreviata -I </b></i>individua univocamente il
|
||
file .ini ed utilizzandone la directory come area applicativa.</p>
|
||
<h3><a class="mozTocH3" name="mozTocId683131"></a>Python</h3>
|
||
<p>Leonardo Platform Simulator utilizza la distribuzione Python
|
||
individuata dalle variabili di ambiente <b>PYTHONHOME </b>e
|
||
<b>PYTHONPATH </b>per poter usufruire dei moduli python
|
||
dispobili e non integrati nell'applicativo ( solo i built-in ).</p>
|
||
<p>Alternativamente si puo' indicare quale python usare
|
||
valorizzando tale argomento.</p>
|
||
<h2><a class="mozTocH2" name="mozTocId96513"></a>Modalita'
|
||
grafica </h2>
|
||
<p>E la modalita' utlizzata per default . Di seguito le opzioni
|
||
di chiamata:</p>
|
||
<p><code>uPlatSim.exe --session=<name> [
|
||
--python=<dir> ] [ --appdata=<dir> ]
|
||
[--debug=<file>]</code></p>
|
||
<p><code> uPlatSim.exe --ini=<inifile> [
|
||
--python=<dir> ] [--debug=<file>]</code></p>
|
||
<p>Sono integrate due visualizzazioni. La prima (<b>GUI
|
||
mode)</b> presenta le interfacce attraverso elementi
|
||
interattivi ( entry , combobox, checkbuttons,... ), mentre la seconda (<b>Python
|
||
Mode</b>) gestisce la parte di interfaccia a python.</p>
|
||
<h3><a class="mozTocH3" name="mozTocId75966"></a>GUI
|
||
Mode</h3>
|
||
<img src="refman_files/image002.jpg" alt="gui 1" title="gui 1" style="width: 900px; height: 562px;"><br>
|
||
Nella seguente modalita' l'applicativo esegue le seguenti operazioni:<br>
|
||
<ul>
|
||
<li> vengono rapresentate in forma grafica tutte le
|
||
interfacce presentate dal file INI </li>
|
||
<li> vengono eseguiti gli scripts di inizializzazione
|
||
( globali e di interfaccia ) </li>
|
||
</ul>
|
||
L'utente ha la possibilita' di accedere ai campi di tutti i messaggi
|
||
implemenati per ogni singola interfaccia sia<br>
|
||
<ul>
|
||
<li>modalita grafica : accesso diretto tramite oggetti grafici
|
||
interattivi</li>
|
||
<li>tramite console python : console python interattiva</li>
|
||
<li>tramite il lancio di uno o piu' scripts: caricamento di
|
||
files ( o liste di files ) ed escuzione con generazione automatica di
|
||
un file di log nella stessa cartella dello script </li>
|
||
</ul>
|
||
<p>Ogni interfaccia e` contraddistinta da un tab indicante il
|
||
nome dell’ interfaccia ( quello relativo all’ attributo <em>name</em>
|
||
del documento ICD (.xml) { Nella figura per es. troviamo le interfacce
|
||
AEROFLEX-IFF45TS e TIC-T760 }.</p>
|
||
<h4><a class="mozTocH4" name="mozTocId73236"></a>comando
|
||
e controllo { controllo interfaccia / bus }</h4>
|
||
<p>Questa sezione gestisce il bus in termini di :<br>
|
||
- Start :attivazione del traffico<br>
|
||
- Stop :terminazione del traffico<br>
|
||
- Configure: gestione dei parametri di interfaccia del bus </p>
|
||
<h4><a class="mozTocH4" name="mozTocId3675"></a>indicatore
|
||
messaggi</h4>
|
||
<p>Indicatore dei messaggi:<br>
|
||
- Tx = trasmessi<br>
|
||
- Rx = ricevuti , <br>
|
||
- Err = errati (Tx eRx )</p>
|
||
<h4><a class="mozTocH4" name="mozTocId334611"></a>iniettore
|
||
errori di protocollo</h4>
|
||
<p>Permette di comunicare al bus l’inserzione di tipologie di
|
||
errore di protocollo al fine di testarne i possibili effetti sul target.<br>
|
||
gestione log<br>
|
||
Permette di registrare e salvare su file il traffico dati in base a
|
||
tipologie di filtraggio:<br>
|
||
- tutti i messaggi, <br>
|
||
- solo i messaggi errati, <br>
|
||
- solo i messaggi modificati<br>
|
||
<br>
|
||
Su Windows per default i files sono salvati in %USERPROFILE%\Documents.</p>
|
||
<h4><a class="mozTocH4" name="mozTocId957256"></a>gestione
|
||
scrittura ed invio dei dati</h4>
|
||
<p>Questa sezione permette di gestire l’invio o la richiesta di
|
||
ricezione di messaggi a seconda della tipologia del messaggio.<br>
|
||
A seguito di una modifica di uno o piu’ campi associati a uno o piu
|
||
messaggi, si possono attuare le seguenti azioni:</p>
|
||
<h5><a class="mozTocH5" name="mozTocId82468"></a>Commit
|
||
Changes</h5>
|
||
<p>TUTTE le modifiche sono salvate ed inviate al bus che ne
|
||
gestisce la trasmissione secondo le modalita’ del caso.</p>
|
||
<h5><a class="mozTocH5" name="mozTocId203014"></a>Revert
|
||
Changes</h5>
|
||
<p>Vengono rigettate le modifiche e ripristinati i dati relativi
|
||
all’ultima modifica. </p>
|
||
<h5><a class="mozTocH5" name="mozTocId367825"></a>Commit
|
||
on the Fly</h5>
|
||
<p>Le modifiche dei campi saranno processate direttamente.</p>
|
||
<h5><a class="mozTocH5" name="mozTocId570965"></a>Invio
|
||
di messaggi non modificati</h5>
|
||
<p>Un messaggio non periodico puo’ essere inviato anche quando
|
||
questo non ha subito modifiche.<br>
|
||
Il comando e’ attivo quando non vi sono modifiche pendenti.<br>
|
||
Di seguito la sequenza:</p>
|
||
<ul>
|
||
<li>selezionare nella combobox associata al comando Resend
|
||
Msg il messaggio </li>
|
||
<li>cliccare sul button avente come testo il nome del messaggio
|
||
( ogni click corrisponde ad un invio ) </li>
|
||
</ul>
|
||
<h5><a class="mozTocH5" name="mozTocId534388"></a>richiesta
|
||
ricezione messaggio</h5>
|
||
<p>Per un messaggio non periodico in lettura puo’
|
||
esserne richiesto l’aggiornamento forzato ( quando questo e’ gestito
|
||
dal protocollo ) <br>
|
||
Il comando e’ attivo quando non vi sono modifiche pendenti.<br>
|
||
Di seguito la sequenza:</p>
|
||
<ul>
|
||
<li>selezionare nella combobox associata al comando Resend
|
||
Msg il messaggio </li>
|
||
<li>cliccare sul button avente come testo il nome del messaggio
|
||
( ogni click corrisponde ad una richiesta di lettura )</li>
|
||
</ul>
|
||
<h3><a class="mozTocH3" name="mozTocId89906"></a>Python
|
||
Mode</h3>
|
||
La modalita' python e' rivolta principalmente ad attivita' di test e
|
||
validazione del target, dove si desidera proceduralizzare seguenze di
|
||
operazioni di input/output du una o piu interfacce in modo da poterle
|
||
rendere riproducibili ed indipendenti dall'operatore.
|
||
<p>Leonardo Platform simulator integra al suo interno un motore
|
||
python contenente un modulo addizionale ( denominato <i>interpreter
|
||
</i>) che permette l'interoperabilita' con i messaggi caricati
|
||
tramite ICD. Sono pertanto disponibili, oltre ai moduli python
|
||
standard, API per:</p>
|
||
<ul>
|
||
<li> la lettura/scrittura di messaggi</li>
|
||
<li>il controllo del bus</li>
|
||
<li>l'esecuzione di funzionalita' fornite dai plugins</li>
|
||
</ul>
|
||
<p><em>NB: </em><em>Leonardo
|
||
Platform <b>NON </b></em><em><em>contiene
|
||
al suo interno una distribuzione Python ma solamente l'interprete</em>;
|
||
questo significa che non sono contenute librerie. L'host deve essere
|
||
munito di distribuzione python ( 2.7.X.X ) compatibile con
|
||
l'architettura dell'applicativo ( 32/64 bit )</em></p>
|
||
<p>Sono presentate per default due tab denominate:</p>
|
||
<ol>
|
||
<li>Python Script #0</li>
|
||
<li>Terminal #0</li>
|
||
</ol>
|
||
<p>Altri terminali python possono essere aggiunti. Ogni
|
||
terminale e' una istanza python indipendente dalle altre.</p>
|
||
<h4><a class="mozTocH4" name="mozTocId122903"></a>controlli
|
||
Python</h4>
|
||
<img src="refman_files/image115.jpg" alt="toolbar python" title="toolbar python">
|
||
<div style="margin-left: 40px;"><br>
|
||
</div>
|
||
<div style="margin-left: 40px;">Da sx a ds:</div>
|
||
<div style="margin-left: 40px;">
|
||
<ul>
|
||
<li>aggiungi un python script alla lista di esecuzione (
|
||
alternativamente il file puo' essere trascinato consentendone il
|
||
caricamento )<br>
|
||
</li>
|
||
<li>carica una lista di scripts (.lst)</li>
|
||
<li>salva la lista corrente su file (.lst)</li>
|
||
<li>pulisci la finestra di output <br>
|
||
</li>
|
||
<li>lancia l'esecuzione della lista di scripts </li>
|
||
<li>abortisci l'esecuzione della lista di scripts</li>
|
||
<li>apri un nuovo terminale python<br>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div style="margin-left: 40px;">Tali funzionalita' sono
|
||
disponibili anche da menu Edit > Python</div>
|
||
<div style="margin-left: 40px;"><br>
|
||
</div>
|
||
<div style="margin-left: 40px;"><img src="file:///C:/Users/Administrator/Documents/refman_files/image116.jpg" alt="menu python" title="menu python"></div>
|
||
<p></p>
|
||
<h4><a class="mozTocH4" name="mozTocId621043"></a>Python
|
||
Script #0</h4>
|
||
<p><img src="refman_files/image012.jpg" alt="python mode 1" title="python mode 1" style="width: 902px; height: 564px;"></p>
|
||
<p>Questa tab e' predisposta per gestire la parte di scripting
|
||
python. In questa sezione si possono aggiungere / eliminare scripts,
|
||
salvare / caricare una lista di scripts ed eseguirli tramite i suddetti
|
||
controlli. </p>
|
||
</div>
|
||
<div style="margin-left: 40px;">
|
||
<table border="1" width="600">
|
||
<tbody>
|
||
<tr>
|
||
<td style="width: 168px; background-color: rgb(51, 204, 255); text-align: center;">file
|
||
manager<br>
|
||
</td>
|
||
<td style="height: 130px; width: 416px; background-color: rgb(255, 255, 153); text-align: center;">output<br>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="2" style="background-color: rgb(204, 204, 204); text-align: center;">log<br>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<br>
|
||
</div>
|
||
<div style="margin-left: 40px;"><br>
|
||
</div>
|
||
<div style="margin-left: 40px;">La parte destra (output)
|
||
della pagina visualizza l' output derivante dall'esecuzione degli
|
||
scripts.Ogni esecuzione produce un file di log avente radice pari al
|
||
nome dello script file ( dirname e basename ) ed estensione .log </div>
|
||
<div style="margin-left: 40px;">La parte bassa (log)
|
||
comunica le operazioni effettuate in ambito di caricamento /
|
||
cancellazione dei files ed esito esecuzione.<br>
|
||
<h4><a class="mozTocH4" name="mozTocId523292"></a>Terminal
|
||
#(n)</h4>
|
||
<img src="refman_files/image010.jpg" alt="terminale python" title="terminale python" style="width: 902px; height: 561px;">
|
||
<p>Qusta finestra riproduce una console python avanzata in quanto
|
||
contenente il modulo relativo alle API per accedere alle interfacce.
|
||
Ogni terminale e' indipendente dagli altri ( oggetti, moduli, ... ).</p>
|
||
<p>Non produce output di log.</p>
|
||
<p>Puo' essere chiuso.</p>
|
||
<h2><a class="mozTocH2" name="mozTocId725560"></a>
|
||
CLI
|
||
( Command Line Interpreter ) </h2>
|
||
<code>uPlatSim.exe --cli --session=<name>
|
||
[--python=<dir> ] [ --appdata=<dir> ]
|
||
[--debug <file>]</code> </div>
|
||
<div style="margin-left: 40px;"><br>
|
||
</div>
|
||
<div style="margin-left: 40px;">L'applicativo si presenta
|
||
come una console a riga di comando python. Non visualizza interfacce
|
||
grafiche.</div>
|
||
<div style="margin-left: 40px;">In questa modalita'
|
||
l'applicativo esegue le seguenti operazioni:<br>
|
||
<ul>
|
||
<li>vengono eseguiti gli scripts di inizializzazione ( globali
|
||
e di interfaccia ) </li>
|
||
<li>viene eseguito un singolo processo di interprete python
|
||
interattivo </li>
|
||
</ul>
|
||
<p><b><u>Esempio</u></b></p>
|
||
<p>Utilizzo la sessione <a href="refman_files/LeonardoCompany/i686-w64-mingw32/test1.ini" title="test1 inifile" target="_self">test1</a>
|
||
in modalita cli ed eseguo comandi python relativi al modulo interno
|
||
'interpreter'</p>
|
||
<img src="refman_files/image114.jpg" alt="cli" title="cli">
|
||
<h2><a class="mozTocH2" name="mozTocId188823"></a>Batch </h2>
|
||
<code>uPlatSim.exe --batch <file>
|
||
--session=<name> [--python=<dir> ] [
|
||
--appdata=<dir> ] [--debug <file>]</code><br>
|
||
In questa modalita' e' possibile eseguire un singolo file di script
|
||
python direttamente da command line senza l'apertura dell' interfaccia
|
||
grafica.L'applicativo esegue le seguenti operazioni:<br>
|
||
<br>
|
||
<ul>
|
||
<li>vengono eseguiti gli scripts di inizializzazione ( globali
|
||
e di interfaccia ) </li>
|
||
<li>viene eseguito lo script passato da argomento </li>
|
||
</ul>
|
||
Tale esecuzione ridirige su <span style="font-weight: bold;">standard
|
||
output</span> le comunicazioni risultanti dall'esecuzionde dello
|
||
script e <span style="font-weight: bold;">non viene
|
||
effettuato il salvataggio su file</span> ( come avviene
|
||
in modalita' grafica ).<br>
|
||
L'applicativo termina con valore:<br>
|
||
<ul>
|
||
<li>0: in caso di esecuzione dello script terminata con
|
||
successo </li>
|
||
<li>numero diverso da 0 : in caso di errore durante
|
||
l'esecuzione dello script oppure con il valore
|
||
specificato dall'istruzione python <a href="https://docs.python.org/2/library/sys.html#sys.exit">sys.exit([arg])</a></li>
|
||
</ul>
|
||
<p><br>
|
||
<u><b>Esempio</b></u></p>
|
||
<p> Utilizziamo la sessione '<b>Test1</b>'
|
||
individuata dal file <a href="refman_files/LeonardoCompany/i686-w64-mingw32/test1.ini">Test1.ini</a>
|
||
e lo script python (<a href="refman_files/LeonardoCompany/i686-w64-mingw32/test1/script/test1.py" title="Test1">Test.1.py</a>).<br>
|
||
</p>
|
||
<img src="refman_files/image113.jpg" alt="batch output" title="batch">
|
||
<h2><a class="mozTocH2" name="mozTocId138808"></a>Log di un traffico dati </h2>
|
||
Ogni interfaccia di una determinata sessione permette di
|
||
salvare su file il traffico dati in ingresso ed uscita.<br>
|
||
La registrazione [ log ] puo' essere attivata/disattivata nei seguenti
|
||
modi:<br>
|
||
<ul>
|
||
<li>tramite Python
|
||
<ul>
|
||
<li>logStart(self, level, dirName) </li>
|
||
<li>logStop() </li>
|
||
</ul>
|
||
</li>
|
||
<li>tramite Gui:
|
||
<ul>
|
||
<li>utilizzanto il tasto "Start Logging" per
|
||
avviare (* un led rosso lampeggiante in prossimita' del tasto indica
|
||
l'attivita' di registrazione in corso) </li>
|
||
</ul>
|
||
<ul>
|
||
<li>utilizzando il medesimo tasto (ma con testo "Stop
|
||
Logging" se in fase di registrazione ) per terminare </li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
Il file viene salvato per default nella cartella Documenti dell'utente
|
||
( in base al sistema operativo ), o nella cartella specificata
|
||
dall'utente a seconda del tipo di chiamata alla funzione ( da Gui
|
||
tramite tasto opportuno e da python tamite argomento ) e il
|
||
nome e' determinato dalla seguente regola:<br>
|
||
<span style="font-style: italic; font-weight: bold;"><nome
|
||
interfaccia>__<anno>_<mese>_<giorno>_<ora>_<minuto>_<secondo>.log
|
||
</span>
|
||
<h3><a class="mozTocH3" name="mozTocId56048"></a>Contenuto del file di log </h3>
|
||
<table style="text-align: left; width: 100%;">
|
||
<tbody>
|
||
<tr>
|
||
<td style="background-color: white;"> <code>#
|
||
[TimeTag] [Flag] [MsgId] [IO] (...)<br>
|
||
(TIME)
|
||
(FLAG)[<ID>] [<IO>]
|
||
(DATA0) ... (DATA-N)<br>
|
||
...</code><br>
|
||
Con:<br>
|
||
<ul>
|
||
<li>TIME : tempo espresso in
|
||
<Hour>.<Mim>.<Sec>.<mSec>
|
||
</li>
|
||
<li>FLAG : [-|E|I] [ Normal ]; E [ Errore ]; I [ Info ] </li>
|
||
<li>ID : <digit> identificativo
|
||
messaggio ( tipicamente utlizzato quello dell'ICD ) </li>
|
||
<li>IO : [Tx/Rx] Tx - se trasmissione ; Rx -
|
||
se ricezione </li>
|
||
<li>DATA : <carattere/parola> expresso in
|
||
formato esadecimale </li>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2><a class="mozTocH2" name="mozTocId9522"></a>Plugins</h2>
|
||
<p>Come si e' detto il simulatore di piattaforma e' in grado di
|
||
supportare funzionalita' particolari la dove l'interfaccia lo richieda,
|
||
oppure aggiungere strumenti di utilizzo generale.</p>
|
||
<p>Questa funzionalita' e' gestita tramite il concetto dei
|
||
plugin, ovvero librerie caricate dinamicamente le quali rspettano una
|
||
struttura dati nota all'applicativo.</p>
|
||
<p>Le regole applicabili per la realizzazione di un plugin sono
|
||
descritte nel documento 'plugin' incluso nell'installazione.</p>
|
||
<p>Gli oggetti applicabili al plugin sono sostanzialmente di 3
|
||
tipi:</p>
|
||
<ol>
|
||
<li>elementi selezionabili ( eventualmente da multiple opzioni
|
||
) { per esempio abilitare/disabilitare una certa funzionalita' estra
|
||
tramite una checkbox }</li>
|
||
<li>elementi richiamanti dialogs (solo GUI ) o azioni dirette
|
||
riferite ad un certo istante</li>
|
||
<li>elementi richiamanti funzionalita' python ( solo python )</li>
|
||
</ol>
|
||
<p>L'utilizzo dei suddetti plugin tramite GUI gli
|
||
elementi sono raggiungibili da <b>menu/Plugins/<nome
|
||
interfaccia>/. </b>Gli elementi possono appartenere a
|
||
sottomenu.</p>
|
||
<p>L'utilizzo tramite Python e' gestito dall oggetto <b>interpreter.PyPluginHandler</b>
|
||
ottenuto dall'interfaccia tramite API <b>getPlugonHandler()</b></p>
|
||
<p><code>>>>dir(interpreter.PyPluginHandler)<br>
|
||
['__class__', '__del__', '__delattr__', '__dict__', '__doc__',
|
||
'__format__', '__getattr__', '__getattribute__', '__hash__',
|
||
'__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__',
|
||
'__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
|
||
'__swig_destroy__', '__swig_getmethods__', '__swig_setmethods__',
|
||
'__weakref__', 'doAction', 'getActionHelp', 'getChecked',
|
||
'isCheckable', 'names', 'setChecked']</code></p>
|
||
<p>con <code>isCheckable(n) [Boolean] : ritorna True se
|
||
l'elemento passato come argomento e' del tipo selezinabile</code></p>
|
||
<p> <code>getChecked(n) [Boolean] :ritorna True se
|
||
l'elemento e' selezionato </code> </p>
|
||
<p><code>setChecked(n,Boolean): imposta l'elemento
|
||
selezionabile con valore passato da argomento </code> </p>
|
||
<p><code>doAction(self, arg2, dict_args=None,
|
||
dict_retval=None) con arg2 nome della funzione, dict_args=Tupla
|
||
nome/valore dei parametri in input, dict_ret_val=Tupla nome/valore dei
|
||
parametri in output</code></p>
|
||
<h1><a class="mozTocH1" name="mozTocId892472"></a>Funzionalita`
|
||
avanzate</h1>
|
||
<h2><a class="mozTocH2" name="mozTocId357140"></a>Modificare
|
||
layout di interfaccia </h2>
|
||
Per layout di una interfacia si intende la visualizzazione
|
||
degli oggetti grafici i quali rappresentano i campi di tutti
|
||
i messaggi descritti nel relativo file di ICD.<br>
|
||
Tipicamente ogni campo di un dato messaggio viene visualizzato con tre
|
||
elementi grafici:<br>
|
||
<ul>
|
||
<li>oggetto nome : contenente il testo indicativo
|
||
il nome del campo </li>
|
||
<li>oggetto valore : contenente il valore [ editabile
|
||
se in scrittura ] del campo </li>
|
||
<li>oggetto unita di misura : conenente il testo indicativo
|
||
l'unita' di misura [ se presente ] del campo </li>
|
||
</ul>
|
||
Il layout di una interfaccia e' descritto da un
|
||
file .ui gestito direttamente dalla piattaforma Qt (
|
||
<a href="http://doc.qt.io/archives/qt-4.8/designer-using-a-ui-file.html">http://doc.qt.io/archives/qt-4.8/designer-using-a-ui-file.html</a>)<br>
|
||
il quale viene caricato in fase di avviamento dell'applicativo.<br>
|
||
Tale file e' specificato ne file .INI relativo alla sessione tramite
|
||
chiave <span style="font-weight: bold;">Interface_</span>
|
||
<span style="font-style: italic; font-weight: bold;"><n></span>
|
||
<span style="font-weight: bold;">/UiFile</span> dove
|
||
n e' un numero progressivo che determina l'interfaccia.<br>
|
||
E' possibile modificare il layout:<br>
|
||
<ul>
|
||
<li>direttamente modificando a mano il file ( che e' in formato
|
||
XML ) </li>
|
||
<li>tramite Designer.exe ( Qt ) che e'
|
||
fornito a corredo dell'applicativo nella directory stessa. </li>
|
||
<li>da applicativo tramite <span style="font-weight: bold; font-style: italic;">Menu->Edit->Interface->[Nome
|
||
Interface]</span> </li>
|
||
</ul>
|
||
L'applicativo gestisce le seguenti modifiche del layout:<br>
|
||
<ul>
|
||
<li>modifiche posizionali [ organizzazione
|
||
degli elementi tramite gestore geometrici di vario tipo
|
||
(verticali / orizzonati / a matrice) ... ] </li>
|
||
<li>modifiche delle proprieta' caratteristiche
|
||
dell' elemento [ per es stile di visualizzazione di
|
||
una combobox ] </li>
|
||
<li>aggiunta/sostituzione di elementi collegabili ( se
|
||
compatibili ) ad un campo di un messaggio.
|
||
<ul>
|
||
<li>Un dato messaggio puo' essere
|
||
rappresentao da uno o piu' elementi grafici i quali sono
|
||
collegati al campo tramite il valore della porprieta' <span style="font-weight: bold; font-style: italic;">ObjectName</span>
|
||
il quale deve seguire il formalismo seguente:
|
||
"___MESSAGEID____ <span style="font-weight: bold;"><id></span>
|
||
_ <span style="font-weight: bold;"><field_name></span>
|
||
___FIELDTAG___ <span style="font-weight: bold;"><obj_text></span>
|
||
"
|
||
<ul>
|
||
<li> <span style="font-style: italic;"><span style="font-weight: bold;"><id> :</span></span>
|
||
e' l'identificativo numerico del messaggio </li>
|
||
<li> <span style="font-style: italic;"><span style="font-weight: bold;"><field_name>:</span></span>
|
||
e' il nome del campo normalizzato ( i caratteri
|
||
[:punct:] sono sostituiti da _ ) </li>
|
||
<li> <span style="font-weight: bold;"><obj_text>
|
||
:</span> testo libero che differenzia l'oggetto ( es: <span style="font-style: italic;">"numeric1"</span>
|
||
)</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h2><a class="mozTocH2" name="mozTocId457542"></a>Utilizzare
|
||
uno script Python come Bus</h2>
|
||
Leonardo Platform Simulator e' in grado di utilizzare uno script Python
|
||
per agire come gestore dei dato di basso livello ( denominato BusDriver
|
||
).<br>
|
||
Per essere compatibile con l'applicativo tale script deve utilizzare
|
||
come riferimento il modulo 'proxybusdriver' presente nella cartella
|
||
dell'eseguibile.<br>
|
||
Tale modulo permette di creare un canale di comunicazione univoco con
|
||
l'applicativo consentendo di interfacciarsi con il
|
||
database con la quale si intende operare ( messaggi e campi ).<br>
|
||
Per creare un istanza di busDriver sono necessarie le seguenti
|
||
operazioni:<br>
|
||
<ul style="margin-left: 40px;">
|
||
<li>Instanziare o ridefinire i metodi della classe
|
||
python fornita dal modulo python (proxybusdriver)
|
||
<ul>
|
||
<li>Basandosi su una classe padre definita in python
|
||
(<span style="font-weight: bold;">proxybus</span>)
|
||
con la quale viene gestita la parte di connessione al simulatore si
|
||
possono finalmente definire le funzionalita' per gestire lo scambio
|
||
dati. Distinguiamo:</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul style="margin-left: 40px;">
|
||
<ul>
|
||
<ul>
|
||
<li>costanti:
|
||
<ul>
|
||
<li><span style="font-weight: bold;">__proxy_icdinterface__</span>
|
||
: srtinga identificativa dell interfaccia</li>
|
||
<li><span style="font-weight: bold;">__proxy_icdxmlfile__</span>
|
||
: path del file xml ( configurazione ) </li>
|
||
<li><span style="font-weight: bold;">__proxy_identifier__</span>
|
||
: identificatore dell'istanza proxybus</li>
|
||
</ul>
|
||
</li>
|
||
<li>metodi richiamabili direttamente da python:
|
||
<ul>
|
||
<li><span style="font-weight: bold;">onBusError</span>
|
||
: da utilizzare per passare al livello superiore (
|
||
il simulatore ) un errore di gestione dati
|
||
|
||
</li>
|
||
<li><span style="font-weight: bold;">onClock</span>
|
||
: notificare al simulatore la
|
||
periodicita' ( in modo da sincronizzare eventuali automatisci
|
||
di varia natura )</li>
|
||
<li><span style="font-weight: bold;">onReceive</span>
|
||
: passare al livello superiore l'avvenuta
|
||
ricezione ( codificata ) di dati proveniente
|
||
dal dispositivo
|
||
collegato </li>
|
||
</ul>
|
||
</li>
|
||
<li>callback python per implementare funzionalita'
|
||
predefinite dal simulatore:
|
||
<ul>
|
||
<li><span style="font-weight: bold;">setOnErrorInjectionListCallback</span>
|
||
: implementare l'evento proveniente dal
|
||
simulatore che definisce una lista di errori iniettabili sul canale di
|
||
comunicazione</li>
|
||
<li><span style="font-weight: bold;">setSendCallback</span>
|
||
: implementare l'evento proveniente dal
|
||
simulatore di invio dati verso il dispositivo collegato</li>
|
||
<li><span style="font-weight: bold;">setStartCallback</span>
|
||
: implementare l'evento proveniente dal
|
||
simulatore di start della counicazione</li>
|
||
<li><span style="font-weight: bold;">setStopCallback</span>
|
||
: implementare l'evento proveniente dal
|
||
simulatore di stop della counicazione</li>
|
||
<li><span style="font-weight: bold;">setUsClockPeriodCallback</span>
|
||
: implementare l'evento proveniente dal
|
||
simulatore che imposta il tempo di clock ( espresso in microsecondi )</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<li>il modulo dispone di una
|
||
classe ProxyBusDriver
|
||
che 'incorpora' proxybus rendendo piu facile la parte di
|
||
programmazione python ( associazioni di callback, uso di
|
||
safe-threading,
|
||
... ) </li>
|
||
</ul>
|
||
</ul>
|
||
<h3><a class="mozTocH3" name="mozTocId379714"></a>Esempio</h3>
|
||
Si vuole stabilire una connesione di tipo seriale tra un
|
||
apparato (TDK-LAMBDA-40-38) e il simulatore utilizzando la libreria
|
||
python PySerial.<br>
|
||
Dato l'ICD: <br>
|
||
<br>
|
||
<div class="example">
|
||
<ICDHandler
|
||
Name='TDK-LAMBDA-40-38' Ui='all_vertical'
|
||
Version='89873786-A8FF-49A9-AF2E-0184193BE6CE' ><br class="example">
|
||
<span class="example">
|
||
<HiLevel>
|
||
</span><br class="example">
|
||
<span class="example">
|
||
|
||
<Message Id='1' Name='OUT' Width='8' IOType='TX'
|
||
>
|
||
</span><br class="example">
|
||
<span class="example">
|
||
<Field Name='ENABLE' Width='8' Offset='0' Type='ENUM'
|
||
Display='DECIMAL' Default='OFF'
|
||
>
|
||
</span><br class="example">
|
||
<span class="example">
|
||
<Values></span><br class="example">
|
||
<span class="example">
|
||
<Value Name="OFF" >0x00</Value></span><br class="example">
|
||
<span class="example">
|
||
<Value Name="ON">0x7F</Value></span><br class="example">
|
||
<span class="example">
|
||
</Values></span><br class="example">
|
||
<span class="example">
|
||
</Field> </span><br class="example">
|
||
<span class="example">
|
||
</Message> </span><br class="example">
|
||
<span class="example">
|
||
|
||
<Message Id='2' Name='VOLTAGE' Width='16' IOType='TX'
|
||
> </span><br class="example">
|
||
<span class="example">
|
||
<Field Name='VOLTAGE' Width='16' Offset='0' Min='0.00'
|
||
Max='40.00' Type='DOUBLE' Weight='0.01' Precision='0.01'
|
||
Default='28.00' Unit='Volt' /></span><br class="example">
|
||
<span class="example">
|
||
</Message></span><br class="example">
|
||
<span class="example">
|
||
<Message Id='3' Name='CURRENT'
|
||
Width='16' IOType='TX' >
|
||
</span><br class="example">
|
||
<span class="example">
|
||
<Field Name='CURRENT' Width='16' Offset='0' Min='0.00'
|
||
Max='38.00' Type='DOUBLE' Weight='0.01' Precision='0.01'
|
||
Default='10.00' Unit='Amp' /></span><br class="example">
|
||
<span class="example">
|
||
</Message></span><br class="example">
|
||
<br class="example">
|
||
<br class="example">
|
||
<span class="example">
|
||
<Message Id='4'
|
||
Name='TDK-LOOPBACK' Width='48' IsPeriodic='FALSE' IOType='RX' ></span><br class="example">
|
||
<span class="example">
|
||
<Field Name='REMOTE-ENABLE' Width='8' Offset='0' Type='ENUM'
|
||
Display='DECIMAL' Default='OFF'
|
||
>
|
||
</span><br class="example">
|
||
<span class="example">
|
||
<Values></span><br class="example">
|
||
<span class="example">
|
||
<Value Name="OFF" >0x00</Value></span><br class="example">
|
||
<span class="example">
|
||
<Value Name="ON">0x7F</Value></span><br class="example">
|
||
<span class="example">
|
||
</Values></span><br class="example">
|
||
<span class="example">
|
||
</Field></span><br class="example">
|
||
<span class="example">
|
||
<Field Name='OUT-ENABLE' Width='8' Offset='8' Type='ENUM'
|
||
Display='DECIMAL' Default='OFF'
|
||
>
|
||
</span><br class="example">
|
||
<span class="example">
|
||
<Values></span><br class="example">
|
||
<span class="example">
|
||
<Value Name="OFF" >0x00</Value></span><br class="example">
|
||
<span class="example">
|
||
<Value Name="ON">0x7F</Value></span><br class="example">
|
||
<span class="example">
|
||
</Values></span><br class="example">
|
||
<span class="example">
|
||
</Field>
|
||
</span><br class="example">
|
||
<span class="example">
|
||
<Field Name='MEAS-VOLTAGE' Width='16' Offset='16' Min='0.00'
|
||
Max='40.00' Type='DOUBLE' Weight='0.01' Precision='0.01' Default='0'
|
||
Unit='Volt' /></span><br class="example">
|
||
<span class="example">
|
||
<Field Name='MEAS-CURRENT' Width='16' Offset='32' Min='0.00'
|
||
Max='38.00' Type='DOUBLE' Weight='0.01' Precision='0.01' Default='0'
|
||
Unit='Amp'
|
||
/>
|
||
</span><br class="example">
|
||
<span class="example">
|
||
</Message>
|
||
</span><br class="example">
|
||
<span class="example"> </span><br class="example">
|
||
<span class="example">
|
||
</HiLevel></span><br class="example">
|
||
<span class="example"> </span><span class="example" style="font-weight: bold;"><LowLevel></span><br class="example" style="font-weight: bold;">
|
||
<span class="example" style="font-weight: bold;">
|
||
<Config Port="COM1"
|
||
/> </span><br class="example" style="font-weight: bold;">
|
||
<span class="example" style="font-weight: bold;">
|
||
</LowLevel></span><br class="example">
|
||
<span class="example">
|
||
<Mapping> </span><br class="example">
|
||
<span class="example">
|
||
</span><span class="example" style="font-weight: bold;"><Map
|
||
Id="1">out</Map></span><br class="example" style="font-weight: bold;">
|
||
<span class="example" style="font-weight: bold;">
|
||
<Map
|
||
Id="2">voltage</Map></span><br class="example" style="font-weight: bold;">
|
||
<span class="example" style="font-weight: bold;">
|
||
<Map
|
||
Id="3">current</Map>
|
||
</span><br class="example" style="font-weight: bold;">
|
||
<span class="example" style="font-weight: bold;">
|
||
<Map
|
||
Id="4">response</Map> </span><span class="example">
|
||
</span><br class="example">
|
||
<span class="example"> </Mapping></span><br class="example">
|
||
<span class="example"></ICDHandler></span><br>
|
||
</div>
|
||
<br>
|
||
il codice python per realizzare il driver sara' il seguente:<br>
|
||
<br>
|
||
<div class="example">
|
||
<span style="font-weight: bold;">import
|
||
proxybus
|
||
|
||
|
||
|
||
|
||
# proxy
|
||
python fornita da ProxyPythonBusDriver</span><br class="example">
|
||
<span style="font-weight: bold;" class="example">from
|
||
proxybusdriver import
|
||
ProxyBusDriver
|
||
|
||
# per
|
||
importare </span><span style="font-weight: bold;" class="example">ProxyBusDriver</span><br style="font-weight: bold;" class="example">
|
||
<span style="font-weight: bold;" class="example">import
|
||
serial
|
||
|
||
|
||
|
||
|
||
#
|
||
carico la
|
||
seriale </span><br class="example">
|
||
<span class="example">import time</span><br class="example">
|
||
<span class="example">import struct</span><br class="example">
|
||
<span class="example">import re</span><br class="example">
|
||
<span class="example">import sys</span><br class="example">
|
||
<span style="font-weight: bold;" class="example">import
|
||
xml.etree.ElementTree as et
|
||
|
||
|
||
# mi serve
|
||
per parsare il file xml e costruire le mappature </span><br class="example">
|
||
<br class="example">
|
||
<br class="example">
|
||
<span class="example">class
|
||
serialTDKLambdaPowerSupply(<span style="font-weight: bold; font-style: italic;">ProxyBusDriver</span>):</span><br class="example">
|
||
<span class="example"> def
|
||
__init__(self):</span><br class="example">
|
||
<span class="example">
|
||
ProxyBusDriver.__init__(self)
|
||
<span style="font-weight: bold;">
|
||
|
||
# costruttore della classe padre</span></span><br class="example">
|
||
<span class="example">
|
||
self.name = "Serial TDK-LAMBDA Power
|
||
Supply"
|
||
</span><br class="example">
|
||
<span class="example">
|
||
self.usclockperiod = 500000
|
||
|
||
</span><span class="example"> <span style="font-weight: bold;"># deternimo la durata del periodo
|
||
di clock </span></span><br class="example">
|
||
<span class="example">
|
||
self.response_id = None</span><br class="example">
|
||
<span class="example">
|
||
self.s=serial.Serial(None, 9600,
|
||
|
||
<span style="font-weight: bold;"># instanzio l'oggetto seriale
|
||
della libreria python</span><br>
|
||
|
||
|
||
timeout=0, <br>
|
||
|
||
|
||
parity=serial.PARITY_NONE) </span><br class="example">
|
||
<span class="example">
|
||
self.s.setWriteTimeout(10.0)</span><br class="example">
|
||
<span class="example">
|
||
self.opened = False</span><br class="example">
|
||
<span class="example">
|
||
self.query_err_reg_exp=re.compile('C0[1-4]')</span><br class="example">
|
||
<span class="example">
|
||
self.eval_tx = {</span><br class="example">
|
||
<span class="example">
|
||
"remote" :
|
||
self.set_remote,</span><br class="example">
|
||
<span class="example">
|
||
"out"
|
||
: self.set_out,</span><br class="example">
|
||
<span class="example">
|
||
"voltage" : self.set_voltage,</span><br class="example">
|
||
<span class="example">
|
||
"current" : self.set_current</span><br class="example">
|
||
<span class="example">
|
||
}</span><br class="example">
|
||
<span class="example">
|
||
self.resolution = { 'voltage' : 0.01, </span><br class="example">
|
||
<span class="example">
|
||
'current' : 0.01 }</span><br class="example">
|
||
<span class="example">
|
||
self.icd_map={}</span><br class="example">
|
||
<span class="example">
|
||
self.parseICD()</span><br class="example">
|
||
<span class="example">
|
||
</span><br class="example">
|
||
<br>
|
||
<span style="font-weight: bold;">
|
||
####</span><br style="color: black; font-weight: bold;">
|
||
<span style="color: black; font-weight: bold;">
|
||
</span><span style="color: black; font-weight: bold;" class="example"># re-implemento il metodo della classe padre
|
||
open_comm</span><br style="color: black; font-weight: bold;">
|
||
<span style="color: black; font-weight: bold;">
|
||
####</span><br class="example">
|
||
<span class="example"> <span style="color: red; font-weight: bold;">def
|
||
open_comm(self):
|
||
|
||
|
||
|
||
</span></span><span style="color: red; font-weight: bold;" class="example"></span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
self.opened = False</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
try:</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
self.s.open()</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
except:</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
print 'failed to open ....'</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
self.opened = self.s.isOpen()</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
if self.opened is True:</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
reg_exp=re.compile('.*LAMBDA,\s*GEN40\-38')</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
self.s.read(255)</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
self.ps_set('RMT REM')</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
self.ps_set('ADR 06')</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
ident = self.ps_query('IDN?')</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
if ident is None or reg_exp.match(ident) is False:</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
self.raiseError('No valid IDN reveived',3)</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
self.close_comm()</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
else:</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
self.raiseError('cannot open serial port %s' %self.s.port,3) </span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
return self.opened</span><br class="example">
|
||
<br>
|
||
<span style="font-weight: bold;">####</span><br style="color: black; font-weight: bold;">
|
||
<span style="color: black; font-weight: bold;">
|
||
</span><span style="color: red; font-weight: bold;" class="example"><span style="color: black; font-weight: bold;"># re-implemento il
|
||
metodo della classe padre close_comm</span><br style="color: black; font-weight: bold;">
|
||
<span style="color: black; font-weight: bold;">
|
||
####</span><br class="example">
|
||
</span><span class="example">
|
||
<span style="color: red; font-weight: bold;">def
|
||
close_comm(self):
|
||
|
||
|
||
|
||
</span></span><span style="color: red; font-weight: bold;" class="example"></span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
self.ps_set('RMT LOC')</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
try:</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
self.s.close()</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
except:</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
self.raiseError(sys.exc_info(),3)</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
self.opened = False </span><br style="font-weight: bold;" class="example">
|
||
<br class="example">
|
||
<span class="example"> <span style="font-weight: bold;">####</span><br style="font-weight: bold;">
|
||
<span style="font-weight: bold;">
|
||
# Utilizzo questo metodo per dedurre:<br>
|
||
# - la
|
||
porta seriale da utilizzare<br>
|
||
# - la
|
||
corrispondenza tra msg_id e tipo di dato da decodificare in
|
||
lettura/scrittura <br style="font-weight: bold;">
|
||
</span><span style="font-weight: bold;">
|
||
####</span><br class="example">
|
||
</span><span class="example">
|
||
def
|
||
parseICD(self): </span><br class="example">
|
||
<span class="example">
|
||
xml=''</span><br class="example">
|
||
<span class="example">
|
||
with open(self.icdxmlfile) as fileinput:</span><br class="example">
|
||
<span class="example">
|
||
for line in fileinput:</span><br class="example">
|
||
<span class="example">
|
||
xml += line.lower()</span><br class="example">
|
||
<span class="example">
|
||
</span><br class="example">
|
||
<span class="example">
|
||
root = et.fromstring(xml)</span><br class="example">
|
||
<span class="example">
|
||
</span><br class="example">
|
||
<span class="example">
|
||
config = root.find(<span style="font-weight: bold;">'./lowlevel/config'</span>)</span><br class="example">
|
||
<span class="example">
|
||
if config is not None: self.s.port = config.attrib.get('<span style="font-weight: bold;">port</span>')</span><br class="example">
|
||
<span class="example">
|
||
</span><br class="example">
|
||
<span class="example">
|
||
for i in root.findall('<span style="font-weight: bold;">./mapping/map</span>'):</span><br class="example">
|
||
<span class="example">
|
||
key= int(i.attrib.get('<span style="font-weight: bold;">id</span>'))</span><br class="example">
|
||
<span class="example">
|
||
val= i.text</span><br class="example">
|
||
<span class="example">
|
||
self.icd_map[key] = val</span><br class="example">
|
||
<span class="example">
|
||
if val == 'response' :</span><br class="example">
|
||
<span class="example">
|
||
self.response_id = key</span><br class="example">
|
||
<span class="example">
|
||
print self.icd_map</span><br class="example">
|
||
<br>
|
||
####<br>
|
||
<span class="example"><span style="font-weight: bold;"># re-implemento il metodo della
|
||
classe padre send<br>
|
||
####<br class="example">
|
||
</span></span><span class="example">
|
||
def
|
||
send(self, m_id, m_data, m_err):</span>
|
||
|
||
|
||
|
||
<span class="example"><span style="font-weight: bold;"></span></span><span style="font-weight: bold;" class="example"></span><br class="example">
|
||
<span class="example">
|
||
ret = False</span><br class="example">
|
||
<span class="example">
|
||
self.acquireLock()</span><br class="example">
|
||
<span class="example">
|
||
try:</span><br class="example">
|
||
<span class="example">
|
||
s_func = self.icd_map.get(m_id,"not_found")</span><br class="example">
|
||
<span class="example">
|
||
ret=self.eval_tx.get(s_func,self.not_found)(m_data)
|
||
<span style="font-weight: bold;"># in base al
|
||
mapping viene richiamata il methodo corrispondente </span></span><br class="example">
|
||
<span class="example">
|
||
except:</span><br class="example">
|
||
<span class="example">
|
||
self.raiseError(sys.exc_info(),3)</span><br class="example">
|
||
<span class="example">
|
||
finally:</span><br class="example">
|
||
<span class="example">
|
||
self.releaseLock()</span><br class="example">
|
||
<span class="example">
|
||
return ret</span><br class="example">
|
||
<br>
|
||
####<br class="example">
|
||
<span class="example"> </span><span class="example"><span style="color: red; font-weight: bold;"></span></span><span class="example"><span style="font-weight: bold;">
|
||
#
|
||
re-implemento il metodo della classe padre iteration ( routine che
|
||
viene eseguita da un thread ogno uSec definiti come da Clock )<br>
|
||
# in questo caso ogni clock voglio
|
||
leggere dati dalla periferica ...<br class="example">
|
||
</span></span><span class="example">
|
||
####<span style="color: red; font-weight: bold;"><br>
|
||
</span><span style="color: red;">def
|
||
iteration(self): </span></span><span class="example"></span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
reg_exp="(\w+)=([a-zA-Z0-9\.]+)\;?\s"</span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
out = { 'REMOTE' : None,</span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
'OUT' : None,</span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
'VOLTAGE' : None,</span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
'CURRENT' : None</span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
}</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
d = self.ps_query("RMT?")</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
if d[:3] == 'LOC': out['REMOTE']=0x00</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
elif d[:3] == 'REM': out['REMOTE']=0x7F</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
d = self.ps_query("OUT?")</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
if d[:3] == 'OFF': out['OUT']=0x00</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
elif d[:2] == 'ON': out['OUT']=0x7F</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
out['VOLTAGE'] = self.ps_query("MV?")</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
out['CURRENT'] = self.ps_query("MC?")</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span style="color: red; font-weight: bold;" class="example">
|
||
</span><span style="color: red;" class="example">#print
|
||
out</span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
</span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
valid=True</span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
for el in out.values():</span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
valid =(False if el == None else
|
||
valid)
|
||
</span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
</span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
if valid and self.response_id:</span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
_rmt = int(out['REMOTE'])</span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
_out = int(out['OUT'])</span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
_vlt =
|
||
float(out['VOLTAGE'])/self.resolution['voltage']</span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
_cur =
|
||
float(out['CURRENT'])/self.resolution['current']</span><br style="color: red;" class="example">
|
||
<br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
<span style="font-weight: bold;">x=struct.pack("bbhh",_rmt,_out,_vlt,_cur)</span>
|
||
|
||
|
||
<span style="font-weight: bold;">#impacchetto
|
||
il messaggio</span></span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
<span style="font-weight: bold;">self.forward_msg(self.response_id,x)
|
||
|
||
|
||
#invio il
|
||
messaggio codificato al simulatore</span></span><br style="color: red;" class="example">
|
||
<span style="color: red;" class="example">
|
||
else:</span><br style="color: red; font-weight: bold;" class="example">
|
||
<span class="example"><span style="color: red; font-weight: bold;">
|
||
</span><span style="color: red;">print
|
||
"invalid" </span><span style="color: red; font-weight: bold;"> </span>
|
||
</span><br class="example">
|
||
<br class="example">
|
||
<span class="example"> def
|
||
ps_set(self,cmd): </span><br class="example">
|
||
<span class="example">
|
||
r = self.ps_query(cmd)</span><br class="example">
|
||
<span class="example">
|
||
#print "recv::",r</span><br class="example">
|
||
<span class="example">
|
||
ret = (True if r[:2] == 'OK' else False )</span><br class="example">
|
||
<span class="example">
|
||
return ret</span><br class="example">
|
||
<br class="example">
|
||
<span class="example"> def
|
||
ps_query(self,cmd):</span><br class="example">
|
||
<span class="example">
|
||
try: </span><br class="example">
|
||
<span class="example">
|
||
n=self.s.write(cmd+'\r') </span><br class="example">
|
||
<span class="example">
|
||
except:</span><br class="example">
|
||
<span class="example">
|
||
self.raiseError(sys.exc_info(),3)</span><br class="example">
|
||
<span class="example">
|
||
raise</span><br class="example">
|
||
<span class="example">
|
||
#print 'sent',n</span><br class="example">
|
||
<span class="example">
|
||
time.sleep(0.1)
|
||
</span><br class="example">
|
||
<span class="example">
|
||
resp = self.s.read(512) </span><br class="example">
|
||
<span class="example">
|
||
#print
|
||
cmd,'->',resp
|
||
</span><br class="example">
|
||
<span class="example">
|
||
if self.query_err_reg_exp.match(resp): resp=None</span><br class="example">
|
||
<span class="example">
|
||
#print cmd,'->',resp</span><br class="example">
|
||
<span class="example">
|
||
return resp</span><br class="example">
|
||
<br class="example">
|
||
<span class="example"> def
|
||
set_remote(self,data):</span><br class="example">
|
||
<span class="example">
|
||
ret = False</span><br class="example">
|
||
<span class="example">
|
||
remote = 'LOC'</span><br class="example">
|
||
<span class="example">
|
||
if len(data) == 1:</span><br class="example">
|
||
<span class="example">
|
||
_bytes=struct.unpack('b',data)</span><br class="example">
|
||
<span class="example">
|
||
if _bytes[0] == 0x7F: remote = 'REM'</span><br class="example">
|
||
<span class="example">
|
||
ret=self.ps_set("RMT %s" %remote)</span><br class="example">
|
||
<span class="example">
|
||
return ret</span><br class="example">
|
||
<br class="example">
|
||
<span class="example"> def
|
||
set_out(self,data):</span><br class="example">
|
||
<span class="example">
|
||
ret =
|
||
False
|
||
</span><br class="example">
|
||
<span class="example">
|
||
out = 'OFF'</span><br class="example">
|
||
<span class="example">
|
||
if len(data) == 1:</span><br class="example">
|
||
<span class="example">
|
||
_bytes=struct.unpack('b',data)</span><br class="example">
|
||
<span class="example">
|
||
if _bytes[0] == 0x7F: out = 'ON'</span><br class="example">
|
||
<span class="example">
|
||
ret=self.ps_set("OUT %s" %out)</span><br class="example">
|
||
<span class="example">
|
||
return ret</span><br class="example">
|
||
<br class="example">
|
||
<span class="example"> def
|
||
set_voltage(self,data):</span><br class="example">
|
||
<span class="example">
|
||
ret = False</span><br class="example">
|
||
<span class="example">
|
||
#print len(data)</span><br class="example">
|
||
<span class="example">
|
||
if len(data) == 2:</span><br class="example">
|
||
<span class="example">
|
||
_bytes=struct.unpack('h',data)</span><br class="example">
|
||
<span class="example">
|
||
voltage=float(_bytes[0])*self.resolution['voltage']</span><br class="example">
|
||
<span class="example">
|
||
ret=self.ps_set("PV %.2f" %voltage)</span><br class="example">
|
||
<span class="example">
|
||
return ret</span><br class="example">
|
||
<br class="example">
|
||
<span class="example"> def
|
||
set_current(self,data):</span><br class="example">
|
||
<span class="example">
|
||
ret = False</span><br class="example">
|
||
<span class="example">
|
||
if len(data) == 2:</span><br class="example">
|
||
<span class="example">
|
||
_bytes=struct.unpack('h',data)</span><br class="example">
|
||
<span class="example">
|
||
#print _bytes</span><br class="example">
|
||
<span class="example">
|
||
current=float(_bytes[0])*self.resolution['current']</span><br class="example">
|
||
<span class="example">
|
||
ret=self.ps_set("PC %.2f" %current)</span><br class="example">
|
||
<span class="example">
|
||
return ret</span><br class="example">
|
||
<span class="example">
|
||
</span><br class="example">
|
||
<span class="example"> def
|
||
not_found(self,data):</span><br class="example">
|
||
<span class="example">
|
||
print "what?"</span><br class="example">
|
||
<span class="example">
|
||
return False</span><br class="example">
|
||
<br class="example">
|
||
<span class="example">
|
||
</span><br class="example">
|
||
<span style="font-weight: bold;" class="example">me
|
||
= serialTDKLambdaPowerSupply()
|
||
|
||
#!!!!!
|
||
IMPORTANTE : instanzio l'oggetto </span>
|
||
</div>
|
||
<h2><a class="mozTocH2" name="mozTocId589281"></a>Utilizzare
|
||
uno script Python come Plugin</h2>
|
||
Leonardo Platform Simulator e' in grado di utilizzare uno script Python
|
||
per ampliare le funzionalita' di base. Tale script si basa sulla classe
|
||
ProxyPluginObject offerta dal modulo python 'proxypluginobjectmod'.<br>
|
||
Tale classe permette di creare un canale diretto di comunicazione con
|
||
l'applicativo offrendo le stesse possibilita' di un plugin scritto in
|
||
cpp e compilato<br>
|
||
con l'ausilio dell'SDK dedicato alla creazione dei plugin ossia:<br>
|
||
- Creazione del menu dedicato ( e sottomenu ) con elementi richiamabili
|
||
e selezionabili ( <span style="font-weight: bold;">addAction</span>
|
||
)<br>
|
||
- Gestione degli eventi menu ( <span style="font-weight: bold;">onPluginAction</span>
|
||
)<br>
|
||
- Controllo del flusso degli eventi dell'applicativo ( <span style="font-weight: bold;">consumeICDEvent</span> )<br>
|
||
- Gestione del database ( lettura scrittura dei campi / messaggi dell
|
||
ICD )<br>
|
||
<span style="font-weight: bold;"><br>
|
||
</span>
|
||
<h3><a class="mozTocH3" name="mozTocId450787"></a>addAction</h3>
|
||
In quanto plugin l'applicativo crea una voce nel menu ( per
|
||
es. fooPlugin ). Aggiungendo azioni quente vengono associate
|
||
al menu <br>
|
||
( e conseguentemente registrate anche dall'interprete python ) in base
|
||
ai criteri descritti dagli argomenti di seguito elencati:<br>
|
||
<br>
|
||
<tt>
|
||
@param action_id : (Integer)
|
||
l'identificativo con il quale l'azione plugin viene registrata<br>
|
||
@param action_name : (String)
|
||
la stringa con la quale viene plubblicata sull'
|
||
applicativo <br>
|
||
@param action_type : (Integer)
|
||
il tipo di azione ( voce diretta / sottomenu / elemento selezionabile /
|
||
insieme di elementi </tt><tt>selezionabili</tt><tt>
|
||
ma esclusivi <br>
|
||
@param action_parent : (Integer)
|
||
l'identificativo del menu padre ( se esistente ) { vedi sottomenu }<br>
|
||
</tt><br>
|
||
<h3><a class="mozTocH3" name="mozTocId986824"></a><span style="font-weight: bold;">onPluginAction</span></h3>
|
||
Questa funzione agisce da callback ed e' invocata dall' applicativo in
|
||
conseguenza della sezione, da parte dell'utente, di una
|
||
determinata azione associata al plugin. Per individuare
|
||
univocamente l'azione invocata si utilizza il paramento action_id
|
||
precedentemente utilizzato nella creazione dell'azione.<br>
|
||
Una volta individuata tale azione non resta altro che indirizzare lo
|
||
script verso la / le funzioni sclete per tale azione.<br>
|
||
I parametri del metodo sono :<br>
|
||
<br>
|
||
<tt>@param action_id : (Integer)
|
||
l'identificativo con il quale l'azione plugin viene registrata<br>
|
||
<br>
|
||
</tt>Per esempio, aggiungo un' azione diretta denominata 'click
|
||
me' con id 7777 e preparo un metodo onClickMe.<br>
|
||
Avro' un elemento grafico nella sezione menu denominato appunto
|
||
'click me'.<br>
|
||
Alla selezione di tale elemento verra` evocata la funzione <span style="font-weight: bold;">onPluginAction </span>con
|
||
il parametro 7777 dal quale lo script python capira` che proprio tale
|
||
elemento e' stato selezionato.<br>
|
||
A questo punto potro` finalmente eseguire la funzione dedicata, ossia
|
||
onClickMe.<br>
|
||
<br>
|
||
<h3><a class="mozTocH3" name="mozTocId33149"></a>consumeICDEvent</h3>
|
||
Questa funzione agisce da callback ed e' invocata dall' applicativo in
|
||
conseguenza di azioni riferibili al database (
|
||
lettura/scrittura/aggiornamento/evento clock) o allo stato
|
||
dell'applicativo ( start/stop/error ... ). L'utilita` della decodifica
|
||
di tali eventi risiede nella possibilita' di sincronizzare operazioni
|
||
sulla base di ebneti esterni al plugin ( tipicamente vogliamo
|
||
effettuare un aggiornamento di una serie di dati ciclicamente
|
||
utilizzando come periodo il clock fornito dall'applicativo <br>
|
||
<br>
|
||
<h3><a class="mozTocH3" name="mozTocId557041"></a>Esempio</h3>
|
||
<br>
|
||
<div class="example"><div class="line"><span class="keyword">import</span> proxyplugin</div><div class="line"><span class="keyword">import</span> sys</div><div class="line">from <a class="code" href="mk:@MSITStore:D:%5Csas%5Csrc%5CLeoPlatSim__trunk%5CproxyPythonPlugin%5Chtml%5CProxyPythonPlugin.chm::/namespaceproxypluginobjectmod.html">proxypluginobjectmod</a> <span class="keyword">import</span> *</div><div class="line"><span class="keyword">import</span> ICDEVENTS</div><div class="line"><span class="keyword">import</span> time</div><div class="line"></div><div class="line">events={}</div><div class="line"></div><div class="line"><span class="keyword">class </span>Test2ProxyHandler(ProxyHandler):</div><div class="line"> def __init__(self):</div><div class="line"> super().__init__()</div><div class="line"></div><div class="line"> def start(self):</div><div class="line"> super().start()</div><div class="line"> print(self.__class__,dir(self) )</div><div class="line"> print('Hello, I\'m',self.name)</div><div class="line"> print(self.interface.getMessageNames())</div><div class="line"></div><div class="line"> def consumeICDEvent(self,event_id):</div><div class="line"> if event_id == ICDEVENTS.ICD_EVENT_ONUPDATE: pass</div><div class="line"> elif event_id == ICDEVENTS.ICD_EVENT_ONBUSCLOCK:</div><div class="line"> ...</div><div class="line"> else:</div><div class="line"> print('event ',events.get(event_id,event_id))</div><div class="line"></div><div class="line">class Test2PluginObject(ProxyPluginObject):</div><div class="line"> def __init__(self):</div><div class="line"></div><div class="line"><span class="preprocessor"> #here i specify the factory class to implements the icd handler interfaces</span></div><div class="line"> ProxyPluginObject.__init__(self,"ExamplePluginObject",Test2ProxyHandler)</div><div class="line"> self.addAction(300,'Menu',ActionTypes['MENU'])</div><div class="line"> self.addAction(301,'Load file',ActionTypes['NORMAL'],300)</div><div class="line"></div><div class="line"> def start(self):</div><div class="line"> """</div><div class="line"> for each handlers built perform start operation</div><div class="line"> """</div><div class="line"> print ( self.handlers_dict )</div><div class="line"> for k,v in self.handlers_dict.items():</div><div class="line"> print('starting ',k)</div><div class="line"> v.start()</div><div class="line"> return True</div><div class="line"></div><div class="line"></div><div class="line"> def onPluginAction(self,action_id):</div><div class="line"> global root</div><div class="line"> if action_id == 301:</div><div class="line"> ret=self.openFileDialog('open file','.','CSV File ( *.csv);;')</div><div class="line"> print(ret)</div><div class="line"> if ret is None:</div><div class="line"> self.messageBox('Operation aborted' ,'foo',2,3)</div><div class="line"> else:</div><div class="line"> self.messageBox('Operation Ok' ,'foo')</div><div class="line"></div><div class="line"></div><div class="line">if __name__ == "__main__":</div><div class="line"><span class="preprocessor"> #build a dictionary for event_id translation</span></div><div class="line"> gen = (i for i in dir(ICDEVENTS) if i.startswith("ICD_EVENT"))</div><div class="line"> for e in list(gen): events[eval( "ICDEVENTS.{}".format(e) )]=e</div><div class="line"> print(events)</div><div class="line"></div><div class="line"> print(dir(ProxyHandler))</div><div class="line"> print(dir(ProxyPluginObject))</div><div class="line"> me = globals().get('me')</div><div class="line"><span class="preprocessor"> #if me is not None: del me</span></div><div class="line"><span class="preprocessor"> me = Test2PluginObject()</span></div><br>
|
||
<br>
|
||
</div>
|
||
</div>
|
||
<div style="margin-left: 40px;">
|
||
<h1><a class="mozTocH1" name="mozTocId733406"></a>Risoluzione
|
||
dei Problemi</h1>
|
||
</div>
|
||
|
||
</body></html> |