Pythonskript bei ControlDesk NG Ausführen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
miriane
User
Beiträge: 17
Registriert: Mittwoch 30. Juli 2014, 14:25

Hallo,
muss ein Pythonskript bei ControlDesk NG Ausführen. Muss erst eine Excell-Tabelle mit variablename und wert erstellen und in meinen Skript aufrufen. Wie folgt datei = "Value.csv".
Es muss auch ein Event für die Variable , die ich ändert will konfuguiert werden (in Layout).
Ich habe einen MatlabModel und will den Parameter Zeitschritt [Name:dSPACE StaticText Control_3/ Wert: dSPACE NumericInput Control] Hilfe meines Skriptes ändert.
Ich weiße leider nicht genau , was in meinen Skript geschrieben wird.
Habe vorher gar nichts zu tun mit Python , versuch einfach aus internet zu lesen.
Hat jemand schon sowas gemacht?
Ich brauche bitte Hilfe, ich habe bis jetzt keinen gefunden, der mir helfen kann.

Hier was ich geschrieben habe, aber scheint nicht logich. :( :?

Code: Alles auswählen

#import com_error
#import cdautomationlib
#import tempfile
#import os
#import exceptions
#import string

datei = "Value.csv"
namen = []        #parameter-Namen werden hier geschrieben
zahlenwerte = []  #Zahllenwerte werden hier geschrieben

liste = [] #eine liste wird erstellt

liste.append('Zeitschritt [s]') # parameter werden Hinzugefügt
index1 = liste.index('Zeitschritt [s]')  # variablenzuweisung

obj = open(datei,"r")  #CSV-datei wird geöffnet r =read(lesen)

for zeile in obj:       #for-schleife für jede einzelne zeile in Dateiobjekt

    zeile = zeile.rstrip("\n") #rstrip, gib eine Kopie der Zeile ohne(nächste Zeile) zurück
    i = 0
    while i < len(liste):
        if liste[i] in zeile:  # falls vorhanden wird folgende ausgeführt
            teile = zeile.split(';') #die zeile wird geteilt mittels ";" 'linken=Name mit Einheit', 'rechten=zahlenwert'
            namen.append(str(teile[0])) #link stehen namen mit Einheit
            zahlenwerte.append(float(teile[1])) # recht stehen zahlenwerte
        i = i+1
        
obj.close() # deteiObjet mit der methode "close()"schliessen

a = Application.ActiveProject.ActiveExperiment.Platforms.Item('ds1006')
b = a.ActiveVariableDescription.DataSets.WorkingDataSet.Parameter.Item('Model Root/Timestep/Value')

indexb = namen.index(liste[index1])
b.Value = zahlenwerte[indexb]
Zuletzt geändert von Anonymous am Mittwoch 30. Juli 2014, 15:29, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Oha... da weiß man ja kaum, wo man anfangen soll... :shock:

Ok, zerlege doch Dein Problem erst einmal in Teilprobleme!

Vergiss, dass Du aus irgend einer CSV-Datei Werte holst. Fake-Daten kannst Du zu Beginn auch fix im Code hinterlegen; eben so viele, wie man braucht, um zu sehen, ob der eigentliche Vorgang arbeitet.

Wobei mir noch gar nicht klar ist, *was* der eigentliche Vorgang ist und *wo* das im Code aufgerufen wird.

Aber imho solltest Du damit anfangen.

Ich kann Dich insofern beruhigen, dass CSV-Dateien parsen echt ziemlich trivial ist.

Also: Erst einmal baue ein Script, welches funktioniert für einen Datensatz mit Demodaten, die Du fix im Script hinterlegst.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Wie man über die Elemente einer Liste iteriert, gehört bei Python zu den absoluten Grundlagen, will sagen, um das Durcharbeiten eines Anfängertutorials kommst Du nicht drumrum (Tipp: while-Schleife ist die falsche Antwort). Dabei macht hier die Liste `liste` überhaupt keinen Sinn, da sie sowieso nur ein immer gleiches Element enthält. Wenn namen und zahlenwerte zusammengehören, steck sie auch zusammen in eine Liste und nicht in zwei.
Sollten doch mehr Schlüssel als 'Zeitschritt [s]' in der Datei relevant sein, dann ist wahrscheinlich die passende Datenstruktur ein Dictionary und keine Liste. Wie man ein Dictionary benutzt steht auch in jedem Anfängertutorial.

PS: csv-Dateien sind keine Excel-Dateien. Nur weil ich absolut jede Datei mit meinem Texteditor öffnen kann, heißt das noch lange nicht, dass alle Dateien Textdateien sind.
miriane
User
Beiträge: 17
Registriert: Mittwoch 30. Juli 2014, 14:25

Hallo,
danke für die Hinweise.Ich selbst habe nicht grosse Ahnung wie es funktioniert wird/soll. Es ist eine Aufgabe , der Prof selbst weißt auch nicht wie man darauf kommt. Die Excel- Tabelle soll man einfach als csv-Datei speichern(habe gelesen).
Ich glaube mein code ist lang und macht auch keinen Sinn für nur eine variable[Zeitschritt],wie gesagt lerne gerade python und muss so schnell als möglich mit meiner Aufgabe fertig seien.
Es ist nicht meine Idee ,die benötige Daten in Excel zu schreiben, muss einfach so tun.
Ich erwarte bitte Vorschlage und brauche Hilfe von jemanden der sich mit ControlDesk und denen Funktionalität kennt (Ausführung von Pythonskript usw).
Wie werden Sie das Skript erstellen?
Grüße
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@miriane: wenn Du wirklich nur eine Zahl hast, dann ist eine Excel-Tabelle wohl etwas umständlich. Als erstes brauchst Du eine Funktion, die einfach nur den Zeitschritt setzt:

Code: Alles auswählen

def set_timestep(value):
    experiment = Application.ActiveProject.ActiveExperiment
    ds1006 = experiment.Platforms.Item('ds1006')
    dataset = ds1006.ActiveVariableDescription.DataSets.WorkingDataSet
    timestep = dataset.Parameter.Item('Model Root/Timestep/Value')
    timestep.Value = value
das kann man mit fest vorgegebenen Werten testen:

Code: Alles auswählen

set_timestep(3.5)
Jetzt wird es ja nicht wohl nur einen Wert geben, denn dann braucht man sich ja die ganze Mühe mit der Automatisierung nicht machen. Daher die Fragen:
1) woher kommen die Werte
2) wie viele sind es?
3) wie häufig ändern sie sich?
daraus läßt sich dann ableiten, welches das sinnvollste Datenformat zur Eingabe/Weiterverarbeitung/Dokumentation ist. Alle drei Punkte muss man dabei im Blick haben, um einen möglichst einfachen Automatisierungsprozess zu haben. Einfach heißt: wenig Code, leicht verständlich, um damit schnell fertig zu sein, Fehler schnell zu finden, Korrektheit schnell zu prüfen, andere schnell einzuarbeiten, Änderungen schnell zu machen, in 5 Jahren schnell wieder hineinzufinden und am wichtigsten die eigentliche Arbeit angenehmer zu machen.
miriane
User
Beiträge: 17
Registriert: Mittwoch 30. Juli 2014, 14:25

Hallo,
sorry war am Wochenende nicht da.
Als test soll ich am Anfang nur die variable Zeitschritt ändert.Wenn es funktioniert werde ich einen Skript für alle Parameter von meinen Matlab-Model(Layout von ControlDesk) ändert, das macht man während der Simulation.
Deswegen wir überlegt , dass ich schon am Anfang die Parameter in Excel schreibe.
Mit CSV (Trennzeichen getrennt), werden die Zeilen untereinander geschrieben und Spalten durch ein Semikolon voneinander getrennt

Nochmals meine Aufgabe:
1- Erstellung eines Parametersets in M-Excel
2-Veränderung von Variabenwerten in ControlDesk mittels eines Python-Scripts
3-Eventgesteuertes Starten des Python-Scripts im Layout von ControlDesk
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Noch zwei Fragen:
1) gibt es nur einen Datensatz? Einen pro Excel-File? Mehrere in einem Excel-File?
2) woher kommen die Werte? Werden sie von Hand in Excel eingetragen? Aus einer anderen Datei kopiert?
miriane
User
Beiträge: 17
Registriert: Mittwoch 30. Juli 2014, 14:25

-Es gibt mehrere Datensätze, und ich werde sie alle in meinen Excel-File schreiben und bestimmte Werte zuweisen.
-Ja die werte werde ich in Excel eintragen.
Im Layout von ControlDesk haben die Parameter schon Werte die geändert werden sollen , die stammen vom Matlab-Model.

Wie schon gesagt ich fange erst mit dem Parameter Zeitschrift und danach werde ich meinen Skript erweitern und die andere Parameter eintragen.
Daher habe ich überlegt schon am Anfang eine For-Schleife zu benutzen.

Grüße.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Im cvs-Modul gibt es den DictReader. Wenn Du also Deine Parameter nicht zeilenweise, sondern spaltenweise mit einer Headerzeile schreibst, ist das Einlesen damit schon erledigt. In Dictionary ist nämlich die sinnhaftere Datenstruktur als zwei Listen.
miriane
User
Beiträge: 17
Registriert: Mittwoch 30. Juli 2014, 14:25

Hi Sirius3,
macht meine for-schleife und die Liste "liste" sinn?

Ich bekomme diese Fehlermeldung und weiße nicht genau was erwartet wird.

File "C:\Program Files (x86)\Python27\lib\codeop.py", line 133, in __call__
codeob = compile(source, filename, symbol, self.flags, 1)

test\python Scripts\_testlayout_01.py", line 18
datei = "Value.csv"
^
IndentationError: expected an indented block
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@mariane: Bei Python ist die Einrückung wichtig für die Bedeutung des Codes. Arbeite mal ein Anfängertutorial durch; ohne kommst Du nicht weiter.
miriane
User
Beiträge: 17
Registriert: Mittwoch 30. Juli 2014, 14:25

ich lese schon
https://www.python.org/doc/" (die Doku zu python allgemein)
Problem (Stress): du bekommst eine Aufgabe, du hast keine Ahnung , du muss überall lesen , aber man erwartet , dass du die Aufgabe so schnell als möglich abgibst (du hast einfach eine Frist).
Bin schon müde, aber leider finde keiner an der FH, der sich damit kennt oder der schon sowass gemacht hat(Ausführung von skripts bei ControlDesk NG in zusammennhang mit Events).
miriane
User
Beiträge: 17
Registriert: Mittwoch 30. Juli 2014, 14:25

32. a = Application.ActiveProject.ActiveExperiment.Platforms.Item('ds1006')
33. b = a.ActiveVariableDescription.DataSets.WorkingDataSet.Parameter.Item('Model Root/Timestep/Value')[/Code]
Fehlermeldung:
Traceback (most recent call last):
File "C:\Program Files (x86)\Python27\lib\codeop.py", line 133, in __call__
codeob = compile(source, filename, symbol, self.flags, 1)
File "D:\Miriane KM\Test_Digitalkarten dig_in_highbits\CDNG5_1\Project_001\test_dig\Python Scripts\_testlayout_01.py", line 32
a = Application.ActiveProject.ActiveExperiment.Platforms.Item('ds1006')
^
IndentationError: expected an indented block

irgendwann hatte ich auch bei 33 "Parameter not defined"

Hat jemand eine Idee ???
Danke im Voraus
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@miriane: wie schon geschrieben, Blöcke müssen in Python eingerückt werden, und zwar am besten mit 4 Leerzeichen. Mit Raten wirst Du nicht weit kommen, es gibt einfach zu viele Möglichkeiten, die falsch sind. Und seit Deinem fehlerhaften Code von letzter Woche scheinst Du auch nicht weiter gekommen zu sein. Das Forum kann aber kein Programmierkurs sein. Das mußt Du Dir schon selbst aneignen.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Um mal Sirius3 zu zitieren:
Bei Python ist die Einrückung wichtig für die Bedeutung des Codes. Arbeite mal ein Anfängertutorial durch; ohne kommst Du nicht weiter.
Guckstu:

Code: Alles auswählen

>>> x = 1
>>> if x == 1:
...     print('ja')
...
ja
>>> if x == 1:
... print('ja')
  File "<stdin>", line 2
    print('ja')
        ^
IndentationError: expected an indented block
In specifications, Murphy's Law supersedes Ohm's.
miriane
User
Beiträge: 17
Registriert: Mittwoch 30. Juli 2014, 14:25

Hi Leute,
hatte nicht verstanden was die Einrückung ist. Jetzt gelesen und verstanden.
Mein erste Problem ist gelöst.
Danke nochmals für die Hinweise.
Ich komme sicher mit neue Frage.
Danke nochmal.
miriane
User
Beiträge: 17
Registriert: Mittwoch 30. Juli 2014, 14:25

Hi,
ich habe insgesamt 59 Parameters(von meinem Layout) , kann ich auch nur eine Funktion (Methode) für die gesamte Parameters erstellen?
Beispiel:
def Hauptprogramm(datei, parametersetnr):
---

Danke im Voraus
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@mariane: ja, das geht. Du mußt aber eine passende Parametrisierung finden, um die Funktion übersichtlich zu halten. Mehr als 30 Zeilen sollte nämlich so eine Funktion nicht haben. Du wirst dafür wahrscheinlich Dictionaries brauchen.
miriane
User
Beiträge: 17
Registriert: Mittwoch 30. Juli 2014, 14:25

Hey,
wer sieht Fehler?

Code: Alles auswählen

datei = "D:\Miriane KM\Test_Digitalkarten dig_in_highbits\CDNG5_1\Project_001\test_dig\Value.csv"
obj = open(datei,"r")
 
Traceback (most recent call last):
  File "D:\Miriane KM\Test_Digitalkarten dig_in_highbits\CDNG5_1\Project_001\test_dig\Python Scripts\testlayout_01.py", line 25, in <module>
    obj = open(datei,"r")
IOError: [Errno 22] invalid mode ('r') or filename: 'D:\\Miriane KM\\Test_Digitalkarten dig_in_highbits\\CDNG5_1\\Project_001\test_dig\\Value.csv'
Zuletzt geändert von Hyperion am Dienstag 12. August 2014, 12:33, insgesamt 1-mal geändert.
Grund: Code in Python-Code Tags gesetzt.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Backslashes haben eine besondere Bedeutung in Strings. Vergleiche mal Zeichen für Zeichen deines Aufrufs mit dem String in der Fehlermeldung.
Das Leben ist wie ein Tennisball.
Antworten