<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://doc4-fr-mirror.openflyers.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jtremblet</id>
	<title>Documentation de la solution web de gestion OpenFlyers - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://doc4-fr-mirror.openflyers.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jtremblet"/>
	<link rel="alternate" type="text/html" href="https://doc4-fr-mirror.openflyers.com/Special:Contributions/Jtremblet"/>
	<updated>2026-05-26T18:04:45Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.6</generator>
	<entry>
		<id>https://doc4-fr-mirror.openflyers.com/index.php?title=Installation-armoire-%C3%A0-cl%C3%A9s&amp;diff=13019</id>
		<title>Installation armoire à clés</title>
		<link rel="alternate" type="text/html" href="https://doc4-fr-mirror.openflyers.com/index.php?title=Installation-armoire-%C3%A0-cl%C3%A9s&amp;diff=13019"/>
		<updated>2024-12-10T10:52:05Z</updated>

		<summary type="html">&lt;p&gt;Jtremblet: /* Navigateur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Présentation=&lt;br /&gt;
L'objet de cette page est de décrire la procédure d'installation d'une [[Contrôle des accès#Armoires_à_clés_Deister_commercialiées_par_OpenFlyers|armoire à clés Deister ProxSafe Smart vendue par OpenFlyers]] et équipée du mini-serveur OpenFlyers.&lt;br /&gt;
&lt;br /&gt;
=Préparation du réseau avant réception de l'armoire=&lt;br /&gt;
''La procédure décrite dans ce paragraphe peut être effectuée avant la réception de l'armoire. A défaut, de préparation anticipée, elle doit être effectuée '''avant''' tout branchement de l'armoire à clés sauf dans le cas d'une Livebox d'orange où il est nécessaire d'effectuer d'abord le branchement du matériel pour pouvoir ensuite effectuer la configuration du routeur. Dans ce cas, il faut d'abord suivre la procédure [[#Connexion_de_l'armoire|connexion de l'armoire et ensuite revenir sur ce paragraphe]]''&lt;br /&gt;
&lt;br /&gt;
L'utilisation de l'armoire à clés Deister, nécessite 1 raccordement électrique 220v avec les 3 câbles (phase, neutre et terre) ainsi que 2 connexions RJ45 au réseau local via un routeur, en général une &amp;quot;box&amp;quot; :&lt;br /&gt;
*une pour le mini-serveur OpenFlyers&lt;br /&gt;
*une pour l'armoire à clés.&lt;br /&gt;
&lt;br /&gt;
Le réseau doit être configuré en DHCP ce qui signifie que toute connexion au réseau est automatiquement reconnue et qu'une adresse IP est automatiquement affectée à cette connexion. Par défaut, les &amp;quot;box&amp;quot; des fournisseurs d'accès sont configurées selon ce mode là.&lt;br /&gt;
&lt;br /&gt;
Cependant pour que le serveur OpenKey et l'armoire à clé puissent communiquer entre-eux et avec le logiciel OpenFlyers, les adresses IP attribuées par le routeur doivent être fixes. Pour forcer le routeur à attribuer toujours la même adresse IP à un équipement il faut le configurer en créant l'association d'une [[Wikipedia-fr:Adresse_IP|adresse IP]] à l'[[Wikipedia-fr:Adresse_MAC|adresse MAC]] du matériel.&lt;br /&gt;
&lt;br /&gt;
Les adresses IP et MAC à configurer vous sont communiquées dans un e-mail qu'OpenFlyers envoie après la commande de l'armoire à clés et qui sont également indiquées le bordereau de livraison.&lt;br /&gt;
&lt;br /&gt;
Ce paramétrage se fait soit directement dans l'interface de gestion du routeur ou par l'intermédiaire de l'interface de gestion de la &amp;quot;box&amp;quot; de votre fournisseur d'accès et dépend du matériel que vous disposez.&lt;br /&gt;
==Configuration du routeur==&lt;br /&gt;
Le routeur d'un fournisseur d'accès internet correspond à la &amp;quot;box&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Configuration d'un Routeur NETGEAR Numericable===&lt;br /&gt;
''Cette documentation a été rédigée à partir d'un routeur NETGEAR CBVG834G''&lt;br /&gt;
*Aller sur la page d'administration du routeur. Elle est par défaut sous la forme http://192.168.0.1&lt;br /&gt;
*Saisir l'identifiant et le mot de passe&lt;br /&gt;
''Rédiger la redirection des ports''&lt;br /&gt;
*Aller '''Paramètres avancés &amp;gt; IP LAN'''&lt;br /&gt;
*Dans le 2ème formulaire, saisir dans les lignes '''Adresse MAC''' et '''Adresse IP''' les couples (adresse IP, adresse MAC) communiqués dans le bordereau de livraison et cliquer à après la saisie de chaque couple sur le bouton '''Ajouter''' de sorte à obtenir le tableau suivant :&lt;br /&gt;
''Copie d'écran à insérer''&lt;br /&gt;
*Débrancher 5 secondes le routeur puis le rebrancher.&lt;br /&gt;
&lt;br /&gt;
===Configuration d'une Box BBox===&lt;br /&gt;
Il faut au préalable connecter l'armoire afin que la BBox lui affecte par défaut une adresse IP.&lt;br /&gt;
*Connecter vous sur votre BBox en tapant son IP 192.168.1.254 et mettre le mot de passe &lt;br /&gt;
* Déployer le menu '''Service de la box''' et sélectionner DHCP&lt;br /&gt;
&lt;br /&gt;
[[File:BBox_acces_DHCP.jpg]]&lt;br /&gt;
* Allez dans la rubrique '''Attribution adresse IP Statique'''&lt;br /&gt;
* Cliquer sur ajouter un équipement&lt;br /&gt;
Sélectionner l'adresse MAC de l'équipement et le nommer pour plus de clarté&lt;br /&gt;
&lt;br /&gt;
[[File:BBox_config_adresse_IP_fixe.jpg]]&lt;br /&gt;
* Refaire l'opération pour le Raspberry Pi&lt;br /&gt;
&lt;br /&gt;
[[File:BBox_adresse_IP_fixe.jpg]]&lt;br /&gt;
&lt;br /&gt;
===Configuration d'une Box SFR===&lt;br /&gt;
Il faut au préalable connecter l'armoire et le module Raspberry Pi par câbles RJ45 et l'alimenter afin que la Box SFR lui affecte par défaut une adresse IP.&lt;br /&gt;
*Connecter vous sur votre Box SFR en tapant son IP 192.168.1.1 &lt;br /&gt;
*Cliquer sur Réseau V4/Général&lt;br /&gt;
*Mettre l'identifiant et mot de passe &lt;br /&gt;
*Vous visualiser les Postes connectés, il doit y en avoir deux supplémentaires à votre configuration habituelle&lt;br /&gt;
*Notez les adresses MAC des deux équipements (celles ci vous ont été communiquées dans le bon de livraison)&lt;br /&gt;
*Aller dans Réseau V4/DHCP&lt;br /&gt;
*Dans la section Adresses statiques &lt;br /&gt;
**Associez l'adresse 192.168.1.200 à l'adresse MAC du Raspberry Pi et cliquez sur le bouton + à droite&lt;br /&gt;
**Associez l'adresse 192.168.1.201 à l'adresse MAC de l'armoire Deister et cliquez sur le bouton + à droite&lt;br /&gt;
&lt;br /&gt;
[[File:Keypanel2012-redirection-de-ports-SFR.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
*Déconnecter l'alimentation de l'armoire et la réalimenter après 10 secondes d'attente pour visualiser les nouvelles affectations d'IP statiques&lt;br /&gt;
&lt;br /&gt;
===Configuration d'une Freebox v4===&lt;br /&gt;
*Aller sur [https://subscribe.free.fr/login/ l'espace client]&lt;br /&gt;
*Saisir l'identifiant et le mot de passe&lt;br /&gt;
*Aller '''Ma Freebox &amp;gt; Configurer mon routeur Freebox'''&lt;br /&gt;
*Dans '''Configuration &amp;gt; Configuration du routeur''', vérifier que l''''Adresse IP Freebox''' est 192.168.0.254&lt;br /&gt;
*Cliquer sur '''Redirections / Baux DHCP''' pour faire dérouler le contenu&lt;br /&gt;
*Dans le paragraphe '''Redirections de ports''', à côté de l’icône symbolisant un &amp;quot;plus&amp;quot; :&lt;br /&gt;
**Dans le champ de la colonne '''PORT EXTERNE''' saisir ''8000''&lt;br /&gt;
**Dans les champs de la colonne '''IP DE DESTINATION''' saisir ''192.168.0.200''&lt;br /&gt;
**Dans le champ de la colonne '''PORT INTERNE''' saisir ''8000''&lt;br /&gt;
**Cliquer sur l'icône symbolisant un &amp;quot;plus&amp;quot; de sorte à ce que la ligne vienne s'ajouter en-dessous&lt;br /&gt;
*Répéter cette opération de sorte à obtenir le tableau suivant :&lt;br /&gt;
&lt;br /&gt;
[[File:Keypanel2012-redirection-de-ports-freebox.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Dans le paragraphe '''Baux DHCP permanents''', saisir sur la ligne avec l'icône symbolisant un &amp;quot;plus&amp;quot; les couples (adresse IP, adresse MAC) communiqués dans le bordereau de livraison de sorte à obtenir le tableau suivant :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Keypanel2012-Baux-DHCP-permanents-freebox.png|center]]&lt;br /&gt;
&lt;br /&gt;
*En bas du formulaire, cliquer sur le bouton '''Sauvegarder les paramètres'''&lt;br /&gt;
*Débrancher 5 secondes la freebox puis la rebrancher.&lt;br /&gt;
*Une fois l'armoire à clés livrée, passer à l'étape de [[Installation armoire à clés#Connexion_de_l'armoire|connexion de l'armoire]].&lt;br /&gt;
&lt;br /&gt;
===Configuration d'une Freebox v6===&lt;br /&gt;
A effectuer avec l'armoire connectée au réseau local de la Freebox&lt;br /&gt;
*Dans un navigateur d'un appareil connecté au réseau local de la Freebox concernée : http://mafreebox.freebox.fr&lt;br /&gt;
*Saisir le mot de passe de connexion à la Freebox&lt;br /&gt;
*Double-cliquer sur le bouton '''Paramètres de la Freebox'''&lt;br /&gt;
*Cliquer sur l'onglet en haut '''Mode avancé'''&lt;br /&gt;
*Double-cliquer le bouton '''DHCP'''&lt;br /&gt;
*Cliquer sur l'onglet '''Baux actifs'''&lt;br /&gt;
*Identifier dans la liste l'armoire à clés&lt;br /&gt;
*Faire un clic droit et cliquer sur le bouton contextuel '''Ajouter un bail statique'''&lt;br /&gt;
*Compléter l'adresse IP statique avec l'adresse IP communiqué dans le bordereau de livraison&lt;br /&gt;
*Indiquer éventuellement un commentaire pour permettre de repérer plus facilement l'élément dans la liste&lt;br /&gt;
*Cliquer le bouton '''Valider'''&lt;br /&gt;
*Vérifier dans '''Baux statiques''' qu'apparait bien le nouvel élément&lt;br /&gt;
&lt;br /&gt;
===Configuration d'une Livebox Orange===&lt;br /&gt;
Pour se connecter à l'interface d'une Livebox Orange, il faut :&lt;br /&gt;
*[[Trucs-et-astuces#Trouver-l'adresse-IP-du-routeur|Trouver l'adresse IP du routeur]].&lt;br /&gt;
*Taper cette adresse dans la barre d'adresse du navigateur.&lt;br /&gt;
*Saisir le couple identifiant mot de passe du routeur. C'est par défaut (admin, admin). ''Il est recommandé de modifier ce mot passe.''&lt;br /&gt;
Ensuite, la procédure dépend du [http://assistance.orange.fr/livebox-tous-les-modeles-524.php modèle de Livebox]. Nous mettons ci-dessous les procédures en fonction des demandes et des difficultés rencontrées par les administrateurs.&lt;br /&gt;
&lt;br /&gt;
''Attention, pour configurer correctement le routeur, il faut mettre les couples (adresses IP, adresses MAC) au niveau de la configuration des adresses IP statiques et non pas au niveau du filtrage du réseau Wifi (WAN).''&lt;br /&gt;
&lt;br /&gt;
====Livebox 2 de Sagem====&lt;br /&gt;
La procédure ci-dessous permet d'associer les couples (adresse IP, adresse MAC) uniquement lorsque l'armoire à clé est connectée.&lt;br /&gt;
* '''Configuration'''&lt;br /&gt;
* Menu de gauche '''Réseaux &amp;amp; Services &amp;gt; Équipements &amp;gt; Visualiser'''&lt;br /&gt;
* Deux nouvelles icônes doivent apparaitre&lt;br /&gt;
* Cliquer dessus chaque icône, vérifier à quel matériel l'adresse MAC correspond (inscrit sur le bordereau de livraison de l'armoire à clés) et renommer chaque icône en &amp;quot;Armoire à clés&amp;quot; et &amp;quot;Daemon RPi&amp;quot; pour une identification plus aisée.&lt;br /&gt;
Attention : orange rajoute ses propres noms qui ne simplifient pas la reconnaissance du matériel.&lt;br /&gt;
*Retourner dans l'onglet '''Configuration'''&lt;br /&gt;
*Menu de gauche '''Réseaux &amp;amp; Services &amp;gt; Livebox &amp;gt; Paramètres avancés'''&lt;br /&gt;
*Onglet '''DHCP'''&lt;br /&gt;
*Section '''Adresse IP statique'''&lt;br /&gt;
*Cliquer sur '''Ajouter'''&lt;br /&gt;
[[File:LiveBox.JPG]]&lt;br /&gt;
*Sélectionner dans le menu déroulant '''Armoire à clés'''&lt;br /&gt;
*Saisir l'adresse &amp;quot;192.168.1.201&amp;quot;&lt;br /&gt;
*Cliquer sur '''Ajouter'''&lt;br /&gt;
*Sélectionner dans le menu déroulant '''Daemon RPi'''&lt;br /&gt;
*Saisir l'adresse &amp;quot;192.168.1.200&amp;quot;&lt;br /&gt;
*Cliquer sur le bouton '''Sauver'''&lt;br /&gt;
*Réinitialiser la Livebox&lt;br /&gt;
Il ne faut pas se fier à l'interface livebox pour la reconnaissance de l'armoire à clés car il semblerait qu'il existe un défaut d'affichage de l'état de connexion de l'armoire à clés dans cette interface. A la place il faut [[Gestion armoire à clés#Vérifier_les_connexions_réseaux_de_l'armoire_et_du_mini-serveur|vérifier la bonne attribution des couples (adresse IP, adresse MAC) en ligne de commande]].&lt;br /&gt;
&lt;br /&gt;
=Fixation de l'armoire DEISTER ProxSafe Smart II=&lt;br /&gt;
L'armoire a un encombrement murale de 630 mm x 300 mm et une profondeur de 200 mm&lt;br /&gt;
&lt;br /&gt;
L'arrière du coffret comporte un capteur de détection d'arrachement, veillez à ce que la zone d'appui soit affleurante aux fixations du coffret&lt;br /&gt;
&lt;br /&gt;
La face arrière du coffret est espacé de 20 mm des fixations murales. Ceci permet le cheminement des câbles (alimentation + 2 Ethernet)&lt;br /&gt;
&lt;br /&gt;
Pour accéder aux fixations de l'armoire il faut ouvrir la porte de service. Prendre la clé dans la pochette rouge fournie avec l'armoire, ouvrir la porte de façade en tournant la clé dans le sens horaire. Ouvrir la porte de service en tournant la clé dans le sens anti-horaire&lt;br /&gt;
&lt;br /&gt;
Sa fixation murale dépend du type de mur sur lequel vous l'installez&lt;br /&gt;
&lt;br /&gt;
==Fixation de l'armoire sur un mur robuste==&lt;br /&gt;
Elle peut dans ce cas être fixée que par les 2 orifices traversants avec 2 vis&lt;br /&gt;
&lt;br /&gt;
[[File:DEISTER_ _Support_fixation_ _dos_armoire.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[Media:DEISTER_fixation_SMART U II.pdf]]&lt;br /&gt;
&lt;br /&gt;
*Entraxe 406 mm, &lt;br /&gt;
*Diamètre 10 mm, &lt;br /&gt;
*Profondeur 20 mm&lt;br /&gt;
Les fixations dépendent de la nature du support, nous conseillons :&lt;br /&gt;
* Dans du bois : 2 tire-fonds de 8 x 70&lt;br /&gt;
* Dans du béton : 2 chevilles à expansion M8 x 55 + 2 vis M8 x 60&lt;br /&gt;
* Dans de la brique alvéolaire : 2 chevilles à scellement chimique M8 + rondelles et écrous (ou bien voir ci dessous)&lt;br /&gt;
&lt;br /&gt;
Ces fixations sont aussi suffisantes si l'armoire est supportée sur un meuble ou une étagère&lt;br /&gt;
&lt;br /&gt;
==Fixation de l'armoire sur un mur de résistance modérée==&lt;br /&gt;
Le support de fixation fournit permet de répartir les efforts. Il est vivement recommandé pour une pose similaire à celle d'une fixation d'une télévision à écran plat murale&lt;br /&gt;
&lt;br /&gt;
[[File:DEISTER_ _Support_fixation.jpg]]&lt;br /&gt;
&lt;br /&gt;
Il présente les avantages suivants :&lt;br /&gt;
*Il permet de faire l'installation seul (pas besoin d'être à deux)&lt;br /&gt;
*Il permet un réglage de horizontalité pour une mise niveaux plus aisée &lt;br /&gt;
*Il réduit le risque de chute (l'armoire pèse 20kg) et de l'endommager en la faisant tomber lors de son installation.&lt;br /&gt;
Ce support ne reprend que les efforts verticaux, il ne dispense pas des 2 fixations centrales qui pourront alors être de résistance moindre. Le support comporte 8 orifices de fixations de diamètre 8 mm, le nombre de fixations sera adaptée au type de support&lt;br /&gt;
*Placo, chevilles à grande expansion (type &amp;quot;Molly&amp;quot;) M6 x 65 ou DuoPower de Fisher + vis 7 x 60&lt;br /&gt;
*Brique plâtrière, carreau de plâtre, parpaing, béton cellulaire : cheville plastique de 10 x 50 + vis 6 ou 8 de longueur 60 mm&lt;br /&gt;
&lt;br /&gt;
Ne pas négliger les fixations, les sollicitations dans un club peuvent être sévères&lt;br /&gt;
&lt;br /&gt;
=Connexions de l'armoire DEISTER ProxSafe Smart II=&lt;br /&gt;
&lt;br /&gt;
Ne brancher la batterie qu'au moment de la [[#Finalisation|finalisation]], c'est à dire une fois que l'armoire est correctement installée et configurée à la plateforme OpenFlyers. En effet, il peut être nécessaire de faire plusieurs reboots de l'armoire en débranchant/rebranchant l'armoire du secteur. De ce fait, si la batterie est branchée, le reboot ne pourrait se faire  en débranchant l'alimentation.&lt;br /&gt;
&lt;br /&gt;
Les câbles suivants doivent être passés avant la fixation définitive au mur :&lt;br /&gt;
*Câble d'alimentation 220v&lt;br /&gt;
*Câble Ethernet entre le routeur et l'armoire&lt;br /&gt;
*Câble Ethernet entre le routeur et le mini-serveur OpenFlyers&lt;br /&gt;
Fixer l'armoire au mur par 4 chevilles et vis en ayant au préalable retiré l’adhésif de maintien de l’interrupteur qui sert à détecter une tentative de vandalisme&lt;br /&gt;
*Identifier le serveur OpenKey situé derrière le verrou de porte &lt;br /&gt;
*Vérifier que la carte microSDHC est correctement enfichée dans le logement du serveur OpenKey situé derrière la carte électronique.&lt;br /&gt;
*Brancher un câble Ethernet sur le serveur OpenKey&lt;br /&gt;
*Identifier la prise RJ45 de l'armoire et y brancher un câble Ethernet :&lt;br /&gt;
*Brancher le câble d'alimentation 220V en y joignant le câble de l'armoire correspondant à la &amp;quot;terre&amp;quot; (câble jaune et vert) :&lt;br /&gt;
*Bien vérifier que la terre soit raccorder sur le connecteur et que votre installation dispose d'un disjoncteur différentielle approprié&lt;br /&gt;
[[File:Connexion_Alim_SmartII.jpg]]&lt;br /&gt;
*Brancher l'alimentation sur le secteur.&lt;br /&gt;
**1 voyant vert, sur l'alimentation signal que l'alimentation est correctement connectée&lt;br /&gt;
**1 voyant rouge, sur le module serveur Openkey signal que la carte est fonctionnelle, un voyant vert cligne lorsque des signaux sont échangé sur le réseaux&lt;br /&gt;
**5 voyants leds, situés sur la carte mère de l'armoire doivent s'éclairer&lt;br /&gt;
**2 leds sur chaque connecteur RJ45, indique que la connexion au réseau est fonctionnelle : orange fixe et clignement vert&lt;br /&gt;
*Refermer la porte de service puis la porte de façade&lt;br /&gt;
*A l'initialisation de l'armoire les voyants en haut de la face  avant signale les phases de démarrage&lt;br /&gt;
** Jaune clignotant durant l'initialisation de la carte mère de l'armoire&lt;br /&gt;
** Jaune fixe en fin d'initialisation&lt;br /&gt;
** Si la configuration du programme est faite le voyant Jaune s'eteint, le voyant rouge s'allumera pour test puis le voyant vert fixe signale la fin de l'initialisation du serveur OpenKey&lt;br /&gt;
&lt;br /&gt;
=Configuration OpenFlyers=&lt;br /&gt;
&lt;br /&gt;
==Navigateur==&lt;br /&gt;
&lt;br /&gt;
*Dialogue avec l'armoire en HTTPS : nous privilégions le navigateur Chrome de Google pour la connexion avec l'armoire à clés. Ce navigateur est compatible avec le certificat de sécurité autosigné installé sur le daemon PyOpenKey et sur le(s) PC permettant l'accès à l'armoire.&lt;br /&gt;
*Le ou les PC de la structure doivent être paramétrés pour que ce soit ce navigateur qui soit utilisé.&lt;br /&gt;
&lt;br /&gt;
=== Installation du certificat de sécurité sur PC Windows ===&lt;br /&gt;
En cas de changement de PC le certificat de sécurité doit être installé&lt;br /&gt;
&lt;br /&gt;
Avant le changement du PC récupérer la clé public sur une clé USB. Par défaut elle est situé dans le répertoire :&lt;br /&gt;
'''C:\Users\OpenFlyers\PyOpenKey\SSL\opkServer.crt'''&lt;br /&gt;
&lt;br /&gt;
Ce certificat est au format texte codé en base 64&lt;br /&gt;
&lt;br /&gt;
En tant qu'administrateur créer les répertoires devant recevoir le certificat&lt;br /&gt;
*Ouvrir l'explorateur et le répertoire Utilisateur&lt;br /&gt;
*Clic droit puis dans le menu popup sélectionné '''Nouveau &amp;gt; Dossier'''&lt;br /&gt;
*Nommer le '''OpenFlyers'''&lt;br /&gt;
*Ce déplacer dans ce nouveau répertoire&lt;br /&gt;
*Clic droit puis dans le menu popup sélectionné '''Nouveau &amp;gt; Dossier'''&lt;br /&gt;
*Nommer le '''PyOpenKey'''&lt;br /&gt;
*Ce déplacer dans ce nouveau répertoire&lt;br /&gt;
*Clic droit puis dans le menu popup sélectionné '''Nouveau &amp;gt; Dossier'''&lt;br /&gt;
*Nommer le '''SSL'''&lt;br /&gt;
*Copier le certificat '''opkServer.crt''' situé sur votre clé USB dans ce répertoire&lt;br /&gt;
&lt;br /&gt;
L'activation du certificat doit être faite dans chaque environnement utilisant OpenFlyers &lt;br /&gt;
&lt;br /&gt;
L'installation sur le nouveau PC s'effectue en ligne de commande&lt;br /&gt;
&lt;br /&gt;
Ouvrir l'interface de ligne de commande de Windows &lt;br /&gt;
* Exécuté la commande '''cmd''' dans la zone de recherche de la barre de tache de Windows&lt;br /&gt;
* Cliquer sur '''Invite de commande''', ceci affiche la fenêtre noir Windows de ligne de commande&lt;br /&gt;
* Exécuter la commande '''certutil -addstore -f -user root &amp;quot;C:\Users\OpenFlyers\PyOpenKey\SSL\opkServer.crt&amp;quot;'''&lt;br /&gt;
&lt;br /&gt;
==Paramétrage OpenFlyers==&lt;br /&gt;
&lt;br /&gt;
*Aller dans '''Admin &amp;gt; Structure &amp;gt; Paramétrage &amp;gt; Contrôle d'accès'''&lt;br /&gt;
*Activer les interrupteurs '''Contrôle d'accès''' et '''Gestion armoire à clés'''&lt;br /&gt;
*Cliquer sur le bouton '''Enregistrer'''&lt;br /&gt;
[[File:Config_parametres_OF_controle_acces 1.jpg|1200px]]&lt;br /&gt;
&lt;br /&gt;
*De nouveaux champs sont alors visibles :&lt;br /&gt;
**Activer l'interrupteur '''Gestion des clés'''&lt;br /&gt;
** sélectionner le Logiciel de contrôle de l'armoire à clés. Pour OpenFlyers version 4.2 en https : PyOpenKey4&lt;br /&gt;
*De nouveaux champs sont alors visibles :&lt;br /&gt;
**Champ '''Nombre de clés''' : indiquer le nombre de clés que l'armoire peut accueillir (8, 16 ou 32)&lt;br /&gt;
*Dans la rubrique '''IP du PC contenant le logiciel de contrôle''' indiquer l'adresse IP du mini-serveur OpenFlyers, par défaut '''192.168.0.200''' ou '''192.168.1.200'''&lt;br /&gt;
*Dans la rubrique '''Port du PC contenant le logiciel de contrôle''' indiquer le port '''4080''' (ou autre si spécifié sur le bordereau de livraison)&lt;br /&gt;
**L'interrupteur '''Vérifier la présence de la clé lors de la fermeture d'activité'''. Il est recommandé de l'activer.&lt;br /&gt;
**Choisissez la durée de '''Temporisation''' pour prendre la clé. Cette durée est uniquement valide pour la prise de clé en mode locale, elle dépend de la distance entre votre PC et l'armoire. 10 à 20 secondes sont des valeurs usuelles. Pour la durée de déclenchement par le logiciel celle ci est paramétrable dans le programme du mini serveur. Demander au support OF pour modification&lt;br /&gt;
**L'interrupteur '''Fermeture automatique des activités au retour de la clé'''. Il est recommandé de le désactiver.&lt;br /&gt;
**Champ '''Phrase mot de passe''', saisir la même phrase que celle paramétrée lors de la configuration de l'armoire&lt;br /&gt;
[[File:Config_parametres_OF_controle_acces 3.jpg|1200px]]&lt;br /&gt;
*Cliquer sur le bouton '''Enregistrer'''&lt;br /&gt;
*Aller dans '''Admin &amp;gt; Utilisateurs &amp;gt; Profils''' et vérifier que le profil sous lequel vous êtes connecté possède le droit '''Gestion des clés''' dans l'onglet '''Généralité admin'''&lt;br /&gt;
&lt;br /&gt;
=Première connexion=&lt;br /&gt;
==Brancher l'alimentation de l'armoire à clés==&lt;br /&gt;
*Le voyant vert de l'armoire doit s'allumer après quelques minutes&lt;br /&gt;
*Le voyant orange reste allumé durant la phase de connexion au serveur OpenFlyers et la vérification de la concordande de la position des clés dans l'armoire&lt;br /&gt;
*A la fin de l'initialisation, si toutes les clés sont bien positionnées, le voyant orange s’éteint&lt;br /&gt;
&lt;br /&gt;
Si le voyant orange ne s'éteint pas, [[Gestion armoire à clés#Remettre_les_clés_à_leur_bonne_position|vérifier si le problème ne vient pas de la position d'une ou plusieurs clés]].&lt;br /&gt;
&lt;br /&gt;
== Vérifier la communication avec le serveur PyOpenKey ==&lt;br /&gt;
Ce chapitre concerne les utilisateurs d'OpenFlyers 4.2 et au delà qui demande une connexion au serveur PyOpenKey en https&lt;br /&gt;
&lt;br /&gt;
Vérifier si le certificat est correctement reconnu sur votre PC&lt;br /&gt;
&lt;br /&gt;
*Ouvrer le Navigateur Google Chrome&lt;br /&gt;
*Dans le champ url indiquer l'adresse du WevServer de PyOpenKey, port 8000 '''https;//192.168.1.200:8000''' (cette adresse est a adapter en fonction de votre configuration réseau)&lt;br /&gt;
*Si c'est une première connexion, une fenêtre Windows s'ouvre vous demandant la confirmation de l'utilisation du certificat&lt;br /&gt;
*Si la fenêtre Windows indique que la connexion n'est pas sécurisé c'est que le certificat n'est pas correctement installé. Ne pas valider une exception de sécurité &lt;br /&gt;
*Si le certificat est reconnu alors la page du [[Gestion-armoire-à-clés#Connexion-à-l'interface-Web-de-secours|Webserver]] doit s'ouvrir&lt;br /&gt;
&lt;br /&gt;
=Appariement des clés aux ressources=&lt;br /&gt;
*Pour attribuer les clés aux ressources dans OpenFlyers il faut aller dans la page '''Gestion &amp;gt; Ressources &amp;gt; Actives'''&lt;br /&gt;
*Sélectionner un numéro de clé pour chaque ressource.&lt;br /&gt;
[[File:Page_Ressource.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Sur les versions au-delà d'OpenFlyers 4.2, si aucune action ne s'exécute ceci être dû à la non reconnaissance du certificat&lt;br /&gt;
 &lt;br /&gt;
Voir [[Installation-armoire-à-clés#Vérifier-la-communication-avec-le-serveur-PyOpenKey |Vérifier la communication avec le serveur PyOpenKey]].&lt;br /&gt;
&lt;br /&gt;
Sur les versions antérieures d'OpenFlyers 4.2, si l'action ne s'exécute pas ceci peut être dû au blocage par le navigateur des scripts javascript car l'appel est en http sur une page https.&lt;br /&gt;
&lt;br /&gt;
Sous Google Chrome apparait un icône en haut à droite&lt;br /&gt;
[[File:Page_Allow_mixed_content_Chrome.png|center]]&lt;br /&gt;
Avec le message&lt;br /&gt;
&amp;lt;bash&amp;gt;This page is trying to load scripts from unauthenticated sources&amp;lt;/bash&amp;gt;&lt;br /&gt;
Avec un lien pour autoriser la page&lt;br /&gt;
&amp;lt;bash&amp;gt;Load unsafe script&amp;lt;/bash&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Enregistrer la position souhaitée des clés=&lt;br /&gt;
*Aller dans '''Gestion &amp;gt; Ressources &amp;gt; Actives'''&lt;br /&gt;
*Cliquer sur l'un des icônes symbolisant une clé dans la colonne '''Armoire à clé &amp;gt; Statut''' afin de pouvoir déverrouiller la porte.&lt;br /&gt;
*Mettre '''toutes les clés''' au tableau dans l'ordre souhaité y compris les clés qui avaient été retirées lors de la [[#Première_connexion|première connexion]]. Il ne faut pas tenir compte des lumières rouges autour des clés.&lt;br /&gt;
*Cliquer sur l'icône '''Activer les tags des clés'''&lt;br /&gt;
Les identifiants de chaque clé doivent apparaître après rafraîchissement de la page :&lt;br /&gt;
&lt;br /&gt;
[[File:Ressources_activees.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Si ce n'est pas le cas, rafraichir manuellement la page en allant dans '''Gestion &amp;gt; Ressources &amp;gt; Actives'''.&lt;br /&gt;
&lt;br /&gt;
Débranchez de nouveau l'armoire pour refaire l'initialisation&lt;br /&gt;
&lt;br /&gt;
=Prise de clé à l'ouverture d'un vol=&lt;br /&gt;
Pour un contrôle de la prise de clé par un utilisateur il faut que le logiciel soit paramétré avec l'option '''Ouverture et fermeture des activités.'''  Aller dans '''Admin &amp;gt; Structure &amp;gt; Structure &amp;gt; Paramétrage''' et dans la rubrique '''Gestion des activités''' activer l'option '''Ouverture et fermeture des activités'''&lt;br /&gt;
.&lt;br /&gt;
[[File:Gestion_des_vols.JPG]]&lt;br /&gt;
&lt;br /&gt;
Pour une prise de clé il faut cliquer droit sur une réservation et choisir l'option Saisir un vol&lt;br /&gt;
La page de saisie d'un vol s'ouvre avec l'option Départ en vol&lt;br /&gt;
Renseigner les champs et cliquer sur Valider&lt;br /&gt;
Une page de prise de clé s'ouvrira &lt;br /&gt;
&lt;br /&gt;
[[File:Prise_de_cle.JPG]]&lt;br /&gt;
&lt;br /&gt;
Cliquer sur le bouton Libérer la clé pour l'aéronef F-XXXX &lt;br /&gt;
La porte doit se déverrouiller (voyant orange) et la clé être libérer durant la temporisation prévue (clé entourée d'un halo lumineux rouge)&lt;br /&gt;
Refermer la porte sinon un buzzer intermittent retenti&lt;br /&gt;
&lt;br /&gt;
Déconnectez-vous de OpenFlyers pour l'utilisateur suivant&lt;br /&gt;
&lt;br /&gt;
=Retour de vol=&lt;br /&gt;
&lt;br /&gt;
Pour remettre la clé, se connecter sur OpenFlyers &lt;br /&gt;
Cliquer sur l'icône Ouvrir la porte en haut à gauche de la page du cahier de réservation&lt;br /&gt;
&lt;br /&gt;
[[File:Ouvrir_porte.JPG]]&lt;br /&gt;
&lt;br /&gt;
La porte sera déverrouillé durant la durée de la temporisation&lt;br /&gt;
*Remettre la clé à son emplacement&lt;br /&gt;
*Si la clé est incorrectement placée, l'armoire déverrouille la clé (halo rouge de la clé reposée) et signale l'emplacement correct en allumant le halo rouge de l'emplacement prévu. &lt;br /&gt;
*Sur le planning l'avion en vol est indiquer par une couleur bleu. Survoler ce vol avec la souris&lt;br /&gt;
*Un menu apparait avec l'option '''Fermer le vol'''&lt;br /&gt;
*Cliquer et enregistré le vol &lt;br /&gt;
&lt;br /&gt;
'''Note:''' Ne pas aller directement sur le menu '''Planning &amp;gt; Activités &amp;gt; Saisir une activité''' pour fermer le vol. Dans ce cas il ne pourra être établi de corrélation entre l'affichage du planning et le vol que vous fermez. Le vol restera ouvert (en bleu sur le planning) et l'avion sera bloqué pour repartir en vol. Néanmoins si un pilote faire l'erreur alors il faut, dans le menu surgissant, cliquer sur '''Annuler'''&lt;br /&gt;
&lt;br /&gt;
=Finalisation=&lt;br /&gt;
*Ouvrir la porte de service&lt;br /&gt;
*Brancher le connecteur de la batterie de sauvegarde (Déconnecté pour le transport)&lt;br /&gt;
&lt;br /&gt;
[[File:Connexion_Batterie_SmartII.jpg]]&lt;br /&gt;
*Refermer la porte de service&lt;br /&gt;
&lt;br /&gt;
L'ouverture de la porte de service enclenche une alarme qui est mise en mémoire dans OpenFlyers. Pour supprimer l'alarme il faut aller sur l'interface [[Gestion armoire à clés#Connexion_interface_Web_de_secours|Web admin]] et cliquer sur '''RESET'''&lt;/div&gt;</summary>
		<author><name>Jtremblet</name></author>
	</entry>
	<entry>
		<id>https://doc4-fr-mirror.openflyers.com/index.php?title=Interfa%C3%A7age-OpenFlyers-et-armoire-%C3%A0-cl%C3%A9s&amp;diff=13017</id>
		<title>Interfaçage OpenFlyers et armoire à clés</title>
		<link rel="alternate" type="text/html" href="https://doc4-fr-mirror.openflyers.com/index.php?title=Interfa%C3%A7age-OpenFlyers-et-armoire-%C3%A0-cl%C3%A9s&amp;diff=13017"/>
		<updated>2024-12-10T10:24:24Z</updated>

		<summary type="html">&lt;p&gt;Jtremblet: /* Modification de l'état d'une clé */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
=Présentation=&lt;br /&gt;
L'objet de cette page est de décrire le protocole d'interfaçage avec toute solution d'armoire à clés tiers. Pour les armoires à clés commercialisées par OpenFlyers, il faut se référer à la [[Contrôle des accès|documentation sur le contrôle d'accès]].&lt;br /&gt;
&lt;br /&gt;
Le protocole repose sur le principe que l'interfaçage est réalisé par un logiciel de contrôle de l'armoire à clé sur un PC ou une solution embarquée et qui dispose d'un accès à internet lui permettant de communiquer avec OpenFlyers. La communication est synchrone.&lt;br /&gt;
&lt;br /&gt;
=Interface utilisateur OpenFlyers=&lt;br /&gt;
L'utilisateur ouvre un vol dans OpenFlyers :&lt;br /&gt;
&lt;br /&gt;
[[File:Menu-contextuel-ouverture-de-vol.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Il se retrouve sur le formulaire de saisie du vol en mode Départ en vol:&lt;br /&gt;
&lt;br /&gt;
[[File:Formulaire-ouverture-de-vol.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lorsqu'il clique sur le bouton de validation, 3 cas peuvent se présenter :&lt;br /&gt;
*Une alerte ou plusieurs alertes rouges (bloquantes), s'affichent : l'utilisateur n'a pas la possibilité de surpasser ses alertes, il ne peut alors récupérer la clé :&lt;br /&gt;
&lt;br /&gt;
[[File:Alertes-bloquantes-en-ouverture-vol.png]]&lt;br /&gt;
&lt;br /&gt;
*Une alerte ou plusieurs alertes oranges (non-bloquantes), s'affichent : l'utilisateur a la possibilité de surpasser ses alertes, et ainsi de récupérer la clé :&lt;br /&gt;
&lt;br /&gt;
[[File:Alertes-non-bloquantes-en-ouverture-vol.png]]&lt;br /&gt;
&lt;br /&gt;
*Aucune alerte ne s'affiche, l'utilisateur se retrouve alors directement sur la page lui indiquant :&lt;br /&gt;
&lt;br /&gt;
[[File:Message_autorisation_libération_clé.png]]&lt;br /&gt;
&lt;br /&gt;
Une fois qu'il a cliqué sur '''LIBÉRER LA CLÉ''', il dispose de X secondes. Cette durée est paramétrable par OpenFlyers.&lt;br /&gt;
&lt;br /&gt;
*Lorsqu'il rentre de vol, l'utilisateur n'a plus qu'a retourner sur le formulaire de saisie de vol et à fermer son vol. La clé doit etre remise en place sur l'armoire pour fermer le vol.&lt;br /&gt;
&lt;br /&gt;
=Interface administrateur OpenFlyers=&lt;br /&gt;
==Activation et configuration de la gestion des armoires à clé==&lt;br /&gt;
Les protocoles OpenKey et PyOpenKey sont propriétaires d'OF, pour les configurer voir &lt;br /&gt;
[[Installation-armoire-à-clés#Configuration-OpenFlyers]]&lt;br /&gt;
&lt;br /&gt;
==Attribution des clés aux ressources/aéronefs==&lt;br /&gt;
''Dans le cas où c'est le logiciel OpenFlyers qui gère les clés.''&lt;br /&gt;
*'''Admin &amp;gt; Types de ressources &amp;gt; Actives'''&lt;br /&gt;
[[File:Liste_des_aéronefs.png]]&lt;br /&gt;
&lt;br /&gt;
Pour chaque aéronef concerné, il suffit d'attribuer un numéro et un nom de clé dans les champs correspondants. La validation de la saisie se fait automatiquement en cliquant hors du champ de saisie.&lt;br /&gt;
&lt;br /&gt;
=Protocole de dialogue XML-RPC entre OpenFlyers et le logiciel de gestion de l'armoire à clé=&lt;br /&gt;
Le dialogue avec le serveur XML-RPC d'OpenFlyers doit s'effectuer en '''HTTPS'''. Les commandes accessibles sont listées par un appel à ActionOnDemand.php&lt;br /&gt;
https://openflyers.com/yourURL/actionOnDemand.php&lt;br /&gt;
&lt;br /&gt;
==Demande de libération d'une clé==&lt;br /&gt;
&lt;br /&gt;
===Cas avec gestion des clés par OpenFlyers===&lt;br /&gt;
&lt;br /&gt;
*Lorsque qu'une clé doit être libérée, le navigateur envoie un message au logiciel de contrôle de l'armoire à clé par le protocole HTTPS sous la forme suivante :&lt;br /&gt;
https://127.0.0.1:4080/?sessid=e5f01p2oqh2vb36arisr8k5j87&amp;amp;amp;timeOut=10000&amp;amp;amp;key=1&amp;amp;amp;resource=2&amp;amp;amp;person=12;action='releaseKey'&lt;br /&gt;
&lt;br /&gt;
:*L'adresse IP (ici 127.0.0.1) et le port (ici 4080) sont fonction de la [[#Activation_et_configuration_de_la_gestion_des_armoires_à_clé|configuration de l'armoire à clé dans OpenFlyers]].&lt;br /&gt;
:*sessid contient le numéro de session en cours&lt;br /&gt;
:*timeout correspond au temps d'attente pour la prise d'une clé en millisecondes&lt;br /&gt;
:*key contient le numéro de la clé concernée&lt;br /&gt;
:*resource contient le numéro de la ressource concernée&lt;br /&gt;
:*person contient le numéro de l'utilisateur qui fait la demande&lt;br /&gt;
:*action est un mot clé désignant l'objet de la commande&lt;br /&gt;
:**release_key: ordre de libérer la clé&lt;br /&gt;
:**open_door: ordre d'ouvrir la porte&lt;br /&gt;
:**init_tags: ordre de lire les tags des clés&lt;br /&gt;
*Le logiciel de contrôle de l'armoire à clé doit alors envoyer une demande d'ordre au serveur OpenFlyers à l'adresse suivante https://openflyers.com/structure/ où il faut remplacer openflyers.com/structure par l'adresse de la plateforme OpenFlyers concernée, avec comme commande XML_RPC '''checkCommand (&amp;quot;e5f01p2oqh2vb36arisr8k5j87&amp;quot;,int(key))'''.&lt;br /&gt;
&lt;br /&gt;
*Le serveur OpenFlyers vérifie alors l'action demandée :&lt;br /&gt;
Pour release_key, il est vérifié :&lt;br /&gt;
#Que la clé est au bon format et existe. Lorsque la clé est validée, on passe à l'étape suivante sinon on retourne 0&lt;br /&gt;
#Que l'utilisateur faisant la demande est bien celui qui est connecté. Lorsque c'est le cas, on passe à l'étape suivante sinon on retourne 0&lt;br /&gt;
#Ensuite si l'utilisateur qui a passé la demande :&lt;br /&gt;
#*A le droit '''Gestion des clés''' (administrateur) alors on libère la clé sans condition (cela permet de libérer la clé sans contrôle) et on retourne 1&lt;br /&gt;
#*N'a pas le droit '''Gestion des clés''' (pilote) alors on vérifie s'il existe un vol ouvert qui remplit la double condition :&lt;br /&gt;
#**Vol attribué à l'utilisateur&lt;br /&gt;
#**Aéronef du vol associé à la demande de libération de la clé&lt;br /&gt;
#**Lorsque la double condition est remplie, on retourne 1 sinon 0&lt;br /&gt;
&lt;br /&gt;
*Le serveur retourne ensuite la réponse :&lt;br /&gt;
**1 dans le cas d'autorisation de libération de clé &lt;br /&gt;
**0 dans le cas contraire&lt;br /&gt;
&lt;br /&gt;
====Exemple de script en Python d'utilisation de la commande checkCommand avec gestion des clés====&lt;br /&gt;
&amp;lt;python&amp;gt;# load library&lt;br /&gt;
from twisted.web.xmlrpc import Proxy&lt;br /&gt;
from twisted.internet import reactor, ssl&lt;br /&gt;
 &lt;br /&gt;
def printValue(value):&lt;br /&gt;
    print repr(value)&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
 &lt;br /&gt;
def printError(error):&lt;br /&gt;
    print 'error', error&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
 &lt;br /&gt;
# URL of the XML-RPC server&lt;br /&gt;
proxy = Proxy('https://yourURL.xx/actionOnDemand.php')&lt;br /&gt;
 &lt;br /&gt;
# init array to send&lt;br /&gt;
sessid = &amp;quot;&amp;quot;&lt;br /&gt;
key_num = 1&lt;br /&gt;
 &lt;br /&gt;
# send to the XML-RPC server&lt;br /&gt;
proxy.callRemote('checkCommand', sessid, key_num).addCallbacks(printValue, printError)&lt;br /&gt;
reactor.run()&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce test peut être complété (pour obtenir une réponse &amp;quot;1&amp;quot;) en simulant une armoire à clé à l'aide d'un script PHP de la façon suivante :&lt;br /&gt;
*Installer un serveur local (par exemple [https://www.wampserver.com/ wampserver] sous Windows) de façon à avoir le port 127.0.0.1 qui lui est attribué&lt;br /&gt;
*Configurer la plateforme OpenFlyers de manière à gérer l'armoire à clé avec les éléments suivants :&lt;br /&gt;
**'''IP du PC contenant le logiciel de contrôle''' : 127.0.0.1&lt;br /&gt;
**'''Port du PC contenant le logiciel de contrôle''' : 80&lt;br /&gt;
*Configurer la plateforme OpenFlyers de manière à gérer les clés&lt;br /&gt;
*A la racine du répertoire www, mettre le script index.php suivant (on suppose que ce script est appelé par défaut lorsqu'on utilise l'URL https://127.0.0.1 ) :&lt;br /&gt;
&amp;lt;php&amp;gt;&amp;lt;?php &lt;br /&gt;
file_put_contents('test.txt', 'TEST', FILE_APPEND );&lt;br /&gt;
file_put_contents('test.txt', print_r($_REQUEST, true), FILE_APPEND );&lt;br /&gt;
?&amp;gt;&amp;lt;/php&amp;gt;&lt;br /&gt;
*Toujours à la racine du répertoire www, créer un fichier test.txt&lt;br /&gt;
Le script PHP écrira dans le fichier test.txt les variables transmises lors de la demande d'ouverture de l'armoire à clé :&lt;br /&gt;
&amp;lt;pre&amp;gt;TESTArray&lt;br /&gt;
(&lt;br /&gt;
    [sessid] =&amp;gt; j2eo92215nbef09borb74jftm1&lt;br /&gt;
    [key] =&amp;gt; 1&lt;br /&gt;
    [resource] =&amp;gt; 1&lt;br /&gt;
    [person] =&amp;gt; 1&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
*Il suffit alors de recopier la valeur de '''sessid''' et de '''key''' dans le script python de ce début de paragraphe et de le tester : il devrait renvoyer 1.&lt;br /&gt;
&lt;br /&gt;
===Cas sans gestion des clés par OpenFlyers===&lt;br /&gt;
&lt;br /&gt;
*Lorsque qu'une demande de vérification doit être réalisée, le navigateur envoie un message au logiciel de contrôle de l'armoire à clé par le protocole HTTPS sous la forme suivante :&lt;br /&gt;
https://127.0.0.1:4080/?sessid=e5f01p2oqh2vb36arisr8k5j87&amp;amp;amp;resource=2&amp;amp;amp;person=12&lt;br /&gt;
&lt;br /&gt;
:*L'adresse IP (ici 127.0.0.1) et le port (ici 4080) sont fonction de la [[#Activation_et_configuration_de_la_gestion_des_armoires_à_clé|configuration de l'armoire à clé dans OpenFlyers]].&lt;br /&gt;
:*sessid contient le numéro de session en cours&lt;br /&gt;
:*resource contient le numéro de la ressource concernée&lt;br /&gt;
:*person contient le numéro de l'utilisateur qui fait la demande&lt;br /&gt;
*Le logiciel de contrôle de l'armoire à clé doit alors envoyer une demande d'ordre au serveur OpenFlyers à l'adresse suivante https://openflyers.com/structure/actionOnDemand.php où il faut remplacer openflyers.com/structure par l'adresse de la plateforme OpenFlyers concernée, avec comme commande XML_RPC '''checkCommand (&amp;quot;e5f01p2oqh2vb36arisr8k5j87&amp;quot;)'''.&lt;br /&gt;
&lt;br /&gt;
*Le serveur OpenFlyers vérifie alors :&lt;br /&gt;
#Que l'utilisateur faisant la demande est bien celui qui est connecté. Lorsque c'est le cas, on passe à l'étape suivante sinon on retourne 0&lt;br /&gt;
#On vérifie s'il existe un vol ouvert qui remplit la double condition :&lt;br /&gt;
#*Vol attribué à l'utilisateur&lt;br /&gt;
#*Aéronef du vol associé à la demande de libération de la clé&lt;br /&gt;
#*Lorsque la double condition est remplie, on retourne 1 sinon 0&lt;br /&gt;
&lt;br /&gt;
*Le serveur retourne ensuite la réponse :&lt;br /&gt;
**1 dans le cas d'autorisation&lt;br /&gt;
**0 dans le cas contraire&lt;br /&gt;
&lt;br /&gt;
====Exemple de script en Python d'utilisation de la commande checkCommand sans gestion des clés====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;# load library&lt;br /&gt;
from twisted.web.xmlrpc import Proxy&lt;br /&gt;
from twisted.internet import reactor, ssl&lt;br /&gt;
 &lt;br /&gt;
def printValue(value):&lt;br /&gt;
    print repr(value)&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
 &lt;br /&gt;
def printError(error):&lt;br /&gt;
    print 'error', error&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
 &lt;br /&gt;
# URL of the XML-RPC server&lt;br /&gt;
proxy = Proxy('https://yourURL.xx/actionOnDemand.php')&lt;br /&gt;
 &lt;br /&gt;
# init array to send&lt;br /&gt;
sessid = &amp;quot;&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
# send to the XML-RPC server&lt;br /&gt;
proxy.callRemote('checkCommand', sessid).addCallbacks(printValue, printError)&lt;br /&gt;
reactor.run()&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce test peut être complété (pour obtenir une réponse &amp;quot;1&amp;quot;) en simulant une armoire à clé à l'aide d'un script PHP de la façon suivante :&lt;br /&gt;
*Installer un serveur local (par exemple [https://www.wampserver.com/ wampserver] sous Windows) de façon à avoir le port 127.0.0.1 qui lui est attribué&lt;br /&gt;
*Configurer la plateforme OpenFlyers de manière à gérer l'armoire à clé avec les éléments suivants :&lt;br /&gt;
**'''IP du PC contenant le logiciel de contrôle''' : 127.0.0.1&lt;br /&gt;
**'''Port du PC contenant le logiciel de contrôle''' : 80&lt;br /&gt;
*Configurer la plateforme OpenFlyers de manière à ne pas gérer les clés&lt;br /&gt;
*A la racine du répertoire www, mettre le script index.php suivant (on suppose que ce script est appelé par défaut lorsqu'on utilise l'URL https://127.0.0.1 ) :&lt;br /&gt;
&amp;lt;php&amp;gt;&amp;lt;?php &lt;br /&gt;
file_put_contents('test.txt', 'TEST', FILE_APPEND );&lt;br /&gt;
file_put_contents('test.txt', print_r($_REQUEST, true), FILE_APPEND );&lt;br /&gt;
?&amp;gt;&amp;lt;/php&amp;gt;&lt;br /&gt;
*Toujours à la racine du répertoire www, créer un fichier test.txt&lt;br /&gt;
Le script PHP écrira dans le fichier test.txt les variables transmises lors de la demande d'ouverture de l'armoire à clé :&lt;br /&gt;
&amp;lt;pre&amp;gt;TESTArray&lt;br /&gt;
(&lt;br /&gt;
    [sessid] =&amp;gt; j2eo92215nbef09borb74jftm1&lt;br /&gt;
    [resource] =&amp;gt; 1&lt;br /&gt;
    [person] =&amp;gt; 1&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
*Il suffit alors de recopier la valeur de '''sessid''' dans le script python de ce début de paragraphe et de le tester : il devrait renvoyer 1.&lt;br /&gt;
&lt;br /&gt;
==Modification de l'état d'une clé==&lt;br /&gt;
''Applicable dans le cas où le protocole PyOpenKeys2 gère les clés.''&lt;br /&gt;
*Le logiciel de contrôle de l'armoire à clés doit envoyer un ordre '''notify([1,0,1,1,1,1,0,0], &amp;quot;passphrase&amp;quot;)''' avec comme paramètre un tableau chronologique des clés ayant pour valeur leur état &lt;br /&gt;
''Applicable dans le cas où le protocole PyOpenKeys4 gère les clés.''&lt;br /&gt;
*Le logiciel de contrôle de l'armoire à clés doit envoyer un ordre '''notify2([[1,1],[2,0],[3,1],[4,1],[5,1],[6,1],[7,0],[8,0]], &amp;quot;passphrase&amp;quot;)''' avec comme paramètre un tableau de tableau avec le numéro de la clé suivi de son état&lt;br /&gt;
**1 = interrupteur de présence de clé fermé = clé absente de l'armoire&lt;br /&gt;
**0 = interrupteur de présence de clé ouvert = clé présente dans l'armoire&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===Exemple de script en Python pour la commande notify===&lt;br /&gt;
Nécessite les librairies Twisted et OpenSSL&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;# load library&lt;br /&gt;
from twisted.web.xmlrpc import Proxy&lt;br /&gt;
from twisted.internet import reactor, ssl&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def printValue(value):&lt;br /&gt;
    print repr(value)&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
&lt;br /&gt;
def printError(error):&lt;br /&gt;
    print 'error', error&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
&lt;br /&gt;
# URL of the XML-RPC server&lt;br /&gt;
proxy = Proxy('https://yourURL.xx/actionOnDemand.php')&lt;br /&gt;
&lt;br /&gt;
# init passphrase&lt;br /&gt;
passphrase = 'SDjklsdiuQSIPO23879ZERK2098ZL2908DFZLK'&lt;br /&gt;
&lt;br /&gt;
# Initiate number of key&lt;br /&gt;
KEY_NUMBER = 16&lt;br /&gt;
&lt;br /&gt;
# init array to send&lt;br /&gt;
state = random.randint(0,1)&lt;br /&gt;
&lt;br /&gt;
if KEY_NUMBER &amp;gt; 8:&lt;br /&gt;
    # Test notify2&lt;br /&gt;
    status = [[d+1,0] for d in range(KEY_NUMBER)]&lt;br /&gt;
    for i in range(KEY_NUMBER):&lt;br /&gt;
        status[i] = [i+1,state]&lt;br /&gt;
        # Alternate 0 and 1 for test&lt;br /&gt;
        state = 0 if state == 1 else 1&lt;br /&gt;
else:&lt;br /&gt;
    # Test notify&lt;br /&gt;
    for i in range(KEY_NUMBER):&lt;br /&gt;
        status.append(state)&lt;br /&gt;
        # Alternate 0 and 1 for test&lt;br /&gt;
        state = 0 if state == 1 else 1&lt;br /&gt;
&lt;br /&gt;
# send to the XML-RPC server&lt;br /&gt;
print &amp;quot;Status sequence : %s&amp;quot; % status&lt;br /&gt;
if KEY_NUMBER&amp;lt;9:&lt;br /&gt;
    proxy.callRemote('notify', status, passphrase).addCallbacks(printValue, printError)&lt;br /&gt;
else:&lt;br /&gt;
    proxy.callRemote('notify2', status, passphrase).addCallbacks(printValue, printError)&lt;br /&gt;
reactor.run()&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
''Nota : to test change the number of key : up to 8 the software use '''notify()''', beyond it uses '''notify2()'''&lt;br /&gt;
&lt;br /&gt;
Cela retournera 0 en cas d'anomalie ou si la passphase transmise n'est pas correcte, 1 si la table des clés a été correctement mise à jour.&lt;br /&gt;
&lt;br /&gt;
==Fermeture automatique d'un vol==&lt;br /&gt;
&lt;br /&gt;
Le logiciel de contrôle de l'armoire à clé doit envoyer un ordre '''closeFlight(&amp;quot;passphrase&amp;quot;, &amp;quot;id de ressource&amp;quot;)''' avec comme paramètre un passphrase et l'id qui va entraîner la fermeture du vol effectué sur cette ressource si un vol avait été ouvert et que la &amp;quot;Fermeture automatique des&lt;br /&gt;
vols au retour de la clé&amp;quot; soit activée. La commande retournera comme réponse une structure JSON pour déterminer si la fermeture du vol s'est bien réalisée ou non et qu'il n'y a pas eu d'erreur.&lt;br /&gt;
&lt;br /&gt;
Réponse quand la vérification du passphrase est incorrecte, ce qui a entraîné la non-fermeture du vol :&lt;br /&gt;
&amp;lt;javascript&amp;gt;{[&lt;br /&gt;
    ack : 0&lt;br /&gt;
]}&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Réponse quand la vérification du passphrase est correcte et que la demande de fermeture du vol s'est bien réalisée :&lt;br /&gt;
&amp;lt;javascript&amp;gt;{[&lt;br /&gt;
    ack : 1&lt;br /&gt;
]}&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Réponse quand la vérification du passphrase est correcte et que la demande de fermeture du vol ne s'est pas bien réalisée suite à une erreur :&lt;br /&gt;
&amp;lt;javascript&amp;gt;{[&lt;br /&gt;
    ack : 1,&lt;br /&gt;
    error : 'Message d\'erreur ...'&lt;br /&gt;
]}&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Script d'exemple pour closeFlight===&lt;br /&gt;
&amp;lt;python&amp;gt;# load library&lt;br /&gt;
from twisted.web.xmlrpc import Proxy&lt;br /&gt;
from twisted.internet import reactor, ssl&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def printValue(value):&lt;br /&gt;
    print repr(value)&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
&lt;br /&gt;
def printError(error):&lt;br /&gt;
    print 'error', error&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
&lt;br /&gt;
# URL of the XML-RPC server&lt;br /&gt;
proxy = Proxy('https://yourURL.xx/actionOnDemand.php')&lt;br /&gt;
&lt;br /&gt;
# Id of resource which needs a flight closing&lt;br /&gt;
resource_id = 1&lt;br /&gt;
&lt;br /&gt;
# init passphrase&lt;br /&gt;
passphrase = 'SDjklsdiuQSIPO23879ZERK2098ZL2908DFZLK'&lt;br /&gt;
&lt;br /&gt;
# send to the XML-RPC server&lt;br /&gt;
proxy.callRemote('closeFlight', resource_id, passphrase).addCallbacks(printValue, printError)&lt;br /&gt;
reactor.run()&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Exemple de script en Python de logiciel de contrôle d'une armoire==&lt;br /&gt;
&amp;lt;python&amp;gt;#!/usr/bin/python&lt;br /&gt;
import xmlrpclib, time, dummy_proto, hashlib&lt;br /&gt;
from twisted.internet import reactor, task, threads, ssl&lt;br /&gt;
from twisted.application import internet, service&lt;br /&gt;
from twisted.internet.protocol import Protocol, ClientCreator, ReconnectingClientFactory&lt;br /&gt;
from twisted.web import resource, server&lt;br /&gt;
&lt;br /&gt;
# Port from which the OF client contact OpenKeys service&lt;br /&gt;
SERVICE_PORT=4080 &lt;br /&gt;
# IP address of the OpenKeys service&lt;br /&gt;
SERVICE_HOST=&amp;quot;192.168.0.200&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# IP address of the key cabinet&lt;br /&gt;
KEYS_ADDR='192.168.0.201'&lt;br /&gt;
# Port from which OpenKeys service contacts the key cabinet&lt;br /&gt;
KEYS_PORT=6002&lt;br /&gt;
#Time to release the key&lt;br /&gt;
KEY_RELEASE_DURATION=15&lt;br /&gt;
&lt;br /&gt;
# sha224 passwords&lt;br /&gt;
PASSWORDS=('847bed9bc354e7e47bc5350a3b3aaf6124f5748224a3c7ad79586c3c')&lt;br /&gt;
&lt;br /&gt;
# init passphrase&lt;br /&gt;
passphrase = 'SDjklsdiuQSIPO23879ZERK2098ZL2908DFZLK'&lt;br /&gt;
&lt;br /&gt;
OF_XMLRPC_URL=&amp;quot;https://openflyers.com/structure/actionOnDemand.php&amp;quot;&lt;br /&gt;
&lt;br /&gt;
DEBUG=False&lt;br /&gt;
&lt;br /&gt;
class dummyProtocol(Protocol):&lt;br /&gt;
	def __init__(self, rpc_server):&lt;br /&gt;
		self.rpc_server=rpc_server&lt;br /&gt;
		self.lc = None&lt;br /&gt;
&lt;br /&gt;
	def connectionMade(self):&lt;br /&gt;
		if not self.lc:&lt;br /&gt;
			# update status every 10 minutes&lt;br /&gt;
			self.lc = task.LoopingCall(self.updateStatus)&lt;br /&gt;
			self.lc.start(600)&lt;br /&gt;
&lt;br /&gt;
	def dataReceived(self, data):&lt;br /&gt;
		msg=dummy_proto.dummy_message.newFromData(data)&lt;br /&gt;
		if DEBUG: msg.display()&lt;br /&gt;
		try:&lt;br /&gt;
			if type(msg)==dummyproto.dummy_ONOFF_Control_Response:&lt;br /&gt;
				response = self.rpc_server.notify(msg.getKeysStatus(),passphrase)&lt;br /&gt;
		except Exception, err:&lt;br /&gt;
			if DEBUG: print &amp;quot;error: &amp;quot;, err&lt;br /&gt;
			pass # ignore&lt;br /&gt;
&lt;br /&gt;
	def updateStatus(self):&lt;br /&gt;
		msg = dummy_proto.dummy_State_Request()&lt;br /&gt;
		self.transport.write(msg.build_message())&lt;br /&gt;
	&lt;br /&gt;
	def send(self, dummy_data):&lt;br /&gt;
		self.transport.write(dummy_data.build_message())&lt;br /&gt;
&lt;br /&gt;
class dummyClientFactory(ReconnectingClientFactory):&lt;br /&gt;
	def __init__(self, rpc_server):&lt;br /&gt;
		self.rpc_server = rpc_server&lt;br /&gt;
&lt;br /&gt;
	def buildProtocol(self, addr):&lt;br /&gt;
		self.resetDelay()&lt;br /&gt;
		self.protocol = dummyProtocol(self.rpc_server)&lt;br /&gt;
		return self.protocol&lt;br /&gt;
&lt;br /&gt;
	def clientConnectionLost(self, connector, reason):&lt;br /&gt;
		ReconnectingClientFactory.clientConnectionLost(self, connector, reason)&lt;br /&gt;
		connector.connect()&lt;br /&gt;
&lt;br /&gt;
	def clientConnectionFailed(self, connector, reason):&lt;br /&gt;
		if DEBUG: print 'Connection failed. Reason:', reason&lt;br /&gt;
		ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)&lt;br /&gt;
&lt;br /&gt;
	# blocking method ! must be run in a new thread&lt;br /&gt;
	def release_key(self, key_num, timeOur):&lt;br /&gt;
		m = dummy_proto.dummy_ONOFF_Control()&lt;br /&gt;
		m.setON(key_num)&lt;br /&gt;
		self.protocol.send(m)&lt;br /&gt;
		time.sleep(timeOut)&lt;br /&gt;
		m.setOFF(key_num)&lt;br /&gt;
		self.protocol.send(m)&lt;br /&gt;
		return key_num&lt;br /&gt;
&lt;br /&gt;
class WebResource(resource.Resource):&lt;br /&gt;
	def __init__(self, rpc_server, dummy_client_factory):&lt;br /&gt;
		self.rpc_server = rpc_server&lt;br /&gt;
		self.dummy_client_factory = dummy_client_factory&lt;br /&gt;
		resource.Resource.__init__(self)&lt;br /&gt;
		self.keys_webcontrol_state = [0,0,0,0,0,0,0,0,0,0]&lt;br /&gt;
		&lt;br /&gt;
	def getChild(self, name, request):&lt;br /&gt;
		return self&lt;br /&gt;
&lt;br /&gt;
	def render(self, request):&lt;br /&gt;
		reponse = 0 # NOK par defaut&lt;br /&gt;
		key_num = 0&lt;br /&gt;
		try:&lt;br /&gt;
			sessid = request.args.get('sessid', [&amp;quot;&amp;quot;])[0]&lt;br /&gt;
			password = request.args.get('password', [&amp;quot;&amp;quot;])[0]&lt;br /&gt;
			key_num = int(request.args.get('key', [&amp;quot;0&amp;quot;])[0])&lt;br /&gt;
			response = 0&lt;br /&gt;
			if password:&lt;br /&gt;
                                if hashlib.sha224(password).hexdigest() in PASSWORDS:&lt;br /&gt;
                                        timeOut   = KEY_RELEASE_DURATION&lt;br /&gt;
                                        response_XMLRPC = 1&lt;br /&gt;
                        else:&lt;br /&gt;
                                timeOut   = int(request.args.get('timeout', [&amp;quot;0&amp;quot;])[0])&lt;br /&gt;
                                response = self.rpc_server.checkCommand(sessid, key_num)&lt;br /&gt;
		except Exception, err:&lt;br /&gt;
			if DEBUG: print &amp;quot;error: &amp;quot;, err&lt;br /&gt;
			return &amp;quot;NOK:bad request&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		if response == 1:&lt;br /&gt;
			# Don't try to release a key that is being released&lt;br /&gt;
			if self.keys_webcontrol_state[key_num-1]: return &amp;quot;OK:already released&amp;quot;&lt;br /&gt;
			self.keys_webcontrol_state[key_num-1] = 1&lt;br /&gt;
			d = threads.deferToThread(self.dummy_client_factory.release_key, key_num, timeOut)&lt;br /&gt;
			d.addCallback(self.unset_webcontrol_state)&lt;br /&gt;
			return &amp;quot;OK:releasing key...&amp;quot;&lt;br /&gt;
		else:&lt;br /&gt;
			return &amp;quot;NOK:permission refused&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	def unset_webcontrol_state(self, key_num):&lt;br /&gt;
		self.keys_webcontrol_state[key_num-1] = 0&lt;br /&gt;
&lt;br /&gt;
class OpenKeysService(service.Service):&lt;br /&gt;
	def __init__(self):&lt;br /&gt;
		rpc_server=xmlrpclib.Server(OF_XMLRPC_URL);&lt;br /&gt;
		self.dummy_client_factory = dummyClientFactory(rpc_server)&lt;br /&gt;
		self.web_resource = WebResource(rpc_server, self.dummy_client_factory)&lt;br /&gt;
		&lt;br /&gt;
	def getdummyClientFactory(self):&lt;br /&gt;
		return self.dummy_client_factory&lt;br /&gt;
&lt;br /&gt;
	def getWebResource(self):&lt;br /&gt;
		return self.web_resource&lt;br /&gt;
&lt;br /&gt;
application = service.Application('openkeys')&lt;br /&gt;
f = OpenKeysService()&lt;br /&gt;
serviceCollection = service.IServiceCollection(application)&lt;br /&gt;
internet.TCPClient(KEYS_ADDR, KEYS_PORT, f.getdummyClientFactory()&lt;br /&gt;
				   ).setServiceParent(serviceCollection)&lt;br /&gt;
internet.TCPServer(SERVICE_PORT, server.Site(f.getWebResource())&lt;br /&gt;
				   ).setServiceParent(serviceCollection)&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Maquette de script actionOnDemand.php côté serveur recevant les appels du logiciel de contrôle de l'armoire==&lt;br /&gt;
Ce script nécessite la bibliothèque PEAR [http://pear.php.net/package/XML_RPC2 XML_RPC2].&lt;br /&gt;
&lt;br /&gt;
Pour les tests, il suffit de modifier la valeur de la variable $weDontWant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;php&amp;gt;&amp;lt;?php&lt;br /&gt;
include 'XML/RPC2/Server.php';&lt;br /&gt;
&lt;br /&gt;
class OpenKeysGateway {&lt;br /&gt;
    /**&lt;br /&gt;
     * Update the status of the keys&lt;br /&gt;
     *&lt;br /&gt;
     * @param array $status Status of keys&lt;br /&gt;
     * @return integer 1 if ok, 0 else&lt;br /&gt;
     */&lt;br /&gt;
    public static function notify($status) {&lt;br /&gt;
        $logmsg = &amp;quot;&amp;quot;;&lt;br /&gt;
        foreach ($status as $key_num_from_zero =&amp;gt; $key_pres) {&lt;br /&gt;
            if (!is_numeric($key_pres) || intval($key_pres)!=$key_pres || $key_pres &amp;lt; 0 || $key_pres &amp;gt; 1) continue;&lt;br /&gt;
            if (!is_numeric($key_num_from_zero) || intval($key_num_from_zero)!=$key_num_from_zero &lt;br /&gt;
                || $key_num_from_zero &amp;lt; 0 || $key_num_from_zero &amp;gt; 9) continue;&lt;br /&gt;
            $logmsg .= &amp;quot;&amp;quot;.($key_num_from_zero+1).&amp;quot;:&amp;quot;.$key_pres.&amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        file_put_contents('test.txt', &amp;quot;key notify :&amp;quot;.$logmsg, FILE_APPEND );&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Check if user is able to release the key 'key_num'&lt;br /&gt;
     *&lt;br /&gt;
     * @param string $sessid PHPSESSID of a connected user&lt;br /&gt;
     * @param integer $key_num number of the key to release&lt;br /&gt;
     * @return integer 0:NOK, 1:OK&lt;br /&gt;
     */&lt;br /&gt;
    public static function checkCommand($sessid, $key_num) {&lt;br /&gt;
        /* sanitize input */&lt;br /&gt;
        if (!is_numeric($key_num) || intval($key_num)!=$key_num || $key_num &amp;lt; 1 || $key_num &amp;gt; 10) {&lt;br /&gt;
            return 0;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $weDontWant = 1;&lt;br /&gt;
&lt;br /&gt;
        if ($weDontWant) {&lt;br /&gt;
            file_put_contents('test.txt', &amp;quot;$key_num has no associated airborne aircraft&amp;quot;, FILE_APPEND );&lt;br /&gt;
            return 0;&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
            file_put_contents('test.txt', &amp;quot;granted key: &amp;quot;.$key_num.&amp;quot;:permission granted&amp;quot;, FILE_APPEND );&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$options = array(&lt;br /&gt;
    'autoDocument' =&amp;gt; true,&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
// dirty hack to get things work !&lt;br /&gt;
$GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents('php://input');&lt;br /&gt;
&lt;br /&gt;
$server = XML_RPC2_Server::create('OpenKeysGateway', $options);&lt;br /&gt;
$server-&amp;gt;handleCall();&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&amp;lt;/php&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jtremblet</name></author>
	</entry>
	<entry>
		<id>https://doc4-fr-mirror.openflyers.com/index.php?title=Interfa%C3%A7age-OpenFlyers-et-armoire-%C3%A0-cl%C3%A9s&amp;diff=13016</id>
		<title>Interfaçage OpenFlyers et armoire à clés</title>
		<link rel="alternate" type="text/html" href="https://doc4-fr-mirror.openflyers.com/index.php?title=Interfa%C3%A7age-OpenFlyers-et-armoire-%C3%A0-cl%C3%A9s&amp;diff=13016"/>
		<updated>2024-12-10T10:04:23Z</updated>

		<summary type="html">&lt;p&gt;Jtremblet: /* Activation et configuration de la gestion des armoires à clé */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
=Présentation=&lt;br /&gt;
L'objet de cette page est de décrire le protocole d'interfaçage avec toute solution d'armoire à clés tiers. Pour les armoires à clés commercialisées par OpenFlyers, il faut se référer à la [[Contrôle des accès|documentation sur le contrôle d'accès]].&lt;br /&gt;
&lt;br /&gt;
Le protocole repose sur le principe que l'interfaçage est réalisé par un logiciel de contrôle de l'armoire à clé sur un PC ou une solution embarquée et qui dispose d'un accès à internet lui permettant de communiquer avec OpenFlyers. La communication est synchrone.&lt;br /&gt;
&lt;br /&gt;
=Interface utilisateur OpenFlyers=&lt;br /&gt;
L'utilisateur ouvre un vol dans OpenFlyers :&lt;br /&gt;
&lt;br /&gt;
[[File:Menu-contextuel-ouverture-de-vol.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Il se retrouve sur le formulaire de saisie du vol en mode Départ en vol:&lt;br /&gt;
&lt;br /&gt;
[[File:Formulaire-ouverture-de-vol.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lorsqu'il clique sur le bouton de validation, 3 cas peuvent se présenter :&lt;br /&gt;
*Une alerte ou plusieurs alertes rouges (bloquantes), s'affichent : l'utilisateur n'a pas la possibilité de surpasser ses alertes, il ne peut alors récupérer la clé :&lt;br /&gt;
&lt;br /&gt;
[[File:Alertes-bloquantes-en-ouverture-vol.png]]&lt;br /&gt;
&lt;br /&gt;
*Une alerte ou plusieurs alertes oranges (non-bloquantes), s'affichent : l'utilisateur a la possibilité de surpasser ses alertes, et ainsi de récupérer la clé :&lt;br /&gt;
&lt;br /&gt;
[[File:Alertes-non-bloquantes-en-ouverture-vol.png]]&lt;br /&gt;
&lt;br /&gt;
*Aucune alerte ne s'affiche, l'utilisateur se retrouve alors directement sur la page lui indiquant :&lt;br /&gt;
&lt;br /&gt;
[[File:Message_autorisation_libération_clé.png]]&lt;br /&gt;
&lt;br /&gt;
Une fois qu'il a cliqué sur '''LIBÉRER LA CLÉ''', il dispose de X secondes. Cette durée est paramétrable par OpenFlyers.&lt;br /&gt;
&lt;br /&gt;
*Lorsqu'il rentre de vol, l'utilisateur n'a plus qu'a retourner sur le formulaire de saisie de vol et à fermer son vol. La clé doit etre remise en place sur l'armoire pour fermer le vol.&lt;br /&gt;
&lt;br /&gt;
=Interface administrateur OpenFlyers=&lt;br /&gt;
==Activation et configuration de la gestion des armoires à clé==&lt;br /&gt;
Les protocoles OpenKey et PyOpenKey sont propriétaires d'OF, pour les configurer voir &lt;br /&gt;
[[Installation-armoire-à-clés#Configuration-OpenFlyers]]&lt;br /&gt;
&lt;br /&gt;
==Attribution des clés aux ressources/aéronefs==&lt;br /&gt;
''Dans le cas où c'est le logiciel OpenFlyers qui gère les clés.''&lt;br /&gt;
*'''Admin &amp;gt; Types de ressources &amp;gt; Actives'''&lt;br /&gt;
[[File:Liste_des_aéronefs.png]]&lt;br /&gt;
&lt;br /&gt;
Pour chaque aéronef concerné, il suffit d'attribuer un numéro et un nom de clé dans les champs correspondants. La validation de la saisie se fait automatiquement en cliquant hors du champ de saisie.&lt;br /&gt;
&lt;br /&gt;
=Protocole de dialogue XML-RPC entre OpenFlyers et le logiciel de gestion de l'armoire à clé=&lt;br /&gt;
Le dialogue avec le serveur XML-RPC d'OpenFlyers doit s'effectuer en '''HTTPS'''. Les commandes accessibles sont listées par un appel à ActionOnDemand.php&lt;br /&gt;
https://openflyers.com/yourURL/actionOnDemand.php&lt;br /&gt;
&lt;br /&gt;
==Demande de libération d'une clé==&lt;br /&gt;
&lt;br /&gt;
===Cas avec gestion des clés par OpenFlyers===&lt;br /&gt;
&lt;br /&gt;
*Lorsque qu'une clé doit être libérée, le navigateur envoie un message au logiciel de contrôle de l'armoire à clé par le protocole HTTPS sous la forme suivante :&lt;br /&gt;
https://127.0.0.1:4080/?sessid=e5f01p2oqh2vb36arisr8k5j87&amp;amp;amp;timeOut=10000&amp;amp;amp;key=1&amp;amp;amp;resource=2&amp;amp;amp;person=12;action='releaseKey'&lt;br /&gt;
&lt;br /&gt;
:*L'adresse IP (ici 127.0.0.1) et le port (ici 4080) sont fonction de la [[#Activation_et_configuration_de_la_gestion_des_armoires_à_clé|configuration de l'armoire à clé dans OpenFlyers]].&lt;br /&gt;
:*sessid contient le numéro de session en cours&lt;br /&gt;
:*timeout correspond au temps d'attente pour la prise d'une clé en millisecondes&lt;br /&gt;
:*key contient le numéro de la clé concernée&lt;br /&gt;
:*resource contient le numéro de la ressource concernée&lt;br /&gt;
:*person contient le numéro de l'utilisateur qui fait la demande&lt;br /&gt;
:*action est un mot clé désignant l'objet de la commande&lt;br /&gt;
:**release_key: ordre de libérer la clé&lt;br /&gt;
:**open_door: ordre d'ouvrir la porte&lt;br /&gt;
:**init_tags: ordre de lire les tags des clés&lt;br /&gt;
*Le logiciel de contrôle de l'armoire à clé doit alors envoyer une demande d'ordre au serveur OpenFlyers à l'adresse suivante https://openflyers.com/structure/ où il faut remplacer openflyers.com/structure par l'adresse de la plateforme OpenFlyers concernée, avec comme commande XML_RPC '''checkCommand (&amp;quot;e5f01p2oqh2vb36arisr8k5j87&amp;quot;,int(key))'''.&lt;br /&gt;
&lt;br /&gt;
*Le serveur OpenFlyers vérifie alors l'action demandée :&lt;br /&gt;
Pour release_key, il est vérifié :&lt;br /&gt;
#Que la clé est au bon format et existe. Lorsque la clé est validée, on passe à l'étape suivante sinon on retourne 0&lt;br /&gt;
#Que l'utilisateur faisant la demande est bien celui qui est connecté. Lorsque c'est le cas, on passe à l'étape suivante sinon on retourne 0&lt;br /&gt;
#Ensuite si l'utilisateur qui a passé la demande :&lt;br /&gt;
#*A le droit '''Gestion des clés''' (administrateur) alors on libère la clé sans condition (cela permet de libérer la clé sans contrôle) et on retourne 1&lt;br /&gt;
#*N'a pas le droit '''Gestion des clés''' (pilote) alors on vérifie s'il existe un vol ouvert qui remplit la double condition :&lt;br /&gt;
#**Vol attribué à l'utilisateur&lt;br /&gt;
#**Aéronef du vol associé à la demande de libération de la clé&lt;br /&gt;
#**Lorsque la double condition est remplie, on retourne 1 sinon 0&lt;br /&gt;
&lt;br /&gt;
*Le serveur retourne ensuite la réponse :&lt;br /&gt;
**1 dans le cas d'autorisation de libération de clé &lt;br /&gt;
**0 dans le cas contraire&lt;br /&gt;
&lt;br /&gt;
====Exemple de script en Python d'utilisation de la commande checkCommand avec gestion des clés====&lt;br /&gt;
&amp;lt;python&amp;gt;# load library&lt;br /&gt;
from twisted.web.xmlrpc import Proxy&lt;br /&gt;
from twisted.internet import reactor, ssl&lt;br /&gt;
 &lt;br /&gt;
def printValue(value):&lt;br /&gt;
    print repr(value)&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
 &lt;br /&gt;
def printError(error):&lt;br /&gt;
    print 'error', error&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
 &lt;br /&gt;
# URL of the XML-RPC server&lt;br /&gt;
proxy = Proxy('https://yourURL.xx/actionOnDemand.php')&lt;br /&gt;
 &lt;br /&gt;
# init array to send&lt;br /&gt;
sessid = &amp;quot;&amp;quot;&lt;br /&gt;
key_num = 1&lt;br /&gt;
 &lt;br /&gt;
# send to the XML-RPC server&lt;br /&gt;
proxy.callRemote('checkCommand', sessid, key_num).addCallbacks(printValue, printError)&lt;br /&gt;
reactor.run()&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce test peut être complété (pour obtenir une réponse &amp;quot;1&amp;quot;) en simulant une armoire à clé à l'aide d'un script PHP de la façon suivante :&lt;br /&gt;
*Installer un serveur local (par exemple [https://www.wampserver.com/ wampserver] sous Windows) de façon à avoir le port 127.0.0.1 qui lui est attribué&lt;br /&gt;
*Configurer la plateforme OpenFlyers de manière à gérer l'armoire à clé avec les éléments suivants :&lt;br /&gt;
**'''IP du PC contenant le logiciel de contrôle''' : 127.0.0.1&lt;br /&gt;
**'''Port du PC contenant le logiciel de contrôle''' : 80&lt;br /&gt;
*Configurer la plateforme OpenFlyers de manière à gérer les clés&lt;br /&gt;
*A la racine du répertoire www, mettre le script index.php suivant (on suppose que ce script est appelé par défaut lorsqu'on utilise l'URL https://127.0.0.1 ) :&lt;br /&gt;
&amp;lt;php&amp;gt;&amp;lt;?php &lt;br /&gt;
file_put_contents('test.txt', 'TEST', FILE_APPEND );&lt;br /&gt;
file_put_contents('test.txt', print_r($_REQUEST, true), FILE_APPEND );&lt;br /&gt;
?&amp;gt;&amp;lt;/php&amp;gt;&lt;br /&gt;
*Toujours à la racine du répertoire www, créer un fichier test.txt&lt;br /&gt;
Le script PHP écrira dans le fichier test.txt les variables transmises lors de la demande d'ouverture de l'armoire à clé :&lt;br /&gt;
&amp;lt;pre&amp;gt;TESTArray&lt;br /&gt;
(&lt;br /&gt;
    [sessid] =&amp;gt; j2eo92215nbef09borb74jftm1&lt;br /&gt;
    [key] =&amp;gt; 1&lt;br /&gt;
    [resource] =&amp;gt; 1&lt;br /&gt;
    [person] =&amp;gt; 1&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
*Il suffit alors de recopier la valeur de '''sessid''' et de '''key''' dans le script python de ce début de paragraphe et de le tester : il devrait renvoyer 1.&lt;br /&gt;
&lt;br /&gt;
===Cas sans gestion des clés par OpenFlyers===&lt;br /&gt;
&lt;br /&gt;
*Lorsque qu'une demande de vérification doit être réalisée, le navigateur envoie un message au logiciel de contrôle de l'armoire à clé par le protocole HTTPS sous la forme suivante :&lt;br /&gt;
https://127.0.0.1:4080/?sessid=e5f01p2oqh2vb36arisr8k5j87&amp;amp;amp;resource=2&amp;amp;amp;person=12&lt;br /&gt;
&lt;br /&gt;
:*L'adresse IP (ici 127.0.0.1) et le port (ici 4080) sont fonction de la [[#Activation_et_configuration_de_la_gestion_des_armoires_à_clé|configuration de l'armoire à clé dans OpenFlyers]].&lt;br /&gt;
:*sessid contient le numéro de session en cours&lt;br /&gt;
:*resource contient le numéro de la ressource concernée&lt;br /&gt;
:*person contient le numéro de l'utilisateur qui fait la demande&lt;br /&gt;
*Le logiciel de contrôle de l'armoire à clé doit alors envoyer une demande d'ordre au serveur OpenFlyers à l'adresse suivante https://openflyers.com/structure/actionOnDemand.php où il faut remplacer openflyers.com/structure par l'adresse de la plateforme OpenFlyers concernée, avec comme commande XML_RPC '''checkCommand (&amp;quot;e5f01p2oqh2vb36arisr8k5j87&amp;quot;)'''.&lt;br /&gt;
&lt;br /&gt;
*Le serveur OpenFlyers vérifie alors :&lt;br /&gt;
#Que l'utilisateur faisant la demande est bien celui qui est connecté. Lorsque c'est le cas, on passe à l'étape suivante sinon on retourne 0&lt;br /&gt;
#On vérifie s'il existe un vol ouvert qui remplit la double condition :&lt;br /&gt;
#*Vol attribué à l'utilisateur&lt;br /&gt;
#*Aéronef du vol associé à la demande de libération de la clé&lt;br /&gt;
#*Lorsque la double condition est remplie, on retourne 1 sinon 0&lt;br /&gt;
&lt;br /&gt;
*Le serveur retourne ensuite la réponse :&lt;br /&gt;
**1 dans le cas d'autorisation&lt;br /&gt;
**0 dans le cas contraire&lt;br /&gt;
&lt;br /&gt;
====Exemple de script en Python d'utilisation de la commande checkCommand sans gestion des clés====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;# load library&lt;br /&gt;
from twisted.web.xmlrpc import Proxy&lt;br /&gt;
from twisted.internet import reactor, ssl&lt;br /&gt;
 &lt;br /&gt;
def printValue(value):&lt;br /&gt;
    print repr(value)&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
 &lt;br /&gt;
def printError(error):&lt;br /&gt;
    print 'error', error&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
 &lt;br /&gt;
# URL of the XML-RPC server&lt;br /&gt;
proxy = Proxy('https://yourURL.xx/actionOnDemand.php')&lt;br /&gt;
 &lt;br /&gt;
# init array to send&lt;br /&gt;
sessid = &amp;quot;&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
# send to the XML-RPC server&lt;br /&gt;
proxy.callRemote('checkCommand', sessid).addCallbacks(printValue, printError)&lt;br /&gt;
reactor.run()&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce test peut être complété (pour obtenir une réponse &amp;quot;1&amp;quot;) en simulant une armoire à clé à l'aide d'un script PHP de la façon suivante :&lt;br /&gt;
*Installer un serveur local (par exemple [https://www.wampserver.com/ wampserver] sous Windows) de façon à avoir le port 127.0.0.1 qui lui est attribué&lt;br /&gt;
*Configurer la plateforme OpenFlyers de manière à gérer l'armoire à clé avec les éléments suivants :&lt;br /&gt;
**'''IP du PC contenant le logiciel de contrôle''' : 127.0.0.1&lt;br /&gt;
**'''Port du PC contenant le logiciel de contrôle''' : 80&lt;br /&gt;
*Configurer la plateforme OpenFlyers de manière à ne pas gérer les clés&lt;br /&gt;
*A la racine du répertoire www, mettre le script index.php suivant (on suppose que ce script est appelé par défaut lorsqu'on utilise l'URL https://127.0.0.1 ) :&lt;br /&gt;
&amp;lt;php&amp;gt;&amp;lt;?php &lt;br /&gt;
file_put_contents('test.txt', 'TEST', FILE_APPEND );&lt;br /&gt;
file_put_contents('test.txt', print_r($_REQUEST, true), FILE_APPEND );&lt;br /&gt;
?&amp;gt;&amp;lt;/php&amp;gt;&lt;br /&gt;
*Toujours à la racine du répertoire www, créer un fichier test.txt&lt;br /&gt;
Le script PHP écrira dans le fichier test.txt les variables transmises lors de la demande d'ouverture de l'armoire à clé :&lt;br /&gt;
&amp;lt;pre&amp;gt;TESTArray&lt;br /&gt;
(&lt;br /&gt;
    [sessid] =&amp;gt; j2eo92215nbef09borb74jftm1&lt;br /&gt;
    [resource] =&amp;gt; 1&lt;br /&gt;
    [person] =&amp;gt; 1&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
*Il suffit alors de recopier la valeur de '''sessid''' dans le script python de ce début de paragraphe et de le tester : il devrait renvoyer 1.&lt;br /&gt;
&lt;br /&gt;
==Modification de l'état d'une clé==&lt;br /&gt;
''Applicable dans le cas où le protocole PyOpenKeys2 gère les clés.''&lt;br /&gt;
*Le logiciel de contrôle de l'armoire à clés doit envoyer un ordre '''notify([1,0,1,1,1,1,0,0], &amp;quot;passphrase&amp;quot;)''' avec comme paramètre un tableau chronologique des clés ayant pour valeur leur état &lt;br /&gt;
''Applicable dans le cas où le protocole PyOpenKeys3 gère les clés.''&lt;br /&gt;
*Le logiciel de contrôle de l'armoire à clés doit envoyer un ordre '''notify2([[1,1],[2,0],[3,1],[4,1],[5,1],[6,1],[7,0],[8,0]], &amp;quot;passphrase&amp;quot;)''' avec comme paramètre un tableau de tableau avec le numéro de la clé suivi de son état&lt;br /&gt;
**1 = interrupteur de présence de clé fermé = clé absente de l'armoire&lt;br /&gt;
**0 = interrupteur de présence de clé ouvert = clé présente dans l'armoire&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===Exemple de script en Python pour la commande notify===&lt;br /&gt;
Nécessite les librairies Twisted et OpenSSL&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;# load library&lt;br /&gt;
from twisted.web.xmlrpc import Proxy&lt;br /&gt;
from twisted.internet import reactor, ssl&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def printValue(value):&lt;br /&gt;
    print repr(value)&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
&lt;br /&gt;
def printError(error):&lt;br /&gt;
    print 'error', error&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
&lt;br /&gt;
# URL of the XML-RPC server&lt;br /&gt;
proxy = Proxy('https://yourURL.xx/actionOnDemand.php')&lt;br /&gt;
&lt;br /&gt;
# init passphrase&lt;br /&gt;
passphrase = 'SDjklsdiuQSIPO23879ZERK2098ZL2908DFZLK'&lt;br /&gt;
&lt;br /&gt;
# Initiate number of key&lt;br /&gt;
KEY_NUMBER = 16&lt;br /&gt;
&lt;br /&gt;
# init array to send&lt;br /&gt;
state = random.randint(0,1)&lt;br /&gt;
&lt;br /&gt;
if KEY_NUMBER &amp;gt; 8:&lt;br /&gt;
    # Test notify2&lt;br /&gt;
    status = [[d+1,0] for d in range(KEY_NUMBER)]&lt;br /&gt;
    for i in range(KEY_NUMBER):&lt;br /&gt;
        status[i] = [i+1,state]&lt;br /&gt;
        # Alternate 0 and 1 for test&lt;br /&gt;
        state = 0 if state == 1 else 1&lt;br /&gt;
else:&lt;br /&gt;
    # Test notify&lt;br /&gt;
    for i in range(KEY_NUMBER):&lt;br /&gt;
        status.append(state)&lt;br /&gt;
        # Alternate 0 and 1 for test&lt;br /&gt;
        state = 0 if state == 1 else 1&lt;br /&gt;
&lt;br /&gt;
# send to the XML-RPC server&lt;br /&gt;
print &amp;quot;Status sequence : %s&amp;quot; % status&lt;br /&gt;
if KEY_NUMBER&amp;lt;9:&lt;br /&gt;
    proxy.callRemote('notify', status, passphrase).addCallbacks(printValue, printError)&lt;br /&gt;
else:&lt;br /&gt;
    proxy.callRemote('notify2', status, passphrase).addCallbacks(printValue, printError)&lt;br /&gt;
reactor.run()&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
''Nota : to test change the number of key : up to 8 the software use '''notify()''', beyond it uses '''notify2()'''&lt;br /&gt;
&lt;br /&gt;
Cela retournera 0 en cas d'anomalie ou si la passphase transmise n'est pas correcte, 1 si la table des clés a été correctement mise à jour.&lt;br /&gt;
&lt;br /&gt;
==Fermeture automatique d'un vol==&lt;br /&gt;
&lt;br /&gt;
Le logiciel de contrôle de l'armoire à clé doit envoyer un ordre '''closeFlight(&amp;quot;passphrase&amp;quot;, &amp;quot;id de ressource&amp;quot;)''' avec comme paramètre un passphrase et l'id qui va entraîner la fermeture du vol effectué sur cette ressource si un vol avait été ouvert et que la &amp;quot;Fermeture automatique des&lt;br /&gt;
vols au retour de la clé&amp;quot; soit activée. La commande retournera comme réponse une structure JSON pour déterminer si la fermeture du vol s'est bien réalisée ou non et qu'il n'y a pas eu d'erreur.&lt;br /&gt;
&lt;br /&gt;
Réponse quand la vérification du passphrase est incorrecte, ce qui a entraîné la non-fermeture du vol :&lt;br /&gt;
&amp;lt;javascript&amp;gt;{[&lt;br /&gt;
    ack : 0&lt;br /&gt;
]}&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Réponse quand la vérification du passphrase est correcte et que la demande de fermeture du vol s'est bien réalisée :&lt;br /&gt;
&amp;lt;javascript&amp;gt;{[&lt;br /&gt;
    ack : 1&lt;br /&gt;
]}&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Réponse quand la vérification du passphrase est correcte et que la demande de fermeture du vol ne s'est pas bien réalisée suite à une erreur :&lt;br /&gt;
&amp;lt;javascript&amp;gt;{[&lt;br /&gt;
    ack : 1,&lt;br /&gt;
    error : 'Message d\'erreur ...'&lt;br /&gt;
]}&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Script d'exemple pour closeFlight===&lt;br /&gt;
&amp;lt;python&amp;gt;# load library&lt;br /&gt;
from twisted.web.xmlrpc import Proxy&lt;br /&gt;
from twisted.internet import reactor, ssl&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def printValue(value):&lt;br /&gt;
    print repr(value)&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
&lt;br /&gt;
def printError(error):&lt;br /&gt;
    print 'error', error&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
&lt;br /&gt;
# URL of the XML-RPC server&lt;br /&gt;
proxy = Proxy('https://yourURL.xx/actionOnDemand.php')&lt;br /&gt;
&lt;br /&gt;
# Id of resource which needs a flight closing&lt;br /&gt;
resource_id = 1&lt;br /&gt;
&lt;br /&gt;
# init passphrase&lt;br /&gt;
passphrase = 'SDjklsdiuQSIPO23879ZERK2098ZL2908DFZLK'&lt;br /&gt;
&lt;br /&gt;
# send to the XML-RPC server&lt;br /&gt;
proxy.callRemote('closeFlight', resource_id, passphrase).addCallbacks(printValue, printError)&lt;br /&gt;
reactor.run()&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Exemple de script en Python de logiciel de contrôle d'une armoire==&lt;br /&gt;
&amp;lt;python&amp;gt;#!/usr/bin/python&lt;br /&gt;
import xmlrpclib, time, dummy_proto, hashlib&lt;br /&gt;
from twisted.internet import reactor, task, threads, ssl&lt;br /&gt;
from twisted.application import internet, service&lt;br /&gt;
from twisted.internet.protocol import Protocol, ClientCreator, ReconnectingClientFactory&lt;br /&gt;
from twisted.web import resource, server&lt;br /&gt;
&lt;br /&gt;
# Port from which the OF client contact OpenKeys service&lt;br /&gt;
SERVICE_PORT=4080 &lt;br /&gt;
# IP address of the OpenKeys service&lt;br /&gt;
SERVICE_HOST=&amp;quot;192.168.0.200&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# IP address of the key cabinet&lt;br /&gt;
KEYS_ADDR='192.168.0.201'&lt;br /&gt;
# Port from which OpenKeys service contacts the key cabinet&lt;br /&gt;
KEYS_PORT=6002&lt;br /&gt;
#Time to release the key&lt;br /&gt;
KEY_RELEASE_DURATION=15&lt;br /&gt;
&lt;br /&gt;
# sha224 passwords&lt;br /&gt;
PASSWORDS=('847bed9bc354e7e47bc5350a3b3aaf6124f5748224a3c7ad79586c3c')&lt;br /&gt;
&lt;br /&gt;
# init passphrase&lt;br /&gt;
passphrase = 'SDjklsdiuQSIPO23879ZERK2098ZL2908DFZLK'&lt;br /&gt;
&lt;br /&gt;
OF_XMLRPC_URL=&amp;quot;https://openflyers.com/structure/actionOnDemand.php&amp;quot;&lt;br /&gt;
&lt;br /&gt;
DEBUG=False&lt;br /&gt;
&lt;br /&gt;
class dummyProtocol(Protocol):&lt;br /&gt;
	def __init__(self, rpc_server):&lt;br /&gt;
		self.rpc_server=rpc_server&lt;br /&gt;
		self.lc = None&lt;br /&gt;
&lt;br /&gt;
	def connectionMade(self):&lt;br /&gt;
		if not self.lc:&lt;br /&gt;
			# update status every 10 minutes&lt;br /&gt;
			self.lc = task.LoopingCall(self.updateStatus)&lt;br /&gt;
			self.lc.start(600)&lt;br /&gt;
&lt;br /&gt;
	def dataReceived(self, data):&lt;br /&gt;
		msg=dummy_proto.dummy_message.newFromData(data)&lt;br /&gt;
		if DEBUG: msg.display()&lt;br /&gt;
		try:&lt;br /&gt;
			if type(msg)==dummyproto.dummy_ONOFF_Control_Response:&lt;br /&gt;
				response = self.rpc_server.notify(msg.getKeysStatus(),passphrase)&lt;br /&gt;
		except Exception, err:&lt;br /&gt;
			if DEBUG: print &amp;quot;error: &amp;quot;, err&lt;br /&gt;
			pass # ignore&lt;br /&gt;
&lt;br /&gt;
	def updateStatus(self):&lt;br /&gt;
		msg = dummy_proto.dummy_State_Request()&lt;br /&gt;
		self.transport.write(msg.build_message())&lt;br /&gt;
	&lt;br /&gt;
	def send(self, dummy_data):&lt;br /&gt;
		self.transport.write(dummy_data.build_message())&lt;br /&gt;
&lt;br /&gt;
class dummyClientFactory(ReconnectingClientFactory):&lt;br /&gt;
	def __init__(self, rpc_server):&lt;br /&gt;
		self.rpc_server = rpc_server&lt;br /&gt;
&lt;br /&gt;
	def buildProtocol(self, addr):&lt;br /&gt;
		self.resetDelay()&lt;br /&gt;
		self.protocol = dummyProtocol(self.rpc_server)&lt;br /&gt;
		return self.protocol&lt;br /&gt;
&lt;br /&gt;
	def clientConnectionLost(self, connector, reason):&lt;br /&gt;
		ReconnectingClientFactory.clientConnectionLost(self, connector, reason)&lt;br /&gt;
		connector.connect()&lt;br /&gt;
&lt;br /&gt;
	def clientConnectionFailed(self, connector, reason):&lt;br /&gt;
		if DEBUG: print 'Connection failed. Reason:', reason&lt;br /&gt;
		ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)&lt;br /&gt;
&lt;br /&gt;
	# blocking method ! must be run in a new thread&lt;br /&gt;
	def release_key(self, key_num, timeOur):&lt;br /&gt;
		m = dummy_proto.dummy_ONOFF_Control()&lt;br /&gt;
		m.setON(key_num)&lt;br /&gt;
		self.protocol.send(m)&lt;br /&gt;
		time.sleep(timeOut)&lt;br /&gt;
		m.setOFF(key_num)&lt;br /&gt;
		self.protocol.send(m)&lt;br /&gt;
		return key_num&lt;br /&gt;
&lt;br /&gt;
class WebResource(resource.Resource):&lt;br /&gt;
	def __init__(self, rpc_server, dummy_client_factory):&lt;br /&gt;
		self.rpc_server = rpc_server&lt;br /&gt;
		self.dummy_client_factory = dummy_client_factory&lt;br /&gt;
		resource.Resource.__init__(self)&lt;br /&gt;
		self.keys_webcontrol_state = [0,0,0,0,0,0,0,0,0,0]&lt;br /&gt;
		&lt;br /&gt;
	def getChild(self, name, request):&lt;br /&gt;
		return self&lt;br /&gt;
&lt;br /&gt;
	def render(self, request):&lt;br /&gt;
		reponse = 0 # NOK par defaut&lt;br /&gt;
		key_num = 0&lt;br /&gt;
		try:&lt;br /&gt;
			sessid = request.args.get('sessid', [&amp;quot;&amp;quot;])[0]&lt;br /&gt;
			password = request.args.get('password', [&amp;quot;&amp;quot;])[0]&lt;br /&gt;
			key_num = int(request.args.get('key', [&amp;quot;0&amp;quot;])[0])&lt;br /&gt;
			response = 0&lt;br /&gt;
			if password:&lt;br /&gt;
                                if hashlib.sha224(password).hexdigest() in PASSWORDS:&lt;br /&gt;
                                        timeOut   = KEY_RELEASE_DURATION&lt;br /&gt;
                                        response_XMLRPC = 1&lt;br /&gt;
                        else:&lt;br /&gt;
                                timeOut   = int(request.args.get('timeout', [&amp;quot;0&amp;quot;])[0])&lt;br /&gt;
                                response = self.rpc_server.checkCommand(sessid, key_num)&lt;br /&gt;
		except Exception, err:&lt;br /&gt;
			if DEBUG: print &amp;quot;error: &amp;quot;, err&lt;br /&gt;
			return &amp;quot;NOK:bad request&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		if response == 1:&lt;br /&gt;
			# Don't try to release a key that is being released&lt;br /&gt;
			if self.keys_webcontrol_state[key_num-1]: return &amp;quot;OK:already released&amp;quot;&lt;br /&gt;
			self.keys_webcontrol_state[key_num-1] = 1&lt;br /&gt;
			d = threads.deferToThread(self.dummy_client_factory.release_key, key_num, timeOut)&lt;br /&gt;
			d.addCallback(self.unset_webcontrol_state)&lt;br /&gt;
			return &amp;quot;OK:releasing key...&amp;quot;&lt;br /&gt;
		else:&lt;br /&gt;
			return &amp;quot;NOK:permission refused&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	def unset_webcontrol_state(self, key_num):&lt;br /&gt;
		self.keys_webcontrol_state[key_num-1] = 0&lt;br /&gt;
&lt;br /&gt;
class OpenKeysService(service.Service):&lt;br /&gt;
	def __init__(self):&lt;br /&gt;
		rpc_server=xmlrpclib.Server(OF_XMLRPC_URL);&lt;br /&gt;
		self.dummy_client_factory = dummyClientFactory(rpc_server)&lt;br /&gt;
		self.web_resource = WebResource(rpc_server, self.dummy_client_factory)&lt;br /&gt;
		&lt;br /&gt;
	def getdummyClientFactory(self):&lt;br /&gt;
		return self.dummy_client_factory&lt;br /&gt;
&lt;br /&gt;
	def getWebResource(self):&lt;br /&gt;
		return self.web_resource&lt;br /&gt;
&lt;br /&gt;
application = service.Application('openkeys')&lt;br /&gt;
f = OpenKeysService()&lt;br /&gt;
serviceCollection = service.IServiceCollection(application)&lt;br /&gt;
internet.TCPClient(KEYS_ADDR, KEYS_PORT, f.getdummyClientFactory()&lt;br /&gt;
				   ).setServiceParent(serviceCollection)&lt;br /&gt;
internet.TCPServer(SERVICE_PORT, server.Site(f.getWebResource())&lt;br /&gt;
				   ).setServiceParent(serviceCollection)&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Maquette de script actionOnDemand.php côté serveur recevant les appels du logiciel de contrôle de l'armoire==&lt;br /&gt;
Ce script nécessite la bibliothèque PEAR [http://pear.php.net/package/XML_RPC2 XML_RPC2].&lt;br /&gt;
&lt;br /&gt;
Pour les tests, il suffit de modifier la valeur de la variable $weDontWant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;php&amp;gt;&amp;lt;?php&lt;br /&gt;
include 'XML/RPC2/Server.php';&lt;br /&gt;
&lt;br /&gt;
class OpenKeysGateway {&lt;br /&gt;
    /**&lt;br /&gt;
     * Update the status of the keys&lt;br /&gt;
     *&lt;br /&gt;
     * @param array $status Status of keys&lt;br /&gt;
     * @return integer 1 if ok, 0 else&lt;br /&gt;
     */&lt;br /&gt;
    public static function notify($status) {&lt;br /&gt;
        $logmsg = &amp;quot;&amp;quot;;&lt;br /&gt;
        foreach ($status as $key_num_from_zero =&amp;gt; $key_pres) {&lt;br /&gt;
            if (!is_numeric($key_pres) || intval($key_pres)!=$key_pres || $key_pres &amp;lt; 0 || $key_pres &amp;gt; 1) continue;&lt;br /&gt;
            if (!is_numeric($key_num_from_zero) || intval($key_num_from_zero)!=$key_num_from_zero &lt;br /&gt;
                || $key_num_from_zero &amp;lt; 0 || $key_num_from_zero &amp;gt; 9) continue;&lt;br /&gt;
            $logmsg .= &amp;quot;&amp;quot;.($key_num_from_zero+1).&amp;quot;:&amp;quot;.$key_pres.&amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        file_put_contents('test.txt', &amp;quot;key notify :&amp;quot;.$logmsg, FILE_APPEND );&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Check if user is able to release the key 'key_num'&lt;br /&gt;
     *&lt;br /&gt;
     * @param string $sessid PHPSESSID of a connected user&lt;br /&gt;
     * @param integer $key_num number of the key to release&lt;br /&gt;
     * @return integer 0:NOK, 1:OK&lt;br /&gt;
     */&lt;br /&gt;
    public static function checkCommand($sessid, $key_num) {&lt;br /&gt;
        /* sanitize input */&lt;br /&gt;
        if (!is_numeric($key_num) || intval($key_num)!=$key_num || $key_num &amp;lt; 1 || $key_num &amp;gt; 10) {&lt;br /&gt;
            return 0;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $weDontWant = 1;&lt;br /&gt;
&lt;br /&gt;
        if ($weDontWant) {&lt;br /&gt;
            file_put_contents('test.txt', &amp;quot;$key_num has no associated airborne aircraft&amp;quot;, FILE_APPEND );&lt;br /&gt;
            return 0;&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
            file_put_contents('test.txt', &amp;quot;granted key: &amp;quot;.$key_num.&amp;quot;:permission granted&amp;quot;, FILE_APPEND );&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$options = array(&lt;br /&gt;
    'autoDocument' =&amp;gt; true,&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
// dirty hack to get things work !&lt;br /&gt;
$GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents('php://input');&lt;br /&gt;
&lt;br /&gt;
$server = XML_RPC2_Server::create('OpenKeysGateway', $options);&lt;br /&gt;
$server-&amp;gt;handleCall();&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&amp;lt;/php&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jtremblet</name></author>
	</entry>
	<entry>
		<id>https://doc4-fr-mirror.openflyers.com/index.php?title=Interfa%C3%A7age-OpenFlyers-et-armoire-%C3%A0-cl%C3%A9s&amp;diff=13015</id>
		<title>Interfaçage OpenFlyers et armoire à clés</title>
		<link rel="alternate" type="text/html" href="https://doc4-fr-mirror.openflyers.com/index.php?title=Interfa%C3%A7age-OpenFlyers-et-armoire-%C3%A0-cl%C3%A9s&amp;diff=13015"/>
		<updated>2024-12-10T09:50:07Z</updated>

		<summary type="html">&lt;p&gt;Jtremblet: /* Activation et configuration de la gestion des armoires à clé */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
=Présentation=&lt;br /&gt;
L'objet de cette page est de décrire le protocole d'interfaçage avec toute solution d'armoire à clés tiers. Pour les armoires à clés commercialisées par OpenFlyers, il faut se référer à la [[Contrôle des accès|documentation sur le contrôle d'accès]].&lt;br /&gt;
&lt;br /&gt;
Le protocole repose sur le principe que l'interfaçage est réalisé par un logiciel de contrôle de l'armoire à clé sur un PC ou une solution embarquée et qui dispose d'un accès à internet lui permettant de communiquer avec OpenFlyers. La communication est synchrone.&lt;br /&gt;
&lt;br /&gt;
=Interface utilisateur OpenFlyers=&lt;br /&gt;
L'utilisateur ouvre un vol dans OpenFlyers :&lt;br /&gt;
&lt;br /&gt;
[[File:Menu-contextuel-ouverture-de-vol.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Il se retrouve sur le formulaire de saisie du vol en mode Départ en vol:&lt;br /&gt;
&lt;br /&gt;
[[File:Formulaire-ouverture-de-vol.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lorsqu'il clique sur le bouton de validation, 3 cas peuvent se présenter :&lt;br /&gt;
*Une alerte ou plusieurs alertes rouges (bloquantes), s'affichent : l'utilisateur n'a pas la possibilité de surpasser ses alertes, il ne peut alors récupérer la clé :&lt;br /&gt;
&lt;br /&gt;
[[File:Alertes-bloquantes-en-ouverture-vol.png]]&lt;br /&gt;
&lt;br /&gt;
*Une alerte ou plusieurs alertes oranges (non-bloquantes), s'affichent : l'utilisateur a la possibilité de surpasser ses alertes, et ainsi de récupérer la clé :&lt;br /&gt;
&lt;br /&gt;
[[File:Alertes-non-bloquantes-en-ouverture-vol.png]]&lt;br /&gt;
&lt;br /&gt;
*Aucune alerte ne s'affiche, l'utilisateur se retrouve alors directement sur la page lui indiquant :&lt;br /&gt;
&lt;br /&gt;
[[File:Message_autorisation_libération_clé.png]]&lt;br /&gt;
&lt;br /&gt;
Une fois qu'il a cliqué sur '''LIBÉRER LA CLÉ''', il dispose de X secondes. Cette durée est paramétrable par OpenFlyers.&lt;br /&gt;
&lt;br /&gt;
*Lorsqu'il rentre de vol, l'utilisateur n'a plus qu'a retourner sur le formulaire de saisie de vol et à fermer son vol. La clé doit etre remise en place sur l'armoire pour fermer le vol.&lt;br /&gt;
&lt;br /&gt;
=Interface administrateur OpenFlyers=&lt;br /&gt;
==Activation et configuration de la gestion des armoires à clé==&lt;br /&gt;
*'''Admin &amp;gt; Structure &amp;gt; Structure &amp;gt; Paramétrage'''&lt;br /&gt;
*Dans la section du formulaire '''Contrôle d'accès''', sélectionner '''Activé(e)''' pour les champs '''Contrôle d'accès''' et '''Gestion armoire à clés'''.&lt;br /&gt;
[[File:Config_parametres_OF_controle_acces 1.jpg]]&lt;br /&gt;
*Cliquer sur le bouton '''Enregistrer''' &lt;br /&gt;
*Un nouveau champ s'affich&lt;br /&gt;
*Sélectionner le '''Logiciel de contrôle de l'armoire à clés''' selon votre armoire à clés&lt;br /&gt;
**Pour armoire FlogBox : [[File:Config_parametres_OF_controle_acces 4.jpg]]&lt;br /&gt;
**Pour armoire Deister : [[File:Config_parametres_OF_controle_acces 3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Les Logiciels OpenKey et PyOpenKey sont des protocoles propriétaires d'OF, pour les configurer voir  [[Interfaçage-OpenFlyers-et-armoire-à-clés#Interface-administrateur-OpenFlyers | Interfaçage armoire à clés OF]]&lt;br /&gt;
&lt;br /&gt;
==Attribution des clés aux ressources/aéronefs==&lt;br /&gt;
''Dans le cas où c'est le logiciel OpenFlyers qui gère les clés.''&lt;br /&gt;
*'''Admin &amp;gt; Types de ressources &amp;gt; Actives'''&lt;br /&gt;
[[File:Liste_des_aéronefs.png]]&lt;br /&gt;
&lt;br /&gt;
Pour chaque aéronef concerné, il suffit d'attribuer un numéro et un nom de clé dans les champs correspondants. La validation de la saisie se fait automatiquement en cliquant hors du champ de saisie.&lt;br /&gt;
&lt;br /&gt;
=Protocole de dialogue XML-RPC entre OpenFlyers et le logiciel de gestion de l'armoire à clé=&lt;br /&gt;
Le dialogue avec le serveur XML-RPC d'OpenFlyers doit s'effectuer en '''HTTPS'''. Les commandes accessibles sont listées par un appel à ActionOnDemand.php&lt;br /&gt;
https://openflyers.com/yourURL/actionOnDemand.php&lt;br /&gt;
&lt;br /&gt;
==Demande de libération d'une clé==&lt;br /&gt;
&lt;br /&gt;
===Cas avec gestion des clés par OpenFlyers===&lt;br /&gt;
&lt;br /&gt;
*Lorsque qu'une clé doit être libérée, le navigateur envoie un message au logiciel de contrôle de l'armoire à clé par le protocole HTTPS sous la forme suivante :&lt;br /&gt;
https://127.0.0.1:4080/?sessid=e5f01p2oqh2vb36arisr8k5j87&amp;amp;amp;timeOut=10000&amp;amp;amp;key=1&amp;amp;amp;resource=2&amp;amp;amp;person=12;action='releaseKey'&lt;br /&gt;
&lt;br /&gt;
:*L'adresse IP (ici 127.0.0.1) et le port (ici 4080) sont fonction de la [[#Activation_et_configuration_de_la_gestion_des_armoires_à_clé|configuration de l'armoire à clé dans OpenFlyers]].&lt;br /&gt;
:*sessid contient le numéro de session en cours&lt;br /&gt;
:*timeout correspond au temps d'attente pour la prise d'une clé en millisecondes&lt;br /&gt;
:*key contient le numéro de la clé concernée&lt;br /&gt;
:*resource contient le numéro de la ressource concernée&lt;br /&gt;
:*person contient le numéro de l'utilisateur qui fait la demande&lt;br /&gt;
:*action est un mot clé désignant l'objet de la commande&lt;br /&gt;
:**release_key: ordre de libérer la clé&lt;br /&gt;
:**open_door: ordre d'ouvrir la porte&lt;br /&gt;
:**init_tags: ordre de lire les tags des clés&lt;br /&gt;
*Le logiciel de contrôle de l'armoire à clé doit alors envoyer une demande d'ordre au serveur OpenFlyers à l'adresse suivante https://openflyers.com/structure/ où il faut remplacer openflyers.com/structure par l'adresse de la plateforme OpenFlyers concernée, avec comme commande XML_RPC '''checkCommand (&amp;quot;e5f01p2oqh2vb36arisr8k5j87&amp;quot;,int(key))'''.&lt;br /&gt;
&lt;br /&gt;
*Le serveur OpenFlyers vérifie alors l'action demandée :&lt;br /&gt;
Pour release_key, il est vérifié :&lt;br /&gt;
#Que la clé est au bon format et existe. Lorsque la clé est validée, on passe à l'étape suivante sinon on retourne 0&lt;br /&gt;
#Que l'utilisateur faisant la demande est bien celui qui est connecté. Lorsque c'est le cas, on passe à l'étape suivante sinon on retourne 0&lt;br /&gt;
#Ensuite si l'utilisateur qui a passé la demande :&lt;br /&gt;
#*A le droit '''Gestion des clés''' (administrateur) alors on libère la clé sans condition (cela permet de libérer la clé sans contrôle) et on retourne 1&lt;br /&gt;
#*N'a pas le droit '''Gestion des clés''' (pilote) alors on vérifie s'il existe un vol ouvert qui remplit la double condition :&lt;br /&gt;
#**Vol attribué à l'utilisateur&lt;br /&gt;
#**Aéronef du vol associé à la demande de libération de la clé&lt;br /&gt;
#**Lorsque la double condition est remplie, on retourne 1 sinon 0&lt;br /&gt;
&lt;br /&gt;
*Le serveur retourne ensuite la réponse :&lt;br /&gt;
**1 dans le cas d'autorisation de libération de clé &lt;br /&gt;
**0 dans le cas contraire&lt;br /&gt;
&lt;br /&gt;
====Exemple de script en Python d'utilisation de la commande checkCommand avec gestion des clés====&lt;br /&gt;
&amp;lt;python&amp;gt;# load library&lt;br /&gt;
from twisted.web.xmlrpc import Proxy&lt;br /&gt;
from twisted.internet import reactor, ssl&lt;br /&gt;
 &lt;br /&gt;
def printValue(value):&lt;br /&gt;
    print repr(value)&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
 &lt;br /&gt;
def printError(error):&lt;br /&gt;
    print 'error', error&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
 &lt;br /&gt;
# URL of the XML-RPC server&lt;br /&gt;
proxy = Proxy('https://yourURL.xx/actionOnDemand.php')&lt;br /&gt;
 &lt;br /&gt;
# init array to send&lt;br /&gt;
sessid = &amp;quot;&amp;quot;&lt;br /&gt;
key_num = 1&lt;br /&gt;
 &lt;br /&gt;
# send to the XML-RPC server&lt;br /&gt;
proxy.callRemote('checkCommand', sessid, key_num).addCallbacks(printValue, printError)&lt;br /&gt;
reactor.run()&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce test peut être complété (pour obtenir une réponse &amp;quot;1&amp;quot;) en simulant une armoire à clé à l'aide d'un script PHP de la façon suivante :&lt;br /&gt;
*Installer un serveur local (par exemple [https://www.wampserver.com/ wampserver] sous Windows) de façon à avoir le port 127.0.0.1 qui lui est attribué&lt;br /&gt;
*Configurer la plateforme OpenFlyers de manière à gérer l'armoire à clé avec les éléments suivants :&lt;br /&gt;
**'''IP du PC contenant le logiciel de contrôle''' : 127.0.0.1&lt;br /&gt;
**'''Port du PC contenant le logiciel de contrôle''' : 80&lt;br /&gt;
*Configurer la plateforme OpenFlyers de manière à gérer les clés&lt;br /&gt;
*A la racine du répertoire www, mettre le script index.php suivant (on suppose que ce script est appelé par défaut lorsqu'on utilise l'URL https://127.0.0.1 ) :&lt;br /&gt;
&amp;lt;php&amp;gt;&amp;lt;?php &lt;br /&gt;
file_put_contents('test.txt', 'TEST', FILE_APPEND );&lt;br /&gt;
file_put_contents('test.txt', print_r($_REQUEST, true), FILE_APPEND );&lt;br /&gt;
?&amp;gt;&amp;lt;/php&amp;gt;&lt;br /&gt;
*Toujours à la racine du répertoire www, créer un fichier test.txt&lt;br /&gt;
Le script PHP écrira dans le fichier test.txt les variables transmises lors de la demande d'ouverture de l'armoire à clé :&lt;br /&gt;
&amp;lt;pre&amp;gt;TESTArray&lt;br /&gt;
(&lt;br /&gt;
    [sessid] =&amp;gt; j2eo92215nbef09borb74jftm1&lt;br /&gt;
    [key] =&amp;gt; 1&lt;br /&gt;
    [resource] =&amp;gt; 1&lt;br /&gt;
    [person] =&amp;gt; 1&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
*Il suffit alors de recopier la valeur de '''sessid''' et de '''key''' dans le script python de ce début de paragraphe et de le tester : il devrait renvoyer 1.&lt;br /&gt;
&lt;br /&gt;
===Cas sans gestion des clés par OpenFlyers===&lt;br /&gt;
&lt;br /&gt;
*Lorsque qu'une demande de vérification doit être réalisée, le navigateur envoie un message au logiciel de contrôle de l'armoire à clé par le protocole HTTPS sous la forme suivante :&lt;br /&gt;
https://127.0.0.1:4080/?sessid=e5f01p2oqh2vb36arisr8k5j87&amp;amp;amp;resource=2&amp;amp;amp;person=12&lt;br /&gt;
&lt;br /&gt;
:*L'adresse IP (ici 127.0.0.1) et le port (ici 4080) sont fonction de la [[#Activation_et_configuration_de_la_gestion_des_armoires_à_clé|configuration de l'armoire à clé dans OpenFlyers]].&lt;br /&gt;
:*sessid contient le numéro de session en cours&lt;br /&gt;
:*resource contient le numéro de la ressource concernée&lt;br /&gt;
:*person contient le numéro de l'utilisateur qui fait la demande&lt;br /&gt;
*Le logiciel de contrôle de l'armoire à clé doit alors envoyer une demande d'ordre au serveur OpenFlyers à l'adresse suivante https://openflyers.com/structure/actionOnDemand.php où il faut remplacer openflyers.com/structure par l'adresse de la plateforme OpenFlyers concernée, avec comme commande XML_RPC '''checkCommand (&amp;quot;e5f01p2oqh2vb36arisr8k5j87&amp;quot;)'''.&lt;br /&gt;
&lt;br /&gt;
*Le serveur OpenFlyers vérifie alors :&lt;br /&gt;
#Que l'utilisateur faisant la demande est bien celui qui est connecté. Lorsque c'est le cas, on passe à l'étape suivante sinon on retourne 0&lt;br /&gt;
#On vérifie s'il existe un vol ouvert qui remplit la double condition :&lt;br /&gt;
#*Vol attribué à l'utilisateur&lt;br /&gt;
#*Aéronef du vol associé à la demande de libération de la clé&lt;br /&gt;
#*Lorsque la double condition est remplie, on retourne 1 sinon 0&lt;br /&gt;
&lt;br /&gt;
*Le serveur retourne ensuite la réponse :&lt;br /&gt;
**1 dans le cas d'autorisation&lt;br /&gt;
**0 dans le cas contraire&lt;br /&gt;
&lt;br /&gt;
====Exemple de script en Python d'utilisation de la commande checkCommand sans gestion des clés====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;# load library&lt;br /&gt;
from twisted.web.xmlrpc import Proxy&lt;br /&gt;
from twisted.internet import reactor, ssl&lt;br /&gt;
 &lt;br /&gt;
def printValue(value):&lt;br /&gt;
    print repr(value)&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
 &lt;br /&gt;
def printError(error):&lt;br /&gt;
    print 'error', error&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
 &lt;br /&gt;
# URL of the XML-RPC server&lt;br /&gt;
proxy = Proxy('https://yourURL.xx/actionOnDemand.php')&lt;br /&gt;
 &lt;br /&gt;
# init array to send&lt;br /&gt;
sessid = &amp;quot;&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
# send to the XML-RPC server&lt;br /&gt;
proxy.callRemote('checkCommand', sessid).addCallbacks(printValue, printError)&lt;br /&gt;
reactor.run()&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce test peut être complété (pour obtenir une réponse &amp;quot;1&amp;quot;) en simulant une armoire à clé à l'aide d'un script PHP de la façon suivante :&lt;br /&gt;
*Installer un serveur local (par exemple [https://www.wampserver.com/ wampserver] sous Windows) de façon à avoir le port 127.0.0.1 qui lui est attribué&lt;br /&gt;
*Configurer la plateforme OpenFlyers de manière à gérer l'armoire à clé avec les éléments suivants :&lt;br /&gt;
**'''IP du PC contenant le logiciel de contrôle''' : 127.0.0.1&lt;br /&gt;
**'''Port du PC contenant le logiciel de contrôle''' : 80&lt;br /&gt;
*Configurer la plateforme OpenFlyers de manière à ne pas gérer les clés&lt;br /&gt;
*A la racine du répertoire www, mettre le script index.php suivant (on suppose que ce script est appelé par défaut lorsqu'on utilise l'URL https://127.0.0.1 ) :&lt;br /&gt;
&amp;lt;php&amp;gt;&amp;lt;?php &lt;br /&gt;
file_put_contents('test.txt', 'TEST', FILE_APPEND );&lt;br /&gt;
file_put_contents('test.txt', print_r($_REQUEST, true), FILE_APPEND );&lt;br /&gt;
?&amp;gt;&amp;lt;/php&amp;gt;&lt;br /&gt;
*Toujours à la racine du répertoire www, créer un fichier test.txt&lt;br /&gt;
Le script PHP écrira dans le fichier test.txt les variables transmises lors de la demande d'ouverture de l'armoire à clé :&lt;br /&gt;
&amp;lt;pre&amp;gt;TESTArray&lt;br /&gt;
(&lt;br /&gt;
    [sessid] =&amp;gt; j2eo92215nbef09borb74jftm1&lt;br /&gt;
    [resource] =&amp;gt; 1&lt;br /&gt;
    [person] =&amp;gt; 1&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
*Il suffit alors de recopier la valeur de '''sessid''' dans le script python de ce début de paragraphe et de le tester : il devrait renvoyer 1.&lt;br /&gt;
&lt;br /&gt;
==Modification de l'état d'une clé==&lt;br /&gt;
''Applicable dans le cas où le protocole PyOpenKeys2 gère les clés.''&lt;br /&gt;
*Le logiciel de contrôle de l'armoire à clés doit envoyer un ordre '''notify([1,0,1,1,1,1,0,0], &amp;quot;passphrase&amp;quot;)''' avec comme paramètre un tableau chronologique des clés ayant pour valeur leur état &lt;br /&gt;
''Applicable dans le cas où le protocole PyOpenKeys3 gère les clés.''&lt;br /&gt;
*Le logiciel de contrôle de l'armoire à clés doit envoyer un ordre '''notify2([[1,1],[2,0],[3,1],[4,1],[5,1],[6,1],[7,0],[8,0]], &amp;quot;passphrase&amp;quot;)''' avec comme paramètre un tableau de tableau avec le numéro de la clé suivi de son état&lt;br /&gt;
**1 = interrupteur de présence de clé fermé = clé absente de l'armoire&lt;br /&gt;
**0 = interrupteur de présence de clé ouvert = clé présente dans l'armoire&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===Exemple de script en Python pour la commande notify===&lt;br /&gt;
Nécessite les librairies Twisted et OpenSSL&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;# load library&lt;br /&gt;
from twisted.web.xmlrpc import Proxy&lt;br /&gt;
from twisted.internet import reactor, ssl&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def printValue(value):&lt;br /&gt;
    print repr(value)&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
&lt;br /&gt;
def printError(error):&lt;br /&gt;
    print 'error', error&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
&lt;br /&gt;
# URL of the XML-RPC server&lt;br /&gt;
proxy = Proxy('https://yourURL.xx/actionOnDemand.php')&lt;br /&gt;
&lt;br /&gt;
# init passphrase&lt;br /&gt;
passphrase = 'SDjklsdiuQSIPO23879ZERK2098ZL2908DFZLK'&lt;br /&gt;
&lt;br /&gt;
# Initiate number of key&lt;br /&gt;
KEY_NUMBER = 16&lt;br /&gt;
&lt;br /&gt;
# init array to send&lt;br /&gt;
state = random.randint(0,1)&lt;br /&gt;
&lt;br /&gt;
if KEY_NUMBER &amp;gt; 8:&lt;br /&gt;
    # Test notify2&lt;br /&gt;
    status = [[d+1,0] for d in range(KEY_NUMBER)]&lt;br /&gt;
    for i in range(KEY_NUMBER):&lt;br /&gt;
        status[i] = [i+1,state]&lt;br /&gt;
        # Alternate 0 and 1 for test&lt;br /&gt;
        state = 0 if state == 1 else 1&lt;br /&gt;
else:&lt;br /&gt;
    # Test notify&lt;br /&gt;
    for i in range(KEY_NUMBER):&lt;br /&gt;
        status.append(state)&lt;br /&gt;
        # Alternate 0 and 1 for test&lt;br /&gt;
        state = 0 if state == 1 else 1&lt;br /&gt;
&lt;br /&gt;
# send to the XML-RPC server&lt;br /&gt;
print &amp;quot;Status sequence : %s&amp;quot; % status&lt;br /&gt;
if KEY_NUMBER&amp;lt;9:&lt;br /&gt;
    proxy.callRemote('notify', status, passphrase).addCallbacks(printValue, printError)&lt;br /&gt;
else:&lt;br /&gt;
    proxy.callRemote('notify2', status, passphrase).addCallbacks(printValue, printError)&lt;br /&gt;
reactor.run()&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
''Nota : to test change the number of key : up to 8 the software use '''notify()''', beyond it uses '''notify2()'''&lt;br /&gt;
&lt;br /&gt;
Cela retournera 0 en cas d'anomalie ou si la passphase transmise n'est pas correcte, 1 si la table des clés a été correctement mise à jour.&lt;br /&gt;
&lt;br /&gt;
==Fermeture automatique d'un vol==&lt;br /&gt;
&lt;br /&gt;
Le logiciel de contrôle de l'armoire à clé doit envoyer un ordre '''closeFlight(&amp;quot;passphrase&amp;quot;, &amp;quot;id de ressource&amp;quot;)''' avec comme paramètre un passphrase et l'id qui va entraîner la fermeture du vol effectué sur cette ressource si un vol avait été ouvert et que la &amp;quot;Fermeture automatique des&lt;br /&gt;
vols au retour de la clé&amp;quot; soit activée. La commande retournera comme réponse une structure JSON pour déterminer si la fermeture du vol s'est bien réalisée ou non et qu'il n'y a pas eu d'erreur.&lt;br /&gt;
&lt;br /&gt;
Réponse quand la vérification du passphrase est incorrecte, ce qui a entraîné la non-fermeture du vol :&lt;br /&gt;
&amp;lt;javascript&amp;gt;{[&lt;br /&gt;
    ack : 0&lt;br /&gt;
]}&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Réponse quand la vérification du passphrase est correcte et que la demande de fermeture du vol s'est bien réalisée :&lt;br /&gt;
&amp;lt;javascript&amp;gt;{[&lt;br /&gt;
    ack : 1&lt;br /&gt;
]}&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Réponse quand la vérification du passphrase est correcte et que la demande de fermeture du vol ne s'est pas bien réalisée suite à une erreur :&lt;br /&gt;
&amp;lt;javascript&amp;gt;{[&lt;br /&gt;
    ack : 1,&lt;br /&gt;
    error : 'Message d\'erreur ...'&lt;br /&gt;
]}&amp;lt;/javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Script d'exemple pour closeFlight===&lt;br /&gt;
&amp;lt;python&amp;gt;# load library&lt;br /&gt;
from twisted.web.xmlrpc import Proxy&lt;br /&gt;
from twisted.internet import reactor, ssl&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
def printValue(value):&lt;br /&gt;
    print repr(value)&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
&lt;br /&gt;
def printError(error):&lt;br /&gt;
    print 'error', error&lt;br /&gt;
    reactor.stop()&lt;br /&gt;
&lt;br /&gt;
# URL of the XML-RPC server&lt;br /&gt;
proxy = Proxy('https://yourURL.xx/actionOnDemand.php')&lt;br /&gt;
&lt;br /&gt;
# Id of resource which needs a flight closing&lt;br /&gt;
resource_id = 1&lt;br /&gt;
&lt;br /&gt;
# init passphrase&lt;br /&gt;
passphrase = 'SDjklsdiuQSIPO23879ZERK2098ZL2908DFZLK'&lt;br /&gt;
&lt;br /&gt;
# send to the XML-RPC server&lt;br /&gt;
proxy.callRemote('closeFlight', resource_id, passphrase).addCallbacks(printValue, printError)&lt;br /&gt;
reactor.run()&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Exemple de script en Python de logiciel de contrôle d'une armoire==&lt;br /&gt;
&amp;lt;python&amp;gt;#!/usr/bin/python&lt;br /&gt;
import xmlrpclib, time, dummy_proto, hashlib&lt;br /&gt;
from twisted.internet import reactor, task, threads, ssl&lt;br /&gt;
from twisted.application import internet, service&lt;br /&gt;
from twisted.internet.protocol import Protocol, ClientCreator, ReconnectingClientFactory&lt;br /&gt;
from twisted.web import resource, server&lt;br /&gt;
&lt;br /&gt;
# Port from which the OF client contact OpenKeys service&lt;br /&gt;
SERVICE_PORT=4080 &lt;br /&gt;
# IP address of the OpenKeys service&lt;br /&gt;
SERVICE_HOST=&amp;quot;192.168.0.200&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# IP address of the key cabinet&lt;br /&gt;
KEYS_ADDR='192.168.0.201'&lt;br /&gt;
# Port from which OpenKeys service contacts the key cabinet&lt;br /&gt;
KEYS_PORT=6002&lt;br /&gt;
#Time to release the key&lt;br /&gt;
KEY_RELEASE_DURATION=15&lt;br /&gt;
&lt;br /&gt;
# sha224 passwords&lt;br /&gt;
PASSWORDS=('847bed9bc354e7e47bc5350a3b3aaf6124f5748224a3c7ad79586c3c')&lt;br /&gt;
&lt;br /&gt;
# init passphrase&lt;br /&gt;
passphrase = 'SDjklsdiuQSIPO23879ZERK2098ZL2908DFZLK'&lt;br /&gt;
&lt;br /&gt;
OF_XMLRPC_URL=&amp;quot;https://openflyers.com/structure/actionOnDemand.php&amp;quot;&lt;br /&gt;
&lt;br /&gt;
DEBUG=False&lt;br /&gt;
&lt;br /&gt;
class dummyProtocol(Protocol):&lt;br /&gt;
	def __init__(self, rpc_server):&lt;br /&gt;
		self.rpc_server=rpc_server&lt;br /&gt;
		self.lc = None&lt;br /&gt;
&lt;br /&gt;
	def connectionMade(self):&lt;br /&gt;
		if not self.lc:&lt;br /&gt;
			# update status every 10 minutes&lt;br /&gt;
			self.lc = task.LoopingCall(self.updateStatus)&lt;br /&gt;
			self.lc.start(600)&lt;br /&gt;
&lt;br /&gt;
	def dataReceived(self, data):&lt;br /&gt;
		msg=dummy_proto.dummy_message.newFromData(data)&lt;br /&gt;
		if DEBUG: msg.display()&lt;br /&gt;
		try:&lt;br /&gt;
			if type(msg)==dummyproto.dummy_ONOFF_Control_Response:&lt;br /&gt;
				response = self.rpc_server.notify(msg.getKeysStatus(),passphrase)&lt;br /&gt;
		except Exception, err:&lt;br /&gt;
			if DEBUG: print &amp;quot;error: &amp;quot;, err&lt;br /&gt;
			pass # ignore&lt;br /&gt;
&lt;br /&gt;
	def updateStatus(self):&lt;br /&gt;
		msg = dummy_proto.dummy_State_Request()&lt;br /&gt;
		self.transport.write(msg.build_message())&lt;br /&gt;
	&lt;br /&gt;
	def send(self, dummy_data):&lt;br /&gt;
		self.transport.write(dummy_data.build_message())&lt;br /&gt;
&lt;br /&gt;
class dummyClientFactory(ReconnectingClientFactory):&lt;br /&gt;
	def __init__(self, rpc_server):&lt;br /&gt;
		self.rpc_server = rpc_server&lt;br /&gt;
&lt;br /&gt;
	def buildProtocol(self, addr):&lt;br /&gt;
		self.resetDelay()&lt;br /&gt;
		self.protocol = dummyProtocol(self.rpc_server)&lt;br /&gt;
		return self.protocol&lt;br /&gt;
&lt;br /&gt;
	def clientConnectionLost(self, connector, reason):&lt;br /&gt;
		ReconnectingClientFactory.clientConnectionLost(self, connector, reason)&lt;br /&gt;
		connector.connect()&lt;br /&gt;
&lt;br /&gt;
	def clientConnectionFailed(self, connector, reason):&lt;br /&gt;
		if DEBUG: print 'Connection failed. Reason:', reason&lt;br /&gt;
		ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)&lt;br /&gt;
&lt;br /&gt;
	# blocking method ! must be run in a new thread&lt;br /&gt;
	def release_key(self, key_num, timeOur):&lt;br /&gt;
		m = dummy_proto.dummy_ONOFF_Control()&lt;br /&gt;
		m.setON(key_num)&lt;br /&gt;
		self.protocol.send(m)&lt;br /&gt;
		time.sleep(timeOut)&lt;br /&gt;
		m.setOFF(key_num)&lt;br /&gt;
		self.protocol.send(m)&lt;br /&gt;
		return key_num&lt;br /&gt;
&lt;br /&gt;
class WebResource(resource.Resource):&lt;br /&gt;
	def __init__(self, rpc_server, dummy_client_factory):&lt;br /&gt;
		self.rpc_server = rpc_server&lt;br /&gt;
		self.dummy_client_factory = dummy_client_factory&lt;br /&gt;
		resource.Resource.__init__(self)&lt;br /&gt;
		self.keys_webcontrol_state = [0,0,0,0,0,0,0,0,0,0]&lt;br /&gt;
		&lt;br /&gt;
	def getChild(self, name, request):&lt;br /&gt;
		return self&lt;br /&gt;
&lt;br /&gt;
	def render(self, request):&lt;br /&gt;
		reponse = 0 # NOK par defaut&lt;br /&gt;
		key_num = 0&lt;br /&gt;
		try:&lt;br /&gt;
			sessid = request.args.get('sessid', [&amp;quot;&amp;quot;])[0]&lt;br /&gt;
			password = request.args.get('password', [&amp;quot;&amp;quot;])[0]&lt;br /&gt;
			key_num = int(request.args.get('key', [&amp;quot;0&amp;quot;])[0])&lt;br /&gt;
			response = 0&lt;br /&gt;
			if password:&lt;br /&gt;
                                if hashlib.sha224(password).hexdigest() in PASSWORDS:&lt;br /&gt;
                                        timeOut   = KEY_RELEASE_DURATION&lt;br /&gt;
                                        response_XMLRPC = 1&lt;br /&gt;
                        else:&lt;br /&gt;
                                timeOut   = int(request.args.get('timeout', [&amp;quot;0&amp;quot;])[0])&lt;br /&gt;
                                response = self.rpc_server.checkCommand(sessid, key_num)&lt;br /&gt;
		except Exception, err:&lt;br /&gt;
			if DEBUG: print &amp;quot;error: &amp;quot;, err&lt;br /&gt;
			return &amp;quot;NOK:bad request&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		if response == 1:&lt;br /&gt;
			# Don't try to release a key that is being released&lt;br /&gt;
			if self.keys_webcontrol_state[key_num-1]: return &amp;quot;OK:already released&amp;quot;&lt;br /&gt;
			self.keys_webcontrol_state[key_num-1] = 1&lt;br /&gt;
			d = threads.deferToThread(self.dummy_client_factory.release_key, key_num, timeOut)&lt;br /&gt;
			d.addCallback(self.unset_webcontrol_state)&lt;br /&gt;
			return &amp;quot;OK:releasing key...&amp;quot;&lt;br /&gt;
		else:&lt;br /&gt;
			return &amp;quot;NOK:permission refused&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	def unset_webcontrol_state(self, key_num):&lt;br /&gt;
		self.keys_webcontrol_state[key_num-1] = 0&lt;br /&gt;
&lt;br /&gt;
class OpenKeysService(service.Service):&lt;br /&gt;
	def __init__(self):&lt;br /&gt;
		rpc_server=xmlrpclib.Server(OF_XMLRPC_URL);&lt;br /&gt;
		self.dummy_client_factory = dummyClientFactory(rpc_server)&lt;br /&gt;
		self.web_resource = WebResource(rpc_server, self.dummy_client_factory)&lt;br /&gt;
		&lt;br /&gt;
	def getdummyClientFactory(self):&lt;br /&gt;
		return self.dummy_client_factory&lt;br /&gt;
&lt;br /&gt;
	def getWebResource(self):&lt;br /&gt;
		return self.web_resource&lt;br /&gt;
&lt;br /&gt;
application = service.Application('openkeys')&lt;br /&gt;
f = OpenKeysService()&lt;br /&gt;
serviceCollection = service.IServiceCollection(application)&lt;br /&gt;
internet.TCPClient(KEYS_ADDR, KEYS_PORT, f.getdummyClientFactory()&lt;br /&gt;
				   ).setServiceParent(serviceCollection)&lt;br /&gt;
internet.TCPServer(SERVICE_PORT, server.Site(f.getWebResource())&lt;br /&gt;
				   ).setServiceParent(serviceCollection)&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Maquette de script actionOnDemand.php côté serveur recevant les appels du logiciel de contrôle de l'armoire==&lt;br /&gt;
Ce script nécessite la bibliothèque PEAR [http://pear.php.net/package/XML_RPC2 XML_RPC2].&lt;br /&gt;
&lt;br /&gt;
Pour les tests, il suffit de modifier la valeur de la variable $weDontWant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;php&amp;gt;&amp;lt;?php&lt;br /&gt;
include 'XML/RPC2/Server.php';&lt;br /&gt;
&lt;br /&gt;
class OpenKeysGateway {&lt;br /&gt;
    /**&lt;br /&gt;
     * Update the status of the keys&lt;br /&gt;
     *&lt;br /&gt;
     * @param array $status Status of keys&lt;br /&gt;
     * @return integer 1 if ok, 0 else&lt;br /&gt;
     */&lt;br /&gt;
    public static function notify($status) {&lt;br /&gt;
        $logmsg = &amp;quot;&amp;quot;;&lt;br /&gt;
        foreach ($status as $key_num_from_zero =&amp;gt; $key_pres) {&lt;br /&gt;
            if (!is_numeric($key_pres) || intval($key_pres)!=$key_pres || $key_pres &amp;lt; 0 || $key_pres &amp;gt; 1) continue;&lt;br /&gt;
            if (!is_numeric($key_num_from_zero) || intval($key_num_from_zero)!=$key_num_from_zero &lt;br /&gt;
                || $key_num_from_zero &amp;lt; 0 || $key_num_from_zero &amp;gt; 9) continue;&lt;br /&gt;
            $logmsg .= &amp;quot;&amp;quot;.($key_num_from_zero+1).&amp;quot;:&amp;quot;.$key_pres.&amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        file_put_contents('test.txt', &amp;quot;key notify :&amp;quot;.$logmsg, FILE_APPEND );&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Check if user is able to release the key 'key_num'&lt;br /&gt;
     *&lt;br /&gt;
     * @param string $sessid PHPSESSID of a connected user&lt;br /&gt;
     * @param integer $key_num number of the key to release&lt;br /&gt;
     * @return integer 0:NOK, 1:OK&lt;br /&gt;
     */&lt;br /&gt;
    public static function checkCommand($sessid, $key_num) {&lt;br /&gt;
        /* sanitize input */&lt;br /&gt;
        if (!is_numeric($key_num) || intval($key_num)!=$key_num || $key_num &amp;lt; 1 || $key_num &amp;gt; 10) {&lt;br /&gt;
            return 0;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $weDontWant = 1;&lt;br /&gt;
&lt;br /&gt;
        if ($weDontWant) {&lt;br /&gt;
            file_put_contents('test.txt', &amp;quot;$key_num has no associated airborne aircraft&amp;quot;, FILE_APPEND );&lt;br /&gt;
            return 0;&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
            file_put_contents('test.txt', &amp;quot;granted key: &amp;quot;.$key_num.&amp;quot;:permission granted&amp;quot;, FILE_APPEND );&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$options = array(&lt;br /&gt;
    'autoDocument' =&amp;gt; true,&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
// dirty hack to get things work !&lt;br /&gt;
$GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents('php://input');&lt;br /&gt;
&lt;br /&gt;
$server = XML_RPC2_Server::create('OpenKeysGateway', $options);&lt;br /&gt;
$server-&amp;gt;handleCall();&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&amp;lt;/php&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jtremblet</name></author>
	</entry>
</feed>