Ankündigung

Einklappen
Keine Ankündigung bisher.

KNX Einbindung einer Wolf Heizung. ISM8i, ISM9i oder doch ISM7?

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

    KNX Einbindung einer Wolf Heizung. ISM8i, ISM9i oder doch ISM7?

    Hallo Forum.

    Ich rätsel seit einiger Weile wie ich meine Wolf Gasheizung und CWL in mein KNX System integrieren möchte.

    Die einfachste aber weniger komplette integration wäre die Ansteuerung der CWL über noch freie 10V bzw. potenzialfreie Schalter und einem KNX Aktor.

    Eine wesentlich schönere Integration ist sicherlich die Nutzung der proprietären Wolf Steuerung via extra Modul. Leider habe ich bis auf die Marketingseiten und PDF´s wenig spezifische technische Informationen zu den verfügbaren Wolf Modulen gefunden.

    Da gibt es ISM7i, ISM8i und ISM9i. In den üblichen ECommerce Seiten manchmal mit und manchmal ohne Bundle.

    ISM9 scheint ausschließlich für WiButler zu sein, incl. WLAN Fähigkeit.

    ISM8 ist wie das ISM9 nur ohne WLAN?

    Was macht dann das ISM7?

    Hat da jmd von Euch Erfahrungen oder Informationen?

    Gruß Weale
    Zuletzt geändert von MatthiasS; 02.07.2018, 15:39.

    #2
    Hi!
    Auf den Wolf-Webseiten steht eigentlich alles:
    http://www.wolf-heiztechnik.de/produ...-knx-netzwerk/

    Du benötigst für eine Anbindung auf jeden Fall ein ISM8.

    Das ISM8 wird quasi in zwei Varianten angeboten: ISM8i und ISM8e

    ISM8i ist nur die reine Platine und stellt die Verbindung zwischen dem Wolf E-Bus und Ethernet her.
    Diese ISM8i-Platine ist als Einsteckmodul für eine Wolf-Heizung gedacht.
    https://www.wolf-heiztechnik.de/file...sanleitung.pdf

    Das ISM8e ist nichts anderes als ein externes Gehäuse, in dem auch ein ISM8i verbaut ist und zusätzlich noch eine kleine Platine mit einem DC/DC-Wandler verbaut ist, um mit dem 5V-USB Netzteil auf die geforderter Spannung von 23VDC zu kommen.

    Um nun die Anbindung an den KNX-Bus zu bekommen, ist noch das KNX BAOS-Modul notwendig. Das hat zum einen eine Ethernet-Schnittstelle und zum anderen die KNX-Bus Klemme. Das ISM8i bzw. ISM8e kommuniziert dann per Ethernet direkt mit dem BAOS Modul.

    Das ISM8i kann man alleine ohne BAOS Modul für ca. 130EUR (inkl. MwSt) kaufen.
    Das gibt es aber auch als Set (ISM8i+BAOS) für ca. 380EUR (inkl. MwSt).

    Das ISM8e kann man nicht alleine kaufen. Das gibt es nur als Set mit dem KNX BAOS-Modul und kostet um die 600EUR (inkl. MwSt).
    https://www.wolf-heiztechnik.de/file...sanleitung.pdf
    Im PDF ist zwar eine Artikelnummer nur für das externe ISM8e Gehäuse angegeben, meine Nachfrage bei Wolf ergab aber, dass es das ISM8e nichts einzeln ohne BAOS-Modul zu erwerben gibt.

    Im PDF des ISM8i siehst die unterstützten Datenpunkte der ISM8-Module für Heizung und CWL.
    Im PDF des ISM8e siehst Du nur die Datenpunkte für die CWL. Liegt wohl daran, dass das ISM8e hautpsächlich für Leute gedacht ist, die nur eine Wolf-CWL zu Hause haben (so wie ich).

    Wichtig ist noch, dass Du immer mind. ein Wolf-BM2 Modul am E-Bus hängen haben musst, sonst funktionieren die ISM8-Gateways nicht.
    http://www.wolf-heiztechnik.de/filea...handwerker.pdf

    Das BAOS-Modul wurde von Wolf dazugekauft. Und zwar von Weinzierl:
    http://www.weinzierl.de/index.php/de...nx-ip-baos-771
    Als ein ganz normales Objektserver-Modul für den KNX.

    Da ich ja nur die CWL 300 Excellent alleine zuhause habe, waren mir 600EUR einfach viel zu teuer. Vor allem, wenn man sich im PDF anschaut, welche Datenpunkte nur unterstützt werden. Du kannst nur das per KNX verstellen, was man als normaler Benutzer am BM2 auch bedienen kann.
    Ätzend ist, dass man die Lüftungsstufen 1-3 nicht direkt ansteuern kann. Für 1 und 3 muss man Zeiten angeben, da es ja zweitweiser Feuchteschutz bzw. zeitweise Intensivlüftung ist.
    Man sieht hauptsächlich Status-Daten wie Vorheizregister aktiv oder nicht, Luftmenge, Temperaturen.
    Zu steuern gibt es bei einer Lüftung ja eigentlich nur die Luftmenge. Die Messwerte sind zwar nett, aber eher Kosmetik.

    Falls es Dich interessiert: ich habe in PHP ein kleines Skript geschrieben, welches das KNX BAOS-Modul emuliert.
    Das ISM8i verbindet sich per TCP mit dem Skript und man die Daten alle angezeigt bekommen.
    Das Skript spricht quasi das Objektserver-Protokoll wie es oben in den PDFs beschrieben ist.
    Man kann die Datenpunkte für die Heizung auch noch einbauen.

    Ich habe übrigens nur das ISM8i gekauft und dann an ein 24VDC Steckernetztel angeschlossen. Dann einfach die beiden E-Bus (+/-) Strippen an das Modul und per Ethernet angeschlossen. Fertig. Hat mich deutlich weniger gekostet.




    Kommentar


      #3
      Hallo zusammen,

      ich habe auch eine CLW300 Excellent verbaut...und würde diese gerne über meine knx Taster/Visu steuern (Scene party oder Intensiv lüften....)

      verstehe ich das richtig, das es sich nicht wirklich lohnt das ISM8 für mehr als 600 Euro zukaufen...

      wie sieht den die andere Lösung aus mit 0-10V aktor ?

      Danke und GRuß
      ALex

      Kommentar


        #4
        Nanosonde Hallo! Danke für deine aufschlussreiche Antwort und entschuldige mein spätes Rückantworten.


        Hmm, also die Lüftungswerte kann man steuern aber nicht direkt? Ist ja merkwürdig, denn man kann ja durch die Binäreingange nen manuellen Schalter nehmen und Modus 3 bzw. 1 ja auch "erzwingen"

        Zudem.. der Tipp mit dem ISM8i alleine ist super! Auf der Anderen Seite ist das BAOS natürlich sehr nett, kann man ja auch als Programmierschnittstelle nutzen und kommt mit SDK...

        Da meine alte Siemens Schnittstelle eh mückert und dessen wirklich rudimentäre WebSchnittstelle sich gern mal aufhängt sind 380 für alles ja noch OK.

        Aber dennoch. Kannst Du dein Script ggf auf GitHub oder so zur Verfügung stellen?

        Gruß Marc

        Kommentar


          #5
          Zitat von weale Beitrag anzeigen
          Nanosonde
          Hmm, also die Lüftungswerte kann man steuern aber nicht direkt? Ist ja merkwürdig, denn man kann ja durch die Binäreingange nen manuellen Schalter nehmen und Modus 3 bzw. 1 ja auch "erzwingen"
          Ja, geht leider nicht anders. Man kann nur die Dinge per ISM8x steuern/sehen, die man als Mensch auch über das BM2 bedienen/sehen kann.

          Zitat von weale Beitrag anzeigen
          Aber dennoch. Kannst Du dein Script ggf auf GitHub oder so zur Verfügung stellen?
          Mit diesem Skript kann Du erstmal nur alles lesen.
          Das Steuern des ISM8x ist noch nicht eingebaut. Als die Datenpunkte, die im Array neben OUT auch IN sind, können aktuell noch nicht gesetzt werden.
          Da kommt aber noch was irgendwann von mir. Ich kann nur nch nicht sagen, wann.

          PHP-Code:
          #!/usr/bin/php -q
          <?php

          /*
          define ("LOG_DEBUG",  4);
          define ("LOG_INFO",   3);
          define ("LOG_WARNING",   2);
          define ("LOG_ERR",  1);
          */
          define ("LOG_SILENT"0);

          $g_loglevel LOG_INFO;

          $dparray = array(
                   
          "53"  => array("Störung(BM2)",                        "DPT_Switch"       "Out"   ),
                   
          "55"  => array("Raumtemperatur(BM2)",                 "DPT_Value_Temp"   "Out"   ),
                   
          "148" => array("Störung",                             "DPT_Switch"       "Out"   ),
                   
          "149" => array("Programm",                            "DPT_DHWMode"      "Out/In"),
                   
          "150" => array("Zeitprogramm1",                       "DPT_Switch"       "Out/In"),
                   
          "151" => array("Zeitprogramm2",                       "DPT_Switch"       "Out/In"),
                   
          "152" => array("Zeitprogramm3",                       "DPT_Switch"       "Out/In"),
                   
          "153" => array("Zeitw.Intensivlüftung_AN/AUS",        "DPT_Switch"       "Out/In"),
                   
          "154" => array("Zeitw.Intensivlüftung_Startdatum",    "DPT_Date"         "Out/In"),
                   
          "155" => array("Zeitw.Intensivlüftung_Enddatum",      "DPT_Date"         "Out/In"),
                   
          "156" => array("Zeitw.Intensivlüftung_Startzeit",     "DPT_TimeOfDay"    "Out/In"),
                   
          "157" => array("Zeitw.Intensivlüftung_Endzeit",       "DPT_TimeOfDay"    "Out/In"),
                   
          "158" => array("Zeitw.Feuchteschutz_AN/AUS",          "DPT_Switch"       "Out/In"),
                   
          "159" => array("Zeitw.Feuchteschutz_Startdatum",      "DPT_Date"         "Out/In"),
                   
          "160" => array("Zeitw.Feuchteschutz_Enddatum",        "DPT_Date"         "Out/In"),
                   
          "161" => array("Zeitw.Feuchteschutz_Startzeit",       "DPT_TimeOfDay"    "Out/In"),
                   
          "162" => array("Zeitw.Feuchteschutz_Endzeit",         "DPT_TimeOfDay"    "Out/In"),
                   
          "163" => array("Lüftungsstufe",                       "DPT_Scaling"      "Out"),
                   
          "164" => array("Ablufttemperatur",                    "DPT_Value_Temp"   "Out"),
                   
          "165" => array("Frischlufttemperatur",                "DPT_Value_Temp"   "Out"),
                   
          "166" => array("Luftdurchsatz Zuluft",                "DPT_FlowRate"     "Out"),
                   
          "167" => array("Luftdurchsatz Abluft",                "DPT_FlowRate"     "Out"),
                   
          "168" => array("Bypass Initialisierung",              "DPT_Bool"         "Out"),
                   
          "169" => array("Bypass öffnet/offen",                 "DPT_Bool"         "Out"),
                   
          "170" => array("Bypass schließt/geschlossen",         "DPT_Bool"         "Out"),
                   
          "171" => array("Bypass Fehler",                       "DPT_Bool"         "Out"),
                   
          "172" => array("Frost Status: Initialisierung/Warte""DPT_Bool"         "Out"),
                   
          "173" => array("Frost Status: Kein Frost",            "DPT_Bool"         "Out"),
                   
          "174" => array("Frost Status: Vorwärmer",             "DPT_Bool"         "Out"),
                   
          "175" => array("Frost Status: Fehler/Unausgeglichen""DPT_Bool"         "Out"),
          );

          function 
          dbgprint()
          {
              global 
          $g_loglevel;

              
          $argv func_get_args();
              
          $loglevel array_shift$argv );

              if (
          $loglevel <= $g_loglevel)
              {
                  
          $format array_shift$argv );

                  switch(
          $loglevel)
                  {
                      case 
          LOG_DEBUG:   printf'DEBUG: ' );
                                        break;
                      case 
          LOG_INFO:    printf'INFO: ' );
                                        break;
                      case 
          LOG_WARNINGprintf'WARNING: ' );
                                        break;
                      case 
          LOG_ERR:     printf'ERROR: ' );
                                        break;
                      default:          
          printf'---: ' );
                  }
                  
          vprintf$format$argv );
                  
          printf"\n" );
              }
          }

          function 
          conv_DPT_Bool($val)
          {
              return 
          $val[0] == '0' "False":"True";
          }

          function 
          conv_DPT_Switch($val)
          {
              return 
          $val[0] == '0' "Off":"On";
          }

          function 
          conv_DPT_DHWMode($val)
          {
              switch (
          $val[0])
              {
                  case 
          0: return "Auto";
                  case 
          1: return "LegioProtect";
                  case 
          2: return "Normal";
                  case 
          3: return "Reduced";
                  case 
          4: return "Off/FrostProtect";
                  default: return 
          "Unknown";
              }
          }

          function 
          conv_DPT_Scaling($val)
          {
              return ((string)
          round($val[0] * 100/255))."%";
          }

          function 
          conv_DPT_FlowRate($val)
          {
              
          $value = ($val[0]<<24)|($val[1]<<16)|($val[2]<<8)|($val[3]<<0);
              
          $flowrate $value 0.0001;
              return ((string)
          $flowrate)."m3/h";
          }

          function 
          conv_DPT_Value_Temp($val)
          {
              if ((
          $val[0] == 0x7F) && ($val[1] == 0xFF))
              {
                  
          $float "<invalid>";
              }
              else
              {
                  
          $mantissa intval(($val[1] & 0xFF) | (($val[0] &0x87)<<8));
                  
          $exponent intval(($val[0] & 0x78)>>3);
                  
          $float 0.01 $mantissa pow(2$exponent);
              }
              return ((string)
          $float)."°C";
          }

          function 
          conv_DPT_TimeOfDay($val)
          {

              
          $daynames = array(
              
          '(no_day_provided)',
              
          'Monday',
              
          'Tuesday',
              
          'Wednesday',
              
          'Thursday',
              
          'Friday',
              
          'Saturday',
              
          'Sunday'
              
          );

              
          $day = ($val[0] & 0xE0) >> 5;
              
          $hour $val[0] & 0x1F;
              
          $minutes $val[1] & 0x3F;
              
          $seconds $val[2] & 0x3F;

              
          $hour sprintf("%02d"$hour);
              
          $minutes sprintf("%02d"$minutes);
              
          $seconds sprintf("%02d"$seconds);

              if (
          $day == 0)
                  return ((string)
          $hour).":".((string)$minutes).":".((string)$seconds);
              else
                  return 
          $daynames[$day].",".((string)$hour).":".((string)$minutes).":".((string)$seconds);
          }

          function 
          conv_DPT_Date($val)
          {
              
          $year $val[2] & 0x7F;
              
          $month $val[1] & 0x0F;
              
          $day $val[0] & 0x1F;

              
          $year sprintf("%02d%02d"substr(date("Y"), 02), $year);
              
          $month sprintf("%02d"$month);
              
          $day sprintf("%02d"$day);

              return ((string)
          $day).".".((string)$month).".".((string)$year);
          }


          function 
          request_all_datapoints($msgsock)
          {
              
          /* Send special message to request all datapoints to be sent. */
              
          $msg = array(0x060x200xF00x800x000x0C0x040x000x000x000xF00xD0);
              
          $str implode(array_map("chr"$msg));
              
          socket_write($msgsock$str strlen($str));
          }

          function 
          send_datapointvalue_indication($msgsock$dp$rawvalue)
          {
              
          $msg = array(0x060x200xF00x800x000x140x040x000x000x000xF00xC10x000x000x000x010x000x000x000x00);
              
          $msg[12] = ($dp &0xFF00) >> 8// Start DP MSB
              
          $msg[13] = $dp 0xFF;         // Start DP LSB
              
          $msg[16] = $msg[12];           // First DP ID MSB
              
          $msg[17] = $msg[13];           // First DP ID LSB
              
          $msg[19] = count(rawvalue);    // DP value length
              
          $msg[5] += $msg[19];           // add value length to frame size
              
          array_push($msg$rawvalue);   // append array with raw values bytes to our message array
              
          var_dump($msg);
              
          $str implode(array_map("chr"$msg));
              
          socket_write($msgsock$str strlen($str));
          }

          function 
          send_setdatapointvalue_response($msgsock$startdp)
          {
              
          $msg = array(0x060x200xF00x800x000x110x040x000x000x000xF00x860x000x000x000x000x00);
              
          $msg[12] = ($startdp &0xFF00) >> 8;
              
          $msg[13] = $startdp 0xFF;
              
          $str implode(array_map("chr"$msg));
              
          socket_write($msgsock$str strlen($str));
          }

          function 
          process_setdatapointvalue_request($msgsock$startdp$numdp$dp)
          {
              global 
          $dparray;

              
          dbgprint(LOG_DEBUG"Subservice: SetDatapointValue.Req: start_dp: %d, num_dp: %d"$startdp$numdp);

              
          $pos 0// for multiple DPs in one message (never seen so far!)
              
          for ($i $startdp$i < ($startdp+$numdp); $i++)
              {
                  
          $curdp = ($dp[$pos+0] << 8) + $dp[$pos+1];
                  
          //$curdpcmd = $dp[$pos+2]; //DP commands are not used
                  
          $curdplen $dp[$pos+3];
                  if ((
          $curdp != $i) && ($startdp == $i))
                  {
                      
          dbgprint(LOG_WARN"Warning! Start datapoint %d does not match first datapoint id %d!"$startdp$curdp);
                  }
                  if ( 
          array_key_exists($curdp$dparray) == FALSE )
                  {
                      
          dbgprint(LOG_DEBUG"Ignoring unknown DP %d"$curdp);
                  }
                  else
                  {
                      
          dbgprint(LOG_INFO"DP %d - %s"$i$dparray[$curdp][0]);
                      
          $rawvalue array_slice($dp$pos 4$curdplen);
                      
          //var_dump($rawvalue);
                      
          $val call_user_func("conv_".$dparray[$curdp][1], $rawvalue);
                      echo 
          "Value: ".$val."\n";
                      
          //$sendline = $i.":"."$val";
                      //msg_send($msg_queue, 2, json_encode($inputSend), false);
                  
          }
                  
          $pos += $curdplen 4// 2 bytes DP id, 1 byte cmd, 1 byte dp value len -> 4 bytes
              
          }

          }

          function 
          process_objsrv_msg($msgsock$msg$msglen)
          {
              
          $mainservice $msg[0];
              
          $subservice $msg[1];

              
          //printf("mainservice: %02X\n", $mainservice);
              //printf("subservice: %02X\n", $subservice);
              //var_dump($msg);

              
          if ($mainservice != 0xF0)
              {
                  
          dbgprint(LOG_ERR"Mainservice type unknown: %02X\n"$mainservice);
                  return;
              }

              switch (
          $subservice)
              {
                  case 
          0x06// SetDatapointValue.Req
                              
          $startdp = ($msg[2] << 8) + $msg[3];
                              
          $numdp = ($msg[4] << 8) + $msg[5];
                              
          $dp array_slice($msg6$msglen 6);
                              
          process_setdatapointvalue_request($msgsock$startdp$numdp$dp);
                              
          send_setdatapointvalue_response($msgsock$startdp);
                              break;
                  case 
          0x86// SetDatapointValue.Res
                              
          dbgprint(LOG_DEBUG"Subservice: SetDatapointValue.Res (ignoring)");
                              break;
                  case 
          0xC1// DatapointValue.Ind
                              
          dbgprint(LOG_DEBUG"Subservice: DatapointValue.Ind (ignoring)");
                              break;
                  default:   
          dbgprint(LOG_ERR"Subservice type unknown: %02X"$subservice);
              }        

          }

          function 
          process_msg ($msgsock$msg)
          {
              
          $headersize $msg[0];
              
          $version $msg[1];
              
          $knxrequest $msg[3] | ($msg[2] << 8);
              
          $framesize $msg[5] | ($msg[4] <<8);
              
          $structlen $msg[$headersize];
              
          $objsrvmsglen $framesize $headersize $structlen;
              
          $objsrvmsg array_slice($msg$headersize $structlen,  $objsrvmsglen);

              
          //printf("headersize: %02X\n", $headersize);
              //printf("version: %02X\n" ,$version);
              //printf("knxrequest: %04X\n" ,$knxrequest);
              //printf("framesize: %04X\n" ,$framesize);
              //printf("structlen: %02X\n", $structlen);
              //printf("objsrvmsglen: %04X\n", $objsrvmsglen);

              
          if ($knxrequest != 0xF080)
              {
                  
          dbgprint(LOG_ERR"Unknown message type! Not an objectserver message type: %04X"$knxrequest);
                  return;
              }

              
          //var_dump($msg);
              
          process_objsrv_msg ($msgsock$objsrvmsg$objsrvmsglen);


              return 
          true;
          }

          error_reporting (E_ALL);

          /* Das Skript wartet auf hereinkommende Verbindungsanforderungen. */
          set_time_limit (0);

          /* Die implizite Ausgabe wird eingeschaltet, so dass man sieht,
           * was gesendet wurde. */
          ob_implicit_flush ();

          $address '0.0.0.0';
          $port 12004;

          if ((
          $sock socket_create(AF_INETSOCK_STREAMSOL_TCP)) === false)
          {
              
          dbgprint(LOG_ERR"socket_create() failed: reason: %s"socket_strerror(socket_last_error()));
          }

          dbgprint(LOG_DEBUG"socket_create done.");

          if (!
          socket_set_option($sockSOL_SOCKETSO_REUSEADDR1))
          {
              
          dbgprint(LOG_ERR"socket_set_option() failed: reason: %s"socket_strerror(socket_last_error()));
          }

          dbgprint(LOG_DEBUG"socket_set_option() done.");

          if (
          socket_bind($sock$address$port) === false) {
              
          dbgprint(LOG_ERR"socket_bind() failed: reason: %s"socket_strerror(socket_last_error($sock)));
          }


          dbgprint(LOG_DEBUG"socket_bind done.");


          if (
          socket_listen($sock1) === false) {
              
          dbgprint(LOG_ERR"socket_listen() failed: reason: %s"socket_strerror(socket_last_error($sock)));
          }


          dbgprint(LOG_DEBUG"socket_listen done.");

          do {
              if ((
          $msgsock socket_accept($sock)) === false) {
                  
          dbgprint(LOG_ERR"socket_accept() failed: reason: %s"socket_strerror(socket_last_error($sock)));
                  break;
              }

              
          dbgprint(LOG_DEBUG"socket_accept done.");

              
          request_all_datapoints($msgsock);

              do {
                  
          $len socket_recv ($msgsock$buf20480);
                  if (
          false === $len) {
                      
          dbgprint(LOG_ERR"socket_recv() failed: reason: %s"socket_strerror(socket_last_error($msgsock)));
                      die();
                  }
                  if ((
          $len === 0) && ($buf === NULL)) {
                      
          dbgprint(LOG_INFO"Closing connection.");
                      break 
          1;
                  }
                  
          //echo "socket_read ". $len." bytes done: " . socket_last_error($msgsock) . "\n";

                  
          $assocarray unpack ('C*'$buf);
                  
          $array array_values($assocarray);
                  
          //var_dump($array);

                  
          process_msg($msgsock$array);        


              } while (
          true);

              
          socket_close ($msgsock);

          } while (
          true);

          socket_close ($sock);
          ?>
          Zuletzt geändert von Nanosonde; 16.02.2018, 11:31.

          Kommentar


            #6
            Zitat von Nanosonde Beitrag anzeigen
            Mit diesem Skript kann Du erstmal nur alles lesen.
            Das Steuern des ISM8x ist noch nicht eingebaut. Als die Datenpunkte, die im Array neben OUT auch IN sind, können aktuell noch nicht gesetzt werden.
            Da kommt aber noch was irgendwann von mir. Ich kann nur nch nicht sagen, wann.
            Grüß dich, Nanosonde! Bist du inzwischen mit der Entwicklung deines Skripts weitergekommen, sodass man neben dem Lesen auch das Setzen der Werte möglich ist?

            Ein fertiges Edomi-LBS wäre natürlich erste Sahne! Kann mir vorstellen, dass noch andere Interesse dran hätten. Wie können wir dich dahingehend fördern/unterstützen?

            Kommentar


              #7
              Friendly push

              Kommentar


                #8
                Hi!

                Sorry, hatte Dich ganz vergessen.
                Ich habe das Skript inzwischen erweitert. Allerdings kann ich immer noch keine Werte setzen.
                Dafür verbindet es sich jetzt mit MQTT und teilt darüber alle Werte per Status-Update mit.
                Das Setzen habe ich schon angefangen. Es wird auf jeden Fall noch kommen.

                Einen LBS wird es wohl nicht geben, da ich das Skript aktuell über den MQTT Subscribe Client LBS eingebunden habe.
                Das Setzen der Werte wird dann über den MQTT Publish Client LBS erfolgen.


                Kommentar


                  #9
                  Hey! Danke für die Rückmeldung!

                  Mit den MQTT-LBS kann ich auch gut leben. Mein Geo-Fencing läuft derzeit auch über MQTT.

                  Ich warte dann solange und harre der Dinge, die da kommen. Halte uns bitte soweit es geht auf dem Laufenden!

                  Kommentar


                    #10
                    Hier die aktuelle Version mit SET. Ist aber nicht ausgiebig getestet.

                    Benötigt zwingend die MQTT Command-Line-Clients mosquitto_sub und mosquitto_pub auf dem System.
                    Die MQTT Topics sind entsprechend der MQTT Smarthome Architecture benannt.

                    Beispiel
                    Status: Subscribe wolf/status/166
                    Set: Publish wolf/set/153 ON
                    Command: wolf/command/SysRequestAllDatapoints DUMMY
                    Ein aktives "Get" gibt es noch nicht.

                    Dafür habe ich aber angefangen, Bequemlichkeitskommandos einzubauen.
                    Zum Beispiel soll "CwlenableMaxAirflow <Dauer in Minuten> die Lüftung für x Minuten auf 100% stellen, ohne dass der User selbst mit den Zeitstempeln für die Intensivlüftung rumhantieren muss. Das ist aber noch nicht zu Ende implementiert.

                    PHP-Code:
                    #!/usr/bin/php -q
                    <?php

                    $port 
                    12004;

                    $mqttbroker "127.0.0.1";
                    $mqttsubcmdpipe="/tmp/mqttsub.fifo";
                    $mqtttopicprefix "wolf";
                    $mqttsub_pidfile "/tmp/mqttsub.pid";
                    $mqttsubcmd ="mosquitto_sub -h $mqttbroker -q 2 -v -t $mqtttopicprefix/set/# -t $mqtttopicprefix/command";
                    $mqttpub_pidfile "/tmp/mqttpub.pid";
                    $mqttpubcmd "mosquitto_pub -h $mqttbroker -q 2";

                    /*
                    define ("LOG_DEBUG",  4);
                    define ("LOG_INFO",   3);
                    define ("LOG_WARNING",   2);
                    define ("LOG_ERR",  1);
                    */
                    define ("LOG_SILENT"0);

                    $g_loglevel LOG_INFO;

                    $dparray = array(
                             
                    "53"  => array("Störung(BM2)",                        "DPT_Switch"       "O",   ""          ),
                             
                    "55"  => array("Raumtemperatur(BM2)",                 "DPT_Value_Temp"   "O",   "C"        ),
                             
                    "148" => array("Störung",                             "DPT_Switch"       "O",   ""          ),
                             
                    "149" => array("Programm",                            "DPT_DHWMode"      "IO",  ""          ),
                             
                    "150" => array("Zeitprogramm1",                       "DPT_Switch"       "IO",  ""          ),
                             
                    "151" => array("Zeitprogramm2",                       "DPT_Switch"       "IO",  ""          ),
                             
                    "152" => array("Zeitprogramm3",                       "DPT_Switch"       "IO",  ""          ),
                             
                    "153" => array("Zeitw.Intensivlüftung_AN/AUS",        "DPT_Switch"       "IO",  ""          ),
                             
                    "154" => array("Zeitw.Intensivlüftung_Startdatum",    "DPT_Date"         "IO",  "dd:mm:yyyy"),
                             
                    "155" => array("Zeitw.Intensivlüftung_Enddatum",      "DPT_Date"         "IO",  "dd:mm:yyyy"),
                             
                    "156" => array("Zeitw.Intensivlüftung_Startzeit",     "DPT_TimeOfDay"    "IO",  "hh:mm:ss"  ),
                             
                    "157" => array("Zeitw.Intensivlüftung_Endzeit",       "DPT_TimeOfDay"    "IO",  "hh:mm:ss"  ),
                             
                    "158" => array("Zeitw.Feuchteschutz_AN/AUS",          "DPT_Switch"       "IO",  ""          ),
                             
                    "159" => array("Zeitw.Feuchteschutz_Startdatum",      "DPT_Date"         "IO",  "dd:mm:yyyy"),
                             
                    "160" => array("Zeitw.Feuchteschutz_Enddatum",        "DPT_Date"         "IO",  "dd:mm:yyyy"),
                             
                    "161" => array("Zeitw.Feuchteschutz_Startzeit",       "DPT_TimeOfDay"    "IO",  "hh:mm:ss"  ),
                             
                    "162" => array("Zeitw.Feuchteschutz_Endzeit",         "DPT_TimeOfDay"    "IO",  "hh:mm:ss"  ),
                             
                    "163" => array("Lüftungsstufe",                       "DPT_Scaling"      "O",   "%"         ),
                             
                    "164" => array("Ablufttemperatur",                    "DPT_Value_Temp"   "O",   "C"        ),
                             
                    "165" => array("Frischlufttemperatur",                "DPT_Value_Temp"   "O",   "C"        ),
                             
                    "166" => array("Luftdurchsatz Zuluft",                "DPT_FlowRate"     "O",   "m3/h"      ),
                             
                    "167" => array("Luftdurchsatz Abluft",                "DPT_FlowRate"     "O",   "m3/h"      ),
                             
                    "168" => array("Bypass Initialisierung",              "DPT_Bool"         "O",   ""          ),
                             
                    "169" => array("Bypass öffnet/offen",                 "DPT_Bool"         "O",   ""          ),
                             
                    "170" => array("Bypass schließt/geschlossen",         "DPT_Bool"         "O",   ""          ),
                             
                    "171" => array("Bypass Fehler",                       "DPT_Bool"         "O",   ""          ),
                             
                    "172" => array("Frost Status: Initialisierung/Warte""DPT_Bool"         "O",   ""          ),
                             
                    "173" => array("Frost Status: Kein Frost",            "DPT_Bool"         "O",   ""          ),
                             
                    "174" => array("Frost Status: Vorwärmer",             "DPT_Bool"         "O",   ""          ),
                             
                    "175" => array("Frost Status: Fehler/Unausgeglichen""DPT_Bool"         "O",   ""          ),
                    );

                    $dplastchange = array();

                    function 
                    dbgprint()
                    {
                        global 
                    $g_loglevel;

                        
                    $argv func_get_args();
                        
                    $loglevel array_shift$argv );

                        if (
                    $loglevel <= $g_loglevel)
                        {
                            
                    $format array_shift$argv );

                            switch(
                    $loglevel)
                            {
                                case 
                    LOG_DEBUG:   printf'DEBUG: ' );
                                                  break;
                                case 
                    LOG_INFO:    printf'INFO: ' );
                                                  break;
                                case 
                    LOG_WARNINGprintf'WARNING: ' );
                                                  break;
                                case 
                    LOG_ERR:     printf'ERROR: ' );
                                                  break;
                                default:          
                    printf'---: ' );
                            }
                            
                    vprintf$format$argv );
                            
                    printf"\n" );
                        }
                    }

                    function 
                    convfrom_DPT_Bool($val)
                    {
                        return 
                    $val[0] == '0' "FALSE":"TRUE";
                    }

                    function 
                    convto_DPT_Bool($val)
                    {
                        
                    $val strtoupper($val);
                        
                    $temp = (($val == 'FALSE') || ($val == '0') ) ? 0:1;
                        
                    $bytearray = array($temp);
                        return 
                    $bytearray;
                    }

                    function 
                    convfrom_DPT_Switch($val)
                    {
                        return 
                    $val[0] == '0' "OFF":"ON";
                    }

                    function 
                    convto_DPT_Switch($val)
                    {
                        
                    $val strtoupper($val);
                        
                    $temp = (($val == 'OFF') || ($val == '0') ) ? 0:1;
                        
                    $bytearray = array($temp);
                        return 
                    $bytearray;
                    }

                    function 
                    convfrom_DPT_DHWMode($val)
                    {
                        switch (
                    $val[0])
                        {
                            case 
                    0: return "Auto";
                            case 
                    1: return "LegioProtect";
                            case 
                    2: return "Normal";
                            case 
                    3: return "Reduced";
                            case 
                    4: return "Off/FrostProtect";
                            default: return 
                    "Unknown";
                        }
                    }

                    function 
                    convto_DPT_DHWMode($val)
                    {
                        switch (
                    $val)
                        {
                            case 
                    'Auto':             $temp 0;
                            case 
                    'LegioProtect':     $temp 1;
                            case 
                    'Normal':           $temp 2;
                            case 
                    'Reduced':          $temp 3;
                            case 
                    'Off/FrostProtect'$temp 4;
                            default:                 
                    $temp 0;
                        }
                        
                    $bytearray = array(temp);
                        return 
                    $bytearray;
                    }

                    function 
                    convfrom_DPT_Scaling($val)
                    {
                        return ((string)
                    round($val[0] * 100/255));
                    }

                    function 
                    convfrom_DPT_FlowRate($val)
                    {
                        
                    $value = ($val[0]<<24)|($val[1]<<16)|($val[2]<<8)|($val[3]<<0);
                        
                    $flowrate $value 0.0001;
                        return ((string)
                    $flowrate);
                    }

                    function 
                    convfrom_DPT_Value_Temp($val)
                    {
                        if ((
                    $val[0] == 0x7F) && ($val[1] == 0xFF))
                        {
                            
                    $float "<invalid>";
                        }
                        else
                        {
                            
                    $mantissa intval(($val[1] & 0xFF) | (($val[0] &0x87)<<8));
                            
                    $exponent intval(($val[0] & 0x78)>>3);
                            
                    $float 0.01 $mantissa pow(2$exponent);
                        }
                        return ((string)
                    $float);
                    }

                    function 
                    convfrom_DPT_TimeOfDay($val)
                    {

                        
                    $daynames = array(
                        
                    '(no_day_provided)',
                        
                    'Monday',
                        
                    'Tuesday',
                        
                    'Wednesday',
                        
                    'Thursday',
                        
                    'Friday',
                        
                    'Saturday',
                        
                    'Sunday'
                        
                    );

                        
                    $day = ($val[0] & 0xE0) >> 5;
                        
                    $hour $val[0] & 0x1F;
                        
                    $minutes $val[1] & 0x3F;
                        
                    $seconds $val[2] & 0x3F;

                        
                    $hour sprintf("%02d"$hour);
                        
                    $minutes sprintf("%02d"$minutes);
                        
                    $seconds sprintf("%02d"$seconds);

                        if (
                    $day == 0)
                            return ((string)
                    $hour).":".((string)$minutes).":".((string)$seconds);
                        else
                            return 
                    $daynames[$day].",".((string)$hour).":".((string)$minutes).":".((string)$seconds);
                    }

                    function 
                    convto_DPT_TimeOfDay($val)
                    {
                        
                    $temp = array();

                        list(
                    $hour$minutes$seconds) = sscanf($val"%d:%d:%d");

                        
                    $temp[0] = $hour 0x1F// day is always 0 -> no day provided
                        
                    $temp[1] = $minutes 0x3F;
                        
                    $temp[2] = $seconds 0x3F;

                        return 
                    $temp;
                    }


                    function 
                    convfrom_DPT_Date($val)
                    {
                        
                    $year $val[2] & 0x7F;
                        
                    $month $val[1] & 0x0F;
                        
                    $day $val[0] & 0x1F;

                        
                    $year sprintf("%02d%02d"substr(date("Y"), 02), $year);
                        
                    $month sprintf("%02d"$month);
                        
                    $day sprintf("%02d"$day);

                        return ((string)
                    $day).".".((string)$month).".".((string)$year);
                    }

                    function 
                    convto_DPT_Date($val)
                    {
                        
                    $temp = array();

                        list(
                    $day$month$year) = sscanf($val"%d.%d.%d");

                        
                    $century substr(date("Y"), 02)*100;
                        if (
                    $year >= $century )
                            
                    $year -= $century;

                        
                    $temp[0] = $day 0x1F;
                        
                    $temp[1] = $month 0x0F;
                        
                    $temp[2] = $year 0x7F;

                        return 
                    $temp;
                    }

                    function 
                    request_all_datapoints($msgsock)
                    {
                        
                    /* Send special message to request all datapoints to be sent. */
                        
                    $msg = array(0x060x200xF00x800x000x0C0x040x000x000x000xF00xD0);
                        
                    $str implode(array_map("chr"$msg));
                        
                    //socket_write($msgsock, $str , strlen($str));
                        
                    fwrite($msgsock$str strlen($str));
                    }

                    function 
                    send_datapointvalue_indication($msgsock$dp$rawvalues)
                    {
                        
                    $msg = array(0x060x200xF00x800x000x140x040x000x000x000xF00xC10x000x000x000x010x000x000x000x00);
                        
                    $msg[12] = ($dp &0xFF00) >> 8// Start DP MSB
                        
                    $msg[13] = $dp 0xFF;         // Start DP LSB
                        
                    $msg[16] = $msg[12];           // First DP ID MSB
                        
                    $msg[17] = $msg[13];           // First DP ID LSB
                        
                    $msg[19] = count($rawvalues);  // DP value length
                        
                    $msg[5] += $msg[19];           // add value length to frame size
                        
                    foreach ($rawvalues as $rawvalue// append array with raw values bytes to our message array
                            
                    array_push($msg$rawvalue);
                        
                    //var_dump($msg);
                        
                    $str implode(array_map("chr"$msg));
                        
                    //var_dump(unpack("C*", $str));
                        
                    fwrite($msgsock$str strlen($str));
                    }

                    function 
                    send_setdatapointvalue_response($msgsock$startdp)
                    {
                        
                    $msg = array(0x060x200xF00x800x000x110x040x000x000x000xF00x860x000x000x000x000x00);
                        
                    $msg[12] = ($startdp &0xFF00) >> 8;
                        
                    $msg[13] = $startdp 0xFF;
                        
                    $str implode(array_map("chr"$msg));
                        
                    //socket_write($msgsock, $str , strlen($str));
                        
                    fwrite($msgsock$str strlen($str));
                    }

                    function 
                    process_setdatapointvalue_request($msgsock$startdp$numdp$dp)
                    {
                        global 
                    $dparray;
                        global 
                    $mqttpubcmd;
                        global 
                    $mqtttopicprefix;
                        global 
                    $mqttpub_pidfile;
                        global 
                    $dplastchange;

                        
                    dbgprint(LOG_DEBUG"Subservice: SetDatapointValue.Req: start_dp: %d, num_dp: %d"$startdp$numdp);

                        
                    $pos 0// for multiple DPs in one message (never seen so far!)
                        
                    for ($i $startdp$i < ($startdp+$numdp); $i++)
                        {
                            
                    $curdp = ($dp[$pos+0] << 8) + $dp[$pos+1];
                            
                    //$curdpcmd = $dp[$pos+2]; //DP commands are not used
                            
                    $curdplen $dp[$pos+3];
                            if ((
                    $curdp != $i) && ($startdp == $i))
                            {
                                
                    dbgprint(LOG_WARN"Warning! Start datapoint %d does not match first datapoint id %d!"$startdp$curdp);
                            }
                            if ( 
                    array_key_exists($curdp$dparray) == FALSE )
                            {
                                
                    dbgprint(LOG_DEBUG"Ignoring unknown DP %d"$curdp);
                            }
                            else
                            {
                                
                    $rawvalue array_slice($dp$pos 4$curdplen);
                                
                    //var_dump($rawvalue);
                                
                    $val call_user_func("convfrom_".$dparray[$curdp][1], $rawvalue);
                                if (
                    $val !== false) {
                                    
                    //var_dump($val);
                                    
                    dbgprint(LOG_INFO"DP %d - %s(%s) - ("%s")"$i$val$dparray[$curdp][3], $dparray[$curdp][0]);

                                    
                    // create payload according smarthome architecture
                                    // https://github.com/mqtt-smarthome/mqtt-smarthome/blob/master/Architecture.md
                                    
                    $payload = array();
                                    
                    $payload['val'] = $val;
                                    
                    $payload['unit']  = $dparray[$curdp][3];
                                    if (
                    array_key_exists($i$dplastchange))
                                        
                    $payload['lc'] = $dplastchange[$i];
                                    else
                                         
                    $payload['lc'] = "";
                                    
                    $payload['ts'] = round(microtime(true) * 1000);
                                    
                    $dplastchange[$i] = $payload['ts'];
                                    
                    $payload['dp'] = $i;
                                    
                    //var_dump($dplastchange);

                                    
                    $outputfile "/dev/null";
                                    
                    $cmd sprintf("%s -t %s/status/%d -m '%s'"$mqttpubcmd$mqtttopicprefix$ijson_encode($payload));
                                    
                    //var_dump($cmd);
                                    
                    exec(sprintf("%s > %s 2>&1 & echo $! > %s"$cmd$outputfile$mqttpub_pidfile));
                                    
                    unlink($mqttpub_pidfile);
                                }
                                else {
                                 
                    dbgprint(LOG_ERR"Function convfrom_%s not found."$dparray[$curdp][1]);
                                }            
                            }
                            
                    $pos += $curdplen 4// 2 bytes DP id, 1 byte cmd, 1 byte dp value len -> 4 bytes
                        
                    }

                    }

                    function 
                    process_objsrv_msg($msgsock$msg$msglen)
                    {
                        
                    $mainservice $msg[0];
                        
                    $subservice $msg[1];

                        
                    //printf("mainservice: %02X\n", $mainservice);
                        //printf("subservice: %02X\n", $subservice);
                        //var_dump($msg);

                        
                    if ($mainservice != 0xF0)
                        {
                            
                    dbgprint(LOG_ERR"Mainservice type unknown: %02X\n"$mainservice);
                            return;
                        }

                        switch (
                    $subservice)
                        {
                            case 
                    0x06// SetDatapointValue.Req
                                        
                    $startdp = ($msg[2] << 8) + $msg[3];
                                        
                    $numdp = ($msg[4] << 8) + $msg[5];
                                        
                    $dp array_slice($msg6$msglen 6);
                                        
                    process_setdatapointvalue_request($msgsock$startdp$numdp$dp);
                                        
                    send_setdatapointvalue_response($msgsock$startdp);
                                        break;
                            case 
                    0x86// SetDatapointValue.Res
                                        
                    dbgprint(LOG_DEBUG"Subservice: SetDatapointValue.Res (ignoring)");
                                        break;
                            case 
                    0xC1// DatapointValue.Ind
                                        
                    dbgprint(LOG_DEBUG"Subservice: DatapointValue.Ind (ignoring)");
                                        break;
                            default:   
                    dbgprint(LOG_ERR"Subservice type unknown: %02X"$subservice);
                        }        

                    }

                    function 
                    process_msg ($msgsock$msg)
                    {
                        
                    $headersize $msg[0];
                        
                    $version $msg[1];
                        
                    $knxrequest $msg[3] | ($msg[2] << 8);
                        
                    $framesize $msg[5] | ($msg[4] <<8);
                        
                    $structlen $msg[$headersize];
                        
                    $objsrvmsglen $framesize $headersize $structlen;
                        
                    $objsrvmsg array_slice($msg$headersize $structlen,  $objsrvmsglen);

                        
                    //printf("headersize: %02X\n", $headersize);
                        //printf("version: %02X\n" ,$version);
                        //printf("knxrequest: %04X\n" ,$knxrequest);
                        //printf("framesize: %04X\n" ,$framesize);
                        //printf("structlen: %02X\n", $structlen);
                        //printf("objsrvmsglen: %04X\n", $objsrvmsglen);

                        
                    if ($knxrequest != 0xF080)
                        {
                            
                    dbgprint(LOG_ERR"Unknown message type! Not an objectserver message type: %04X"$knxrequest);
                            
                    var_dump($msg);
                            return;
                        }

                        
                    //var_dump($msg);
                        
                    process_objsrv_msg ($msgsock$objsrvmsg$objsrvmsglen);


                        return 
                    true;
                    }

                    function 
                    set_datapoint($msgsock$dp$value)
                    {
                        global 
                    $dparray;

                        if (
                    $dparray[$dp][2] == "IO") {
                         
                    $rawvalue call_user_func("convto_".$dparray[$dp][1], $value);
                         if (
                    $val !== false) {
                             
                    //var_dump($rawvalue);
                             
                    send_datapointvalue_indication($msgsock$dp$rawvalue);
                             return 
                    true;
                         }
                         else {
                             
                    dbgprint(LOG_ERR"Function convto_%s not found."$dparray[$dp][1]);
                         }
                        }
                        else {
                         
                    dbgprint(LOG_ERR"DP %d is not writable."$dp);
                        }    
                        return 
                    false;
                    }

                    function 
                    isRunning($pid){
                        try{
                            
                    $result shell_exec(sprintf("ps %d"$pid));
                            if( 
                    count(preg_split("/\n/"$result)) > 2){
                                return 
                    true;
                            }
                        }catch(
                    Exception $e){}

                        return 
                    false;
                    }

                    function 
                    signalHandler($signo)
                    {
                        global 
                    $running;
                        
                    $running false;
                        
                    printf("Warning: interrupt received, exiting…%s"PHP_EOL);
                    }

                    declare(
                    ticks=1); // PHP internal, make signal handling work

                    error_reporting (E_ALL);

                    /* Das Skript wartet auf hereinkommende Verbindungsanforderungen. */
                    set_time_limit (0);

                    /* Die implizite Ausgabe wird eingeschaltet, so dass man sieht,
                     * was gesendet wurde. */
                    ob_implicit_flush ();

                    posix_mkfifo($mqttsubcmdpipe0644);
                    $file fopen($mqttsubcmdpipe,"r+");
                    stream_set_blocking($filefalse);

                    exec(sprintf("%s > %s 2>&1 & echo $! > %s"$mqttsubcmd$mqttsubcmdpipe$mqttsub_pidfile));

                    $pid intval(file_get_contents($mqttsub_pidfile));;
                    unlink($mqttsub_pidfile);

                    dbgprint(LOG_INFO"Started sub-process with PID %d"$pid);

                    if ((
                    $sock stream_socket_server("tcp://0.0.0.0:$port"$errno$errstr)) === false)
                    {
                        
                    dbgprint(LOG_ERR"stream_socket_server() failed: reason: %s (%d)"$errstr$errno);
                    }

                    dbgprint(LOG_DEBUG"stream_socket_server() done.");

                    $running true;

                    pcntl_signal(SIGINT'signalHandler');
                    pcntl_signal(SIGINT'signalHandler');

                    while(
                    $running) {

                        if ((
                    $msgsock =  stream_socket_accept ($sock)) === false) {
                            
                    dbgprint(LOG_ERR"stream_socket_accept() failed: reason: %s"socket_strerror(socket_last_error($sock)));
                            break;
                        }

                        
                    dbgprint(LOG_DEBUG"stream_socket_accept() done.");

                        
                    request_all_datapoints($msgsock);

                        
                    stream_set_blocking($msgsockfalse);

                        while(
                    $running) {

                            
                    $readers = array($msgsock$file);
                            
                    $writers=null;
                            
                    $except=null;
                            if (@
                    stream_select($readers,$writers,$except,1) < 1)
                            {
                             continue;
                            }
                            else
                            {
                                if (
                    in_array($msgsock$readers)) {
                                    
                    $buf fread($msgsock2048);
                                    if (
                    false === $buf) {
                                        
                    dbgprint(LOG_ERR"fread() failed: reason: %s"socket_strerror(socket_last_error($msgsock)));
                                        die();
                                    }
                                    if (empty(
                    $buf)) {
                                        
                    $data stream_get_meta_data($msgsock);
                                        if (
                    $data['timed_out'] !== true) {
                                            
                    dbgprint(LOG_INFO"Closing connection.");
                                            break 
                    1;
                                        }
                                        else {
                                            
                    dbgprint(LOG_INFO"Ignoring stream timeout.");
                                            continue;
                                        }
                                    }
                                    
                    $assocarray unpack ('C*'$buf);
                                    
                    $array array_values($assocarray);
                                    
                    //var_dump($array);
                                    
                    process_msg($msgsock$array);        
                                }
                                elseif (
                    in_array($file$readers)) {
                                    
                    // read data from the fifo
                                    
                    $line fgets($file,4096);
                                    echo 
                    $line;                    
                                    
                    $pattern "/wolf\/set\/(\d+)\s([\w|\S]+)/";
                                    if (
                    preg_match($pattern$line$matches)) {
                                        
                    $dp $matches[1];
                                        
                    $value $matches[2];
                                        
                    set_datapoint($msgsock$dp$value);
                                    }
                                    else {
                                        
                    $pattern "/wolf\/command\s+(\w+):(\S*)/";
                                        if (
                    preg_match($pattern$line$matches)) {
                                            
                    $cmd $matches[1];
                                            
                    $args explode(","$matches[2]);
                                            switch (
                    $cmd) {
                                                case 
                    'SysRequestAllDatapoints':
                                                    
                    dbgprint(LOG_INFO"Requesting all datapoints from gateway");
                                                    
                    request_all_datapoints($msgsock);
                                                    break;
                                                case 
                    'CwlenableMaxAirflow':
                                                    
                    $duration intval($args[0]);
                                                    
                    dbgprint(LOG_INFO"Enabling maximum airflow for %d minutes"$duration);

                                                    break;
                                                default:
                                                    
                    dbgprint(LOG_ERR"Unknown command: %s"$cmd);
                                            }
                                        }
                                        else {
                                            
                    dbgprint(LOG_INFO"Ignoring MQTT line: %s"$line);
                                        }
                                    }
                                }
                            }
                        }

                        
                    fclose($msgsock);
                    }

                    fclose($file);
                    fclose($sock);

                    posix_kill($pidSIGTERM);
                    sleep(1);
                    if (
                    isRunning($pid))
                        
                    dbgprint(LOG_WARNING"Warning sub-process with PID %d is still running!"$pid);
                    else
                        
                    dbgprint(LOG_INFO"Terminated sub-process with PID %d"$pid);

                    unlink($mqttsubcmdpipe);

                    dbgprint(LOG_INFO"Finished.");
                    ?>

                    Kommentar


                      #11
                      Vielen Dank soweit! Ich werd mir jetzt das ISM8i besorgen und mich einarbeiten. Mal schauen, was so geht...

                      Kommentar


                        #12
                        Hi!

                        Ich habe jetzt doch mal den KNX BAOS Server für Wolf ISM8 zu Ende gebaut (LBS19001221).
                        Dieser benötigt zwingend den TCP Server LBS von mir (LBS19001220).

                        Ich habe es gerade auf die Schnelle getestet und es funktioniert soweit bei mir auch.
                        Du kannst sogar alle beschreibbaren Datenpunkte an den Eingängen setzen.
                        Damit kannst Du nun auch die Intensivlüftung oder den Feuchteschutz ein bzw. ausschalten.
                        Damit ist es nun bei mir möglich, die Lüftungsstufen 25%(Feuchteschutz), 50% (reduziert), 75 (normal) und 100% (Intensivlüftung) anzusteuern.

                        Steuerung Feuchteschutz und Intensivlüftung über die Eingänge E10 und E15 dürfte klar sein (0/1).
                        Die Intensivlüftung hat in der Anlage offenbar immer Priorität vor dem Feuchteschutz.
                        Wenn beides AUS ist, dann läuft die Anlage entweder NORMAL oder REDUCED, je nachdem was an E6 eingestellt wird.
                        Auch AUTO ist an E6 möglich, so dass die Anlage dann über eines der drei ausgewählten Zeitprogramme läuft.

                        Unbenannt.PNG
                        Zuletzt geändert von Nanosonde; 28.12.2017, 19:34.

                        Kommentar


                          #13
                          Das ist ja genial! Mein liebstes Weihnachtsgeschenk dieses Jahr!

                          Leider ist meine Hardware noch nicht da... Sobald diese hier eintrudelt, wird fleißig getestet!

                          Herzlichen Dank Nanosonde !

                          Kommentar


                            #14
                            Ich werde im Haus folgende Kombination bekommen:
                            • Gas-Brennwert-Therme CGB-2-14
                            • Bedienmodul BM-2
                            • Mischermodul MM-2
                            Wäre natürlich klasse gewesen, wenn es auch dafür einen Edomi Baustein gegeben hätte...

                            Was mich wunder ist, dass es auf der Wolf Homepage das ISM8i Modul anscheinend garnicht mehr gibt: https://www.wolf.eu/service/smarthome-smartset/
                            Da ist nur von ISM7 und ISM9 die Rede. Auch die Suche nach BAOS gibt dort keinen Treffer. Wurde da was ersetzt oder würde ich dann immer noch ISM8i+BAOS benötigen?
                            Ciao Jochen

                            Kommentar


                              #15
                              Hallo McEgg ,

                              Du kannst Dir den vorhandenen Baustein ganz einfach erweitern.
                              In der Tabelle $dparray musst Du nur die weiteren Datenpunkte hinzufügen, die im ISM8 Handbuch für die Heizung, BM2, etc. aufgeführt sind.
                              Die ersten zwei Datenpunkte bei dem aktuellen Baustein sind übrigens zwei Datenpunkte vom BM2, da ich auch die Raumtemperatur vom BM2 haben wollte.
                              Für den LBS musst Du dann nur die entsprechenden Ein- und Ausgänge dazumalen und die Nummern der Ein- und Ausgänge in der Tabelle $dparray zusätzlich vermerken.
                              Es muss also nichts extra programmiert werden!

                              Das ISM8i kann man offenbar aber noch kaufen. Vielleicht sind es nur noch Restbestände. Keine Ahnung.
                              ISM8 spricht nur das Weinzierl BAOS Protokoll. Daher braucht man entweder ein Skript/LBS (siehe oben) oder direkt das komplette Wolf-Set inkl. KNX BAOS-Modul.
                              Das war mir aber viel zu teuer!




                              Kommentar

                              Lädt...
                              X