Anbindung an IOBROKER

Anbindung des Controllers an externe Hausautomationssysteme.
Sven
Beiträge: 24
Registriert: 19. Juli 2015, 19:48

Anbindung an IOBROKER

Beitrag von Sven »

Hallo,
hat schon jemand Erfahrung mit der Anbindung an IOBroker?
Ich persönlich habe bisher Fhem genutzt, nochmal vielen Dank für das Fhem Modul, und bin jetzt fast mit der Umstellung von Fhem auf http://iobroker.org fertig. Nie wieder Perl :D
Da stellt sich nun die Frage, hat schon jemand einen Adpater oder JavaScripte zur Anbindung an den Pool Controller umgesetzt bzw. in Planung?

Falls ja könnte man sich ja mal darüber austauschen :)

Viele Grüße
Sven

Sven
Beiträge: 24
Registriert: 19. Juli 2015, 19:48

Re: Anbindung an IOBROKER

Beitrag von Sven »

Hallo,
nachdem ich mich nun mit Javascript auseinader gesetzt habe ist nachfolgendes Script entstanden.
Ich habe viel von anderer Stelle zusammen getragen und in diesem Script verabeitet, vielen Dank an alle die dazu beigetragen haben.
Anregungen und Erfahrungsaustausch ist willkommen :D

Gruß
Sven

Code: Alles auswählen

/**************************************************************************** 
*                                                                           * 
*  Script zum einlesen der GetState.csv vom PoolController in IOBroker      *
*  Wichtig: Die Namen im Controller dürfen kein Punkte enthalten !!!        *
*  Also es darf kein "n.a." verwendet werden Leerzeichen werden für         *
*  IOBroker durch Unterstriche ersetzt.                                     *
*  Die URL muss entsprechend auf die IP des PoolController angepasst werden *
*                                                                           *
*  Funktion:                                                                *
*  Beim Skript start werden die Namen eingelesen und dann als Objekt unter  *
*  Javascript.0.Poolcontroller.XXX angelegt. Die Einheiten werden auch      *
*  automatisch zugeordnet. Danach wird alle 30 Sekunden die GetState.csv    *
*  abgerufen und die Variablen werden in IOBroker Objekte geschrieben       *
*  Die Berechnug offset + ( gain * value) erfolgt bereits in diesem Script  *
*                                                                           *
****************************************************************************/

var url='http://192.168.x.x:8080/GetState.csv'

//*********************************************************************
var result, json;
var stateanlegen = true;

//SYSINFO Variablen anlegen
       createState('javascript.0.PoolController.SYSINFO.VERSION', {
        name: 'VERSION',
        type: 'string',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.CPU_TIME', {
        name: 'CPU_TIME',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.RESET_ROOT_CAUSE', {
        name: 'RESET_ROOT_CAUSE',
        type: 'number',
        write: false,
        read:  true
        });
         createState('javascript.0.PoolController.SYSINFO.NTP_FAULT_STATE', {
        name: 'NTP_FAULT_STATE',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.CONFIG_OTHER_ENABLE', {
        name: 'CONFIG_OTHER_ENABLE',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.DOSAGE_CNTRL', {
        name: 'DOSAGE_CNTRL',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.pH+_DOSAGE_RELAIS_ID', {
        name: 'pH+_DOSAGE_RELAIS_ID',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.pH-_DOSAGE_RELAIS_ID', {
        name: 'pH-_DOSAGE_RELAIS_ID',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.Chlor_DOSAGE_RELAIS_ID', {
        name: 'Chlor_DOSAGE_RELAIS_ID',
        type: 'number',
        write: false,
        read:  true
        });


//alle 30 Sekunden Werte neu einlesen
schedule("*/30 * * * * *", function () {
  try {
    require("request")(url, function (error, response, result) {
   //   console.log(result);
    result = result.replace(/ /g, '_');  //alle Leerzeichen durch Unterstrich ersetzten
    var data=CSVToArray(result);         //CSV in ein Array einlesen
    json = JSON.stringify(data);         //Array in einen String formatieren
    var jdata = JSON.parse(json);        //Json Array erzeugen
    var arr1 = jdata[0];                 // Array 0 von ingesamt 6, weil 6 Zeilen im CVS mit \n getrennt
    var arr2 = jdata[1];                 // Array 1-5 haben je 42 einzelne  Daten
    var arr3 = jdata[2];
    var arr4 = jdata[3];
    var arr5 = jdata[4];
    var arr6 = jdata[5];
   
/** Debug Ausgaben der Arrays
    console.log(arr1);
    console.log(arr2);
    console.log(arr3);
    console.log(arr4);
    console.log(arr5);
    console.log(arr6);
 */

  if (stateanlegen === true){
    // User Variablen anlegen Achtung keine Punkte im Namen verwenden. 
    var i=0;
    for (i=0; i<=41;i++){
        createState('javascript.0.PoolController.'+jdata[1][i],'', {
        name: ''+jdata[1][i],
        type: 'number',
        unit: ''+jdata[2][i],
        write: false,
        read:  true
        });
    }
    console.log("Variablen angelegt");
    stateanlegen = false;
  }
  else {
  
  //SYSINFO Variablen mit aktuellen Werten beschreiben 
    setState('javascript.0.PoolController.SYSINFO.VERSION', jdata[0][1]);
    setState('javascript.0.PoolController.SYSINFO.CPU_TIME', parseFloat(Number(jdata[0][2]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.RESET_ROOT_CAUSE', parseFloat(Number(jdata[0][3]).toFixed(2))); 
    setState('javascript.0.PoolController.SYSINFO.NTP_FAULT_STATE', parseFloat(Number(jdata[0][4]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.CONFIG_OTHER_ENABLE', parseFloat(Number(jdata[0][5]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.DOSAGE_CNTRL', parseFloat(Number(jdata[0][6]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.pH+_DOSAGE_RELAIS_ID', parseFloat(Number(jdata[0][7]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.pH-_DOSAGE_RELAIS_ID', parseFloat(Number(jdata[0][8]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.Chlor_DOSAGE_RELAIS_ID', parseFloat(Number(jdata[0][9]).toFixed(2)));
  
  
   // User Variablen mit aktuellen Werten beschreiben
   i=0; 
    for (i=0; i<=41;i++){
        //var wert = offset + ( gain * value);
    	var offset =  parseFloat(jdata[3][i]);
    	var gain =   parseFloat(jdata[4][i]);
    	var value =   parseFloat(jdata[5][i]);
      	var wert =  offset + ( gain * value);
        setState('javascript.0.PoolController.'+jdata[1][i], parseFloat(Number(wert).toFixed(2)));
      	}    
    console.log("Variablen updated");
  }
    }).on("error", function (e) {console.error(e);});
  } catch (e) { console.error(e); }
});


/**
* Javascript CSV To Array
*/

function CSVToArray( strData, strDelimiter ){
    // Check to see if the delimiter is defined. If not,
    // then default to comma.
    strDelimiter = (strDelimiter || ",");

    // Create a regular expression to parse the CSV values.
    var objPattern = new RegExp(
        (
            // Delimiters.
            "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +

            // Quoted fields.
            "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +

            // Standard fields.
            "([^\"\\" + strDelimiter + "\\r\\n]*))"
        ),
        "gi"
        );


    // Create an array to hold our data. Give the array
    // a default empty first row.
    var arrData = [[]];

    // Create an array to hold our individual pattern
    // matching groups.
    var arrMatches = null;


    // Keep looping over the regular expression matches
    // until we can no longer find a match.
    while (arrMatches = objPattern.exec( strData )){

        // Get the delimiter that was found.
        var strMatchedDelimiter = arrMatches[ 1 ];

        // Check to see if the given delimiter has a length
        // (is not the start of string) and if it matches
        // field delimiter. If id does not, then we know
        // that this delimiter is a row delimiter.
        if (
            strMatchedDelimiter.length &&
            strMatchedDelimiter !== strDelimiter
            ){

            // Since we have reached a new row of data,
            // add an empty row to our data array.
            arrData.push( [] );

        }

        var strMatchedValue;

        // Now that we have our delimiter out of the way,
        // let's check to see which kind of value we
        // captured (quoted or unquoted).
        if (arrMatches[ 2 ]){

            // We found a quoted value. When we capture
            // this value, unescape any double quotes.
            strMatchedValue = arrMatches[ 2 ].replace(
                new RegExp( "\"\"", "g" ),
                "\""
                );

        } else {

            // We found a non-quoted value.
            strMatchedValue = arrMatches[ 3 ];

        }


        // Now that we have our value string, let's add
        // it to the data array.
        arrData[ arrData.length - 1 ].push( strMatchedValue );
    }

    // Return the parsed data.
    return( arrData );
}


Sven
Beiträge: 24
Registriert: 19. Juli 2015, 19:48

Re: Anbindung an IOBROKER

Beitrag von Sven »

Hallo,
in der Beschreibung steht, das man die Urhzeit folgendermaßen berechnet:

Code: Alles auswählen

hh = (Wert/256)
mm = (Wert Modulo 60)
In Javascript sieht das dann folgendermaßen aus:

Code: Alles auswählen

var hour = (wert/256).toFixed(0);
var minute = (wert%60).toFixed(0);
      	   if (minute <10){
      	       wert = (hour+':0'+minute);
      	   }
      	   else{
      	        wert = (hour+':'+minute);
      	   }
Leider wird die minute nicht korrekt dargestellt- Die Anzeige ist immer 32 Minuten zuweit vorne.
Die Modulo Berechnug mit dem Taschenrechner kommt allerdings auf das selbe Ergebnis.
Kann es sein das Modulo 60 nicht mehr korrekt ist?
Gruß
Sven

michaelv
Beiträge: 60
Registriert: 6. Januar 2015, 17:03

Re: Anbindung an IOBROKER

Beitrag von michaelv »

Hallo Sven,

dein Script funktioniert

hier ein mal der Auszug über dein Script
mit_javascript.jpg
mit_javascript.jpg (20.38 KiB) 1035 mal betrachtet
und hier über den Fhem Adapter unter Fhem läuft ein Modul für den Controller
vielleicht für dich zum vergleichen
mit_fhem.jpg
mit_fhem.jpg (25.84 KiB) 1035 mal betrachtet
Gruß Michael

Benutzeravatar
Alex
Administrator
Beiträge: 9988
Registriert: 28. Mai 2014, 23:00

Re: Anbindung an IOBROKER

Beitrag von Alex »

Sven hat geschrieben:Hallo,
in der Beschreibung steht, das man die Urhzeit folgendermaßen berechnet:

hm... ist ein Fehler in der Beschreibung. Muss wohl eigentlich WERT%256 (für die Minuten) heissen

Kannst es auch shiften ... wenn Du nen eher kryptischen Einzeiler willst:
(t wäre der Wert für die Zeit aus der GetState.csv)

Code: Alles auswählen

wert = ((t>>8)<10?0:'')+''+(t>>8)+':'+((t&0xFF)<10?0:'')+''+(t&0xFF);
Stellt auch die Stunden mit führender 0 dar, wenn kleiner 10
https://jsfiddle.net/63zs43fy/

Sven
Beiträge: 24
Registriert: 19. Juli 2015, 19:48

Re: Anbindung an IOBROKER

Beitrag von Sven »

@Michael danke für die Info, freut mich das es funktioniert, leider sind die Bilder so klein das man kaum etwas erkennen kann. Kannst Du denn mit den Daten so arbeiten oder sollte noch etwas anders sein?

@Alex Danke für den Einzeiler, ich verstehe Ihn zwar nicht aber hab den jetzt mal ins Script eingebaut.
Der Test mut modulo256 war auch erfolgreich. Doku müsste dann mal angepasst werden ;)

Hier die aktuelle Version mit berechneter Uhrzeit

Code: Alles auswählen

/**************************************************************************** 
*                                                                           * 
*  Script zum einlesen der GetState.csv vom PoolController in IOBroker      *
*  Wichtig: Die Namen im Controller dürfen kein Punkte enthalten !!!        *
*  Also es darf kein "n.a." verwendet werden Leerzeichen werden für         *
*  IOBroker durch Unterstriche ersetzt.                                     *
*  Die URL muss entsprechend auf die IP des PoolController angepasst werden *
*                                                                           *
*  Funktion:                                                                *
*  Beim Skript start werden die Namen eingelesen und dann als Objekt unter  *
*  Javascript.0.Poolcontroller.XXX angelegt. Die Einheiten werden auch      *
*  automatisch zugeordnet. Danach wird alle 30 Sekunden die GetState.csv    *
*  abgerufen und die Variablen werden in IOBroker Objekte geschrieben       *
*  Die Berechnug offset + ( gain * value) erfolgt bereits in diesem Script  *
*                                                                          
*  Version 0.2
****************************************************************************/

var url='http://192.168.X.X:8080/GetState.csv'

//*********************************************************************
var result, json;
var stateanlegen = true;

//SYSINFO Variablen anlegen
       createState('javascript.0.PoolController.SYSINFO.VERSION', {
        name: 'VERSION',
        type: 'string',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.CPU_TIME', {
        name: 'CPU_TIME',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.RESET_ROOT_CAUSE', {
        name: 'RESET_ROOT_CAUSE',
        type: 'number',
        write: false,
        read:  true
        });
         createState('javascript.0.PoolController.SYSINFO.NTP_FAULT_STATE', {
        name: 'NTP_FAULT_STATE',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.CONFIG_OTHER_ENABLE', {
        name: 'CONFIG_OTHER_ENABLE',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.DOSAGE_CNTRL', {
        name: 'DOSAGE_CNTRL',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.pH+_DOSAGE_RELAIS_ID', {
        name: 'pH+_DOSAGE_RELAIS_ID',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.pH-_DOSAGE_RELAIS_ID', {
        name: 'pH-_DOSAGE_RELAIS_ID',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.Chlor_DOSAGE_RELAIS_ID', {
        name: 'Chlor_DOSAGE_RELAIS_ID',
        type: 'number',
        write: false,
        read:  true
        });


//alle 30 Sekunden Werte neu einlesen
schedule("*/30 * * * * *", function () {
  try {
    require("request")(url, function (error, response, result) {
   //   console.log(result);
    result = result.replace(/ /g, '_');  //alle Leerzeichen durch Unterstrich ersetzten
    var data=CSVToArray(result);         //CSV in ein Array einlesen
    json = JSON.stringify(data);         //Array in einen String formatieren
    var jdata = JSON.parse(json);        //Json Array erzeugen
    var arr1 = jdata[0];                 // Array 0 von ingesamt 6, weil 6 Zeilen im CVS mit \n getrennt
    var arr2 = jdata[1];                 // Array 1-5 haben je 42 einzelne  Daten
    var arr3 = jdata[2];
    var arr4 = jdata[3];
    var arr5 = jdata[4];
    var arr6 = jdata[5];
   
/** Debug Ausgaben der Arrays
    console.log(arr1);
    console.log(arr2);
    console.log(arr3);
    console.log(arr4);
    console.log(arr5);
    console.log(arr6);
 */

  if (stateanlegen === true){
    // User Variablen anlegen Achtung keine Punkte im Namen verwenden. 
    var i=0;
    for (i=0; i<=41;i++){
        if (i===0){
        createState('javascript.0.PoolController.'+jdata[1][i],'', {
        name: ''+jdata[1][i],
        type: 'string',
        write: false,
        read:  true
        });
        }
        else{
        createState('javascript.0.PoolController.'+jdata[1][i],'', {
        name: ''+jdata[1][i],
        type: 'number',
        unit: ''+jdata[2][i],
        write: false,
        read:  true
        });
        }
    }
    console.log("Variablen angelegt");
    stateanlegen = false;
  }
  else {
  
  //SYSINFO Variablen mit aktuellen Werten beschreiben 
    setState('javascript.0.PoolController.SYSINFO.VERSION', jdata[0][1]);
    setState('javascript.0.PoolController.SYSINFO.CPU_TIME', parseFloat(Number(jdata[0][2]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.RESET_ROOT_CAUSE', parseFloat(Number(jdata[0][3]).toFixed(2))); 
    setState('javascript.0.PoolController.SYSINFO.NTP_FAULT_STATE', parseFloat(Number(jdata[0][4]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.CONFIG_OTHER_ENABLE', parseFloat(Number(jdata[0][5]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.DOSAGE_CNTRL', parseFloat(Number(jdata[0][6]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.pH+_DOSAGE_RELAIS_ID', parseFloat(Number(jdata[0][7]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.pH-_DOSAGE_RELAIS_ID', parseFloat(Number(jdata[0][8]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.Chlor_DOSAGE_RELAIS_ID', parseFloat(Number(jdata[0][9]).toFixed(2)));
  
  
   // User Variablen mit aktuellen Werten beschreiben
   i=0; 
    for (i=0; i<=41;i++){
        //var wert = offset + ( gain * value);
    	var offset =  parseFloat(jdata[3][i]);
    	var gain =   parseFloat(jdata[4][i]);
    	var value =   parseFloat(jdata[5][i]);
      	var wert =  offset + ( gain * value);
      
      	if (i===0) {
      	    wert = ((wert>>8)<10?0:'')+''+(wert>>8)+':'+((wert&0xFF)<10?0:'')+''+(wert&0xFF);
      	  /**  var hour = (wert/256).toFixed(0);
      	    var minute = (wert%256).toFixed(0);
      	   if (minute <10){
      	       wert = (hour+':0'+minute);
      	   }
      	   else{
      	        wert = (hour+':'+minute);
      	   }*/
      	   setState('javascript.0.PoolController.Time',wert);
      	}
      	else{
        setState('javascript.0.PoolController.'+jdata[1][i], parseFloat(Number(wert).toFixed(2)));
      	}
      	    
      	}    
    console.log("Variablen updated");
  }
    }).on("error", function (e) {console.error(e);});
  } catch (e) { console.error(e); }
});


/**
* Javascript CSV To Array
*/

function CSVToArray( strData, strDelimiter ){
    // Check to see if the delimiter is defined. If not,
    // then default to comma.
    strDelimiter = (strDelimiter || ",");

    // Create a regular expression to parse the CSV values.
    var objPattern = new RegExp(
        (
            // Delimiters.
            "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +

            // Quoted fields.
            "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +

            // Standard fields.
            "([^\"\\" + strDelimiter + "\\r\\n]*))"
        ),
        "gi"
        );


    // Create an array to hold our data. Give the array
    // a default empty first row.
    var arrData = [[]];

    // Create an array to hold our individual pattern
    // matching groups.
    var arrMatches = null;


    // Keep looping over the regular expression matches
    // until we can no longer find a match.
    while (arrMatches = objPattern.exec( strData )){

        // Get the delimiter that was found.
        var strMatchedDelimiter = arrMatches[ 1 ];

        // Check to see if the given delimiter has a length
        // (is not the start of string) and if it matches
        // field delimiter. If id does not, then we know
        // that this delimiter is a row delimiter.
        if (
            strMatchedDelimiter.length &&
            strMatchedDelimiter !== strDelimiter
            ){

            // Since we have reached a new row of data,
            // add an empty row to our data array.
            arrData.push( [] );

        }

        var strMatchedValue;

        // Now that we have our delimiter out of the way,
        // let's check to see which kind of value we
        // captured (quoted or unquoted).
        if (arrMatches[ 2 ]){

            // We found a quoted value. When we capture
            // this value, unescape any double quotes.
            strMatchedValue = arrMatches[ 2 ].replace(
                new RegExp( "\"\"", "g" ),
                "\""
                );

        } else {

            // We found a non-quoted value.
            strMatchedValue = arrMatches[ 3 ];

        }


        // Now that we have our value string, let's add
        // it to the data array.
        arrData[ arrData.length - 1 ].push( strMatchedValue );
    }

    // Return the parsed data.
    return( arrData );
}


Benutzeravatar
Alex
Administrator
Beiträge: 9988
Registriert: 28. Mai 2014, 23:00

Re: Anbindung an IOBROKER

Beitrag von Alex »

Doku hab ich schon upgedatet.

>>..., ich verstehe Ihn zwar nicht aber hab den jetzt mal ins Script eingebaut. ...
Macht nix, ich auch nicht :mrgreen:

Die shifterei is wohl eigentlich das "kryptische". Die Zahl die der Controller ausgibt ist eigentlich ein binärer-Wert...
als Beispiel aus dem fiddle-link hatte ich t=4662 verwendet
4662 (Dezimal) == 0001 0010 0011 0110 (Binär). Die ersten 8 Bit sind die Stunden, die zweiten 8 die Minuten

t>>8 shiftet 8 bits nach rechts... (schiebt von links 8 0-en rein) ... es bleibt:
0000 0000 0001 0010 (Binär) == 18 (Dezimal) (das fette waren vorher die ersten 8 Bit)

t&0xFF verwendet die letzten 8 Bit ("überschreibt" die ersten 8 mit 0-en)
0000 0000 0011 0110 (Binär) == 54 (Dezimal)
Uhrzeit ist also 18:54

result = i<10 ? 0:1
Das ist quasi ein if/else... wenn i<10 = true, dann wird "result" 0 (das was vor dem ":" kommt); Wenn i<10 = false; wird "result" 1 (das was nach dem ":" kommt)
In der Codezeile gibt es halt keine 1 sondern nur zwei '' (für "nix" - denn einfach leer lassen geht ja nicht, deswegen '').

wert = ((t>>8) < 10 ? 0:'') +''+ (t>>8)+':'+((t&0xFF)<10?0:'')+''+(t&0xFF);
Ist t>>8 kleiner 10, schreibe eine 0 und schreib dann das Ergebnis von t>>8 dazu.... dann ein ":" usw...
Ist t>>8 nicht kleiner 0, schreibe "nix" und schreib dann das Ergebnis von t>>8 dazu ....

michaelv
Beiträge: 60
Registriert: 6. Januar 2015, 17:03

Re: Anbindung an IOBROKER

Beitrag von michaelv »

Hallo Sven,

ja ich kann damit arbeiten, ich hole mir die Daten aber schon über den Fhem Adapter in den IO-Broker.

Ich bekomme aber im Log immer einen Error obwohl alles ok ist

host.debian 2018-01-08 09:24:00.214 error instance system.adapter.javascript.0 terminated with code 0 (OK)

Vielleicht kannst du ja daraus auch einen Adapter bauen.

Gruß Michael

Sven
Beiträge: 24
Registriert: 19. Juli 2015, 19:48

Re: Anbindung an IOBROKER

Beitrag von Sven »

ja ich kann damit arbeiten, ich hole mir die Daten aber schon über den Fhem Adapter in den IO-Broker.
Ja das hatte ich auch erst so, aber ich habe Fhem inzwischen abgeschaltet, deshalb jetzt dieser Weg.
host.debian 2018-01-08 09:24:00.214 error instance system.adapter.javascript.0 terminated with code 0 (OK)
Kann es sein das Du das Script unter Global angelegt hast? Da darf es nämlich nicht rein.
Vielleicht kannst du ja daraus auch einen Adapter bauen.
Ich fürchte dafür reichen meine anfänglichen Javascript Kentnisse (noch ) nicht aus ;)

Und als Javascript macht es ja genau was es soll :mrgreen:
Gruß
Sven

Benutzeravatar
Raffke
Beiträge: 80
Registriert: 20. Juni 2016, 22:19

Re: Anbindung an IOBROKER

Beitrag von Raffke »

Vielen Dank, Herr Namensvetter!

Ich habe ja schon an anderer Stelle erwähnt, dass ich mit dem Vorgänger CCU.IO arbeite und wollte das Script jetzt mal übernehmen.
Dazu dann aber gleich ein paar Fragen oder Anmerkungen:

1. Wozu erst das CSV in ein Array, dann in ein JSON und zuletzt wieder in ein Array umwandeln? Sind die letzten 2 Schritte nicht überflüssig?

Code: Alles auswählen

    var data=CSVToArray(result);         //CSV in ein Array einlesen
    json = JSON.stringify(data);         //Array in einen String formatieren
    var jdata = JSON.parse(json);        //Json Array erzeugen
2. Im ersten Durchlauf werden nur die Variablen angelegt, noch nicht die Werte gesetzt - ist das Absicht? Ansonsten würde ich das "else" einfach rausnehmen:

Code: Alles auswählen

    console.log("Variablen angelegt");
    stateanlegen = false;
  }
  else {
@michaelv:
Für CCU.IO habe ich schon Adapter geschrieben, im Groben sollte das für IoBroker ähnlich funktionieren - mir erschließt sich hier aber der Sinn (noch) nicht so wirklich...
Welchen Vorteil würdest du dir davon versprechen? Sollte dann variabel sein, welche Werte er als Datenpunkte erstellt? Und/oder mehrere PoolController unterstützen?

Sven
Beiträge: 24
Registriert: 19. Juli 2015, 19:48

Re: Anbindung an IOBROKER

Beitrag von Sven »

Hallo Sven,
1. Wozu erst das CSV in ein Array, dann in ein JSON und zuletzt wieder in ein Array umwandeln? Sind die letzten 2 Schritte nicht überflüssig?
Das ich keine Programmier Leuchte bin hatte ich auch bereits erwähnt :lol:
Für mich ist es einfacher mit einem JSON formatierten Array zu arbeiten weil ich dann an exakter stelle auf die Daten zugreifen kann [data] wie das in einem CSV Array geht, keine Ahnung ;)
2. Im ersten Durchlauf werden nur die Variablen angelegt, noch nicht die Werte gesetzt
Ja das ist Absicht, weil bei ersten Durchlauf vor einem setstate erstmal die Variable da sein muss, dafür wird sie beim ersten Start des scriptes aus dem Array gelesen und dann mit createstate erzeugt.
Danach werden nur noch die Daten mit setstate geändert.

Ich hoffe das konnte deine Fragen beantworten.
Du darfst das Script aber gerne optimieren, wenns was besseres gibt baue ich das genre bei mir ein, aktuell kann ich damit ganz gut leben :D

Viele Grüße
Sven

michaelv
Beiträge: 60
Registriert: 6. Januar 2015, 17:03

Re: Anbindung an IOBROKER

Beitrag von michaelv »

Hallo

den Adapter habe ich bereits entwickelt siehe https://www.poolsteuerung.de/viewtopic.php?f=29&t=841

hier habe ich auch schon Feedback erhalten und konnte davon einiges in den Adapter übernehmen. Sysinfo Variablen sind ausgelagert und werden bei
der Installation des Adapters erzeugt.
Den Vorteil den ich mit dem Adapter sehe ist eine gemeinsame Weiterentwicklung und der Adapter ist für Leute die nicht scripten halt einfacher zu integrieren.
Ich möchte hier auch noch das schalten von den Relais einbauen.
Es wäre super wenn ihr den Adapter testen könntet und mir Feedback geben könntet.

Gruß Michael

Benutzeravatar
Raffke
Beiträge: 80
Registriert: 20. Juni 2016, 22:19

Re: Anbindung an IOBROKER

Beitrag von Raffke »

Ah, gut Michael.
Ich habe leider aktuell kein installiertes IoBroker - die Poolrestarbeiten sind aktuell wichtiger. :-)

Wenn du Unterstützung bei der Umsetzung der asynchronen Abarbeitung brauchst, sag kurz Bescheid - wenn du selbst daran arbeitest bzw. dich einarbeitest, bleibe ich als stiller Beobachter im Hintergrund. :-)

Sven
Beiträge: 24
Registriert: 19. Juli 2015, 19:48

Re: Anbindung an IOBROKER

Beitrag von Sven »

Hallo,
für den IoBroker Adapter von Michael habe ich hier mal meine aktuelle Version mit vielen Verbessungen und Vorbereitungen zum Relay Status ändern.

Code: Alles auswählen

/**************************************************************************** 
*  Version 0.3                                                                   * 
*  Script zum einlesen der GetState.csv vom PoolController in IOBroker      *
*  Wichtig: Die Namen im Controller dürfen kein Punkte enthalten !!!        *
*  Also es darf kein "n.a." verwendet werden Leerzeichen werden für         *
*  IOBroker durch Unterstriche ersetzt.                                     *
*  Die URL muss entsprechend auf die IP des PoolController angepasst werden *
*                                                                           *
*  Funktion:                                                                *
*  Beim Skript start werden die Namen eingelesen und dann als Objekt unter  *
*  Javascript.0.Poolcontroller.XXX angelegt. Die Einheiten werden auch      *
*  automatisch zugeordnet. Danach wird alle 30 Sekunden die GetState.csv    *
*  abgerufen und die Variablen werden in IOBroker Objekte geschrieben       *
*  Die Berechnug offset + ( gain * value) erfolgt bereits in diesem Script  *
*                                                                           *
****************************************************************************/

var url='http://192.168.xx.xx:8080/GetState.csv'

//*********************************************************************
var result, json;
var stateanlegen = true;

//alle 30 Sekunden Werte neu einlesen
schedule("*/30 * * * * *", function () {
  ReadData();
});

// Abfrage der VIS_Buttons Relais Status
on({id: "javascript.0.PoolController.visButtons.Relais0", change: "ne"}, function (obj) {
  var value = obj.state.val;
  var oldValue = obj.oldState.val;
  visButtonChanged(0);
});
on({id: "javascript.0.PoolController.visButtons.Relais1", change: "ne"}, function (obj) {
  var value = obj.state.val;
  var oldValue = obj.oldState.val;
  visButtonChanged(1);
});
on({id: "javascript.0.PoolController.visButtons.Relais2", change: "ne"}, function (obj) {
  var value = obj.state.val;
  var oldValue = obj.oldState.val;
  visButtonChanged(2);
});
on({id: "javascript.0.PoolController.visButtons.Relais3", change: "ne"}, function (obj) {
  var value = obj.state.val;
  var oldValue = obj.oldState.val;
  visButtonChanged(3);
});
on({id: "javascript.0.PoolController.visButtons.Relais4", change: "ne"}, function (obj) {
  var value = obj.state.val;
  var oldValue = obj.oldState.val;
  visButtonChanged(4);
});
on({id: "javascript.0.PoolController.visButtons.Relais5", change: "ne"}, function (obj) {
  var value = obj.state.val;
  var oldValue = obj.oldState.val;
  visButtonChanged(5);
});
on({id: "javascript.0.PoolController.visButtons.Relais6", change: "ne"}, function (obj) {
  var value = obj.state.val;
  var oldValue = obj.oldState.val;
  visButtonChanged(6);
});
on({id: "javascript.0.PoolController.visButtons.Relais7", change: "ne"}, function (obj) {
  var value = obj.state.val;
  var oldValue = obj.oldState.val;
  visButtonChanged(7);
});
on({id: "javascript.0.PoolController.visButtons.Relais8", change: "ne"}, function (obj) {
  var value = obj.state.val;
  var oldValue = obj.oldState.val;
  visButtonChanged(8);
});
on({id: "javascript.0.PoolController.visButtons.Relais9", change: "ne"}, function (obj) {
  var value = obj.state.val;
  var oldValue = obj.oldState.val;
  visButtonChanged(9);
});
on({id: "javascript.0.PoolController.visButtons.Relais10", change: "ne"}, function (obj) {
  var value = obj.state.val;
  var oldValue = obj.oldState.val;
  visButtonChanged(10);
});
on({id: "javascript.0.PoolController.visButtons.Relais11", change: "ne"}, function (obj) {
  var value = obj.state.val;
  var oldValue = obj.oldState.val;
  visButtonChanged(11);
});
on({id: "javascript.0.PoolController.visButtons.Relais12", change: "ne"}, function (obj) {
  var value = obj.state.val;
  var oldValue = obj.oldState.val;
  visButtonChanged(12);
});
on({id: "javascript.0.PoolController.visButtons.Relais13", change: "ne"}, function (obj) {
  var value = obj.state.val;
  var oldValue = obj.oldState.val;
  visButtonChanged(13);
});
on({id: "javascript.0.PoolController.visButtons.Relais14", change: "ne"}, function (obj) {
  var value = obj.state.val;
  var oldValue = obj.oldState.val;
  visButtonChanged(14);
});
on({id: "javascript.0.PoolController.visButtons.Relais15", change: "ne"}, function (obj) {
  var value = obj.state.val;
  var oldValue = obj.oldState.val;
  visButtonChanged(15);
});


function visButtonChanged(relaisNumber){
    ReadData();
    var visRelaisState = getState('javascript.0.PoolController.visButtons.Relais'+relaisNumber).val;
   // console.log(visRelaisState);
    var relaisState = getState('javascript.0.PoolController.Relais'+relaisNumber).val;
   // console.log(visRelaisState);
    if (visRelaisState != relaisState){
        var ena,state;
        console.log("Status Relais ändern");
        if (visRelaisState===0 && relaisState > 1){
            // 00 = 0 Aus / Automatik
             ena = 0 & ~(0x01<< relaisNumber);
             state = 0 & ~(0x01<< relaisNumber )
        }
        
        if (visRelaisState===1 && relaisState ===3){
            // 01 = 1 Aus / Manuell
             ena = 0 & ~(0x01<< relaisNumber);
             state = 1 |(0x01<< relaisNumber)
        }
        if (visRelaisState===2){
            // 10 = 2 Ein / Automatik
            ena = 1 | (0x01<< relaisNumber)
             state = 0 & ~(0x01<< relaisNumber)
        }
        if (visRelaisState===3){
            // 11 = 3 Ein / Manuell
             ena = 1 | (0x01<< relaisNumber)
             state = 1 |(0x01<< relaisNumber)
        }
        console.log('Relais: '+ena);
        console.log('State: '+state);
    }
    else{
        console.log("Kein Änderung nötig");
    }
    
/**
00 = 0 Aus / Automatik
01 = 1 Aus / Manuell
10 = 2 Ein / Automatik
11 = 3 Ein / Manuell
den Status holen und das passende Relais bit maskieren ( entweder löschen oder setzen)
löschen = ena = ena & ~(0x01<< RELAIS ) // mit Relais von 0..15)
setzen = ena = ena | (0x01<< RELAIS ) // mit Relais von 0..15)

das Gleiche für State
löschen = state = state & ~(0x01<< RELAIS ) // mit Relais von 0..15)
setzen = state = state | (0x01<< RELAIS ) // mit Relais von 0..15)**/
    
}

function ReadData(){
    try {
    require("request")(url, function (error, response, result) {
     // console.log(result);
    result = result.replace(/ /g, '_');  //alle Leerzeichen durch Unterstrich ersetzten
    var data=CSVToArray(result);         //CSV in ein Array einlesen
    json = JSON.stringify(data);         //Array in einen String formatieren
    var jdata = JSON.parse(json);        //Json Array erzeugen
    var arr1 = jdata[0];                 // Array 0 von ingesamt 6, weil 6 Zeilen im CVS mit \n getrennt
    var arr2 = jdata[1];                 // Array 1-5 haben je 42 einzelne  Daten
    var arr3 = jdata[2];
    var arr4 = jdata[3];
    var arr5 = jdata[4];
    var arr6 = jdata[5];
   
//Debug Ausgaben der Arrays
  /*console.log(arr1);
    console.log(arr2);
    console.log(arr3);
    console.log(arr4);
    console.log(arr5);
    console.log(arr6);
 */

  if (stateanlegen === true){

//SYSINFO Variablen anlegen
       createState('javascript.0.PoolController.SYSINFO.VERSION', {
        name: 'VERSION',
        type: 'string',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.CPU_TIME', {
        name: 'CPU_TIME',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.RESET_ROOT_CAUSE', {
        name: 'RESET_ROOT_CAUSE',
        type: 'number',
        write: false,
        read:  true
        });
         createState('javascript.0.PoolController.SYSINFO.NTP_FAULT_STATE', {
        name: 'NTP_FAULT_STATE',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.CONFIG_OTHER_ENABLE', {
        name: 'CONFIG_OTHER_ENABLE',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.DOSAGE_CNTRL', {
        name: 'DOSAGE_CNTRL',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.pH+_DOSAGE_RELAIS_ID', {
        name: 'pH+_DOSAGE_RELAIS_ID',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.pH-_DOSAGE_RELAIS_ID', {
        name: 'pH-_DOSAGE_RELAIS_ID',
        type: 'number',
        write: false,
        read:  true
        });
        createState('javascript.0.PoolController.SYSINFO.Chlor_DOSAGE_RELAIS_ID', {
        name: 'Chlor_DOSAGE_RELAIS_ID',
        type: 'number',
        write: false,
        read:  true
        });
    // User Variablen anlegen Achtung keine Punkte im Namen verwenden. 
    var i=16;
      
    for (i=16; i<=23;i++){
        createState('javascript.0.PoolController.visButtons.Relais'+[i-16],'', {
        name: ''+jdata[1][i],
        type: 'number',
        write: true,
        read:  true
        });
       }
       i=28;
       for (i=28; i<=35;i++){
        createState('javascript.0.PoolController.visButtons.Relais'+[i-20],'', {
        name: ''+jdata[1][i],
        type: 'number',
        write: true,
        read:  true
        });
        }
     i=0;
    for (i=0; i<=41;i++){
        if (i===0){
        createState('javascript.0.PoolController.'+jdata[1][i],'', {
        name: ''+jdata[1][i],
        type: 'string',
        write: false,
        read:  true
        });
        }
        if (i>=1 && i<=5){
        createState('javascript.0.PoolController.ADC'+[i-1],'', {
        name: ''+jdata[1][i],
        type: 'number',
        unit: ''+jdata[2][i],
        write: false,
        read:  true
        });
        }
        if (i===6){
        createState('javascript.0.PoolController.Redox', {
        name: ''+jdata[1][i],
        type: 'number',
        unit: ''+jdata[2][i],
        write: false,
        read:  true
        });
        }
        if (i===7){
        createState('javascript.0.PoolController.pH', {
        name: ''+jdata[1][i],
        type: 'number',
        unit: ''+jdata[2][i],
        write: false,
        read:  true
        });
        }
        if (i>=8 && i<=15){
        createState('javascript.0.PoolController.Temperatur'+[i-7],'', {
        name: ''+jdata[1][i],
        type: 'number',
        unit: ''+jdata[2][i],
        write: false,
        read:  true
        });
        }
        if (i>=16 && i<=23){
        createState('javascript.0.PoolController.Relais'+[i-16],'', {
        name: ''+jdata[1][i],
        type: 'number',
        unit: ''+jdata[2][i],
        write: false,
        read:  true
        });
        }
        if (i>=24 && i<=27){
        createState('javascript.0.PoolController.Digital_Input'+[i-23],'', {
        name: ''+jdata[1][i],
        type: 'number',
        unit: ''+jdata[2][i],
        write: false,
        read:  true
        });
        }
        if (i>=28 && i<=35){
        createState('javascript.0.PoolController.Relais'+[i-20],'', {
        name: ''+jdata[1][i],
        type: 'number',
        unit: ''+jdata[2][i],
        write: false,
        read:  true
        });
        }
        if (i===36){
        createState('javascript.0.PoolController.CL_Rest', {
        name: ''+jdata[1][i],
        type: 'number',
        unit: ''+jdata[2][i],
        write: false,
        read:  true
        });
        }
        if (i===37){
        createState('javascript.0.PoolController.pH-_Rest', {
        name: ''+jdata[1][i],
        type: 'number',
        unit: ''+jdata[2][i],
        write: false,
        read:  true
        });
        }
        if (i===38){
        createState('javascript.0.PoolController.pH+_Rest', {
        name: ''+jdata[1][i],
        type: 'number',
        unit: ''+jdata[2][i],
        write: false,
        read:  true
        });
        }
        if (i===39){
        createState('javascript.0.PoolController.Cl_consumption', {
        name: ''+jdata[1][i],
        type: 'number',
        unit: ''+jdata[2][i],
        write: false,
        read:  true
        });
        }
        if (i===40){
        createState('javascript.0.PoolController.pH-_consumption', {
        name: ''+jdata[1][i],
        type: 'number',
        unit: ''+jdata[2][i],
        write: false,
        read:  true
        });
        }
         if (i===41){
        createState('javascript.0.PoolController.pH+_consumption', {
        name: ''+jdata[1][i],
        type: 'number',
        unit: ''+jdata[2][i],
        write: false,
        read:  true
        });
        }
    }
    console.log("Variablen angelegt");
    stateanlegen = false;
  }
  else {
  
  //SYSINFO Variablen mit aktuellen Werten beschreiben 
    setState('javascript.0.PoolController.SYSINFO.VERSION', jdata[0][1]);
    setState('javascript.0.PoolController.SYSINFO.CPU_TIME', parseFloat(Number(jdata[0][2]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.RESET_ROOT_CAUSE', parseFloat(Number(jdata[0][3]).toFixed(2))); 
    setState('javascript.0.PoolController.SYSINFO.NTP_FAULT_STATE', parseFloat(Number(jdata[0][4]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.CONFIG_OTHER_ENABLE', parseFloat(Number(jdata[0][5]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.DOSAGE_CNTRL', parseFloat(Number(jdata[0][6]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.pH+_DOSAGE_RELAIS_ID', parseFloat(Number(jdata[0][7]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.pH-_DOSAGE_RELAIS_ID', parseFloat(Number(jdata[0][8]).toFixed(2)));
    setState('javascript.0.PoolController.SYSINFO.Chlor_DOSAGE_RELAIS_ID', parseFloat(Number(jdata[0][9]).toFixed(2)));
  
  
   // User Variablen mit aktuellen Werten beschreiben
   i=0; 
    for (i=0; i<=41;i++){
        //var wert = offset + ( gain * value);
    	var offset =  parseFloat(jdata[3][i]);
    	var gain =   parseFloat(jdata[4][i]);
    	var value =   parseFloat(jdata[5][i]);
      	var wert =  offset + ( gain * value);
      
      	if (i===0) {
      	    wert = ((wert>>8)<10?0:'')+''+(wert>>8)+':'+((wert&0xFF)<10?0:'')+''+(wert&0xFF);
      	  /**  var hour = (wert/256).toFixed(0);
      	    var minute = (wert%256).toFixed(0);
      	   if (minute <10){
      	       wert = (hour+':0'+minute);
      	   }
      	   else{
      	        wert = (hour+':'+minute);
      	   }*/
      	   setState('javascript.0.PoolController.Time',wert);
      	}
      	if (i>=1 && i<=5){
            setState('javascript.0.PoolController.ADC'+[i-1], parseFloat(Number(wert).toFixed(2)));
      	}
      	if (i===6){
      	    setState('javascript.0.PoolController.Redox', parseFloat(Number(wert).toFixed(2)));
      	}
        if (i===7){
        	setState('javascript.0.PoolController.pH', parseFloat(Number(wert).toFixed(2)));
      	}
        if (i>=8 && i<=15){
            setState('javascript.0.PoolController.Temperatur'+[i-7], parseFloat(Number(wert).toFixed(2)));  
        }
        if (i>=16 && i<=23){
            setState('javascript.0.PoolController.Relais'+[i-16], parseFloat(Number(wert).toFixed(2)));  
        }
        if (i>=24 && i<=27){   
            setState('javascript.0.PoolController.Digital_Input'+[i-23], parseFloat(Number(wert).toFixed(2)));  
        }
        if (i>=28 && i<=35){
            setState('javascript.0.PoolController.Relais'+[i-20], parseFloat(Number(wert).toFixed(2)));   
        }
        if (i===36){
           setState('javascript.0.PoolController.CL_Rest', parseFloat(Number(wert).toFixed(2)));   
        }
        if (i===37){
            setState('javascript.0.PoolController.pH-_Rest', parseFloat(Number(wert).toFixed(2)));   
        }
      	if (i===38){
      	    setState('javascript.0.PoolController.pH+_Rest', parseFloat(Number(wert).toFixed(2)));  
      	}
      	if (i===39){
      	    setState('javascript.0.PoolController.Cl_consumption', parseFloat(Number(wert).toFixed(2))); 
      	}
      	if (i===40){
      	     setState('javascript.0.PoolController.pH-_consumption', parseFloat(Number(wert).toFixed(2)));
      	}
      	if (i===41){
      	    setState('javascript.0.PoolController.pH+_consumption', parseFloat(Number(wert).toFixed(2)));
      	}
      	}    
 //   console.log("Variablen updated");
  }
    }).on("error", function (e) {console.error(e);});
  } catch (e) { console.error(e); }
}

/**
* Javascript Transmit Function to set 16 Bit Relais Status
*/

function TransmitPost(relaisNumber, relaisStatus)
{
  var i; var ena; var state;
  ena = 0;
  state = 0;
  //window.clearInterval(timerHandle);
  //timerHandle = 0;
  //with(document)
  {
    for(i=0;i<16;i++)
      {
	if(relaisNumber.val == "2")
	{
	  ena |= 0x0001<<i;
	}
	else if(getElementById("IR"+i+"_0").value == "true")
	{
	  ena |= 0x0001<< i;
	  state |= 0x0001<< i;
	}
      }
  }
  PostBuffer = "ENA="+ena+","+state+"&MANUAL=1";
  //AjaxPostRequest("usrcfg.cgi",PostBuffer,Call);
}



/**
* Javascript CSV To Array
*/

function CSVToArray( strData, strDelimiter ){
    // Check to see if the delimiter is defined. If not,
    // then default to comma.
    strDelimiter = (strDelimiter || ",");

    // Create a regular expression to parse the CSV values.
    var objPattern = new RegExp(
        (
            // Delimiters.
            "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +

            // Quoted fields.
            "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +

            // Standard fields.
            "([^\"\\" + strDelimiter + "\\r\\n]*))"
        ),
        "gi"
        );


    // Create an array to hold our data. Give the array
    // a default empty first row.
    var arrData = [[]];

    // Create an array to hold our individual pattern
    // matching groups.
    var arrMatches = null;


    // Keep looping over the regular expression matches
    // until we can no longer find a match.
    while (arrMatches = objPattern.exec( strData )){

        // Get the delimiter that was found.
        var strMatchedDelimiter = arrMatches[ 1 ];

        // Check to see if the given delimiter has a length
        // (is not the start of string) and if it matches
        // field delimiter. If id does not, then we know
        // that this delimiter is a row delimiter.
        if (
            strMatchedDelimiter.length &&
            strMatchedDelimiter !== strDelimiter
            ){

            // Since we have reached a new row of data,
            // add an empty row to our data array.
            arrData.push( [] );

        }

        var strMatchedValue;

        // Now that we have our delimiter out of the way,
        // let's check to see which kind of value we
        // captured (quoted or unquoted).
        if (arrMatches[ 2 ]){

            // We found a quoted value. When we capture
            // this value, unescape any double quotes.
            strMatchedValue = arrMatches[ 2 ].replace(
                new RegExp( "\"\"", "g" ),
                "\""
                );

        } else {

            // We found a non-quoted value.
            strMatchedValue = arrMatches[ 3 ];

        }


        // Now that we have our value string, let's add
        // it to the data array.
        arrData[ arrData.length - 1 ].push( strMatchedValue );
    }

    // Return the parsed data.
    return( arrData );
}

Mir wäre auch an einem Adapter gelegen, deshalb habe ich mal angefangen mein script auf michales Adapter zu portieren.
Gruß
Sven

Sven
Beiträge: 24
Registriert: 19. Juli 2015, 19:48

Re: Anbindung an IOBROKER

Beitrag von Sven »

Hallo,
wer meine Version des angepassten ioBroker Adapter von Michael testen mag, sollte hier schauen..
https://github.com/svenp/ioBroker.poolcontroller

Aber immer bedenken, das ist die aktuelle Entwicklung, Fehler können vorhanden sein....

Gruß
Sven

mcmuller
Beiträge: 14
Registriert: 10. Juli 2015, 09:31

Re: Anbindung an IOBROKER

Beitrag von mcmuller »

Bom Dia,

...gerade mal über die 0.2.3 installiert. Sieht gut aus, alle Custom-Names übernommen und die Werte da - DANKE dafür! Controller-Version hier noch 1.6.9

Grüße,
mcmuller

Sven
Beiträge: 24
Registriert: 19. Juli 2015, 19:48

Re: Anbindung an IOBROKER

Beitrag von Sven »

Hallo,

heute einge Änderungen im github übernommen.
Betrifft nur Kompatibilität zur aktuellen iobroker Version.
Ansonsten leider noch keine neuen Funktionen.
https://github.com/svenp/ioBroker.poolcontroller


Gruß
Sven

wburst
Beiträge: 28
Registriert: 7. Dezember 2018, 16:35

Re: Anbindung an IOBROKER

Beitrag von wburst »

Schade das es das nicht für NodeRed gibt. Die Ankopplung an KNX ist hier meiner Meinung nach wesentlich besser.

Benutzeravatar
Raffke
Beiträge: 80
Registriert: 20. Juni 2016, 22:19

Re: Anbindung an IOBROKER

Beitrag von Raffke »

Eigentlich hat doch Sven hier super Vorarbeit geleistet!
Und wenn ich das richtig sehe, läuft NodeRed doch auch mit JavaScript/Node - da müsste sich doch das Script hier super als Vorlage eignen, eine eigene Anbindung zu basteln?!

Sven
Beiträge: 24
Registriert: 19. Juli 2015, 19:48

Re: Anbindung an IOBROKER

Beitrag von Sven »

Hallo,

@wburst
Ich hatte bis jetzt noch keine Berührung mit NodeRed und schon garnicht mit KNX, da mich die hohen Preise immer abgeschreckt haben.
Deshalb kann ich Dir da leider nicht weiter helfen.
Wie aber Raffke schon schrieb.....
Du kannst gerne aus meiner Vorarbeit einen Node-Red/KNX Adapter entwickeln ;)

Eine Info noch für alle:

Der Adapter läuft auch mit der kommenden js-controller 2.0 Version. Aktuell 2.0.17
Hier wurde "unter der Haube" einiges in Sachen Kommunikation (socket.io/TCP)verändert....
Das habe ich heute mal getestet....
Einem ioBroker "Latest" Update steht also in ca. 14 Tagen nichts im Wege.

Viele Grüße
Sven