Curriculum Vitae

Login Form

TIA PORTAL : la parola chiave Variant ed il suo uso

Verso una programmazione OOP (Object Oriented Programming) prendiamo in considerazione la parola chiave VARIANT di TIA Portal.

Inoltre è proposta una metodologia, mediante l'uso della parola chiave REGION, di scrittura del codice in "stile Codesys". Potremmo pensare di rendere trasportabile, secondo ciascuna sintassi dei due ambienti di programmazione, il codice scritto in CodeSys in TIA Portal e vicecersa.

Durante lo sviluppo di applicazioni, possiamo avere la necessità di eseguire una stessa funzione per tipi di dati diversi. Piuttosto che avere un certo numero di funzioni, ciascuna che gestisce il proprio tipo di dato, preferisco averne una sola che sia in grado di trattare i tipi di dati che necessitano.

Dall'Help in linea del TIA Portal abbiamo:

Help TIA portal Variant

 

################    In costruzione  ######################

XML JAVA

CREARE UN FILE XML IN JAVA UTILIZZANDO LE LIBRERIE STANDARD DOM.

In questo articolo verrà presentato come creare, scrivere, un file xml con le librerie standard DOM che troviamo in ogni distribuzione di JSE.

Non parliamo dell'architettura del file xml, come è strutturato, dato che in rete sono disponibili numerose informazioni, ma illustro come ho risolto l'esigenza di scrivere un file xml. Per chi interessato alla struttura dell'xml una particolare sorgente di informazioni, molto utile, anche se un pò datata, ma i concetti sono gli stessi, la potete reperire all'indirizzo: http://www.cafeconleche.org/books/xmljava/chapters/index.html.

Di seguito la struttura base del file xml che deve essere scritto, che è utilizzato come data base dell'applicazione:

<?xml version="1.0" encoding="UTF-8"?>

<!-- xml MEP DATA BASE --> //questo è un commento

<xDB_MEP>                       //questo è l'elemento root
    <RIFERIMENTI>
         <DataGenerazione>4/1/2019 12:31:57</DataGenerazione>
         <DataModifica>4/1/2019 12:31:57</DataModifica>
         <Versione>0.0.0.0</Versione>
    </RIFERIMENTI>
    <PROGRAMMA Id="1" cancellato="0">    //questo è un nodo con attributi
         <Codice>qwertyuniop</Codice>
         <Misura>45.0</Misura>
         <Tagli>5</Tagli>
         <Beta1>0</Beta1>
         <Beta2>0</Beta2>
         <GruppoMateriale>2</GruppoMateriale>
         <Geometria>2</Geometria>
         <L>0.0</L>
         <H>0.0</H>
         <D>78.0</D>
         <T>0.0</T>
         <F>78.0</F>
         <S>56</S>
         <OverrideFInizio>0</OverrideFInizio>
         <SpazioOverrideFInizio>0.0</SpazioOverrideFInizio>
         <OverrideFFine>0</OverrideFFine>
         <SpazioOverrideFFine>0.0</SpazioOverrideFFine>
         <OverrideSInizio>0</OverrideSInizio>
         <SpazioOverrideSInizio>0.0</SpazioOverrideSInizio>
         <OverrideSFine>0</OverrideSFine>
         <SpazioOverrideSFine>0.0</SpazioOverrideSFine>
         <IndiceLibreriePLC>0</IndiceLibreriePLC>
         <Fcta>6.0</Fcta>
         <Riserva_0>riserva_0</Riserva_0>
         <Riserva_1>riserva_1</Riserva_1>
         <Riserva_2>riserva_2</Riserva_2>
         <Riserva_3>riserva_3</Riserva_3>
         <Riserva_4>riserva_4</Riserva_4>
         <Riserva_5>riserva_5</Riserva_5>
         <Riserva_6>riserva_6</Riserva_6>
         <Riserva_7>riserva_7</Riserva_7>
         <Riserva_8>riserva_8</Riserva_8>
         <Riserva_9>riserva_9</Riserva_9>
         <Riserva_10>riserva_10</Riserva_10>
         <Data_Gen>4/1/2019 12:31:57</Data_Gen>
         <Data_Canc>4/1/2019 12:31:57</Data_Canc>
         <Data_Mod>4/1/2019 12:31:57</Data_Mod>
         <crc_32>nu</crc_32>
     </PROGRAMMA>

</xDB_MEP>

Distinguiamo: una sezione RIFERIMENTI che contiene dati generali, una sezione PROGRAMMA che contiene i dati del relativo programma. La sezione RIFERIMENTI è unica per il file, la sezione PROGRAMMA rappresenta il record e può essere ripetuta n volte.

 Il codice: fatto per provare la funzionalità, poi potete tranquillamente renderlo più compatto con variabili di appoggio degli elementi da creare.

     /**
     * metodo per creare un nuovo file xml, secondo la struttura di xMep
     */
    public int creaFile(JTable tab, File f) {
        int ris = -1;
        int passo = 0;
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();        
        dbf.setValidating(false);
        try {
            Document doc = dbf.newDocumentBuilder().newDocument();            
            doc.setXmlStandalone(true);        
            //Element root = doc.getDocumentElement();
            doc.appendChild(doc.createComment(COMMENTO));
            try {
                Element radice = doc.createElement(RADICE);
                passo = ++passo;    //1
                doc.appendChild(radice);
                passo = ++passo;    //2
                Element rif = doc.createElement("RIFERIMENTI");
                passo = ++passo;    //3
                radice.appendChild(rif);
                passo = ++passo;    //4
                DataManager data = new DataManager();
                String dt = data.dataGenerazione((byte)0);
                int i;
                //aggiunge la sezione RIFERIMENTI
                for (i=0; i < 3; i++) {
                    String nc = "RIF_" + i;
                    Element campo;                    
                    if (i < 2) {
                        if (i==0) {
                            campo = doc.createElement(RIF_0);
                        }
                        else {
                            campo = doc.createElement(RIF_1);
                        }
                        passo = ++passo;
                        campo.setTextContent(dt);
                    }
                    else {
                        passo = ++passo;
                        campo = doc.createElement(RIF_2);
                        passo = ++passo;
                        campo.setTextContent(VERS);
                    }
                    passo = ++passo;
                    rif.appendChild(campo);
                    passo = ++passo;
                }
                //aggiungi i programmi
                for (i=0; i<tab.getRowCount(); i++) {
                    int numprg = i+1;
                    String aux = "";
                    aux = aux + numprg;    //contiene il numero di programma
                    Element prg = doc.createElement("PROGRAMMA");
                    passo = ++passo;
                    prg.setAttribute("Id", aux);
                    passo = ++passo;
                    prg.setAttribute("cancellato", "0");        
                    passo = ++passo;
                    radice.appendChild(prg);
                    //recupera gli elementi della riga da salvare
                    RowManager riga = new RowManager();
                    passo = ++passo;
                    riga.RowManagerDammiDatiRiga(tab, i);
                    passo = ++passo;
                    Element cod = doc.createElement("Codice");
                    passo = ++passo;
                    aux = riga.getCodice();
                    if (aux.equals("") || aux.equals(null)) {
                        aux = " ";
                    }
                    cod.setTextContent(aux);
                    passo = ++passo;
                    prg.appendChild(cod);
                    Element mis = doc.createElement("Misura");
                    mis.setTextContent(riga.getMisura());
                    prg.appendChild(mis);
                    passo = ++passo;
                    Element el = doc.createElement("Tagli");
                    el.setTextContent(riga.getTagli());
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("Beta1");
                    el.setTextContent("0");
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("Beta2");
                    el.setTextContent("0");
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("GruppoMateriale");
                    aux = "";
                    aux = aux + riga.getGruppo();
                    el.setTextContent(aux);
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("Geometria");
                    aux = "";
                    aux = aux + riga.getTipo();
                    el.setTextContent(aux);
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("L");
                    el.setTextContent(riga.getLarghezza());
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("H");
                    el.setTextContent(riga.getAltezza());
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("D");
                    el.setTextContent(riga.getDiametro());
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("T");
                    el.setTextContent(riga.getSpessore());
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("F");
                    el.setTextContent(riga.getF());
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("S");
                    el.setTextContent(riga.getS());
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("OverrideFInizio");
                    el.setTextContent("0");
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("SpazioOverrideFInizio");
                    el.setTextContent("0.0");
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("OverrideFFine");
                    el.setTextContent("0");
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("SpazioOverrideFFine");
                    el.setTextContent("0.0");
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("OverrideSInizio");
                    el.setTextContent("0");
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("SpazioOverrideSInizio");
                    el.setTextContent("0.0");
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("OverrideSFine");
                    el.setTextContent("0");
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("SpazioOverrideSFine");
                    el.setTextContent("0.0");
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("IndiceLibreriePLC");
                    el.setTextContent("0");
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("Fcta");
                    el.setTextContent(riga.getFcta());
                    prg.appendChild(el);
                    passo = ++passo;
                    for (int j=0; j< 11;j++) {
                        aux = "Riserva_" + j;
                        el = doc.createElement(aux);
                        aux = "riserva_" + j;
                        el.setTextContent(aux);
                        prg.appendChild(el);
                        passo = ++passo;
                    }
                    el = doc.createElement("Data_Gen");
                    el.setTextContent(dt);
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("Data_Canc");
                    el.setTextContent(dt);
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("Data_Mod");
                    el.setTextContent(dt);
                    prg.appendChild(el);
                    passo = ++passo;
                    el = doc.createElement("crc_32");
                    el.setTextContent("nu");
                    prg.appendChild(el);
                    passo = ++passo;
                }                                                
            }
            catch (DOMException dex) {
                dex.printStackTrace();
                ris = 10 + passo;
                switch (passo) {
                    case 0: ris = 10; break;    //errore nella creazione dell'elemento radice
                    case 1: ris = 11; break;    //errore nell'aggiunta del nodo radice
                    case 2: ris = 12; break;    //errore nella creazione dell'elemento RIFERIMENTI
                    case 3: ris = 13; break;    //errore nell'aggiunta del nodo RIFERIMENTI
                    case 4: ris = 14; break;    //errore nella creazione dell'elemento RIF_0
                    case 5: ris = 15; break;    //errore nell'aggiunta del testo del nodo RIF_0
                    case 6: ris = 16; break;    //errore nell'aggiunta dell'elemento RIF_0
                    case 7: ris = 17; break;    //errore nella creazione dell'elemento RIF_1
                    case 8: ris = 18; break;    //errore nell'aggiunta del testo del nodo RIF_1
                    case 9: ris = 19; break;    //errore nell'aggiunta dell'elemento RIF_1
                    case 10: ris = 20; break;    //errore nella creazione dell'elemento RIF_2
                    case 11: ris = 21; break;    //errore nell'aggiunta del testo del nodo RIF_2
                    case 12: ris = 22; break;    //errore nell'aggiunta dell'elemento RIF_2
                }
            }
            try {
                salvaFileXml(doc, f);
                ris = 0;
            } catch (TransformerConfigurationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                ris = 1;
            }
            
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            //errore durante la generazione del documentbuilder
            ris = 99;
        }
        return ris;
    }

La routine SalvaFileXml:

/*
     * metoso per salvare il file xml nuovo
     */
    public byte salvaFileXml(Document doc, File f) throws TransformerConfigurationException {
        byte ris = 0;
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer t= tf.newTransformer();
        t.setOutputProperty(OutputKeys.INDENT, "Yes");
        DOMSource src = new DOMSource(doc);
        StreamResult result = new StreamResult(f);
        try {
            t.transform(src, result);
        } catch (TransformerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            ris = 1;
        }
        return ris;
    }

RowManager è una classe per recuperare gli elementi di una riga di una tabella. Dato che il tutto ècontenuto in un blocco Try Catch, la variabile passo è utilizzata per capire in quale punto di generazione del'Xml è accaduto l'errore.

 

 

Mio test.

PROSSIMO ARTICOLO

Programmazione OOP in TIA Portal

utilizzo dell'oggetto VARIANT

******************************************************

                                                                                                NEXT CONTENT

                                                                                          OOP with TIA PORTAL

                                                                                           how to use VARIANT

******************************************************

WORKING IN PROGRESS

******************************************************

"Nuovo progetto. Pagina bianca dell'ambiente di sviluppo.... E' in questo momento che ci si sente veramente soli! Un leader deve sapere cogliere la sfida ... e la prima istruzione è scritta!"

Da lì in poi è una storia che si ripete dal 2002 da quando ho iniziato a proporre soluzioni tecnologiche per lo sviluppo di software per automazione industriale.

In questi anni sono stati sviluppati software per i più svariati settori, dalle macchine da stampa, macchine per la lavorazione del legno, linee di lavorazione del vetro, impianti di depurazione e trattamento acqua, impianti domotici, impianti per la movimentazione di materiali, impianti di aspirazione, impianti di frantumazione, macchine per il taglio di materiali ferrosi. Le piattaforme hadware di sviluppo utilizzate sono state varie. Vuoi perchè alcuni lavori sono stati dei rimodernamenti o magari perchè il quadro elettrico era già stato progettato da un terzista.

Non sono mancate però le occasioni in cui sia stato progettato e scelto la piattaforma hardware per soddisfare le specifche tecniche funzionali del cliente.

 


CODESYS

Codesys

 Un esempio di codice sviluppato in Codesys per un impianto di depolverizzazione. Particolare in Ladder ma anche il formato ST è utilizzato.