Neues Modul: 22_HOMEMODE.pm - grundlegende Automationen und mehr

Begonnen von DeeSPe, 07 Januar 2017, 15:59:43

Vorheriges Thema - Nächstes Thema

C0mmanda

Moin,

habe mein Homemode länger nicht gepflegt, mich aber nun mal wieder damit beschäftigt.

Ich habe die Situation dass mein Homemode bei "absent" aller Roommates in den Alarm-Modus "armhome" geht.
Laut Commandref kann "armhome" aber nur manuell gesetzt werden, bei Abwesenheit und Attribut HomeAutoAlarmModes 1 sollte Homemode automatisch in "armaway" schalten.

Liegts an mir und irgendeiner Einstellung oder ist das ein Bug?
Danke!

DeeSPe

Zitat von: C0mmanda am 25 Juni 2020, 17:40:40
Moin,

habe mein Homemode länger nicht gepflegt, mich aber nun mal wieder damit beschäftigt.

Ich habe die Situation dass mein Homemode bei "absent" aller Roommates in den Alarm-Modus "armhome" geht.
Laut Commandref kann "armhome" aber nur manuell gesetzt werden, bei Abwesenheit und Attribut HomeAutoAlarmModes 1 sollte Homemode automatisch in "armaway" schalten.

Liegts an mir und irgendeiner Einstellung oder ist das ein Bug?
Danke!

Ich nehme an anyoneElseAtHome steht auf on.
Das ist so ziemlich die einzige Möglichkeit.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

C0mmanda

Wow, das wars!
Tausend Dank für den schnellen Hinweis!

Gruss

dk3572

Zitat von: DeeSPe am 08 November 2019, 09:50:13
Das wurde schon einmal gefragt und meine Antwort damals dazu war:
https://forum.fhem.de/index.php/topic,64317.msg927012.html#msg927012

Aber einen Trick gibt es immer wenn man etwas programmieren kann. ;)

Eine mögliche Lösung dazu wäre statt in "HomeCMDcontactOpenWarning1" direkt jeden Kontakt auszugeben, eine entsprechende Funktion aufzurufen, die dann aus allen überwachten Kontakten die offenen raussucht, die ein "HomeOpenMaxTrigger" gesetzt haben. Diese werden dann ausgegeben und ein Reading gesetzt dass diese ausgegeben wurden. Entsprechend vorher schaust Du wie alt dieses gesetzte Reading ist und wenn es ein gewisses Alter erreicht hat wird neu ausgegeben.

Die Funktion könnte wie folgt aussehen (diese Funktion bitte in die 99_myUtils.pm):
sub checkContacts($)
{
  my ($name) = @_;
  # Funktion nur durchlaufen wenn das Reading älter als 5 min ist
  return undef if (ReadingsAge($name,"notifiedContacts",300) < 300);
  my $contacts = InternalVal($name,"SENSORSCONTACT","");
  $contacts=~s/,/|/g;
  my @aliases;
  foreach (devspec2array("$contacts:FILTER=HomeOpenMaxTrigger>0:FILTER=state!=closed"))
  {
    push @aliases,AttrVal($_,"alias",$_);
  }
  my $ret = join(", ",@aliases);
  fhem "setreading $name notifiedContacts $ret";
  return $ret;
}


Und dann hinterlegst Du einfach in "HomeCMDcontactOpenWarning2" z.B. folgenden Code (speak natürlich anpassen auf das was Du machen möchtest):
{
  my $c = checkContacts("%SELF%");
  fhem "speak HINWEIS: Folgende Kontakte sind immer noch offen: $c" if ($c);
}


Gruß
Dan

Hallo Dan,

habe mich noch mal an dieses Beispiel gewagt.
Leider bekomme ich folgende Meldungen:

2020.07.10 09:12:23.608 1: PERL WARNING: Argument "Bürofenster, Gästezimmerfenster" isn't numeric in numeric gt (>) at (eval 2536102) line 1.
2020.07.10 10:12:12.412 1: ERROR evaluating {checkContacts()}: Not enough arguments for main::checkContacts at (eval 2546661) line 1, near "()"


Die sub habe ich 1:1 übernommen.

In HomeCMDcontactOpenWarning1 habe ich das eingetragen:

{checkContacts()}

In HomeCMDcontactOpenWarning2 das:

{
my $c = checkContacts("%SELF%");
my $is = "ist";
$is = "sind" if (%SELF% > 1);
fhem "set ECHO_G090LV03644201AX speak_ssml <speak>Info. $c $is noch offen.</speak>" if ($c);
}


Was habe ich falsch gemacht und wie kann ich eine Ansage bekommen, wie sie in contactsWindowsOpen_hr steht?

Danke schon mal und VG Dieter

DeeSPe

Hallo Dieter,

mal eins nach dem anderen:
Zitat von: dk3572 am 10 Juli 2020, 10:37:40
In HomeCMDcontactOpenWarning1 habe ich das eingetragen:

{checkContacts()}

Das dürfte zu dieser Fehlermeldung gehören:
Zitat von: dk3572 am 10 Juli 2020, 10:37:40
2020.07.10 10:12:12.412 1: ERROR evaluating {checkContacts()}: Not enough arguments for main::checkContacts at (eval 2546661) line 1, near "()"
Das ist auch verständlich, denn Du hast nicht den Namen des HOMEMODE Device mit übergeben, z.B. "%SELF%".
Allerdings gibt die Funktion auch nur die Namen/Aliase der noch offenen Kontakte in Komma separierter Schreibweise zurück. Es kann somit nichts wirklich passieren beim Ausführen von HomeCMDcontactOpenWarning1.

Zitat von: dk3572 am 10 Juli 2020, 10:37:40
In HomeCMDcontactOpenWarning2 das:

{
my $c = checkContacts("%SELF%");
my $is = "ist";
$is = "sind" if (%SELF% > 1);
fhem "set ECHO_G090LV03644201AX speak_ssml <speak>Info. $c $is noch offen.</speak>" if ($c);
}


Dazu gehört diese Fehlermeldung und das ist auch verständlich:
Zitat von: dk3572 am 10 Juli 2020, 10:37:40
2020.07.10 09:12:23.608 1: PERL WARNING: Argument "Bürofenster, Gästezimmerfenster" isn't numeric in numeric gt (>) at (eval 2536102) line 1.

denn %SELF% ist nicht nummerisch, sondern nur der Name des HOMEMODE Device.
Ich nehme an Du willst das mit der Anzahl der zurückgemeldeten Kontakte vergleichen, das sollte dann so gehen:
{
  my $c = checkContacts("%SELF%");
  if ($c) {
    my $is = "ist";
    $is = "sind" if (split(", ",$c));
    fhem "set ECHO_G090LV03644201AX speak_ssml <speak>Info. $c $is noch offen.</speak>"
  }
}


Ich hoffe ich konnte etwas Licht ins Dunkel bringen.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

dk3572

Hallo Dan,

vielen Dank für die schnelle und ausführliche Hilfe.

Muss ich nun in HomeCMDcontactOpenWarning1 {checkContacts("%SELF%")} eintragen?

VG Dieter

dk3572

Hallo Dan,
funktioniert leider immer noch nicht ganz:

Zitat von: DeeSPe am 10 Juli 2020, 14:31:30
Allerdings gibt die Funktion auch nur die Namen/Aliase der noch offenen Kontakte in Komma separierter Schreibweise zurück. Es kann somit nichts wirklich passieren beim Ausführen von HomeCMDcontactOpenWarning1.

Wie kann ich dann z.B. diesen Satz "Das Gästezimmerfenster, das Schlafzimmerfenster und das WC Fenster" wie er in contactsWindowsOpen_hr steht ausgeben?

Und fehlt hier nicht noch die Angabe ">1"?

{
  my $c = checkContacts("%SELF%");
  if ($c) {
    my $is = "ist";
    $is = "sind" if (split(", ",$c));
    fhem "set ECHO_G090LV03644201AX speak_ssml <speak>Info. $c $is noch offen.</speak>"
  }
}


Bei lastCMDerror erhalte ich das:

error: >Gästezimmerfenster, Schlafzimmerfenster, WC Fenster< in CMD: {checkContacts("Home")}


Danke und VG Dieter


DeeSPe

Zitat von: dk3572 am 10 Juli 2020, 17:43:46
Hallo Dan,

vielen Dank für die schnelle und ausführliche Hilfe.

Muss ich nun in HomeCMDcontactOpenWarning1 {checkContacts("%SELF%")} eintragen?

VG Dieter

Moin Dieter,

wie gesagt, der Funktionsaufruf alleine bringt außer dieser Fehlermeldung nichts:
Zitat von: dk3572 am 13 Juli 2020, 07:27:56
error: >Gästezimmerfenster, Schlafzimmerfenster, WC Fenster< in CMD: {checkContacts("Home")}

da diese Funktion halt nur die Kontakte zurück gibt die eine Kontakt-Offen-Warnung ausgeben sollen und die noch offen sind. Was damit geschehen soll musst Du noch selbst weiterverarbeiten, z.B. Ausgabe per TTS oder Mail, ....

Zitat von: dk3572 am 13 Juli 2020, 07:27:56
Wie kann ich dann z.B. diesen Satz "Das Gästezimmerfenster, das Schlafzimmerfenster und das WC Fenster" wie er in contactsWindowsOpen_hr steht ausgeben?

Das eine ist nicht gleich dem anderen uns somit eher nicht passend.
Die Funktion checkContacts() ermittelt alle offenen Kontakte die eine Kontakt-Offen-Warnung ausgeben sollen, in contactsWindowsOpen_hr hingegen stehen alle offenen Fenster. Ist also nicht zwangsweise die selbe Information.

Du könntest die Funktion checkContacts wie folgt abändern (rote Zeile), dann sollte sie die Kontakte in HR-Form (human readable) zurückliefern:
Zitatsub checkContacts($)
{
  my ($name) = @_;
  # Funktion nur durchlaufen wenn das Reading älter als 5 min ist
  return undef if (ReadingsAge($name,"notifiedContacts",300) < 300);
  my $contacts = InternalVal($name,"SENSORSCONTACT","");
  $contacts=~s/,/|/g;
  my @aliases;
  foreach (devspec2array("$contacts:FILTER=HomeOpenMaxTrigger>0:FILTER=state!=closed"))
  {
    push @aliases,AttrVal($_,"alias",$_);
  }
  my $ret = HOMEMODE_makeHR($defs{$name},0,@aliases);
  fhem "setreading $name notifiedContacts $ret";
  return $ret;
}

Zitat von: dk3572 am 13 Juli 2020, 07:27:56
Und fehlt hier nicht noch die Angabe ">1"?

Nein, denn ist:
split(", ",$c)
gleich 0 (Null), dann läuft das if in false. Wenn es größer als 1 ist wird es automatisch zu true. Der Vergleich mit ">1" ist also unnötig.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

dk3572

Zitat von: DeeSPe am 13 Juli 2020, 08:56:10
Moin Dieter,

wie gesagt, der Funktionsaufruf alleine bringt außer dieser Fehlermeldung nichts:
da diese Funktion halt nur die Kontakte zurück gibt die eine Kontakt-Offen-Warnung ausgeben sollen und die noch offen sind. Was damit geschehen soll musst Du noch selbst weiterverarbeiten, z.B. Ausgabe per TTS oder Mail, ....

Verstehe ich jetzt nicht wirklich.

Bei der 1. Warnung rufe ich doch hiermit "{checkContacts("%SELF%")}" die sub auf. (stimmt das überhaupt so mit dem "%SELFE%" ?)

Bei der 2. Warnung erfolgt doch erst die Ausgabe:

{
  my $c = checkContacts("%SELF%");
  if ($c) {
    my $is = "ist";
    $is = "sind" if (split(", ",$c));
    fhem "set ECHO_G090LV03644201AX speak_ssml <speak>Info. $c $is noch offen.</speak>"
  }
}


Was soll da beim Funktionsaufruf noch dazu?

DeeSPe

Warum rufst Du die Funktion in HomeCMDcontactOpenWarning1 überhaupt auf wenn Du die Rückgabe nicht weiter verarbeitest?
Lass doch einfach den Funktionsaufruf in HomeCMDcontactOpenWarning1 ganz weg und lasse den Code in HomeCMDcontactOpenWarning2.

Um es noch  einmal ganz deutlich zu betonen, das war nie so gedacht und es handelt sich hiermit lediglich um eine "Krücke" um die Kontakte die eine Offen-Warnung ausgeben sollen gemeinsam auszugeben und nicht jeder einzeln.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

dk3572

Habe jetzt bei HomeCMDcontactOpenWarning1 + 2 jeweils das drin:

{
  my $c = checkContacts("%SELF%");
  if ($c) {
    my $is = "ist";
    $is = "sind" if (split(", ",$c));
    fhem "set ECHO_G090LV03644201AX speak_ssml <speak>Info. $c $is noch offen.</speak>"
  }
}


Funktioniert erst mal.

Bis auf das:

my $is = "ist";
    $is = "sind" if (split(", ",$c));


Es wird auch bei einem Fenster "sind" ausgegeben.

pjakobs

Moin zusammen,

ich habe immer noch das Problem, dass mein fhem mich manchmal nachts aufweckt, weil es glaubt, das Licht einschalten zu müssen. Habt Ihr da noch einen Tip?

ich hab folgendes (neben vielen Triggern) im Homemode device eingestellt:

Attributes:
   HomeAdvancedDetails both
   HomeAdvancedUserAttr 1
   HomeAutoAsleep 15
   HomeAutoAwoken 15
   HomeAutoPresence 1
   HomeAutoPresenceSuppressState asleep|gotosleep


Was passiert ist das:

2020.07.13 03:18:34 5: Homestatus: Events from monitored device RR_Peter: durTimerAbsence_cr: 1 --- durTimerAbsence: 00:01:03
2020.07.13 03:18:34 5: Homestatus: Events from monitored device RGR_Residents: durTimerAbsence_cr: 1 --- durTimerAbsence: 00:01:03
2020.07.13 03:18:34 5: Homestatus: Events from monitored device Peter_bt: state: present --- presence: present --- rooms: OG
2020.07.13 03:18:34 2: ROOMMATE set RR_Peter home
2020.07.13 03:18:35 5: Homestatus: Events from monitored device RGR_Residents: residentsTotalRoommatesPresent: 1 --- residentsTotalRoommatesPresentDevs: RR_Peter --- residentsTotalRoommatesAbsent: 0 --- residentsTotalRoommatesAbsentDevs: - --- residentsTotalPeoplePresent: 1 --- residentsTotalPeoplePresentDevs: RR_Peter --- residentsTotalPeopleAbsent: 0 --- residentsTotalPeopleAbsentDevs: - --- residentsTotalPresent: 1 --- residentsTotalPresentDevs: RR_Peter --- residentsTotalAbsent: 1 --- residentsTotalAbsentDevs: Malaika --- residentsHome: 1 --- residentsHomeDevs: RR_Peter --- residentsAbsent: 0 --- residentsAbsentDevs: - --- lastState: absent --- state: home --- presence: present --- lastArrival: 2020-07-13 03:18:34 --- lastDurAbsence: 00:01:03 --- lastDurAbsence_cr: 1 --- durTimerAbsence_cr: 0 --- durTimerAbsence: 00:00:00 --- lastActivity: home --- lastActivityBy: RR_Peter --- lastActivityByDev: RR_Peter
2020.07.13 03:18:35 5: Homestatus: HOMEMODE_RESIDENTS dev: RGR_Residents type: RESIDENTS
2020.07.13 03:18:35 5: Homestatus: HOMEMODE_RESIDENTS mode: home
2020.07.13 03:18:35 5: Homestatus: cmdnew: {  Debug "HomeCMDlocation-home triggered";  fhem("msg HomeCMDlocation-home triggered") }
2020.07.13 03:18:35 1: DEBUG>HomeCMDlocation-home triggered


meines Erachtens sieht das so aus, als ob das PresenceSuppressState setting einfach ignoriert würde?

Hat jemand tips?

Grüße

pj

DeeSPe

Zitat von: dk3572 am 13 Juli 2020, 10:15:24
Habe jetzt bei HomeCMDcontactOpenWarning1 + 2 jeweils das drin:

{
  my $c = checkContacts("%SELF%");
  if ($c) {
    my $is = "ist";
    $is = "sind" if (split(", ",$c));
    fhem "set ECHO_G090LV03644201AX speak_ssml <speak>Info. $c $is noch offen.</speak>"
  }
}


Funktioniert erst mal.

Bis auf das:

my $is = "ist";
    $is = "sind" if (split(", ",$c));


Es wird auch bei einem Fenster "sind" ausgegeben.

Dann doch:
my $is = "ist";
    $is = "sind" if (split(", ",$c) > 1);


Offenbar zählt mindestens 1x split auch wenn der zu teilende String nicht gefunden wird.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

dk3572

Zitat von: DeeSPe am 13 Juli 2020, 16:31:22
Dann doch:
my $is = "ist";
    $is = "sind" if (split(", ",$c) > 1);


Offenbar zählt mindestens 1x split auch wenn der zu teilende String nicht gefunden wird.

Gruß
Dan

Prima, jetzt funktioniert es wie es soll.

Lag ich mit meinem >1 doch nicht so verkehrt  ;)

Vielen Dank noch mal für deine Hilfe und Geduld.

VG Dieter

DeeSPe

Zitat von: pjakobs am 13 Juli 2020, 16:00:50
Moin zusammen,

ich habe immer noch das Problem, dass mein fhem mich manchmal nachts aufweckt, weil es glaubt, das Licht einschalten zu müssen. Habt Ihr da noch einen Tip?

ich hab folgendes (neben vielen Triggern) im Homemode device eingestellt:

Attributes:
   HomeAdvancedDetails both
   HomeAdvancedUserAttr 1
   HomeAutoAsleep 15
   HomeAutoAwoken 15
   HomeAutoPresence 1
   HomeAutoPresenceSuppressState asleep|gotosleep


Was passiert ist das:

2020.07.13 03:18:34 5: Homestatus: Events from monitored device RR_Peter: durTimerAbsence_cr: 1 --- durTimerAbsence: 00:01:03
2020.07.13 03:18:34 5: Homestatus: Events from monitored device RGR_Residents: durTimerAbsence_cr: 1 --- durTimerAbsence: 00:01:03
2020.07.13 03:18:34 5: Homestatus: Events from monitored device Peter_bt: state: present --- presence: present --- rooms: OG
2020.07.13 03:18:34 2: ROOMMATE set RR_Peter home
2020.07.13 03:18:35 5: Homestatus: Events from monitored device RGR_Residents: residentsTotalRoommatesPresent: 1 --- residentsTotalRoommatesPresentDevs: RR_Peter --- residentsTotalRoommatesAbsent: 0 --- residentsTotalRoommatesAbsentDevs: - --- residentsTotalPeoplePresent: 1 --- residentsTotalPeoplePresentDevs: RR_Peter --- residentsTotalPeopleAbsent: 0 --- residentsTotalPeopleAbsentDevs: - --- residentsTotalPresent: 1 --- residentsTotalPresentDevs: RR_Peter --- residentsTotalAbsent: 1 --- residentsTotalAbsentDevs: Malaika --- residentsHome: 1 --- residentsHomeDevs: RR_Peter --- residentsAbsent: 0 --- residentsAbsentDevs: - --- lastState: absent --- state: home --- presence: present --- lastArrival: 2020-07-13 03:18:34 --- lastDurAbsence: 00:01:03 --- lastDurAbsence_cr: 1 --- durTimerAbsence_cr: 0 --- durTimerAbsence: 00:00:00 --- lastActivity: home --- lastActivityBy: RR_Peter --- lastActivityByDev: RR_Peter
2020.07.13 03:18:35 5: Homestatus: HOMEMODE_RESIDENTS dev: RGR_Residents type: RESIDENTS
2020.07.13 03:18:35 5: Homestatus: HOMEMODE_RESIDENTS mode: home
2020.07.13 03:18:35 5: Homestatus: cmdnew: {  Debug "HomeCMDlocation-home triggered";  fhem("msg HomeCMDlocation-home triggered") }
2020.07.13 03:18:35 1: DEBUG>HomeCMDlocation-home triggered


meines Erachtens sieht das so aus, als ob das PresenceSuppressState setting einfach ignoriert würde?

Hat jemand tips?

Grüße

pj

Hallo pj,

HomeAutoPresenceSuppressState wird definitiv nicht ignoriert.
Es wirkt aber nur in den definierten Zuständen um nicht auf "absent" gesetzt zu werden. Es geht bei dem Attribut darum dass man nicht auf "absent" gesetzt wird nur weil man (nachts?) evtl. BT oder WLAN ausschaltet und somit eigentlich auf "absent" gesetzt würde.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe