Aktuelles CSharp Beispiel

Hallo,
da ich bei der Einarbeitung aktuell einige Probleme mit den Beispielen im Forum hatte (bzw. wenig CSharp Beispiele zu finden sind), möchte ich kurz meine Erfahrungen dokumentieren und einen Beispielcode liefern (vielleicht hilfts Jemanden):

Unter Visual Studio 2008 muss der Webservice als Webservice und NICHT als Service eingebunden werden, sonst funktionieren die per WDSL generierten Routinen nicht (per wdsl.exe generierte proxys funktionierten bei mir unter visual studio 2008 leider auch nicht)!

Mein funktionierender Testcode:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using fs20cmd.IIPSFHT;
using fs20cmd.IIPSFS20;
using fs20cmd.IIPSSOAPServer;
using fs20cmd.IIPSInstanceManager;
namespace fs20cmd
{
class Program
{
static void Main(string args)
{
// Tests der verschiedenen Services
// SOAP Server

        IIPSSOAPServerservice proxy = new IIPSSOAPServerservice();
        string message = proxy.StartSession(TIPSFilterType.ftExcludeFilter); 
        // Hum, damit kann man irgendwie nicht so viel machen...oder ich verpasse etwas?
        Console.WriteLine("Debug: {0}",message);
        
        // Instancen ausgeben
        Console.WriteLine("Instances:");
        IIPSInstanceManagerservice instance = new IIPSInstanceManagerservice(); 
        ushort[] aListe = instance.GetInstanceList(); 
        
        foreach (ushort element in aListe) 
        { 
            Console.WriteLine("ID: {0}", element);
        }
        ConsoleKeyInfo key;

        // Mit fs20 Service verbinden
        IIPSFS20.IIPSFS20service fs20device = new IIPSFS20.IIPSFS20service(); 
        
        // Id der zu schaltenden Steckdose   
        fs20device.TIDHeaderValue = new IIPSFS20.TIDHeader(); 
        fs20device.TIDHeaderValue.ID = 20196;

        // 1 = einschalten für 10 sekunden, 0= ausschalten, q=quit 
        do
        {
            key = Console.ReadKey();
            if (key.KeyChar.Equals(Convert.ToChar("q"))) return;
            else if (key.KeyChar.Equals(Convert.ToChar("0")))
                fs20device.SwitchMode(false);
            else fs20device.SwitchDuration(true, 10);

        } while (true);
    }
}

}
Grüße, Benjamin

Hallo, danke für Dein Beispiel. Soweit war ich heute morgen auch gerade gekommen :wink:

Was mir aber fehlt (hat auch nichts mit C# zu tun): wie kann ich in der Instancen-Liste erkennen, von welchem Typ eine Instanz ist?

Was ich möchte, ist sowas wie ein- und ausschalten realisieren, egal ob das device über fs20 oder xComfort angeschlossen ist. dazu müßte ich eben eine Fallunterscheidung einbauen, je nach type.

Kann mir jemand einen Tipp geben? Ist alles etwas schlecht dokumentiert. Oder man findet es schlecht. Wo könnte ich sowas denn nachlesen oder ein Beispiel finden?

Viele Grüße Steve

Überleg, wie du es unter PHP machen würdest. Dann wirst du es auch über SOAP schaffen, da die Befehle die selben sind.

=> Guck einfach in die Befehlsreferenz

paresy

Ok, d.h. per GetInstance / ModulInfo bzw. getObject / ObjectType. Was anderes finde ich nicht. Was ich auch nicht finde, ist eine Übersicht welche String-Konstanten werden denn zurückgegeben, wenn ich nach ModulName frage?

Okay, das kann ich evtl. über die Modulverwaltung rauskriegen …

Hab ich was vergessen?

Was ich mir überlege, ist für MediaPortal ein natives Plugin zu schreiben mit dem man ähnlich wie im WebFront über den Baum navigieren und die Devices steuern kann.

Oder hat jemand sowas schon? ipshomecontrol mal ausgenommen, weil mir dass nicht so wirklich gefällt (Optik und Funktionalität).

Gruss Steve

GetObject + ObjectType und GetInstance + ModuleID wäre die bessere Wahl.

Eine Auflistung gibt es dann hier:
IPS_GetModuleList - IP-Symcon :: Automatisierungssoftware

paresy

PS: Ein MP Plugin gibt es meines Wissens nach noch nicht.

Hallo Steve,

cool dies ist exakt mein Beweggründ mit C SHarp die Soap Schnittstelle auszuprobieren und den o.g. Code zu schreiben. :eek:

Ich habe bisher leider auch nur einen Beispielcode für ein Mediaportal Plugin in C Sharp und die o.g. Zeilen. Halt mich gerne auf dem Laufenden oder binde mich gerne direkt mit ein!!

Grüße, Benjamin

Hi,

ich hab jetzt ein Plugin laufen, was für meine Zwecke schon ganz gut funktioniert. Es ist nicht so generisch wie das WebFront, sondern nutzt recht
einfach den Skin-Editor von Mediaportal selber.

Das ganze geht so:

  • [li] man nutzt den Skin-Editor von Media-Portal und stellt sich ein oder mehrere Screen zusammen, die die Steuerung ergeben sollen.
    [/li][li] bei bestimmten Controls in den Skins gibt’s ein paar magische Eigenschaften (Description): man trägt einfach die IP-Symcon ID ein und schon installiert das Plugin den passenden Handler, der beim Anklicken, das richtige tun.
    [/li]Beispiel: ein ToogleButton -> ein Ein-Aus-Schalter mit Zustands-Visualisierung.

Damit ist zwar etwas Handarbeit nötig, aber man kann sich die Oberfläche ganz individuell zusammen bauen.

Bislang geht’s allerdings nur mit FS20-Aktoren und Script-Instanzen ist aber relativ leicht erweiterbar.

Für mich tut’s das schon :wink:

Gruß Steve

Hallo,
cool das es so schnell vorran geht.

Bzgl. des Skin-Editors bin ich fast der Meinung, dass man dies bei entsprechender Dokumentation so belassen könnte.
Die meitsen Ip-Symcon Anwender sind ja durchaus technisch versiert und arbeiten sich da schnell ein.:stuck_out_tongue:

Laß mir gerne den Code zukommen, dann teste ich das Plugin am Wochenende mal und sehe mir den Code an.
Grüße, Benjamin

Ja der neue Skin Editor ist recht komfortabel. Wenn ich’s halbwegs aufgeräumt hab, dann lad ich mal ein paar Screenshots und den Quellcode hoch.

Bedienen kann man es jetzt schon recht gut.

Gruß Steve

Hi,

gerade „hänge“ ich ein bisschen: Wie kann ich denn auf ein Ereignis reagieren? Das ich ein Event erzeugen kann ist schon klar. Aber ich will nicht nur ein Script auf IPS starten, sondern mein remote C# Client soll das mirkriegen.

Also konkret wenn sich in ips eine Variable ändert, dann soll ein Stück C# angesprungen werden. Wie mache ich das denn? (die remote console kann sowas ja).

Gruß Steve

Guck dir mal das Delphi Beispiel an und dort den „MessageReader“.

paresy

@paresy: welches delphi beispiel?

gruss steve

Hallo Steve,
schau Dir mal den Thread an:

Am Ende ist ein VB.Net Beispiel verlinkt, ich denke dies ist genau das was Du suchst.:slight_smile:

Viele GRüße, Benjamin

Okay, danke. ich habs jetzt. klappt wunderbar.

jetzt muss ich das nur halbwegs sinnvoll in den MP Plugin-Code integrieren. dann ändert sich auch der angezeigte status, wenn ich das nicht selber schalte :wink:

gruss steve

Hi, jetzt häng ich schon wieder etwas:

Wie geht denn ein GetValueFormatted, also Variable mit Profil auslesen, von remote (über SOAP)?

Irgendwie hab ich’s in der Doku nicht gefunden …

@Paresy: kannst Du vielleicht nochmal helfen.

Gruss Steve

Da du über den Rückkanal nur die Rohwerte bekommst, hat es keinen Sinn die GetValueFormatted über SOAP anzubieten.

Du musst das Profil der Variable einlesen und selber darauf anwenden. (z.B. Prefix/Suffix/Nachkommastelle)

paresy

Gut dann kann man es auch so ausdrücken:

Wäre schön wenn es eine Möglichkeit gäbe über den Rückkanal auch gleich formatierte Wert zu bekommen.

So bleibt mir in der Tat nur die komplette Formatier-Logik der Profile (inkl. Associations) abzubilden.

Gruss Steve

So viel Code ist das gar nicht. Hier mal als PHP-Beispiel aus dem WebFront Retro:

function getAssociatedValue ($object, $value, $useAssociations = true, $printValue = null)
    {
        if ($object["VariableProfile"]["ProfileName"] == "~UnixTimestamp") { return date("m.d.y H:i:s", $value); }
        
        $printValue = ($printValue === null) ? $value : $printValue;
        $last = null;
        
        if ($useAssociations)
        {
            foreach ($object["VariableProfile"]["Associations"] as $i)
            {
                if ($value >= $i["Value"])
                {
                    if ($i["Name"] !== "")
                    {
                        $last = $i;
                    }
                    else
                    {
                        $last = null;
                    }
                }
                else
                {
                    break;
                }
            }
        }
        
        if ($last !== null)
        {
            $value = sprintf($last["Name"], $printValue);
        }
        else if (!is_string($value))
        {
            if (trim($object["VariableProfile"]["Suffix"]) == "%")
            {
                $value = ($value / ($object["VariableProfile"]["MaxValue"] - $object["VariableProfile"]["MinValue"])) * 100;
            }
            $value = sprintf("%.".$object["VariableProfile"]["Digits"]."f", $value);
        }
        $result = $object["VariableProfile"]["Prefix"].$value.$object["VariableProfile"]["Suffix"];
        
        return $result;
    }

Ok, stimmt. Sieht sehr übersichtlich aus. Ich hab inzwischen erst mal ne Variante, die C# String.format nutzt, da geht ja auch schon einiges.

Nachteil ist aber, dass man dann ggf. doppelte Arbeit hat, erst in IPS das Profil und dann nochmal in C# das Format.

Aber das ist in der Tat nicht viel, das werde ich mir noch gönnen :wink:

Ich hoffe mal, dass ich diese Woche dann genug zusammen habe, um es mal vorzustellen

Gruß Steve.

Was in deinem Beispiel nicht vorkommt sind CustomProfiles, oder?

Ausserdem gibt’s in C# wegen der strengeren Typisierung doch etwas mehr Code zu schreiben (Associations auf Bool z.B. da die Wert der Association immer double sind???)

Ein weiteres Problem über das ich gestoplert bin: Das Encoding passt nicht. Wenn ich mit einem ~Temperature Profile formatiere kommt das °C nicht richtig rüber, stattdessen wird ??C ausgeben (ist vielleicht UTF-8 encoded, wird aber nicht so aufgefasst).

Fällt da jemand was zu ein?

Gruß Steve