Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Entwicklung
    4. Neuer Adapter für UniPi Board - Websocket

    NEWS

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    Neuer Adapter für UniPi Board - Websocket

    This topic has been deleted. Only users with topic management privileges can see it.
    • apollon77
      apollon77 last edited by

      Ich habs mal ins Trello gepackt als Idea/Request …

      1 Reply Last reply Reply Quote 0
      • apollon77
        apollon77 last edited by

        Bzw zum lesen kannst DU mal den "parser"-Adapter versuchen … das sollte gehen. Schreiben kann der aber (noch) nicht

        1 Reply Last reply Reply Quote 0
        • T
          TOBO last edited by

          Sorry, aber ich verstehe kein Wort.

          1 Reply Last reply Reply Quote 0
          • Y
            ykuendig last edited by

            Es gibt einen Adapter mit Namen "parser". Der kann URLs aufrufen und die Antwort auswerten. Damit könntest Du die wget's nachbilden und die Relais-Stati visualisieren.

            Schreiben kann der Adapter aber noch nicht - sprich: um die Relais umzusteuern müsste man mit JavaScript ran.

            Obwohl geplant ist den Adapter in dieser Hinsicht zu erweitern, kann das noch etwas dauern.

            1 Reply Last reply Reply Quote 0
            • T
              TOBO last edited by

              Das hört sich doch sehr kompliziert an und ist ja auch noch keine Lösung.

              Es hat wohl keiner ein richtiges Interesse daran so einen Adapter zu schreiben.

              Liegt es daran das es doch sehr viel komplizierter ist als ich mir vorstelle, oder das Board nicht interessant ist ?

              1 Reply Last reply Reply Quote 0
              • Y
                ykuendig last edited by

                Tja, die Wahrheit ist manchmal nicht schwarz oder weiss.

                Ich kann nicht - Mangelhafte Programmierkenntnisse.

                Du kannst auch nicht - Kenntnisse.

                Apollon hat genug Arbeit damit die bestehenden Adapter von Fehlern zu bereinigen.

                Sonst ist zur Zeit keiner da im Gespräch.

                Das Board ist wahrscheinlich nicht schlecht (obwohl, das müsstest Du besser wissen als ich). Scheinbar noch nicht so verbreitet.

                Zudem hört sich das steuern über JavaScript komplizierter an als Du befürchtest. Wenn Du das probieren willst, bin ich sicher das wir da Leute finden die beim Scripten helfen. Aber ein Script in ein Adapter zu wandeln, das ist doch noch ein Unterschied.

                Wer weiss schon, plötzlich tut sich was.

                1 Reply Last reply Reply Quote 0
                • Vumer
                  Vumer last edited by

                  @TOBO:

                  Es gibt dafür eine Websocket API namens EVOK.

                  https://github.com/UniPiTechnology/evok

                  Nun, ich bin leider ein absoluter Laie was Java angeht und sehe keinerlei Möglichkeit für das Board selbst einen Adapter für IOBroker zu erstellen. `
                  hab versucht dem https://github.com/mwittig/pimatic-unipi-evok zu installieren, Ergebnis natürlich mit error :roll:

                  1 Reply Last reply Reply Quote 0
                  • T
                    TOBO last edited by

                    Wenn Du es zum laufen bekommst, bitte melden.

                    1 Reply Last reply Reply Quote 0
                    • Vumer
                      Vumer last edited by

                      Wenn ich wüsste wie :shock:

                      1 Reply Last reply Reply Quote 0
                      • apollon77
                        apollon77 last edited by

                        An alle Interessierten: Adapter-Request ist jetzt auf Github unter https://github.com/ioBroker/AdapterRequests/issues/29 zu finden. Bitte dort wie unter https://github.com/ioBroker/AdapterRequ … o-use-this beschrieben voten!

                        Apollon77 created this issue in ioBroker/AdapterRequests

                        open UniPi #29

                        1 Reply Last reply Reply Quote 0
                        • J
                          JR-Home @TOBO last edited by JR-Home

                          @TOBO Das Unipi 1.1 Board finde ich wirklich klasse. Schade dass es dafür noch keinen fertigen Adapter gibt. Preis Leistungs/Verhältnis einfach unschlagbar.
                          Da ich noch nicht weiß wie man einen Adapter schreibt, habe ich dennoch ein Java Script erstellt, mit dem man über das EVOK Interface die Relais und Eingänge wie gewohnt ansprechen kann. Für jeden Ein/Ausgang wird dabei ein Objekt angelegt. Wer kann daraus einen Adapter basteln?

                          console.log("Starte UniPi 1.1 EVOK Interface V1.0."); 
                          
                          const csUnipi = "http://localhost:9599/rest/";
                          const csUnipiObjectPath ="javascript.0.UniPi."
                          var aOneWireIDs = {};
                          
                          // Liste der erwarteten OneWire IDs mit dem dazugehörenden IOBroker Objekt. Diese können über
                          // das Unipi Control Panal mit http://Raspi-IP:UnipiEvokPort ermittelt werden.
                          // Diese Tabelle stellt sicher, dass unter der ID immer derselbe Sensor gefunden wird, und sich
                          // die Reihenfolge und Zugriff auf einen spezifischen Sensor auch bei Ausfall eines anderen Sensors 
                          // nicht ändert!
                          aOneWireIDs["28FF6419D5853EB0"] = csUnipiObjectPath + "Input.OneWire1.";
                          aOneWireIDs["xyz"] = csUnipiObjectPath + "Input.OneWire2.";
                          
                          // Das Objekt das den Relais Status representiert anlegen
                          // true wenn bereits vorhanden überschreiben, false nur falls nicht vorhanden anlegen
                          createState( csUnipiObjectPath + "Status", 0, false, {name: 'Unipi Status', type: 'string', unit: 'Info'});
                          var i;
                          for (i = 1; i <= 8; i++) {
                              createState( csUnipiObjectPath + "Relay.R" + i, 0, false, {name: 'Unipi Rel ' + i, type: 'number', min: 0, max: 1, unit: ''});
                          }
                          for (i = 1; i <= 12; i++) {
                              createState( csUnipiObjectPath + "Input.I" + String( i ).padStart(2, '0'), 0, false, {name: 'Unipi Inp ' + i, type: 'number', min: 0, max: 1, unit: ''});
                          }
                          
                          createState( csUnipiObjectPath + "Input.AI1", 0, false, {name: 'Unipi AInp 1', unit: ''});
                          createState( csUnipiObjectPath + "Input.AI2", 0, false, {name: 'Unipi AInp 2', unit: ''});
                          
                          function AddOneWireObject( sOneWireAddress, sIOBrokerObjectPath )
                          {
                          //    console.log( `Adding OneWire Object: ${sIOBrokerObjectPath} Device ID: ${sOneWireAddress}` );
                              createState( sIOBrokerObjectPath + "value", 0, false, {name: 'Unipi One Wire value', unit: '°C'});
                              createState( sIOBrokerObjectPath + "typ", "not connected", false, {name: 'Unipi One Wire sensor type', unit: ''});
                              createState( sIOBrokerObjectPath + "address", sOneWireAddress, false, {name: 'Unipi One Wire adress', unit: ''});
                          };
                          
                          // Und die Datenpunkte für die OneWire Sensoren anlegen
                          for (var key in aOneWireIDs ) {
                              // OneWireIDs.forEach( function(key, value) {
                              AddOneWireObject( key, aOneWireIDs[key] );
                          };
                          
                          var request = require( "request" );
                          
                          function ReadUnipiInputs()
                          {
                              // Status aller Komponenten auslesen
                              request( csUnipi + "all", function (error, response, body) {
                                  if( error != null )
                                  {
                                      console.error( "Error accessing Unipi Evok: " + error );
                                      setState( csUnipiObjectPath + "Status", "Last Error: " + error, true ); 
                                  }
                                  else
                                  {
                                      setState( csUnipiObjectPath + "Status", "Available", true ); 
                                      var json = JSON.parse(body);
                                      // console.log ( "JSON: " + JSON.stringify(json) );
                                      json.forEach( oUnipi => {
                                          if( oUnipi.dev == "input" ) // && obj.circuit == "4")
                                          {
                                              // ACK=True, da Wert von "Hardware" geändert
                                              // String( oUnipi.circuit ).padStart(2, '0') liefert die Input Nummer mit einer führenden Null
                                              setState( csUnipiObjectPath + "Input.I" + String( oUnipi.circuit ).padStart(2, '0'), oUnipi.value, true ); 
                                              // console.log( "Input " + obj.circuit + ":" + obj.value )
                                              // Object.entries(obj).forEach(([key, value]) => {
                                              // console.log(`${key} ${value}`);
                                              // });
                                          }
                                          if( oUnipi.dev == "ai" )
                                          {
                                              // Tatsächlicher Wert der Hardware gelesen, daher ACK=TRUE
                                              setState( csUnipiObjectPath + "Input.AI" + oUnipi.circuit, oUnipi.value, true ); 
                                              //console.log( "Analog Input " + obj.circuit + ":" + obj.value )
                                          }
                                          // Falls sich der Zustand der Relais geändert hat (z. B. andere Zugriffe direkt auf EVOK) 
                                          // dann diesen auch übernehmen
                                          // Auch falls Ack noch nicht gesetzt sein sollte, "Wertübernahme durch HW" bestätigen
                                          if( oUnipi.dev == "relay")
                                          {
                                              var oRel = getState( csUnipiObjectPath + "Relay.R" + oUnipi.circuit );
                                              // Den Wert übernehmen wir aber nur mit Verzögerung, um zu verhindern, dass wir der asynchronen 
                                              // Bearbeitung der "On" Event Funktion dazwischenfunken.
                                              if( ( Number( oRel.val ) != oUnipi.value || oRel.ack != true ) && Date.now() - oRel.lc > 2000 )
                                              {
                                                  // console.log( "TimeDiff: " + ( Date.now() - oRel.lc ) );
                                                  // Tatsächlicher Wert der Hardware gelesen, daher ACK=TRUE
                                                  setState( csUnipiObjectPath + "Relay.R" + oUnipi.circuit, oUnipi.value, true );
                                              }
                                          }
                                          // Typ ist gesetzt bei den 1 Wire devices
                                          if( oUnipi.typ > "" )
                                          {
                                              // Die I/O Broker Objekt ID ermitteln
                                              var sOneWireObject = aOneWireIDs[ oUnipi.address ];
                                              if( sOneWireObject > "" )
                                              {
                                                  setState( sOneWireObject + "value", oUnipi.value, true );
                                                  if( getState( sOneWireObject + "typ" ).val != oUnipi.typ )
                                                  {
                                                      setState( sOneWireObject + "typ", oUnipi.typ, true );
                                                  }
                                                  // Wird schon beim anlegen des Objektes gesetzt...
                                                  // setState( OneWireObject + "address", oUnipi.address, true );
                                              }
                                              else
                                              {
                                                  var iLength = Object.keys( aOneWireIDs ).length + 1;    // aOneWire.length funktioniert bei einem assoziativen Array nicht....
                                                  console.error( "Error unknown One Wire device found. Please add new Datapoint: " + oUnipi.address + ". Temporary added as ID: " + iLength );
                                                  aOneWireIDs[oUnipi.address] = csUnipiObjectPath + "Input.OneWire_temp" + iLength + ".";
                                                  AddOneWireObject( oUnipi.address, aOneWireIDs[oUnipi.address] );
                                              }    
                                          }
                                      }); 
                                  }
                              });
                          }
                          
                          schedule("*/1 * * * * *", function () { // Abfrage alle 1 Sec
                              ReadUnipiInputs(); 
                          });
                          
                          function WriteOutput( obj )
                          {
                              var RelNum = obj.id.substring(obj.id.length - 1);
                          //    console.log( "Rel " + RelNum + " ObjID: " + obj.id + " Val: " + Number( obj.state.val ) + " Ack: " + obj.state.ack );
                              // Nur falls der Wert nicht bereits von der Hardware bestätigt wurde übernehmen.
                              if( obj.state.ack == false )
                              {
                                  // Mit Number() wird das Objekt auch bei true/false in eine Zahl umgewandelt.
                                  request.post( csUnipi + "relay/" + RelNum, {form:{ value:Number( obj.state.val ) }}, function (error, response, body){
                                      if( error == null )
                                      {
                                          // Schreiben auf die HW war erfolgreich, damit mit Ack=true bestätigen.
                                          setState( obj.id, Number( obj.state.val ), true );
                                      }
                                      else
                                      {
                                          console.error( "Error accessing Unipi Evok: " + error );
                                      }
                                  });
                              }
                          }
                          
                          // Damit nicht der On-Event für jedes Relais einzeln gesetzt werden muss 8x mit
                          // on({id: csUnipiObjectPath + "Relay.R1", change: 'ne'}, function (obj) {
                          // eine RegExpr. anlegen. Zu beachten: im String den \\ verdoppeln!
                          // \d beliebige Zahl
                          var RelObjectPath = csUnipiObjectPath + "Relay.R\\d";
                          on({id: new RegExp( RelObjectPath.replace(".", "\\.") ), change: 'ne'}, function (obj) {
                              WriteOutput( obj );
                          });
                          

                          MOD-Edit: Code in code-tags gesetzt!

                          P 1 Reply Last reply Reply Quote 0
                          • P
                            PEPITO82 @JR-Home last edited by

                            @jr-home Ich finde es auch sehr schade, dass es keinen Adapter für das Unipi Board bzw. die Neurons gibt.

                            In FHEM gibt es z.B. das Modul hier: https://forum.fhem.de/index.php?topic=84746.0
                            Ist offiziell zwar für die Neurons, aber klappt auch mit dem Unipi 1.1 Board.

                            Bei der Adapter Entwicklung könnte ich ggf. mit Hardware unterstützen, da ich zu Hause ein zweites Board rumliegen habe.

                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post

                            Support us

                            ioBroker
                            Community Adapters
                            Donate

                            797
                            Online

                            31.7k
                            Users

                            79.8k
                            Topics

                            1.3m
                            Posts

                            6
                            13
                            3318
                            Loading More Posts
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes
                            Reply
                            • Reply as topic
                            Log in to reply
                            Community
                            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                            The ioBroker Community 2014-2023
                            logo