[Wunsch] 93_DbLog - einfache Funktion um Readings auszulesen

Begonnen von betateilchen, 17 Februar 2014, 01:12:07

Vorheriges Thema - Nächstes Thema

betateilchen

Ich bin auf der Suche nach Funktionen analog zu ReadingsVal und ReadingsTimestamp, mit denen sich jedes beliebige aktuelle Reading eines beliebigen Devices aus der Datenbank abfragen lassen.

Hierzu habe ich mir folgendes für die 93_DbLog ausgedacht:



sub
DbLog_Get($@)
{
  my ($hash, @a) = @_;

return dbReadings($hash,@a) if $a[1] =~ m/^Readings/;

  return "Usage: get $a[0] <in> <out> <from> <to> <column_spec>...\n".

...

sub dbReadings($@) {
my($hash,@a) = @_;
my $dbhf= $hash->{DBHF};
return 'Wrong Syntax for ReadingsVal!' unless defined($a[4]);
my $query = "select VALUE,TIMESTAMP from history where DEVICE= '$a[2]' and READING= '$a[3]' order by TIMESTAMP desc limit 1";
my ($reading,$timestamp) = $dbhf->selectrow_array($query);
$reading = ($reading) ? $reading : $a[4];
$timestamp = ($timestamp) ? $timestamp : $a[4];
return $reading if $a[1] eq 'ReadingsVal';
return $timestamp if $a[1] eq 'ReadingsTimestamp';
return "Syntax error: $a[1]";
}



Damit kann ich nun mittels


get MySqlLog ReadingsVal       BMP180 pressure-nn 77
get MySqlLog ReadingsTimestamp BMP180 pressure-nn 77


jedes beliebige Reading abfragen. Der Aufruf ist identisch zu ReadingsVal() und ReadingsTimestamp, nur dass die Klammern fehlen.

BMP180 = deviceName
pressure-nn = readingName
77 = default
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig

Die Funktionalitaet mit deutlich komplexeren Syntax gibt es schon fuer FileLog und DbLog, und wird von SVG.pm verwendet.
Siehe http://fhem.de/commandref.html#FileLogget bzw. http://fhem.de/commandref.html#DbLogget


betateilchen

Hallo Rudi,

kenn ich, und damit habe ich gestern bereits mehrere Stunden (!) verbracht, ohne das gewünschte Ergebnis zu bekommen.
Genau die Komplexität ist das Problem. Fürs Plotten mag das wunderbar funktionieren - aber vermutlich auch NUR fürs Plotten.

Hast Du eigentlich verstanden, WAS ich haben will?
EINEN einzigen bestimmten - nämlich den letzten (ich weiss also weder ein FROM noch ein TO!) - geloggten Wert eines Readings. Mehr nicht. Und dafür eine EINFACHE Lösung.

Viele Grüße
Udo
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

achja, wo wir grade beim Wünschen sind, ich hätte gerne in der DbLog Struktur noch ein Feld, in dem der Host geloggt wird, der die Daten in die Datenbank schickt  8)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Wuppi68

Hallo betateilchen,

wäre nicht allen geholfen, wenn man direkt einen SQL String abschicken kann?
Jetzt auf nem I3 und primär Homematic - kein Support für cfg Editierer

Support heißt nicht wenn die Frau zu Ihrem Mann sagt: Geh mal bitte zum Frauenarzt, ich habe Bauchschmerzen

rudolfkoenig

ZitatHast Du eigentlich verstanden, WAS ich haben will?

Erst nach dieser Erklaerung.
So aehnlich wie OldValue(), aber auch fuer Readings.

betateilchen

nein, so ähnlich wie ReadingsVal(), nur nicht aus dem Device, sondern den geloggten Wert aus der Datenbank.

Hintergrund:

Bei mir loggen drei fhem Installation gemeinsam in eine Datenbank (auf einer zentralen 4. Hardware) und ich möchte das Plotten und die RSS-Generierung auf diese vierte Hardware verlegen.

Auf dieser Hardware sind keinerlei devices vorhanden (ausser den SVG und RSS) aber die Datenbank mit den zu verwendenden Werten. Für das Plotten funktioniert das auch jetzt schon problemlos. Aber in den RSS-layouts muss ich aktuelle einzelne ReadingsVal() ermitteln, was bisher in dieser Konstellation nicht funktioniert.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

Aus Performancegründen macht es viel mehr Sinn, auf die Tabelle "current" zuzugreifen, dann kann man das "Limit 1" und das "order by" komplett weglassen.


sub dbReadings($@) {
my($hash,@a) = @_;
my $dbhf= $hash->{DBHF};
return 'Wrong Syntax for ReadingsVal!' unless defined($a[4]);
my $query = "select VALUE,TIMESTAMP from current where DEVICE= '$a[2]' and READING= '$a[3]'";
my ($reading,$timestamp) = $dbhf->selectrow_array($query);
$reading = ($reading) ? $reading : $a[4];
$timestamp = ($timestamp) ? $timestamp : $a[4];
return $reading if $a[1] eq 'ReadingsVal';
return $timestamp if $a[1] eq 'ReadingsTimestamp';
return "Syntax error: $a[1]";
}


Endlich hab ich den Sinn der Tabelle current verstanden - auch wenn die scheinbar nur bei MySQL Logging existiert, bei SQlite ist die bei mir immer leer.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

justme1968

wie in dem anderen thread schon gesagt :) die ist nicht leer sondern pro prozess in memory gecached.

wenn du das cachen abschaltest wie es ganz ursprünglich mal war wird es genau so wie history auf platte geschrieben und ist zu sehen.

leider leider die dann performance  erheblich.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

betateilchen

Warum ist das Verhalten bei sqlite und bei mysql derartig unterschiedlich?

Das select * from current funktioniert in mysql, aber nicht in sqlite.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

JoeALLb

sqlite speichert die Werte nicht ind er Tabelle, sondern in einer Memory-Tabelle.
Meines Wissens ist diese nur für die aktuelle Verbindung verfügbar.
FHEM-Server auf IntelAtom+Debian (8.1 Watt), KNX,
RasPi-2 Sonos-FHEM per FHEM2FHEM,RasPi-3 Versuchs-RasPi für WLAN-Tests
Gateways: DuoFern Stick, CUL866 PCA301, CUL HM, HMLan, JeeLink, LaCrosse,VCO2
Synology. Ardurino UNO für 1-Wire Tests, FB7270

betateilchen

Danke für den 27. Versuch, mir das erklären zu wollen, dadurch wird Dein Hinweis aber auch nicht zielführend. Denn ich nutze ja für die Abfrage die bestehende Verbindung.

Und warum man für SQLITE diese Extrawurst brät, ist mir nach wie vor unklar, die immer wieder angebrachten Performancegründe können definitiv nicht der wirkliche Grund sein. (Das hab ich inzwischen mit 100.000 Datensätzen getestet!) Ich arbeite gerade (aufgrund einer ohnehin bestehenden Socket-Problematik in diesem Modul) an einer tiefen Analyse der Verbindungsabläufe und bin auf der Suche nach einer wirklichen Optimierung und Fehlerbehebung. Da im Modul beim Loggen transaktional gearbeitet wird, macht es z.B. keinen Sinn, das auto-commit aktiviert zu lassen, das alleine schon für erhebliche Performance-Problem sorgt. Der technische Ablauf des Loggens innerhalb des Moduls muss m.E. grundlegend optimiert werden. Sobald ich da konkrete Vorschläge habe, werde ich die natürlich kundtun.

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

justme1968

ja. ich glaube das hab ich schon ein paar mal versucht zu erklären.

bei sqlite wird für current explizit eine temporäre in memory tabelle verwendet und die ist nur für die connection zu sehen die sie auch angelegt hat.

wenn du statt dessen eine normale tabelle verwendest ist current auch für andere connections zu sehen. das war füher mal so ist aber sehr viel langsamer. da konnte man current glaube ich aber noch nicht abschalten. d.h. eigentlich könnte man die optimierung auch wieder raus bauen und statt dessen current nicht verwenden wenn man man es nicht braucht.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

betateilchen

#13
siehe meinen letzten Beitrag - ich verwende die aktuelle Verbindung...

Laßt mich doch einfach mal schrauben ;) Diese ganzen workarounds sind doch alles keine Lösungen.

Heute haben wir die SET-Funktionen bekommen, das finde ich schonmal klasse.
Und hier im Thread gehts um eine neue Funktion, um Readings auslesen, und eigentlich nicht um die technischen Hintergründe des Moduls selbst.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!