Ecriture de variables automate en utilisant le service web de l`ETZ
Transcription
Ecriture de variables automate en utilisant le service web de l`ETZ
J2ME : Ecriture de variables automate (service web ETZ) Ecriture de variables automate en utilisant le service web de l’ETZ (application J2ME) Sommaire 1. 2. 3. 3.1. 3.2. 3.3. 3.4. 4. 4.1. 4.2. 4.3. 4.4. 5. 5.1. 5.2. 6. 6.1. 6.2. Objectifs ...........................................................................................................................................................2 Création d’un nouveau projet J2ME ................................................................................................................2 Intégration du client Web Service....................................................................................................................8 Description du service web du coupleur ETZ..............................................................................................8 Récupération du fichier WSDL du coupleur ETZ ........................................................................................8 Intégration du fichier WSDL dans NetBeans.............................................................................................10 Problèmes de génération des classes de stub .........................................................................................12 Codage de l’application (utilisation du client Web Service)...........................................................................12 writeMultipleRegister(int UnitID, int Adresse, int[] valeur).........................................................................12 Création d’un Thread.................................................................................................................................13 Création et lancement de l’objet Thread ...................................................................................................14 Liaison du Thread avec ModbusXmlDa ....................................................................................................14 Validation de l’écriture ...................................................................................................................................15 Exécution dans l‘environnement de développement.................................................................................15 Exécution sur le PDA Palm TX..................................................................................................................16 Codes sources...............................................................................................................................................18 MIDlet : ConfigPoste1.java........................................................................................................................18 Thread d’écriture : ClassThConfP1.java ...................................................................................................19 BTS iris - Lycée Eiffel - Armentières Page 1 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) 1. Objectifs L’objectif de ce chapitre consiste uniquement à utiliser le plus simplement possible les méthodes du service web du coupleur ETZ (writeMultipleRegisters) pour modifier à partir d’une application Java ME la configuration du poste 1 du Tapiris : spécifier les numéros de codes barre évacués au poste 1. 2. Création d’un nouveau projet J2ME File > New Project > Mobile > Mobile Application BTS iris - Lycée Eiffel - Armentières Page 2 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) BTS iris - Lycée Eiffel - Armentières Page 3 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) Clic droit sur le projet > New Package > « com.iris.wspda » Clic droit sur le package > New > Visual MIDlet Attention : respecter scrupuleusement la démarche proposée Dans le Flow Design : 1. Ajout d’une Form : Instance Name = formConfPoste1 et Title = « Config. Poste 1 » 2. Etablir la liaison « Start point » Dans le Screen Design : 1. Ajout d’un Exit Command : Instance Name = exitCmdConf1 et Label = « Quitter » 2. Ajout de 3 Textfield : Instance Name = textFieldCodeX, Label = « Code num. X » et Contraints = NUMERIC 3. Ajout d’un OK Command : Instance Name = okCmdConf1 et Label = « Valider » 4. Désactivez le mode « Lazy Initialised » de la Form, des Command et des TextField. BTS iris - Lycée Eiffel - Armentières Page 4 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) Dans le Flow Design : 1. Etablir la liaison entre « Quitter » et « Exit Point » Dans le code source de ConfigPoste1.java : 1. Créez un attribut qui contiendra les codes barres à évacuer au poste 1 static int vectValeurPoste1 []; 2. A la fin de la fonction initialize(), initialisez le vecteur vectValeurPoste1[] vectValeurPoste1 = new int [3]; 3. Dans commandAction() recopiez la valeur des TextFields dans vectValeurPoste1[] … } else if (command == okCmdConf1) { vectValeurPoste1[0] = Integer.parseInt(textFieldCode1.getString()); vectValeurPoste1[1] = Integer.parseInt(textFieldCode2.getString()); vectValeurPoste1[2] = Integer.parseInt(textFieldCode3.getString()); } … Copie en éxécution : BTS iris - Lycée Eiffel - Armentières Page 5 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) Code source généré : /* * ConfigPoste1.java * * Created on 28 novembre 2006, 13:22 */ package com.iris.wspda; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; /** * * @author gwenael */ public class ConfigPoste1 extends MIDlet implements CommandListener { /** Creates a new instance of ConfigPoste1 */ public ConfigPoste1() { initialize(); } private Form formConfPoste1; private Command exitCmdConf1; private TextField textFieldCode1; private TextField textFieldCode2; private TextField textFieldCode3; private Command okCmdConf1; static int vectValeurPoste1 []; /** Called by the system to indicate that a command has been invoked on a particular displayable. * @param command the Command that ws invoked * @param displayable the Displayable on which the command was invoked */ public void commandAction(Command command, Displayable displayable) { // Insert global pre-action code here if (displayable == formConfPoste1) { if (command == exitCmdConf1) { // Insert pre-action code here exitMIDlet(); // Insert post-action code here } else if (command == okCmdConf1) { // Insert pre-action code here // Do nothing // Insert post-action code here vectValeurPoste1[0] = Integer.parseInt(textFieldCode1.getString()); vectValeurPoste1[1] = Integer.parseInt(textFieldCode2.getString()); vectValeurPoste1[2] = Integer.parseInt(textFieldCode3.getString()); } } // Insert global post-action code here } BTS iris - Lycée Eiffel - Armentières Page 6 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) /** This method initializes UI of the application. */ private void initialize() { // Insert pre-init code here textFieldCode3 = new TextField("Code num. 3", null, 120, TextField.NUMERIC); okCmdConf1 = new Command("Valider", Command.OK, 1); exitCmdConf1 = new Command("Quitter", Command.EXIT, 1); textFieldCode1 = new TextField("Code num. 1", null, 120, TextField.NUMERIC); textFieldCode2 = new TextField("Code num. 2", null, 120, TextField.NUMERIC); formConfPoste1 = new Form("Config. Poste 1", new Item[] { textFieldCode1, textFieldCode2, textFieldCode3 }); formConfPoste1.addCommand(exitCmdConf1); formConfPoste1.addCommand(okCmdConf1); formConfPoste1.setCommandListener(this); getDisplay().setCurrent(formConfPoste1); // Insert post-init code here vectValeurPoste1 = new int [3]; } /** * This method should return an instance of the display. */ public Display getDisplay() { return Display.getDisplay(this); } /** * This method should exit the midlet. */ public void exitMIDlet() { getDisplay().setCurrent(null); destroyApp(true); notifyDestroyed(); } public void startApp() { } public void pauseApp() { } public void destroyApp(boolean unconditional) { } } BTS iris - Lycée Eiffel - Armentières Page 7 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) 3. Intégration du client Web Service 3.1. Description du service web du coupleur ETZ Voici les méthodes disponibles sur le service web (implémentation d’un accès aux données en Modbus) : ReadDeviceIdentification Transparent Ready Modbus BASIC class. Operation to read device identification. inputs: int UnitID. outputs: DeviceIdentification ReadDeviceIdentificationResult. ReadMultipleRegisters Transparent Ready Modbus BASIC class. Operation to read multiple registers. inputs: int UnitID, int Address, int Quantity. outputs: int[] ReadMultipleRegistersResult. WriteMultipleRegisters Transparent Ready Modbus BASIC class. Operation to write multiple registers. inputs: int UnitID, int Address, int[] Value. outputs: ReadCoils Transparent Ready Modbus REGULAR class. Operation to read multiple coils. inputs: int UnitID, int Address, int Quantity. outputs: int[] ReadCoilsResult. WriteMultipleCoils Transparent Ready Modbus REGULAR class. Operation to write multiple coils. inputs: int UnitID, int Address, int[] Value. outputs: ReadInt32 Extension of Transparent Ready Modbus REGULAR class. Operation to read integer (32 bits). inputs: int UnitID, int Address, int Quantity. outputs: int[] ReadInt32Result. WriteInt32 Extension of Transparent Ready Modbus REGULAR class. Operation to write integer (32 bits). inputs: int UnitID, int Address, int[] Value. outputs: Remarques : Les méthodes XXXRegisters() travaillent sur des mots mémoire (%MW) et les méthodes XXXCoils() travaillent sur des bits mémoire (%M). Le coupleur ETZ 510 est capable de traiter au maximum une requête SOAP toutes les 200 ms (appel d’une méthode du Web Service). 3.2. Récupération du fichier WSDL du coupleur ETZ A l’aide d’un navigateur web, connectez-vous sur l’adresse du coupleur ETZ : http://192.168.33.8 Cliquez sur Documentation puis Web Services. Choisissez le service web « ModbusXmlDa » (utilisation directe des adresses mémoires de l’automate, les accès sont plus rapides que par les symboles) BTS iris - Lycée Eiffel - Armentières Page 8 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) Copier le raccourci vers WSDL 1.1 http://192.168.33.8/ws/ModbusXmlDa?wsdl BTS iris - Lycée Eiffel - Armentières Page 9 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) 3.3. Intégration du fichier WSDL dans NetBeans Clic droit sur le projet > New > File Folder > MIDP > J2ME Web Service Client Remplir le champ WSDL URL avec l’adresse du fichier WSDL récupéré précédemment Cliquez sur « Retrieve WSDL » Décochez « Create Sample MIDlet » Cliquez sur Finish BTS iris - Lycée Eiffel - Armentières Page 10 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) BTS iris - Lycée Eiffel - Armentières Page 11 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) NetBeans génère un paquetage portant le nom du service web (modbusxmlda). Ce paquetage contient différentes classes : ¾ La classe ModbusXmlDaSoap_Stub est la classe principale qui permet d’établir la liaison avec le coupleur ETZ et qui permet d’appeler les différentes méthodes exportées (WriteMultipleRegisters, ReadMultipleRegisters, …) ¾ Les classes associées aux méthodes exportées ¾ Les classes de conversion de types (ArrayOfInt) 3.4. Problèmes de génération des classes de stub Sur un poste utilisant NetBeans Mobility 5.5 avec le JDK 6.0, l’assistant d’’intégration du fichier WSDL ne fonctionne pas toujours bien : il ne crée pas les classes de stub (permettant d’utiliser le service web). Ce problème se produit quand à la fin de l’assistant « J2ME Web Service Client », seul 2 fichiers sont créés (les fichiers .wsdl et .wsclient). Les classes de stub peuvent être générées en utilisant Sun Java Wireless Toolkit 2.5 : ¾ Démarrer > Programmes > Sun Java Wireless Toolkit 2.5 … > Utilities ¾ Lancez « Stub Generator » Adresse du fichier WSDL Sélectionnez le dossier « src » du projet NetBeans Nom du paquetage généré précédemment par l’assistant « J2ME Web Service Client » 4. Codage de l’application (utilisation du client Web Service) En MIDP, l’utilisation de fonctions réseau associées avec les évènements de l’IHM (CommandAction) doit se faire dans un Thread (pour éviter les blocages possibles du MIDlet). Nous créerons donc une classe Thread pour appeler les méthodes exportées du service web (writeMultipleRegisters, …). 4.1. writeMultipleRegister(int UnitID, int Adresse, int[] valeur) Rappel : %MW30 et suivantes = adresses mémoire de l’automate contenant la liste des codes barres à évacuer au poste 1 Dans notre exemple, nous utiliserons la classe ArrayOfInt, créée avec le stub, pour mettre en œuvre le troisième paramètre de la méthode ( de type int[] ). BTS iris - Lycée Eiffel - Armentières Page 12 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) // This class was generated by the JAXRPC SI, do not edit. // Contents subject to change without notice. // JSR-172 Reference Implementation wscompile 1.0, using: JAX-RPC Standard Implementation (1.1, build R59) package modbusxmlda; public class ArrayOfInt { protected int[] _int; public ArrayOfInt() { } public ArrayOfInt(int[] _int) { this._int = _int; } public int[] get_int() { return _int; } public void set_int(int[] _int) { this._int = _int; } } Les paramètres de la méthode writeMultipleregister() sont : ¾ ¾ ¾ UnitID = 0 par défaut car non utilisé dans la version actuelle Adresse = 30, cf. adresse mémoire désirée de l’automate valeur = un objet ArrayOfInt contenant les codes barres à évacuer au poste 1 4.2. Création d’un Thread Clic droit sur le paquetage com.iris.wspda > New > Java Class Nommez la nouvelle classe : ClassThConfP1 Modifiez le code généré pour : ¾ Dérivation de la classe Thread ¾ Création de la méthode run() package com.iris.wspda; public class ClassThConfP1 extends Thread{ public ClassThConfP1() { } public void run () { System.out.println("début écriture"); System.out.println("fin écriture"); } } BTS iris - Lycée Eiffel - Armentières Page 13 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) 4.3. Création et lancement de l’objet Thread Dans ConfigPoste1.java : ¾ Créez un attribut private ClassThConfP1 objThConfP1 ; ¾ A la fin de la fonction initialize(), instantiez l’objet Thread objThConfP1 = new ClassThConfP1(); ¾ Lancez le Thread dans commandAction() pour un test unitaire ... } else if (command == okCmdConf1) { ... objThConfP1.start(); ... } 4.4. Liaison du Thread avec ModbusXmlDa Dans ClassThConfP1.java : ¾ Importez les paquetages import modbusxmlda.* ; import java.rmi.RemoteException; ¾ Créez un objet objStub private ModbusXmlDaSoap_Stub objStub ; ¾ ¾ public ClassThConfP1() { objStub = new ModbusXmlDaSoap_Stub(); } Créez une méthode d’écriture de la configuration du poste 1 public void ecrireConfigP1() { ArrayOfInt objAOInt ; objAOInt = new ArrayOfInt (ConfigPoste1.vectValeurPoste1); try { // objAOInt, vecteur d’entiers initialisé avec les valeurs de // l’IHM contenues dans ConfigPoste1.vectValeurPoste1 objStub.writeMultipleRegisters(0, 30, objAOInt); } catch (RemoteException ex) { ex.printStackTrace(); } } Appel de la méthode ecrireConfigP1() dans le run() du Thread public void run () { System.out.println("début écriture"); ecrireConfigP1(); System.out.println("fin écriture"); } Remarque : Pour insérer automatiquement la gestion des exceptions : clic droit sur la ligne > Surround with Try-catch (génère aussi les importations de packages nécessaires) BTS iris - Lycée Eiffel - Armentières Page 14 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) 5. Validation de l’écriture Pour toutes les validations, les nouvelles valeurs écrites dans l’automate seront visualisées grâce au site embarqué FactoryCast. 5.1. Exécution dans l‘environnement de développement Dans NetBeans, lancez le programme en exécution. BTS iris - Lycée Eiffel - Armentières Page 15 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) 5.2. Exécution sur le PDA Palm TX Il faut générer le fichier .PRC correspondant aux fichiers JAD et JAR : ¾ Lancez le logiciel jartoprc_w.exe ¾ Spécifier l’emplacement du fichier .jad de votre projet (dans le sous-dossier « dist ») ¾ Cliquez sur « Generate PRC » Transférez le fichier EcritureWSTapiris.prc sur le palm TX et exécutez-le. BTS iris - Lycée Eiffel - Armentières Page 16 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) BTS iris - Lycée Eiffel - Armentières Page 17 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) 6. Codes sources 6.1. MIDlet : ConfigPoste1.java /* * ConfigPoste1.java * * Created on 28 novembre 2006, 13:22 */ package com.iris.wspda; import java.rmi.RemoteException; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; /** * * @author BTS iris Armentières */ public class ConfigPoste1 extends MIDlet implements CommandListener { /** Creates a new instance of ConfigPoste1 */ public ConfigPoste1() { initialize(); } private Form formConfPoste1; private Command exitCmdConf1; private TextField textFieldCode1; private TextField textFieldCode2; private TextField textFieldCode3; private Command okCmdConf1; private Command okCommand1; private ClassThConfP1 objThConfP1 ; static int vectValeurPoste1 []; /** Called by the system to indicate that a command has been invoked on a particular displayable. * @param command the Command that ws invoked * @param displayable the Displayable on which the command was invoked */ public void commandAction(Command command, Displayable displayable) { // Insert global pre-action code here if (displayable == formConfPoste1) { if (command == exitCmdConf1) { // Insert pre-action code here exitMIDlet(); // Insert post-action code here } else if (command == okCmdConf1) { // Insert pre-action code here // Do nothing // Insert post-action code here vectValeurPoste1[0] = Integer.parseInt(textFieldCode1.getString()); vectValeurPoste1[1] = Integer.parseInt(textFieldCode2.getString()); vectValeurPoste1[2] = Integer.parseInt(textFieldCode3.getString()); objThConfP1.start(); textFieldCode1.setString(""); textFieldCode2.setString(""); textFieldCode3.setString(""); } } // Insert global post-action code here } /** This method initializes UI of the application. */ private void initialize() { // Insert pre-init code here textFieldCode3 = new TextField("Code num. 3", null, 120, TextField.NUMERIC); okCmdConf1 = new Command("Valider", Command.OK, 1); textFieldCode1 = new TextField("Code num. 1", null, 120, TextField.NUMERIC); BTS iris - Lycée Eiffel - Armentières Page 18 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) exitCmdConf1 = new Command("Quitter", Command.EXIT, 1); textFieldCode2 = new TextField("Code num. 2", null, 120, TextField.NUMERIC); formConfPoste1 = new Form("Config. Poste 1", new Item[] { textFieldCode1, textFieldCode2, textFieldCode3 }); formConfPoste1.addCommand(exitCmdConf1); formConfPoste1.addCommand(okCmdConf1); formConfPoste1.setCommandListener(this); getDisplay().setCurrent(formConfPoste1); // Insert post-init code here objThConfP1 = new ClassThConfP1(); vectValeurPoste1 = new int [3]; } /** * This method should return an instance of the display. */ public Display getDisplay() { return Display.getDisplay(this); } /** * This method should exit the midlet. */ public void exitMIDlet() { getDisplay().setCurrent(null); destroyApp(true); notifyDestroyed(); } /** This method returns instance for okCommand1 component and should be called instead of accessing okCommand1 field directly. * @return Instance for okCommand1 component */ public Command get_okCommand1() { if (okCommand1 == null) { // Insert pre-init code here okCommand1 = new Command("Ok", Command.OK, 1); // Insert post-init code here } return okCommand1; } public void startApp() { } public void pauseApp() { } public void destroyApp(boolean unconditional) { } } 6.2. Thread d’écriture : ClassThConfP1.java /* * ClassThConfP1.java * * Created on 5 décembre 2006, 09:22 * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package com.iris.wspda; import java.rmi.RemoteException; import modbusxmlda.* ; /** * * @author BTS iris Armentières BTS iris - Lycée Eiffel - Armentières Page 19 sur 20 03/05/2007 J2ME : Ecriture de variables automate (service web ETZ) */ public class ClassThConfP1 extends Thread{ private ModbusXmlDaSoap_Stub objStub ; /** Creates a new instance of ClassThConfP1 */ public ClassThConfP1() { objStub = new ModbusXmlDaSoap_Stub(); } public void run (){ System.out.println("début écriture"); ecrireConfigP1(); System.out.println("fin écriture"); } public void ecrireConfigP1() { ArrayOfInt objAOInt ; objAOInt = new ArrayOfInt (ConfigPoste1.vectValeurPoste1); try { //%MW30 = Table de paramétrage des produits à aiguiller au poste 1 objStub.writeMultipleRegisters(0, 30, objAOInt); } catch (RemoteException ex) { ex.printStackTrace(); } } } BTS iris - Lycée Eiffel - Armentières Page 20 sur 20 03/05/2007