1
0
mirror of https://github.com/naruxde/revpipycontrol.git synced 2025-11-08 15:43:52 +01:00

RevPiLogfile auf neue Byte?bertragung angepasst

Reaktion auf Fehlerbytes vom RevPi f?r Logfile
In Dialogfenster ESC zum schlie?en eingebaut
_checkclose Funktionen zur Pr?fung auf ?nderung und Schlie?en hinzugef?gt
This commit is contained in:
2017-06-29 20:11:55 +02:00
parent 1f668b153c
commit a60431e456
8 changed files with 314 additions and 176 deletions

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Project SYSTEM "Project-5.1.dtd"> <!DOCTYPE Project SYSTEM "Project-5.1.dtd">
<!-- eric project file for project revpipycontrol --> <!-- eric project file for project revpipycontrol -->
<!-- Saved: 2017-06-28, 17:00:06 --> <!-- Saved: 2017-06-29, 17:51:42 -->
<!-- Copyright (C) 2017 Sven Sager, akira@narux.de --> <!-- Copyright (C) 2017 Sven Sager, akira@narux.de -->
<Project version="5.1"> <Project version="5.1">
<Language>en_US</Language> <Language>en_US</Language>
@@ -9,7 +9,7 @@
<ProgLanguage mixed="0">Python3</ProgLanguage> <ProgLanguage mixed="0">Python3</ProgLanguage>
<ProjectType>Console</ProjectType> <ProjectType>Console</ProjectType>
<Description></Description> <Description></Description>
<Version>0.4.0</Version> <Version>0.4.1</Version>
<Author>Sven Sager</Author> <Author>Sven Sager</Author>
<Email>akira@narux.de</Email> <Email>akira@narux.de</Email>
<Eol index="-1"/> <Eol index="-1"/>

View File

@@ -1,8 +1,8 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: RevPiPyControl 0.4.0\n" "Project-Id-Version: RevPiPyControl 0.4.0\n"
"POT-Creation-Date: 2017-06-29 12:59+0200\n" "POT-Creation-Date: 2017-06-29 20:10+0200\n"
"PO-Revision-Date: 2017-06-29 13:03+0200\n" "PO-Revision-Date: 2017-06-29 20:10+0200\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"Language: de\n" "Language: de\n"
@@ -43,39 +43,56 @@ msgstr "Aktualisiere automatisch"
msgid "Write values to RevPi" msgid "Write values to RevPi"
msgstr "Schreibe Werte auf RevPi" msgstr "Schreibe Werte auf RevPi"
#: revpilogfile.py:27 #: revpilogfile.py:37
msgid "RevPi Python PLC Logs" msgid "RevPi Python PLC Logs"
msgstr "RevPi Python PLC Logdaten" msgstr "RevPi Python PLC Logdaten"
#: revpilogfile.py:40 #: revpilogfile.py:50
msgid "RevPiPyLoad - Logfile" msgid "RevPiPyLoad - Logfile"
msgstr "RevPiPyLoad - Logdatei" msgstr "RevPiPyLoad - Logdatei"
#: revpilogfile.py:44 revpilogfile.py:59 #: revpilogfile.py:54 revpilogfile.py:69
msgid "Clear screen" msgid "Clear screen"
msgstr "Leere Ansicht" msgstr "Leere Ansicht"
#: revpilogfile.py:55 #: revpilogfile.py:65
msgid "Python PLC program - Logfile" msgid "Python PLC program - Logfile"
msgstr "Python PLC Programm - Logdatei" msgstr "Python PLC Programm - Logdatei"
#: revpioption.py:33 #: revpilogfile.py:145
msgid "Can not access log file on the RevPi"
msgstr "RevPi kann auf Logdatei nicht zugreifen"
#: revpioption.py:61 revpioption.py:273 revpioption.py:298 revpiplclist.py:58
#: revpiplclist.py:175 revpiprogram.py:370 revpiprogram.py:418
msgid "Question"
msgstr "Frage"
#: revpioption.py:62 revpiplclist.py:59
msgid ""
"Do you really want to quit? \n"
"Unsaved changes will be lost"
msgstr ""
"Wollen Sie wirklich beenden? \n"
"Nicht gespeicherte Änderungen gehen verloren"
#: revpioption.py:72
msgid "RevPi Python PLC Options" msgid "RevPi Python PLC Options"
msgstr "RevPi Python PLC Einstellungen" msgstr "RevPi Python PLC Einstellungen"
#: revpioption.py:41 #: revpioption.py:80
msgid "Start / Stop behavior" msgid "Start / Stop behavior"
msgstr "Start / Stop Verhalten" msgstr "Start / Stop Verhalten"
#: revpioption.py:50 #: revpioption.py:89
msgid "Start program automatically" msgid "Start program automatically"
msgstr "Starte Programm automatisch" msgstr "Starte Programm automatisch"
#: revpioption.py:56 #: revpioption.py:95
msgid "Restart program after exit" msgid "Restart program after exit"
msgstr "Starte Programm nach Beenden neu" msgstr "Starte Programm nach Beenden neu"
#: revpioption.py:63 #: revpioption.py:103
msgid "" msgid ""
"Set process image to NULL if program\n" "Set process image to NULL if program\n"
"terminates successfully" "terminates successfully"
@@ -83,7 +100,7 @@ msgstr ""
"\"Prozessabbild auf NULL setzen, wenn Programm\n" "\"Prozessabbild auf NULL setzen, wenn Programm\n"
"\"erfolgreich beendet wird\"" "\"erfolgreich beendet wird\""
#: revpioption.py:70 #: revpioption.py:111
msgid "" msgid ""
"Set process image to NULL if program\n" "Set process image to NULL if program\n"
"terminates with errors" "terminates with errors"
@@ -91,35 +108,35 @@ msgstr ""
"Prozessabbild auf NULL setzen, wenn Programm\n" "Prozessabbild auf NULL setzen, wenn Programm\n"
"fehlerhaft beendet wird" "fehlerhaft beendet wird"
#: revpioption.py:77 #: revpioption.py:118
msgid "PLC program" msgid "PLC program"
msgstr "PLC Programm" msgstr "PLC Programm"
#: revpioption.py:88 #: revpioption.py:129
msgid "Python version" msgid "Python version"
msgstr "Python Version" msgstr "Python Version"
#: revpioption.py:105 #: revpioption.py:146
msgid "Python PLC program name" msgid "Python PLC program name"
msgstr "Python PLC Programmname" msgstr "Python PLC Programmname"
#: revpioption.py:117 #: revpioption.py:158
msgid "Program arguments" msgid "Program arguments"
msgstr "Programmargumente" msgstr "Programmargumente"
#: revpioption.py:126 #: revpioption.py:167
msgid "Use RevPi as PLC-Slave" msgid "Use RevPi as PLC-Slave"
msgstr "RevPi als PLC-Slave verwenden" msgstr "RevPi als PLC-Slave verwenden"
#: revpioption.py:133 #: revpioption.py:174
msgid "XML-RPC server" msgid "XML-RPC server"
msgstr "XML-RPC Server" msgstr "XML-RPC Server"
#: revpioption.py:145 #: revpioption.py:186
msgid "Activate XML-RPC server on RevPi" msgid "Activate XML-RPC server on RevPi"
msgstr "Aktiviere XML-RPC Server auf RevPi" msgstr "Aktiviere XML-RPC Server auf RevPi"
#: revpioption.py:153 #: revpioption.py:194
msgid "" msgid ""
"Allow download of piCtory configuration and\n" "Allow download of piCtory configuration and\n"
"PLC programm" "PLC programm"
@@ -127,7 +144,7 @@ msgstr ""
"Download von piCtroy Konfiguration und\n" "Download von piCtroy Konfiguration und\n"
"PLC Programm zulassen" "PLC Programm zulassen"
#: revpioption.py:160 #: revpioption.py:201
msgid "" msgid ""
"Allow upload of piCtory configuration and\n" "Allow upload of piCtory configuration and\n"
"PLC programm" "PLC programm"
@@ -135,24 +152,19 @@ msgstr ""
"Hochladen von piCtroy Konfiguration und\n" "Hochladen von piCtroy Konfiguration und\n"
"PLC Programm zulassen" "PLC Programm zulassen"
#: revpioption.py:165 #: revpioption.py:206
msgid "XML-RPC server port" msgid "XML-RPC server port"
msgstr "XML-RPC Serverport" msgstr "XML-RPC Serverport"
#: revpioption.py:179 revpiplclist.py:111 #: revpioption.py:220 revpiplclist.py:125
msgid "Save" msgid "Save"
msgstr "Speichern" msgstr "Speichern"
#: revpioption.py:184 revpiplclist.py:114 #: revpioption.py:225 revpiplclist.py:128
msgid "Close" msgid "Close"
msgstr "Schließen" msgstr "Schließen"
#: revpioption.py:230 revpioption.py:254 revpiplclist.py:150 #: revpioption.py:274
#: revpiplclist.py:175 revpiprogram.py:370 revpiprogram.py:418
msgid "Question"
msgstr "Frage"
#: revpioption.py:231
msgid "" msgid ""
"The settings are now saved on the Revolution Pi. \n" "The settings are now saved on the Revolution Pi. \n"
"\n" "\n"
@@ -164,29 +176,29 @@ msgstr ""
"Sollen die neuen Einstellungen sofort in Kraft treten?\n" "Sollen die neuen Einstellungen sofort in Kraft treten?\n"
"Dies bedeutet einen Neustart des Dienstes und des laufenden PLC-Programms!" "Dies bedeutet einen Neustart des Dienstes und des laufenden PLC-Programms!"
#: revpioption.py:239 revpiplclist.py:190 revpiprogram.py:65 #: revpioption.py:282 revpiplclist.py:190 revpiprogram.py:65
msgid "Information" msgid "Information"
msgstr "Information" msgstr "Information"
#: revpioption.py:240 #: revpioption.py:283
msgid "Settings saved" msgid "Settings saved"
msgstr "Einstellungen gespeichert" msgstr "Einstellungen gespeichert"
#: revpioption.py:245 revpiplclist.py:198 revpiprogram.py:306 #: revpioption.py:288 revpiplclist.py:198 revpiprogram.py:306
#: revpiprogram.py:337 revpiprogram.py:400 revpiprogram.py:433 #: revpiprogram.py:337 revpiprogram.py:400 revpiprogram.py:433
#: revpiprogram.py:517 revpiprogram.py:589 revpiprogram.py:620 #: revpiprogram.py:515 revpiprogram.py:587 revpiprogram.py:618
#: revpiprogram.py:633 revpiprogram.py:682 revpiprogram.py:702 #: revpiprogram.py:631 revpiprogram.py:686 revpiprogram.py:706
#: revpiprogram.py:710 revpipycontrol.py:307 #: revpiprogram.py:714 revpipycontrol.py:325
msgid "Error" msgid "Error"
msgstr "Fehler" msgstr "Fehler"
#: revpioption.py:246 #: revpioption.py:289
msgid "The settings could not be saved. This can happen if values are wrong!" msgid "The settings could not be saved. This can happen if values are wrong!"
msgstr "" msgstr ""
"Die Einstellungen konnten nicht gesichert werden. Dies kann passieren, wenn " "Die Einstellungen konnten nicht gesichert werden. Dies kann passieren, wenn "
"Werte falsch sind!" "Werte falsch sind!"
#: revpioption.py:255 #: revpioption.py:299
msgid "" msgid ""
"Are you sure you want to deactivate the XML-RPC server? You will NOT be able " "Are you sure you want to deactivate the XML-RPC server? You will NOT be able "
"to access the Revolution Pi with this program." "to access the Revolution Pi with this program."
@@ -194,42 +206,34 @@ msgstr ""
"Soll der XML-RPC Server wirklich beendet werden? Sie können dann NICHT mehr " "Soll der XML-RPC Server wirklich beendet werden? Sie können dann NICHT mehr "
"mit diesem Programm auf den Revolution Pi zugreifen." "mit diesem Programm auf den Revolution Pi zugreifen."
#: revpiplclist.py:54 #: revpiplclist.py:68
msgid "RevPi Python PLC connections" msgid "RevPi Python PLC connections"
msgstr "RevPi Python PLC Verbindungen" msgstr "RevPi Python PLC Verbindungen"
#: revpiplclist.py:74 #: revpiplclist.py:88
msgid "Name" msgid "Name"
msgstr "Name" msgstr "Name"
#: revpiplclist.py:81 #: revpiplclist.py:95
msgid "IP address" msgid "IP address"
msgstr "IP Adresse" msgstr "IP Adresse"
#: revpiplclist.py:89 #: revpiplclist.py:103
msgid "Port" msgid "Port"
msgstr "Port" msgstr "Port"
#: revpiplclist.py:98 #: revpiplclist.py:112
msgid "New" msgid "New"
msgstr "Neu" msgstr "Neu"
#: revpiplclist.py:101 #: revpiplclist.py:115
msgid "Apply" msgid "Apply"
msgstr "Übernehmen" msgstr "Übernehmen"
#: revpiplclist.py:105 #: revpiplclist.py:119
msgid "Remove" msgid "Remove"
msgstr "Entfernen" msgstr "Entfernen"
#: revpiplclist.py:151
msgid ""
"Do you really want to quit? \n"
"Unsaved changes will be lost"
msgstr ""
"Wollen Sie wirklich beenden? \n"
"Nicht gespeicherte Änderungen gehen verloren"
#: revpiplclist.py:176 #: revpiplclist.py:176
msgid "Do you really want to delete the selected connection '{}'" msgid "Do you really want to delete the selected connection '{}'"
msgstr "Wollen Sie die ausgewählte Verbindung '{}' wirklich löschen?" msgstr "Wollen Sie die ausgewählte Verbindung '{}' wirklich löschen?"
@@ -268,12 +272,12 @@ msgid "Files"
msgstr "Dateien" msgstr "Dateien"
#: revpiprogram.py:98 revpiprogram.py:100 revpiprogram.py:465 #: revpiprogram.py:98 revpiprogram.py:100 revpiprogram.py:465
#: revpiprogram.py:573 #: revpiprogram.py:571
msgid "Zip archive" msgid "Zip archive"
msgstr "Zip Archiv" msgstr "Zip Archiv"
#: revpiprogram.py:98 revpiprogram.py:100 revpiprogram.py:478 #: revpiprogram.py:98 revpiprogram.py:100 revpiprogram.py:478
#: revpiprogram.py:603 #: revpiprogram.py:601
msgid "TGZ archive" msgid "TGZ archive"
msgstr "TGZ Archiv" msgstr "TGZ Archiv"
@@ -341,7 +345,7 @@ msgstr "piControlReset ausführen"
msgid "execute" msgid "execute"
msgstr "ausführen" msgstr "ausführen"
#: revpiprogram.py:216 revpipycontrol.py:96 #: revpiprogram.py:216 revpipycontrol.py:95
msgid "Exit" msgid "Exit"
msgstr "Beenden" msgstr "Beenden"
@@ -355,22 +359,22 @@ msgid "piCtory config"
msgstr "piCtory Konfiguration" msgstr "piCtory Konfiguration"
#: revpiprogram.py:299 revpiprogram.py:330 revpiprogram.py:362 #: revpiprogram.py:299 revpiprogram.py:330 revpiprogram.py:362
#: revpiprogram.py:465 revpiprogram.py:478 revpiprogram.py:548 #: revpiprogram.py:465 revpiprogram.py:478 revpiprogram.py:546
#: revpiprogram.py:573 revpiprogram.py:603 #: revpiprogram.py:571 revpiprogram.py:601
msgid "All files" msgid "All files"
msgstr "Alle Dateien" msgstr "Alle Dateien"
#: revpiprogram.py:307 revpiprogram.py:338 revpiprogram.py:518 #: revpiprogram.py:307 revpiprogram.py:338 revpiprogram.py:516
msgid "Could not load and save file!" msgid "Could not load and save file!"
msgstr "Datei konnte nicht geladen und gespeichert werden!" msgstr "Datei konnte nicht geladen und gespeichert werden!"
#: revpiprogram.py:312 revpiprogram.py:343 revpiprogram.py:381 #: revpiprogram.py:312 revpiprogram.py:343 revpiprogram.py:381
#: revpiprogram.py:389 revpiprogram.py:427 revpiprogram.py:523 #: revpiprogram.py:389 revpiprogram.py:427 revpiprogram.py:521
#: revpiprogram.py:672 #: revpiprogram.py:676
msgid "Success" msgid "Success"
msgstr "Erfolgreich" msgstr "Erfolgreich"
#: revpiprogram.py:313 revpiprogram.py:344 revpiprogram.py:524 #: revpiprogram.py:313 revpiprogram.py:344 revpiprogram.py:522
msgid "File successfully loaded and saved." msgid "File successfully loaded and saved."
msgstr "Dateien erfolgreich übertragen und gespeichert." msgstr "Dateien erfolgreich übertragen und gespeichert."
@@ -408,8 +412,8 @@ msgstr ""
"Die piCtory Konfiguration konnte auf dem Revolution Pi nicht geschrieben " "Die piCtory Konfiguration konnte auf dem Revolution Pi nicht geschrieben "
"werden." "werden."
#: revpiprogram.py:407 revpipycontrol.py:199 revpipycontrol.py:246 #: revpiprogram.py:407 revpipycontrol.py:211 revpipycontrol.py:250
#: revpipycontrol.py:266 #: revpipycontrol.py:268 revpipycontrol.py:286
msgid "Warning" msgid "Warning"
msgstr "Warnung" msgstr "Warnung"
@@ -441,104 +445,124 @@ msgstr "piControl Reset konnte nicht erfolgreich durchgeführt werden"
msgid "Directory to save" msgid "Directory to save"
msgstr "Verzeichnis zum Ablegen" msgstr "Verzeichnis zum Ablegen"
#: revpiprogram.py:558 #: revpiprogram.py:556
msgid "Folder to upload" msgid "Folder to upload"
msgstr "Verzeichnis zum Hochladen" msgstr "Verzeichnis zum Hochladen"
#: revpiprogram.py:569 #: revpiprogram.py:567
msgid "Upload Zip archive..." msgid "Upload Zip archive..."
msgstr "Zip Archiv hochladen..." msgstr "Zip Archiv hochladen..."
#: revpiprogram.py:590 #: revpiprogram.py:588
msgid "The specified file is not a ZIP archive." msgid "The specified file is not a ZIP archive."
msgstr "Die angegebene Datei ist kein ZIP Archiv" msgstr "Die angegebene Datei ist kein ZIP Archiv"
#: revpiprogram.py:599 #: revpiprogram.py:597
msgid "Upload TarGz archiv..." msgid "Upload TarGz archiv..."
msgstr "TarGz Archiv hochladen..." msgstr "TarGz Archiv hochladen..."
#: revpiprogram.py:621 #: revpiprogram.py:619
msgid "The specified file is not a TAR archive." msgid "The specified file is not a TAR archive."
msgstr "Die angegebene Datei ist kein TAR Archiv." msgstr "Die angegebene Datei ist kein TAR Archiv."
#: revpiprogram.py:634 #: revpiprogram.py:632
msgid "There was an error deleting the files on the Revolution Pi." msgid "There was an error deleting the files on the Revolution Pi."
msgstr "" msgstr ""
"Beim Löschen der Dateien auf dem Revolution Pi ist ein Fehler aufgetreten." "Beim Löschen der Dateien auf dem Revolution Pi ist ein Fehler aufgetreten."
#: revpiprogram.py:673 #: revpiprogram.py:677
msgid "The transfer was successful." msgid "The transfer was successful."
msgstr "Die Übertragung war erfolgreich." msgstr "Die Übertragung war erfolgreich."
#: revpiprogram.py:683 #: revpiprogram.py:687
msgid "There is no piCtory configuration in this archive." msgid "There is no piCtory configuration in this archive."
msgstr "Es wurde keine piCtory Konfiguration im Archiv gefunden." msgstr "Es wurde keine piCtory Konfiguration im Archiv gefunden."
#: revpiprogram.py:703 #: revpiprogram.py:707
msgid "The Revolution Pi could not process some parts of the transmission." msgid "The Revolution Pi could not process some parts of the transmission."
msgstr "Der Revoluton Pi konnte Teile der Übertragung nicht verarbeiten." msgstr "Der Revoluton Pi konnte Teile der Übertragung nicht verarbeiten."
#: revpiprogram.py:711 #: revpiprogram.py:715
msgid "Errors occurred during transmission" msgid "Errors occurred during transmission"
msgstr "Bei der Übertragung traten Fehler auf" msgstr "Bei der Übertragung traten Fehler auf"
#: revpipycontrol.py:94 #: revpipycontrol.py:93
msgid "Connections..." msgid "Connections..."
msgstr "Verbindungen..." msgstr "Verbindungen..."
#: revpipycontrol.py:97 #: revpipycontrol.py:96
msgid "Main" msgid "Main"
msgstr "Datei" msgstr "Datei"
#: revpipycontrol.py:104
msgid "Visit website..."
msgstr "Webseite besuchen..."
#: revpipycontrol.py:106
msgid "Info..."
msgstr "Info..."
#: revpipycontrol.py:108 #: revpipycontrol.py:108
msgid "Help"
msgstr "Hilfe"
#: revpipycontrol.py:116
msgid "PLC start" msgid "PLC start"
msgstr "PLC Start" msgstr "PLC Start"
#: revpipycontrol.py:113 #: revpipycontrol.py:121
msgid "PLC stop" msgid "PLC stop"
msgstr "PLC Stopp" msgstr "PLC Stopp"
#: revpipycontrol.py:118 #: revpipycontrol.py:126
msgid "PLC restart" msgid "PLC restart"
msgstr "PLC Neustart" msgstr "PLC Neustart"
#: revpipycontrol.py:123 #: revpipycontrol.py:131
msgid "PLC logs" msgid "PLC logs"
msgstr "PLC Logs" msgstr "PLC Logs"
#: revpipycontrol.py:134 #: revpipycontrol.py:142
msgid "PLC watch mode" msgid "PLC watch mode"
msgstr "PLC watch Modus" msgstr "PLC watch Modus"
#: revpipycontrol.py:151 #: revpipycontrol.py:159
msgid "PLC log..." msgid "PLC log..."
msgstr "PLC Log..." msgstr "PLC Log..."
#: revpipycontrol.py:153 #: revpipycontrol.py:161
msgid "PLC options..." msgid "PLC options..."
msgstr "PLC Optionen..." msgstr "PLC Optionen..."
#: revpipycontrol.py:155 #: revpipycontrol.py:163
msgid "PLC program..." msgid "PLC program..."
msgstr "PLC Programm..." msgstr "PLC Programm..."
#: revpipycontrol.py:159 #: revpipycontrol.py:167
msgid "Disconnect" msgid "Disconnect"
msgstr "Trennen" msgstr "Trennen"
#: revpipycontrol.py:164 #: revpipycontrol.py:172
msgid "Connect" msgid "Connect"
msgstr "Verbinden" msgstr "Verbinden"
#: revpipycontrol.py:200 #: revpipycontrol.py:212
msgid "" msgid ""
"The watch mode ist not supported in version {} of RevPiPyLoad on your RevPi! " "The watch mode ist not supported in version {} of RevPiPyLoad on your RevPi! "
"You need at least version 0.4.0." "You need at least version 0.4.0."
msgstr "" msgstr ""
"Die Debug-Funktion wird von der RevPiPyLoad Version {} auf dem RevPi nicht " "Der Watch-Modus wird von der RevPiPyLoad Version {} auf dem RevPi nicht "
"unterstützt! Sie benötigen mindestens Version 0.4.0." "unterstützt! Sie benötigen mindestens Version 0.4.0."
#: revpipycontrol.py:248 revpipycontrol.py:268 #: revpipycontrol.py:251
msgid ""
"This version of Logviewer ist not supported in version {} of RevPiPyLoad on "
"your RevPi! You need at least version 0.4.1."
msgstr ""
"Diese Version vom Logbetrachter wird in der RevPiPyLoad Version {} auf Ihrem "
"RevPi nicht unterstützt! Sie benötigen mindestens Version 0.4.1."
#: revpipycontrol.py:269 revpipycontrol.py:287
msgid "" msgid ""
"XML-RPC access mode in the RevPiPyLoad configuration is to small to access " "XML-RPC access mode in the RevPiPyLoad configuration is to small to access "
"this dialog" "this dialog"
@@ -546,6 +570,6 @@ msgstr ""
"Der XML-RPC Modus ist beim RevPiPyLoad nicht hoch genug eingestellt, um " "Der XML-RPC Modus ist beim RevPiPyLoad nicht hoch genug eingestellt, um "
"diesen Dialog zu verwenden!" "diesen Dialog zu verwenden!"
#: revpipycontrol.py:308 #: revpipycontrol.py:326
msgid "Can not reach server!" msgid "Can not reach server!"
msgstr "Server ist nicht erreichbar!" msgstr "Server ist nicht erreichbar!"

View File

@@ -5,7 +5,6 @@
# (c) Sven Sager, License: LGPLv3 # (c) Sven Sager, License: LGPLv3
# #
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import pickle
import tkinter import tkinter
from mytools import gettrans from mytools import gettrans
@@ -16,14 +15,25 @@ _ = gettrans()
class RevPiLogfile(tkinter.Frame): class RevPiLogfile(tkinter.Frame):
def __init__(self, master, xmlcli): def __init__(self, master, xmlcli):
u"""Init RevPiLogfile-Class."""
super().__init__(master) super().__init__(master)
self.master.bind("<KeyPress-Escape>", self._closewin)
self.pack(fill="both", expand=True) self.pack(fill="both", expand=True)
self.xmlcli = xmlcli self.xmlcli = xmlcli
# Systemvariablen
self.loadblock = 16384
self.mrkapp = 0
self.mrkplc = 0
# Fenster bauen # Fenster bauen
self._createwidgets() self._createwidgets()
def _closewin(self, event):
self.master.destroy()
def _createwidgets(self): def _createwidgets(self):
u"""Erstellt alle Widgets."""
self.master.wm_title(_("RevPi Python PLC Logs")) self.master.wm_title(_("RevPi Python PLC Logs"))
self.rowconfigure(0, weight=0) self.rowconfigure(0, weight=0)
@@ -65,47 +75,84 @@ class RevPiLogfile(tkinter.Frame):
self.applog["yscrollcommand"] = self.appscr.set self.applog["yscrollcommand"] = self.appscr.set
self.appscr["command"] = self.applog.yview self.appscr["command"] = self.applog.yview
self.get_applog() # Logtimer zum Laden starten
self.get_plclog() self.get_applog(full=True)
self.get_plclog(full=True)
# Timer zum nachladen aktivieren
self.master.after(1000, self.get_applines)
self.master.after(1000, self.get_plclines)
def btn_clearapp(self): def btn_clearapp(self):
u"""Leert die Logliste der App."""
self.applog.delete(1.0, tkinter.END) self.applog.delete(1.0, tkinter.END)
def btn_clearplc(self): def btn_clearplc(self):
u"""Leert die Logliste des PLC."""
self.plclog.delete(1.0, tkinter.END) self.plclog.delete(1.0, tkinter.END)
def get_applines(self): def get_applog(self, full=False):
roll = self.applog.yview()[1] == 1.0 u"""Ruft App Logbuch ab.
try: @param full: Ganzes Logbuch laden"""
for line in pickle.loads(self.xmlcli.get_applines().data):
self.applog.insert(tkinter.END, line)
except:
pass
if roll:
self.applog.see(tkinter.END)
self.master.after(1000, self.get_applines)
def get_applog(self): # Logs abrufen und letzte Position merken
self.applog.delete(1.0, tkinter.END) self.mrkapp = self._load_log(
self.applog.insert(1.0, pickle.loads(self.xmlcli.get_applog().data)) self.applog, self.xmlcli.load_applog, self.mrkapp, full
self.applog.see(tkinter.END) )
def get_plclines(self): # Timer neu starten
roll = self.plclog.yview()[1] == 1.0 self.master.after(1000, self.get_applog)
try:
for line in pickle.loads(self.xmlcli.get_plclines().data):
self.plclog.insert(tkinter.END, line)
except:
pass
if roll:
self.plclog.see(tkinter.END)
self.master.after(1000, self.get_plclines)
def get_plclog(self): def get_plclog(self, full=False):
self.plclog.delete(1.0, tkinter.END) u"""Ruft PLC Logbuch ab.
self.plclog.insert(1.0, pickle.loads(self.xmlcli.get_plclog().data)) @param full: Ganzes Logbuch laden"""
self.plclog.see(tkinter.END)
# Logs abrufen und letzte Position merken
self.mrkplc = self._load_log(
self.plclog, self.xmlcli.load_plclog, self.mrkplc, full
)
# Timer neu starten
self.master.after(1000, self.get_plclog)
def _load_log(self, textwidget, xmlcall, startposition, full):
u"""Läd die angegebenen Logfiles herunter.
@param textwidget: Widget in das Logs eingefügt werden sollen
@param xmlcall: xmlrpc Funktion zum Abrufen der Logdaten
@param startposition: Startposition ab der Logdaten kommen sollen
@param full: Komplettes Logbuch laden
@returns: Ende der Datei (neue Startposition)
"""
roll = textwidget.yview()[1] == 1.0
startposition = 0 if full else startposition
logbytes = b''
while True:
# Datenblock vom XML-RPC Server holen
bytebuff = xmlcall(startposition, self.loadblock).data
logbytes += bytebuff
startposition += len(bytebuff)
# Prüfen ob alle Daten übertragen wurden
if len(bytebuff) < self.loadblock:
break
if full:
textwidget.delete(1.0, tkinter.END)
if bytebuff == b'\x16': # 
# Kein Zugriff auf Logdatei
textwidget.delete(1.0, tkinter.END)
textwidget.insert(
tkinter.END, _("Can not access log file on the RevPi")
)
elif bytebuff == b'\x19': # 
# Logdatei neu begonnen
startposition = 0
else:
# Text in Widget übernehmen
textwidget.insert(tkinter.END, logbytes.decode("utf-8"))
# Automatisch ans Ende rollen
if roll or full:
textwidget.see(tkinter.END)
return startposition

View File

@@ -16,10 +16,14 @@ _ = gettrans()
class RevPiOption(tkinter.Frame): class RevPiOption(tkinter.Frame):
def __init__(self, master, xmlcli, xmlmode): def __init__(self, master, xmlcli, xmlmode):
u"""Init RevPiOption-Class.
@returns: None"""
if xmlmode < 2: if xmlmode < 2:
return None return None
super().__init__(master) super().__init__(master)
self.master.bind("<KeyPress-Escape>", self._checkclose)
self.master.protocol("WM_DELETE_WINDOW", self._checkclose)
self.pack(expand=True, fill="both") self.pack(expand=True, fill="both")
self.xmlcli = xmlcli self.xmlcli = xmlcli
@@ -30,7 +34,41 @@ class RevPiOption(tkinter.Frame):
self._createwidgets() self._createwidgets()
self._loadappdata() self._loadappdata()
def _changesdone(self):
u"""Prüft ob sich die Einstellungen geändert haben.
@returns: True, wenn min. eine Einstellung geändert wurde"""
return (
self.var_start.get() != self.dc.get("autostart", "1")
or self.var_reload.get() != self.dc.get("autoreload", "1")
or self.var_zexit.get() != self.dc.get("zeroonexit", "0")
or self.var_zerr.get() != self.dc.get("zeroonerror", "0")
or self.var_startpy.get() != self.dc.get("plcprogram", "none.py")
or self.var_startargs.get() != self.dc.get("plcarguments", "")
or self.var_pythonver.get() != self.dc.get("pythonversion", "3")
or self.var_slave.get() != self.dc.get("plcslave", "0")
or self.var_xmlon.get() != (self.dc.get("xmlrpc", 0) >= 1)
or self.var_xmlmod2.get() != (self.dc.get("xmlrpc", 0) >= 2)
or self.var_xmlmod3.get() != (self.dc.get("xmlrpc", 0) >= 3)
or self.var_xmlport.get() != self.dc.get("xmlrpcport", "55123")
)
def _checkclose(self, event=None):
u"""Prüft ob Fenster beendet werden soll.
@param event: tkinter-Event"""
ask = True
if self._changesdone():
ask = tkmsg.askyesno(
_("Question"),
_("Do you really want to quit? \nUnsaved changes will "
"be lost"),
parent=self.master
)
if ask:
self.master.destroy()
def _createwidgets(self): def _createwidgets(self):
u"""Erstellt Widgets."""
self.master.wm_title(_("RevPi Python PLC Options")) self.master.wm_title(_("RevPi Python PLC Options"))
self.master.wm_resizable(width=False, height=False) self.master.wm_resizable(width=False, height=False)
@@ -183,30 +221,32 @@ class RevPiOption(tkinter.Frame):
btn_save.grid(column=0, row=3) btn_save.grid(column=0, row=3)
btn_close = tkinter.Button(self) btn_close = tkinter.Button(self)
btn_close["command"] = self.master.destroy btn_close["command"] = self._checkclose
btn_close["text"] = _("Close") btn_close["text"] = _("Close")
btn_close.grid(column=1, row=3) btn_close.grid(column=1, row=3)
def _loadappdata(self): def _loadappdata(self):
dc = self.xmlcli.get_config() u"""Läd aktuelle Einstellungen vom RevPi."""
self.dc = self.xmlcli.get_config()
self.var_start.set(dc.get("autostart", "1")) self.var_start.set(self.dc.get("autostart", "1"))
self.var_reload.set(dc.get("autoreload", "1")) self.var_reload.set(self.dc.get("autoreload", "1"))
self.var_zexit.set(dc.get("zeroonexit", "0")) self.var_zexit.set(self.dc.get("zeroonexit", "0"))
self.var_zerr.set(dc.get("zeroonerror", "0")) self.var_zerr.set(self.dc.get("zeroonerror", "0"))
self.var_startpy.set(dc.get("plcprogram", "none.py")) self.var_startpy.set(self.dc.get("plcprogram", "none.py"))
self.var_startargs.set(dc.get("plcarguments", "")) self.var_startargs.set(self.dc.get("plcarguments", ""))
self.var_pythonver.set(dc.get("pythonversion", "3")) self.var_pythonver.set(self.dc.get("pythonversion", "3"))
self.var_slave.set(dc.get("plcslave", "0")) self.var_slave.set(self.dc.get("plcslave", "0"))
self.var_xmlon.set(dc.get("xmlrpc", 0) >= 1) self.var_xmlon.set(self.dc.get("xmlrpc", 0) >= 1)
self.var_xmlmod2.set(dc.get("xmlrpc", 0) >= 2) self.var_xmlmod2.set(self.dc.get("xmlrpc", 0) >= 2)
self.var_xmlmod3.set(dc.get("xmlrpc", 0) >= 3) self.var_xmlmod3.set(self.dc.get("xmlrpc", 0) >= 3)
self.var_xmlport.set(dc.get("xmlrpcport", "55123")) self.var_xmlport.set(self.dc.get("xmlrpcport", "55123"))
def _setappdata(self): def _setappdata(self):
u"""Speichert geänderte Einstellungen auf RevPi."""
dc = {} dc = {}
dc["autostart"] = int(self.var_start.get()) dc["autostart"] = int(self.var_start.get())
dc["autoreload"] = int(self.var_reload.get()) dc["autoreload"] = int(self.var_reload.get())
@@ -252,6 +292,7 @@ class RevPiOption(tkinter.Frame):
) )
def askxmlon(self): def askxmlon(self):
u"""Fragt Nuter, ob wirklicht abgeschaltet werden soll."""
if not self.var_xmlon.get(): if not self.var_xmlon.get():
ask = tkmsg.askyesno( ask = tkmsg.askyesno(
_("Question"), _("Question"),
@@ -266,6 +307,7 @@ class RevPiOption(tkinter.Frame):
self.xmlmods() self.xmlmods()
def xmlmods(self): def xmlmods(self):
u"""Passt XML-Optionszugriff an."""
self.ckb_xmlmod2["state"] = \ self.ckb_xmlmod2["state"] = \
"normal" if self.var_xmlon.get() else "disabled" "normal" if self.var_xmlon.get() else "disabled"
self.ckb_xmlmod3["state"] = \ self.ckb_xmlmod3["state"] = \

View File

@@ -39,6 +39,7 @@ class RevPiPlcList(tkinter.Frame):
def __init__(self, master): def __init__(self, master):
super().__init__(master) super().__init__(master)
self.master.bind("<KeyPress-Escape>", self._checkclose)
self.pack() self.pack()
self.changes = False self.changes = False
@@ -50,10 +51,23 @@ class RevPiPlcList(tkinter.Frame):
self._createwidgets() self._createwidgets()
self._loadappdata() self._loadappdata()
def _checkclose(self, event=None):
ask = True
if self.changes:
ask = tkmsg.askyesno(
_("Question"),
_("Do you really want to quit? \nUnsaved changes will "
"be lost"),
parent=self.master
)
if ask:
self.master.destroy()
def _createwidgets(self): def _createwidgets(self):
self.master.wm_title(_("RevPi Python PLC connections")) self.master.wm_title(_("RevPi Python PLC connections"))
self.master.wm_resizable(width=False, height=False) self.master.wm_resizable(width=False, height=False)
self.master.protocol("WM_DELETE_WINDOW", self.evt_btnclose) self.master.protocol("WM_DELETE_WINDOW", self._checkclose)
# Listbox mit vorhandenen Verbindungen # Listbox mit vorhandenen Verbindungen
self.scr_conn = tkinter.Scrollbar(self) self.scr_conn = tkinter.Scrollbar(self)
@@ -111,7 +125,7 @@ class RevPiPlcList(tkinter.Frame):
self, text=_("Save"), command=self.evt_btnsave) self, text=_("Save"), command=self.evt_btnsave)
self.btn_save.grid(column=3, row=9, sticky="se") self.btn_save.grid(column=3, row=9, sticky="se")
self.btn_close = tkinter.Button( self.btn_close = tkinter.Button(
self, text=_("Close"), command=self.evt_btnclose) self, text=_("Close"), command=self._checkclose)
self.btn_close.grid(column=4, row=9, sticky="se") self.btn_close.grid(column=4, row=9, sticky="se")
def _loadappdata(self): def _loadappdata(self):
@@ -144,20 +158,6 @@ class RevPiPlcList(tkinter.Frame):
self.evt_btnnew() self.evt_btnnew()
self.changes = True self.changes = True
def evt_btnclose(self):
if self.changes:
ask = tkmsg.askyesno(
_("Question"),
_("Do you really want to quit? \nUnsaved changes will "
"be lost"),
parent=self.master
)
else:
ask = True
if ask:
self.master.destroy()
def evt_btnnew(self): def evt_btnnew(self):
self.list_conn.select_clear(0, "end") self.list_conn.select_clear(0, "end")
self.evt_listconn() self.evt_listconn()

View File

@@ -40,8 +40,8 @@ class RevPiProgram(tkinter.Frame):
return None return None
super().__init__(master) super().__init__(master)
# FIXME: Warnung kann nerven self.master.protocol("WM_DELETE_WINDOW", self._checkclose)
# self.master.protocol("WM_DELETE_WINDOW", self._checkclose) self.master.bind("<KeyPress-Escape>", self._checkclose)
self.pack(expand=True, fill="both") self.pack(expand=True, fill="both")
self.uploaded = False self.uploaded = False
@@ -59,8 +59,8 @@ class RevPiProgram(tkinter.Frame):
self._evt_optdown() self._evt_optdown()
self._evt_optup() self._evt_optup()
def _checkclose(self): def _checkclose(self, event=None):
if True or self.uploaded: if self.uploaded:
tkmsg.showinfo( tkmsg.showinfo(
_("Information"), _("Information"),
_("A PLC program has been uploaded. Please check the " _("A PLC program has been uploaded. Please check the "
@@ -212,7 +212,7 @@ class RevPiProgram(tkinter.Frame):
# Beendenbutton # Beendenbutton
btn = tkinter.Button(self) btn = tkinter.Button(self)
btn["command"] = self.master.destroy btn["command"] = self._checkclose
btn["text"] = _("Exit") btn["text"] = _("Exit")
btn.grid() btn.grid()
@@ -374,7 +374,7 @@ class RevPiProgram(tkinter.Frame):
) )
ec = self.xmlcli.set_pictoryrsc(Binary(fh.read()), ask) ec = self.xmlcli.set_pictoryrsc(Binary(fh.read()), ask)
print(ec)
if ec == 0: if ec == 0:
if ask: if ask:
tkmsg.showinfo( tkmsg.showinfo(
@@ -496,9 +496,7 @@ class RevPiProgram(tkinter.Frame):
fh_pack = tarfile.open(fh.name) fh_pack = tarfile.open(fh.name)
# Unterverzeichnis streichen # Unterverzeichnis streichen
rootname = ""
for taritem in fh_pack.getmembers(): for taritem in fh_pack.getmembers():
print(rootname)
if not taritem.name == "revpipyload": if not taritem.name == "revpipyload":
taritem.name = \ taritem.name = \
taritem.name.replace("revpipyload/", "") taritem.name.replace("revpipyload/", "")
@@ -637,7 +635,9 @@ class RevPiProgram(tkinter.Frame):
) )
return False return False
# Flag setzen, weil ab hier Veränderungen existieren # Aktuell konfiguriertes Programm lesen (für uploaded Flag)
opt_program = self.xmlcli.get_config()
opt_program = opt_program.get("plcprogram", "none.py")
self.uploaded = True self.uploaded = True
ec = 0 ec = 0
@@ -655,6 +655,10 @@ class RevPiProgram(tkinter.Frame):
else: else:
sendname = fname.replace(dirselect, "")[1:] sendname = fname.replace(dirselect, "")[1:]
# Prüfen ob Dateiname bereits als Startprogramm angegeben ist
if sendname == opt_program:
self.uploaded = False
# Datei übertragen # Datei übertragen
try: try:
ustatus = self.xmlcli.plcupload( ustatus = self.xmlcli.plcupload(

View File

@@ -1,7 +1,7 @@
#!/usr/bin/python3 #!/usr/bin/python3
# #
# RevPiPyControl # RevPiPyControl
# Version: 0.4.0 # Version: 0.4.1
# #
# Webpage: https://revpimodio.org/revpipyplc/ # Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3 # (c) Sven Sager, License: LGPLv3
@@ -19,7 +19,6 @@ from functools import partial
from mytools import addroot, gettrans from mytools import addroot, gettrans
from xmlrpc.client import ServerProxy from xmlrpc.client import ServerProxy
# Übersetzung laden # Übersetzung laden
_ = gettrans() _ = gettrans()
@@ -99,6 +98,15 @@ class RevPiPyControl(tkinter.Frame):
self._fillmbar() self._fillmbar()
self._fillconnbar() self._fillconnbar()
# Hilfe Menü
menu1 = tkinter.Menu(self.mbar, tearoff=False)
menu1.add_command(
label=_("Visit website..."), command=self.visitwebsite)
menu1.add_separator()
menu1.add_command(label=_("Info..."), command=self.infowindow)
# TODO: Menü einbauen
self.mbar.add_cascade(label=_("Help"), menu=menu1)
self.var_conn = tkinter.StringVar(self) self.var_conn = tkinter.StringVar(self)
self.txt_connect = tkinter.Entry( self.txt_connect = tkinter.Entry(
self, textvariable=self.var_conn, state="readonly", width=30) self, textvariable=self.var_conn, state="readonly", width=30)
@@ -190,6 +198,10 @@ class RevPiPyControl(tkinter.Frame):
)) ))
self.mbar.entryconfig("PLC", state="normal") self.mbar.entryconfig("PLC", state="normal")
def infowindow(self):
# TODO: Infofenster aufrufen
pass
def plcdebug(self): def plcdebug(self):
u"""Baut den Debugframe und packt ihn.""" u"""Baut den Debugframe und packt ihn."""
self.btn_debug["state"] = "disabled" self.btn_debug["state"] = "disabled"
@@ -233,6 +245,16 @@ class RevPiPyControl(tkinter.Frame):
def plclogs(self): def plclogs(self):
u"""Öffnet das Fenster für Logdateien.""" u"""Öffnet das Fenster für Logdateien."""
if "load_plclog" not in self.xmlfuncs:
tkmsg.showwarning(
_("Warning"),
_("This version of Logviewer ist not supported in version {} "
"of RevPiPyLoad on your RevPi! You need at least version "
"0.4.1.").format(self.cli.version()),
parent=self.master
)
return None
if self.tklogs is None or len(self.tklogs.children) == 0: if self.tklogs is None or len(self.tklogs.children) == 0:
win = tkinter.Toplevel(self) win = tkinter.Toplevel(self)
self.tklogs = revpilogfile.RevPiLogfile(win, self.cli) self.tklogs = revpilogfile.RevPiLogfile(win, self.cli)
@@ -244,10 +266,8 @@ class RevPiPyControl(tkinter.Frame):
if self.xmlmode < 2: if self.xmlmode < 2:
tkmsg.showwarning( tkmsg.showwarning(
_("Warning"), _("Warning"),
_( _("XML-RPC access mode in the RevPiPyLoad "
"XML-RPC access mode in the RevPiPyLoad " "configuration is to small to access this dialog"),
"configuration is to small to access this dialog"
),
parent=self.master parent=self.master
) )
else: else:
@@ -264,10 +284,8 @@ class RevPiPyControl(tkinter.Frame):
if self.xmlmode < 2: if self.xmlmode < 2:
tkmsg.showwarning( tkmsg.showwarning(
_("Warning"), _("Warning"),
_( _("XML-RPC access mode in the RevPiPyLoad "
"XML-RPC access mode in the RevPiPyLoad " "configuration is to small to access this dialog"),
"configuration is to small to access this dialog"
),
parent=self.master parent=self.master
) )
else: else:
@@ -343,6 +361,9 @@ class RevPiPyControl(tkinter.Frame):
self.master.after(1000, self.tmr_plcrunning) self.master.after(1000, self.tmr_plcrunning)
def visitwebsite(self):
# TODO: Webseite besuchen
pass
if __name__ == "__main__": if __name__ == "__main__":
root = tkinter.Tk() root = tkinter.Tk()

View File

@@ -23,7 +23,7 @@ globsetup = {
"author_email": "akira@narux.de", "author_email": "akira@narux.de",
"url": "https://revpimodio.org/revpipyplc/", "url": "https://revpimodio.org/revpipyplc/",
"license": "LGPLv3", "license": "LGPLv3",
"version": "0.4.0", "version": "0.4.1",
"name": "revpipycontrol", "name": "revpipycontrol",