[PYTHON] Ein Programm, das den Betriebszustand von vollautomatischen Anlagenfotografieanlagen mitteilt

Die Geschichte der Erstellung eines Python-Programms, das den Betriebsstatus des Pflanzenfotografiegeräts per Slack benachrichtigt

Es stellte sich heraus, dass es so etwas war.

Das Aufnahmegerät stoppt mit einem Fehler. image.png ↓ Es kommt eine Nachricht, in der ich gebeten werde, etwas dagegen zu unternehmen. image.png

Hintergrund

* Pressemitteilung des vollautomatischen Pflanzenexpressionstyp-Analysesystems "RIPPS" *

Artikel: Miki Fujita, Takanari Tanabata, Kaoru Urano, Saya Kikuchi, Kazuo Shinozaki, "RIPPS: Ein Pflanzenphänotypisierungssystem zur quantitativen Bewertung des Wachstums unter kontrollierten Umweltstressbedingungen", Pflanzen- und Zellphysiologie, 10.1093 / pcp / pcy122 //academic.oup.com/pcp/advance-article/doi/10.1093/pcp/pcy122/5043525)

Automatisches Pflanzenbau- und Bildgebungsgerät, entwickelt vom CSRS, Institut für physikalische und chemische Forschung. Einzelheiten finden Sie in der Presse (Japanisch) oben oder in der Zeitung (Englisch, Open Access).

image.png *Fujita et al., 2018*.

Es ist ein Gerät, das Fotos und Wachstumsdaten mit einer eingebauten Kamera im Laufe der Zeit auf einem PC speichert, während Pflanzen auf einem Förderband gedreht werden. Es scheint jedoch, dass es manchmal aufgrund eines Fehlers stoppt. Wir kennen die Details der Ursache nicht, aber es scheint, dass es verschiedene Ursachen gibt, wie z. B. Wassertropfen im Wasserversorgungstank aufgrund von Hardware-Ursachen wie Beschädigung von Teilen und Verschlechterung aufgrund von Haftung von Boden und Lösung. Da sich das Forschungsgebäude zwischen dem Raum, in dem sich der verantwortliche Forscher befindet, und dem Raum, in dem sich das Gerät mit dem Steuer-PC befindet, unterscheidet, war es außerdem schwierig, weiterhin zu überwachen, ob es normal funktioniert. Zuerst dachte ich, ich sollte die letzte Aktualisierungszeit des Speicherzielordners über das Netzwerk anzeigen, aber es gibt Ordner für jeden Kameratyp in einem Gerät und durch Multiplikation mit der Anzahl der Geräte. Angesichts des Anstiegs war dies eine sehr sehr schwierige Situation. Als ich als Benutzer des Bildgebungsgeräts über gemeinsame Forschung sprach, beschloss ich, es eilig zu machen, da dies die Erfassung meiner eigenen experimentellen Daten behindern würde.

Da festgestellt wurde, dass es schwierig ist, die Fehlerbehandlungsfunktion in der Steuerungssoftware zu implementieren (ich möchte die einmal abgeschlossene Hardwaresteuerungssoftware nicht berühren), überwache ich den Aktualisierungsstatus des Ordners von außen und benachrichtige Slack über den Status. Ich habe ein einfaches Programm gemacht. Memorandum und Informationsaustausch unten.

Idee

-python

Programm

1. Laden Sie die erforderlichen Bibliotheken und die automatische Installation

Als ich Python aus der Ferne laufen ließ, stellte ich fest, dass das Anweisen der Pip-Installation ~~~ tatsächlich eine große Hürde war, daher habe ich diesen Teil auch in das Skript aufgenommen.

from pip._internal import main as _main
import importlib

def _import(name, module, ver=None):
    try:
        globals()[name] = importlib.import_module(module)
    except ImportError:
        try:
            if ver is None:
                _main(['install', module])
            else:
                _main(['install', '{}=={}'.format(module, ver)])
            globals()[name] = importlib.import_module(module)
        except:
            print("can't import: {}".format(module))

_import('requests','requests')
_import('argparse','argparse')
_import('json','json')
_import('threading','threading')

Referenz https://vaaaaaanquish.hatenablog.com/entry/2018/12/02/210647 https://stackoverflow.com/questions/12332975/installing-python-module-within-code

Wenn beim Start keine Bibliothek vorhanden ist und ein Importfehler angezeigt wird, installieren Sie diese und versuchen Sie erneut zu importieren. Requests, Argparse, JSON, Threading wurden angegeben, da sie in vielen Fällen nicht standardmäßig installiert wurden.

2. Verwalten Sie Befehlszeilenargumente mit argparse

parser = argparse.ArgumentParser()
parser.add_argument('-i', '--interval',default=1)
parser.add_argument('-d', '--dir', nargs='+', help="pass abs directory pass as list", required = True)
parser.add_argument('-n', '--name',default="RIPPS-Überwachungsprogramm_Erste Ausgabe")

Intervall: Häufigkeit der Dateibestätigung (Zeit) dir: Monitorordner (absoluter Pfad), mehrere können angegeben werden Name: Slack Poster Name

Verwenden Sie wie unten

python monitor.py --dir PATH1 PATH2 --interval 1.5 --name RIPPS_monitoring_robot_1

3. Andere Hardcode-Variablen

SLACK_WEBHOOK = "https://hooks.slack.com/services/XXXXXXXXXXXXX" start = time.time()

4. Erster Scan des Überwachungsordners und Slack Posting

def initiation(path,nfiles):    
	message = "%Überwachung starten s. Derzeit im überwachten Ordner%Es gibt d Dateien.%Suchen Sie alle Stunden nach Updates." % (path,nfiles,args.interval) 
	ellapsed = int(time.time() - start)
	payload_dic = {
		"icon_emoji": ':heartpulse:',
		"text": message,
		"username": args.name + "_" + str(int(ellapsed/(60*60))),
		"channel": "#general", # #Auch benötigt
	}
	try:
		r = requests.post(SLACK_WEBHOOK, data=json.dumps(payload_dic))
	except requests.ConnectionError:
		print(requests.ConnectionError)
		print("Verbindung zum Durchhang konnte nicht hergestellt werden.")

befores = []

for i, path_to_watch in enumerate(args.dir):
	print(path_to_watch)
	assert os.path.isdir(path_to_watch) == True, print("%s is not a valid directory" % path_to_watch)
	if path_to_watch[-1] != "/":
		path_to_watch += "/**"
	else:
		path_to_watch += "**"
	before = dict ([(f, None) for f in glob.glob(path_to_watch,recursive=True)])
	initiation(path_to_watch,len(before))
	args.dir[i] = path_to_watch
	befores.append(before)

Das Folgende ist das Verhalten des Bots, wenn er so eingestellt ist, dass er zwei Ordner überwacht スクリーンショット 2020-01-15 14.37.46.jpg

5. Ordnerüberwachung


def errorpostslack(path):
	error_message = "Überwachter Ordner(%s)Aber%Nicht länger als s Stunden aktualisiert" % (path,args.interval)  #Keine Update-Nachricht
	ellapsed = int(time.time() - start)
	payload_dic = {
		"icon_emoji": ':cry:',
		"text": error_message,
		"username": args.name + "_" + str(int(ellapsed/(60*60))),
		"channel": "#general", # #Auch benötigt
	}
	try:
		r = requests.post(SLACK_WEBHOOK, data=json.dumps(payload_dic))
	except requests.ConnectionError:
		print(requests.ConnectionError)
		print("Verbindung zum Durchhang konnte nicht hergestellt werden.")

while 1:
	time.sleep(float(args.interval)*60*60)
	for i, (before, path_to_watch) in enumerate(zip(befores,args.directory)):
	    after = dict ([(f, None) for f in glob.glob(path_to_watch,recursive=True)])
	    added = [f for f in after if not f in before]
	    removed = [f for f in before if not f in after]
	    if added:
	        print ("Added: ", ", ".join (added))
	        #goodpostslack(added)
	        pass
	    elif removed:
	        print ("Removed: ", ", ".join (removed))
	        pass
	    else:
	        errorpostslack(path_to_watch)
	    befores[i] = after

Ergebnis Clipboard2.jpg

6. Überlebensbericht

Wenn das Aufnahmegerät ordnungsgemäß funktioniert und sich die Bilder weiterhin ansammeln, erfolgt keine Benachrichtigung. Andererseits ist es schwierig, die normale Benachrichtigung in jedem Intervall beizubehalten. Daher werden wir eine Funktion hinzufügen, um das Überleben einmal am Tag zu melden.

def dailynotice():
	message = "Es ist ein regelmäßiger Bericht einmal am Tag."
	ellapsed = int(time.time() - start)
	for i, (before, path_to_watch) in enumerate(zip(befores,args.dir)):
		nfiles = len(glob.glob(path_to_watch,recursive=True))
		message += "%Unter dem Ordner s%Es gibt d Ordner und Dateien" % (path_to_watch,nfiles)
	payload_dic = {
		"icon_emoji": ':smile:',
		"text": message,
		"username": args.name + "_" + str(int(ellapsed/(60*60))),
		"channel": "#general", # #Auch benötigt
	}
	try:
		r = requests.post(SLACK_WEBHOOK, data=json.dumps(payload_dic))
	except requests.ConnectionError:
		print(requests.ConnectionError)
		print("Verbindung zum Durchhang konnte nicht hergestellt werden.")	
    
while 1:
	dailynotice()
	time.sleep(24*60*60)

Ergebnis image.png

7. Koexistenz von Fehlererkennung und Überlebensbericht

Da es zwei while-Schleifen gibt, fädeln Sie sie gleichzeitig ein.

pseudocode
def error_check():
Beobachtete Funktion zur Überprüfung der Ordneraktualisierung
def daily_check():
Überlebensbericht

t1 = Thread(target = error_check)
t2 = Thread(target = daily_check)
t1.start()
t2.start()

8. Schließlich

image.png

	payload_dic = {
		"icon_emoji": ':heartpulse:',
		"text": message,
		"username": args.name + "_" + str(int(ellapsed/(60*60))),
		"channel": "#general", # #Auch benötigt
	}

Recommended Posts

Ein Programm, das den Betriebszustand von vollautomatischen Anlagenfotografieanlagen mitteilt
Ich habe einen schlaffen Bot gemacht, der mich über die Temperatur informiert
[Python] Ein Programm, das die Anzahl der Täler zählt
[Python] Ein Programm, das die Positionen von Kängurus vergleicht.
Die Geschichte des Exportierens eines Programms
[Python] Ein Programm, das den Inhalt der Liste nach links dreht
[Python] Ein Programm, das die Anzahl der Schokoladensegmente berechnet, die die Bedingungen erfüllen
[Python] Ein Programm, das die Anzahl der gepaarten Socken berechnet
[Python] Ein Programm, das die Partitur rundet
Erstellt einen Slack-Bot, der AWS Lambda über das Ablaufdatum eines SSL-Zertifikats bestätigt und benachrichtigt
[Python] Ein Programm, das die Anzahl der Aktualisierungen der höchsten und niedrigsten Datensätze berechnet
Programm zur Suche nach demselben Bild
Ein Shell-Programm, das eine Fibonacci-Sequenz anzeigt
[Python] Ein Programm, das die kürzeste Anzahl von Schritten in einem Spiel findet, das Wolken überquert
Programm, das die CSV-Daten der Transaktionshistorie der SBI Securities-Aktie zusammenfasst [Python3]
Eine Geschichte, die den Aufwand für Betrieb / Wartung reduziert
Erstellen Sie einen BOT, der die Discord-URL verkürzt
#Eine Funktion, die den Zeichencode einer Zeichenfolge zurückgibt
Shell-Programm, das in Vielfachen von 3 aho wird
LINE Bot, der Sie über die interessierenden Aktien informiert
Erzeugen Sie diese Form des Bodens einer Haustierflasche
Eine Geschichte, die die Lieferung von Nico Nama analysierte.
Python-Skript, das den Status des Servers über den Browser überprüfen kann
[Python] Ein Programm, um die Anzahl der Äpfel und Orangen zu ermitteln, die geerntet werden können