2017-03-09 1 views
3

Je suis tombé sur this question en essayant de comprendre comment obtenir un script Python pour envoyer une frappe gauche ou droite après une pression sur le bouton (en utilisant les broches GPIO).Simuler une frappe dans Raspbian avec python

Il semble que la réponse choisie à la question liée est de savoir ce dont j'ai besoin pour démarrer mais après l'installation de xautomation, en essayant d'adapter le code à mon script et en lisant la documentation pour Popen. fichier avec le code verbatim) Je continue à obtenir l'erreur suivante:

Traceback (most recent call last): 
    File "/home/zdistaging/Documents/xte test.py", line 17, in <module> 
    keypress(shift_a_sequence) 
    File "/home/zdistaging/Documents/xte test.py", line 15, in keypress 
    p.communicate(input=sequence) 
    File "/usr/lib/python3.4/subprocess.py", line 941, in communicate 
    self.stdin.write(input) 
TypeError: 'str' does not support the buffer interface 

Je suis en python3 sur un modèle Pi 3 B, en Raspbian Jessie avec Pixel (téléchargé à partir raspberrypi.org)

Toutes les idées Pourquoi est-ce une erreur? Si cela aide du tout, tout ce que j'essaie de faire est de permettre à un utilisateur de faire défiler vers la gauche et la droite dans un diaporama FEH ... Je pourrais être totalement hors de propos avec cette approche apparemment simple est. Je ne cherche pas quelqu'un pour résoudre ceci pour moi directement - j'aime le défi associé au codage - je suis juste super nouveau à python; me pousser dans la bonne direction serait super utile.

Toute aide est grandement appréciée !!!

EDIT: Désolé de ne pas inclure le code!

from subprocess import Popen, PIPE 

control_f4_sequence = '''keydown Control_L 
key F4 
keyup Control_L 
''' 

shift_a_sequence = '''keydown Shift_L 
key A 
keyup Shift_L 
''' 

def keypress(sequence): 
    p = Popen(['xte'], stdin=PIPE) 
    p.communicate(input=sequence) 

keypress(shift_a_sequence) 
keypress(control_f4_sequence) 

EDIT EDIT:

Voici mon code mis à jour ... il imprime en fait des espaces pour les appuyer sur des boutons gauche et droite.

import time 
import RPi.GPIO as GPIO 
from subprocess import Popen, PIPE 
GPIO.setmode(GPIO.BCM) 
GPIO.setwarnings(False) 

leftArrow = '''key \x1B[D''' # I've tried '''key Left''' 
rightArrow = '''key \x1B[C''' # and '''key Right''' with the same results 

offButton = 26  # Black wire 
onButton = 19  # White wire 
leftButton = 13  # Red wire 
rightButton = 6  # Green wire 


def keypress(sequence): 
    if isinstance(sequence, str): 
     sequence = sequence.encode('ascii') 
    p = Popen(['xte'], stdin=PIPE) 
    p.communicate(input=sequence) 


GPIO.setup(offButton, GPIO.IN, GPIO.PUD_UP) 
GPIO.setup(onButton, GPIO.IN, GPIO.PUD_UP) 
GPIO.setup(leftButton, GPIO.IN, GPIO.PUD_UP) 
GPIO.setup(rightButton, GPIO.IN, GPIO.PUD_UP) 


while True: 
    offButton_state = GPIO.input(offButton) 
    onButton_state = GPIO.input(onButton) 
    leftButton_state = GPIO.input(leftButton) 
    rightButton_state = GPIO.input(rightButton) 

    if offButton_state == GPIO.LOW: 
     print("Off button pressed") 

    if onButton_state == GPIO.LOW: 
     print("On button pressed") 

    if leftButton_state == GPIO.LOW: 
     keypress(leftArrow) 
     print("Left button pressed") 

    if rightButton_state == GPIO.LOW: 
     keypress(rightArrow) 
     print("Right button pressed") 

    time.sleep(1) 

J'ai lu jusqu'à avait quelque chose à faire sur subprocess and Popen.communicate() mais ne pouvait pas vraiment dire si le problème avec cela ou avec ce xte is expecting as an argument. Pensées?

+1

Veuillez ajouter le code correspondant à votre question! –

Répondre

1

L'erreur indique que vos séquences de contrôle sont des chaînes (c'est-à-dire unicode), mais que le sous-processus semble attendre des octets.

En fonction keypress, convertir la séquence en octets comme ceci:

if isinstance(sequence, str): 
    sequence = sequence.encode('ascii') 

Une très bonne writeup sur les octets, les chaînes et unicode peuvent être trouvés ici: https://nedbatchelder.com/text/unipain.html

+0

Vache sacrée !!! Cela a fonctionné comme un charme, merci beaucoup !!! Cela fait quelque chose de bizarre ... même si j'ai défini différentes séquences pour les flèches gauche et droite, les deux me donnent des espaces. –

+0

En outre, c'est une écriture impressionnante, merci pour le partage! –

0

J'ai regardé les mêmes exemples, voici mon exemple de travail pour 6 boutons: (il est un peu en désordre, mais mes lignes de débogage peuvent aider les autres aussi)

import time 
import RPi.GPIO as GPIO 
GPIO.setmode(GPIO.BCM) 
GPIO.setwarnings(False) 
from Xlib import X 
from subprocess import Popen, PIPE 

buttons = [18,   23,   24,   25,  8,  7 ] 
opcodes = ['next', 'enter', 'alt tab', 'previous', 'spacebar', 'shift' ] 
opcodes2 = ['key Left ', 'key Up ', 'key Down ', 'key Right ', 'key Enter ', 'key Shift_L '] 

# set the gpio pins 
for button in buttons: 
    GPIO.setup(button, GPIO.IN, GPIO.PUD_UP) 

def keypress(sequence): 
    #if isinstance(sequence, str): 
    #sequence = sequence.encode('ascii') 
    p = Popen(['xte', '-x:0'], stdin=PIPE) 
    p.communicate(input=sequence) 

def main(): 
    while True: 
     button_state = [] 
     for button in buttons: 
      button_state.append(GPIO.input(button)) 

     for item in range(len(button_state)): 
      if button_state[item] == 0: 
       print (opcodes2[item]) #debugging 
      # send X key for keystroke in (for the given iteration of the loop) opcodes[button.output(index)] 
       #print (repr(str(opcodes2[item]).encode('ascii'))) 
       keypress(str(opcodes2[item]).encode('ascii')) 
     print (repr(button_state)) #for debugging 
     time.sleep(0.3) 
     del button_state 

if __name__ == '__main__': 
    main() 

notez l'espace de fin (peut-être n'importe quel caractère) dans opcodes2 par commande. l'encodage ascii laissait tomber le dernier personnage sur moi, donc c'est ma solution de contournement plutôt laide.