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

Wenn Ordner ?bertragen werden soll, wird dieser auch auf RevPi angelegt

Developer-Dialog begonnen
This commit is contained in:
2018-07-31 18:36:12 +02:00
parent 6c2578f84c
commit e42cc1a6d2
13 changed files with 618 additions and 11 deletions

View File

@@ -30,6 +30,9 @@ Modules</h3>
<td><a style="color:#0000FF" href="revpicheckclient.html">revpicheckclient</a></td>
<td></td>
</tr><tr>
<td><a style="color:#0000FF" href="revpidevelop.html">revpidevelop</a></td>
<td></td>
</tr><tr>
<td><a style="color:#0000FF" href="revpiinfo.html">revpiinfo</a></td>
<td></td>
</tr><tr>

View File

@@ -12,7 +12,7 @@ Tools-Sammlung.
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>savefile_connections</td></tr><tr><td>savefile_programpath</td></tr>
<tr><td>savefile_connections</td></tr><tr><td>savefile_developer</td></tr><tr><td>savefile_programpath</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>

192
doc/revpidevelop.html Normal file
View File

@@ -0,0 +1,192 @@
<!DOCTYPE html>
<html><head>
<title>revpidevelop</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a>
<h1 style="background-color:#FFFFFF;color:#0000FF">
revpidevelop</h1>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>_</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiDevelop">RevPiDevelop</a></td>
<td>Zeigt Debugfenster an.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#_loaddefaults">_loaddefaults</a></td>
<td>&#220;bernimmt f&#252;r den Pi die letzen Pfade.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#_savedefaults">_savedefaults</a></td>
<td>Schreibt fuer den Pi die letzen Pfade.</td>
</tr>
</table>
<hr /><hr />
<a NAME="RevPiDevelop" ID="RevPiDevelop"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiDevelop</h2>
<p>
Zeigt Debugfenster an.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
ttk.Frame
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>app</td></tr><tr><td>cli</td></tr><tr><td>root</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiDevelop.__init__">RevPiDevelop</a></td>
<td>Init RevPiDevelop-Class.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiDevelop._checkclose">_checkclose</a></td>
<td>Pr&#252;ft ob Fenster beendet werden soll.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiDevelop._createwidgets">_createwidgets</a></td>
<td>Erstellt alle Widgets.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiDevelop.btn_domyjob">btn_domyjob</a></td>
<td>Hochladen und neu starten.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiDevelop.btn_selectpath">btn_selectpath</a></td>
<td>L&#228;sst dem Benuzter ein Verzeichnis ausw&#228;hlen.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiDevelop.load_pathfiles">load_pathfiles</a></td>
<td>Aktualisiert die Dateiliste.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiDevelop.refresh_stats">refresh_stats</a></td>
<td>Passt die Widgets an.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiDevelop.select_pathfiles">select_pathfiles</a></td>
<td>Setzt state der Buttons.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="RevPiDevelop.__init__" ID="RevPiDevelop.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiDevelop (Constructor)</h3>
<b>RevPiDevelop</b>(<i>master, xmlcli, xmlmode, revpi</i>)
<p>
Init RevPiDevelop-Class.
</p><dl>
<dt>Returns:</dt>
<dd>
None
</dd>
</dl><a NAME="RevPiDevelop._checkclose" ID="RevPiDevelop._checkclose"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiDevelop._checkclose</h3>
<b>_checkclose</b>(<i>event=None</i>)
<p>
Pr&#252;ft ob Fenster beendet werden soll.
</p><dl>
<dt><i>event</i></dt>
<dd>
tkinter-Event
</dd>
</dl><a NAME="RevPiDevelop._createwidgets" ID="RevPiDevelop._createwidgets"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiDevelop._createwidgets</h3>
<b>_createwidgets</b>(<i></i>)
<p>
Erstellt alle Widgets.
</p><a NAME="RevPiDevelop.btn_domyjob" ID="RevPiDevelop.btn_domyjob"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiDevelop.btn_domyjob</h3>
<b>btn_domyjob</b>(<i></i>)
<p>
Hochladen und neu starten.
</p><a NAME="RevPiDevelop.btn_selectpath" ID="RevPiDevelop.btn_selectpath"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiDevelop.btn_selectpath</h3>
<b>btn_selectpath</b>(<i></i>)
<p>
L&#228;sst dem Benuzter ein Verzeichnis ausw&#228;hlen.
</p><a NAME="RevPiDevelop.load_pathfiles" ID="RevPiDevelop.load_pathfiles"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiDevelop.load_pathfiles</h3>
<b>load_pathfiles</b>(<i>silent=False</i>)
<p>
Aktualisiert die Dateiliste.
</p><dl>
<dt><i>silent</i></dt>
<dd>
Keinen Dialog anzeigen
</dd>
</dl><a NAME="RevPiDevelop.refresh_stats" ID="RevPiDevelop.refresh_stats"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiDevelop.refresh_stats</h3>
<b>refresh_stats</b>(<i></i>)
<p>
Passt die Widgets an.
</p><a NAME="RevPiDevelop.select_pathfiles" ID="RevPiDevelop.select_pathfiles"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiDevelop.select_pathfiles</h3>
<b>select_pathfiles</b>(<i>tkevt</i>)
<p>
Setzt state der Buttons.
</p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="_loaddefaults" ID="_loaddefaults"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">_loaddefaults</h2>
<b>_loaddefaults</b>(<i>revpiname=None</i>)
<p>
&#220;bernimmt f&#252;r den Pi die letzen Pfade.
</p><dl>
<dt><i>revpiname</i></dt>
<dd>
Einstellungen nur f&#252;r RevPi laden
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
<class 'dict'> mit Einstellungen
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="_savedefaults" ID="_savedefaults"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">_savedefaults</h2>
<b>_savedefaults</b>(<i>revpiname, settings</i>)
<p>
Schreibt fuer den Pi die letzen Pfade.
</p><dl>
<dt><i>revpiname</i></dt>
<dd>
Einstellungen sind f&#252;r diesen RevPi
</dd><dt><i>settings</i></dt>
<dd>
<class 'dict'> mit Einstellungen
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
True, bei erfolgreicher Verarbeitung
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

View File

@@ -78,6 +78,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiPyControl.plcdebug">plcdebug</a></td>
<td>Baut den Debugframe und packt ihn.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyControl.plcdevelop">plcdevelop</a></td>
<td>Startet das Developfenster.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiPyControl.plclist">plclist</a></td>
<td>&#214;ffnet das Fenster f&#252;r die Verbindungen.</td>
</tr><tr>
@@ -200,7 +203,13 @@ Baut den Debugframe und packt ihn.
<dd>
None
</dd>
</dl><a NAME="RevPiPyControl.plclist" ID="RevPiPyControl.plclist"></a>
</dl><a NAME="RevPiPyControl.plcdevelop" ID="RevPiPyControl.plcdevelop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyControl.plcdevelop</h3>
<b>plcdevelop</b>(<i></i>)
<p>
Startet das Developfenster.
</p><a NAME="RevPiPyControl.plclist" ID="RevPiPyControl.plclist"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiPyControl.plclist</h3>
<b>plclist</b>(<i></i>)

View File

@@ -21,6 +21,7 @@ aclmanager._?8
mytools.addroot?4(filename)
mytools.gettrans?4(proglang=None)
mytools.savefile_connections?7
mytools.savefile_developer?7
mytools.savefile_programpath?7
revpicheckclient.RevPiCheckClient.__chval?6(device, io, event=None)
revpicheckclient.RevPiCheckClient.__hidewin?6(win, event=None)
@@ -43,6 +44,20 @@ revpicheckclient.RevPiCheckClient.validatereturn?4(returnlist)
revpicheckclient.RevPiCheckClient.writevalues?4()
revpicheckclient.RevPiCheckClient?1(master, xmlcli, xmlmode=0)
revpicheckclient._?8
revpidevelop.RevPiDevelop._checkclose?5(event=None)
revpidevelop.RevPiDevelop._createwidgets?5()
revpidevelop.RevPiDevelop.app?7
revpidevelop.RevPiDevelop.btn_domyjob?4()
revpidevelop.RevPiDevelop.btn_selectpath?4()
revpidevelop.RevPiDevelop.cli?7
revpidevelop.RevPiDevelop.load_pathfiles?4(silent=False)
revpidevelop.RevPiDevelop.refresh_stats?4()
revpidevelop.RevPiDevelop.root?7
revpidevelop.RevPiDevelop.select_pathfiles?4(tkevt)
revpidevelop.RevPiDevelop?1(master, xmlcli, xmlmode, revpi)
revpidevelop._?8
revpidevelop._loaddefaults?5(revpiname=None)
revpidevelop._savedefaults?5(revpiname, settings)
revpiinfo.RevPiInfo._checkclose?5(event=None)
revpiinfo.RevPiInfo._createwidgets?5(extended=False)
revpiinfo.RevPiInfo.visitwebsite?4(event=None)
@@ -119,6 +134,7 @@ revpipycontrol.RevPiPyControl._opt_conn?5(text, reconnect=False)
revpipycontrol.RevPiPyControl.infowindow?4()
revpipycontrol.RevPiPyControl.myapp?7
revpipycontrol.RevPiPyControl.plcdebug?4()
revpipycontrol.RevPiPyControl.plcdevelop?4()
revpipycontrol.RevPiPyControl.plclist?4()
revpipycontrol.RevPiPyControl.plclogs?4()
revpipycontrol.RevPiPyControl.plcoptions?4()

View File

@@ -1,5 +1,6 @@
AclManager ttk.Frame
RevPiCheckClient tkinter.Frame
RevPiDevelop ttk.Frame
RevPiInfo tkinter.Frame
RevPiLogfile tkinter.Frame
RevPiOption tkinter.Frame

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Project SYSTEM "Project-5.1.dtd">
<!-- eric project file for project revpipycontrol -->
<!-- Saved: 2018-05-25, 08:26:59 -->
<!-- Saved: 2018-07-31, 17:58:55 -->
<!-- Copyright (C) 2018 Sven Sager, akira@narux.de -->
<Project version="5.1">
<Language>en_US</Language>
@@ -9,7 +9,7 @@
<ProgLanguage mixed="0">Python3</ProgLanguage>
<ProjectType>Console</ProjectType>
<Description></Description>
<Version>0.6.2</Version>
<Version>0.7.0</Version>
<Author>Sven Sager</Author>
<Email>akira@narux.de</Email>
<Eol index="1"/>
@@ -27,6 +27,7 @@
<Source>revpipycontrol/revpilegacy.py</Source>
<Source>revpipycontrol/shared/ipaclmanager.py</Source>
<Source>revpipycontrol/shared/__init__.py</Source>
<Source>revpipycontrol/revpidevelop.py</Source>
</Sources>
<Forms/>
<Translations/>

View File

@@ -19,8 +19,11 @@ if platform == "linux":
homedir = environ["HOME"]
else:
homedir = environ["APPDATA"]
savefile_connections = pathjoin(
homedir, ".revpipyplc", "connections.dat")
savefile_developer = pathjoin(
homedir, ".revpipyplc", "developer.dat")
savefile_programpath = pathjoin(
homedir, ".revpipyplc", "programpath.dat")

View File

@@ -0,0 +1,339 @@
# -*- coding: utf-8 -*-
#
# RevPiPyControl
#
# Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3
#
u"""PLC Programm und Konfig hoch und runterladen."""
import gzip
import os
import pickle
import tkinter
import tkinter.filedialog as tkfd
import tkinter.messagebox as tkmsg
from mytools import homedir
from mytools import gettrans
from mytools import savefile_developer as savefile
from revpilogfile import RevPiLogfile
from tkinter import ttk
from xmlrpc.client import Binary
# Übersetzung laden
_ = gettrans()
def _loaddefaults(revpiname=None):
u"""Übernimmt für den Pi die letzen Pfade.
@param revpiname Einstellungen nur für RevPi laden
@return <class 'dict'> mit Einstellungen"""
if os.path.exists(savefile):
with open(savefile, "rb") as fh:
dict_all = pickle.load(fh)
if revpiname is None:
return dict_all
else:
return dict_all.get(revpiname, {})
return {}
def _savedefaults(revpiname, settings):
u"""Schreibt fuer den Pi die letzen Pfade.
@param revpiname Einstellungen sind für diesen RevPi
@param settings <class 'dict'> mit Einstellungen
@return True, bei erfolgreicher Verarbeitung
"""
try:
os.makedirs(os.path.dirname(savefile), exist_ok=True)
if revpiname is None:
dict_all = settings
else:
dict_all = _loaddefaults()
dict_all[revpiname] = settings
with open(savefile, "wb") as fh:
pickle.dump(dict_all, fh)
except:
return False
return True
class RevPiDevelop(ttk.Frame):
u"""Zeigt Debugfenster an."""
def __init__(self, master, xmlcli, xmlmode, revpi):
u"""Init RevPiDevelop-Class.
@return None"""
if xmlmode < 3:
return None
super().__init__(master)
self.master.protocol("WM_DELETE_WINDOW", self._checkclose)
self.master.bind("<KeyPress-Escape>", self._checkclose)
self.pack(expand=True, fill="both")
self.revpi = revpi
self.xmlcli = xmlcli
# Letzte Einstellungen übernehmen
self.opt = _loaddefaults(revpi)
# Einstellungen
self.pathselected = self.opt.get("pathselected", False)
self.watchpath = self.opt.get("watchpath", homedir)
self.watchfiles = self.opt.get("watchfiles", [])
# Fenster bauen
self._createwidgets()
# Alte Einstellungen anwenden
if self.pathselected:
self.load_pathfiles(silent=True)
self.refresh_stats()
# Logfenster öffnen
self.tklog = RevPiLogfile(master, self.xmlcli)
def _checkclose(self, event=None):
u"""Prüft ob Fenster beendet werden soll.
@param event tkinter-Event"""
# Einstellungen speichern
self.opt["pathselected"] = self.pathselected
self.opt["watchpath"] = self.watchpath
self.opt["watchfiles"] = self.watchfiles
_savedefaults(self.revpi, self.opt)
# Logfile und eigenes fenster schließen
self.tklog.destroy()
self.master.destroy()
def _createwidgets(self):
u"""Erstellt alle Widgets."""
self.master.wm_title(_("RevPi Python PLC program"))
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
cpad = {"padx": 4, "pady": 2}
# cpade = {"padx": 4, "pady": 2, "sticky": "e"}
cpadw = {"padx": 4, "pady": 2, "sticky": "w"}
cpadwe = {"padx": 4, "pady": 2, "sticky": "we"}
# Gruppe Develop
devel = ttk.LabelFrame(self)
devel.columnconfigure(0, weight=1)
devel["text"] = _("File watcher for PLC development")
devel.grid(**cpadwe)
r = 0
lbl = ttk.Label(devel)
lbl["text"] = _("Path to list files:")
lbl.grid(row=r, **cpadw)
r += 1
self.lbl_path = ttk.Label(devel)
self.lbl_path["text"] = self.watchpath
self.lbl_path.grid(row=r, column=0, columnspan=2, **cpadw)
btn = ttk.Button(devel)
btn["command"] = self.btn_selectpath
btn["text"] = _("Select path")
btn.grid(row=r, column=1, **cpadw)
# Listbox
r += 1
trv = ttk.Frame(devel)
trv.columnconfigure(0, weight=1)
trv.grid(row=r, columnspan=2, sticky="we")
scb_files = ttk.Scrollbar(trv)
self.trv_files = ttk.Treeview(trv)
self.trv_files.bind("<<TreeviewSelect>>", self.select_pathfiles)
self.trv_files["height"] = 15
self.trv_files["yscrollcommand"] = scb_files.set
self.trv_files.grid(row=0, column=0, sticky="we")
scb_files["command"] = self.trv_files.yview
scb_files.grid(row=0, column=1, sticky="ns")
# Uploadbutton
r += 1
btnlist = ttk.Frame(devel)
btnlist.columnconfigure(1, weight=1)
btnlist.grid(row=r, columnspan=2, sticky="we")
btn = ttk.Button(btnlist)
btn["command"] = lambda: self.xmlcli.plcstop()
btn["text"] = _("Just stop PLC")
btn.grid(row=0, column=0, **cpadwe)
self.btn_jobs = ttk.Button(btnlist)
self.btn_jobs["command"] = self.btn_domyjob
self.btn_jobs["text"] = _("Stop / Upload / Start")
self.btn_jobs.grid(row=0, column=1, **cpadwe)
btn = ttk.Button(btnlist)
btn["command"] = lambda: self.xmlcli.plcstart()
btn["text"] = _("Just start PLC")
btn.grid(row=0, column=2, **cpadwe)
# Beendenbutton
btn = ttk.Button(self)
btn["command"] = self._checkclose
btn["text"] = _("Exit")
btn.grid(**cpad)
def btn_domyjob(self):
u"""Hochladen und neu starten."""
# PLC Programm anhalten
self.xmlcli.plcstop()
# Aktuell konfiguriertes Programm lesen (für uploaded Flag)
opt_program = self.xmlcli.get_config()
opt_program = opt_program.get("plcprogram", "none.py")
uploaded = True
ec = 0
for fname in self.watchfiles:
# FIXME: Fehlerabfang bei Dateilesen
with open(fname, "rb") as fh:
# Ordnernamen vom System entfernen
sendname = fname.replace(self.watchpath, "")[1:]
# Prüfen ob Dateiname bereits als Startprogramm angegeben ist
if sendname == opt_program:
uploaded = False
# Datei übertragen
try:
ustatus = self.xmlcli.plcupload(
Binary(gzip.compress(fh.read())), sendname
)
except:
ec = -2
break
if not ustatus:
ec = -1
break
if ec == 0:
# Wenn eines der Dateien nicht das Hauptprogram ist, info
if uploaded:
tkmsg.showinfo(
_("Information"),
_("A PLC program has been uploaded. Please check the "
"PLC options to see if the correct program is "
"specified as the start program."),
parent=self.master
)
elif ec == -1:
tkmsg.showerror(
_("Error"),
_("The Revolution Pi could not process some parts of the "
"transmission."),
parent=self.master
)
elif ec == -2:
tkmsg.showerror(
_("Error"),
_("Errors occurred during transmission"),
parent=self.master
)
# PLC Programm starten
self.xmlcli.plcstart()
def btn_selectpath(self):
u"""Lässt dem Benuzter ein Verzeichnis auswählen."""
dirselect = tkfd.askdirectory(
parent=self.master,
title=_("Directory to watch"),
mustexist=False,
initialdir=self.watchpath
)
if not dirselect:
return
# Neuen Pfad übernehmen
if os.path.exists(dirselect):
self.pathselected = True
self.watchpath = dirselect
self.load_pathfiles()
else:
tkmsg.showerror(
_("Error"),
_("Can not open the selected folder."),
parent=self.master
)
self.refresh_stats()
def load_pathfiles(self, silent=False):
u"""Aktualisiert die Dateiliste.
@param silent Keinen Dialog anzeigen"""
# Liste leeren
self.trv_files.delete(*self.trv_files.get_children())
# Dateiliste erstellen
filecount = 0
for tup_walk in os.walk(self.watchpath):
for filename in tup_walk[2]:
fullname = os.path.join(tup_walk[0], filename)
self.trv_files.insert(
"", "end", fullname,
text=fullname.replace(self.watchpath, "")[1:],
values=fullname
)
# Dateiobergrenze
filecount += 1
if filecount >= 1000:
break
if filecount >= 1000:
if not silent:
tkmsg.showwarning(
_("Warning"),
_("Found more than 1000 files! Only 1000 files can be "
"shown in this dialog, all other will be ignored."
""),
parent=self.master
)
break
# Alle Elemente für Selection prüfen und anwenden
for watchfile in self.watchfiles.copy():
try:
self.trv_files.item(watchfile)
except:
self.watchfiles.remove(watchfile)
self.trv_files.selection_set(self.watchfiles)
def select_pathfiles(self, tkevt):
u"""Setzt state der Buttons."""
self.watchfiles = list(self.trv_files.selection())
self.refresh_stats()
def refresh_stats(self):
u"""Passt die Widgets an."""
self.btn_jobs["state"] = "normal" if len(self.watchfiles) > 0 \
else "disabled"
self.lbl_path["text"] = self.watchpath
# Debugging
if __name__ == "__main__":
from xmlrpc.client import ServerProxy
cli = ServerProxy("http://localhost:55123")
root = tkinter.Tk()
app = RevPiDevelop(root, cli, 3, "debugging")
app.mainloop()

View File

@@ -12,6 +12,8 @@ import tkinter
import tkinter.messagebox as tkmsg
from mytools import gettrans
from mytools import savefile_connections as savefile
from revpidevelop import _loaddefaults as developloaddefaults
from revpidevelop import _savedefaults as developsavedefaults
from revpiprogram import _loaddefaults as programloaddefaults
from revpiprogram import _savedefaults as programsavedefaults
from os import makedirs
@@ -154,6 +156,11 @@ class RevPiPlcList(tkinter.Frame):
return False
# Andere Einstellungen aufräumen
dict = developloaddefaults()
for revpi in tuple(dict.keys()):
if revpi not in self._connections:
del dict[revpi]
developsavedefaults(None, dict)
dict = programloaddefaults()
for revpi in tuple(dict.keys()):
if revpi not in self._connections:

View File

@@ -15,8 +15,8 @@ import tkinter.filedialog as tkfd
import tkinter.messagebox as tkmsg
import zipfile
from mytools import gettrans
from mytools import homedir
from mytools import savefile_programpath as savefile
from os import makedirs
from shutil import rmtree
from tempfile import mkstemp, mkdtemp
from xmlrpc.client import Binary
@@ -48,7 +48,7 @@ def _savedefaults(revpiname, settings):
"""
try:
makedirs(os.path.dirname(savefile), exist_ok=True)
os.makedirs(os.path.dirname(savefile), exist_ok=True)
if revpiname is None:
dict_all = settings
else:
@@ -588,6 +588,7 @@ class RevPiProgram(tkinter.Frame):
dirtmp = None
filelist = []
fileselect = None
foldername = ""
rscfile = None
if tup == 0:
@@ -595,7 +596,7 @@ class RevPiProgram(tkinter.Frame):
fileselect = tkfd.askopenfilenames(
parent=self.master,
title="Upload Python program...",
initialdir=self.opt.get("plcupload_dir", ""),
initialdir=self.opt.get("plcupload_dir", homedir),
filetypes=(("Python", "*.py"), (_("All files"), "*.*"))
)
if type(fileselect) == tuple and len(fileselect) > 0:
@@ -608,8 +609,12 @@ class RevPiProgram(tkinter.Frame):
parent=self.master,
title=_("Folder to upload"),
mustexist=True,
initialdir=self.opt.get("plcupload_dir", self.revpi)
initialdir=self.opt.get("plcupload_dir", homedir)
)
# Ordnernamen merken um diesen auf RevPi anzulegen
foldername = os.path.basename(dirselect)
if type(dirselect) == str and dirselect != "":
filelist = self.create_filelist(dirselect)
@@ -706,7 +711,11 @@ class RevPiProgram(tkinter.Frame):
if dirselect == "":
sendname = os.path.basename(fname)
else:
sendname = fname.replace(dirselect, "")[1:]
# Ordnernamen in Dateipfad für RevPi übernehmen
sendname = os.path.join(
foldername,
fname.replace(dirselect, "")[1:]
)
# Prüfen ob Dateiname bereits als Startprogramm angegeben ist
if sendname == opt_program:

View File

@@ -9,6 +9,7 @@
#
u"""Hauptprogramm."""
import revpicheckclient
import revpidevelop
import revpiinfo
import revpilogfile
import revpioption
@@ -25,7 +26,7 @@ from xmlrpc.client import ServerProxy
# Übersetzung laden
_ = gettrans()
pycontrolversion = "0.6.2"
pycontrolversion = "0.7.0"
class RevPiPyControl(tkinter.Frame):
@@ -52,6 +53,7 @@ class RevPiPyControl(tkinter.Frame):
# Globale Fenster
self.tkcheckclient = None
self.tkdevelop = None
self.tklogs = None
self.tkoptions = None
self.tkprogram = None
@@ -75,6 +77,8 @@ class RevPiPyControl(tkinter.Frame):
u"""Schließt alle Fenster."""
if self.tkcheckclient is not None:
self.tkcheckclient.destroy()
if self.tkdevelop is not None:
self.tkdevelop.destroy()
if self.tklogs is not None:
self.tklogs.master.destroy()
if self.tkoptions is not None:
@@ -179,6 +183,8 @@ class RevPiPyControl(tkinter.Frame):
label=_("PLC options..."), command=self.plcoptions)
self.mplc.add_command(
label=_("PLC program..."), command=self.plcprogram)
self.mplc.add_command(
label=_("PLC developer..."), command=self.plcdevelop)
self.mplc.add_separator()
self.mplc.add_command(
@@ -282,6 +288,27 @@ class RevPiPyControl(tkinter.Frame):
self.btn_debug["state"] = "normal"
def plcdevelop(self):
u"""Startet das Developfenster."""
if self.xmlmode < 3:
tkmsg.showwarning(
_("Warning"),
_("XML-RPC access mode in the RevPiPyLoad "
"configuration is too small to access this dialog!"),
parent=self.master
)
else:
# Logfenster schließen
if self.tklogs is not None:
self.tklogs.master.destroy()
win = tkinter.Toplevel(self)
win.focus_set()
win.grab_set()
self.tkdevelop = revpidevelop.RevPiDevelop(
win, self.cli, self.xmlmode, self.revpiname)
self.wait_window(win)
def plclist(self):
u"""Öffnet das Fenster für die Verbindungen."""
win = tkinter.Toplevel(self)

View File

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