:lang: fr :toc: = PyVCP [[cha:Panneau-Virtuel-Control]] (((Panneau de Contrôle Virtuel))) == Introduction Panneau virtuel de contrôle en python (**Py**thon **V**irtual **C**ontrol **P**anel) Le panneau de contrôle virtuel pyVCP a été créé pour donner à l'intégrateur la possibilité de personnaliser l'interface graphique d'AXIS avec des boutons et des indicateurs destinés aux tâches spéciales. Le coût d'un panneau de contrôle physique est très élevé et il peut utiliser un grand nombre de broches d'entrées/sorties. C'est là que le panneau virtuel prends l'avantage car il ne coûte rien d'utiliser pyVCP. Les panneaux de contrôle virtuels peuvent être utilisés pour tester ou monitorer le matériel, les entrées/sorties, remplacer temporairement d'autres matériels d'entrées/sorties pendant le déboguage d'une logique ladder ou pour simuler un panneau physique, avant de le construire et de le câbler vers les cartes électroniques. L'image suivante montre quelques widgets pyVCP. image::images/pyvcp_group.png[] == Construction d'un panneau pyVCP La disposition d'un panneau pyVCP est spécifiée dans un fichier XML qui contient les balises des widgets entre et . Par exemple: ---- ---- image::images/pyvcp_mypanel_fr.png[] Si vous placez ce texte dans un fichier nommé tiny.xml et que vous le lancez avec: ---- pyvcp -c panneau tiny.xml ---- pyVCP va créer le panneau pour vous, il y inclut deux widgets, un Label avec le texte _Ceci est un indicateur à LED_ et une LED rouge, utilisée pour afficher l'état d'un signal HAL de type BIT. Il va aussi créer un composant HAL nommé _panneau_ (tous les widgets dans ce panneau sont connectés aux pins qui démarrent avec _panneau_). Comme aucune balise n'était présente à l'intérieur de la balise , pyVCP nomme automatiquement la pin HAL pour le widget LED panneau.led.0 Pour obtenir la liste des widgets, leurs balises et options, consultez <>. Un fois que vous avez créé votre panneau, connectez lui les signaux HAL, vers et à partir des pins pyVCP et avec la commande habituelle: ---- net signal-name ---- Si vous débutez avec HAL, <> est vivement recommandé. == Sécurité avec pyVCP Certaines parties de pyVCP sont évaluées comme du code Python, elles peuvent donc exécuter n'importe quelle action disponible dans les programmes Python. N'utilisez que des fichiers pyVCP en .xml à partir d'une source de confiance.tag [[sec:pyvcp-avec-axis]] == Utiliser pyVCP avec AXIS (((PyVCP avec Axis))) Puisque AXIS utilise le même environnement graphique et les même outils (Tkinter) que pyVCP, il est possible d'inclure un panneau pyVCP sur le côté droit de l'interface utilisateur normale d'AXIS. Un exemple typique est présenté ci-dessous. Placer le fichier pyVCP XML décrivant le panneau dans le même répertoire que le fichier .ini. Nous voulons afficher la vitesse courante de la broche sur un widget barre de progression. Copier le code XML suivant dans un fichier appelé broche.xml: [source,xml] ---- "spindle-speed" 5000 ---- Ici nous avons fait un panneau avec un label _Vitesse broche:_ et un widget barre de progression. Nous avons spécifié que la pin HAL connectée à la barre de progression devait s'appeler _spindle-speed_ et régler la valeur maximum de la barre à 5000 (se reporter à la <>, pour toutes les options disponibles). Pour faire connaître ce fichier à AXIS et qu'il l'appelle au démarrage, nous devons préciser ce qui suit dans la section [DISPLAY] du fichier .ini: ---- PYVCP = broche.xml ---- Pour que notre widget affiche réellement la vitesse de la broche _spindle-speed_, il doit être raccordé au signal approprié de HAL. Le fichier .hal qui sera exécuté quand AXIS et pyVCP démarreront doit être spécifié, de la manière suivante, dans la section [HAL] du fichier .ini: ---- POSTGUI_HALFILE = broche_vers_pyvcp.hal ---- Ce changement lancera la commande HAL spécifiée dans _broche_vers_pyvcp.hal_. Dans notre exemple, ce fichier contiendra juste la commande suivante: ---- net spindle-rpm-filtered => pyvcp.spindle-speed ---- ce qui suppose que le signal appelé _spindle-rpm-filtered_ existe aussi. Noter que lors de l'exécution avec AXIS, toutes les pins des widgets de pyVCP ont des noms commençant par _pyvcp._. image::images/pyvcp_AXIS_fr.png[] Voila à quoi ressemble le panneau pyVCP que nous venons de créer, incorporé à AXIS. La configuration _sim/lathe_ fournie en exemple, est configurée de cette manière. == Panneaux PyVCP autonomes Cette section va décrire comment les panneaux PyVCP peuvent être affichés par eux même, par l'intermédiaire ou non des contrôleurs machine de LinuxCNC. Pour charger un panneau PyVCP autonome avec LinuxCNC utiliser cette commande: ---- loadusr -Wn monpanneau pyvcp -g WxH+X+Y -c monpanneau fichier_panneau.xml ---- Vous l'utiliserez pour avoir un panneau flottant ou un panneau avec une interface graphique autre que Axis. * '-Wn monpanneau' - Fait attendre à HAL que le composant _monpanneau_ soit chargé (devienne _ready_ en langage HAL), avant d'exécuter d'autres commandes HAL. C'est important parce-que les panneaux PyVCP exportent des pins de HAL ainsi que d'autres composants de HAL qui doivent être présents pour pouvoir se connecter à eux. Noter la lettre *W* en majuscule et la lettre *n* en minuscule. Si vous utilisez l'option -Wn vous devez également utiliser l'option -c pour nommer le panneau. * 'pyvcp < -g> < -c> panneau.xml' - Construit le panneau avec la géométrie optionnelle et/ou le nom de panneau depuis le fichier panneau.xml. Le fichier panneau.xml peut avoir n'importe quel nom avec l'extension .xml. Le fichier .xml décrit comment construire le panneau. Il est nécessaire d'ajouter le nom du chemin si le panneau n'est pas dans le répertoire dans lequel se trouve le script HAL. * '-g <+X+Y>' - Spécifie la géométrie à utiliser quand le panneau est construit. La syntaxe est _Largeur x Hauteur + Ancrage X + Ancrage Y_. La taille ou la position, ou les deux peuvent être fixés. Le point d'ancrage est le coin supérieur gauche du panneau. Par exemple; -g 250x500+800+0 fixe le panneau à 250 pixels de large, 500 pixels de haut avec le point d'ancrage placé en X800 Y0. * '-c nompanneau' - Indique à PyVCP quel composant appeler et le titre de la fenêtre. Le nom du fichier _nompanneau_ peut être n'importe quel nom sans espace. Pour charger un panneau PyVCP autonome, sans LinuxCNC utiliser cette commande: ---- loadusr -Wn monpanneau pyvcp -g 250x500+800+0 -c monpanneau monpanneau.xml ---- La commande minimale pour charger un panneau pyvcp est la suivante: ---- loadusr pyvcp monpanneau.xml ---- Vous pourrez utiliser cette commande si vous voulez un panneau sans passer par un des contrôleurs machine de LinuxCNC, par exemple pour des tests ou une visu autonome. La commande loadusr est utilisée quand vous chargez aussi un composant qui stoppera HAL depuis la fermeture jusqu'à ce qu'il soit prêt. Si vous avez chargé un panneau puis chargé Classic Ladder en utilisant la commande _loadusr -w classicladder_, CL maintiendra HAL et le panneau ouverts jusqu'à ce que vous fermiez Classic Ladder. Le '-Wn' signifie d'attendre que le composant '-Wn "nom"' devienne prêt. ('nom' peut être n'importe quel nom. Noter la lettre *W* en majuscule et le *n* en minuscule.) Le -c indique à PyVCP de construire un panneau avec le nom 'monpanneau' en utilisant les infos contenues dans le fichier 'monpanneau.xml'. Le nom du fichier 'monpanneau.xml' est sans importante mais doit porter l'extension .xml. C'est le fichier qui décrit comment construire le panneau. Il est nécessaire d'ajouter le nom du chemin si le panneau n'est pas dans le répertoire dans lequel se trouve le script HAL. Une commande optionnelle à utiliser si vous voulez que le panneau stoppe HAL depuis les commandes _Continuer_ / _Quitter_. Après avoir chargé n'importe quelles autres composants la dernière commande HAL sera: ---- waituser nompanneau ---- Cette commande indique à HAL d'attendre que le composant _nompanneau_ soit fermé avant de continuer avec d'autres commandes. C'est généralement défini comme étant la dernière commande, de sorte que HAL s'arrêtera si le panneau est fermé. [[sec:Documentation-des-widgets]] == Documentation des widgets de pyVCP (((Documentation des widgets))) Les signaux de HAL existent en deux variantes, BIT et FLOAT. pyVCP peut afficher la valeur d'un signal avec un widget indicateur, ou modifier la valeur d'un signal avec un widget de contrôle. Ainsi, il y a quatre classes de widgets pyVCP connectables aux signaux de HAL. Une cinquième classe de widgets d'aide permet d'organiser et d'appliquer des labels aux panneaux. - Widgets de signalisation, signaux de type bit: led, rectled - Widgets de contrôle, signaux de type bit: button, checkbutton, radiobutton - Widgets de signalisation de type nombre: number, s32, u32, bar, meter - Widgets de contrôle de type nombre: spinbox, scale, jogwheel - Widgets d'aide: hbox, vbox, table, label, labelframe === Syntaxe Chaque widget sera décrit brièvement, suivi par la forme d'écriture utilisée et d'une capture d'écran. Toutes les balises contenues dans la balise du widget principal, sont optionnelles. === Notes générales Á l'heure actuelle, les deux syntaxes, basée sur les balises et basée sur les attributs, sont supportées. Par exemple, les deux fragments de code XML suivants sont traités de manière identique: ---- ---- et ---- "ma-led" ---- Quand la syntaxe basée sur les attributs est utilisée, les règles suivantes sont utilisées pour convertir les valeurs des attributs en valeurs Python: . Si le premier caractère de l'attribut est un des suivants: _{(["'_ , il est évalué comme une expression Python. . Si la chaine est acceptée par int(), la valeur est traitée comme un entier. . Si la chaine est acceptée par float(), la valeur est traitée comme un flottant. . Autrement, la chaine est acceptée comme une chaine. Quand la syntaxe basée sur les balises est utilisée, le texte entre les balises est toujours évalué comme un expression Python. Les exemples ci-dessous montrent un mélange des deux formats. === Commentaires Pour ajouter un commentaire utiliser la syntaxe de xml. ---- ---- === Editer un fichier XML Editer le fichier XML avec un éditeur de texte. La plupart du temps un double click sur le nom de fichier permet de choisir _ouvrir avec l'editeur de texte_ ou similaire. === Couleurs Les couleurs peuvent être spécifiées en utilisant les couleurs RGB de X11 soit par le nom, par exemple: _gray75_ ou soit en hexa décimal, par exemple: _#0000ff_. Une liste complète est consultable ici: http://sedition.com/perl/rgb.html[http://sedition.com/perl/rgb.html]. Couleurs les plus courantes (les numéros suivant la couleur indiquent la nuance de la couleur) - white (blanc) - black (noir) - blue et blue1 - blue4 (bleu) - cyan et cyan1 - cyan4 (cyan) - green et green1 - green4 (vert) - yellow et yellow1 - yellow4 (jaune) - red et red1 - red4 (rouge) - purple et purple1 - purple4 (violet/pourpre) - gray et gray0 - gray100 (gris) === Pins de HAL Les pins de HAL fournisse le moyen de connecter les widgets aux autres éléments. Quand une pin de HAL est créée pour un widget, il est possible de la _connecter_ à une autre pin de HAL avec une commande _net_ dans un fichier .hal. Pour plus de détails, voir la commande _net_ dans le manuel de HAL. === Label Un label est un texte qui s'affiche sur le panneau. Le label a une pin optionnelle de désactivation en ajoutant: _True_. [source,xml] ---- ---- Ce code produira: image::images/pyvcp_label_fr.png[] === Les leds Une led est utilisée pour indiquer l'état d'une pin de HAL de type bit. La couleur de la led sera on_color quand le signal est vrai et off_color autrement. * __ définit le nom de la pin, par défaut: _led.n_, où n est un entier. * __ définit la taille de la led, par défaut: 20. * __ définit la couleur de la led led quand la pin est vraie, par défaut: _green_ * __ définit la couleur de la led quand la pin est fausse, par défaut: _ref_ === La led ronde [source,xml] ---- "ma-led" 50 "verte" "rouge" ---- Le résultat du code ci-dessus. image::images/pyvcp_led.png[] === La led rectangulaire C'est une variante du widget _led_. [source,xml] ---- RIDGE 6 "ma-led-rect" "50" "100" "green" "red" ---- Le code ci-dessus produit cette led, entourée d'un relief. image::images/pyvcp_rectled.png[] === Le bouton (button) Un bouton permet de contrôler une pin de type bit. La pin sera mise vraie quand le bouton sera pressé et maintenu enfoncé, elle sera mise fausse quand le bouton sera relâché. Les boutons peuvent suivre les options de formatage suivantes: - n où _n_ est le nombre d'espaces horizontaux supplémentaires - n où _n_ est le nombre d'espaces verticaux supplémentaires - "color" Couleur au survol du curseur - "color" Couleur du bouton ==== Bouton avec texte (Text Button) [source,xml] ---- "coolant-chkbtn" "Coolant" "chip-chkbtn" "Chips " ---- Le code ci-dessus produit: image::images/pyvcp_checkbutton.png[] ==== Bouton radio (radiobutton) Un bouton radio placera une seule des pins vraie. Les autres seront mises fausses. [source,xml] ------------------------------------------------- ["un","deux","trois"] "mon-radiobtn" ------------------------------------------------- Le code ci-dessus donne ce résultat: image::images/pyvcp_radiobutton_fr.png[] Noter que dans l'exemple ci-dessus, les pins de HAL seront nommées mon-radiobtn.un, mon-radiobtn.deux et mon-radiobtn.trois. Dans l'image précédente, 'trois' est la valeur sélectionnée courante. === Affichage d'un nombre (number) L'affichage d'un nombre peux recevoir les options de formatage suivantes: - ("Font Name",n) où _n_ est la taille de la police - n où _n_ est la largeur totale utilisée - pos où "pos" peut être LEFT, CENTER ou RIGHT (devrait marcher) - n où "n" est le nombre d'espaces horizontaux supplémentaires - n où "n" est le nombre d'espaces verticaux supplémentaires ==== Number Le widget _number_ affiche la valeur d'un signal de type flottant. ---- "number" ("Helvetica",24) "+4.4f" ---- Le code ci-dessus donne ce résultat: image::images/pyvcp_number.png[] ==== Flottant Le widget number affiche la valeur d'un signal de type flottant. [source,xml] ---- "my-number" ("Helvetica",24) "+4.4f" ---- image::images/pyvcp_number.png[] est une police de caractères de type Tkinter avec la spécification de sa taille. Une police qui peut être agrandie jusqu'à la taille 200 est la police _courier 10 pitch_, que vous pouvez spécifier de la manière suivante, pour afficher des chiffres réellement grands: ---- ('courier 10 pitch',100) ---- est un format _style C_, spécifié pour définir le format d'affichage du nombre. ==== Nombre s32 Le widget s32 affiche la valeur d'un nombre s32. La syntaxe est la même que celle de _number_ excepté le nom qui est . Il faut prévoir une largeur suffisante pour afficher le nombre dans sa totalité. ---- "simple-number" ("Helvetica",24) "6d" 6 ---- image::images/pyvcp_s32.png[] ==== Nombre u32 Le widget u32 affiche la valeur d'un nombre u32. La syntaxe est la même que celle de _number_ excepté le nom qui est . === Affichage d'images Seul l'affichage d'images au format gif est possible. Toutes les images doivent avoir la même taille. Les images doivent être toutes dans le même répertoire que le fichier ini (ou dans le répertoire courant pour un fonctionnement en ligne de commande avec halrun/halcmd). ==== Image Bit La bascule _image_bit_ bascule entre deux images selon la position vraie ou fausse de halpin. ---- ---- En utilisant les deux images fwd.gif et rev.gif. FWD est affiché quand _selectimage_ est fausse et REV est affiché quand _selectimage_ est vraie. .selectimage fausse image::images/pyvcp_image01.png[] .selectimage vraie image::images/pyvcp_image02.png[] ==== Image u32 La bascule _image_u32_ est la même que _image_bit_ excepté que le nombre d'images n'est pratiquement plus limité, il suffit de _selectionner_ l'image en ajustant halpin à une valeur entière commençant à 0 pour la première image de la liste, à 1 pour la seconde image etc. ---- ---- Même résultat mais en ajoutant l'image stb.gif. .Halpin = 0 image::images/pyvcp_image_u32_01.png[] .Halpin = 1 image::images/pyvcp_image01.png[] .Halpin = 2 image::images/pyvcp_image02.png[] === Barre de progression (bar) Le widget barre de progression affiche la valeur d'un signal FLOAT, graphiquement dans une barre de progression et simultanément, en numérique. [source,xml] ---- "bar" 0 123 "grey" "red" ---- Le code ci-dessus donne ce résultat: image::images/pyvcp_bar.png[] === Galvanomètre (meter) Le galvanomètre affiche la valeur d'un signal FLOAT dans un affichage à aiguille _à l'ancienne_. [source,xml] ---- "mymeter" "Battery" "Volts" 250 0 15.5 1 0.2 (14.5,15.5,"yellow") (12,14.5,"green") (0,12,"red") ---- Le code ci-dessus donne ce résultat: image::images/pyvcp_meter.png[] === Boîte d'incrément (spinbox) La boîte d'incrément contrôle une pin FLOAT. La valeur de la pin est augmentée ou diminuée de la valeur de _resolution_, à chaque pression sur une flèche, ou en positionnant la souris sur le nombre puis en tournant la molette de la souris. [source,xml] ---- "my-spinbox" -12 33 0 0.1 "2.3f" ("Arial",30) ---- Le code ci-dessus donne ce résultat: image::images/pyvcp_spinbox.png[] === Curseur (scale) Le curseur contrôle une pin FLOAT. La valeur de la pin est augmentée ou diminuée en déplaçant le curseur, ou en positionnant la souris sur le curseur puis en tournant la molette de la souris. [source,xml] ---- ("Helvetica",16) "25" "my-hscale" 0.1 HORIZONTAL -15 -33 26 ("Helvetica",16) "50" "my-vscale" 1 VERTICAL 100 0 ---- Le code ci-dessus donne ce résultat: image::images/pyvcp_scale.png[] Noter que par défaut c'est min qui est affiché même si il est supérieur à max, à moins que min ne soit négatif. === Bouton tournant (dial) Le bouton tournant imite le fonctionnement d'un vrai bouton tournant, en sortant sur un FLOAT HAL la valeur sur laquelle est positionné le curseur, que ce soit en le faisant tourner avec un mouvement circulaire, ou en tournant la molette de la souris. Un double click gauche augmente la résolution et un double click droit la diminue d'un digit. La sortie est limitée par les valeurs min et max. La variable cpr fixe le nombre de graduations sur le pourtour du cadran (prudence avec les grands nombres). [source,xml] ---- 200 100 -15 15 "Dial" 0 0.001 "anaout" "yellow" "green" "black" ---- Le code ci-dessus donne ce résultat: image::images/pyvcp_dial.png[] === Manivelle (jogwheel) La manivelle imite le fonctionnement d'une vraie manivelle, en sortant sur une pin FLOAT la valeur sur laquelle est positionné le curseur, que ce soit en le faisant tourner avec un mouvement circulaire, ou en tournant la molette de la souris. [source,xml] ---- "my-wheel" 45 250 ---- Le code ci-dessus donne ce résultat: image::images/pyvcp_jogwheel.png[] == Documentation des containers de pyVCP Les containers sont des widgets qui contiennent d'autres widgets. === Bordures Le container bordure est spécifié avec deux balises utilisées ensembles. La balise spécifie le type de bordure et la balise spécifie la largeur de la bordure. type:: La valeur de _type_ peut être: FLAT, SUNKEN, RAISED, GROOVE, ou RIDGE n:: La valeur de *n* fixe la largeur de la bordure. ---- ---- image::images/pyvcp_borders.png[] === Hbox Utilisez une Hbox lorsque vous voulez aligner les widgets, horizontalement, les uns à côtés des autres. [source,xml] ---- RIDGE 6 ---- image::images/pyvcp_hbox.png[] Á l'intérieur d'une Hbox, il est possible d'utiliser les balises __, __ et __ pour choisir le comportement des éléments contenus dans la boîte, lors d'un redimensionnement de la fenêtre. Pour des détails sur le comportement de fill, anchor, et expand, référez vous au manuel du pack Tk, _pack(3tk)_. Valeurs par défaut, _fill='y'_, _anchor='center'_, _expand='yes'_. === Vbox Utilisez une Vbox lorsque vous voulez aligner les widgets verticalement, les uns au dessus des autres. [source,xml] ---- RIDGE 6 ---- image::images/pyvcp_vbox.png[] Á l'intérieur d'une Vbox, vous pouvez utiliser les balises __, __ et __ pour choisir le comportement des éléments contenus dans la boîte, lors d'un redimensionnement de la fenêtre. Pour des détails sur le comportement de fill, anchor, et expand, référez vous au manuel du pack Tk, _pack(3tk)_. Valeurs par défaut, _fill='y'_, _anchor='center'_, _expand='yes'_. === Labelframe Un labelframe est un cadre entouré d'un sillon et un label en haut à gauche. ---- ---- [source,xml] ---- ("Helvetica",16) ---- image::images/pyvcp_labelframe_fr1.png[] === Table Une table est un container qui permet d'écrire dans une grille de lignes et de colonnes. Chaque ligne débute avec la balise __ . Un widget contenu peut être en lignes ou en colonnes par l'utilisation de la balise __. Les bordures des cellules contenant les widgets _sticky_ peuvent être réglées grâce à l'utilisation de la balise __. Une table flexible peut s'étirer sur ses lignes et ses colonnes (sticky). Exemple: [source,xml] ----
---- image::images/pyvcp_table.png[] === Onglets (Tabs) Une interface à onglets permet d'économiser l'espace en créant un container pour chaque nom d'onglet (tabs). Une seule section _tabs_ peut exister, les _tabs_ ne peuvent pas être imbriqués ni empilés. La largeur de l'onglet le plus large, determine la largeur des onglets. [source,xml] ---- ["Spindle", "Green Eggs", "Ham"] "spindle-speed" 5000 ---- image::images/pyvcp_tabs1.png[] image::images/pyvcp_tabs2.png[] image::images/pyvcp_tabs3.png[]