hallo ich habe eben auf der suche nach einem anderen fehler diesen eintrag im Log gefunden
2023.08.21 14:43:20 1: PERL WARNING: Subroutine myUtils_Initialize redefined at ./FHEM/99_myUtils.pm line 15, <$fh> line 13.
2023.08.21 14:43:20 1: PERL WARNING: Subroutine checkAllFritzMACpresent redefined at ./FHEM/99_myUtils.pm line 20, <$fh> line 13.
2023.08.21 14:43:20 1: PERL WARNING: Subroutine checkFritzMACpresent redefined at ./FHEM/99_myUtils.pm line 45, <$fh> line 13.
2023.08.21 14:43:20 1: PERL WARNING: Subroutine movingAverage redefined at ./FHEM/99_myUtils.pm line 79, <$fh> line 13.
2023.08.21 14:43:20 1: PERL WARNING: Subroutine TibberDaten redefined at ./FHEM/99_myUtils.pm line 129, <$fh> line 13.
2023.08.21 14:43:20 1: PERL WARNING: "my" variable $tmp masks earlier declaration in same statement at ./FHEM/99_myUtils.pm line 250, <$fh> line 13.
2023.08.21 14:43:20 1: reload: Error:Modul 99_myUtils deactivated:
syntax error at ./FHEM/99_myUtils.pm line 217, near "sum @"
Global symbol "$i" requires explicit package name (did you forget to declare "my $i"?) at ./FHEM/99_myUtils.pm line 217, <$fh> line 13.
Global symbol "$i" requires explicit package name (did you forget to declare "my $i"?) at ./FHEM/99_myUtils.pm line 217, <$fh> line 13.
Global symbol "@PreisIntervall" requires explicit package name (did you forget to declare "my @PreisIntervall"?) at ./FHEM/99_myUtils.pm line 221, <$fh> line 13.
Global symbol "@PreisIntervall" requires explicit package name (did you forget to declare "my @PreisIntervall"?) at ./FHEM/99_myUtils.pm line 222, <$fh> line 13.
syntax error at ./FHEM/99_myUtils.pm line 227, near "}"
Can't use global @_ in "my" at ./FHEM/99_myUtils.pm line 245, near "= @_"
syntax error at ./FHEM/99_myUtils.pm line 278, near "}"
kann mir da vielleicht jemand helfen ich habe da immer nur via Copy and Past eingetragen und weiß nicht was der an den einzelnen stellen von mir möchte.
##############################################
# $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
myUtils_Initialize($$)
{
my ($hash) = @_;
}
# Enter you functions below _this_ line.
sub checkAllFritzMACpresent($) {
# Benötigt: nur die zu suchende MAC ($MAC),
# Es werden alle Instanzen vom Type FRITZBOX abgefragt
#
# Rückgabe: 1 = Gerät gefunden
# 0 = Gerät nicht gefunden
my ($MAC) = @_;
# Wird in keiner Instanz die MAC Adresse gefunden bleibt der Status 0
my $Status = 0;
$MAC =~ tr/:/_/;
$MAC = "mac_".uc($MAC);
my @FBS = devspec2array("TYPE=FRITZBOX");
foreach( @FBS ) {
my $StatusFritz = ReadingsVal($_, $MAC, "weg");
if ($StatusFritz eq "weg") {
} elsif ($StatusFritz eq "inactive") {
} else {
# Reading existiert, Rückgabewert ist nicht "inactive", also ist das Gerät am Netzwerk angemeldet.
$Status = 1;
}
}
return $Status
}
sub checkFritzMACpresent($$) {
# Benötigt: Name der zu testenden Fritzbox ($Device),
# zu suchende MAC ($MAC),
# Rückgabe: 1 = Gerät gefunden
# 0 = Gerät nicht gefunden
my ($Device, $MAC) = @_;
my $Status = 0;
$MAC =~ tr/:/_/;
$MAC = "mac_".uc($MAC);
my $StatusFritz = ReadingsVal($Device, $MAC, "weg");
if ($StatusFritz eq "weg") {
# Log 1, ("checkFritzMACpresent ($Device): $MAC nicht gefunden, abwesend.");
$Status = 0;
} elsif ($StatusFritz eq "inactive") {
# Log 1, ("checkFritzMACpresent ($Device): $MAC ist >inactive<, also abwesend.");
$Status = 0;
} else {
# Reading existiert, Rückgabewert ist nicht "inactive", also ist das Gerät per WLAN angemeldet.
# Log 1, ("checkFritzMACpresent ($Device): $MAC gefunden, Gerät heißt >$StatusFritz<.");
$Status = 1;
}
return $Status
}
1;
###############################################################################
#
# Moving average
#
# Aufruf: movingAverage(devicename,readingname,zeitspanne in s)
#
###############################################################################
sub movingAverage($$$){
my ($name,$reading,$avtime) = @_;
my $hash = $defs{$name};
my @new = my ($val,$time) = (ReadingsVal($name,$reading,undef),ReadingsTimestamp($name,$reading,undef));
my ($cyear, $cmonth, $cday, $chour, $cmin, $csec) = $time =~ /(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2}):(\d{2})/;
my $ctime = $csec+60*$cmin+3600*$chour;
my $num;
my $arr;
#-- initialize if requested
if( ($avtime eq "-1") ){
$hash->{helper}{history}=undef;
}
#-- test for existence
if( !$hash->{helper}{history}){
#Log 1,"ARRAY CREATED";
push(@{$hash->{helper}{history}},\@new);
$num = 1;
$arr=\@{$hash->{helper}{history}};
} else {
$num = int(@{$hash->{helper}{history}});
$arr=\@{$hash->{helper}{history}};
my $starttime = $arr->[0][1];
my ($syear, $smonth, $sday, $shour, $smin, $ssec) = $starttime =~ /(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2}):(\d{2})/;
my $stime = $ssec+60*$smin+3600*$shour;
#-- correct for daybreak
$stime-=86400
if( $stime > $ctime);
if( ($num < 25)&&( ($ctime-$stime)<$avtime) ){
#Log 1,"ARRAY has $num elements, adding another one";
push(@{$hash->{helper}{history}},\@new);
}else{
shift(@{$hash->{helper}{history}});
push(@{$hash->{helper}{history}},\@new);
}
}
#-- output and average
my $average = 0;
for(my $i=0;$i<$num;$i++){
$average+=$arr->[$i][0];
Log 4,"[$name moving average] Value = ".$arr->[$i][0]." Time = ".$arr->[$i][1];
}
$average=sprintf( "%5.3f", $average/$num);
#--average
Log 4,"[$name moving average] calculated over $num values is $average";
return $average;
}
1;
#Tibber per HTTP auswerten
sub TibberDaten()
{
my $json = decode_json(InternalVal("myTibber", "httpbody", ""));
my $today_total = "";
my $today_energy = "";
my $today_tax = "";
my $tomorrow_total = "";
my $tomorrow_energy = "";
my $tomorrow_tax = "";
# Alte Einträge erst einmal löschen
#my $timedelete = TimeNow();
my $timedelete = strftime("%F",localtime(time))." 00:00";
my $time_tomorrow = strftime("%F",localtime(time+86400));
my ($year_today,$mon_today,$day_today) = $timedelete =~ m/(\d\d\d\d)-(\d\d)-(\d\d)/;
my ($year_tomorrow,$mon_tomorrow,$day_tomorrow) = $time_tomorrow =~ m/(\d\d\d\d)-(\d\d)-(\d\d)/;
Log3 undef, 3, "Aufruf von TibberDaten um ".localtime()." mit Löschzeit ".$timedelete." und time_tomorrow ".$time_tomorrow;
fhem "set DBRep_PV sqlCmd delete from history where DEVICE = 'myTibber' and READING like 'to%' AND TIMESTAMP>='".$timedelete."'";
for(my $j=0; $j<24;$j++)
{
# Werte ermitteln
my $value_today_total = $json->{data}->{viewer}->{homes}[0]->{currentSubscription}->{priceInfo}->{today}[$j]->{total};
my $value_today_energy = $json->{data}->{viewer}->{homes}[0]->{currentSubscription}->{priceInfo}->{today}[$j]->{energy};
my $value_today_tax = $json->{data}->{viewer}->{homes}[0]->{currentSubscription}->{priceInfo}->{today}[$j]->{tax};
my $value_tomorrow_total = $json->{data}->{viewer}->{homes}[0]->{currentSubscription}->{priceInfo}->{tomorrow}[$j]->{total};
my $value_tomorrow_energy = $json->{data}->{viewer}->{homes}[0]->{currentSubscription}->{priceInfo}->{tomorrow}[$j]->{energy};
my $value_tomorrow_tax = $json->{data}->{viewer}->{homes}[0]->{currentSubscription}->{priceInfo}->{tomorrow}[$j]->{tax};
$today_total = $today_total.$value_today_total."|";
$today_energy = $today_energy.$value_today_energy."|";
$today_tax = $today_tax.$value_today_tax."|";
if(defined $value_tomorrow_total)
{
$tomorrow_total = $tomorrow_total.$value_tomorrow_total."|";
$tomorrow_energy = $tomorrow_energy.$value_tomorrow_energy."|";
$tomorrow_tax = $tomorrow_tax.$value_tomorrow_tax."|";
}
else
{
$tomorrow_total = $tomorrow_energy = $tomorrow_tax = "NV";
}
#Timestamp für den Stundenwert
my $timestamp_today = ($j < 10) ? "$year_today-$mon_today-$day_today 0".$j.":00:00" : "$year_today-$mon_today-$day_today $j:00:00";
my $timestamp_tomorrow = ($j < 10) ? "$year_tomorrow-$mon_tomorrow-$day_tomorrow 0".$j.":00:00" : "$year_tomorrow-$mon_tomorrow-$day_tomorrow $j:00:00";
# Werte in der Datenbank loggen
fhem "set DBLog_PV addCacheLine ".$timestamp_today."|myTibber|addlog|today_total:".$j."|today_total|".$value_today_total."|";
fhem "set DBLog_PV addCacheLine ".$timestamp_today."|myTibber|addlog|today_energy:".$j."|today_energy|".$value_today_energy."|";
fhem "set DBLog_PV addCacheLine ".$timestamp_today."|myTibber|addlog|today_tax:".$j."|today_tax|".$value_today_tax."|";
if(defined $value_tomorrow_total)
{
fhem "set DBLog_PV addCacheLine ".$timestamp_tomorrow."|myTibber|addlog|tomorrow_total:".$j."|tomorrow_total|".$value_tomorrow_total."|";
fhem "set DBLog_PV addCacheLine ".$timestamp_tomorrow."|myTibber|addlog|tomorrow_energy:".$j."|tomorrow_energy|".$value_tomorrow_energy."|";
fhem "set DBLog_PV addCacheLine ".$timestamp_tomorrow."|myTibber|addlog|tomorrow_tax:".$j."|tomorrow_tax|".$value_tomorrow_tax."|";
}
}
fhem("setreading myTibber TodayTotal $today_total");
fhem("setreading myTibber TodayEnergy $today_energy");
fhem("setreading myTibber TodayTax $today_tax");
fhem("setreading myTibber TomorrowTotal $tomorrow_total");
fhem("setreading myTibber TomorrowEnergy $tomorrow_energy");
fhem("setreading myTibber TomorrowTax $tomorrow_tax");
Log3 undef, 3, "TibberDaten:".$today_total;
}
# Aus dem Array mit den Strompreisen des definierten Zeitfenster wird der Zeitraum mit dem niedrigsten Preis ermittelt
# Parameter1: Preisarray
# Parameter2: Laufzeit in Stunden
# Return: Der StartIndex innerhalb der übergebenen Strompreise
#
sub MinTibberZeitfenster
{
my ($Strompreise, $Laufzeit) = @_;
my $anz = @{$Strompreise};
my @PreisIntervall;
Log3 undef, 3, "MinTibberZeitfenster: Strompreise=@{$Strompreise} Laufzeit=$Laufzeit";
for (my $i = 0; $i < ($anz - $Laufzeit +1); $i++)
{
@PreisIntervall[$i] = sum @{$Strompreise}[$i..$i+$Laufzeit-1];
#Log3 undef, 3, "Preisintervall Summe: @PreisIntervall[$i]";
}
my $MinPreis = min @PreisIntervall;
my $MinIndex = first_index { $_ eq $MinPreis } @PreisIntervall;
Log3 undef, 3, "MinTibberZeitfenster: $MinPreis MinIndex=$MinIndex";
return $MinIndex;
}
# Günstigsten Strompreis für eine Dauer von X Minuten finden
# Parameter:
# MinHour: FrühesterStart (Beispiel: 15 für 15:00 Uhr),
# Laufzeit: Laufzeit in Stunden, (Da es nur Stundenpreise gibt, kann die Laufzeit immer auf Stunden aufgerundet werden)
# Laufzeit_Ende: Anzahl Stunden nach frühestem Start (Beispiel: 12 für 12 Stunden nach frühester Start).
# Der Wert gibt dann quasi das Ende der Laufzeit an
# Es wird immer die Startzeit für den aktuellen Tag angenommen und wenn die aktuelle Zeit nach dem frühesten Start liegt,
# wird die früheste Startzeit auf die aktuelle Zeit zzgl. 2 Minuten gesetzt
# Die Funktion ermittelt dann die Uhrzeit, in der der günstigste Strom für die Dauer von Laufzeit zu erwarten ist
#
# Beispiel: MinStromTime(15, 3, 24) -> Ermittelt den günstigsten Strom für 3 Stunden Laufzeit,
# der am gleichen Tag nach 15:00 Uhr liegt und im Zeitfenster bis 15:00 + 24 Stunden - also am nächsten Tag um 15:00 Uhr liegt
#
sub MinStromTime($$$)
{
my ($MinHour,$Laufzeit,$LaufzeitEnde) = @_;
my @PreiseHeute = split /\|/, ReadingsVal("myTibber","TodayTotal",0.25);
my @PreiseMorgen = split /\|/, ReadingsVal("myTibber","TomorrowTotal",0.25);
my @AllePreise = (@PreiseHeute, @PreiseMorgen);
my ($tmp, $m, $h, $tmp, $tmp, $tmp, $tmp, $tmp, $tmp) = localtime(time);
my $MinZeit = "";
# Falls die Mindestzeit vor der akt. Zeit liegt Mindestzeit auf akt. Zeit setzen
if($h >= $MinHour)
{
$LaufzeitEnde = $LaufzeitEnde - ($h - $MinHour);
$MinHour = $h;
}
my $LaufzeitIndex = ($MinHour + $LaufzeitEnde) <= 48 ? $MinHour + $LaufzeitEnde - 1 : 47;
@AllePreise = @AllePreise[$h..$LaufzeitIndex];
my $MinZeitIndex = MinTibberZeitfenster(\@AllePreise, $Laufzeit);
if($MinZeitIndex + $h > 24) # Uhrzeit ist am nächsten Tag
{
$MinZeit = sprintf("%02d", $MinZeitIndex + $h - 24).":00";
}
else
{
$m = $MinZeitIndex == 0 && $MinHour == $h ? $m + 2 : 0; # Uhrzeit entspricht Aufrufzeit, daher 2 Minuten aufschlagen
$MinZeit = sprintf("%02d", $MinZeitIndex + $h).":".sprintf("%02d", $m);
}
Log3 undef, 3, "MindestStrompreis: Aktuelle Zeit:$h:$m Startzeit:$MinZeit";
return $MinZeit;
}
Lieben gruß Holger
Hi Holger,
auf die Schnelle: das Template sieht so aus:
##############################################
# $Id: myUtilsTemplate.pm 21509 2020-03-25 11:20:51Z 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;
sub
myUtils_Initialize($$)
{
my ($hash) = @_;
}
# Enter you functions below _this_ line.
1;
Da fällt am Ende die Zeile auf 1; - die ist wichtig - am Ende! :)
Bei Dir steht die Zeile jetzt zwischendrin!
below _this_ line. -> heisst nach dieser Linie - nicht nach der übernächsten bzw. einfach am Ende!
Der Rest muss halt immer in solchen Blöcken sein (siehe auch https://wiki.fhem.de/wiki/99_myUtils_anlegen) :
sub name {
Dein Perl Code
}
Gruß Otto
Okay die eins habe ich jetzt ans ende geschoben, beim abspeichern aber noch die meldung:
syntax error at ./FHEM/99_myUtils.pm line 217, near "sum @" Global symbol "$i" requires explicit package name (did you forget to declare "my $i"?) at ./FHEM/99_myUtils.pm line 217. Global symbol "$i" requires explicit package name (did you forget to declare "my $i"?) at ./FHEM/99_myUtils.pm line 217. Global symbol "@PreisIntervall" requires explicit package name (did you forget to declare "my @PreisIntervall"?) at ./FHEM/99_myUtils.pm line 221. Global symbol "@PreisIntervall" requires explicit package name (did you forget to declare "my @PreisIntervall"?) at ./FHEM/99_myUtils.pm line 222. syntax error at ./FHEM/99_myUtils.pm line 227, near "}" Can't use global @_ in "my" at ./FHEM/99_myUtils.pm line 245, near "= @_" syntax error at ./FHEM/99_myUtils.pm line 278, near "}"
Lg Holger
Hey also der erste fehler
syntax error at ./FHEM/99_myUtils.pm line 217, near "sum @" Global symbol "$i" requires explicit package name (did you forget to declare "my $i"?) at ./FHEM/99_myUtils.pm line 217. Global symbol "$i" requires explicit package name (did you forget to declare "my $i"?) at ./FHEM/99_myUtils.pm line 217. Global symbol "@PreisIntervall" requires explicit package name (did you forget to declare "my @PreisIntervall"?)
da steht das
@PreisIntervall[$i] = sum @{$Strompreise}[$i..$i+$Laufzeit-1];
#Log3 undef, 3, "Preisintervall Summe: @PreisIntervall[$i]";
}
der 2. Fehler: at ./FHEM/99_myUtils.pm line 221. Global symbol "@PreisIntervall" requires explicit package name (did you forget to declare "my @PreisIntervall"?)
my $MinPreis = min @PreisIntervall;
Fehler3 at ./FHEM/99_myUtils.pm line 222. syntax error at ./FHEM/99_myUtils.pm line 227, near "}" Can't use global @_ in "my"
my $MinIndex = first_index { $_ eq $MinPreis } @PreisIntervall;
und zuletzt at ./FHEM/99_myUtils.pm line 245, near "= @_" syntax error at ./FHEM/99_myUtils.pm line 278, near "}"
my ($MinHour,$Laufzeit,$LaufzeitEnde) = @_;
my @PreiseHeute = split /\|/, ReadingsVal("myTibber","TodayTotal",0.25);
my @PreiseMorgen = split /\|/, ReadingsVal("myTibber","TomorrowTotal",0.25);
my @AllePreise = (@PreiseHeute, @PreiseMorgen);
my ($tmp, $m, $h, $tmp, $tmp, $tmp, $tmp, $tmp, $tmp) = localtime(time);
my $MinZeit = "";
# Falls die Mindestzeit vor der akt. Zeit liegt Mindestzeit auf akt. Zeit setzen
if($h >= $MinHour)
{
$LaufzeitEnde = $LaufzeitEnde - ($h - $MinHour);
$MinHour = $h;
}
my $LaufzeitIndex = ($MinHour + $LaufzeitEnde) <= 48 ? $MinHour + $LaufzeitEnde - 1 : 47;
@AllePreise = @AllePreise[$h..$LaufzeitIndex];
my $MinZeitIndex = MinTibberZeitfenster(\@AllePreise, $Laufzeit);
if($MinZeitIndex + $h > 24) # Uhrzeit ist am nächsten Tag
{
$MinZeit = sprintf("%02d", $MinZeitIndex + $h - 24).":00";
}
else
{
$m = $MinZeitIndex == 0 && $MinHour == $h ? $m + 2 : 0; # Uhrzeit entspricht Aufrufzeit, daher 2 Minuten aufschlagen
$MinZeit = sprintf("%02d", $MinZeitIndex + $h).":".sprintf("%02d", $m);
}
Log3 undef, 3, "MindestStrompreis: Aktuelle Zeit:$h:$m Startzeit:$MinZeit";
return $MinZeit;
}
myutils1.jpgmyutils2.jpg
Das ist doch fast immer der gleiche Fehler - Du versuchst, auf Variablen zuzugreifen, die nicht existieren, weil Du sie nicht definiert hast.
did you forget to declare "my $i"?
did you forget to declare "my @PreisIntervall"?
Mit den Bruchstücken, die Du hier postest, kann Dir aber niemand weiterhelfen.
(Vermutung)
Mal wieder irgendein ohne Sinn und Verstand zusammengeklauter copy&paste Schrott...?
(/Vermutung)
Zitat von: Tueftler1983 am 21 August 2023, 16:05:07Okay die eins habe ich jetzt ans ende geschoben, beim abspeichern aber noch die meldung:
Sicher? ich sehe in #1 mindestens 2 x diese Textkette mittendrin. ;) Wenn einer schauen soll, musst Du schon nochmal den aktuellen Stand posten.
Zitat von: Otto123 am 21 August 2023, 20:22:51Wenn einer schauen soll, musst Du schon nochmal den aktuellen Stand posten.
Und zwar vollständig und möglichst nicht als Screenshot, sondern als Datei.
Und ansonsten .. er schreibt ja incl. Zeilennumer den genauen Fehler .....
Sorry, war nicht Zuhause und habe seltsamerweise keine Benachrichtigung bekommen das ihr geantwortet habt.
Zur Vermutung ja es ist eig alles Copy und Paste und es scheint ja zu funktionieren also ich bekomme die Werte aber halt diese Meldungen.
Vielen dank für die hilfe, hoffe das ich die Syntax verstehe wenn ich mir nachher angucke was anders ist bzw ich die änderungen mache.
Zeile 125, also mitten drin steht immer noch das 1;
Muss da also weg!
Versuche bitte einmal folgenden Code
sub MinTibberZeitfenster
{
my ($Strompreise, $Laufzeit) = @_;
my $anz = @{$Strompreise};
my @PreisIntervall;
Log3 undef, 3, "MinTibberZeitfenster: Strompreise=@{$Strompreise} Laufzeit=$Laufzeit";
for (my $i = 0; $i < ($anz - $Laufzeit +1); $i++)
{
$PreisIntervall[$i] = sum ${$Strompreise}->[$i..$i+$Laufzeit-1];
#Log3 undef, 3, "Preisintervall Summe: @PreisIntervall[$i]";
}
my $MinPreis = min @PreisIntervall;
my $MinIndex = first_index { $_ eq $MinPreis } @PreisIntervall;
Log3 undef, 3, "MinTibberZeitfenster: $MinPreis MinIndex=$MinIndex";
return $MinIndex;
}
Also die Fehlermeldungen im Log sind weg, wo das Zeitfenster des Günstigsten Stromes angezeigt werden soll erschließt sich mir trotzdem nicht. Ich denke ich muss mich da nochmal in den Beitrag einlesen.
Es waren oder sind einfach Grade sehr viele Baustellen nicht nur mit fhem.
Aber nochmals herzlichen Dank für die Hilfe