Seite 2 von 2

Re: Prozess ID mittels Pythonscript beenden

Verfasst: Dienstag 16. Juni 2015, 09:31
von Zappelmann
hallo nochmal zusammen,

also ich hab mitlerweile nachdem ich diese Nacht ziemlich lange mit einem Python versierten Mensch in einem IRC Chat getextet habe, eine Lösung gefunden.

hier kurz das Script, falls das nochmal jemand fragen sollte.

Code: Alles auswählen

        elif line=="start autonom":
            pollster.auto_command = autonom1()
            self.send('\r\n')
        elif line=="stop autonom":
            pollster.auto_command.terminate()
            self.send('\r\n')
            pollster.auto_command.wait()
            GPIO.cleanup()

def autonom1():
    command = ["sudo", "python", "robot-umbau-3.py"]
    return subprocess.Popen(command)



und nochmal Danke auch für Eure Geduld und Hilfestellungen.....

MFG

Zappelmann

Re: Prozess ID mittels Pythonscript beenden

Verfasst: Dienstag 16. Juni 2015, 12:21
von BlackJack
@Zappelmann: Was passiert wenn man gleich nach dem der Server gestartet wurde "stop autonom" sendet‽ Was passiert wenn man zwei (oder mehr) mal "start autonom" sendet‽

Re: Prozess ID mittels Pythonscript beenden

Verfasst: Dienstag 16. Juni 2015, 14:43
von Zappelmann
@BackJack,

Also wenn die Reihenfolge eingehalten wird dann passiert nichts, außer dass das Script beendet wird.
Aber wenn man versehentlich oder mit absicht drauf tippt, dann erzeugt das tatsächlich ein Error.

error: uncaptured python exception, closing channel <__main__.Client connected 192.168.2.30:45834 at 0xb69de2d8> (<type 'exceptions.AttributeError'>:'EPoll' object has no attribute 'auto_command' [netio_server-test-2.py|readwrite|181] [/usr/lib/python2.7/asyncore.py|handle_read_event|449] [netio_server-test-2.py|handle_read|48] [netio_server-test-2.py|handle_command|93])


kann ich das irgendwie abfangen, damit das nicht passiert?

Re: Prozess ID mittels Pythonscript beenden

Verfasst: Dienstag 16. Juni 2015, 14:50
von BlackJack
@Zappelmann: Ja natürlich kann man das ”abfangen”. Man muss halt jeweils testen ob bereits das externe Programm gestartet wurde oder nicht und beim beenden auch das Attribut wieder auf einen Wert setzt der ”kein Prozess” bedeutet. `None` würde sich da als Wert anbieten. Dass das Objekt dieses Attribut *gar nicht* besitzt ist übrigens sehr unschön weil das bedeutet das dieses Attribut ausserhalb der `__init__()`-Methode eingeführt wird, was man nicht machen sollte weil man dann die gesamte Klasse lesen muss um zu sehen welche Attribute solche Objekte besitzen.

Re: Prozess ID mittels Pythonscript beenden

Verfasst: Dienstag 16. Juni 2015, 14:53
von Zappelmann
aktuelles Script.....

Code: Alles auswählen

import asyncore
import socket
import select
import RPi.GPIO as GPIO
import serial
import time
import os
import signal
import subprocess
import sys

GPIO.setup
GPIO.setwarnings(False)
GPIO.cleanup()

GPIO.setmode(GPIO.BOARD)

GPIO.setup(19,GPIO.OUT)
GPIO.setup(7,GPIO.OUT)
GPIO.setup(22,GPIO.OUT)
GPIO.setup(11,GPIO.OUT)


class Client(asyncore.dispatcher_with_send):
    def __init__(self, socket=None, pollster=None):
        asyncore.dispatcher_with_send.__init__(self, socket)
        self.data = ''
        if pollster:
            self.pollster = pollster
            pollster.register(self, select.EPOLLIN)

    def handle_close(self):
        if self.pollster:
#            self.pollster.unregister(self)
#            self.pollster=None
           p=self.pollster
           self.pollster=None
           p.unregister(self)

    def handle_read(self):
        receivedData = self.recv(8192)
        if not receivedData:
            self.close()
            return
        receivedData = self.data + receivedData
        while '\n' in receivedData:
            line, receivedData = receivedData.split('\n',1)
            self.handle_command(line)
        self.data = receivedData

    def handle_command(self, line):
        print repr(line)
        if line=="forward start":
            Vorwaerts_fahren()
            self.send('\r\n')
        elif line=="forward stop":
            Stop()
            self.send('\r\n')
        elif line=="forward left":
            Links_fahren_voll()
            self.send('\r\n')
        elif line=="forward stop":
            Stop()
            self.send('\r\n')
        elif line=="forward right":
            Rechts_fahren_voll()
            self.send('\r\n')
        elif line=="forward stop":
            Stop()
            self.send('\r\n')
        elif line=="backward start":
            Rueckwaerts_fahren()
            self.send('\r\n')
        elif line=="backward stop":
            Stop()
            self.send('\r\n')
        elif line=="poweroff":
            shutdown()
            self.send('\r\n')
        elif line=="forward stop":
            Stop()
            self.send('\r\n')
        elif line=="/usr/bin/sudo /sbin/shutdown -r now":
            restart()
            self.send('\r\n')
        elif line=="forward stop":
            Stop()
            self.send('\r\n')
        elif line=="start autonom":
            pollster.auto_command = autonom1()
            self.send('\r\n')
        elif line=="stop autonom":
            pollster.auto_command.terminate()
            self.send('\r\n')
            pollster.auto_command.wait()
            GPIO.cleanup()
        elif line=="GPIO.cleanup()":
            gpiooff()
            self.send('\r\n')
#        if line=="cd Downloads/raspirobotboard-master/examples":
#            cd()
#            self.send('ok\n')
#        else:
#            self.send('unknown Command\n')
#            print 'unknown Command:', line

def ControlAPairOfPins(FirstPin,FirstState,SecondPin,SecondState):
    if FirstState == "1":
        GPIO.output(int(FirstPin),True)
    else:
        GPIO.output(int(FirstPin),False)
    if SecondState == "1":
        GPIO.output(int(SecondPin),True)
    else:
        GPIO.output(int(SecondPin),False)
    return

def Stop():
    ControlAPairOfPins("19","0","7","0")
    ControlAPairOfPins("22","0","11","0")

def Vorwaerts_fahren():
    ControlAPairOfPins("19","1","7","0")
    ControlAPairOfPins("22","1","11","1")

def Rechts_fahren_voll():
    ControlAPairOfPins("19","1","7","1")
    ControlAPairOfPins("22","1","11","1")

def Links_fahren_voll():
    ControlAPairOfPins("19","1","7","0")
    ControlAPairOfPins("22","0","11","1")

def Rueckwaerts_fahren():
    ControlAPairOfPins("19","1","7","1")
    ControlAPairOfPins("22","0","11","1")

def shutdown():
    os.system("poweroff")

def restart():
    command = "/usr/bin/sudo /sbin/shutdown -r now"
    proc = subprocess.Popen(['sudo','reboot'])
    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
    output = process.communicate()[0]
    print output


def autonom1():
    command = ["sudo", "python", "robot-umbau-3.py"]
    return subprocess.Popen(command)

def gpiooff():
    GPIO.cleanup()

#def chaser():
#    command = "sudo python led-chaser-small.py"
#    import subprocess
#    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
#    output = process.communicate()[0]
#    print output


class Server(asyncore.dispatcher):
    def __init__(self, listen_to, pollster):
        asyncore.dispatcher.__init__(self)
        self.pollster = pollster
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.bind(listen_to)
        self.listen(5)

    def handle_accept(self):
        newSocket, address = self.accept()
        print "Connected from", address
        Client(newSocket,self.pollster)

def readwrite(obj, flags):
    try:
        if flags & select.EPOLLIN:
            print >>sys.stderr, "1"
            obj.handle_read_event()
            print >>sys.stderr, "2"
        if flags & select.EPOLLOUT:
            print >>sys.stderr, "3"
            obj.handle_write_event()
            print >>sys.stderr, "4"
        if flags & select.EPOLLPRI:
            print >>sys.stderr, "5"
            obj.handle_expt_event()
            print >>sys.stderr, "6"
        if flags & (select.EPOLLHUP | select.EPOLLERR | select.POLLNVAL):
            print >>sys.stderr, "7"
            obj.handle_close()
            print >>sys.stderr, "8"
    except socket.error, e:
        print >>sys.stderr, "9"
        if e.args[0] not in asyncore._DISCONNECTED:
            print >>sys.stderr, "10"
            obj.handle_error()
            print >>sys.stderr, "11"
        else:
            print >>sys.stderr, "12"
            obj.handle_close()
            print >>sys.stderr, "13"
    except asyncore._reraised_exceptions:
        print >>sys.stderr, "14"
        raise
        print >>sys.stderr, "15"
    except:
        print >>sys.stderr, "16"
        obj.handle_error()
        print >>sys.stderr, "17"


class EPoll(object):
    def __init__(self):
        self.epoll = select.epoll()
        self.fdmap = {}
    def register(self, obj, flags):
        fd = obj.fileno()
        self.epoll.register(fd, flags)
        self.fdmap[fd] = obj
    def unregister(self, obj):
        fd = obj.fileno()
        del self.fdmap[fd]
        self.epoll.unregister(fd)
    def poll(self):
        evt = self.epoll.poll()
        for fd, flags in evt:
            yield self.fdmap[fd], flags


if __name__ == "__main__":
    pollster = EPoll()
    pollster.register(Server(("",12340),pollster), select.EPOLLIN)
    while True:
        evt = pollster.poll()
        for obj, flags in evt:
            readwrite(obj, flags)


Re: Prozess ID mittels Pythonscript beenden

Verfasst: Donnerstag 18. Juni 2015, 19:20
von Zappelmann
Jo Hallo zusammen,

also ich hab das Script jetzt nochmal überarbeitet.
siehe http://paste.debian.net/238647/

Jedoch hat sich da irgendein fehler eingeschlichen den ich irgendwie übersehe.
Denn es ist so das Eigentlich alles funzt nur ds er jetzt das autonom Script wieder nicht beendet.
Irgendwo im dem Abschnitt von Zeile 96 - 110 sitzt woh der Fehler.
Die debug Ausgabe Zeigt mir das der schon beim (stop autonom 1) anhält und nicht in die Nächste Zeile springt.

Kann sich dass mal jemand bitte ansehen.....

MFG

Zappelmann

Re: Prozess ID mittels Pythonscript beenden

Verfasst: Freitag 19. Juni 2015, 07:06
von Sirius3
@Zappelmann: welche der vielen Debugausgaben wird denn ausgegeben? Alle? Oder bleibt er an einer Stelle stehen?

Re: Prozess ID mittels Pythonscript beenden

Verfasst: Freitag 19. Juni 2015, 17:34
von Zappelmann
also die Problematik auch mit dem Einwand des mehrfachen Befehlseingabe "stop autonom" ist jetzt am funktionieren. Habs vorerst gelöst bekommen.

hier der Link http://paste.debian.net/241471/ zum aktuellen Script.

MFG

Zappelmann