Cet article fait suite au précédent (logique…) présentant les différentes étapes de montage de la machine. Il faut avoir respecté rigoureusement les branchements de l’article en question pour continuer le projet.
Rappel
Nous allons utiliser les ports GPIO du Raspberry Pi pour piloter nos LEDs. C’est ici notre seule et unique objectif. Comme nous l’avons vu dans le précédent article, la LED rouge, témoin d’alimentation de la machine, ne passera pas par le script Python mais simplement par les ports « alimentés » de notre Raspberry Pi. Vous avez normalement branché les autres sur les PINs OUTPUT et GND.
Le script Python gérera la communication entre le Pi et PINs (et donc les LED).
J’ai un serpent dans ma boot
Avant de commencer l’explication sur les différentes lignes de codes que composent notre code, NE FUYER PAS !
Les gens pensent souvent à tort, que le « développement » ou le « code » est un monde inaccessible par sa complexité. Nous allons principalement parler de logique, c’est un domaine tout à fait accessible à tout le monde, la partie technique n’est pas très importante.
Tout le monde peut comprendre le code que nous allons écrire
Grands comme petits pourront parcourir et comprendre le code ci-dessous. Il a été volontairement accès sur l’accessibilité et la facilité de lecture au détriment de l’optimisation.
Python est un langage de programmation, connu pour sa courbe d’apprentissage généreuse et ses multiples utilisations dans le domaine scientifique. De nombreuses librairies sont disponibles pour nous faire gagner du temps et c’est grâce à elles que nous allons programmer notre micro serveur Minecraft.
A l’attaque
Dans un premier temps, nous allons créer notre répertoire de travail sur le Pi. Il est préférable de garder celui utilisé lors de l’installation de Minecraft.
Pour ma part, j’ai choisi de créer un répertoire « script ». Dans un premier temps, connectez-vous à votre Craftbox (Raspberry Pi) en utilisant Putty par exemple.
Pour rappel, il vous suffit de rentrer l’IP de votre machine puis le nom d’utilisateur et le mot de passe. Respectivement « pi » et « raspberry » (sans les guillemets) pour le login par défaut.
Commençons par installer le gestionnaire de paquets (pour les librairies) de Python sur la machine :
sudo apt-get install python3-pip
Je me positionne dans le répertoire courant de Minecraft :
cd /home/minecraft
Puis je créais mon dossier de travail pour le script Python :
sudo mkdir script
Pour rappel, la commande « sudo » vous permet d’accéder temporairement aux droits de l’utilisateur « root » (administrateur), l’utilisateur pi n’ayant pas « tous les droits ». Pour aller dans notre répertoire fraîchement créé :
cd script
Avant de commencer notre fichier, nous allons charger les librairies nécessaires. Le gestionnaire de paquets (pour les librairies je le rappelle) s’appelle PIP comme vous avez pu le voir plus haut :
sudo pip install mcstatus
sudo pip install socket
- mcstatus est une librairie qui surveille l’état de l’instance Minecraft Server présente sur la machine. Elle nous retournera des informations importantes pour notre serveur comme le nombre de joueurs.
- socket est une librairie qui établie une connexion du même nom entre un client et un serveur, nous nous en serviront pour « pinger » (interroger) le site de Google afin de savoir si nous sommes en ligne ou hors ligne.
Puis nous allons créer et éditer le script Python en faisant la commande suivante :
sudo nano script.py
« nano » étant l’éditeur de texte que nous allons utilisé pour écrire notre code (sorte de Notepad si vous préférez.
Une fois dans « nano« , nous allons mettre les mains dans le cambouis ^^, c’est parti pour le code :
#!/usr/bin/env python
# -*- coding: utf-8 -*-
Ces deux premières lignes serviront à l’interprétation du code, la première indique qu’il sagit de code python et la deuxième que nous allons utiliser l’encodage utf8 pour le texte.
Si vous n’êtres pas à l’aise avec ces notions, passez outre, il n’est pas essentiel de maîtriser cette partie.
import RPi.GPIO as GPIO # bibliothèque pour utiliser les GPIO
import time # bibliothèque pour gestion du temps
from mcstatus import MinecraftServer # bibliothéque de status du serveur
import socket
Le code ci-dessus charge les librairies que nous avons préalablement installé et ceux présentes d’origines.
Nous allons définir notre serveur Minecraft et l’associé à une variable globale pour ainsi l’utiliser sur l’ensemble de notre code. Localhost étant la machine sur lequel se situe le serveur et 25565 le port utilisé par le serveur Minecraft (par default) :
server = MinecraftServer.lookup("localhost:25565");
Notre code va être coupé par de multiple portion de code qu’on appelle des « fonctions ». Cela nous permet de mieux découper et lire le code que nous écrivons. Commençons par la portion qui vérifie l’état de la connexion à internet / réseau de la machine :
def is_connected():
try:
host = socket.gethostbyname("www.google.com")
socket.create_connection((host, 80), 2)
print("WIFI fonctionnel")
GPIO.output(21, GPIO.HIGH) # allume la LED jaune
return True
except:
GPIO.output(21, GPIO.LOW)
print("Le wifi ne marche pas !")
pass
return False
- def : définie notre fonction (ou définition) « is_connected() » correspond au nom de la fonction.
- try / except : sécurise notre code en cas d’échec. Try va essayer, dans notre cas, nous allons essayer nous connecter à Google.com grâce à la libraire socket.
Si il y a une erreur, notre code passera dans la portion « except » et éteindra la LED jaune du Wifi positionnée sur la sortie 21 du GPIO.
L’élément GPIO.LOW baisse la tension à 0v et va éteindre la LED.
L’élément GPIO.HIGH baisse la tension à 3.3v et va allumer la LED. - Return true renvoie la valeur « vrai » à l’appelant, sinon ce sera false.
def blink(players):
i = 0
while i < 5:
if players > 0:
GPIO.output(25, GPIO.HIGH)
if players > 1:
GPIO.output(24, GPIO.HIGH)
if players > 2:
GPIO.output(23, GPIO.HIGH)
if players > 3:
GPIO.output(18, GPIO.HIGH)
time.sleep(0.2)
GPIO.output(18, GPIO.LOW)
GPIO.output(23, GPIO.LOW)
GPIO.output(24, GPIO.LOW)
GPIO.output(25, GPIO.LOW)
time.sleep(0.2)
i += 1
Vous l’aurez peut être deviné, c’est la fonction qui va nous permettre de faire clignoter nos différentes LEDs correspondant au nombre de joueurs (de un à quatre). La fonction possède un paramètre « players » qui correspond au nombre de joueurs. La logique est la suivante.
Si la valeur de « players » vaut 2, on va définir la valeur de sortie correspondant au PIN des LED du joueur 1 et 2 sur GPIO.HIGH puis on attend 200ms ensuite on éteint toute les LED avec GPIO.LOW et enfin on attend encore 200ms. Le processus recommence…
- i = 0 déclare une variable à 0 pour notre def (fonction)
- while permet d’exécuter un code tant qu’une condition est respectée, ici tant que i est inférieur à 5.
- time.sleep(0.2) va faire un pause de traitement selon un temps défini, ici 200ms
- i += 1 va incrémenter notre variable locale (à la fonction) c’est la même chose que i = i + 1
def process():
print("Process DEF")
# boucle répétée jusqu'à l'interruption du programme
while True:
# 'status' est supporté par toutes les versions également ou supéreieur à 1.7
status = server.status()
# Affiche les informations sur le nombre de joueurs et le nombre de réponse
print("Le serveur a {0} joueur(s) et répond en {1} ms".format(
status.players.online, status.latency))
if status.players.online > 0:
# Si il y a un ou plusieurs joueurs alors on allume la/les leds
blink(status.players.online)
else:
# Si il n'y a pas de joueur alors on eteint la/les LEDs
GPIO.output(18, GPIO.LOW) # sortie au niveau logique bas (0 V)
GPIO.output(23, GPIO.LOW)
GPIO.output(24, GPIO.LOW)
GPIO.output(25, GPIO.LOW)
time.sleep(3) # on ne change rien pendant 1 seconde
- Process() sera la fonction qui va appeler de manière récurrente la librairie mcstatus et donc notre fonction blink().
- status = server.status() définie une variable avec l’instance de la librairie. Il ira récupérer les informations de notre instance locale de Minecraft Serveur.
- While: true générera une boucle jusqu’à l’interruption du programme.
def setup():
print("Setup")
GPIO.setmode(GPIO.BCM) # Mode de numérotation des pins du GPIO
GPIO.setup(18, GPIO.OUT)
GPIO.setup(21, GPIO.OUT)
GPIO.setup(23, GPIO.OUT)
GPIO.setup(24, GPIO.OUT)
GPIO.setup(25, GPIO.OUT)
print("end setup")
setup() sera notre fonction d’initialisation. indispensable au bon fonctionnement de notre interaction électrique.
- GPIO.setmode(GPIO.BCM) définie le mode de numérotation des pins du GPIO. C’est avec ce système que nous pourront utiliser des nombres pour identifier nos PINs
- GPIO.setup() prépare la PIN en question pour son utilisation future dans la programme.
def destroy():
GPIO.output(18, GPIO.LOW) # eteint la led
GPIO.output(21, GPIO.LOW)
GPIO.output(23, GPIO.LOW)
GPIO.output(24, GPIO.LOW)
GPIO.output(25, GPIO.LOW)
GPIO.cleanup() # Libère les ressources
print("Fin du programme, on sort proprement")
- destroy() est la fonction qui sera utilisée lors de la fermeture du programme. Il faudra, sortir « proprement » pour ne pas endommager notre matériel.
- GPIO.LOW va baisser la tension de sortie au minimum, soit 0v
- GPIO.Cleanup() libère les ressources, notre GPIO ne sera plus contraint.
if __name__ == '__main__': # Le script demarre
while True:
try:
setup()
is_connected()
process()
except KeyboardInterrupt:
destroy()
break
except Exception as err:
destroy()
print('Erreur: ', err)
break
La première ligne du code ci-dessus sera le code qui sera exécuté quand le script sera lancé. C’est notre point d’entré.
- While True génère une boucle infini car la condition est toujours vraie.
- try sécurise le code exécuté à l’intérieur de ce dernier
- except KeyboardInterrupt va exécuter le code quand on va appuyer sur Ctrl + c
- except Exception va exécuter un portion de code si une erreur de type « exception » est capturé dans le try
Terminus le terminal
Voilà pour les explications détaillées, vous pouvez retrouver l’ensemble du code directement sur le dépôt GIT officiel du projet :
https://github.com/paduction/Craftbox
Enfin, faites Ctrl + W pour fermer le fichier, à la confirmation répondez « O » pour valider l’enregistrement du fichier. Nous venons officiellement de créer notre script sur la machine.
Testons le code
Pour tester, nous allons lancer notre script avec la commande python avec pour paramètre notre fichier :
sudo python blink.py
Maintenant que le script est lancé, vous pourrez tester en ajoutant votre Craftbox dans la liste des serveurs multijoueurs, ce qui était déjà le cas normalement si vous avez fait les articles précédents.
En vous connectant, vous devriez voir une LED bleu s’allumer ;)
Evidemment, nous n’allons pas exécuter le script « à la main » à chaque démarrage de la machine au contraire, nous allons réutilisé la même méthode qu’au début du projet en passant par rc.local.
Modifions le fichier ensemble avec la commande :
sudo nano /etc/rc.local
python /home/minecraft/script/blink.py > /home/minecraft/script/log.txt 2>&1 & sh /home/minecraft/autorun-minecraft.sh || /bin/true
Cette ligne est à positionner juste avant la ligne « exit 0 ».
Final Stage
Pour terminer enfin, nous allons redémarrer le serveur avec la commande suivante :
sudo reboot
Si tout s’est bien passé, vous devriez voir la LED jaune s’allumée quelques temps après le redémarrage de la machine. Prenez le temps de tester en vous connectant une fois de plus à votre micro serveur.
Félicitation, vous avez fini votre Craftbox !
Dans un monde parfait, le code fonctionne sans test et du premier coup. Je suis conscient que cette partie peut-être un peu difficile pour certains. Prenez votre temps pour le réaliser, pour le comprendre, relisez bien les différentes étapes et aidez-vous du lien ci-dessous qui contient l’ensemble du code final :
https://github.com/paduction/Craftbox
Si vraiment vous n’arrivez pas à finaliser votre Craftbox, venez en discuter sur le channel dédié du Discord de Paduction, la petite communauté et moi-même essayerons de vous aider le mieux possible ;)
Sommaire du projet Craftbox
- Craftbox : Fabriquer son serveur Minecraft : Installation19 mai 2017
- Craftbox : Fabriquer son serveur Minecraft : Concept et design3 janvier 2018
- Craftbox : Fabriquer son serveur Minecraft : Montage & électronique11 juin 2020
- Craftbox : Fabriquer son serveur Minecraft : Programmation20 novembre 2020
- Craftbox : Fabriquer son serveur Minecraft : Présentation vidéo21 novembre 2020