NEWS

[Vorlage] Alias per Skript erzeugen


  • Im folgenden Skript wird ein Alias zu einem Datenpunkt mit dessen common-Eigenschaften erstellt. Bei gewollten Abweichungen von common-Eigenschaften des Alias zum Original muss man die zugehörigen // (Kommentar) entfernen und den gewünschten Wert zuweisen.

    // Original-Datenpunkt
    const idOrigin = 'mqtt.0.switch.status'; 
    // Optional: Status-Datenpunkt, wenn Kommando und Status getrennt.
    // Bei Nicht-Verwendung Leerstring '' zuweisen
    const idRead = '';
     
    // Alias-Datenpunkt
    const idAlias = 'Pool.Pumpe.Schalter';
    
    var typeAlias, read, write, nameAlias, role, desc, min, max, unit, states, custom, raum, gewerk;
    
    // Folgende kommentieren, wenn keine Änderung der Eigenschaft erforderlich
    nameAlias = 'Poolpumpe Ein';
    desc = 'per Script erstellt';
    // typeAlias = 'boolean'; // oder 'number'
    // read = "val < 0 ? -val : 0"; // Erkennung "Aus" --> false erfolgt automatisch  
    // write = "val ? String(1) : String(0)";
    // role = 'value';
    // min = 0; // nur Zahlen
    // max = 100; // nur Zahlen
    // unit = '%'; // nur für Zahlen
    // states = {0: 'Aus', 1: 'Auto', 2: 'Ein'}; // Zahlen (Multistate) oder Logikwert (z.B. Aus/Ein)
    custom = {}; // verhindert doppelte Ausführung von history, ...
    // raum = 'EG_Flur'; // Groß-/Kleinschreibung in der ID beachten !
    // gewerk = 'Licht'; // Groß-/Kleinschreibung in der ID beachten !
    
    // Ab hier nichts ändern !!
    function createAlias(idDst, idSrc, idRd) {
       if(existsState(idDst)) log(idDst + ' schon vorhanden !', 'warn');
       else {
          var obj = {};
          obj.type = 'state';
          obj.common = getObject(idSrc).common;
          obj.common.alias = {};
          if(idRd) {
              obj.common.alias.id = {};
              obj.common.alias.id.read = idRd;
              obj.common.alias.id.write = idSrc;
              obj.common.read = true;
          } else obj.common.alias.id = idSrc;
          if(typeAlias) obj.common.type = typeAlias;
          if(obj.common.read !== false && read) obj.common.alias.read = read;
          if(obj.common.write !== false && write) obj.common.alias.write = write;
          if(nameAlias) obj.common.name = nameAlias;
          if(role) obj.common.role = role;
          if(desc) obj.common.desc = desc;
          if(obj.common.type == 'number') {
             if(min !== undefined) obj.common.min = min;
             if(max !== undefined) obj.common.max = max;
             if(unit) obj.common.unit = unit;
          } else {
             if(obj.common.min !== undefined) delete obj.common.min;
             if(obj.common.max !== undefined) delete obj.common.max;
             if(obj.common.unit) delete obj.common.unit;
          }
          if(states) obj.common.states = states;
          if(custom && obj.common.custom) obj.common.custom = custom;
          obj.native = {};
          setObject(idDst, obj, function() {
             if(idRd) setState(idRd, getState(idRd).val, true);
             else setState(idSrc, getState(idSrc).val, true); 
          });
          if(raum && existsObject('enum.rooms.' + raum)) {
             let obj = getObject('enum.rooms.' + raum)
             obj.common.members.push(idDst);
             setObject('enum.rooms.' + raum, obj);
          }
          if(gewerk && existsObject('enum.functions.' + gewerk)) {
             let obj = getObject('enum.functions.' + gewerk)
             obj.common.members.push(idDst);
             setObject('enum.functions.' + gewerk, obj);
          }
       } 
    }
     
    createAlias('alias.0.' + idAlias, idOrigin, idRead);
    

    Beispiele für Konvertierung (write);

    write = "val ? 1 : 0"; // boolean --> binary
    write = "val ? 'On' : 'Off'"; // boolean --> string
    write = "val.toString()"; // number --> string dezimal
    write = "val.toFixed(2)"; // number --> string mit 2 Nachkommastellen
    

    EDIT(20.12.2019): obj.native ergänzt.
    EDIT(16.01.2020): Abfrage (Zeile 20) geändert
    EDIT(06.02.2020): obj.common.custom ergänzt

    EDIT(17.02.2020): Da man Raum und Gewerk in die Struktur der Alias-ID einbringen kann, sind enums für Raum und Gewerk oftmals nicht erforderlich. Für diejenigen, die den erzeugten Alias-Datenpunkt zu enum.rooms und/oder enum.functions hinzufügen wollen, wurde das Skript erweitert.

    EDIT(21.04.2020): Erweiterung für getrennte Kommando- und Status-Datenpunkte ab js-controller 3.x.

    EDIT(05.12.2020): Wenn Alias-Typ keine Zahl ist, werden min, max und unit gelöscht, falls vorhanden

    EDIT(16.02.2021): Zeile 23 geändert von leerem Array in leeres Objekt


  • Hi @paul53,
    will grad anfangen meine Alias mit deinem Script anzulegen.

    Derzeit muss ich anschließend diesen dann händisch eine "Funktion" sowie "Raum" zuweisen.
    Kannst du dein Script damit erweitern?
    Ganz nach der Art deiner anderen Eigenschaften:

    // room = 'EG_Flur';
    // functions = 'Licht';
    

  • @Troya sagte:

    Kannst du dein Script damit erweitern?

    Raum und Gewerk sind eigene Objekte (enums) und keine Eigenschaft des Datenpunktes.


  • Ok, das heißt dann wohl nein.
    Hatte ich gehofft, weil der Beitrag ganz vielversprechend aussah.


  • @Troya sagte:

    Kannst du dein Script damit erweitern?

    Versuche es bitte selbst mit folgenden Erweiterungen:

    var raum, gewerk; // Zeile 6 ergänzen
    
    // raum = 'EG_Flur'; // Zeile 18
    // gewerk = 'Licht'; // Zeile 19
    
    // am Ende der Funktion createAlias() ergänzen (hinter setObject())
          if(raum && getObject('enum.rooms.' + raum)) {
             let obj = getObject('enum.rooms.' + raum)
             obj.common.members.push(idDst);
             setObject('enum.rooms.' + raum, obj);
          }
          if(gewerk && getObject('enum.functions.' + gewerk)) {
             let obj = getObject('enum.functions.' + gewerk)
             obj.common.members.push(idDst);
             setObject('enum.functions.' + gewerk, obj);
          }
    

  • @paul53
    Klasse das klappt, danke Paul!🤗

    Aber nicht den Satz wie ich falsch verstehen:

    // am Ende der Funktion createAlias() ergänzen (hinter setObject())
    

    Hab das zuerst so verstanden, dass man die Funktion createAlias() in die Gewerk-Funktion hinter setObject() setzen soll.
    ...am Ende der Funktion, createAlias() erzänzen...🤦‍♂️
    ...am Ende der createAlias()-Funktion erzänzen 👍

    --

    Eins noch nebenbei,weil ich das Problem hatte:
    Falls es heißt

    javascript.0	2019-12-09 10:49:50.479	warn	(908) Object "enum.rooms.OG_Bad" does not exist
    

    Achtet bei den IDs der Räume und Gewerke auf die Groß- & Kleinschreibung.
    Lässt man den Haken bei "IDs behalten" angehakt, werden diese nämlich klein geschrieben!
    Das lässt sich aber nachträglich korrigieren über das Stift-Symbol.

  • Developer

    @paul53
    Hi,
    bitte erweitere dein Skript doch so, dass auch der native Part gesetzt wird, also das hier noch einfügen:

    obj.native = {}
    

    Ansonsten gibt es Probleme mit iot (Alexa, usw.), siehe Diskussion hier

    Danke. 🙂

    Viele Grüße,
    Garfonso


  • @Garfonso sagte:

    erweitere dein Skript doch so, dass auch der native Part gesetzt wird

    Erledigt.


  • Ich bin leider totaler Anfänger und würde mich freuen, wenn mir jemand bezüglich dem Erzeugen von Alias etwas Hilfestellung geben könnte. Ich möchte die Alias-Funktion nutzen, um von Anfang an für den Fall, dass ein Austausch eines Gerätes notwendig wird, vorzusorgen (und nicht alle Verweise in Vis oder Blockly ändern zu müssen). Eine "idiotensichere" Anleitung zum Erstellen eines Alias habe ich leider nicht gefunden - das Skript scheint bereits die einfachste Möglichkeit zu sein. Oder gibt es inzwischen eine einfachere Möglichkeit?

    Muss ich das oben stehende Skript einfach bei Skripte einfügen und das Skript aktivieren damit der Alias erstellt wird?

    Wenn ich beispielsweise eine LED Lampe habe, muss ich dann für on/off, brightness, color, etc. das Skirpt für jeden einzelnen Datenpunkt separat laufen lassen? Gibt es eine Funktion, die für alle Datenpunkte eines Geräts auf einmal Alias anlegt?

    Mir ist nicht ganz klar, wann ich oben im Skript die Auskommentierung rausnehmen muss und wann nicht. Könnte mir das bitte jemand erklären?


  • @Markus84 sagte:

    Muss ich das oben stehende Skript einfach bei Skripte einfügen und das Skript aktivieren damit der Alias erstellt wird?

    Ja, vor Aktivierung die IDs (Original und Alias) anpassen. Wenn alle common-Attribute wie im Original bleiben können, genügt das.

    @Markus84 sagte in [Vorlage] Alias per Skript erzeugen:

    das Skirpt für jeden einzelnen Datenpunkt separat laufen lassen?

    Ja, das Skript erzeugt genau einen Alias-Datenpunkt.

    @Markus84 sagte in [Vorlage] Alias per Skript erzeugen:

    wann ich oben im Skript die Auskommentierung rausnehmen muss

    Wenn sich mind. ein common-Attribut(siehe unter "Attribute für bestimmte Objekttypen") im Alias vom Original unterscheiden soll. In der Regel ist es mind. der Name.


  • @paul53 Besten Dank. Jetzt habe ich es (hoffentlich) verstanden und werde es gleich mal versuchen umzusetzen.


  • @Markus84 said in [Vorlage] Alias per Skript erzeugen:

    @paul53 Besten Dank. Jetzt habe ich es (hoffentlich) verstanden und werde es gleich mal versuchen umzusetzen.

    Vielleicht habe ich es doch nicht so ganz verstanden... Den Alias anzulegen hat wunderbar funktioniert. Den value synchronisiert er auch sehr schön zwischen Alias und dem zu schaltenden Datenpunkt. Wenn ich Name, state oder role ändere, wird diese Änderung jedoch nicht mitsynchronisiert. Ist das normal? Falls dies normal ist, kann ich bedenkenlos diese Daten im Alias ändern (werden dann logischerweise zwar nicht synchronisiert) oder lässt man besser die Finger davon?


  • @Markus84 sagte:

    Wenn ich Name, state oder role ändere, wird diese Änderung jedoch nicht mitsynchronisiert. Ist das normal?

    Ja, das sind statische Attribute. Der Alias kann andere Attribute haben als das Original, wozu bei der Alias-Erzeugung die kommentierten Zeilen im Skript dienen. Einmal erzeugte Attribute können nur manuell geändert werden.


  • Hallo, leider wird bei mir der alias.0 nicht angelegt.
    Im Log steht folgendes:

    javascript.0 2020-01-04 08:20:56.572 info (2420) script.js.common.alias_anlegen: registered 0 subscriptions and 0 schedules
    javascript.0 2020-01-04 08:20:56.571 warn (2420) script.js.common.alias_anlegen: setObject(id=alias.0.lampe2, obj={"type":"state","common":{"name":"Lampe1 on","type":"boolean","role":"switch","read":true,"write":true,"alias":{"id":"deconz.0.
    javascript.0 2020-01-04 08:20:56.569 info (2420) script.js.common.alias_anlegen: getObject(id=deconz.0.Lights.2.on, enumName=undefined) => {"type":"state","common":{"name":"Lampe1 on","type":"boolean","role":"switch","read":true,"write":true
    javascript.0 2020-01-04 08:20:56.554 info (2420) Start javascript script.js.common.alias_anlegen

    Das komische auf einer anderen iobroker-Installation geht es. Softwarestand ist der gleiche. Zwei Unterschiede gibt es. Beim funktionierenden läuft iobroker auf ner VM und bei der anderen auf einem Rasberry Pi 3. Der 2te Unterschied es sind weniger Instancen auf der problematischen Installation.
    Im Skript aber ich nur die Namen angepasst, den Rest auskommentiert gelassen.


  • @patti72 sagte:

    wird bei mir der alias.0 nicht angelegt.

    In der Konfiguration der JS-Instanz ist setObject freigegeben ?

    Logs bitte in Code tags (</>) posten.


  • @paul53

    Könntest Du bitte kurz erklären, wie aus einem alias vom typ boolean ein "offen" oder "geschlossen" wird?

    Leider fehlen mir die Javascript-Kenntnisse, um Dein Script aus dem ersten Post dahingehend richtig zu interpretieren.

    Danke!

    Beispiel hier:

    {
      "_id": "alias.0.Fenster_und_Tuer_Sensoren.Fenster.EG.Esszimmer.Fenster.Stellung",
      "type": "state",
      "common": {
        "name": "Stellung",
        "role": "",
        "type": "boolean",
        "read": true,
        "write": true,
        "desc": "Manuell erzeugt",
        "def": false,
        "alias": {
          "id": "zigbee.0.00158d00028b5941.opened"
        }
      },
      "native": {},
      "from": "system.adapter.admin.0",
      "user": "system.user.admin",
      "ts": 1577905721582,
      "acl": {
        "object": 1636,
        "state": 1636,
        "owner": "system.user.admin",
        "ownerGroup": "system.group.administrator"
      }
    }
    

  • @XxJooO :
    Wie sieht das Objekt vom Datenpunkt "zigbee.0.00158d00028b5941.opened" aus ? Welche Werte kann er annehmen ?


  • @paul53

    {
      "from": "system.adapter.zigbee.0",
      "user": "system.user.admin",
      "ts": 1572607261264,
      "common": {
        "name": "Is open",
        "type": "boolean",
        "role": "state",
        "read": true,
        "write": false,
        "custom": {
          "history.0": {
            "enabled": true,
            "changesOnly": true,
            "debounce": "",
            "maxLength": "",
            "retention": "31536000",
            "changesRelogInterval": "",
            "changesMinDelta": "",
            "aliasId": ""
          },
          "influxdb.0": {
            "enabled": true,
            "changesOnly": true,
            "debounce": "",
            "maxLength": 10,
            "retention": 0,
            "changesRelogInterval": "",
            "changesMinDelta": "",
            "storageType": "",
            "aliasId": ""
          }
        }
      },
      "native": {},
      "acl": {
        "object": 1636,
        "owner": "system.user.admin",
        "ownerGroup": "system.group.administrator",
        "state": 1636
      },
      "_id": "zigbee.0.00158d000288e163.opened",
      "type": "state"
    }
    

  • @XxJooO
    Der Original-Datenpunkt ist doch ebenfalls vom Typ "boolean", allerdings "read only". Da muss nichts gewandelt werden. Oder möchtest Du Zustandstexte darstellen (Zeile 17) ?

    states = {false: 'geschlossen', true: 'offen'}; // Zahlen (Multistate) oder Logikwert (z.B. Aus/Ein)
    

  • @paul53

    ja, der Ausgabewert soll bei true offen und bei false gern geschlossen sein.

Suggested Topics

  • 50
  • 38
  • 11
  • 2
  • 5
  • 3
  • 16
  • 4

1.6k
Online

36.9k
Users

42.6k
Topics

591.3k
Posts