NEWS

IoBroker mit HA Bridge synchronsieren



  • Hallo zusammen,

    ich habe ein Script geschrieben mit welchem ich Geräte in HA Bridge bequemer anlegen kann.

    Kurze Faktenübersicht:

    • Der Name des Gerätes wird aus common.smartName.de ausgelesen (gleicher Name wie im Cloud-Adapter)

    • Im Script muss angepasst werden:

    – Das Array "objects"

    -- habridgeURL

    -- ioBrokerURL

    • Nach Anlage wird die ID aus HA Bridge in das ioBroker Objekt geschrieben (der Javascript-Adapter muss das dürfen)

    • Objekte mit vorhandener ID werden nicht übertragen. Updates sind möglich aber nicht vorgesehen.

    Update: Geräte wurden doppelt angelegt, Namen werden nicht mehr aktualisiert (Funktion wegrationalisiert)

    var objects = [
       "data.0.Roborock.CleanZoneBadezimmer",
       "lgtv.0.reallyon",
       "data.0.Roborock.CleanZoneKüche",
       "data.0.Alexa.Wie_warm_ist_es"
       ]
    var habridgeURL = "http://192.168.xx.xx:yy/api/devices"
    var ioBrokerURL = "http://192.168.xx.xx:yy/set/"
    
    /////////////////////////////////////////// 
    function escapeRegExp(str) {
     return str.replace(/[\-[]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\><");
    }
    function sendrequest(habridgeURL, params){
       	var request = require('request');
       	request.post({
       			headers: {'content-type': 'application/json'},
       			url:     habridgeURL,
       			body:   params,
       			json: true
       	}, function(error, response, body) {
       		if (error){
       			return log(error, 'error');
       		}
       		log("Response: "+JSON.stringify(body),"debug");
       		var regexp = escapeRegExp(ioBrokerURL)+"(.*)\\?value.*"
               var patt = new RegExp(regexp)
               var result = patt.exec(body[0].onUrl)
       		log("ID für "+ result[1] +" erhalten: " + body[0].id,"debug");
       		if (!isNaN(body[0].id)) extendObject(result[1], {common: {habridgeid: body[0].id}});
       	});
    }
    for (var i = 0; i < objects.length; i++) {
       var curobject = objects[i];
       log("Durchlaufe Objekte","debug");
       log("Objekt: "+curobject,"debug");
       // Prüfe ob Objekt schon in HA Bridge existiert
       if (isNaN((getObject(curobject).common.habridgeid))){
       	// Nein, nicht vorhanden, anlegen
       	log("Lege "+curobject+" neu an","debug");
       	var params = {
       		"name" : getObject(curobject).common.smartName.de,
       		"deviceType" : "switch",
       		"onUrl" : "[{\"item\":\""+ioBrokerURL+curobject+"?value=1\",\"type\":\"veraDevice\"}]",
       		"offUrl" : "[{\"item\":\""+ioBrokerURL+curobject+"?value=0\",\"type\":\"veraDevice\"}]",
       		"Description": "TEST",
       		"Comments": "TEST"
       	}
       	sendrequest(habridgeURL,params);
       }
    } 
    

    Grüße
    Oliver



  • @PacGyver:

    Hallo zusammen,

    ich habe ein Script geschrieben mit welchem ich Geräte in HA Bridge bequemer anlegen kann.

    Kurze Faktenübersicht:

    • Der Name des Gerätes wird aus common.smartName.de ausgelesen (gleicher Name wie im Cloud-Adapter)

    • Im Script muss angepasst werden:

    – Das Array "objects"

    -- habridgeURL

    -- ioBrokerURL

    • Nach Anlage wird die ID aus HA Bridge in das ioBroker Objekt geschrieben (der Javascript-Adapter muss das dürfen)

    • Objekte mit vorhandener ID werden nicht übertragen. Updates sind möglich aber nicht vorgesehen.

    Update: Geräte wurden doppelt angelegt, Namen werden nicht mehr aktualisiert (Funktion wegrationalisiert)

    ! ```
    `var objects = [
    "data.0.Roborock.CleanZoneBadezimmer",
    "lgtv.0.reallyon",
    "data.0.Roborock.CleanZoneKüche",
    "data.0.Alexa.Wie_warm_ist_es"
    ]
    var habridgeURL = "http://192.168.xx.xx:yy/api/devices"
    var ioBrokerURL = "http://192.168.xx.xx:yy/set/"

    ///////////////////////////////////////////
    function escapeRegExp(str) {
    return str.replace(/[-[]/{}()*+?.\^$|]/g, "\><");
    }
    function sendrequest(habridgeURL, params){
    var request = require('request');
    request.post({
    headers: {'content-type': 'application/json'},
    url: habridgeURL,
    body: params,
    json: true
    }, function(error, response, body) {
    if (error){
    return log(error, 'error');
    }
    log("Response: "+JSON.stringify(body),"debug");
    var regexp = escapeRegExp(ioBrokerURL)+"(.)\?value."
    var patt = new RegExp(regexp)
    var result = patt.exec(body[0].onUrl)
    log("ID für "+ result[1] +" erhalten: " + body[0].id,"debug");
    if (!isNaN(body[0].id)) extendObject(result[1], {common: {habridgeid: body[0].id}});
    });
    }

    ! for (var i = 0; i < objects.length; i++) {
    var curobject = objects[i];
    log("Durchlaufe Objekte","debug");
    log("Objekt: "+curobject,"debug");
    // Prüfe ob Objekt schon in HA Bridge existiert
    if (isNaN((getObject(curobject).common.habridgeid))){
    // Nein, nicht vorhanden, anlegen
    log("Lege "+curobject+" neu an","debug");
    var params = {
    "name" : getObject(curobject).common.smartName.de,
    "deviceType" : "switch",
    "onUrl" : "[{"item":""+ioBrokerURL+curobject+"?value=1","type":"veraDevice"}]",
    "offUrl" : "[{"item":""+ioBrokerURL+curobject+"?value=0","type":"veraDevice"}]",
    "Description": "TEST",
    "Comments": "TEST"
    }
    sendrequest(habridgeURL,params);
    }
    }! Grüße ! Oliver ! Hi, ! ist es nicht besser die objects automatisch zu füllen? Warum nutzt du veraDevice?[/i] ```



  • Hallo,

    anbei mal ein Skript welches ich nutze:

    var anz=0;
    
    var habridgeURL = "http://192.168.1.13:8080/api/devices"
    var ioBrokerURL = "http://192.168.1.13:8087/set/"
    
    /////////////////////////////////////////// 
    function escapeRegExp(str) {
      return str.replace(/[\-[]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\><");
    }
    
    function delDevices(from_val,to_val,habridgeURL) {
        for (var i=from_val;i<=to_val;i++) {
          	var request = require('request');
    		request.delete({
    				headers: {'content-type': 'application/json'},
    				url:     habridgeURL+"/"+i
    		}, function(error, response, body) {
    			if (error){
    				return log(error, 'error');
    			}
    			log("Del Response: "+JSON.stringify(body));
    		}); 
        }
    }
    
    function getDevice(val,habridgeURL) {
          	var request = require('sync-request');
    		var erg = request.get({
    				headers: {'content-type': 'application/json'},
    				url:     habridgeURL+"/"+val
    		}, function(error, response, body) {
    			if (error){
    				return log(error, 'error');
    			}
    			log("Get Response: "+body);
    			log("GET-NAME:"+JSON.parse(body).name);
    		});
    }
    
    function sendrequest(habridgeURL, params,id,devid){
        if (devid.length!==0) {  // ID Vorhanden, dh. hole Namen aus ha-bridge
          	var request = require('request');
    		var erg = request.get({
    				headers: {'content-type': 'application/json'},
    				url:     habridgeURL+"/"+devid
    		}, function(error, response, body) {
    			if (error){
    				return log(error, 'error');
    			}
    			// log("Get Response: "+body);
    			// log("GET-NAME:"+JSON.parse(body).name);
                var name=JSON.parse(body).name;
                var addurl="";
                if (name===undefined) {
                    log("NOT FOUND - "+devid);
                    return;  // auskommentieren um nicht gefundene neu anzulegen!  <<<<<<<<<<<<<<<<<<<<<<<<<<<<
                    params["id"]=null;
                    sendrequest(habridgeURL, params,id,"");
                } else if (name.length>0) {
                    params["name"]=name;
                    addurl="/"+devid;
                }
                var request = require('request');
    		    request.put({
    				headers: {'content-type': 'application/json'},
    				url:     habridgeURL+addurl,
    				body:   params,
    				json: true
    		    }, function(error, response, body) {
    			    if (error){
    				    return log(error, 'error');
    			    }
    			    // log("Update Response: "+JSON.stringify(body));
    	//		var regexp = escapeRegExp(ioBrokerURL)+"(.*)\\?value.*";
            	    log("update ok - "+devid); 
    		    });
    		});
        } else {
            var request = require('request');
    		request.post({
    				headers: {'content-type': 'application/json'},
    				url:     habridgeURL,
    				body:   params,
    				json: true
    		}, function(error, response, body) {
    			if (error){
    				return log(error, 'error');
    			}
    			// log("Response: "+JSON.stringify(body));
    			var regexp = escapeRegExp(ioBrokerURL)+"(.*)\\?value.*";
                var patt = new RegExp(regexp);
                var result = patt.exec(body[0].onUrl);
                if (result!==null) {
    			    log("ID für "+ decodeURI(result[1]) +" erhalten: " + body[0].id); 
    			    if (!isNaN(body[0].id)) extendObject(decodeURI(result[1]), {common: {habridgeid: body[0].id}});
    			} else {
    			    log("update nok"); 
    			}
    		});
        }
    }
    
    function saveData(id,raum,devname,onurl,offurl,dimurl) {
    	// log("Objekt: "+id);
    	devid="";
    	var params = {};
    	if (isNaN((getObject(id).common.habridgeid))){
    	    devid="";
        	log("++++++++ Neu "+id+devid+" ");
    	} else {
    	    devid=getObject(id).common.habridgeid;    
        	log("======== Update "+id+"-"+devid+"-");
    	}
    	    // devid="";  // add trotz ID
        	idu=encodeURI(id);
        	if (devid.length>0) {
        	    params["id"]=devid;
        	} 
        	params["name"]= devname;
        	params["deviceType"]= "switch";
        	params["onUrl"]= "[{\"item\":\""+ioBrokerURL+idu+"?value="+onurl+"\",\"type\":\"httpDevice\"}]";
        	if (offurl.length>0) params["offUrl"]= "[{\"item\":\""+ioBrokerURL+idu+"?value="+offurl+"\",\"type\":\"httpDevice\"}]";
        	if (dimurl.length>0) params["dimUrl"]= "[{\"item\":\""+ioBrokerURL+idu+"?value="+dimurl+"\",\"type\":\"httpDevice\"}]";
        	params["description"]= "\""+raum+"\"";
        	params["comments"]= id;
    
        	sendrequest(habridgeURL,params,id,devid);
    
    }
    
    function callme(id,i,b,onurl,offurl,dimurl) {
           if (getObject(id) && anz<500) {
            var devname=getObject(id).common.name;
            var channel=getObject(id).common.name.split(":");
            var idteile=id.split(".");
            var dev="";
            var dp = getObject(id,"rooms");
            var raum=dp.enumNames;
            if (idteile.length>2) {
                dev=idteile[2];
            }
            if (raum.length===0) {
                raum="-"
            }
          if (b===false || raum!="-") { 
           anz=anz+1;
           // log( '"'+id+'","'+channel[0]+'","'+devname+'","'+raum+'","'+dev+'"'+String.fromCharCode(10));
           saveData(id,raum,devname,onurl,offurl,dimurl);
          }
        } 
    }
    
    // callme 
    //      id = Geraeteid
    //      i  = Nummer (nicht verwendet)
    //      b  = Nur Geräte mit Raum (true/false)
    //      onurl = Wert für ON
    //      offurl = Wert für OFF
    //      dimurl = Wert für DIM ("${intensity.percent}")
    
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    
    //var states = $('broadlink2.0.*.L.*').each(function(id,i) { callme(id,i,false,"true","false",""); });
    //var states = $('broadlink2.0.States.*').each(function(id,i) { callme(id,i,false,"true","false",""); });
    //var states = $('broadlink2.0.Scenes.*').each(function(id,i) { callme(id,i,false,"true","false",""); });
    //var states = $('scene.0.*').each(function(id,i) { callme(id,i,false,"true","false",""); });
    //var states = $('hm-rpc.0.*.SET*').each(function(id,i) { callme(id,i,true,"true","false",""); });
    var states = $('hm-rpc.0.*.1.LEVEL').each(function(id,i) { callme(id,i,true,"100","0","${intensity.percent}"); });
    //var states = $('hm-rpc.0.LEQ1023360.1.LEVEL').each(function(id,i) { callme(id,i,true,"100","0","${intensity.percent}"); });   
    
    //delDevices(25,200,habridgeURL);
    //getDevice(25,habridgeURL);
    

    Auskommentieren um gelöschte Objekte erneut anzulegen;

                    return;  // auskommentieren um nicht gefundene neu anzulegen!  <<<<<<<<<<<<<<<<<<<<<<<<<<<<
    
    

    Wenn ihr die nächste Zeile auch auskommentiert wird keine neue ID vergeben.

    Im unteren Bereich könnt ihr die Geräte suchen:

    //var states = $('broadlink2.0.*.L.*').each(function(id,i) { callme(id,i,false,"true","false",""); });
    //var states = $('broadlink2.0.States.*').each(function(id,i) { callme(id,i,false,"true","false",""); });
    //var states = $('broadlink2.0.Scenes.*').each(function(id,i) { callme(id,i,false,"true","false",""); });
    //var states = $('scene.0.*').each(function(id,i) { callme(id,i,false,"true","false",""); });
    //var states = $('hm-rpc.0.*.SET*').each(function(id,i) { callme(id,i,true,"true","false",""); });
    var states = $('hm-rpc.0.*.1.LEVEL').each(function(id,i) { callme(id,i,true,"100","0","${intensity.percent}"); });
    //var states = $('hm-rpc.0.LEQ1023360.1.LEVEL').each(function(id,i) { callme(id,i,true,"100","0","${intensity.percent}"); });   
    

    Wenn ihr in HA-Bridge den Namen geändert habt, dann wird dieser beim update nicht verändert.

    // callme 
    //      id = Geraeteid
    //      i  = Nummer (nicht verwendet)
    //      b  = Nur Geräte mit Raum (true/false)
    //      onurl = Wert für ON
    //      offurl = Wert für OFF
    //      dimurl = Wert für DIM ("${intensity.percent}")
    

    mit den Werten bestimmt ihr Schalter oder Jalousie oder Dimbare Lampe verwendet wird.

    Es müssen die Werte verwendet werden, die die simple-api benötigt!

    Als Ergbins sollte so etwas rauskommen:

    22:25:14.452	[info]	javascript.0 script.js.to-ha-bridge: ======== Update hm-rpc.0.BidCoS-RF.1.LEVEL-119-
    22:25:14.452	[info]	javascript.0 script.js.to-ha-bridge: ======== Update hm-rpc.0.LEQ0042303.1.LEVEL-121-
    22:25:14.452	[info]	javascript.0 script.js.to-ha-bridge: ======== Update hm-rpc.0.LEQ1023360.1.LEVEL-126-
    22:25:14.452	[info]	javascript.0 script.js.to-ha-bridge: ======== Update hm-rpc.0.LEQ1439999.1.LEVEL-120-
    22:25:14.452	[info]	javascript.0 script.js.to-ha-bridge: ======== Update hm-rpc.0.NEQ0351944.1.LEVEL-117-
    22:25:14.452	[info]	javascript.0 script.js.to-ha-bridge: registered 0 subscriptions and 0 schedules
    22:25:14.462	[info]	javascript.0 script.js.to-ha-bridge: NOT FOUND - 119
    22:25:14.482	[info]	javascript.0 script.js.to-ha-bridge: ID für hm-rpc.0.BidCoS-RF.1.LEVEL erhalten: 127
    22:25:14.482	[info]	javascript.0 script.js.to-ha-bridge: update ok - 119
    22:25:14.482	[info]	javascript.0 script.js.to-ha-bridge: update ok - 121
    22:25:14.482	[info]	javascript.0 script.js.to-ha-bridge: update ok - 126
    22:25:14.482	[info]	javascript.0 script.js.to-ha-bridge: update ok - 117
    22:25:14.482	[info]	javascript.0 script.js.to-ha-bridge: update ok - 120
    22:25:36.103	[info]	javascript.0 Stop script script.js.to-ha-bridge
    

  • Starter

    Hallo,

    würde gern über die Haussteuerungstasten meiner Harmony Fernbedienung ein paar Lampen steuern. Bei der Recherche bin ich auf eure Skripts gestoßen. Leider komme ich mit beiden nicht zurecht. Hoffe ihr könnt mich unterstützen oder zumindest in die richtige Richtung schubsen…

    @PacGyver:

    Wenn ich dein Skript kopiere und ausführe, bekomme ich bei Zeile 42 ein ERROR im log. Das hängt wohl mit common.smartName.de zusammen, was genau müsste ich hier unternehmen? Muss ich einen weiteren Adapter Alexa und/oder Cloud installieren? Oben hatte ich in der var objects meine IDs korrekt hinrelegt. Im Raw-Bereich meiner beiden Datenpunkte finde ich jedenfalls unter "common" nicht die Variable "SmartName". Könnte den Namen auch manell eintragen. Würde aber ungern schon nach wenigen Tagen das System zerschießen :lol:

    EDIT: Habe die Einträge smartName bei meinen beiden Lampen händisch eingetragen, dadurch ist der eben beschriebene Fehler weg. In der HA-Bridge sehe ich sogar zwei Einträge bei den Devices aber diese funktionieren nicht, die Inhalte sind leer wenn ich auf "edit" klicke. Was mache ich noch falsch?

    @Sissi:

    Wie nutze ich überhaupt dein Skript? Ich hatte es so verstanden, dass wenn ich es innerhalb von ioBroker ausführe, dann sollte ich meine Devices in HA-Bridge sehen? Du hast unten viele auskommentierte devices, muss ich in diesem Bereich händisch meine devices anlegen? Wenn ja, muss ich dieselben dann in der HA-Bridge auch anlegen? Von wo rufe ich die function "callme" auf?

    Ein wenig mit Bash kenne ich mich aus, aber ich glaube ich verstehe hier nicht die grundsätzliche Vorgehensweise zur Verwendung eurer Skripte.

    Das Skript wird doch unter dem Reiter "Skripte" (aus dem Adapter) eingepflegt und nur ausgeführt, oder? Wieso müsste ich dann eine IP für ioBroker eingeben, localhost müsste doch immer reichen.

    Ich hoffe ihr könnt mich hier etwas erleuchten. Hatte die HA-Bridge bisher nativ mit domoticz genutzt und würde gern zu iobroker wechseln.

    Danke + Gruß,

    Giuseppe

    EDIT:

    Eure Lösungen sind Komfort-Lösungen würde ich mal sagen. Ich habe da nicht viele Variationen und Veränderungen; daher würde es mir reichen, wenn ich in der ha-bridge es iwie einrichten könnte, dass bei den on- und off-Befehlen die simple-api Befehlszeilen eingetragen werden könnten. Wisst ihr ob das funktioniert und wie ich die anderen Parameter wählen müsste? Konnte dazu im Netz nichts finden.



  • @sissiwup:

    ist es nicht besser die objects automatisch zu füllen? Warum nutzt du veraDevice? `

    Warum veraDevice kann ich Dir nicht sagen, wahrscheinlich irgendwo herauskopiert oder ein Übertragungsfehler. Es funktioniert jedenfalls. Object automatisch füllen ist natürlich besser aber ich war mit dem Ergebnis zufrieden.

    @davincino

    Der Parameter "SmartName" wird vom Cloud-Adapter genutzt, daher habe ich den gleichen gewählt falls ich irgendwann dorthin migrieren möchte. Ich habe keinen Nachteil daran bemerkt die Namen manuell einzutragen.

    Mein Script ist nur dazu gedacht die Geräte einmalig in ha-bridge anzulegen. Das funktioniert manuell ebenso gut, ist nur aufwändiger. Mein Script funktioniert bei mir aber noch, ich habe es gerade ausprobiert:

    Im Objekt unter "RAW" hinzugefügt

    ,
        "smartName": {
          "de": "Deckenfluter",
          "smartType": "SWITCH"
        },
    
    

    So sieht es nun aus:

    {
      "type": "state",
      "common": {
        "name": "on",
        "type": "boolean",
        "role": "switch",
        "read": true,
        "write": true,
        "smartName": {
          "de": "Deckenfluter",
          "smartType": "SWITCH"
        }
      },
      "native": {},
      "n": "on",
      "g": 7,
      "tf": 255,
      "_id": "lightify.0.3F5ACA0000261884.on",
      "acl": {
        "object": 1636,
        "state": 1636,
        "owner": "system.user.admin",
        "ownerGroup": "system.group.administrator"
      },
      "from": "system.adapter.javascript.1",
      "ts": 1542398734843
    }
    
    

    im Script das Objekt eingefügt und ein mal gestartet. Jetzt sieht es so aus:

    {
      "type": "state",
      "common": {
        "name": "on",
        "type": "boolean",
        "role": "switch",
        "read": true,
        "write": true,
        "smartName": {
          "de": "Deckenfluter",
          "smartType": "SWITCH"
        },
        "habridgeid": "55"
      },
      "native": {},
      "n": "on",
      "g": 7,
      "tf": 255,
      "_id": "lightify.0.3F5ACA0000261884.on",
      "acl": {
        "object": 1636,
        "state": 1636,
        "owner": "system.user.admin",
        "ownerGroup": "system.group.administrator"
      },
      "from": "system.adapter.javascript.1",
      "ts": 1542398734843
    }
    
    

    Alexa suchen lassen, fertig.



  • @davincino:

    Hallo,

    @Sissi:

    Wie nutze ich überhaupt dein Skript? Ich hatte es so verstanden, dass wenn ich es innerhalb von ioBroker ausführe, dann sollte ich meine Devices in HA-Bridge sehen? Du hast unten viele auskommentierte devices, muss ich in diesem Bereich händisch meine devices anlegen? Wenn ja, muss ich dieselben dann in der HA-Bridge auch anlegen? Von wo rufe ich die function "callme" auf? `

    Hallo,

    ich möchte nicht alle devices in die Bridge übernehmen, deshalb kommentiert du unten nur das aus, was du haben möchtest.

    Das A und O sind die richtigen Selektoren.

    Bei mir ist der Name eine Rollos immer RL-…, man kann aber auch natürlich die Grupper der Rollos oder nur spezielle Namen auswählen.

    //var states = $('broadlink2.0.*.L.*').each(function(id,i) { callme(id,i,false,"true","false",""); });
    

    => hier werden z.B. die im Unterverzeichnis L (gelernten) Geräte vom Broadlink übernommen.

    //var states = $('broadlink2.0.States.*').each(function(id,i) { callme(id,i,false,"true","false",""); });
    

    => hier die States

    //var states = $('broadlink2.0.Scenes.*').each(function(id,i) { callme(id,i,false,"true","false",""); });
    

    => hier die Scenen

    //var states = $('scene.0.*').each(function(id,i) { callme(id,i,false,"true","false",""); });
    

    => hier wird der Scenen-Adapter von ioBroker bemüht. Alle Scenen werden importiert.

    //var states = $('hm-rpc.0.*.SET*').each(function(id,i) { callme(id,i,true,"true","false",""); });
    

    => hier werden alle Geräte von Homematic die einen Parameter SET… unterstützen übernommen

    var states = $('hm-rpc.0.*.1.LEVEL').each(function(id,i) { callme(id,i,true,"100","0","${intensity.percent}"); });
    

    => hier werden alle Rollos (Erkennbar an LEVEL) übernommen. Hier wird 100 als Offen, 0 als Zu und Zwischenwerte möglich gesetzt.

    //var states = $('hm-rpc.0.LEQ1023360.1.LEVEL').each(function(id,i) { callme(id,i,true,"100","0","${intensity.percent}"); });   
    

    => hier wird nur ein spezielles Rollo hinzugefügt.

    Mit

    //delDevices(25,200,habridgeURL);
    //getDevice(25,habridgeURL);
    

    kannst du entweder alle Devices löschen (von Nummer 25 bis 200 hier)

    oder lesen


Log in to reply
 

Suggested Topics

2.0k
Online

32.3k
Users

39.0k
Topics

528.0k
Posts