Ultimative Rolladensteuerung

Problemlösungen und Hinweise von allgemeinem Interesse zur Haussteuerung mit HomeMatic

Moderator: Co-Administratoren

Benutzeravatar
Tecky80
Beiträge: 61
Registriert: 28.04.2016, 07:10
Danksagung erhalten: 1 Mal

Re: Ultimative Rolladensteuerung

Beitrag von Tecky80 » 30.01.2017, 14:24

Hallo,
folgendes steht in der Datei:

Code: Alles auswählen

#!/bin/sh

if [ $# -lt 2 ]; then
   echo "Fehlerhafter Aufruf!"
   echo "Es müssen 2 Parameter übergeben werden, der Erste ist der Längengrad, der Zweite der Breitengrad:"
   echo "z. B. ./GetAstroDates.sh 51.188499 6.812093"
fi

wget -q --header="User-Agent: Mozilla" "http://www.calsky.com/cs.cgi/Sun/2?lang=de&showtwilight=true&hideglos=true&dateNow&lon=${1}&lat=${2}" -O - | sed -e 's/[<]/\n&/g;s/&nbsp;//g;/class="caltab"/,/<\/table>/!d' | sed -e 's/\(<b>\|<tt>\)//g;/\(Aufgang\|Untergang\|Begin\|Morgen\)/!d;s/\(Ende\|Abend\|Tag\)/\n&/g' | sed -e ':a;N;$!ba;s/\n/;/g;s/ //g;s/:/-/g;s/h/:/g;s/m//g;s/ ;/;/g'
Gruß
Tecky80
"Habe Angst, dass der Elektriker ein Terrorist ist. Er sprach irgendwas von ,Kosten vor Anschlag‘"

sailor79ac

Re: Ultimative Rolladensteuerung

Beitrag von sailor79ac » 30.01.2017, 15:36

Sieht erstmal gut aus.

Das letzte was mit noch einfällt ist ein Zeichenproblem bei der Intpretierung zwischen DOS/UNIX (versteckte Returns), falls du Windows nutzt.

Hierzu folgender Workararound (ohne Gewähr!):

per ssh (bzw. putty etc)

Code: Alles auswählen

apt-get install dos2unix
cd /usr/local/
dos2unix GetAstroDates.sh
sh GetAstroDates.sh
Update:
bzw. besser:

Code: Alles auswählen

sed -n l /usr/local/GetAstroDates.sh
cd /usr/local/
sh GetAstroDates.sh

Benutzeravatar
Tecky80
Beiträge: 61
Registriert: 28.04.2016, 07:10
Danksagung erhalten: 1 Mal

Re: Ultimative Rolladensteuerung

Beitrag von Tecky80 » 30.01.2017, 15:56

sailor79ac hat geschrieben:Sieht erstmal gut aus.

Das letzte was mit noch einfällt ist ein Zeichenproblem bei der Intpretierung zwischen DOS/UNIX (versteckte Returns), falls du Windows nutzt.

Hierzu folgender Workararound (ohne Gewähr!):

per ssh (bzw. putty etc)

Code: Alles auswählen

apt-get install dos2unix
cd /usr/local/
dos2unix GetAstroDates.sh
sh GetAstroDates.sh
Update:
bzw. besser:

Code: Alles auswählen

sed -n l /usr/local/GetAstroDates.sh
cd /usr/local/
sh GetAstroDates.sh
Super! Nun funktioniert auch das Aufrufen über das CCU Program.
Vielen Dank!
"Habe Angst, dass der Elektriker ein Terrorist ist. Er sprach irgendwas von ,Kosten vor Anschlag‘"

dodi
Beiträge: 137
Registriert: 26.12.2016, 11:59
Hat sich bedankt: 2 Mal

Re: Ultimative Rolladensteuerung

Beitrag von dodi » 03.03.2017, 12:24

Hallo zusammen,
ich hatte jetzt den Fall, dass die CCU keine Verbindung zum Internet hatte,
und somit sich Nachts die Astro Daten nicht ziehen konnte.
Dies führte dazu, dass die eingelesenen Zeiten alle auf Null standen,
und die Berechnung nicht funktionierte.
Ich würde am Liebsten die Internetverbindung noch überwachen, und sämtliche Skripte die Internet benötigen nur abfragen,
wenn die Verbindung OK ist.
Hat jemand schon so etwas realisiert?
Oder ist es vielleicht besser, das Skript so aufzubauen, dass beim Einlesen von "Null"-Werten automatisch die Frühestens/Spätestens Zeiten verwendet werden?

Grüße
Sascha

Xel66
Beiträge: 14277
Registriert: 08.05.2013, 23:33
System: Alternative CCU (auf Basis OCCU)
Wohnort: Nordwürttemberg
Hat sich bedankt: 599 Mal
Danksagung erhalten: 1527 Mal

Re: Ultimative Rolladensteuerung

Beitrag von Xel66 » 03.03.2017, 12:33

dodi hat geschrieben:und somit sich Nachts die Astro Daten nicht ziehen konnte.
Die braucht sie nicht zu holen. Die berechnet sie aus der Angabe der Position und vergleicht sie mit der Uhrzeit. Sie konnte vielleicht maximal nicht ihre eigene Uhr korrigieren. Das dürfte aber nicht zu derartigen Ausfällen führen, denn die interne Uhr läuft ja weiter. Es wird nur nicht der Drift korrigiert. Ich vermute eher einen Reboot ohne dass sie sich die Uhrzeit holen konnte. Dann weiß sie nicht, wie spät es ist und kann natürlich keine von der Uhrzeit abhängigen Programme starten.

Gruß Xel66
-------------------------------------------------------------------------------------------
524 Kanäle in 146 Geräten und 267 CUxD-Kanäle in 34 CUxD-Geräten:
343 Programme, 334 Systemvariablen und 183 Direktverknüpfungen,
RaspberryMatic Version: 3.65.11.20221005 + Testsystem: CCU2 2.61.7
-------------------------------------------------------------------------------------------
Einsteigerthread, Programmlogik-Thread, WebUI-Handbuch

Franzens
Beiträge: 147
Registriert: 18.04.2014, 17:11
Hat sich bedankt: 15 Mal

Re: Ultimative Rolladensteuerung

Beitrag von Franzens » 03.03.2017, 21:13

...doch ich denke schon, dass über das Skript die Daten nachts via Internet geholt werden und dann die Timer gesetzt werden. wir reden hier nicht von den Astrodaten der CCU. Ich hatte ebenfalls mehrere Tage kein Netz und dementsprechend bleiben die Variablen für die Timer leer.
Die Frage ist nur, was hilfts wenn ich weiß, dass ich kein Netz habe? M.E. Helfen hier nur alternativ feste Zeiten in der "oder" Schleife

Franzens
RasberryMatic auf Synology-VM - Sonos - pocket Control HM - CuL V2 868mHz & Somfy RTS Anbindung - Pushover - hm-pdetect - homebridge - homeassistant - Alexa - Netatmo - Shelly - hue...; 373 Kanäle in 100 Geräten und 209 CUxD-Kanäle in 18 CUxD-Geräten

Magda
Beiträge: 7
Registriert: 09.03.2017, 09:05

Re: Ultimative Rolladensteuerung

Beitrag von Magda » 09.03.2017, 09:42

Ich hab mir die Version von Luckysnooze auf meine Bedürfnisse angepasst und stelle meine Version hier mal zur Verfügung. Ist noch nicht ganz schön, aber funktioniert und vor allem braucht man kein SSH, es läuft alles als Homematic Script.
Da ich im Script noch prüfe ob Wochenende oder Feiertag ist, ist die Systemvariablen Feiertag_heute notwendig. Das passende Feiertags-Script von Peter Beck findet man auch hier im Forum.
Zudem habe ich die Systemvariablen an meine Bedürfnisse angepasst (umbenannt mit S_, bzw. auch entfernt), wer das nicht mag kann es ja wieder ändern.
Es ist auch ein Backup implementiert, falls der REST Service einen Fehler zurück gibt, dann werden die Spätestens- und Frühestens-Zeiten genutzt.

Da ich das Script für meine Anwesenheitssimulation nutze, habe ich in v3 jetzt ein Zufallselement eingebaut, welches entweder den Offset zufällig setzt und bei den Frühestens- und Spätestens-Zeiten eine Varianz von 30 min hinzufügt.

Für die Daten nutze ich die den REST Service von sunrise-sunset.org. Die API ist hier zu finden: http://sunrise-sunset.org/api.
Für den Zufallswert wird die Webseite https://www.random.org genutzt.

Hier nochmal die Kurzanleitung:
1. Systemvariablen anlegen
2. CUxD Timer und Exec einrichten
3. Script per Programm täglich laufen lassen, möglichst nach 3 Uhr und vor dem Sonnenaufgang

Code: Alles auswählen

!# Astro Daten holen - Zeitpunkte setzen V1.05.3
!# folgende Variablen werden benötigt: 	S_Sonnenaufgang
!#										S_Sonnenuntergang
!#										S_Sonnenhochstand
!#										S_Tageslaenge
!#										S_BeginBuergDaemm
!#										S_EndBuergDaemm
!#										S_BeginNautDaemm
!#										S_EndNautDaemm
!#										S_BeginAstroDaemm
!#										S_EndAstroDaemm
!#										S_RolladenZu
!#										S_RolladenAuf
!#										Feiertag_heute


! -------------------- Schliessen Anpassungen ---------------------
!  S_Sonnenuntergang -> S_EndBuergDaemm -> S_EndNautDaemm -> S_EndAstroDaemm
var Zeit1_Zu = "S_Sonnenuntergang"; ! (Fruehere Zeit)
var Zeit2_Zu = "S_EndBuergDaemm"; ! (Spaetere Zeit)
var Offset_Zu = 85.0; ! (0.0 -> 100.0 %)
boolean random_Zu = true; !Offset_Zu als Zufallszahl und Spaet_Zu mit 30 min Varianz nach unten, sonst Festwert Offset_Zu
var Spaet_Zu = "21:00"; ! (Spaetester Schliessenzeitpunkt HH:MM)
var Spaet_Zu_frei = "22:00"; ! (Spaetester Schliessenzeitpunkt an Wochenenden/Feiertagen HH:MM)
! ---------------------- Oeffnen Anpassungen ----------------------
!  S_BeginAstroDaemm -> S_BeginNautDaemm -> S_BeginBuergDaemm -> S_Sonnenaufgang
var Zeit1_Auf = "S_BeginBuergDaemm"; ! (Fruehere Zeit)
var Zeit2_Auf = "S_Sonnenaufgang"; ! (Spaetere Zeit)
var Offset_Auf = 15.0; ! (0.0 -> 100.0 %)
boolean random_auf = true; ! Offset_Auf als Zufallszahl und Frueh_Auf mit 30 min Varianz nach oben, sonst Festwert Offset_Auf
var Frueh_Auf = "06:30"; ! (Fruehester Oeffnenzeitpunkt HH:MM)
var Frueh_Auf_frei = "07:30"; ! (Fruehester Oeffnenzeitpunkt an Wochenende/Feiertagen HH:MM)
! ------------------------ Ende Anpassung -------------------------

string sunsetUrl;
string Zeitpunkte;
string ReturnClean = "";
string ReturnList;
string Tmp;
string okStatus = "\"status\":\"OK\"";
string quoteSign = "\""; !"
integer Zaehler;
string Wert;
var cmd;
var Return;
var Rolladen_Zu;
var Rolladen_Auf;


! Befehl zusammenbauen
sunsetUrl = "http://api.sunrise-sunset.org/json?lat=" # system.Latitude() # "&lng=" # system.Longitude() # "&formatted=0&date=" # system.Date("%F");   
cmd = "wget -q -O - '" # sunsetUrl # "'";

! Befehl ausfuehren: Werte von Website holen
dom.GetObject("CUxD.CUX2801001:7.CMD_SETS").State(cmd);
dom.GetObject("CUxD.CUX2801001:7.CMD_QUERY_RET").State(1);
Return = dom.GetObject("CUxD.CUX2801001:7.CMD_RETS").State();

! Ergebnis des Aufrufs prüfen
if (Return.Find(okStatus) > 1) {
	! Anführungszeichen entfernen
	foreach(Wert, Return.Split(quoteSign)) {
		ReturnClean = ReturnClean # Wert;
	};
	! Liste erzeugen
	ReturnList = ReturnClean.Substr(10,ReturnClean.Length()-22); ! 10 + 12 vorne und hinten JSon abschneiden
	
	! Werte auslesen und in Systemvariablen schreiben
	Zeitpunkte = "S_Sonnenaufgang,S_Sonnenuntergang,S_Sonnenhochstand,S_Tageslaenge,S_BeginBuergDaemm,S_EndBuergDaemm,S_BeginNautDaemm,S_EndNautDaemm,S_BeginAstroDaemm,S_EndAstroDaemm";
	Zaehler = 0;
    foreach(Wert, Zeitpunkte.Split(",")) {
		Tmp = ReturnList.StrValueByIndex(",", Zaehler);
		Tmp = Tmp.Substr(Tmp.Find(":") + 1);
		if (Wert != "S_Tageslaenge") {
			! Umrechnung auf aktuelle Zeitzone
			Tmp = Tmp.StrValueByIndex("T", 0) # " " # Tmp.StrValueByIndex("T", 1).StrValueByIndex("+", 0);
			var uhrzeit = Tmp.ToTime().ToInteger();
			var zeitzone = (system.Date("%z").Substr(1,2).ToInteger())*3600 + system.Date("%z").Substr(3,2).ToInteger();
			var lokaleUhrzeit;
			if (system.Date("%z").Substr(0,1) == "+") {
				lokaleUhrzeit = uhrzeit + zeitzone;
			} else {
				lokaleUhrzeit = uhrzeit - zeitzone;
			}
			Tmp = lokaleUhrzeit.ToTime();
		} else {
			! Umrechnung in hh:mm:ss
			var tageslaenge = 0.0 + Tmp.ToInteger();
			var stunden = 1 * tageslaenge / 3600;
			var minuten = 1 * (((tageslaenge / 3600) - stunden) *60) ;
			var sekunden = 1 * ((((tageslaenge / 3600) - stunden) *60) - minuten) * 60;
			Tmp = stunden # ":" # minuten # ":" # sekunden;
		}
		dom.GetObject(Wert).State(Tmp);
		Zaehler = Zaehler + 1;
		WriteLine(Wert # ": " # Tmp);
	}
	
	! Prüfung ob Wochenende oder Feiertag
	if ((dom.GetObject("Feiertag_heute").Variable() == true) || 
		(system.Date("%w").ToInteger() == 6) ||
		(system.Date("%w").ToInteger() == 0)) {
			Frueh_Auf = Frueh_Auf_frei;
			Spaet_Zu = Spaet_Zu_frei;
	}
	
	!Zufallssteuerung für Zu
	if (random_Zu) {
		string randomNumURL = "https://www.random.org/decimal-fractions/?num=1&dec=2&col=2&format=plain&rnd=new";   
		string randCmdSSL = "LD_LIBRARY_PATH=/usr/local/addons/cuxd /usr/local/addons/cuxd/curl -s -k -L '" # randomNumURL # "'";
		! Befehl ausfuehren: Werte von Website holen
		dom.GetObject("CUxD.CUX2801001:5.CMD_SETS").State(randCmdSSL);
		dom.GetObject("CUxD.CUX2801001:5.CMD_QUERY_RET").State(1);
		var randomNum = 0.0 + dom.GetObject("CUxD.CUX2801001:5.CMD_RETS").State();
		if ((randomNum >= 0) && (randomNum <= 1)) {
			Offset_Zu = 0.0 + randomNum * 100;
			integer offsetMinutes = 0 + randomNum * 30;
			if (offsetMinutes < 10) {
				offsetMinutes = "0" # offsetMinutes;
			}
			WriteLine("Random Offset Zu: " # Offset_Zu);
			Spaet_Zu = (((("2000-01-01 " # Spaet_Zu # ":00").ToTime() - (("1970-01-01 00:" # offsetMinutes # ":00").ToTime() + 3600))).Format("%H:%M")); 
			
		}
	}
	
	!Zufallssteuerung für auf
	if (random_auf) {
		string randomNumURL = "https://www.random.org/decimal-fractions/?num=1&dec=2&col=2&format=plain&rnd=new";   
		string randCmdSSL = "LD_LIBRARY_PATH=/usr/local/addons/cuxd /usr/local/addons/cuxd/curl -s -k -L '" # randomNumURL # "'";
		! Befehl ausfuehren: Werte von Website holen
		dom.GetObject("CUxD.CUX2801001:5.CMD_SETS").State(randCmdSSL);
		dom.GetObject("CUxD.CUX2801001:5.CMD_QUERY_RET").State(1);
		var randomNum = 0.0 + dom.GetObject("CUxD.CUX2801001:5.CMD_RETS").State();
		if ((randomNum >= 0) && (randomNum <= 1)) {
			Offset_Auf = 0.0 + randomNum * 100;
			integer offsetMinutes = 0 + randomNum * 30;
			if (offsetMinutes < 10) {
				offsetMinutes = "0" # offsetMinutes;
			}
			WriteLine("Random Offset Auf: " # Offset_Auf);
			Frueh_Auf = (((("2000-01-01 " # Frueh_Auf # ":00").ToTime() + (("1970-01-01 00:" # offsetMinutes # ":00").ToTime() + 3600))).Format("%H:%M"));
		}
	}
	
	! Schliessen - Zeiten einlesen
	Zeit1_Zu = dom.GetObject(Zeit1_Zu).Variable();
	Zeit2_Zu = dom.GetObject(Zeit2_Zu).Variable();
	! Schliessen - Datum und Zeiten in Ganzzahl wandeln
	Zeit1_Zu = Zeit1_Zu.ToTime().ToInteger();
	Zeit2_Zu = Zeit2_Zu.ToTime().ToInteger();
	Spaet_Zu = system.Date("%F") # " " # Spaet_Zu;
	Spaet_Zu = Spaet_Zu.ToTime().ToInteger();
	! Schliessen - Zeit berechnen und mit Spaet_Zu vergleichen
	Rolladen_Zu = Zeit1_Zu + (0.0 + Zeit2_Zu - Zeit1_Zu) * Offset_Zu / 100.0;
	if (Rolladen_Zu > Spaet_Zu) {
		Rolladen_Zu = Spaet_Zu;
	}
	
	! Oeffnen - Zeit berechnen und mit Frueh_Auf vergleichen
    Zeit1_Auf = dom.GetObject(Zeit1_Auf).Variable();
    Zeit2_Auf = dom.GetObject(Zeit2_Auf).Variable();
    ! Oeffnen - Datum und Zeiten in Ganzzahl wandeln
	Zeit1_Auf = Zeit1_Auf.ToTime().ToInteger();
    Zeit2_Auf = Zeit2_Auf.ToTime().ToInteger();
    Frueh_Auf = system.Date("%F") # " " # Frueh_Auf;
    Frueh_Auf = Frueh_Auf.ToTime().ToInteger();
    ! Oeffnen - Zeit berechnen und mit Frueh_Auf vergleichen
    Rolladen_Auf = Zeit1_Auf + (0.0 + Zeit2_Auf - Zeit1_Auf) * Offset_Auf / 100.0;
    if (Rolladen_Auf < Frueh_Auf) {
		Rolladen_Auf = Frueh_Auf;
	}

} else {
	! Backup-Lösung falls REST_Service Fehler zurück gibt
	Spaet_Zu = system.Date("%F") # " " # Spaet_Zu;
	Spaet_Zu = Spaet_Zu.ToTime().ToInteger();
	Rolladen_Zu = Spaet_Zu;
	
	Frueh_Auf = system.Date("%F") # " " # Frueh_Auf;
    Frueh_Auf = Frueh_Auf.ToTime().ToInteger();
	Rolladen_Auf = Frueh_Auf;
	system.Exec("logger -t script -p user.debug Rollosteuerung konnte keine neuen Werte lesen Backup Werte werden verwendet");
}

! Schliessen - Zeit von Ganzzahl nach HH:MM:SS wandeln
Rolladen_Zu = Rolladen_Zu.ToTime().Format("%T");
!Oeffnen - Zeit von Ganzzahl nach HH:MM:SS wandeln
Rolladen_Auf = Rolladen_Auf.ToTime().Format("%T");

! Schliessen und Oeffnen Zeiten speichern und Timer setzen
dom.GetObject("S_RolladenZu").State(Rolladen_Zu);
dom.GetObject("CUxD.CUX2800001:1.TIMER_SET").State(Rolladen_Zu);
WriteLine(Rolladen_Zu);
dom.GetObject("S_RolladenAuf").State(Rolladen_Auf);
dom.GetObject("CUxD.CUX2800001:2.TIMER_SET").State(Rolladen_Auf);
WriteLine(Rolladen_Auf);
P.S.: Wer einen schöneren Weg kennt um JSON/XML zu parsen, immer raus damit!

Edit 1: Klammern gesetzt, da Wochenendabfrage nicht funktioniert hat.
Edit 2: Zufallswerte hinzugefügt.
Edit 3: Script sollte nach 3 Uhr laufen, damit die Zeitumstellung berücksichtigt wird.
Zuletzt geändert von Magda am 04.04.2017, 08:20, insgesamt 4-mal geändert.

dodi
Beiträge: 137
Registriert: 26.12.2016, 11:59
Hat sich bedankt: 2 Mal

Re: Ultimative Rolladensteuerung

Beitrag von dodi » 09.03.2017, 20:39

Franzens hat geschrieben:...doch ich denke schon, dass über das Skript die Daten nachts via Internet geholt werden und dann die Timer gesetzt werden. wir reden hier nicht von den Astrodaten der CCU. Ich hatte ebenfalls mehrere Tage kein Netz und dementsprechend bleiben die Variablen für die Timer leer.
Die Frage ist nur, was hilfts wenn ich weiß, dass ich kein Netz habe? M.E. Helfen hier nur alternativ feste Zeiten in der "oder" Schleife

Franzens
Mein Gedanke war,
dass Skript dann einfach nicht auszuführen.
Somit würden die bestehenden Werte erhalten bleiben, und es wird evtl. ein paar Minuten zu früh oder zu früh geschlossen/geöffnet.

Gruß Sascha

Franzens
Beiträge: 147
Registriert: 18.04.2014, 17:11
Hat sich bedankt: 15 Mal

Re: Ultimative Rolladensteuerung

Beitrag von Franzens » 09.03.2017, 20:45

Ja, daran habe ich auch schon mal gedacht. Aber da geht es mir wie dir, dass ich dafür bislang keine Lösung habe.

Gruß Franzens
RasberryMatic auf Synology-VM - Sonos - pocket Control HM - CuL V2 868mHz & Somfy RTS Anbindung - Pushover - hm-pdetect - homebridge - homeassistant - Alexa - Netatmo - Shelly - hue...; 373 Kanäle in 100 Geräten und 209 CUxD-Kanäle in 18 CUxD-Geräten

dodi
Beiträge: 137
Registriert: 26.12.2016, 11:59
Hat sich bedankt: 2 Mal

Re: Ultimative Rolladensteuerung

Beitrag von dodi » 12.03.2017, 18:51

Franzens hat geschrieben:Ja, daran habe ich auch schon mal gedacht. Aber da geht es mir wie dir, dass ich dafür bislang keine Lösung habe.

Gruß Franzens
Habe es jetzt folgendermaßen realisiert:
1. CuxD Ping Gerät eingerichtet, welches Google anpingt.
CUxD Ping - Google.jpg
2. Systemvariable anlegen, welchen den Zustand Online/Offline hat, und diese entsprechend des Ping Gerätes setzen.
PRG.000.SYS.SV.INet.Status.jpg
3. Astro Programm entsprechend abändern.
PRG.001.SYS.AstroDaten.jpg
Grüße
Sascha

Antworten

Zurück zu „HomeMatic Tipps & Tricks - keine Fragen!“