Ankündigung

Einklappen
Keine Ankündigung bisher.

C# -> knx

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    C# -> knx

    Ich habe grade mal einen kurzen Test mit der KNX.net Bibliothek von Codeplex ausprobiert und auf meinem Test-Board eine Lampe an und ausgeschaltet.
    Das möchte ich euch nicht vorenthalten!

    Die Verwendung ist denkbar einfach. Ein beiligendes Testprojekt veranschaulicht dies auch. Dazu musste ich nur die Objekt-Gruppenadresse anpassen und es lief sofort.
    Die Events und Status-Änderungen kommen per Event rein und können dann dementsprechend auch gefiltert werden wenn man möchte.
    Zusätzlich sind noch Beispiele für Temperatur und Blendensteuerung mit dabei aber auskommentiert.

    Code:
    class TestRouting
        {
    
            private static KNXLib.KNXConnection connection = null;
            static void Main(string[] args)
            {
                connection = new KNXLib.KNXConnectionRouting();
                connection.Debug = false;
                connection.ActionMessageCode = 0x29;
                connection.Connect();
                connection.KNXConnectedDelegate += new KNXLib.KNXConnection.KNXConnected(Connected);
                connection.KNXDisconnectedDelegate += new KNXLib.KNXConnection.KNXDisconnected(Disconnected);
                connection.KNXEventDelegate += new KNXLib.KNXConnection.KNXEvent(Event);
                connection.KNXStatusDelegate += new KNXLib.KNXConnection.KNXStatus(Status);
    
                //// LIGHT ON/OFF
                Console.WriteLine("Lampe 1 AN senden");
                Console.ReadLine();
                connection.Action("0/0/1", true);
                Thread.Sleep(200);
                Console.WriteLine("Lampe 1 AUS senden");
                Console.ReadLine();
                connection.Action("0/0/1", false);
                Thread.Sleep(200);
    
                //// BLIND UP/DOWN
                //Console.WriteLine("Press [ENTER] to send command (2/1/1) - false");
                //Console.ReadLine();
                //connection.Action("2/1/1", false);
                //Thread.Sleep(200);
                //Console.WriteLine("Press [ENTER] to send command (2/1/1) - true");
                //Console.ReadLine();
                //connection.Action("2/1/1", true);
                //Thread.Sleep(200);
                //Console.WriteLine("Press [ENTER] to send command (2/2/1) - true");
                //Console.ReadLine();
                //connection.Action("2/2/1", true);
                //Thread.Sleep(200);
    
                //// BLIND UP/DOWN
                //Console.WriteLine("Press [ENTER] to send command (2/3/1) - \x00");
                //Console.ReadLine();
                //connection.Action("2/3/1", 0x00);
                //Thread.Sleep(200);
                //Console.WriteLine("Press [ENTER] to send command (2/3/1) - \xFF");
                //Console.ReadLine();
                //connection.Action("2/3/1", 0xFF);
                //Thread.Sleep(200);
                //Console.WriteLine("Press [ENTER] to send command (2/3/1) - \x80");
                //Console.ReadLine();
                //connection.Action("2/3/1", 0x80);
                //Thread.Sleep(200);
                //Console.WriteLine("Press [ENTER] to send command (2/2/1) - true");
                //Console.ReadLine();
                //connection.Action("2/2/1", true);
                //Thread.Sleep(200);
    
                // TEMPERATURE SETPOINT
                //Console.WriteLine("Press [ENTER] to send command (1/1/16) - 28ºC");
                //Console.ReadLine();
                //connection.Action("1/1/16", connection.toDPT("9.001", 28.0f));
                //Thread.Sleep(200);
                //Console.WriteLine("Press [ENTER] to send command (1/1/16) - 27ºC");
                //Console.ReadLine();
                //connection.Action("1/1/16", connection.toDPT("9.001", 27.0f));
                //Thread.Sleep(200);
                //Console.WriteLine("Press [ENTER] to send command (1/1/16) - 26ºC");
                //Console.ReadLine();
                //connection.Action("1/1/16", connection.toDPT("9.001", 26.0f));
                //Thread.Sleep(200);
                //Console.WriteLine("Press [ENTER] to send command (1/1/16) - 25ºC");
                //Console.ReadLine();
                //connection.Action("1/1/16", connection.toDPT("9.001", 25.0f));
                //Thread.Sleep(200);
                //Console.WriteLine("Press [ENTER] to send command (1/1/16) - 24ºC");
                //Console.ReadLine();
                //connection.Action("1/1/16", connection.toDPT("9.001", 24.0f));
                //Thread.Sleep(200);
    
                // 1/1/16
                // 1/1/18 feedback
                // 1/1/17 temp feedback
    
                Console.WriteLine("Ende. [ENTER to EXTI]");
                Console.Read();
                System.Environment.Exit(0);
            }
    
            static void Event(string address, string state)
            {
                if (address.Equals("1/1/18") || address.Equals("1/1/17"))
                {
                    float temp = (float)connection.fromDPT("9.001", state);
                    Console.WriteLine("New Event: TEMPERATURE device " + address + " has status (" + state + ")" + temp);
                }
                if (address.Equals("5/1/2"))
                {
                    Console.WriteLine("New Event: LIGHT device " + address + " has status (" + state + ")" + state);
                }
                else
                {
                    Console.WriteLine("New Event: device " + address + " has status " + state);
                }
            }
            static void Status(string address, string state)
            {
                Console.WriteLine("New Status: device " + address + " has status " + state);
            }
            static void Connected()
            {
                Console.WriteLine("Connected!");
            }
            static void Disconnected()
            {
                Console.WriteLine("Disconnected! Reconnecting");
                if (connection != null)
                {
                    Thread.Sleep(1000);
                    connection.Connect();
                }
            }
    KNX Association zur Lizenzierung der ETS5:
    "Bitte beachten Sie: Wenn Sie Ihre Lizenz von einer älteren ETS-Version zu einer ETS5 aktualisiert haben, beachten Sie bitte, dass ein neuer Dongle wird gesendet und daher müssen Sie warten, bis der Dongle um in der Lage, Ihr Produkt zu aktivieren ankommen"

    #2
    Hallo
    Verfolgst du das weiter? Bzw. Hast du schon eine Testanwendung? Da ich selbst recht viel in c# programmiere ist die Kompatibilität mit dem knx für mich sehr interessant... Wäre schön wenn du noch ein paar Erfahrungen posten könntest. 👍😉

    Kommentar


      #3
      Hallo Hefti,

      würde mich auch über weitere Infos im Zusammenhang mit C# <> KNX interessieren.
      Danke fürs Posten des Beispielcodes.

      bye
      schlumpfuser

      Kommentar


        #4
        Also ich habe mein ganzes Projekt nun mit einer eigenen C# Lösung umgesetzt, da ich mich nicht so gut in Javascript und HTML5 auskenne.
        Kostet alles etwas Zeit, macht aber Laune und man spart sich einen Haufen Geld für teure Industrie Produkte.

        Bei mir läuft eine VISU mittels WinForms, dahinter ein Backend mittels C#/.NET, das auch die ganzen Logikbausteine übernimmt.

        Falls hier noch mehr C-Sharper sind, bin ich an einem Austausch sehr interessiert.

        Kommentar


          #5
          Zitat von mymazl Beitrag anzeigen
          Falls hier noch mehr C-Sharper sind, bin ich an einem Austausch sehr interessiert.
          Anwesend

          Interesse hätte ich auf jeden Fall. Hast du das Projekt bereits irgendwo online?
          Gruß,
          Christoph

          Kommentar


            #6
            Nein, bisher nur auf meiner Dropbox, da auch noch private Inhalte direkt im Code sind.

            Öffentlich ist ja auch lizenztechnisch ein Problem, zumindest die FalconLib benötigt man ja, um Zugang zum Bus zu erhalten.
            Und diese FalconLib unterliegt der ETS Lizenz.

            Aber ich kann mal schreiben, was ich alles habe.
            Mein ganzes Projekt ist mehr oder weniger sauber in verschiedene Schichten getrennt:
            - "BusAccess" nach Observer-Pattern: Stellt den Zugang zum Bus bereit, sowohl mit synchronen als auch asynchronen Abfragen. Services können sich für den BusAccess registrieren und dann filtern, welche Nachrichten für Sie von Interesse sind.
            - "DataAccess": Ganz simple Datenbankschicht, loggt Wetter- und Stromdaten, Auswertung existiert noch nicht automatisiert, bisher nur one-way-Logging
            - "Logik" (Hier steckt meine Hauptarbeit drin): Individuelle Szenen, Statusspeicher für Szenen und andere Logiken, Zeitschaltuhr, Sonos-Anbindung, Wetter-Online, dazu die ganzen Services, die die Befehle vom Bus interpretieren (RolloService, HeizungService, WetterstationService, MobotixService, BeleuchtungService, Schnellzugriff)

            Das ist soweit mein "Backend". Aktuell habe ich halt eine WinForms-UI dazu, die auf einem Intel NUC läuft.
            Aktuell hängt ein iPad an der Wand, dass per RDP auf den NUC geht und dort die Anwendung ausführt.
            Das UI kann aber jederzeit durch ein Web-UI abgelöst werden, verschiedene Factories ermöglichen auch, dass das Backend auf einem anderen Server läuft.

            Ich hab es also schon ziemlich sauber aufgebaut, aber veröffentlichen würde ich es so nicht

            Viele Grüße
            Marcel

            Kommentar


              #7
              Hallo, ich habe in den letzten Tagen auch einiges an Zeit in die KNX.NET investiert:

              Die erste UI war sehr einfach gehalten:
              - Datenbank mit den Räumen (Raum / Typ, also Licht oder Jalousie / Adresse im Bus)
              - Dropdown mit der Auswahl der Räume
              - Wird ein Raum gewählt, so werden die "Buttons" dynaisch nach zugehörigem DB-Inhalt aufgebaut.

              Die UI funktioniert auf allen Handys im Haus (5" Android und 6" WindowsPhone), auf dem iPad und in den "modernen" Browsern.
              home2.jpg



              Das war aber nur der erste "schnelle" Versuch.
              Nr.2 sollte hübscher werden.

              Als Erstes "Sweet Home 3D" - kostenlos und unglaublich einfach zu bedienen - Haus nachbauen.
              Zweitens, das Bild als Background inbinden und die entsprechenden Buttons + Adressen zuweisen.
              Auf den Smartphones wird immer die erste Variante angezeigt. Auf'm iPad und in den Browsern die Zweite.

              Et voila:
              home1.jpg


              Für die versierten Coder:
              - C# Webservice (.NET 4.51)
              - SQL Express 2014, oder lokales JSON-File
              - IIS auf einem Rechner im Haus (auch von Außen erreichbar)
              - UI im Bsp1 mit "Kendo UI" umgesetzt.
              - UI im Bsp2 mit einfachen Standardmitteln.
              - Klicks bilden per jQuery.ajax die Webserviceaufrufe..

              Gruß
              Rafael

              Kommentar


                #8
                Hi Rafael,

                wow sehr cool, gerade das UI macht mir als unerfahrenen UX Entwickler etwas Schwierigkeiten. Bei mir läuft wie schon gesagt noch eine WinForms-Anwendung, die ich per RDP vom iPad aufrufe.

                Ich nutze übrigens nicht KNX.NET, sondern hab die Schnittstelle über FalconLib selbst entwickelt nach schönen OOP-Design Patterns.

                Hast du asp.net verwendet?
                Wie machst du das mit den Calls zum Webservice genau (habe leider wenig Plan von jquery)?
                Wie funktionieren dabei Callbacks, also wie kriegt die UI den Status des Lichts mit, wenn jemand den Schalter betätigt?
                Wie ist dein Webservice aufgebaut? REST? SOAP?

                Kommentar


                  #9
                  Hier auch mal 3 Bilder meiner aktuellen VISU
                  You do not have permission to view this gallery.
                  This gallery has 3 photos.

                  Kommentar


                    #10
                    Hallo,

                    WinForms - RDP - iPad ist schon leicht abenteuerlich.. :-)
                    Ich habe mir bereits vor gut einem Jahr die KNX.NET Sources mal angeschaut.
                    Da hat es micht auch nicht besonders angesprochen.
                    In der Zwischenzeit ist aber sehr viel "Pragmatismus" in den Code geflossen.

                    Ich bin selber Software-Ingenieur und kann die Art und Weise wie die Source geschrieben ist sehr gut nachvollziehen.
                    Es ist sehr leicht zu debuggen und anzupassen.

                    Aus eigener Erfahrung kann ich nur bestätigen, dass zu extensive OOP einfach nur Zeit frisst.
                    Wenn ich mich so anschaue was wir (schwäbischer Automobilhersteller) an der hochgelobten
                    "Wiederverwendung durch OOP" umsetzen muss ich manchmal schmunzeln.

                    Der Webservice ist ein relativ einfacher asmx-soap-service:

                    public KNXConnection connection = null;

                    Code:
                    "WebMethod"
                    public string CallBus(string Adress, int Action, bool value) {
                      try {
                        if (connection == null) {
                            connection = new KNXLib.KNXConnectionRouting { };
                            connection.Connect();
                         }
                    
                        switch (Action) {
                           case 1:
                                // LIGHT
                                connection.Action(Adress, value);
                                break;
                    Im Grunde sind es diese kurzen Zeilen die jeglichen Aufruf, egal ob Licht, Jalousie, Rolladen, Heizung, PV, usw ausführen können.

                    Und hier noch das JavaScript dazu:

                    Code:
                    function onClick(adress, type, value) {
                          console.log(adress + " - " + type + " - " + value);
                    
                           var sendAction = "http://localhost:50178/Service1.asmx/CallBus";
                           var parameters = "{'Adress':'" + adress + "', 'Action':'" + type + "','value':'" + value + "'}";
                           var retValMsg = "";
                    
                            $.ajax({
                                type: "POST",
                                url: sendAction,
                                data: parameters,
                                async: false,
                                contentType: "application/json; charset=utf-8",
                                dataType: "json",
                                success: function (msg) {
                                retValMsg = msg.d;
                                popupNotification.show(retValMsg, "info");
                                    },
                                    error: function (e) {
                                    popupNotification.show("Ajax fail!!", "error");
                                }
                            });
                    }

                    Stell Dir vor Du hast einen Button gewählt um das Licht im WZ zu schalten:

                    Code:
                    onClick("1/1/0", 1, true);
                    "1/1/0" = ist die Adresse die Du in der ETS vergeben hast.
                    1 = ist in meinem Fall nur die Info dass es sich um ein Licht handelt.
                    true = an / false = aus


                    Jetzt kommt aber der schwierigere Teil "STATUS":
                    Dafür hast Du "hoffentlich" in Deinem Schaltaktor auch eine Adresse hinterlegt.
                    Nun, diese kannst Du auf die selber Weise rufen (ohne den value "true or false").
                    Hier bekommst Du dann einen simplen Rückgabewert (1 or 0)..

                    Dadurch dass wir hier im "stateless"-Web unterwegs sind müsstest Du die Abfrage gegen den Webserver "hämmern". (nur so bekommst Du eine "In-Time"-Anzeige).

                    Ich mache es in einem Intervall von 3s. Dabei sende ich alle Adressen (Array) an den Webservice und update die UI.
                    Das ist aber ok so, da die Stellung der Jalousien, Temperaturanzeigen, Solarwerte und Heizungskennzahlen sehr träge upgedatet werden vom Bus..

                    Gruß
                    Rafael

                    p.s. keine Zeile "ASP.NET" geschrieben.. UI ist "neumodisch" HTML5.

                    Kommentar


                      #11
                      Zitat von raphaello Beitrag anzeigen
                      WinForms - RDP - iPad ist schon leicht abenteuerlich.. :-)
                      Definitiv, aber ich bin auch ein Freund von Pragmatismus und als "Backend"-Entwickler kann ich kein UI.
                      Das einzige, was ich noch einigermaßen hinbekomme, ist eben Winforms

                      Zitat von raphaello Beitrag anzeigen
                      Ich habe mir bereits vor gut einem Jahr die KNX.NET Sources mal angeschaut.
                      Da hat es micht auch nicht besonders angesprochen.
                      In der Zwischenzeit ist aber sehr viel "Pragmatismus" in den Code geflossen.
                      Okay dann hast du auf dieser Basis weiter gemacht.
                      Ich hab einfach einen .Net-ComWrapper gebaut und rufe die Methoden direkt mittels FalconLib.
                      Ist ja nichts anderes...

                      Zitat von raphaello Beitrag anzeigen
                      Aus eigener Erfahrung kann ich nur bestätigen, dass zu extensive OOP einfach nur Zeit frisst.
                      Wenn ich mich so anschaue was wir (schwäbischer Automobilhersteller) an der hochgelobten
                      "Wiederverwendung durch OOP" umsetzen muss ich manchmal schmunzeln.
                      Mag sein, aber ich hatte ursprünglich die Idee meine Sourcen auf GitHub bereitzustellen.
                      Da hatte ich für mich den Anspruch es etwas sauberer zu schreiben.

                      Zitat von raphaello Beitrag anzeigen
                      Der Webservice ist ein relativ einfacher asmx-soap-service:
                      Okay, das ist simpel.

                      Zitat von raphaello Beitrag anzeigen
                      Und hier noch das JavaScript dazu:

                      Code:
                      function onClick(adress, type, value) {
                      console.log(adress + " - " + type + " - " + value);
                      
                      var sendAction = "http://localhost:50178/Service1.asmx/CallBus";
                      var parameters = "{'Adress':'" + adress + "', 'Action':'" + type + "','value':'" + value + "'}";
                      var retValMsg = "";
                      
                      $.ajax({
                      type: "POST",
                      url: sendAction,
                      data: parameters,
                      async: false,
                      contentType: "application/json; charset=utf-8",
                      dataType: "json",
                      success: function (msg) {
                      retValMsg = msg.d;
                      popupNotification.show(retValMsg, "info");
                      },
                      error: function (e) {
                      popupNotification.show("Ajax fail!!", "error");
                      }
                      });
                      }

                      Stell Dir vor Du hast einen Button gewählt um das Licht im WZ zu schalten:

                      Code:
                      onClick("1/1/0", 1, true);
                      "1/1/0" = ist die Adresse die Du in der ETS vergeben hast.
                      1 = ist in meinem Fall nur die Info dass es sich um ein Licht handelt.
                      true = an / false = aus
                      Okay, das mit den Adressen ist klar, hier ist mein Problem auch eher wieder das JS und AJAX.
                      Aber deinen Ausschnitt verstehe ich


                      Zitat von raphaello Beitrag anzeigen
                      Jetzt kommt aber der schwierigere Teil "STATUS":
                      Dafür hast Du "hoffentlich" in Deinem Schaltaktor auch eine Adresse hinterlegt.
                      Nun, diese kannst Du auf die selber Weise rufen (ohne den value "true or false").
                      Hier bekommst Du dann einen simplen Rückgabewert (1 or 0)..

                      Dadurch dass wir hier im "stateless"-Web unterwegs sind müsstest Du die Abfrage gegen den Webserver "hämmern". (nur so bekommst Du eine "In-Time"-Anzeige).

                      Ich mache es in einem Intervall von 3s. Dabei sende ich alle Adressen (Array) an den Webservice und update die UI.
                      Das ist aber ok so, da die Stellung der Jalousien, Temperaturanzeigen, Solarwerte und Heizungskennzahlen sehr träge upgedatet werden vom Bus..
                      Okay, das finde ich etwas unschön. Da hab ich in meinem UI durch die Callbacks mittels INotifyPropertyChanged die schönere Lösung. "Pinging" ist ziemlich hässlich, aber in unserem Szenario (Privat, Einzel-Lösung) durchaus pragmatisch und praktikabel.

                      Online hatte ich aber auch schon mal eine AJAX Lösung mit asynchronen Callbacks gelesen. Müsste also auch irgendwie möglich sein!

                      Vielen Dank für deine ausführliche Beschreibung! Vielleicht wage ich mich nochmal ran an das Thema WebUi

                      Viele Grüße
                      Marcel

                      Kommentar


                        #12
                        Stichwort Anzeige in Echtzeit: Ich mache das über ASP.NET SignalR. D.h. (Rück-) Meldungen vom Bus werden in "Echtzeit" in der UI dargestellt. Das funktioniert sowohl für Web- als auch für WinForm-Apps.

                        Grüße,
                        Stefan

                        Kommentar


                          #13
                          Hui! Klasse was hier passiert ist. War und bin leider etwas länger raus aus dem Thema da ich immer noch mitten im Hausbau stecke und fertig werden muss.

                          Habe aber in der Zwischenzeit ab und an mit dem Testboard nochmal rumgespielt.

                          Mein Ziel wird sein:
                          • Raspberry PI mit Raspbian und Mono --> .NET unter Linux auf sparsamen PC (prinzipiell geht jeder PC mit Mono/.NET ...)
                          • Access-Layer auf KNX in C# als Klassendiagramm mittels Attributen auf Properties:
                          z.B.
                          Code:
                          public class Kueche
                          {
                              [KNXAddress("1/2/3")]
                              public bool Lampe1 { get;set;}
                          
                              [KNXAddress("1/2/4")]
                              [Description("Schaltet die Lampe über dem Herd ein/aus")]
                              public bool Lampe2 { get;set;}
                          
                          ....
                          
                          }
                          • ASP.NET WebApi Zugriff auf KNX Access-Layer mittels REST/JSON.
                          • SignalR Zugriff für Status-Updates.
                          • FrontEnd App als HTML5 AngularJS/Bootstrap UI. Das UI wird komplett über die Attribute im Access-Layer aufgebaut.
                          Das FrontEnd kann so auch auf einen anderen System gehostet werden, oder es können viele verschiedene individuelle FrontEnds erstellt werden.
                          Ich denke da zur Zeit an einen Magic-Mirror, etc.

                          Wichtig ist mir, das die gesamte Konfiguration des KNX-Systems im C# Code passiert. CodeFirst. Ich möchte nur eine zentrale Stelle haben, die ich warten muss und was im Code steht ist Gesetz. Dabei soll mein gesamtes Anwesen als C# Klassenstruktur repräsentiert werden.

                          Leider fehlt mir noch mein fertiges Haus in dem ich wohne um endlich mit KNX auch rumspielen zu können.
                          Zuletzt geändert von Hefti; 11.06.2015, 16:46.
                          KNX Association zur Lizenzierung der ETS5:
                          "Bitte beachten Sie: Wenn Sie Ihre Lizenz von einer älteren ETS-Version zu einer ETS5 aktualisiert haben, beachten Sie bitte, dass ein neuer Dongle wird gesendet und daher müssen Sie warten, bis der Dongle um in der Lage, Ihr Produkt zu aktivieren ankommen"

                          Kommentar


                            #14
                            Besitze ein Raspberry Pi mit smarthome.py und ein Enertex Interface.
                            Versuche nun eine Verbindung mit dem Interface aufzubauen, jedoch erfolglos mit
                            dem Knx-net-lib....

                            Mit ETS kann ich aber den Bus über das Interface überwachen...

                            Mein Code:
                            Code:
                             string ipHost = textBoxIp.Text.ToString();
                                        int portHost = Convert.ToInt32(textBoxPort.Text);
                            
                            
                                        var connection = new KnxConnectionRouting(ipHost);
                            
                                        connection.ActionMessageCode = 0x29;
                                        
                                        try
                                        {
                                            connection.Connect();
                                            //connection.KnxEventDelegate += Event;
                                            //connection.RequestStatus(address);
                                            if (!onOff)
                                            {
                                                onOff = true;
                                                connection.Action(address, true);
                                            }
                                            else
                                            {
                                                onOff = false;
                                                connection.Action(address, false);
                                            }
                                          
                                            connection.Disconnect();
                                        }
                                        catch(Exception ex)
                                        {
                                            MessageBox.Show(ex.Message + Environment.NewLine+ex.InnerException);
                                            
                                        }
                            Alternativ habe ich auch schon probiert:

                            Code:
                            var connection = new KnxConnectionRouting();
                            You do not have permission to view this gallery.
                            This gallery has 1 photos.
                            Zuletzt geändert von schorge; 30.05.2016, 20:18.
                            RaspberryPi B+ und Pi2, Enertex KNXnet/IP Interface u TULIP, XS1-FS20, QNap TS-212, OpenELEC, Asterisk TK

                            Kommentar


                              #15
                              Erlaubt deinen Firewall den Zugriff auf den Port?

                              Kommentar

                              Lädt...
                              X