[Python] Création d'un package


#1

Bonjour !

Je viens de créer un petit paquet python possédant deux fichiers. Un “button.py” contenant une bibliothèque permettant de gérer les entrées GPIO d’un RPi3 et un fichier index.py contenant toutes les instructions “normales” d’un packet Python.

Le problème est qu’au démarrage, rien ne se passe du tout et la console Constellation indique “Starting script : 'C:…\Scripts\button.py”.

Est-il possible de débuter le fichier “index.py” en priorité ?

Juste pour information, le code du fichier :

import Constellation
from button import *
import time

""" FONCTION : setup
    ================
    Permet de démarer l'écoute des boutons sur les ports GPIO en entrée

    PARAMETRES
    ==========
    pins : liste d'entiers contenant les numéros des pins à écouter

"""
def setup(pins):
    GPIO.setmode(GPIO.BCM)
        
    for i in range(len(pins)):
        Constellation.WriteInfo("Début de l'écoute du bouton %i" % pins[i])
		pinBuffer = pins[i]
		pins[i] = Button(pins[i]) 
		pins[i].addXButtonListener(onButtonEvent)

""" FONCTION : onButtonEvent
    ========================
    Fonction de callback d'un bouton utilisée par la bilbiothèque button.py (voir le fichier pur référence)
"""
def onButtonEvent(button, event):
    if event == BUTTON_LONGPRESSED:
		Constellation.WriteInfo("Bouton %i clique longuement" % button.buttonPin)
    elif event == BUTTON_CLICKED:
        Constellation.WriteInfo("Bouton %i clique simplement" % button.buttonPin)
    elif event == BUTTON_DOUBLECLICKED:
		Constellation.WriteInfo("Bouton %i double clique" % button.buttonPin)

""" PROGRAMME PRINCIPAL
    ===================
"""
def OnStart():

    Constellation.WriteInfo("Démarage du packet Boutons...")
    # On écoute les boutons suivants :
    setup([13,19,16,20,21])
    
    pass

Constellation.Start(OnStart)

#2

Après investigation, il semblerait que Constellation charge les fichiers par ordre alphabétique, j’ai donc changé le nom de mon fichier “index.py” pour qu’il soit chargé à la place de “button.py”.

Cela-dit j’ai un autre soucis parce qu’il me semble que mon fichier button.py pose problème avec Constellation et bloque son fonctionnement (alors qu’il fonctionne sans soucis en Python pur). Celui-ci utilise différents threads pour écouter et repérer les doubles clics par exemples. Est-ce que quelqu’un pourrait jeter un œil et voir comment il serait possible de régler le problème ?

Le code peut se trouver depuis Github sur le lien suivant : https://github.com/CeriseGoutPelican/Package-boutons-GPIO-pour-Constellation/blob/master/Scripts/button.py


#3

Je continue le débug, en vérité, il suffit de faire un import RPi.GPIO as GPIO pour que Constellation ne fonctionne plus du tout… Des idées ?


#4

Bonjour,

Il y a un début d’explication ici : https://developer.myconstellation.io/getting-started/creez-votre-premier-package-constellation-en-python/#Creez_le_package_Python_dans_Visual_Studio

En effet tous les scripts “.py” du dossier “Scripts” sont lancés par ordre alphabétique. Le PythonProxy attend de pouvoir se connecter au script avant de poursuivre c’ets pourquoi on pense “qu’il est planté”.

Pour se connecter il faut faire un Constellation.Start. Seulement cela n’a pas de sens sur les scripts de type “librarie”. Pour cela le Python Proxy ne lance pas les scripts dont le nom de fichier se termine par “lib.py”. Ainsi dans ton cas, je te recommande de renommer ta lib “button” en buttonlib.py ! Mais ceci dit aucun rapport avec l’import RPi.GPIO as GPIO :wink:

Je vais prochainement mettre à jour le PythonProxy dans lequel il y aura un fichier de configuration XML qui déterminera les scripts à lancer ou non (plutôt que jouer avec le nom du fichier), l’ordre de lancement (plutôt que l’ordre alphabétique du nom du fichier) et il n’attendra pas “à l’infini” un script.


#5

Bonjour !

Je viens d’effectivement de repérer le problème de nommage des fichiers et j’ai corrigé ça !

Par contre impossible de faire fonctionne RpI.GPIO. J’ai essayé de partir sur une base de code beaucoup plus simple avec un seul simple fichier (vous pouvez trouver la structure ici : https://github.com/CeriseGoutPelican/ConstellationSimpleClic)

Même en écrivant le code minimal pour un Constellation.WriteInfo(“Hello World”), le packet ne se lance pas si j’ajoute la ligne d’import du GPIO. :-/

Le code est le suivant :

import Constellation 
import RPi.GPIO as GPIO # Pose problème avec constellation

def click(pin):
	Constellation.WriteInfo("Clic sur le bouton %i" % pin)

def OnStart():

    Constellation.WriteInfo("Démarage du packet Boutons simples...")
    
    # On écoute les PINS suivants :
    GPIO.setmode(GPIO.BCM)
    pins = [13,19,16,20,21]

    for i in pins:
	    GPIO.setup(i, GPIO.IN, pull_up_down = GPIO.PUD_UP)
	    GPIO.add_event_detect(i, GPIO.FALLING, callback=click, bouncetime=300)    
    
    pass

Constellation.Start(OnStart)
GPIO.cleanup()

#6

Avant tout je te conseille d’ignorer les répertoires de builds de VS (dossiers “bin” et “obj”) entre autre. Pour cela tu peux reprendre le fichier .gitignore comme celui là que tu placera à la racine de ton repository Git.

Pour ton problème d’import, as-tu bien installer la lib ? Par exemple avec PIP : pip install RPi.GPIO ou via APT : sudo apt-get install RPi.GPIO ?

Car il n’y a pas de problème connu avec cette lib et Constellation. Je l’utilise d’ailleurs dans de nombreux projets dont celui là.


#7

J’arrive bien à lancer le code depuis un script python classique depuis le RPi directement, je ne comprends pas. Dès que je décale le code sur un script Constellation il n’affiche même pas le premier WriteInfo sauf si je mets en commentaire import RPi.GPIO as GPIO (auquel cas j’ai une erreur comme quoi il est importé et le WriteInfo de la ligne 9 fonctionne)


#8

Hum je me demande si tu n’as pas la même erreur que j’ai déjà vu sur un poste d’un de tes camarades.

Tentes d’éditer via nano ton script py sur ton Pi directement (sudo nano /opt/constellation-sentinel/Packages/XXXXXX/Script/monscript.py) et regardes si tout est OK au niveau de l’encodage.

En effet, sur un poste on a remarqué que l’encoding des fins de lignes par VS n’était pas bon sur Linux/Pi et tout le script ne tenait que sur une seule ligne. Ainsi rien ne fonctionnait !

Il fallait faire un “enregistrer sous” dans VS et dans les options avancées remettre des fins de lignes au format Windows (CR LF)


#9

Je viens de vérifier, il n’y pas de soucis d’encodage particulier avec l’éditeur nano.

J’ai, par sécurité, changé l’encodage CR LF de mon fichier et renvoyé le paquet, et je ne suis pas plus avancé malheureusement.

J’ai par curiosité juste généré un projet Python constellation et ajouté l’import GPIO au fichier Demo.py qui ne fonctionne plus après.


#10

On a réinstallé entièrement rasbian, python, constellation et les dépendances, nous en sommes toujours au même point, ça n’a aucun sens


#11

Hello,

Hum je ne comprends pas. Je viens d’installer un RPi (modèle B v2) et créé un nouveau package Python avec le code trouvé ici : https://github.com/CeriseGoutPelican/ConstellationSimpleClic/blob/master/Scripts/main.py

Le package démarre parfaitement :

[rpi2/Sentinel] 09:48:04 : Downloading ConstellationPackagePython2 (URI:http://localhost:8088/packages/ConstellationPackagePython2.zip)
[rpi2/Sentinel] 09:48:04 : Unzipping ConstellationPackagePython2
[rpi2/Sentinel] 09:48:07 : ConstellationPackagePython2 (Package 'ConstellationPackagePython2' version 1.0) is started with the PID 1256 (/opt/constellation-sentinel/Packages/ConstellationPackagePython2/ConstellationPackagePython2.exe)
[rpi2/ConstellationPackagePython2] 09:48:07 : Package connected (Package:1.0 Constellation:1.8.1.16288)
[rpi2/ConstellationPackagePython2] 09:48:08 : Waiting for settings ...
[rpi2/ConstellationPackagePython2] 09:48:08 : Declaring PackageDescriptor for ConstellationPackagePython2
[rpi2/ConstellationPackagePython2] 09:48:08 : Updating 0 setting(s)
[rpi2/ConstellationPackagePython2] 09:48:09 : Calling OnStart on Constellation.PythonProxy.PythonPackage
[rpi2/ConstellationPackagePython2] 09:48:09 : Starting script '/opt/constellation-sentinel/Packages/ConstellationPackagePython2/Scripts/Demo.py'
[rpi2/ConstellationPackagePython2] 09:48:11 : '/opt/constellation-sentinel/Packages/ConstellationPackagePython2/Scripts/Demo.py' is running
[rpi2/ConstellationPackagePython2] 09:48:14 : Démarage du packet Boutons simples...

J’ai ajouté ensuite un WriteInfo à la fin de la méthode OnStart après la configuration des GPIO, sans problème. Comme je suis à distance sans accès physique à mon Pi je n’ai pas testé le FALLING sur les IO mais en principe ca marchera également.

A+


#12

Tout se passe exactement de la même façon sur le RPi3 mais le script s’arrête à l’étape “Starting” sans jamais atteindre le “is running”.

Est-ce que des logs détaillés de l’exécution du paquet sont accessibles ?

[Server/PackageMiddleware] 20:02:25 : 'raspberrypi' getting '/packages/ConstellationButtonsSimpleClick.zip' (Local path: /opt/con
stellation-server/packages/ConstellationButtonsSimpleClick.zip)
[raspberrypi/Sentinel] 20:02:25 : Downloading ConstellationButtonsSimpleClick (URI:http://localhost:8088/packages/ConstellationBu
ttonsSimpleClick.zip)
[raspberrypi/Sentinel] 20:02:25 : Unzipping ConstellationButtonsSimpleClick
[raspberrypi/Sentinel] 20:02:26 : ConstellationButtonsSimpleClick (Package 'ConstellationButtonsSimpleClick' version 1.0) is star
ted with the PID 1457 (/opt/constellation-sentinel/Packages/ConstellationButtonsSimpleClick/ConstellationButtonsSimpleClick.exe)
[raspberrypi/ConstellationButtonsSimpleClick] 20:02:28 : Package connected (Package:1.0 Constellation:1.8.1.16288)
[raspberrypi/ConstellationButtonsSimpleClick] 20:02:29 : Declaring PackageDescriptor for ConstellationButtonsSimpleClick
[raspberrypi/ConstellationButtonsSimpleClick] 20:02:29 : Waiting for settings ...
[raspberrypi/ConstellationButtonsSimpleClick] 20:02:29 : Updating 0 setting(s)
[raspberrypi/ConstellationButtonsSimpleClick] 20:02:29 : Calling OnStart on Constellation.PythonProxy.PythonPackage
[raspberrypi/ConstellationButtonsSimpleClick] 20:02:30 : Starting script '/opt/constellation-sentinel/Packages/ConstellationButto
nsSimpleClick/Scripts/main.py'

#13

De manière assez improbable j’ai recomplété ligne par ligne monde et j’ai réussi à (enfin) le faire fonctionner sur le RPi3 sans problème, avec la gestion des clics simples et longs.

Merci pour votre aide !


#14

Ok super nouvelle ! Ceci dit je n’ai pas compris :wink: Tu as recomplété quoi ?


#15

J’ai repris le packet de zéro puis j’ai ajouté une ligne de code, compilé pour voir si tout fonctionnait, puis recommencé avec une nouvelle ligne… Je n’ai fait pratiquement aucun changement et le code n’a jamais planté. Je ne comprends pas. Je vais bientôt le mettre sur mon GitHub.

Cela dit, j’ai un dernier problème qui n’est pas de lié à Constellation mais plus à Python en général : pour démarrer l’écoute d’un bouton avec mon buttonlib.py il faut écrire les lignes suivantes :


    button_pin = 16
    Constellation.WriteInfo("Début de l'écoute du bouton %i" % button_pin)
    button_16 = Button(button_pin)
    button_16.addXButtonListener(onButtonEvent)
    Constellation.WriteInfo("Bouton %i opérationnel !" % button_pin)

Cependant, j’aimerais utiliser ce code pour écouter 5 boutons différents et si je remplace button_16 par exemple par une liste, cela ne fonctionne plus :


    pin = [13,16,19,20,21]
    for i in range(len(pins)):
        Constellation.WriteInfo("Début de l'écoute du bouton %i" % pins[i])
		pins[i] = Button(pins[i]) 
		pins[i].addXButtonListener(onButtonEvent)

J’imagine que c’est lié au fait que pin[i] devienne alors un objet. Vous avez des idées ? Sinon ce n’est pas grave, je copierait mon premier code cinq fois même si ce n’est pas très propre.


#16

Dans ton code ci-dessus il ya “pin” un tableau de int et “pins” (avec un ‘s’) un tableau de Button.

Je pense que c’est une erreur, mais pins ne peut pas etre à un fois un tableau de int puis un tableau de Button.

Après si ca te sert juste à attacher un event n’est pas obligé de garder un référence, tu pourrais avoir :

pins = [13,16,19,20,21]
for i in range(len(pins)):
  Constellation.WriteInfo("Début de l'écoute du bouton %i" % pins[i])
  bt = Button(pins[i]) 
  bt.addXButtonListener(onButtonEvent)

2ème solutions tu as deux tableaux, un contenant le N° des pins (tableau de int) l’autre tes buttons (tableau de Button)


#17

Ah effectivement la référence n’est pas nécessaire ! Tout fonctionne bien ainsi ! Merci beaucoup !

Juste dernière question au cas où d’un souci qui dure depuis quelques jours : j’ai acheté une matrice LED RGB 8x32 que j’ai réussi à faire fonctionner avec une bibliothèque Adafruit (rpi-ws281x) et ça fonctionnait très bien jusqu’à dimanche (vous pouvez voir l’historique de l’évolution sur plusieurs tweets ici : https://twitter.com/ShiningParadox/status/878332780748447744)

Et maintenant le matrice plante systématiquement avec soit des couleurs aléatoires pastelles (comme ici : https://twitter.com/ShiningParadox/status/879397978372493313) ou alors avec une erreur “Segmentation Fault”. Est-ce que vous pensez que c’est une erreur matérielle ? Comment est-ce qu’on pourrait débugger ça ?


#18

Hello,

Pour info une update du SDK Constellation ainsi que du PythonProxy en version 1.8.2 est dispo depuis hier avec pas mal d’ameiloration sur l’expérience de dev des packages Python.

Toutes les infos ici : https://developer.myconstellation.io/blog/api-python-et-sdk-version-1-8-2/

Bonne fin de journée,