Hallo,
wäre es für die Funktionalität "Energiemanagement" nicht eine gute Erweiterung wenn unter "Global" ein Reading "Zeit/Time" in Minuten-Genauigkeit eingeführt wird, verbunden mit Events im Minutentakt an die man sich ran hängen kann?
Für Testzwecke erzeuge ich es so:
define EmulatedTimeEvent_global at +*00:01:00 {my $t=POSIX::strftime("%H:%M:%S",localtime(time));{fhem("setreading global time $t")};}
Hintergrund:
ich möchte in meinem Modul, Modulen ein virtuelles Verbrauchs-Reading implementieren. Also wenn die Hardware dieses Reading nicht liefert.
Aktueller Verbrauch/Power + Gesamtverbrauch/Consumption.
Also auf Basis des Status On/Off, vielleicht auch Dim, Val wird beim Schalten+Init ein Reading Power gesetzt,
also wenn ein Attribut Power in Watt zugewiesen ist (=Power wenn 100% an).
Sollte ja nicht kompliziert sein ??
Beispiel Berechnung Gesamtverbrauch:
sub XXX_Notify($$)
{
my ($own_hash, $dev_hash) = @_;
my $ownName = $own_hash->{NAME}; # own name / hash
return "" if(IsDisabled($ownName)); # Return without any further action if the module is disabled
my $devName = $dev_hash->{NAME}; # Device that created the events
# expecting only events from 'global' here
my $events = deviceEvents($dev_hash, 1);
return if (!$events);
foreach my $event (@{$events}) {
$event = "" if(!defined($event));
# Log3 $own_hash, 5, "$ownName: Looping through Events, now from Device '$devName' Event '$event'.";
#---
# Event 'time' triggers calculation loop with period 1 min
if ($event =~ m/time/) {
# reading power is required for clc!
my $power = ReadingsVal($ownName, "power", undef);
if (defined $power) {
readingsBeginUpdate($own_hash);
my $old_timestamp = ReadingsTimestamp($ownName, "consumption", undef);
my $old_consumption = ReadingsVal($ownName, "consumption", undef);
my $cur_timestamp = $own_hash->{".updateTimestamp"};
# valid values?
if (!defined($old_timestamp)) {
$old_timestamp = $cur_timestamp;
$old_consumption = "0";
Log3 $own_hash, 1, "'Consumption' reading missing. Starting new calculation at '$cur_timestamp'.";
} else {
Log3 $own_hash, 5, "Adding power consumption for period '$old_timestamp' to '$cur_timestamp' to '$old_consumption'.";
}
my $period = time_str2num($cur_timestamp) - time_str2num($old_timestamp);
my $cur_consumption = $old_consumption + ($period * $power) / 3600;
readingsBulkUpdate($own_hash, "consumption", $cur_consumption);
readingsEndUpdate($own_hash, 1);
}
}
}
}
MfG
Warum deine Berechnung nicht gleich an das at packen?
Statt at -> setzen in global -> notify -> Berechnung
Und ich denke der Ansatz ist eh "falsch".
Was wenn ein Verbraucher genau zwischen 2 Zeitpunkten an ist, sonst aber aus?
(nur ein mögliches Beispiel)
(ElectricityCalculator,) HourCounter reagieren auf Events der Devices und berechnen dann die Laufzeit...
EDIT: ganz abgesehen davon, dass Geräte ja auch schon nur ab und an Werte senden. Zwischenwerte bekommst du ja u.U. gar nicht mit...
Gruß, Joachim
Zitat von: MadMax-FHEM am 17 Dezember 2022, 15:46:37
EDIT: ganz abgesehen davon, dass Geräte ja auch schon nur ab und an Werte senden. Zwischenwerte bekommst du ja u.U. gar nicht mit...
Der abgebildete Beispiel-Code muss noch ergänzt werden - in der Set und Parse Funktion müssten ggf. Zwischenberechnungen erfolgen wenn Geräte geschaltet werden.
Es gibt da schon ein Modul, müsste powerMap oder so heißen.