[gelöst] Ereignisse zählen

Begonnen von odie13690, 25 Mai 2015, 00:34:06

Vorheriges Thema - Nächstes Thema

odie13690

Hallo zusammen,

ich möchte die Zustände, bei denen die aktuelle Leistungsaufnahme > 5W eines HomeMatic Schaltaktors fortlaufend zählen.

Dafür habe ich mir einen Dummy definiert
define Zaehler dummy

Dieser soll per DOIF auf eine Funktion in der 99_myUtils.pm zurückgreifen. Ich habe mir das folgender Maßen gedacht
define diZaehlen DOIF ([Aktor_Leistung]>5) ({set_Anzahl(Zaehler)})

Die Funktion sieht so aus
# Ereignisse zählen
sub set_Anzahl($)
{
  my $count = ReadingsVal($Zaehler,"state","0");
  $count++;
  fhem("setreading $Zaehler state $count");
}


Leider funktioniert das Ganze nicht. Kann mir jemand auf die Sprünge helfen?

odie13690

igami

Mach doch einfach ein

define diZaehlen DOIF ([Aktor_Leistung]>5)({fhem("set Zaehler ".([Zaehler]+1))})


Grüße
igami
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

Damian

Zitat von: igami am 25 Mai 2015, 05:39:18
Mach doch einfach ein

define diZaehlen DOIF ([Aktor_Leistung]>5)({fhem("set Zaehler ".([Zaehler]+1))})


Grüße
igami

oder noch einfacher:


define diZaehlen DOIF ([Aktor_Leistung]>5) (set Zaehler {([Zaehler]+1)})


Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

odie13690

Vielen Dank. Klappt wie es soll.

odie13690

cwagner

Hi Damian,

steckt da nicht ein weiteres Feature für Dein Schweizer Taschenmesser drin. Aktuell benutzer ich das statistics-Modul, um zum Beispiel auch Einschaltzeiten zu dokumentieren/auszuwerten. hourcounter von John ist auch ein Ansatz in diese Richtung.

Aber wenn es nur um das Zählen der Ereignisse geht, das man womöglich sogar schon per DOIF in eine Aktion umwandelt, dann wäre es doch perfekt, wenn DOIF mit einem Reading gleich selbst zählt, wie oft es das Ereignis ausgelöst hat, oder? Ist doch alles an Bord...

Christian
PI 2B+/5 Raspbian 12, Perl 5.36.0, FHEM 6.3: 295 Module in ConfigDB: Steuerung Heizkessel, FBH, Solarthermie, kontr. Lüftung mit WRG. Smarthome u.a. HMCUL, 1-Wire (FT232RL ; DS2480B), EnOcean (TCM EPS3), MQTT2. DOIF, PID20, Threshold, OWX; Micropelt IRTV, Volkszähler, SolarForecast; MariaDB

Damian

Zitat von: cwagner am 25 Mai 2015, 11:39:32
Hi Damian,

steckt da nicht ein weiteres Feature für Dein Schweizer Taschenmesser drin. Aktuell benutzer ich das statistics-Modul, um zum Beispiel auch Einschaltzeiten zu dokumentieren/auszuwerten. hourcounter von John ist auch ein Ansatz in diese Richtung.

Aber wenn es nur um das Zählen der Ereignisse geht, das man womöglich sogar schon per DOIF in eine Aktion umwandelt, dann wäre es doch perfekt, wenn DOIF mit einem Reading gleich selbst zählt, wie oft es das Ereignis ausgelöst hat, oder? Ist doch alles an Bord...

Christian

Das macht das Modul bereits ;)

Mit Attribut repeatsame wird im Reading cmd_count die Anzahl abgelegt - musst du nur groß genug wählen z. B. repeatsame 1000000


Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

flurin

#6
Zitat von: odie13690 am 25 Mai 2015, 00:34:06
....
Leider funktioniert das Ganze nicht. Kann mir jemand auf die Sprünge helfen?

So würde es funktionieren:


define diZaehlen DOIF ([Aktor_Leistung]>5) ({set_Anzahl("Zaehler")})



# Ereignisse zählen
sub set_Anzahl($)
{
  my ($Zaehler) = @_;
  my $count = ReadingsVal($Zaehler,"state","0");
  $count++;
  fhem("setreading $Zaehler state $count");
}


Evtl. willst du den Zähler um 00:00 loggen und zurücksetzen, dann ist eine perl-Funktion nützlich.
Bei einem ähnlichen Fall erfasse ich die Einschaltstunden pro Tag und logge das Resultat.

Gruss
flurin

Nachtrag: Funktionen zum Plot


sub myStat($$)
{
  my ($device,$reading) = @_;
 
  my ($sec,$min,$hour) = localtime(time);
  my $now_hours = sprintf("%.4f",$hour + $min/60 + $sec/3600);
 
  return if ($now_hours < 0.02); # filter 00:01 addLog
 
  my $statCurrent;
  my $status = ReadingsVal($device,$reading,0);
  Log(3, "myStat: $device $status $now_hours");
 
  if ($status =~ m/on|pressed|AI|BI/) {
    $status = "on";
  } elsif ($status =~ m/off|released|A0|B0/) {
    $status = "off";
  }

  if($status eq "on") {
    fhem("setreading $device last_on $now_hours");
  } elsif ($status eq "off") {
    fhem("setreading $device last_off $now_hours");
    $statCurrent = sprintf("%.4f",ReadingsVal($device,"statCurrent",0) + ($now_hours - ReadingsVal($device,"last_on",0)));
    fhem("setreading $device statCurrent $statCurrent");
  }
}



sub add_Stat_Log($)
{
  my ($device) = @_;
  my ($sec,$min,$hour) = localtime(time);
 
  my $statCurrent = ReadingsVal($device,"statCurrent",0);
   
  fhem("trigger $device statDay: $statCurrent   << addStatLog");
  fhem("setreading $device statDay $statCurrent");
  fhem("setreading $device last_on 0");
  fhem("setreading $device last_off 0");
  fhem("setreading $device statCurrent 0");
  Log(3, "add_Stat_Log: $device $statCurrent");
}


Anwendung

Erfassen:


define di_switch_heating_stat DOIF ([switch_heating:buttons]) ({myStat("switch_heating","buttons")})
attr di_switch_heating_stat do always


Logging und Reset:


define at_tc_addLog_pm at *23:59 {add_Stat_Log("switch_heating")}


Die Perl-Funktionen sind für meinen Fall (EnOcean) vereinfacht und ohne Error-Handling.

odie13690

Zitat von: flurin am 25 Mai 2015, 15:40:14
So würde es funktionieren:


define diZaehlen DOIF ([Aktor_Leistung]>5) ({set_Anzahl("Zaehler")})



# Ereignisse zählen
sub set_Anzahl($)
{
  my ($Zaehler) = @_;
  my $count = ReadingsVal($Zaehler,"state","0");
  $count++;
  fhem("setreading $Zaehler state $count");
}


Evtl. willst du den Zähler um 00:00 loggen und zurücksetzen, dann ist eine perl-Funktion nützlich.
Bei einem ähnlichen Fall erfasse ich die Einschaltstunden pro Tag und logge das Resultat.

Gruss
flurin

Hallo,

ich versuche mal deinen Ansatz auszuprobieren. Dazu erstmal ein paar Fragen zum Verständnis.

1. Wohin schreiben die beiden Funktionen "myStat($$)" und "add_Stat_Log($)" die Daten. Ich erkenne keinen Verweis auf eine Logdatei.
2. An die Funktion "myStat($$)" werden das Device (in meinem Fall der Leistungschannel eines Aktors) und der Status (bei mir Wert in Watt) übergeben. Wie muss ich den Teil "$status =~ m/on|pressed|AI|BI/" anpassen, um nur die Ereignisse zu zählen mit $status > 5? Die elseif ($status < 5) benötige ich nicht, kann ich also weg lassen?

odie13690

frank

zum ereigniszählen gibt es auch das wunderschöne modul HourCounter. das vermisst dir sogar gleichzeitig die puls- und pausendauer und liefert noch statistiken frei haus.

http://www.fhemwiki.de/wiki/HourCounter
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

odie13690

Zitat von: frank am 01 Juni 2015, 19:28:33
zum ereigniszählen gibt es auch das wunderschöne modul HourCounter. das vermisst dir sogar gleichzeitig die puls- und pausendauer und liefert noch statistiken frei haus.

http://www.fhemwiki.de/wiki/HourCounter

Das hatte ich mir auch schon angeschaut. Irgendwie hat mich aber die Lösung von Damian (der Einfachheit halber) überzeugt. Deshalb habe ich diese z. Z. im Einsatz.
Zur "Horizonterweiterung" sind alle Tipps und Hinweise gern gelesen...

odie13690

flurin

#10
Zitat von: odie13690 am 01 Juni 2015, 18:29:50
Hallo,

ich versuche mal deinen Ansatz auszuprobieren. Dazu erstmal ein paar Fragen zum Verständnis.

1. Wohin schreiben die beiden Funktionen "myStat($$)" und "add_Stat_Log($)" die Daten. Ich erkenne keinen Verweis auf eine Logdatei.
2. An die Funktion "myStat($$)" werden das Device (in meinem Fall der Leistungschannel eines Aktors) und der Status (bei mir Wert in Watt) übergeben. Wie muss ich den Teil "$status =~ m/on|pressed|AI|BI/" anpassen, um nur die Ereignisse zu zählen mit $status > 5? Die elseif ($status < 5) benötige ich nicht, kann ich also weg lassen?

odie13690

Damit es für alle nachvollziehbar ist, habe ich oben die Perl-Funktionen zum Plot ergänzt.

zu 1) myStat speichert die Daten in $device (switch_heating):


Internals:
DEF 0013F646
IODev USB_300
NAME switch_heating
NR 51
NTFY_ORDER 50-switch_heating
STATE released
TYPE EnOcean
Readings:
2015-05-08 08:24:02 buttons released
2015-05-08 08:18:28 channelA AI
2015-05-26 23:59:00 last_off 0
2015-05-26 23:59:00 last_on 0
2015-05-26 23:59:00 statCurrent 0
2015-05-26 23:59:00 statDay 0
2015-05-08 08:24:02 state released


Die Readings sind alle 0, weil die Heizung nicht in Betrieb ist.

Mit add_Stat_Log wird statDay (Stundenzähler) in entsprechendem Log-File indirekt mit dem trigger-Befehl gespeichert.


  fhem("trigger $device statDay: $statCurrent   << addStatLog");


zu 2) Bei myStat werden 2 Parameter übergeben: device (z.B. switch_heating) und das Reading (z.B. state oder buttons),
die Funktion liest dann den Wert aus dem Reading.
Bei meinem Fall wird die Zeit in Stunden (sobald switch_heating off ist) aus $now_hour - last_on berechnet und in statCurrent gespeichert (addiert).
Für deinen Fall muss die Funktion entsprechend angepasst werden.

odie13690

Zitat von: flurin am 01 Juni 2015, 20:17:34
Damit es für alle nachvollziehbar ist, habe ich oben die Perl-Funktionen zum Plot ergänzt.
Danke!

Zitat von: flurin am 01 Juni 2015, 20:17:34Mit add_Stat_Log wird statDay (Stundenzähler) in entsprechendem Log-File indirekt mit dem trigger-Befehl gespeichert.
Um in meinem Fall den Counter um 23:59 in einem extra Log zu speichern, benötige ich also nur die "add_Stat_Log". Was mir allerdings nicht klar ist, wo ist "in entsprechendem Log-File". Bisher habe ich Log-Files nur per define in der Fhem-Oberfläche angelegt.

define at_tc_addLog_pm at *23:59 {add_Stat_Log("sanctum_infrared")} bedeutet doch, dass täglich um 23:59 die Funktion "add_Stat_Log" aufgerufen wird. Dort wird "state" vom Device "sanctum_infrared" abgefragt (my $statCurrent = ReadingsVal($device,"statCurrent",0) und wie/wohin an Fhem zurückgegeben?

odie13690

flurin

#12
Wenn ich es richtig verstanden habe, sieht es bei deinem Fall so aus:

Dummy

define Zaehler dummy


DOIF

define diZaehlen DOIF ([Aktor_Leistung]>5) (set Zaehler {([Zaehler]+1)})


Logging (habe ich vorausgesetzt)

define FileLog_Zaehler FileLog ./log/Zaehler-%Y.log Zaehler
attr FileLog_Zaehler logtype text


Für den Log-Eintrag würde ein "at" reichen:

define at_addLog at *23:59 {fhem("trigger Zaehler statDay: ".ReadingsVal("Zaehler","state","invalid")." << addStatLog")}


Das LogFile sieht dann so aus:

2015-06-03_11:35:21 Zaehler 3
2015-06-03_11:44:59 Zaehler 4
...
2015-06-03_23:59:00 Zaehler statDay: 15 << addStatLog


Evtl. um 23:59 dann den Zaehler auf 0 setzen und weitere Wünsche einbauen - aber das sollte kein Problem sein.

Trebor5

#13
Hallo ,

suche auch so eine Lösung um einfach zu Zählen wie oft meine Haustür auf und zugeht.
Am schönsten wäre es noch wenn man jeden Monat zusammenfassen könnte und das in einem Plot für das ganze Jahr darstellen könnte.

Leider bekomme ich das nicht hin mit den Beispielen die hier aufgezeigt werden.
Geht das Zählen eines Kontaktes nicht nur mit einem Satz und den Plot einzeln dazu ?

#### Test Zaehlung Haustuer

define Zaehler dummy
attr Zaehler room Test

define diZaehlen DOIF ([Haustuer] eq "open")(set Zaehler {([Zaehler]+1)})
attr diZaehlen room Test

define FileLog_HAUSTUER_ZAEHLUNG FileLog ./log/Zaehler-%Y-%m.log Zaehler
attr FileLog_HAUSTUER_ZAEHLUNG logtype text
attr FileLog_HAUSTUER_ZAEHLUNG room Test

define at_addLog at *23:59 {fhem("trigger Zaehler statDay: ".ReadingsVal("Zaehler","state","invalid")." << addStatLog")}
attr at_addLog room Test


Update
Habe jetzt die Lösung das er Zählt.
#### Zaehlung Haustuer #############################

define Zaehler dummy
attr Zaehler group Zählungen
attr Zaehler room Haustuer

define diZaehlen DOIF ([Haustuer] eq "offen")(set Zaehler {([Zaehler]+1)})
attr diZaehlen room CUL_HM

define FileLog_HAUSTUER_ZAEHLUNG FileLog ./log/Zaehler-%Y-%m.log Zaehler
attr FileLog_HAUSTUER_ZAEHLUNG logtype text
attr FileLog_HAUSTUER_ZAEHLUNG room LOG
define HAUSTUER_ZAEHLUNG_Plot SVG FileLog_HAUSTUER_ZAEHLUNG:Zaehler:CURRENT
attr HAUSTUER_ZAEHLUNG_Plot fixedrange 7days
attr HAUSTUER_ZAEHLUNG_Plot label "Hausstuer Zaehler Min $data{min1} , Max $data{max1} , Last $data{currval1}"
attr HAUSTUER_ZAEHLUNG_Plot room Haustuer

define at_addLog at *23:59 {fhem("trigger Zaehler statDay:".ReadingsVal("Zaehler","state","invalid")." << addStatLog")}
attr at_addLog room AT


Jetzt muss ich nur noch den Zähler nachts auf null setzen da es im Log so aussieht.
2016-01-08_23:15:41 Zaehler 104
2016-01-08_23:15:51 Zaehler 105
2016-01-08_23:16:42 Zaehler 106
2016-01-08_23:33:09 Zaehler 107
2016-01-08_23:36:33 Zaehler 108
2016-01-08_23:42:48 Zaehler 109
2016-01-08_23:58:32 Zaehler 110
2016-01-08_23:59:00 Zaehler statDay:110 << addStatLog
2016-01-09_00:00:02 Zaehler 111
2016-01-09_00:01:43 Zaehler 112
2016-01-09_00:02:00 Zaehler 113
2016-01-09_00:05:56 Zaehler 114
2016-01-09_00:27:28 Zaehler 115

Odroid N2,Hauptsensoren Homematic + 1 Wire + 8Kanal Homematic auf Relay Schaltung. Forum Beiträge sind meine letzte Hoffnung nach Stundenlangen erfolglosen suchen und probieren.