API für Zugriff aus Webanwendung

  • OK, ist dann quasi im Programmer nur hinterlegt, dass auf dem Property eine Änderung vorhanden ist. Und wenn ich dann in dem Device der Änderung nachschaue, komme ich auf den Effekt?

    Sehe ich das richtig?

  • Wenn ich auf Properties des Programmers auflisten will, muss ich da auf die WorkingSceneEntries zugreifen?

    Für was ist dann die EditScene?


    public IScene EditScene { get; }

    public IList<ISceneEntry> WorkingSceneEntries { get; }

  • Jein. Eigentlich ist die "getProgrammerState" Methode die richtige. Da bekommst du einen Komprimierte Darstellung mit dem Inhalt. Du kannst auch "EditScene.SceneEntries" nehmen, aber das ist leer, wenn gerade keine Szene editiert wird. Also in dem Moment in dem per Clear die zu editierende Szene aus dem Programmer entfernt wird, ist "EditScene" leer. Ansonsten ist "getProgrammerScene" das richtige. Die Methode hat einen Parameter der angibt ob die Einträge als "Saved" markiert werden sollen. Das machst du für Darstellungsszwecke natürlich nicht :D


    WorkingSceneEntries ist auf jeden Fall falsch, das ist für interne Zwecke und sollte "private" sein. Hab ich gerade korrigiert.

  • Hi nochmal,


    ich scheitere gerade am Aufbau meiner Api.

    Vielleicht hat ja jemand einen Rat für mich.


    Ich hab mir jetzt einen Controller für die CueLists angelegt.

    Jetzt hätte ich 2 allgemeine Fragen:

    • Soll ich für die Cues der CueList einen eigenen Controller anlegen, oder soll ich das wie im Programm Beispiel unten machen mit der GetCues(string sceneListID) Methode?
    • Soll ich für die Programmer Aktionen einen eigenen Controller machen, oder diese auch hier in die CueListController reintung.
      • Wenn einen ProgrammerController: Wie sollen die aktionen dann aussehen:
        • ./api/programmer/editscene/<sceneListId>/<sceneId>
        • ./api/programmer/loadprogrammerinscenelist/<scenelistId>/<sceneID>

    Das gleiche müsste ich dann für die Devices auch machen.

    Kann mir da jemand helfen? Bin recht neu in der Materie WebApi


  • Willkommen in einer sehr komplexen Welt. Ein gutes API Design ist schwer zu erstellen. Moritz, der die API für die DDFLib entwarf, hat hier einige male umgebaut.


    Ich würde generell versuchen die Objekte zu trennen, also Cuelist, Programmer, Preset, Device, alles eigene Objekte, ergo eigene Controller und eigene Routes. Dabei würde ich nur für Objekte die Eigenständig existieren können einen Controller anlegen. Cues können nur im Kontext einer Cuelist existieren, ergo würde ich für diese keinen Controller vorsehen.


    Die Klassen "Cue" bzw. "Cuelist" die du als Wrapper um die DMXC Objekte packst, sind Facaden oder, die die relevanten Attribute für die REST API bereit Stellen, korrekt?

  • Ja das dachte ich mir schon, dass das eine sehr komplexe Welt ist ;)

    Ja CueList und Cue sind Wrapper Objekte, die nur die für mich relevanten Daten enthalten.


    Wie geht man in einer Rest Api generell vor, wenn man sowas wie den Programmer nachbildet.

    Macht man das so, wie ich oben vorgeschlagen habe? Und ist das dann auch ein "ProgrammerController : APiController"

    • ./api/programmer/editscene/<sceneListId>/<sceneId>
    • ./api/programmer/loadprogrammerinscenelist/<scenelistId>/<sceneID>
  • An dieser Stelle möchte ich nochmal die Frage stellen: was ist der Hintergrund, dass du (zwingend) die (komplette) Programmierung der Lichtsteuerung über die Web-App laufen lassen möchtest und gerade deswegen verschiedene Programmteile entsprechend nachbaust? Bist du in vielen verschiedenen Locations unterwegs, oder was ist der Hintergrund, dass du eben nicht die "klassische" GUI von DMXControl 3 für die Programmierung nutzen kannst?


    Ich frage deswegen (möglicherweise auch gefühlt) recht provokativ nach, weil ich gerne das komplette Szenario verstehen möchte, welches dich auf die Idee gebracht hat, die Web-App zu entwickeln. Vielleicht kannst du ja das komplette Szenario (also insbesondere deine aktuelle Ausgangssituation / die Problemstellung) etwas detaillierter umreißen - natürlich nur wenn du magst. ;) Das Ziel hattest du ja mal kurz beschrieben: Nutzung eines Tablets für die Programmierung.


    Bestimmt kannst du dann - wenn (mir) die Ausgangssituation klar ist - auch noch weitere Tipps erhalten, die dir weiterhelfen und - was ja auch sein kann: vielleicht ergibt sich hieraus über kurz oder lang für DMXControl 3 selbst ebenfalls Verbesserungs-Potentiale, welche die Software insgesamt noch weiter nach vorne bringen. :)

  • Ich will eigentlich damit nur folgendes Abdecken.


    Der Laptop steht fest verbaut auf der Bühne und ich will vor dem Gig eigentlich nur die Bewegungszenen editieren. Und das am besten per Tablet oder Smartphone vor der Bühne.

    Ich will keine neuen Properties hinzufügen, oder Devices ändern.

    Ziel ist wirklich nur die Werte der einzelnen Programmer Properties aufzulisten und die Werte zu ändern.


    Dazu sind folgende Schritte notwendig:

    1. Alles CueLists auflisten.

    2. CueList auswählen und die Cues dazu auflisten.

    3. Cue in Programmer laden.

    4. Programmer Properties (+Effekte) anzeigen und ganz einfach per Tastatur im AnzeigeGrid ändern.

    5. Entweder Programmer Values in Cue übernehmen, oder Programmer löschen.


    Und evtl. kommt hinter jede CueList noch ein Button "play".

    Unser Live Laptop ist ganz unten im Rack verbaut und das ist immer sehr umständlich auf diesen zu Programmieren.


    Hoffe es ist jetzt ersichtlich, was mir das ganze bringt?

  • Schau dir mal die https://martinfowler.com/artic…hardsonMaturityModel.html an.


    Beim Programmer würdest du das eher so machen:

    POST /api/programmer/edit => Und im Body dann die sceneListID und die SceneID, oder eben eine PresetID, wenn man ein Preset in den Programmer laden will.


    Zurück speichern dann in der Cueliste


    POST /api/cuelist/sceneListID/cue/sceneId => Im Body dann die Referenz auf den Programmer der gespeichert werden soll.


    Das mal als Beispiel, wie ich es machen würde.

  • Puh, bis jetzt funktioniert alles soweit, aber beim Auflisten der aktuellen Werte vom Programmer bin ich ein bisschen überfordert.


    Ich dachte ich muss hier nur eine Liste von Key-Value-Paaren ausgeben, und den geänderten Value an DMXC3 zurückgeben.


    Die Fragen sind in <Frage> geschrieben.

  • Ok jetzt bin ich schon ein bisschen weiter.

    Eigentlich müsste ich nur wissen, wie ich von einen IGuiSceneEntry auf die SubProperties komme?

    Da ich vermute, dass dort die Effekte gespeichert sind.

    Und wie ich die SubProperties/Effekte dann im Programmer ändere...


    Code
    foreach (IGUISceneEntry sceneEntry in programmerSceneEntries)
    {
    
    }
  • Die Effekte hängen alle in der "sceneEntry.GUIPropertyValue.GUIValueAttachables" Liste.


    Jedes "GUIAttachableContext" Objekt in der Liste ist ein Effekt. Das AttachedToSubProperty Property des Context ist "null" wenn es sich um einen Effekt auf dem Haupt Property Handelt (z.B. Position), ansonsten den Namen des SubProperties (e.g. Tilt).


    Das Attachable Objekt ist der Effekt. Die Parameter können direkt geändert werden. Eine Liste der Parameter bekommst du mit Attachable.Parameters. Lesen, und Schreiben im Programmer geht über die "setAttachableParameter" bzw. "getAttachableParameter" Operationen im Programmer.

  • Ok, jetzt hab ich das verstanden.


    In den DeviceProperties kann man ja in der Gui die Strings selber bearbeiten und diese werden automatisch im Programmer gesetzt.

    z.B. wenn ich beim Dimmer eingebe "100 # 0"


    Kann ich das irgendwie 1:1 im Code machen, dass ich den fertigen String auslese und als fertigen String im Programmer setze?


    Code
    // Hier z.B. für die Position
    MySession.SessionProgrammer.setPropertyValue(groupID, propID, "45 # -45; 0", false);
  • Dafür gibt es 2 Strukturen: IFannedValue ist das Interface für die interne Speicherung und die Logik dahinter. Hier gibt es pro Fanning Operator (also z.B. #) eine entsprechende Klasse die das implementiert. Für den Transport ins UI und dir dortige Darstellung gibt es "IFannedValueContainer". Hier gibt es pro Datentyp (Double, Color, Position) jeweils eine Implementierung.


    Auf dem Weg vom / zum UI gibt es den "FannedValueManager" der vom einen ins andere umwandeln kann.

  • So hab mir jetzt wieder einen Account zugelegt ;)

    vielen Dank für die Hilfe bis jetzt.


    Wow, ihr macht mich echt fertig ;)


    Ich beschänke mich jetzt mal nur auf Positionen:


    Hab ein PositionFannedValue-Objekt und dieses hat ja Values.

    Die Values sind Position[].

    Warum hat hier eine normale Position 2 Einträge.


    Code
            public PositionFannedValueWrapper(PositionFannedValue positionFannedValue)
            {
                Position[] positions = positionFannedValue.Values;
                this.Positions = new List<PositionWrapper>();
                foreach (Position position in positions)
                {
                    this.Positions.Add(new PositionWrapper(position));
                }
            }

    Hier gebe ich meine Werte vom Programmer schon in der Angular Anwendung aus.


  • Newly created posts will remain inaccessible for others until approved by a moderator.

    The last reply was more than 365 days ago, this thread is most likely obsolete. It is recommended to create a new thread instead.