Hauptmenü

FHEM Log

Begonnen von Mundus, 24 März 2018, 23:05:18

Vorheriges Thema - Nächstes Thema

Mundus

Hi,

ich habe -auch im CUL-Forum https://forum.fhem.de/index.php/topic,85184.0.html bereits geschrieben- leider das Problem, dass mein Log-File nicht mit Werten befüllt wird, die ich tatsächlich brauche.

In dem File würde ich gerne, damit die Readings im LOG auftauchen, "setreading" gegen "readingsSingleUpdate" austauschen. Leider fehlt mir dafür die Umsetzungsidee bzw. die richtige Syntax.

So der Code der File lautet##############################################
# $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 berechneBinaer($);

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

# Enter you functions below _this_ line.

sub TCM302($$)
{
  my ($hexWert,$Device) = @_;
my @hexarray = split(//,$hexWert);
my @binArray;

foreach (@hexarray) {
push(@binArray,sprintf("%04b",hex($_)));
}

#Channel Bits
my @binZerlegt = split(//,$binArray[3]);
my $channel = $binZerlegt[0].$binZerlegt[1];
if ($channel == "00") {
$channel = 1;
}elsif ($channel == "01"){
$channel = 2;
}elsif ($channel == "10"){
$channel = 3;
}

fhem("setreading $Device Kanal $channel");

#TX Bit
@binZerlegt = split(//,$binArray[8]);
my $tx = $binZerlegt[2];

fhem("setreading $Device TX $tx");

#Luftfeuchte
@binZerlegt = split(//,$binArray[7]);
my $Luft = $binZerlegt[2].$binZerlegt[3];
@binZerlegt =split(//,$binArray[8]);
$Luft = $Luft . $binZerlegt[0]. $binZerlegt[1];
@binZerlegt =split(//,$binArray[6]);
$Luft = $Luft . $binZerlegt[2]. $binZerlegt[3];
@binZerlegt =split(//,$binArray[7]);
$Luft = $Luft . $binZerlegt[0]. $binZerlegt[1];
$Luft = berechneBinaer($Luft);

#Log3 $hexWert,3, "Die Luft hat $Luft%\n";
fhem("setreading $Device Luftfeuchte $Luft%");

#Temperatur
@binZerlegt = split(//,$binArray[5]);
my $Temp = $binZerlegt[2].$binZerlegt[3];
@binZerlegt =split(//,$binArray[6]);
$Temp = $Temp . $binZerlegt[0]. $binZerlegt[1];
@binZerlegt =split(//,$binArray[4]);
$Temp = $Temp . $binZerlegt[2]. $binZerlegt[3];
@binZerlegt =split(//,$binArray[5]);
$Temp = $Temp . $binZerlegt[0]. $binZerlegt[1];
@binZerlegt =split(//,$binArray[3]);
$Temp = $Temp . $binZerlegt[2]. $binZerlegt[3];
@binZerlegt =split(//,$binArray[4]);
$Temp = $Temp . $binZerlegt[0]. $binZerlegt[1];
$Temp = berechneBinaer($Temp);

my $TempFahr = ($Temp-900)/10;
my $TempCels = ($TempFahr-32)/1.8;
$TempCels = sprintf("%.2f", $TempCels);

#Log3 $hexWert,3, "Celsius lautet die Temp: $TempCels°C\n";
fhem("setreading $Device Temperatur $TempCels°C");
}

sub berechneBinaer{

foreach(@_){
my $x = $_;
my $n = 1;
my $value;
while($x) {
$value +=$n*chop($x);
$n *=2;
}
return $value;
}
}
 
1;


Sämtliche Versuche readingsSingleUpdate einzubinden scheitern.
readingsSingleUpdate($hash->{NAME},"Temperatur",$TempCels,1)
ist nicht erfolgreich, auch readingsSingleUpdate($defs{$Device},"Temperatur",$TempCels,1) nicht. Ich vermute meine Wertzuweisung ist falsch, aber wie es richtig aussehen muss, ist mir schleierhaft.

Ich würde mich freuen, wenn ihr mir helfen könnt und ich mein LogFile nutzen kann:-). Denn ehrlich gesagt hilft mir ein Log mit Hexadezimalen zahlen nicht (sofort) weiter.

Gruß

Mundus

mumpitzstuff

Guckst du hier:

https://wiki.fhem.de/wiki/DevelopmentModuleAPI

Übergib mal nur $hash als ersten Parameter.

Wzut

jetzt
fhem("setreading $Device Temperatur $TempCels°C");
wird zu
readingsSingleUpdate($Device,"Temperatur",$TempCels,1);
bzw
readingsSingleUpdate($Device,"Temperatur",$TempCels."°C"",1);
wenn die Einheit unbedingt noch mit ins Reading soll
Wenn das mit allen Werten klappt  : bau das ganze noch um so das alle Werte aus $hexwert mittels readingsBulkUpdate am Stück übertragen werden.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

Thorsten Pferdekaemper

Hi,
in welches Log schreibt readingsSingleUpdate rein, setreading aber nicht? Schau Dir mal CommandSetReading in fhem.pl an. Der Befehl setreading macht auch nichts anderes ans readingsSingleUpdate aufzurufen.
Nach Konsultation der Glaskugel: Möglicherweise hilft es, wenn Du das ganze (egal ob setreading oder readingsSingleUpdate) per InternalTimer "asynchron" machst.
Gruß,
   Thorsten
FUIP

Mundus

Hi,

vielen Dank für eure Hilfe.

1. Den Hinweis von Wzut hatte ich bereits im Vorfeld ausprobiert, funktionierte auch nicht...

2. Den Hinweis von mumpitzstuff verstehe ich nicht bzw. setze ihn falsch um. Mein Notify sieht dann wie folgt ausdefine nt_Wetter_Sensor_aussen notify cul_Wetter_Sensor_aussen.Code.* {
TCM302($hash);
}

Die File habe ich natürlich angepasst, aber es gibt eine Fehlermeldung das $hash nicht bekannt ist...

3. Der Hinweis von Thorsten hat mich erneut einige Einträge lesen lassen https://forum.fhem.de/index.php/topic,28017.15.html und die Commandref zu setstate. Jetzt habe ich meine File entsprechend der Commandref angepasst. Alle setreadings sind jetzt um sleep 0.1 ergänzt. Dementsprechend sieht eine Zeile jetzt wie folgt aus
...
fhem("sleep 0.1; setreading $Device Temperatur $TempCels°C");
...


@Thorsten, ist das die Lösung, die du meintest?

Könnt ihr mir noch sagen, ob dies der gewollte Weg in FHEM ist, umso Einträge in das Log zu schreiben?

Gruß

Thorsten Pferdekaemper

Zitat von: Mundus am 25 März 2018, 23:15:43
@Thorsten, ist das die Lösung, die du meintest?
Prinzipiell ja, nur dass ich das per InternalTimer machen würde und es nicht gleich ganze 0.1s in die Zukunft schicken würde.

Zitat
Könnt ihr mir noch sagen, ob dies der gewollte Weg in FHEM ist, umso Einträge in das Log zu schreiben?
Wenn man aus einem richtigen Gerätemodul heraus Readings setzt, dann braucht man das oft nicht. Das Problem ist aber folgendes: Wenn ein Reading gesetzt wird dann wird (normalerweise) ein Event ausgelöst. Dieses Event triggert dann (potenziell) Notifys, DOIFs und anderen Kram. "Anderer Kram" kann auch das Schreiben eines Filelog sein. (Die Filelogs greifen sich einfach die Events ab und filtern sie.) Wenn man jetzt aus einem Notify (oder ähnlichem) heraus ein Reading setzt, dann löst das wiederum ein Event aus, welches ggf. Notifys triggert usw. Wenn's blöd läuft würde dadurch FHEM komplett blockiert.
Deswegen ist es besser, wenn in dieser Situation die Readings keine Events mehr generieren.
Durch das "Verschieben in die Zukunft" stellt sich das Reading (und damit sein Event) sozusagen erstmal hinten an und FHEM kann alles, was ansteht, erstmal fertig machen. Dadurch gibt es dann keine "Notify-Rekursion" mehr.
Gruß,
    Thorsten

FUIP

Mundus

Zitat von: Thorsten Pferdekaemper am 25 März 2018, 23:37:12
Prinzipiell ja, nur dass ich das per InternalTimer machen würde und es nicht gleich ganze 0.1s in die Zukunft schicken würde.
Wie würde das korrekt aussehen? Ein Aufruf im Notify InternalTimer(time()+1,TCM302,$EVTPART1 $NAME) ist scheinbar nicht richtig. Laut wiki kann InternalTimer nur einen Übergabeparameter verarbeiten...

ZitatWenn man jetzt aus einem Notify (oder ähnlichem) heraus ein Reading setzt, dann löst das wiederum ein Event aus, welches ggf. Notifys triggert usw. Wenn's blöd läuft würde dadurch FHEM komplett blockiert.
;D das ist mir leider auch passiert. Ein Reboot und schnelles Anpassen des Notify hat das Problem gelöst. Das Notify "lauschte" vor der Anpassung an allen Events des Device und hat zu dem beschriebenen Phänomen geführt. Also habe ich das ganze so angepasst cul_Wetter_Sensor_aussen.Code.* und keine Probleme mehr.

Gruß

Mundus

mumpitzstuff

Ich meinte, das du z.B.

readingsSingleUpdate($hash,"Temperatur",$TempCels,1)

anstatt

readingsSingleUpdate($hash->{NAME},"Temperatur",$TempCels,1)

verwenden sollst.

Thorsten Pferdekaemper

Zitat von: Mundus am 26 März 2018, 00:30:38
Wie würde das korrekt aussehen? Ein Aufruf im Notify InternalTimer(time()+1,TCM302,$EVTPART1 $NAME) ist scheinbar nicht richtig. Laut wiki kann InternalTimer nur einen Übergabeparameter verarbeiten...
Ich würde sagen in etwa so:

InternalTimer(gettimeofday(),\&TCM302,[$EVTPART1,$NAME]);

...und dann am Anfang von TCM302:

sub TCM302($)
{
  my ($hexWert,$Device) = @{$_[0]};
my @hexarray = split(//,$hexWert);

...oder so.

Zitat
;D das ist mir leider auch passiert. Ein Reboot und schnelles Anpassen des Notify hat das Problem gelöst. Das Notify "lauschte" vor der Anpassung an allen Events des Device und hat zu dem beschriebenen Phänomen geführt. Also habe ich das ganze so angepasst cul_Wetter_Sensor_aussen.Code.* und keine Probleme mehr.
Ja, auch wenn alle mit InternalTimer oder so arbeiten kann es solche Effekte geben. Das mit dem InternalTimer verhindert ja das unendliche Abarbeiten nicht, sondern gibt FHEM nur die Chance, "zwischendurch" auch mal wieder dranzukommen um andere Sachen zu erledigen und nicht komplett zu blockieren. Trotzdem kann die CPU-Belastung auf 100% gehen und es kann die Performance- und Timingproblemen kommen.
Gruß,
   Thorsten
FUIP