Archiv des Autors: Stephan

Über Stephan

Als Kind der 90er Jahre wuchs ich in einer Übergangs-Ära von analog zu digital auf. Vorteil: man kennt analog und stieg direkt in's Digitale ein. Auch heute begeistert mich die digitale Welt noch - wenn nicht sogar mehr denn je. Heutzutage sind die kleinen Nullen und Einsen gar nicht mehr wegzudenken ...

Radiowelle

Shelly mit Hilfe eines NFC Tag schalten

Du hast für Dein Schlafzimmer einen Shelly 1 oder gar Shelly 2.5 (für Decken- und Stehleuchte) eingebaut? Dann stellt sich beim Schlafen gehen meistens die Frage: “Licht aus? Handy-Taschenlampe an!”, damit Du nicht über Dinge, die am Boden liegen, stolperst? Oder gar: Nachttischlampe an, wieder zurück zum Schalter, diesen ausschalten und erneut den Weg Richtung Bett antreten.

Das geht auch einfacher!

Benötigt werden:

Einrichtung des Makros in MacroDroid

Als Auslöser stellst Du NFC Sticker ein und als Aktion den Aufruf als HTTP GET (Ohne Web Browser). Beim Auswählen des NFC Sticker muss dieser bereitliegen, da er gescannt wird. Ein Name “Licht Schlafzimmer” o.ä. ist hier hilfreich, damit man die Sticker später auseinander halten kann. MacroDroid schreibt nun nur den Namen auf den Sticker und speichert diesen ab.

Die Adresse für den Aufruf über MacroDroid stellst Du wie folgt ein:

http://IP-DEINES-SHELLY/relay/0?turn=toggle

Die Variable “turn” steht hier auf toggle. Das heißt, das bei jedem Aufruf der Status geändert wird: An -> Aus, Aus -> An. Diese kannst Du auch verwenden, um das Licht immer nur aus oder nur an zuschalten.

Für an:
http://IP-DEINES-SHELLY/relay/0?turn=on

Für aus:
http://IP-DEINES-SHELLY/relay/0?turn=off

Nach dem Speichern des Makros kannst Du den NFC Tag direkt testen.

E-Mail

E-Mail aus der HomeMatic heraus senden

Wenn alle Schaltungen oder Timer in Deiner HomeMatic Installation reibungslos laufen, ist dies ein beruhigendes Gefühl. Doch, was ist, wenn plötzlich ein Fehler auftritt und du unterwegs bist? Oder, Du möchtest benachrichtigt werden, wenn ein gewisses Ereignis eintritt? In solchen Fällen benötigst Du, um eine E-Mail Benachrichtigung aus der HomeMatic heraus senden zu können, das E-Mail Plugin, welches Du hier herunterladen kannst.
Bitte die tar.gz-Datei nicht entpacken.

Installation auf der HomeMatic

Die Installation des Plugin läuft genauso ab, wie die Installation der anderen Plugins.

HomeMatic WebUI über Einstellungen -> Systemsteuerung -> Zusatzsoftware

Installation des E-Mail Plugin
Installation des E-Mail Plugin

Konfiguration des Plugin

Um das Plugin einzustellen, gehst Du nach der Installation auf Einstellen.

Einstellung des E-Mail Plugin
Einstellung des E-Mail Plugin

E-Mails

In diesem Bereich richtest Du zuerst eine Testmail unter der Vorlage 01 ein. Diese einhält eine funktionierende Adresse, einen Betreff und einen Test-Text.

E-Mail Vorlage erstellen
E-Mail Vorlage erstellen

Account

Danach wechselst Du in den Reiter Account. Dort kannst Du die Einstellungen deines E-Mail Kontos angeben.

Account Einstellungen
Account Einstellungen

Nach einem Klick auf Übernehmen. Kannst Du in der Karteikarte Hilfe einsehen, ob die Einstellungen korrekt sind. Für gmail, web.de oder o.ä. muss ggf. der Versand über SMTP noch im Kundenkonto aktiviert werden.

Tcl

Tcl Einstellungen
Tcl Einstellungen

Die Tcl Einstellungen (Tool command language) kannst Du verwenden, um Variablen in einer E-Mail zu übergeben. Ich verwende hier einen kleinen Code, der den Betreff (Subject) und E-Mail Text (Body) aus HomeMatic Variablen ausliest und diese entsprechend formatiert einfügt.

load tclrega.so

array set values [rega_script {

var subject = dom.GetObject("E-Mail.Subject").Value();
var body = dom.GetObject("E-Mail.Body").Value();

} ]

set subject $values(subject)
set body [encoding convertto $values(body)]

Hinweis: Mittels der im Tcl-Skript definierten Platzhalter können nicht nur Werte und Zustände von HomeMatic Geräten oder Variablen in den Email-Text oder den Betreff übergeben werden, sondern auch die Empfänger Email-Adresse oder einen Pfad für den Dateianhang.

Hilfe

In diesem Bereich kannst du nun eine Testmail versenden, um Deine Konfiguration zu testen.

Testmail versenden
Testmail versenden

Nachdem nun der Versand der Mails problemlos funktioniert, können wir uns an die Einrichtung der Vorlagen machen.

E-Mail Vorlagen erstellen

In diesem Bereich kannst Du Vorlagen für verschiedene Ereignisse anlegen. Ich benutze bei mir 4 Vorlagen (Fehler, Status, Abgeschlossen und Alarm). Diese kannst Du natürlich an Deine Bedürfnisse anpassen. Im weiteren Verlauf werden wir diese in HomeMatic einrichten. Hier sind die 2 ersten Vorlagen, die ich verwende:

Hier kannst Du direkt sehen, das die Variablen $subject und $body von oben erneut auftauchen. So lässt sich das Layout der Mail schon festlegen und später über die HomeMatic Variablen befüllen.

Mit der Einrichtung des Plugins sind wir nun fertig. Mit einem Klick auf Übernehmen werden die Vorlagen gespeichert und das Plugin ist einsatzbereit.

Einrichtung auf der HomeMatic

Anlegen der Systemvariablen

Insgesamt benötigst Du 3 Systemvariablen. 2 vom Typ Zeichenkette und 1 vom Typ Werteliste.

Name:Typ:
E-Mail.BodyZeichenkette
E-Mail.SubjectZeichenkette
E-Mail.VersandWerteliste
Folgende Systemvariablen müssen angelegt werden
HomeMatic Variablen anlegen
HomeMatic Variablen anlegen

Die Werteliste beinhaltet kein Versand;Fehler;Status;Abgeschlossen;Alarm als Werte. Somit baut sich die Vorlagenliste von oben wir folgt auf:

Werteliste-Element:Vorlage:
0
101
202
303
404
Vorlage und Werteliste-Element

Nachdem wir nun alle Variablen angelegt haben, erstellen wir das Herzstück: das Programm.

E-Mail Programm erstellen

Damit das Versenden von E-Mails zentral gesteuert wird, legst Du ein Programm an, welches den Zustand der Werteliste E-Mail.Versand überwacht.

E-Mail Programm auf der HomeMatic
E-Mail Programm auf der HomeMatic

Skript:

! Servicemeldungen versenden ####################################
object subject = dom.GetObject ("E-Mail.Subject");
object body = dom.GetObject ("E-Mail.Body");
object versand = dom.GetObject ("E-Mail.Versand");

if ((subject.Value() != "") && (body.Value() != "") && (versand.Value() > 0)) {
	system.Exec ("/etc/config/addons/email/email 0" # versand.Value());
	
	subject.State ("");
	body.State ("");
	versand.State (0);
}

Damit Du nun endlich eine E-Mail beim Eintreten eines Ereignisses versenden kannst, zeige ich Dir nun die Einrichtung.

Du kannst zum Beispiel ein Programm erstellen, welches Dich benachrichtigt, sobald die Waschmaschine fertig ist. Dies ist bei mir eine “Abgeschlossen” Meldung.

E-Mail beim Eintreten eines Ereignisses versenden
E-Mail beim Eintreten eines Ereignisses versenden

Implementierung per Skript

Eine Implementierung per Skript lässt sich wie folgt durchführen. Das Skript lässt sich so schnell kopieren und erneut ans Ende eines Programms einfügen, als jedes Mal 5 zusätzliche Felder anzuklicken.

Skript:

! Servicemeldungen versenden ####################################
object subject = dom.GetObject ("E-Mail.Subject");
object body = dom.GetObject ("E-Mail.Body");
object versand = dom.GetObject ("E-Mail.Versand");

subject.State ("Waschmaschine");
body.State ("Die Waschmaschine ist fertig!");
versand.State (3);
Schalter

Shelly Fensterkontakt schaltet Plug-S, Shelly 1 oder Shelly 2.5

Ist Dir schon mal aufgefallen, das die Schaltvorgänge über die Szenen mit der Shelly App ziemlich lange (>3 Sekunden) dauern? Dies resultiert aus der Cloud-Verbindung. Die Szene wird in der Cloud gespeichert und so muss der Auslöser seinen Status in die Cloud senden, die Cloud verarbeitet das Skript und aktiviert dann den jeweiligen Aktor.
Das geht auch schneller!

Installation des Shelly Adapter

Installation des Shelly Adapter
Installation des Shelly Adapter

Nach kurzer Zeit stehen die Datenpunkte aller gefundenen Shellys unter shelly.0 zur Verfügung.

Mit diesem Skript kannst Du einen Shelly Fensterkontakt als Auslöser nutzen und z.B. einen Shelly Plug S, Shelly 1 oder Shelly 2.5 schalten.

Skripte für ioBroker

Shelly Plug-S

on({id: "shelly.0.SHWND-S#XXXXXX5#1.open", change: "ne"}, function (obj) {
    setState("shelly.0.SHPLG-S#DE69XX#1.Relay0.Switch",obj.state.val);
});

Shelly 1

on({id: "shelly.0.SHWND-S#XXXXXX5#1.open", change: "ne"}, function (obj) {
    setState("shelly.0.SHSW-PM#765BXX#1.Relay0.Switch",obj.state.val);
});

Shelly 2.5

on({id: "shelly.0.SHWND-S#XXXXXX5#1.open", change: "ne"}, function (obj) {
    setState("shelly.0.SHSW-25#F3FXXB#1.Relay0.Switch",obj.state.val);
});

In Zeile 2 bitte darauf achten, den richtigen Schaltpunkt auszuwählen.

Nun werden die Shelly Geräte durch den Status des Fensterkontaktes geschaltet.

Fenster

Shelly Fensterkontakt mit HomeMatic Heizkörperthermostat

Seit geraumer Zeit bietet Shelly auch Fensterkontakte an. Diese haben zusätzlich einen Helligkeitssensor eingebaut, den Du für die Rollladensteuerung mit einem Shelly 2.5 nutzen kannst. Aber, was ist, wenn Du bereits Heizkörperthermostate von HomeMatic verbaut hast? Normalerweise verknüpft man die Komponenten in HomeMatic per direkter Verknüpfung. Dies klappt mit einem Shelly natürlich nicht.

Aber halt, hier gibt es Abhilfe mit einem Skript in ioBroker. Du abonnierst einfach den Datenpunkt des Shelly und reagierst auf die Öffnung des Fenster und schaltest so das Heizkörperthermostat auf den manuellen Modus. Später, wenn das Fenster wieder verschlossen ist, kannst Du wieder den Auto-Modus aktivieren.

Installation des Shelly Adapter

Installation des Shelly Adapter
Installation des Shelly Adapter

Nach kurzer Zeit stehen die Datenpunkte aller gefundenen Shellys unter shelly.0 zur Verfügung.

Skript für das Heizkörperthermostat in ioBroker

on({id: "shelly.0.SHWND-S#XXXXXX5#1.open", change: "ne"}, function (obj) {
    if (obj.state.val === true) {
        setState("hm-rpc.0.KEQ10419XX.4.AUTO_MODE",false);
    } else {
        setState("hm-rpc.0.KEQ10419XX.4.AUTO_MODE",true);
    }  
});

Jetzt schaltet sich das Heizkörperthermostat auf den manuellen Modus, sobald das Fenster geöffnet wurde.

Hast Du allerdings ein Wandthermostat per direkter Verknüpfung an das Heizkörperthermostat angelernt, so macht es Sinn, dieses anzusteuern, da das Wandthermostat das Heizkörperthermostat in diesem Fall steuert und so die Werte immer überschreiben würde.

Skript für das Wandthermostat

on({id: "shelly.0.SHWND-S#XXXXXX5#1.open", change: "ne"}, function (obj) {
    if (obj.state.val === true) {
        setState("hm-rpc.0.LEQ09997XX.2.AUTO_MODE",false);
    } else {
        setState("hm-rpc.0.LEQ09997XX.2.AUTO_MODE",true);
    }  
});
KeyMatic

HomeMatic KeyMatic mit NFC Tag öffnen und schließen

Die KeyMatic von HomeMatic habe ich bereits seit Jahren im Einsatz und sie läuft ohne Probleme. Nun habe ich mir überlegt, wie man NFC in die KeyMatic integrieren kann, damit auch eine Öffnung möglich ist, wenn man das Smartphone benutzt.

Um dies zu realisieren benötigst Du nur ein Set von NFC Tags (Aufkleber). Diese dienen hier nur als Auslöser für ein Makro und beinhalten keine sonstigen Informationen.

Programm für die HomeMatic

Ich habe hier ein Programm erstellt, welches zuerst den Status des Schlosses ermittelt (geöffnet/geschlossen). Somit wird das Schloss geöffnet, wenn es verschlossen ist und verschlossen, wenn es aufgeschlossen ist.

Programm zum Öffnen oder Schließen der Tür
Programm zum Öffnen oder Schließen der Tür

Achtung: Dieses Programm hat keinen Auslöser, somit wird das Programm immer ausgeführt, wenn die Zentrale neu startet.

! KeyMatic steuern ####################################
var schloss = dom.GetObject("BidCos-RF.LEQXXXXXX:1.STATE").Value();

if (schloss) {
	WriteLine("Schloss ist auf und wird abgeschlossen!");
	dom.GetObject("BidCos-RF.LEQXXXXXX:1.STATE").State(0);
	dom.GetObject(950).State(0);
} else {
	WriteLine("Schloss ist abgeschlossen und wird geöffnet!");
	dom.GetObject(950).State(1);
	dom.GetObject("BidCos-RF.LEQXXXXXX:1.OPEN").State(1);
}

Der Name des Programms sollte nach Möglichkeit keine Sonderzeichen oder Leerzeichen enthalten, da er sonst später nicht aufgerufen werden kann.

Nachdem das Programm erstellt worden ist, kannst Du dich an die Einrichtung eines Makros in MacroDroid machen.

Als Auslöser stellst Du NFC Sticker ein und als Aktion den Aufruf als HTTP GET (Ohne Web Browser). Beim Auswählen des NFC Sticker muss dieser bereitliegen, da er gescannt wird. Ein Name “Haustuer” o.ä. ist hier hilfreich, damit man die Sticker später auseinander halten kann. MacroDroid schreibt nun nur den Namen auf den Sticker und speichert diesen ab. Es kann also mit dem NFC Tag ansich kein Unfug getrieben werden, da er nur die Information seines Namens beinhaltet.

Die Adresse für den Aufruf über MacroDroid stellst Du wie folgt ein:

http://IP-DEINER-CCU:8181/x.exe?Antwort=dom.GetObject("geheimer_Tueroeffner").ProgramExecute()

geheimer_Tueroeffner ist hier der Name des Programms, welches über den Aufruf der URL gestartet wird. Ich habe hier bewusst die lokale IP benutzt, da somit auch sichergestellt ist, dass die CCU weiterhin nicht von Außen erreichbar sein muss.

Solltest Du nur die Öffnung der Türe benötigen, so kannst Du das HomeMatic Programm von oben wieder entfernen und den Aufruf der Adresse von MacroDroid in folgenden Aufruf abändern:

http://IP-DEINER-CCU:8181/x.exe?Antwort=dom.GetObject("BidCos-RF.LEQXXXXXXX:1.OPEN").State(1)

Nun kannst Du den Sticker in die Nähe Deines Türschlosses o. ä. kleben und zum Testen Dein Handy an diesen halten.
Bitte beachte: Bei neueren Android Versionen muss das Handy entsperrt sein, damit der Tag gelesen werden kann. Dies ist aus Sicherheitsgründen so gewollt, da so auch Zahlungen bei gesperrtem Smartphone getätigt werden könnten.

Volume

In VIS auf Onkyo Favoriten zugreifen und steuern

Um auf die verschiedenen Internet Radio Favoriten Deines Onkyo Receivers von VIS aus zugreifen zu können benötigst du ein ctrl – Icon State Widget.

Zuerst aber legst Du dir die Favoriten über die Weboberfläche deines Onkyo Receivers an. Dazu öffnest Du die IP des Receivers in einem Browser deiner Wahl und wechselst auf den Tab “My Favorites”.

Hier kannst Du nun die Namen der gewünschten Radio Station und deren URL eingeben.

Internet Radio Favoriten anlegen

Internet Radio Favoriten anlegen
Internet Radio Favoriten anlegen

Du kannst in der ersten Spalte bereits eine ID ablesen, die uns später den Zugriff auf den Favoriten erlaubt. Mit einem Klick auf “Save” werden die eingegebenen Favoriten abgespeichert.

Favoriten Zugriff in VIS anlegen

Um nun einen Favoriten mit einem Klick aktivieren zu können, ziehst Du dir das folgende Widget auf deine View.

ctrl - Icon State Widget
ctrl – Icon State Widget

Diesem Widget weist du nun den folgenden Datenpunkt zu:

onkyo.0.Zone1.NetRadioPreset

Damit du nun diesen Datenpunkt verändern kannst, musst natürlich noch ein Wert übergeben werden. Dieser Wert entspricht der ID des Favoriten, den Du gerne abspielen möchtest. Dem Widget kannst Du nun auch noch einen Text zuweisen, damit Du weißt, welcher Favorit hier abgespielt werden soll.

Control Widget einrichten
Control Widget einrichten

Wenn Du nun deine View aufrufst und das Widget anklickst, sollte sich der Receiver automatisch einschalten, den Kanal auf .Net stellen und den entsprechenden Sender wiedergeben. Damit ist das Widget schon einmal funktional.

Favoriten Widget mit Senderlogo

Zu schöneren Ansicht in der View kannst Du dem Favoriten auch ein Senderlogo hinterlegen.

Über die Google Bildersuche kannst Du passende Senderlogos suchen und herunterladen. Diese werden über den integrierten Dateimanager wie folgt hochgeladen.

Senderlogos über den Dateimanager hochladen
Senderlogos über den Dateimanager hochladen

Nachdem Du nun die Logos via Dateimanager hochgeladen hast, kannst Du sie dem entsprechenden Favoriten hinzufügen.

Dazu wählst du erneut das Widget aus, entfernst den vorher eingegebenen Text und erreichst über das kleine Symbol neben “Quelle” den Dateimanager erneut. Dort kannst Du das Senderlogo auswählen und dem Widget zuweisen. Über width und height im Bereich CSS Allgemein kannst Du die entsprechende Breite und Höhe definieren.

Senderlogo dem Widget zuweisen
Senderlogo dem Widget zuweisen

Eine passende View für den Receiver stelle ich Dir im nächsten Beitrag vor.

View für den Onkyo Receiver
View für den Onkyo Receiver

ioBroker eigene Protokoll Funktion (Logging) erstellen

Über ein kleines Javascript lässt sich eine Protokoll Funktion in ioBroker erstellen. Diese ordnet die Ereignisse chronologisch, färbt sie entsprechend ihrer Bedeutung (Info, Warnung, Fehler) ein und weist ihnen ein kleines Symbol zu.

Javascript erstellen

Zuerst erstellst Du ein neues Javascript im Bereich global.

 // Hauptdatenpunkt unterhalb javascript
  var datenpunkt = "Ereignisprotokoll.";
  
  // Mögliche Protokoll-Texte
  const texte = ["Info","Warnung","Fehler"];
  
  // Farben zu den Texten (schwarz, gelb, rot)
  const farbe = ["#000000","#F0DB4F","#EF5350"];
  
  // Symbole zu den Texten
  const symbol = ["ⓘ","⚠","☠"];
   
  function Protokoll(typ, Text) {
      // Protokoll abholen
      var Protokoll_Liste = getState(datenpunkt+"Ereignisse").val;
      var datum = formatDate(new Date(), "TT.MM.JJ hh:mm:ss");
  
      // Neues Protokoll generieren
      let tmp_Protokoll = datum + "<span style=\"display:inline-block;width:90px;margin-left:10px;color:" + farbe[typ] + "\">"
      + symbol[typ] + " " + texte[typ] + "</span>" + Text + "<br>";
  
      // Neues Protokoll an den Anfang setzen
      Protokoll_Liste = tmp_Protokoll + Protokoll_Liste;
  
      // Neues Protokoll in Datenpunkt speichern
      setState(datenpunkt + "Ereignisse", Protokoll_Liste);
  }
  
  // Zugehörige Datenpunkte erstellen
  function erstelleDatenpunkte() {
      // Datenpunkt Protokoll
      createState(datenpunkt+"Ereignisse", "", false, {
          name: "Ereignisprotokolle",
          desc: "Protokoll Funktion über JavaScript",
          type: "string",
          role: "text",
          unit: ""
      });    
  }
  
  // einmaliger Aufruf zum Erstellen der DP's
  erstelleDatenpunkte();
 

Skript verwenden

Da das Skript im globalen Bereich von Javascript liegt, kann jedes Skript nun auf diese Funktion zugreifen. Der Aufruf erfolgt nach folgendem Schema.

Beispiel 1:

 Protokoll(0, "Ich bin eine Information!");
 

Beispiel 2:

 Protokoll(1, "Ich bin eine Warnung!");
 

Beispiel 3:

 Protokoll(2, "Ich bin ein Fehler!");
 

Tür- bzw. Fensterkontakt protokollieren

In diesem Skript wird das Öffnen und schließen eines Fensters protokolliert.

 // Protokoll - 0 - Information
  on({id: "hm-rpc.0.LEQ01737XX.1.STATE", change: "ne"}, function (obj) {
      if (obj.state.val === true) {
          Protokoll(0, "Wohnzimmer Fenster wurde geöffnet!");
      } else {
          Protokoll(0, "Wohnzimmer Fenster wurde geschlossen!");
      }
  });
 

Die erste Zahl ist jeweils einem Index zugewiesen. Hier 0 = Information, 1 = Warnung und 2 = Fehler. Der Text danach kann frei im Funktionsaufruf belegt werden.

Protokoll in VIS einbinden

Damit Du nun nicht nur eine Ereignisdatenbank in ioBroker hast, sondern sie auch darstellen lassen kannst, benötigst du nur ein HTML Widget, welches Du auf einer View platzierst.

HTML Widget auf der View platzieren
HTML Widget auf der View platzieren

Dem Widget weisen wir nun den Datenpunkt aus dem Skript hinzu.

 {javascript.0.Ereignisprotokoll.Ereignisse}
 
HTML Widget mit zugewiesenem Datenpunkt
HTML Widget mit zugewiesenem Datenpunkt

Die Schriftfarbe lässt sich über über die Eigenschaften des Widgets anpassen.

Farbanpassung des HTML Widget
Farbanpassung des HTML Widget

Widget in View anzeigen

Nun kannst Du deine View öffnen und die Ereignisse anzeigen lassen.

Ereignisse in VIS anzeigen
Ereignisse in VIS anzeigen

Scrollbare Ereignisanzeige

Die Ereignisanzeige wird bei jedem Aufruf natürlich um ein Element verlängert. Damit Du in der Liste noch die Möglichkeit hast, ältere Elemente abzurufen, kannst Du das Scrollen der Liste aktivieren. Dies geschieht über:

Scrollen der Ereignisse ermöglichen
Scrollen der Ereignisse ermöglichen

overflow-y ist in dem Falle der senkrechte Scrollbalken; overflow-x der Vertikale.

So sieht es aus:

Ereignisse mit Scrollbalken anzeigen
Ereignisse mit Scrollbalken anzeigen

Ereignisanzeige für geöffnete/geschlossene Fenster

Die Protokollfunktion aus dem Beispiel oberhalb sieht in VIS so aus:

Ereignisanzeige für geöffnete/geschlossene Fenster
Ereignisanzeige für geöffnete/geschlossene Fenster
Fernbedienung

Shelly RGBW mit Shelly Plug-S synchronisieren

Ich steuere bei mir hinter dem TV eine LED Lichtleiste mit einem Shelly RGBW2 an. Damit nun auch die Vitrinenbeleuchtung im Schrank nebenan mit eingeschaltet wird, habe ich diese noch über einen Shelly Plug-S angeschlossen.

Installation des Shelly Adapter

Installation des Shelly Adapter
Installation des Shelly Adapter

Nach kurzer Zeit stehen die Datenpunkte aller gefundenen Shellys unter shelly.0 zur Verfügung.

Per Javascript abonniere ich nun den Schaltzustand der LED Beleuchtung hinter dem TV und übertrage sie auf den Shelly Plug-S.

//Skript zum Synchronisieren des Shelly Plug-S im Wohnzimmer
var master = "shelly.0.SHRGBW2#6F65XX#1.color";
var slave_1 = "shelly.0.SHPLG-S#51D5XX#1.Relay0";

on({id: master+".Switch", change: "any"}, function (obj) 
{
    //Zustand des 1. Slave Shelly setzen
    setState(slave_1+".Switch", obj.state.val);
});
Update

ioBroker Adapter aktualisieren

ioBroker wird ständig weiterentwickelt und so kommt es vor, das auch die Adapter neue Versionen zur Verfügung stellen. Diese bieten meist Fehlerbehebungen, als auch neue Funktionen an, die implementiert wurden.

Adapter auf der Weboberfläche aktualisieren

Über den Adapter Bereich in ioBroker lässt sich der Filter für die Adapter setzen, die aktualisiert werden können.

Aktualisierbare Adapter in ioBroker
Aktualisierbare Adapter in ioBroker

Danach kannst Du über den Pfeil vor der neuen Versionsnummer den Adapter auf die neue Version aktualisieren. Beachte bitte, das der Adapter danach automatisch neu gestartet wird. Wenn mehrere Adapter zu aktualisieren sind, so kannst auf die Flagge klicken und es werden alle Adapter nacheinander aktualisiert.

Alle Adapter aktualisieren
Alle Adapter aktualisieren
Astro

ioBroker Astro-Tageszeit abfragen und in Datenpunkt eintragen

In ioBroker kannst Du mit den Astro Funktionen eine ganze Menge abfragen. Aber jede Astrozeit immer in jedem Skript abzufragen ist lästig, oder? Richtig! Mit diesem Skript kannst du global alle Werte der Astro Funktion abfragen und in passenden Datenpunkten abspeichern. Das Skript erstellt beim ersten Aufruf automatisch die benötigten Datenpunkte und sollte im common Bereich erstellt werden. Der Aufruf des Skripts geschieht alle 30 Minuten automatisch und kann in der letzten Zeile angepasst werden.
Hier kann es natürlich vorkommen, das die ein oder andere Tageszeit übersprungen wir, da sie nur 2-5 Minuten (gerade im Sommer: Sonnenauf- und untergang innerhalb von 5 Minuten) auseinander liegen. Zusätzlich gibt es 6 Variablen, die den aktuellen Astro – Zustand anzeigen (tageszeitAstro, naechsteTageszeitAstro, tageszeitLesbar, naechsteTageszeitLesbar, aktuelleAstroZeit, Tag). Die Variable Tag steht zwischen Sonnenauf- und untergang auf Tag.

Extra: Bei jedem Durchlauf des Skriptes wird überprüft, ob die eingetragene Uhrzeit bereits vergangen ist. Wenn ja, wird hier schon der Wert für die nächste Zeit dieses Ereignisses gespeichert. Auch bekommst du im Log immer eine Übersicht, wie der aktuelle Durchlauf des Skriptes abgelaufen ist.

Screenshot der verfügbaren Variablen

Screenshot der verfügbaren Variablen
Screenshot der verfügbaren Variablen

Ausgabe im Log

Log-Ausgabe
Log-Ausgabe

Skript

// Astro Zeiten erstellen
// Datenpunkte neu erstellen
var ueberschreiben = false;

// Hauptdatenpunkt unterhalb javascript
var datenpunkt = "Astro.";

// Lesbare Zeiten
const lesbare_zeiten = ["Früher Morgen","Frühe Dämmerung","Morgendämmerung","Sonnenaufgang","Vormittag","später Vormittag","Mittag",
                    "früher Abend","Abend","Sonnenuntergang","Abenddämmerung","später Abend","Nacht","Mitternacht"];

// Objekte der Astro Zeiten
const objekt = ["nightEnd","nauticalDawn","dawn","sunrise","sunriseEnd","goldenHourEnd","solarNoon","goldenHour",
            "sunsetStart","sunset","dusk","nauticalDusk","night","nadir","tageszeitAstro","naechsteTageszeitAstro",
            "tageszeitLesbar","naechsteTageszeitLesbar","aktuelleAstroZeit","Tag"];

// Zustände der Astro-Zeiten
const beschreibung = ["00 - Ende der Nacht","01 - nautische Morgendämmerung","02 - Morgendämmerung","03 - Sonnenaufgang",
            "04 - Ende des Sonnenaufgangs","05 - Ende der goldenen Stunde VM","06 - Mittag", "07 - goldene Abendstunde",
            "08 - Start des Sonnenuntergangs","09 - Sonnenuntergang","10 - Dämmerung Abends","11 - nautische Dämmerung abends",
            "12 - Start der Nacht","13 - Mitternacht","Aktuelle Tageszeit (Astro)","Nächste Tageszeit (Astro)", 
            "Aktuelle Tageszeit (lesbar)","Nächste Tageszeit (lesbar)","aktuelle Astrozeit","Solange die Sonne scheint, ist Tag"];

// Erstelle die benötigten Datenpunkte
function datenpunkte_erstellen() {
    for(var i = 0; i < objekt.length; i++) {
        createState(datenpunkt+objekt[i], "", ueberschreiben, {
        name: beschreibung[i],
        desc: beschreibung[i],
        type: "string",
        role: "value",
        unit: ""
        });
    }
    log("Astro: Datenpunkte erstellt!");
}

// Datenpunkte mit erstem Inhalt füllen
function datenpunkte_fuellen() {
    for (var i = 0; i < objekt.length-6; i++) {
        var datum = new Date();
        var astro_zeit = zeit_formatieren(getAstroDate(objekt[i], datum));
        if (astro_zeit=="Invalid Date") {
            astro_zeit = "00:00";
        }
        setState(datenpunkt+objekt[i], astro_zeit);
    }
    log("Astro: Erste Datenpunkte gefüllt!");
}

// Haupt-Skript
function update_astro_zeiten() {
    var datum = new Date();
    var uhrzeit = zeit_formatieren(datum);

    // Zustand der Daten
    var aktuell = 0;
    var aktualisiert = 0;
    var keine_aktualisierung = 0;
    var astro_index = 0;

    // Aktuellen Tagesabschnitt bestimmen
    var ergebnis = -1;
    var naechste_element = false;

    // Aktuelle & kommende Tageszeit
    var aktuelle_tageszeit = 0;
    var kommende_tageszeit = 0;

    // Tag
    var astroTag = "Nacht";
    
    for (var i = 0; i < objekt.length-6; i++) {
        // Temporäre Zahl
        var tmp_ergebnis = 0;

        // Hole Uhrzeit aus aktuellem Datenpunkt
        var dp_zeit = getState(datenpunkt+objekt[i]).val;
        
        // Hole Index aktuelle Tageszeit
        var tmp_time_uhr = Date.parse('1970-01-01 '+uhrzeit+':00');
        var tmp_time_dp = Date.parse('1970-01-01 '+dp_zeit+':00');
        
        // Aktuelle Zeit ist kleiner als DP
        if (tmp_time_uhr<tmp_time_dp) {
            tmp_ergebnis = tmp_time_dp-tmp_time_uhr;
            if (tmp_ergebnis<=ergebnis || ergebnis==-1) {
                ergebnis = tmp_ergebnis;
                astro_index = i;
                naechste_element = true;
            }
        // Aktuelle Zeit ist größer als DP
        } else {
            tmp_ergebnis = tmp_time_uhr-tmp_time_dp;
            if (tmp_ergebnis<=ergebnis || ergebnis==-1) {
                ergebnis = tmp_ergebnis;
                astro_index = i;
                naechste_element = false;
            }
        }
        // Datenpunkt ist kleiner als aktuelle Uhrzeit. Update!
        if (dp_zeit<uhrzeit) {
            // Neue Astro-Zeit für den nächsten Tag generieren
            var morgen = new Date();
            morgen.setDate(morgen.getDate() + 1);
            var astro_zeit = zeit_formatieren(getAstroDate(objekt[i], morgen));
            // Datenpunkt und Astro Zeit sind gleich. Kein Update!
            if (dp_zeit==astro_zeit) {
                keine_aktualisierung++;
            } else {
                if (astro_zeit=="Invalid Date") {
                    astro_zeit = "00:00";
                }                
                setState(datenpunkt+objekt[i], astro_zeit);
                aktualisiert++;
            }
        } else {
            // Zeit kommt noch! Kein Update!
            aktuell++;
        }
    }
    // Wenn wahr, ist der Abstand zum nächsten Zeitpunkt kleiner. Also -1 um aktuellen Index zu erhalten.
    if (naechste_element) {
        astro_index--;
    }
    
    // Navigiere zum richtigen Index
    if (astro_index>12) {
        aktuelle_tageszeit = 13;
        kommende_tageszeit = 0;
    } else if (astro_index<0) {
        aktuelle_tageszeit = 0;
        kommende_tageszeit = 1;
    }else {
        aktuelle_tageszeit = astro_index;
        kommende_tageszeit = astro_index+1;
    }

    // Prüfe, ob aktuelle Uhrzeit zwischen Sonnenauf- und untergang liegt
    if (astro_index>2 && astro_index<10) {
        astroTag = "Tag";
    }

    // Update aktuelle Tageszeit Astro (Text)
    setState(datenpunkt+objekt[14],text_formatieren(beschreibung[aktuelle_tageszeit]));
    
    // Update kommende Tageszeit Astro (Text)
    setState(datenpunkt+objekt[15],text_formatieren(beschreibung[kommende_tageszeit]));

    // Update aktuelle Tageszeit lesbar (Text)
    setState(datenpunkt+objekt[16],lesbare_zeiten[aktuelle_tageszeit]);

    // Update kommende Tageszeit lesbar (Text)
    setState(datenpunkt+objekt[17],lesbare_zeiten[kommende_tageszeit]);

    // Update aktuelle AstroZeit
    setState(datenpunkt+objekt[18],objekt[aktuelle_tageszeit]);

    // Setze die Variable "Tag" auf "Tag", wenn Uhrzeit zwischen Sonnenauf- und untergang
    setState(datenpunkt+objekt[19],astroTag);
        
    var ausgabe = "Astro: Gültige Zeiten: [aktueller Tag: "+aktuell+"] | [nächster Tag: " +keine_aktualisierung+"] | [Aktualisiert: "+ aktualisiert+
                "] | Aktuelle Tageszeit: "+lesbare_zeiten[aktuelle_tageszeit]+" | Kommende Tageszeit: "+lesbare_zeiten[kommende_tageszeit];
    log (ausgabe);
}

// Funktion, um die Zeit in HH:MM zu formatieren
function zeit_formatieren(zeit) {
    return zeit.toLocaleTimeString('de-DE',{ hour12: false, hour:'2-digit', minute:'2-digit' });
}

// Funktion, um den Text zu formatieren. "Mittag" statt "6 - Mittag"
function text_formatieren(text) {
    text = text.split("-")[1];
    text = text.substr(1, text.length);
    return text;
}

// Erster Start des Skripts und anlegen der Datenpunkte
function update_astro_zeiten_erster_start() {
    log ("Astro: Erster Start des Skriptes!")
    // Datenpunkte werden erstellt
    datenpunkte_erstellen();

    // erstes Füllen der Datenpunkte um 3 Sek. verzögert
    setTimeout(datenpunkte_fuellen,3000);

    // Das Update der Zeiten ist um 5 Sek. verzögert
    setTimeout(update_astro_zeiten,5000);
}

// Erster Start und Initialisierung
update_astro_zeiten_erster_start();

// Alle 60 Minunten das Hauptskript ausführen
schedule('*/30 * * * *', update_astro_zeiten);

Einbindung in VIS

Um nun die aktuelle Tageszeit in VIS anzeigen zu können, kannst Du einfach ein String Widget auf deine View ziehen und den Datenpunkt verknüpfen.

String Widget
String Widget auf der View platzieren

Folgender Datenpunkt wird dem String zugewiesen:

javascript.0.Astro.tageszeitLesbar
Datenpunkt der Tageszeit