Terminerinnerung 1 Stunde vorher mit Sprachausgabe

Begonnen von rischbiter123, 31 Januar 2018, 14:29:44

Vorheriges Thema - Nächstes Thema

rischbiter123

Da ich hier nichts gefunden habe, vielleicht auch nur zu dumm zum Suchen, habe ich mich mal selber an einen kleinen Code gewagt. Vielleicht kann ihn ja der eine oder andere als Denkanstoss verwenden.
Voraussetzung: Definierte Kalender und Calview, der einfachkeit halber habe ich die Kalender nach ihren 'Besitzern' benannt.

Zuerst das DOIF zum Aufrufen der Subfunktionen:

define KalenderAnsage DOIF ([00:40] and [KalenderAndi:c-today] gt 0) (
{for(my $z = 1; $z <= [KalenderAndi:c-today]; $z++)
{
fhem( "{TerminMinus$z}" )
}
}
)

Dann habe ich eine Hilfsdatei 99_ZeitUtils.pm angelegt, es geht natürlich auch die 99_myUtils, man muß dann nur Zeile 14 anpassen.
Und hier der einzufügende Code:

##############################################
# $Id: myUtilsTemplate.pm 7570 2015-01-14 18:31:44Z rudolfkoenig $
#
# Save this file as 99_myUtils.pm, and create your own functions in the new
# file. They are then available in every Perl expression.

package main;

use strict;
use warnings;
use POSIX;

sub
ZeitUtils_Initialize($)
{
  my ($hash) = @_;
}

# Enter you functions below _this_ line.
sub TerminMinus1() {
  my $Termin1 = (ReadingsVal("KalenderAndi","today_001_btime",0)); # Anfangszeit des Termins
my @AR = split(/:/,$Termin1); # Aufteilung in Stunde, Minute, Sekunde
my $GR = $AR[0]; # Stunde Terminbeginn
my $HR = $AR[1]; # Minute Terminbeginn
my $BR = (--$AR[0]).":".$AR[1].":".$AR[2]; # Eine Stunde vor Terminbeginn
my $CR = $AR[0].":".$AR[1].":".($AR[2]+10); # Verzögerung um 10 Sekunden für zweite TTS-Instanz
my $DR = (ReadingsVal("KalenderAndi","today_001_source",0)); # Kalendername
my $ER = (ReadingsVal("KalenderAndi","today_001_summary",0)); # Terminname
my $FR = (ReadingsVal("KalenderAndi","today_001_location",0)); # Terminort
my $IR = $DR." hat um ".$GR." Uhr ".$HR." ".$ER." in ".$FR; # Zusammensetzen der Sprachausgabe
fhem( "define a1 at $CR set MyTTS tts $IR" ); # Setzen des Temporären at-Device
fhem( "define a2 at $BR set MyTTSwz tts $IR" );
}

sub TerminMinus2() {
  my $Termin2 = (ReadingsVal("KalenderAndi","today_002_btime",0));
my @AR2 = split(/:/,$Termin2);
my $GR2 = $AR2[0];
my $HR2 = $AR2[1];
my $BR2 = (--$AR2[0]).":".$AR2[1].":".($AR2[2]+15);
my $CR2 = $AR2[0].":".$AR2[1].":".($AR2[2]+20);
my $DR2 = (ReadingsVal("KalenderAndi","today_002_source",0));
my $ER2 = (ReadingsVal("KalenderAndi","today_002_summary",0));
my $FR2 = (ReadingsVal("KalenderAndi","today_002_location",0));
my $IR2 = $DR2." hat um ".$GR2." Uhr ".$HR2." ".$ER2." in ".$FR2;
fhem( "define a3 at $CR2 set MyTTS tts $IR2" );
fhem( "define a4 at $BR2 set MyTTSwz tts $IR2" );
}

sub TerminMinus3() {
  my $Termin3 = (ReadingsVal("KalenderAndi","today_003_btime",0));
my @AR3 = split(/:/,$Termin3);
my $GR3 = $AR3[0];
my $HR3 = $AR3[1];
my $BR3 = (--$AR3[0]).":".$AR3[1].":".($AR3[2]+25);
my $CR3 = $AR3[0].":".$AR3[1].":".($AR3[2]+30);
my $DR3 = (ReadingsVal("KalenderAndi","today_003_source",0));
my $ER3 = (ReadingsVal("KalenderAndi","today_003_summary",0));
my $FR3 = (ReadingsVal("KalenderAndi","today_003_location",0));
my $IR3 = $DR3." hat um ".$GR3." Uhr ".$HR3." ".$ER3." in ".$FR3;
fhem( "define a5 at $CR3 set MyTTS tts $IR3" );
fhem( "define a6 at $BR3 set MyTTSwz tts $IR3" );
}

sub TerminMinus4() {
  my $Termin4 = (ReadingsVal("KalenderAndi","today_004_btime",0));
my @AR4 = split(/:/,$Termin4);
my $GR4 = $AR4[0];
my $HR4 = $AR4[1];
my $BR4 = (--$AR4[0]).":".$AR4[1].":".($AR4[2]+35);
my $CR4 = $AR4[0].":".$AR4[1].":".($AR4[2]+40);
my $DR4 = (ReadingsVal("KalenderAndi","today_004_source",0));
my $ER4 = (ReadingsVal("KalenderAndi","today_004_summary",0));
my $FR4 = (ReadingsVal("KalenderAndi","today_004_location",0));
my $IR4 = $DR4." hat um ".$GR4." Uhr ".$HR4." ".$ER4." in ".$FR4;
fhem( "define a7 at $CR4 set MyTTS tts $IR4" );
fhem( "define a8 at $BR4 set MyTTSwz tts $IR4" );
}

sub TerminMinus5() {
  my $Termin5 = (ReadingsVal("KalenderAndi","today_005_btime",0));
my @AR5 = split(/:/,$Termin5);
my $GR5 = $AR5[0];
my $HR5 = $AR5[1];
my $BR5 = (--$AR5[0]).":".$AR5[1].":".($AR5[2]+45);
my $CR5 = $AR5[0].":".$AR5[1].":".($AR5[2]+50);
my $DR5 = (ReadingsVal("KalenderAndi","today_005_source",0));
my $ER5 = (ReadingsVal("KalenderAndi","today_005_summary",0));
my $FR5 = (ReadingsVal("KalenderAndi","today_005_location",0));
my $IR5 = $DR5." hat um ".$GR5." Uhr ".$HR5." ".$ER5." in ".$FR5;
fhem( "define a9 at $CR5 set MyTTS tts $IR5" );
fhem( "define a10 at $BR5 set MyTTSwz tts $IR5" );
}

sub TerminMinus6() {
  my $Termin6 = (ReadingsVal("KalenderAndi","today_006_btime",0));
my @AR6 = split(/:/,$Termin6);
my $GR6 = $AR6[0];
my $HR6 = $AR6[1];
my $BR6 = (--$AR6[0]).":".$AR6[1].":".($AR6[2]+55);
my $CR6 = $AR6[0].":".(++$AR6[1]).":".$AR6[2];
my $DR6 = (ReadingsVal("KalenderAndi","today_006_source",0));
my $ER6 = (ReadingsVal("KalenderAndi","today_006_summary",0));
my $FR6 = (ReadingsVal("KalenderAndi","today_006_location",0));
my $IR6 = $DR6." hat um ".$GR6." Uhr ".$HR6." ".$ER6." in ".$FR6;
fhem( "define a11 at $CR6 set MyTTS tts $IR6" );
fhem( "define a12 at $BR6 set MyTTSwz tts $IR6" );
}

1;


Hierdurch werden nachts Sprachausgaben für bis zu 6 Terminen generiert. Verbesserungsvorschläge sind gerne gesehen.
4*Raspi, Max Thermostate und Fensterkontakte, FB7590, Mysensors und NanoCUL, IT und Sonoff, zigbee2mqtt2

Phill

Mal davon abgesehen das ich nicht ganz durchsteige, gibt es die Möglichkeit Perlfunktionen Parameter zu übergeben.
Dann reicht eine Funktion völlig aus.
sub TerminMinus() {
my ($no, $cal) = @_;
  my $Termin1 = (ReadingsVal($cal,"today_00$no_btime",0)); # Anfangszeit des Termins
my @AR = split(/:/,$Termin1); # Aufteilung in Stunde, Minute, Sekunde
my $GR = $AR[0]; # Stunde Terminbeginn
my $HR = $AR[1]; # Minute Terminbeginn
my $BR = (--$AR[0]).":".$AR[1].":".$AR[2]; # Eine Stunde vor Terminbeginn
my $CR = $AR[0].":".$AR[1].":".($AR[2]+10*$no); # Verzögerung um 10 Sekunden für zweite TTS-Instanz
my $DR = (ReadingsVal($cal,"today_00$no_source",0)); # Kalendername
my $ER = (ReadingsVal($cal,"today_00$no_summary",0)); # Terminname
my $FR = (ReadingsVal($cal,"today_00$no_location",0)); # Terminort
my $IR = $DR." hat um ".$GR." Uhr ".$HR." ".$ER." in ".$FR; # Zusammensetzen der Sprachausgabe
fhem( "define a1 at $CR set MyTTS tts $IR" ); # Setzen des Temporären at-Device
fhem( "define a2 at $BR set MyTTSwz tts $IR" );
}


Mit dem aufruf TeminMinus(1,"KalenderAndi"); bist du jetzt schon viel flexibler. Es geht natürlich noch eleganter, aber schau dir das erst mal an.
Homebrew 1-Wire / HomeMatic Mix - Cubietruck mit FHEM als Server - Raspberry PI 3 als Informationsanzeige im MagicMirror Stil - Raspberry Pi 1 als Klingelanlage - VDR

Mein Modul: Talk2Fhem - Mein Tipp: https://forum.fhem.de/index.php/topic,82442.0.html

rischbiter123

#2
Ist durchaus eine Möglichkeit. Das Problem dabei ist, wenn mehrere Kalender im Calview zusammengefasst sind, man auch gleiche Anfangszeiten hat. Dann würde sich TTS entweder gar nicht melden, oder die Termine gleichzeitig vorlesen. Daher hatte ich es aufgeteilt und die Verzögerungen eingebaut. Die zwei TTS kommen übrigens daher, daß ich in zwei verschiedenen Räumen Ansagen habe und die 10 Sekunden  dazwischen sind für eine halbwegs annehmbare Synchronisation.
In Perl bin ich leider noch Anfänger, aber ich werde am WE mal sehen, ob ich dass umsetzen kann, zumal ja auch die at entsprechend hochgezählt werden müssten.
Danke auf alle Fälle für den Denkanstoß.
4*Raspi, Max Thermostate und Fensterkontakte, FB7590, Mysensors und NanoCUL, IT und Sonoff, zigbee2mqtt2

Phill

Gerne, jeder fängt mal an.
Bezgl. des hochzählens hatte ich 10*$noeingesetzt
Homebrew 1-Wire / HomeMatic Mix - Cubietruck mit FHEM als Server - Raspberry PI 3 als Informationsanzeige im MagicMirror Stil - Raspberry Pi 1 als Klingelanlage - VDR

Mein Modul: Talk2Fhem - Mein Tipp: https://forum.fhem.de/index.php/topic,82442.0.html

rischbiter123

Hatte ich gesehen, bei der Sekundenvariable. Das dürfte aber nur bei maximal 5 Terminen klappen. Aber wie gesagt, ich sehe mir das am WE mal genauer an. Die at müsste man ja mit der $no dann im 10'er Bereich hochzählen können. Ich werde, wenn alles klappt, das Ganze für eine TTS-Instanz posten.
4*Raspi, Max Thermostate und Fensterkontakte, FB7590, Mysensors und NanoCUL, IT und Sonoff, zigbee2mqtt2

Phill

Das ist auch genau das was ich nicht wirklich verstanden habe. Warum muss der eine Termin einen Offset von 10 der andere von 20 Sekunden haben? Das sind doch unterschiedliche Termine. Die können doch alle den gleichen offset haben?
Homebrew 1-Wire / HomeMatic Mix - Cubietruck mit FHEM als Server - Raspberry PI 3 als Informationsanzeige im MagicMirror Stil - Raspberry Pi 1 als Klingelanlage - VDR

Mein Modul: Talk2Fhem - Mein Tipp: https://forum.fhem.de/index.php/topic,82442.0.html

rischbiter123

Das ist, weil ich in dem Calview, aus dem ich die Readings hole, 4 verschiedene (Familien)Kalender zusammenfasse. Und wenn dann 2 oder mehr Termine die gleiche Startzeit haben, dürfte es Probleme mit der Sprachausgabe geben. Die 10 Sekunden zwischen $BR und $CR sind, weil mein zweiter Pi länger für die Sprachgenerierung braucht und ich es gerne halbwegs synchron haben möchte. 10 Sekunden sind auch, zumindest beim ersten Versatz, mindestens nötig, weil ich sonst beim Splitten nur eine einstellige Zahl ohne führende Null zurückbekomme und damit kann der at-Befehl nichts anfangen.
4*Raspi, Max Thermostate und Fensterkontakte, FB7590, Mysensors und NanoCUL, IT und Sonoff, zigbee2mqtt2

rischbiter123

Hier jetzt die verbesserte Version. Sie ist für bis zu 9 Termine und nur eine Distanz.

Aufruf:

define KalenderAnsage DOIF ([00:40] and [KalenderAndi:c-today] gt 0) (
{
for(my $z = 1; $z <= [KalenderAndi:c-today]; $z++)
{
TerminMinus($z,"KalenderAndi");
}
}
)


Und hier die Subroutine:

sub TerminMinus($$) {
my ($no, $cal) = @_;
my $Tag = "today_"."00".$no; # 1. Teil Zusammensetzung für das Reading
my $T1 = $Tag."_btime"; # 2. Teil Zusammensetzung für das Reading
my $Termin = (ReadingsVal($cal,$T1,0)); # Anfangszeit des Termins
my @AR = split(/:/,$Termin); # Aufteilung in Stunde, Minute, Sekunde
my $GR = $AR[0]; # Stunde Terminbeginn
my $HR = $AR[1]; # Minute Terminbeginn
my $BR = (--$AR[0]).":".$AR[1].":".($AR[2]+(5+5*$no)); # Eine Stunde vor Terminbeginn + Versatz bei gleichem Beginn
my $T2 = $Tag."_source";
my $DR = (ReadingsVal($cal,$T2,0)); # Kalendername
my $T3 = $Tag."_summary";
my $ER = (ReadingsVal($cal,$T3,0)); # Terminname
my $T4 = $Tag."_location";
my $FR = (ReadingsVal($cal,$T4,0)); # Terminort
my $IR = $DR." hat um ".$GR." Uhr ".$HR." ".$ER." bei ".$FR; # Zusammensetzen der Sprachausgabe
$no = $no+10;
fhem( "define a$no at $BR set MyTTS tts $IR" ); # Setzen des Temporären at-Device
}


Noch mal Vielen Dank an @Phill für den Denkanstoß.
4*Raspi, Max Thermostate und Fensterkontakte, FB7590, Mysensors und NanoCUL, IT und Sonoff, zigbee2mqtt2