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

5 Commits
0.7.2 ... 0.8.0

Author SHA1 Message Date
93e02df73e Style in Devices bei Watch-Mode verbessert
?bersetzungen
linux und mac haben selbe setup.py Einstellungen
2019-09-16 21:17:19 +02:00
63f60f9e36 Mit procimgserver zusammenf?hren 2019-09-16 10:47:48 +02:00
34f133ea6e Konfiguration plcworkdir_set_uid in Optionen integriert
Konfiguraiton replace_ios in Optionen integriert
Dropdownliste f?r forkonfigurierten Pfad von replace_ios eingebaut
2019-09-16 10:45:39 +02:00
472605bb38 Watchmode wertet nun auch byteorder und signed aus 2019-09-15 22:17:06 +02:00
79ea020903 Etikett 0.7.2 zum ?nderungssatz be20c934030f hinzugef?gt 2019-07-01 11:15:49 +02:00
10 changed files with 377 additions and 130 deletions

View File

@@ -3,3 +3,5 @@ include stdeb.cfg
recursive-include data *
recursive-include revpipycontrol *
global-exclude *.pyc
include LICENSE.txt

View File

@@ -87,6 +87,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiCheckClient.maxint">maxint</a></td>
<td>Errechnet maximalen int() Wert f&#252;r Bytes max 22.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiCheckClient.minint">minint</a></td>
<td>Errechnet maximalen int() Wert f&#252;r Bytes max 22.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiCheckClient.readvalues">readvalues</a></td>
<td>Ruft nur Input Werte von RevPi ab und aktualisiert Fenster.</td>
</tr><tr>
@@ -244,13 +247,29 @@ Versteckt alle Fenster.
</p><a NAME="RevPiCheckClient.maxint" ID="RevPiCheckClient.maxint"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiCheckClient.maxint</h3>
<b>maxint</b>(<i>bytelen</i>)
<b>maxint</b>(<i>io</i>)
<p>
Errechnet maximalen int() Wert f&#252;r Bytes max 22.
</p><dl>
<dt><i>bytelen</i></dt>
<dt><i>io</i></dt>
<dd>
Anzahl Bytes
IO-Liste, deren Wert berechnet werden soll
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
int() max oder 0 bei &#220;berschreitung
</dd>
</dl><a NAME="RevPiCheckClient.minint" ID="RevPiCheckClient.minint"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiCheckClient.minint</h3>
<b>minint</b>(<i>io</i>)
<p>
Errechnet maximalen int() Wert f&#252;r Bytes max 22.
</p><dl>
<dt><i>io</i></dt>
<dd>
IO-Liste, deren Wert berechnet werden soll
</dd>
</dl><dl>
<dt>Returns:</dt>

View File

@@ -51,6 +51,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiOption.__init__">RevPiOption</a></td>
<td>Init RevPiOption-Class.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption.__state_replace_ios">__state_replace_ios</a></td>
<td>Konfiguriert Werte f&#252;r replace_io.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption._changesdone">_changesdone</a></td>
<td>Pr&#252;ft ob sich die Einstellungen ge&#228;ndert haben.</td>
</tr><tr>
@@ -104,6 +107,17 @@ Init RevPiOption-Class.
<dd>
None
</dd>
</dl><a NAME="RevPiOption.__state_replace_ios" ID="RevPiOption.__state_replace_ios"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption.__state_replace_ios</h3>
<b>__state_replace_ios</b>(<i>text</i>)
<p>
Konfiguriert Werte f&#252;r replace_io.
</p><dl>
<dt><i>text:</i></dt>
<dd>
Ausgew&#228;hlter Eintrag in Liste
</dd>
</dl><a NAME="RevPiOption._changesdone" ID="RevPiOption._changesdone"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption._changesdone</h3>

View File

@@ -53,7 +53,8 @@ revpicheckclient.RevPiCheckClient._onfrmconf?5(canvas)
revpicheckclient.RevPiCheckClient._warnwrite?5()
revpicheckclient.RevPiCheckClient._workvalues?5(io_dicts=None, writeout=False)
revpicheckclient.RevPiCheckClient.hideallwindows?4()
revpicheckclient.RevPiCheckClient.maxint?4(bytelen)
revpicheckclient.RevPiCheckClient.maxint?4(io)
revpicheckclient.RevPiCheckClient.minint?4(io)
revpicheckclient.RevPiCheckClient.readvalues?4()
revpicheckclient.RevPiCheckClient.refreshvalues?4()
revpicheckclient.RevPiCheckClient.tmr_workvalues?4()
@@ -116,6 +117,7 @@ revpilogfile._?8
revpilogfile.__author__?9
revpilogfile.__copyright__?9
revpilogfile.__license__?9
revpioption.RevPiOption.__state_replace_ios?6(text)
revpioption.RevPiOption._changesdone?5()
revpioption.RevPiOption._changesdone_mqtt?5()
revpioption.RevPiOption._checkclose?5(event=None)

View File

@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Project SYSTEM "Project-5.1.dtd">
<!-- eric project file for project revpipycontrol -->
<!-- Saved: 2019-06-27, 14:10:32 -->
<!-- Saved: 2019-09-16, 10:44:39 -->
<!-- Copyright (C) 2019 Sven Sager, akira@narux.de -->
<Project version="5.1">
<Language>en_US</Language>
<Hash>66103e2eaf8a762f14d1fd51d8b1c9dcaf35a275</Hash>
<ProgLanguage mixed="0">Python3</ProgLanguage>
<ProjectType>Console</ProjectType>
<Version>0.7.2</Version>
<Version>0.8.0</Version>
<Author>Sven Sager</Author>
<Email>akira@narux.de</Email>
<Eol index="1"/>
@@ -387,6 +387,41 @@
</key>
<value>
<dict>
<key>
<string>BuiltinsChecker</string>
</key>
<value>
<dict>
<key>
<string>chr</string>
</key>
<value>
<list>
<string>unichr</string>
</list>
</value>
<key>
<string>str</string>
</key>
<value>
<list>
<string>unicode</string>
</list>
</value>
</dict>
</value>
<key>
<string>CopyrightAuthor</string>
</key>
<value>
<string></string>
</value>
<key>
<string>CopyrightMinFileSize</string>
</key>
<value>
<int>0</int>
</value>
<key>
<string>DocstringType</string>
</key>
@@ -403,7 +438,7 @@
<string>ExcludeMessages</string>
</key>
<value>
<string>E123,E226,E24</string>
<string>E123,E226,E24,C101</string>
</value>
<key>
<string>FixCodes</string>
@@ -417,6 +452,12 @@
<value>
<bool>False</bool>
</value>
<key>
<string>FutureChecker</string>
</key>
<value>
<string></string>
</value>
<key>
<string>HangClosing</string>
</key>
@@ -429,6 +470,24 @@
<value>
<string></string>
</value>
<key>
<string>LineComplexity</string>
</key>
<value>
<int>15</int>
</value>
<key>
<string>LineComplexityScore</string>
</key>
<value>
<int>10</int>
</value>
<key>
<string>MaxCodeComplexity</string>
</key>
<value>
<int>10</int>
</value>
<key>
<string>MaxLineLength</string>
</key>
@@ -453,6 +512,12 @@
<value>
<bool>False</bool>
</value>
<key>
<string>ValidEncodings</string>
</key>
<value>
<string>latin-1, utf-8</string>
</value>
</dict>
</value>
</dict>

View File

@@ -1,8 +1,8 @@
msgid ""
msgstr ""
"Project-Id-Version: RevPiPyControl 0.4.0\n"
"POT-Creation-Date: 2018-10-07 12:08+0200\n"
"PO-Revision-Date: 2018-10-07 12:08+0200\n"
"POT-Creation-Date: 2019-09-16 20:56+0200\n"
"PO-Revision-Date: 2019-09-16 20:56+0200\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: de\n"
@@ -20,13 +20,13 @@ msgid "Level"
msgstr "Level"
#: aclmanager.py:76 aclmanager.py:276 mqttmanager.py:66 revpilegacy.py:68
#: revpilegacy.py:281 revpilegacy.py:328 revpioption.py:101 revpioption.py:377
#: revpioption.py:446 revpiplclist.py:62 revpiplclist.py:203
#: revpilegacy.py:281 revpilegacy.py:328 revpioption.py:130 revpioption.py:458
#: revpioption.py:530 revpiplclist.py:62 revpiplclist.py:203
#: revpiprogram.py:393 revpiprogram.py:467
msgid "Question"
msgstr "Frage"
#: aclmanager.py:77 mqttmanager.py:67 revpilegacy.py:69 revpioption.py:102
#: aclmanager.py:77 mqttmanager.py:67 revpilegacy.py:69 revpioption.py:131
#: revpiplclist.py:63
msgid ""
"Do you really want to quit? \n"
@@ -71,13 +71,13 @@ msgstr "in Liste einfügen"
msgid "clear"
msgstr "leeren"
#: aclmanager.py:259 mqttmanager.py:270 revpilegacy.py:235 revpioption.py:322
#: aclmanager.py:259 mqttmanager.py:270 revpilegacy.py:235 revpioption.py:390
#: revpiplclist.py:138
msgid "Save"
msgstr "Speichern"
#: aclmanager.py:264 mqttmanager.py:275 revpiinfo.py:140 revpilegacy.py:240
#: revpioption.py:327 revpiplclist.py:142
#: revpioption.py:395 revpiplclist.py:142
msgid "Close"
msgstr "Schließen"
@@ -93,9 +93,9 @@ msgstr ""
"IP: {0} / Level: {1}"
#: aclmanager.py:291 aclmanager.py:367 revpicheckclient.py:112
#: revpicheckclient.py:335 revpicheckclient.py:460 revpidevelop.py:216
#: revpicheckclient.py:342 revpicheckclient.py:493 revpidevelop.py:216
#: revpidevelop.py:224 revpidevelop.py:252 revpilegacy.py:318
#: revpioption.py:115 revpioption.py:436 revpiplclist.py:227
#: revpioption.py:144 revpioption.py:520 revpiplclist.py:227
#: revpiprogram.py:329 revpiprogram.py:360 revpiprogram.py:423
#: revpiprogram.py:429 revpiprogram.py:435 revpiprogram.py:443
#: revpiprogram.py:449 revpiprogram.py:482 revpiprogram.py:566
@@ -218,41 +218,41 @@ msgstr ""
"Angegebener Wert für Output '{0}' ist nicht gültig! \n"
"Setze auf '{1}' zurück"
#: revpicheckclient.py:216
#: revpicheckclient.py:223
msgid "Devices of RevPi"
msgstr "Devices vom RevPi"
#: revpicheckclient.py:248
#: revpicheckclient.py:255
msgid "Control"
msgstr "Kontrolle"
#: revpicheckclient.py:252
#: revpicheckclient.py:259
msgid "Read all IOs"
msgstr "Lese alle IOs"
#: revpicheckclient.py:257
#: revpicheckclient.py:264
msgid "Read just Inputs"
msgstr "Nur Inputs lesen"
#: revpicheckclient.py:264
#: revpicheckclient.py:271
msgid "Write Outputs"
msgstr "Outputs schreiben"
#: revpicheckclient.py:270
#: revpicheckclient.py:277
msgid "Autorefresh values"
msgstr "Aktualisiere Werte automatisch"
#: revpicheckclient.py:278
#: revpicheckclient.py:285
msgid "Write values to RevPi"
msgstr "Schreibe Werte auf RevPi"
#: revpicheckclient.py:292 revpidevelop.py:284 revpiprogram.py:456
#: revpicheckclient.py:299 revpidevelop.py:284 revpiprogram.py:456
#: revpipycontrol.py:255 revpipycontrol.py:304 revpipycontrol.py:338
#: revpipycontrol.py:356 revpipycontrol.py:389
msgid "Warning"
msgstr "Warnung"
#: revpicheckclient.py:293
#: revpicheckclient.py:300
msgid ""
"You want to set outputs on the RevPi! Note that these are set "
"IMMEDIATELY!!! \n"
@@ -264,13 +264,13 @@ msgstr ""
"Wenn auf dem RevPi ein anderes Programm zur Steuerung läuft, könnte dies "
"gestört werden und die Ausgänge wieder zurücksetzen."
#: revpicheckclient.py:336
#: revpicheckclient.py:343
msgid "To many errors while reading IO data. Can not show the Watch-Mode."
msgstr ""
"Zu viele Fehler beim Lesen der IO-Daten. Watch-Mode kann nicht angezeigt "
"werden."
#: revpicheckclient.py:456
#: revpicheckclient.py:489
#, python-brace-format
msgid "Error set value of device '{0}' Output '{1}': {2} \n"
msgstr "Fehler beim Setzen der Werte auf Device '{0}' bei Output '{1}': {2} \n"
@@ -295,8 +295,8 @@ msgstr "Stoppen / Hochladen / Starten"
msgid "Just upload"
msgstr "Nur hochladen"
#: revpidevelop.py:207 revpilegacy.py:273 revpilegacy.py:310 revpioption.py:365
#: revpioption.py:428 revpiplclist.py:219 revpiprogram.py:97
#: revpidevelop.py:207 revpilegacy.py:273 revpilegacy.py:310 revpioption.py:446
#: revpioption.py:512 revpiplclist.py:219 revpiprogram.py:97
msgid "Information"
msgstr "Information"
@@ -376,51 +376,51 @@ msgstr ""
"\n"
"(c) Sven Sager, Lizenz: LGPLv3"
#: revpilegacy.py:79 revpioption.py:125
#: revpilegacy.py:79 revpioption.py:154
msgid "RevPi Python PLC Options"
msgstr "RevPi Python PLC Einstellungen"
#: revpilegacy.py:89 revpioption.py:136
#: revpilegacy.py:89 revpioption.py:168
msgid "Start / Stop behavior"
msgstr "Start / Stop Verhalten"
#: revpilegacy.py:98 revpioption.py:146
#: revpilegacy.py:98 revpioption.py:181
msgid "Start program automatically"
msgstr "Starte Programm automatisch"
#: revpilegacy.py:104 revpioption.py:152
#: revpilegacy.py:104 revpioption.py:188
msgid "Restart program after exit"
msgstr "Starte Programm nach Beenden neu"
#: revpilegacy.py:110 revpioption.py:168
#: revpilegacy.py:110 revpioption.py:206
msgid "Set process image to NULL if program terminates..."
msgstr "Prozessabbild auf NULL setzen, wenn Programm..."
#: revpilegacy.py:115 revpioption.py:173
#: revpilegacy.py:115 revpioption.py:212
msgid "... successfully"
msgstr "... ohne Fehler beendet"
#: revpilegacy.py:121 revpioption.py:179
#: revpilegacy.py:121 revpioption.py:219
msgid "... with errors"
msgstr "... mit Fehlern beendet"
#: revpilegacy.py:127 revpioption.py:187
#: revpilegacy.py:127 revpioption.py:247
msgid "PLC program"
msgstr "PLC Programm"
#: revpilegacy.py:138 revpioption.py:197
#: revpilegacy.py:138 revpioption.py:259
msgid "Python version"
msgstr "Python Version"
#: revpilegacy.py:157 revpioption.py:216
#: revpilegacy.py:157 revpioption.py:278
msgid "Python PLC program name"
msgstr "Python PLC Programmname"
#: revpilegacy.py:172 revpioption.py:234
#: revpilegacy.py:172
msgid "Program arguments"
msgstr "Programmargumente"
#: revpilegacy.py:183 revpioption.py:253
#: revpilegacy.py:183 revpioption.py:321
msgid "Use RevPi as PLC-Slave"
msgstr "RevPi als PLC-Slave verwenden"
@@ -428,7 +428,7 @@ msgstr "RevPi als PLC-Slave verwenden"
msgid "XML-RPC server"
msgstr "XML-RPC Server"
#: revpilegacy.py:201 revpioption.py:309
#: revpilegacy.py:201 revpioption.py:377
msgid "Activate XML-RPC server on RevPi"
msgstr "Aktiviere XML-RPC Server auf RevPi"
@@ -452,7 +452,7 @@ msgstr ""
msgid "XML-RPC server port"
msgstr "XML-RPC Serverport"
#: revpilegacy.py:274 revpioption.py:366
#: revpilegacy.py:274 revpioption.py:447
msgid "You have not made any changes to save."
msgstr "Sie haben keine Änderungen zum Speichern vorgenommen."
@@ -468,17 +468,17 @@ msgstr ""
"Sollen die neuen Einstellungen sofort in Kraft treten? \n"
"Dies bedeutet einen Neustart des Dienstes und des laufenden PLC-Programms!"
#: revpilegacy.py:311 revpioption.py:429
#: revpilegacy.py:311 revpioption.py:513
msgid "Settings saved"
msgstr "Einstellungen gespeichert"
#: revpilegacy.py:319 revpioption.py:437
#: revpilegacy.py:319 revpioption.py:521
msgid "The settings could not be saved. This can happen if values are wrong!"
msgstr ""
"Die Einstellungen konnten nicht gesichert werden. Dies kann passieren, wenn "
"Werte falsch sind!"
#: revpilegacy.py:329 revpioption.py:447
#: revpilegacy.py:329 revpioption.py:531
msgid ""
"Are you sure you want to deactivate the XML-RPC server? You will NOT be able "
"to access the Revolution Pi with this program."
@@ -506,47 +506,75 @@ msgstr "Python PLC Programm - Logdatei"
msgid "Can not access log file on the RevPi"
msgstr "Auf die Logdatei des RevPi kann nicht zugegriffen werden"
#: revpioption.py:116
#: revpioption.py:58
msgid "Do not use replace io file"
msgstr "Keine replace io Datei verwenden"
#: revpioption.py:59
msgid "Use static file from RevPiPyLoad"
msgstr "Statische Datei von RevPiPyLoad"
#: revpioption.py:60
msgid "Use dynamic file from work directory"
msgstr "Dynamische Datei des Steuerungsprogramms"
#: revpioption.py:61
msgid "Give own path and filename"
msgstr "Eigenen Pfad angeben"
#: revpioption.py:145
msgid "The value of 'restart delay' ist not valid."
msgstr "Der Wert für 'Neustart Verzögerung' ist nicht gültig."
#: revpioption.py:158
#: revpioption.py:195
msgid "Restart after n seconds of delay"
msgstr "Neustart nach n Sekunden Verzögerung"
#: revpioption.py:244
#: revpioption.py:225
msgid "Replace IO file:"
msgstr "Replace IO Datei:"
#: revpioption.py:296
msgid "Program arguments:"
msgstr "Programmargumente:"
#: revpioption.py:305
msgid "Set write access to workdirectory"
msgstr "Schreibzugriffe in Arbeitsverzeichnis erlauben"
#: revpioption.py:312
msgid "RevPiPyLoad server services"
msgstr "RevPiPyLoad Server Dienste"
#: revpioption.py:259 revpioption.py:315
#: revpioption.py:327 revpioption.py:383
msgid "Edit ACL"
msgstr "ACL bearbeiten"
#: revpioption.py:264
#: revpioption.py:332
msgid "RevPi-Slave service is:"
msgstr "RevPi-Slave Dienst Status:"
#: revpioption.py:270 revpioption.py:299
#: revpioption.py:338 revpioption.py:367
msgid "running"
msgstr "läuft"
#: revpioption.py:270 revpioption.py:299
#: revpioption.py:338 revpioption.py:367
msgid "stopped"
msgstr "beendet"
#: revpioption.py:283
#: revpioption.py:351
msgid "MQTT process image publisher"
msgstr "MQTT Übertragung des Prozessabbilds"
#: revpioption.py:289
#: revpioption.py:357
msgid "Settings"
msgstr "Einstellungen"
#: revpioption.py:294
#: revpioption.py:362
msgid "MQTT publish service is:"
msgstr "MQTT Übertragungsdienst Status:"
#: revpioption.py:378
#: revpioption.py:459
msgid ""
"The settings will be set on the Revolution Pi now. \n"
"\n"
@@ -560,31 +588,31 @@ msgstr ""
"Programm jetzt neu starten!\n"
"ACL Änderungen und Diensteinstellungen werden sofort angewandt."
#: revpioption.py:478
#: revpioption.py:562
msgid "read only"
msgstr "nur lesen"
#: revpioption.py:479
#: revpioption.py:563
msgid "read and write"
msgstr "lesen und schreiben"
#: revpioption.py:495
#: revpioption.py:579
msgid "Start/Stop PLC program and read logs"
msgstr "PLC Programm starten/stoppen und Logs lesen"
#: revpioption.py:496
#: revpioption.py:580
msgid "+ read IOs in watch modus"
msgstr "+ IOs in 'Watch modus' lesen"
#: revpioption.py:497
#: revpioption.py:581
msgid "+ read properties and download PLC program"
msgstr "+ Einstellungen lesen und PLC Programm herunterladen"
#: revpioption.py:498
#: revpioption.py:582
msgid "+ upload PLC program"
msgstr "+ PLC Programm hochladen"
#: revpioption.py:499
#: revpioption.py:583
msgid "+ set properties"
msgstr "+ Einstellungen ändern"

View File

@@ -101,8 +101,8 @@ class RevPiCheckClient(tkinter.Frame):
try:
newvalue = io[5].get()
# Wertebereich prüfen
if newvalue < 0 or newvalue > self.maxint(io[1]):
raise ValueError("too big")
if not self.minint(io) <= newvalue <= self.maxint(io):
raise ValueError("value not valid")
self.__chval(device, io)
@@ -144,6 +144,7 @@ class RevPiCheckClient(tkinter.Frame):
heigh=calc_heigh if calc_heigh <= 600 else 600
)
s_frame = tkinter.Frame(canvas)
s_frame.columnconfigure(1, weight=1)
vsb = tkinter.Scrollbar(frame, orient="vertical", command=canvas.yview)
canvas.configure(yscrollcommand=vsb.set)
@@ -168,7 +169,7 @@ class RevPiCheckClient(tkinter.Frame):
# IOs generieren
rowcount = 0
for io in lst_io:
# io = [name,bytelen,byteaddr,bmk,bitaddress,(tkinter_var)]
# io = [name,blen,baddr,bmk,bitaddr,(tkinter_var),border,signed]
tkinter.Label(s_frame, text=io[0]).grid(
column=1, row=rowcount, sticky="w"
@@ -185,7 +186,11 @@ class RevPiCheckClient(tkinter.Frame):
check.grid(column=0, row=rowcount)
else:
var = tkinter.IntVar()
txt = tkinter.Spinbox(s_frame, to=self.maxint(io[1]))
txt = tkinter.Spinbox(
s_frame,
from_=self.minint(io),
to=self.maxint(io),
)
txt.bind(
"<Key>",
lambda event, tkvar=var: self.__saveoldvalue(event, tkvar)
@@ -198,15 +203,17 @@ class RevPiCheckClient(tkinter.Frame):
txt["command"] = \
lambda device=device, io=io: self.__chval(device, io)
txt["state"] = "disabled" if iotype == "inp" or \
self.maxint(io[1]) == 0 else "normal"
txt["width"] = 5
self.maxint(io) == 0 else "normal"
width = len(str(self.maxint(io))) + 1
txt["width"] = 7 if width > 7 else width
txt["textvariable"] = var
txt.grid(column=0, row=rowcount)
# Steuerelementvariable in IO übernehmen (mutabel)
io.append(var)
io.insert(5, var)
rowcount += 1
s_frame.update()
def _createwidgets(self):
"""Erstellt den Fensterinhalt."""
@@ -223,7 +230,6 @@ class RevPiCheckClient(tkinter.Frame):
"WM_DELETE_WINDOW",
lambda win=win: self.__hidewin(win)
)
win.resizable(False, True)
win.withdraw()
self.dict_wins[dev] = win
@@ -235,6 +241,7 @@ class RevPiCheckClient(tkinter.Frame):
for iotype in ["inp", "out"]:
frame = tkinter.Frame(group)
frame.pack(side="left", fill="both", expand=True)
frame.update()
self._createiogroup(dev, frame, iotype)
# Button erstellen
@@ -345,7 +352,7 @@ class RevPiCheckClient(tkinter.Frame):
xmlmc = MultiCall(self.cli)
for dev in self.dict_devices:
# io = [name,bytelen,byteaddr,bmk,bitaddress,(tkinter_var)]
# io = [name,blen,baddr,bmk,bitaddr,(tkinter_var),border,signed]
# IO Typ verarbeiten
for iotype in io_dicts:
@@ -358,7 +365,9 @@ class RevPiCheckClient(tkinter.Frame):
# Bytes umwandeln
int_byte = int.from_bytes(
ba_values[io[2]:io[2] + io[1]], byteorder="little"
ba_values[io[2]:io[2] + io[1]],
byteorder="little" if len(io) < 7 else io[6],
signed=False if len(io) < 8 else io[7],
)
if io[4] >= 0:
# Bit-IO
@@ -384,11 +393,35 @@ class RevPiCheckClient(tkinter.Frame):
for win in self.dict_wins:
self.dict_wins[win].withdraw()
def maxint(self, bytelen):
def maxint(self, io):
u"""Errechnet maximalen int() Wert für Bytes max 22.
@param bytelen Anzahl Bytes
@param io IO-Liste, deren Wert berechnet werden soll
@return int() max oder 0 bei Überschreitung"""
return 0 if bytelen > 22 else 256 ** bytelen - 1
# io = [name,blen,baddr,bmk,bitaddr,(tkinter_var),border,signed]
bytelen = io[1]
if bytelen == 0:
return 0
signed = io[-1] if type(io[-1]) == bool else False
return 0 if bytelen > 22 else int.from_bytes(
(b'\x7f' if signed else b'\xff') + b'\xff' * (bytelen - 1),
byteorder="big"
)
def minint(self, io):
u"""Errechnet maximalen int() Wert für Bytes max 22.
@param io IO-Liste, deren Wert berechnet werden soll
@return int() max oder 0 bei Überschreitung"""
# io = [name,blen,baddr,bmk,bitaddr,(tkinter_var),border,signed]
bytelen = io[1]
if bytelen == 0:
return 0
signed = io[-1] if type(io[-1]) == bool else False
rc = 0 if bytelen > 22 or not signed else int.from_bytes(
b'\x80' + b'\x00' * (bytelen - 1),
byteorder="big",
signed=True
)
return rc
def readvalues(self):
u"""Ruft nur Input Werte von RevPi ab und aktualisiert Fenster."""

View File

@@ -54,6 +54,13 @@ class RevPiOption(tkinter.Frame):
"mqttwrite_outputs": 0,
}
self.replace_ios_options = [
_("Do not use replace io file"),
_("Use static file from RevPiPyLoad"),
_("Use dynamic file from work directory"),
_("Give own path and filename"),
]
self.mrk_xmlmodask = False
self.dorestart = False
@@ -61,6 +68,25 @@ class RevPiOption(tkinter.Frame):
self._createwidgets()
self._loadappdata()
def __state_replace_ios(self, text):
u"""Konfiguriert Werte für replace_io.
@param text: Ausgewählter Eintrag in Liste"""
selected_id = self.replace_ios_options.index(text)
# Preset value
if selected_id == 0:
self.var_replace_ios.set("")
elif selected_id == 1:
self.var_replace_ios.set("/etc/revpipyload/replace_ios.conf")
else:
self.var_replace_ios.set("replace_ios.conf")
# Set state of input field
self.txt_replace_ios["state"] = "normal" \
if self.xmlmodus >= 4 and \
selected_id == 3 \
else "disabled"
def _changesdone(self):
u"""Prüft ob sich die Einstellungen geändert haben.
@return True, wenn min. eine Einstellung geändert wurde"""
@@ -71,10 +97,13 @@ class RevPiOption(tkinter.Frame):
str(self.dc.get("autoreloaddelay", 5)) or
self.var_zexit.get() != self.dc.get("zeroonexit", 0) or
self.var_zerr.get() != self.dc.get("zeroonerror", 0) or
self.var_replace_ios.get() != self.dc.get("replace_ios", "") or
# TODO: rtlevel (0)
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_plcworkdir_set_uid.get() != \
self.dc.get("plcworkdir_set_uid") or
self.var_slave.get() != self.dc.get("plcslave", 0) or
self.var_slaveacl.get() != self.dc.get("plcslaveacl", "") or
self.var_mqtton.get() != self.dc.get("mqtt", 0) or
@@ -133,6 +162,9 @@ class RevPiOption(tkinter.Frame):
# Gruppe Start/Stop
stst = tkinter.LabelFrame(self)
stst.columnconfigure(0, weight=1)
stst.columnconfigure(1, weight=1)
stst.columnconfigure(2, weight=1)
stst["text"] = _("Start / Stop behavior")
stst.grid(columnspan=2, pady=2, sticky="we")
@@ -141,82 +173,112 @@ class RevPiOption(tkinter.Frame):
self.var_reload_delay = tkinter.StringVar(stst)
self.var_zexit = tkinter.BooleanVar(stst)
self.var_zerr = tkinter.BooleanVar(stst)
self.var_replace_ios = tkinter.StringVar(stst)
self.var_replace_ios_options = tkinter.StringVar(stst)
# Row 0
ckb_start = tkinter.Checkbutton(stst)
ckb_start["text"] = _("Start program automatically")
ckb_start["state"] = xmlstate
ckb_start["variable"] = self.var_start
ckb_start.grid(columnspan=2, **cpadw)
ckb_start.grid(columnspan=3, **cpadw)
# Row 1
ckb_reload = tkinter.Checkbutton(stst)
ckb_reload["text"] = _("Restart program after exit")
ckb_reload["state"] = xmlstate
ckb_reload["variable"] = self.var_reload
ckb_reload.grid(columnspan=2, **cpadw)
ckb_reload.grid(columnspan=3, **cpadw)
# Row 2
lbl = tkinter.Label(stst)
lbl["text"] = _("Restart after n seconds of delay")
lbl.grid(**cpadw)
lbl.grid(columnspan=2, **cpadw)
sbx = tkinter.Spinbox(stst)
sbx["to"] = 60
sbx["from_"] = 5
sbx["textvariable"] = self.var_reload_delay
sbx["width"] = 4
sbx.grid(column=1, row=2, **cpade)
sbx.grid(column=2, row=2, **cpade)
# Row 3
lbl = tkinter.Label(stst)
lbl["text"] = _("Set process image to NULL if program terminates...")
lbl.grid(columnspan=2, **cpadw)
lbl.grid(columnspan=3, **cpadw)
# Row 4
ckb_zexit = tkinter.Checkbutton(stst, justify="left")
ckb_zexit["state"] = xmlstate
ckb_zexit["text"] = _("... successfully")
ckb_zexit["variable"] = self.var_zexit
ckb_zexit.grid(**cpadw)
ckb_zexit.grid(column=1, **cpadw)
# Row 5
ckb_zerr = tkinter.Checkbutton(stst, justify="left")
ckb_zerr["state"] = xmlstate
ckb_zerr["text"] = _("... with errors")
ckb_zerr["variable"] = self.var_zerr
ckb_zerr.grid(**cpadw)
ckb_zerr.grid(column=1, **cpadw)
# Row 6
lbl = tkinter.Label(stst)
lbl["text"] = _("Replace IO file:")
lbl.grid(row=6, **cpadw)
opt = tkinter.OptionMenu(
stst, self.var_replace_ios_options, *self.replace_ios_options,
command=self.__state_replace_ios
)
opt["state"] = xmlstate
opt["width"] = 30
opt.grid(row=6, column=1, columnspan=2, **cpadwe)
# Row 7
self.txt_replace_ios = tkinter.Entry(stst)
self.txt_replace_ios["state"] = xmlstate
self.txt_replace_ios["textvariable"] = self.var_replace_ios
self.txt_replace_ios.grid(column=1, columnspan=2, **cpadwe)
# Gruppe Programm
prog = tkinter.LabelFrame(self)
prog.columnconfigure(0, weight=1)
prog.columnconfigure(1, weight=1)
prog.columnconfigure(2, weight=1)
prog["text"] = _("PLC program")
prog.grid(columnspan=2, pady=2, sticky="we")
self.var_pythonver = tkinter.IntVar(prog)
self.var_startpy = tkinter.StringVar(prog)
self.var_startargs = tkinter.StringVar(prog)
self.var_plcworkdir_set_uid = tkinter.BooleanVar(prog)
self.var_pythonver.set(3)
# Row 0
lbl = tkinter.Label(prog)
lbl["text"] = _("Python version") + ":"
lbl.grid(columnspan=2, row=0, **cpadw)
lbl.grid(row=0, **cpadw)
rbn = tkinter.Radiobutton(prog)
rbn["state"] = xmlstate
rbn["text"] = "Python2"
rbn["value"] = 2
rbn["variable"] = self.var_pythonver
rbn.grid(column=0, row=1, **cpade)
rbn.grid(row=0, column=1, **cpade)
rbn = tkinter.Radiobutton(prog)
rbn["state"] = xmlstate
rbn["text"] = "Python3"
rbn["value"] = 3
rbn["variable"] = self.var_pythonver
rbn.grid(column=1, row=1, **cpadw)
rbn.grid(row=0, column=2, **cpadw)
# Row 2
# Row 1
lbl = tkinter.Label(prog)
lbl["text"] = _("Python PLC program name")
lbl.grid(columnspan=2, **cpadw)
lbl.grid(columnspan=3, **cpadw)
# Row 3
# Row 2
lst = self.xmlcli.get_filelist()
lst.sort()
if ".placeholder" in lst:
@@ -227,17 +289,23 @@ class RevPiOption(tkinter.Frame):
prog, self.var_startpy, *lst
)
opt_startpy["state"] = xmlstate
opt_startpy.grid(columnspan=2, **cpadwe)
opt_startpy.grid(columnspan=3, **cpadwe)
# Row 4
# Row 3
lbl = tkinter.Label(prog)
lbl["text"] = _("Program arguments")
lbl.grid(columnspan=2, **cpadw)
lbl["text"] = _("Program arguments:")
lbl.grid(**cpadw)
# Row 5
txt = tkinter.Entry(prog)
txt["textvariable"] = self.var_startargs
txt.grid(columnspan=2, **cpadw)
txt.grid(row=3, column=1, columnspan=2, **cpadwe)
# Row 4
ckb = tkinter.Checkbutton(prog)
ckb["text"] = _("Set write access to workdirectory")
ckb["state"] = xmlstate
ckb["variable"] = self.var_plcworkdir_set_uid
ckb.grid(columnspan=2, **cpadw)
# Gruppe Services
services = tkinter.LabelFrame(self)
@@ -338,11 +406,24 @@ class RevPiOption(tkinter.Frame):
self.var_reload_delay.set(self.dc.get("autoreloaddelay", 5))
self.var_zexit.set(self.dc.get("zeroonexit", 0))
self.var_zerr.set(self.dc.get("zeroonerror", 0))
replace_ios = self.dc.get("replace_ios", "")
self.var_replace_ios.set(replace_ios)
if replace_ios == "":
self.var_replace_ios_options.set(self.replace_ios_options[0])
elif replace_ios == "/etc/revpipyload/replace_ios.conf":
self.var_replace_ios_options.set(self.replace_ios_options[1])
elif replace_ios == "replace_ios.conf":
self.var_replace_ios_options.set(self.replace_ios_options[2])
else:
self.var_replace_ios_options.set(self.replace_ios_options[3])
self.__state_replace_ios(self.var_replace_ios_options.get())
# TODO: rtlevel (0)
self.var_startpy.set(self.dc.get("plcprogram", "none.py"))
self.var_startargs.set(self.dc.get("plcarguments", ""))
self.var_pythonver.set(self.dc.get("pythonversion", 3))
self.var_plcworkdir_set_uid.set(
self.dc.get("plcworkdir_set_uid", False))
# MQTT Einstellungen laden
self.var_mqtton.set(self.dc.get("mqtt", 0))
@@ -388,9 +469,12 @@ class RevPiOption(tkinter.Frame):
self.dc["plcprogram"] = self.var_startpy.get()
self.dc["plcarguments"] = self.var_startargs.get()
self.dc["pythonversion"] = self.var_pythonver.get()
self.dc["plcworkdir_set_uid"] = \
int(self.var_plcworkdir_set_uid.get())
# TODO: rtlevel (0)
self.dc["zeroonerror"] = int(self.var_zerr.get())
self.dc["zeroonexit"] = int(self.var_zexit.get())
self.dc["replace_ios"] = self.var_replace_ios.get()
# MQTT Settings
self.dc["mqtt"] = int(self.var_mqtton.get())

View File

@@ -5,7 +5,7 @@ u"""RevPiPyControl main program."""
__author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2018 Sven Sager"
__license__ = "GPLv3"
__version__ = "0.7.2"
__version__ = "0.8.0"
import revpicheckclient
import revpidevelop

View File

@@ -19,11 +19,14 @@ class MyEggInfo(distutils.command.install_egg_info.install_egg_info):
globsetup = {
"version": "0.8.0",
"author": "Sven Sager",
"author_email": "akira@narux.de",
"maintainer": "Sven Sager",
"maintainer_email": "akira@revpimodio.org",
"url": "https://revpimodio.org/revpipyplc/",
"license": "LGPLv3",
"version": "0.7.2",
"name": "revpipycontrol",
@@ -35,40 +38,18 @@ globsetup = {
"Außerdem stellt es einen XML-RPC Server bereit, über den die Software\n"
"auf den RevPi geladen werden kann. Das Prozessabbild kann über ein Tool\n"
"zur Laufzeit überwacht werden.",
"install_requires": ["tkinter"],
"classifiers": [
"License :: OSI Approved :: "
"GNU Lesser General Public License v3 (LGPLv3)",
"Operating System :: POSIX :: Linux",
],
"cmdclass": {"install_egg_info": MyEggInfo},
}
# TODO: Mac einbauen
if platform == "linux":
from setuptools import setup
setup(
maintainer="Sven Sager",
maintainer_email="akira@revpimodio.org",
scripts=["data/revpipycontrol"],
data_files=[
("share/applications", ["data/revpipycontrol.desktop"]),
("share/icons/hicolor/32x32/apps", ["data/revpipycontrol.png"]),
("share/revpipycontrol", glob("revpipycontrol/*.*")),
("share/revpipycontrol/shared", glob("revpipycontrol/shared/*.*")),
(
"share/revpipycontrol/locale/de/LC_MESSAGES",
glob("revpipycontrol/locale/de/LC_MESSAGES/*.mo")
),
],
install_requires=["tkinter"],
classifiers=[
"License :: OSI Approved :: "
"GNU Lesser General Public License v3 (LGPLv3)",
"Operating System :: POSIX :: Linux",
],
cmdclass={"install_egg_info": MyEggInfo},
**globsetup
)
elif platform == "win32":
if platform == "win32":
import sys
from cx_Freeze import setup, Executable
@@ -92,5 +73,24 @@ elif platform == "win32":
]
}},
executables=[exe],
**globsetup
)
else:
from setuptools import setup
setup(
scripts=["data/revpipycontrol"],
data_files=[
("share/applications", ["data/revpipycontrol.desktop"]),
("share/icons/hicolor/32x32/apps", ["data/revpipycontrol.png"]),
("share/revpipycontrol", glob("revpipycontrol/*.*")),
("share/revpipycontrol/shared", glob("revpipycontrol/shared/*.*")),
(
"share/revpipycontrol/locale/de/LC_MESSAGES",
glob("revpipycontrol/locale/de/LC_MESSAGES/*.mo")
),
],
**globsetup
)