Modul 93_DbRep - Reporting und Management von Datenbankinhalten (DbLog)

Begonnen von DS_Starter, 19 Mai 2016, 22:52:13

Vorheriges Thema - Nächstes Thema

ch.eick

Zitat
Kann man das nicht eleganter lösen, so dass man es auch einfacher warten kann?
Die at-Befehle kann ich auch nicht gleichzeitig ausführen lassen, da die dbRep sich gegenseitig sperren... der erste geht, und die nachfolgenden bekommen Fehler beim DB-Zugriff.
Ich bin ein Freund von DOIF, somit könntest Du alles in ein DOIF, eventuell mit einem gewünschtem wait abarbeiten.
Dann könntest Du die Statistiken auch eventuell in einem SQL Skript abarbeiten.

@Heiko: Kann man eigentlich alle "maxValue writeToDB"  in ein DbRep mit einer reading Maske eintragen?

Gruß
   Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Hallo zusammen,
Ich rufe folgendes auf, um einen Wert zur vollen Stunde abzufragen:
$i läuft dabei von 7-19

my $Solar_Correction_Faktor_fc0 = DbReadingsVal("LogDBRep_select_PV_Forecast","PV_1:fc0_Factor",sprintf("%4d-%02d-%02d_%02d:00:00",$year,$mon,$mday,$i),1) ;


Nach 17:00 Uhr sollte dann eigentlich nichts mehr kommen und der Faktor auf 1 gesetzt werden

SELECT * from history where DEVICE='PV_1' AND READING='fc0_Factor' AND TIMESTAMP > CURDATE();
+---------------------+--------+------+-------+------------+-------+------+
| TIMESTAMP           | DEVICE | TYPE | EVENT | READING    | VALUE | UNIT |
+---------------------+--------+------+-------+------------+-------+------+
| 2021-02-08 09:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 6.9   | NULL |
| 2021-02-08 10:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 5.0   | NULL |
| 2021-02-08 11:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 1.9   | NULL |
| 2021-02-08 12:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 1.9   | NULL |
| 2021-02-08 13:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 1.8   | NULL |
| 2021-02-08 14:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 1.9   | NULL |
| 2021-02-08 15:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 2.0   | NULL |
| 2021-02-08 16:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 2.0   | NULL |
+---------------------+--------+------+-------+------------+-------+------+


Das List vom DbRep nach dem Lauf

Internals:
   DATABASE   fhem
   DEF        LogDB
   FUUID      5f50bc9b-f33f-61a8-e635-e249a4e08a2531c6
   FVERSION   93_DbRep.pm:v8.42.3-s23462/2021-01-03
   LASTCMD    sqlCmdBlocking select value from (
                ( select *, TIMESTAMPDIFF(SECOND, '2021-02-08 19:00:00', timestamp) as diff from history
                  where device='PV_1' and reading='fc0_Factor' and timestamp >= '2021-02-08 19:00:00' order by timestamp asc limit 1
                )
                union
                ( select *, TIMESTAMPDIFF(SECOND, timestamp, '2021-02-08 19:00:00') as diff from history
                  where device='PV_1' and reading='fc0_Factor' and timestamp < '2021-02-08 19:00:00' order by timestamp desc limit 1
                )
              ) x order by diff limit 1;
   MODEL      Client
   NAME       LogDBRep_select_PV_Forecast
   NOTIFYDEV  global,LogDBRep_select_PV_Forecast
   NR         478
   NTFY_ORDER 50-LogDBRep_select_PV_Forecast
   ROLE       Client
   STATE      done
   TYPE       DbRep
   UTF8       1
   HELPER:
     DBLOGDEVICE LogDB
     IDRETRIES  3
     PACKAGE    main
     SQLHIST   
     VERSION    8.42.3
   OLDREADINGS:
   READINGS:
     2021-01-04 15:40:02   index_state     Index Report_Idx exists
     2021-02-08 22:49:51   state           done
Attributes:
   DbLogExclude .*
   readingNameMap VALUE
   room       System


Habe ich da ein Attribut vergessen?

Gruß
   Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

EDIT: Jetzt habe ich es geschafft.
1. Es darf nur ein SQL Command sein.
2. Die Set Statements kommen ins Attribut sqlCmdVars
3. Das SQL DELETE habe ich ins INSERT integriert

Dann sieht das jetzt so als RAW aus

defmod LogDBRep_insert_PV_Forecast_correction DbRep LogDB
attr LogDBRep_insert_PV_Forecast_correction DbLogExclude .*
attr LogDBRep_insert_PV_Forecast_correction room System
attr LogDBRep_insert_PV_Forecast_correction sqlCmdVars SET @days:=3, @corr:=0.7, @diff:=0, @temp:=0, @device:='PV_1', @reading1:='Total_DC_Power_(sumOfAllPVInputs)', @reading2:='Solar_Calculation_fc0', @readingname:='Solar_Correction_Faktor_auto' ;;

Und wird so aufgerufen :-) :-)

set LogDBRep_insert_PV_Forecast_correction sqlCmd   INSERT INTO history  (TIMESTAMP,DEVICE,READING,VALUE)  SELECT  TIMESTAMP,DEVICE,READING,VALUE  FROM (  SELECT  DATE_ADD(CURDATE(),INTERVAL t2.HOUR HOUR) AS TIMESTAMP,  t2.DEVICE,  @readingname AS READING,  cast(if(avg(t2.FACTOR) > 1.6, 1.6,  avg(t2.FACTOR) ) AS DECIMAL(2,1)) AS VALUE  FROM (  SELECT * FROM (  SELECT  t1.TIMESTAMP,  t1.HOUR,  t1.DEVICE,  t1.READING,  t1.VALUE,  if(@diff = 0,NULL, @temp:=cast((t1.VALUE-@diff) AS DECIMAL(6,2))) AS DIFF,  cast((t1.VALUE/(t1.VALUE+(-1*@temp))*@corr) AS DECIMAL(2,1)) AS FACTOR,  @diff:=t1.VALUE AS curr_V  FROM (  SELECT  TIMESTAMP,  date(TIMESTAMP) AS DATE,  hour(TIMESTAMP) AS HOUR,  DEVICE,  READING,  VALUE  FROM history  WHERE DEVICE = @device  AND (READING = @reading1 OR READING = @reading2)  AND TIMESTAMP >= DATE_SUB(DATE(now()),INTERVAL @days DAY)  AND TIMESTAMP <= CURDATE()  AND MINUTE(TIMESTAMP) = 0  AND VALUE >= 0  GROUP BY DATE,HOUR,READING  )t1  )tx  WHERE  READING != @reading2  )t2  GROUP BY t2.HOUR  )t3  WHERE  t3.VALUE != 0  ON DUPLICATE KEY UPDATE  VALUE=t3.VALUE;


Im Perl baut man das dann lieber folgendermaßen ein, damit man es auch lesen kann.

         # Neuberechnung der stündlichen Autokorrektur Faktoren in der Datenbank. Das DbRep Device LogDBRep_insert_PV_Forecast_correction muss vorhanden sein.
         # Achtung, beim SQL muss '@' mit '\@' maskiert werden.
         CommandSet(undef, "LogDBRep_insert_PV_Forecast_correction sqlCmd ".sprintf("
                INSERT INTO history
                 (TIMESTAMP,DEVICE,READING,VALUE)
                  SELECT
                    TIMESTAMP,DEVICE,READING,VALUE
                  FROM (
                    SELECT
                      DATE_ADD(CURDATE(),INTERVAL t2.HOUR HOUR) AS TIMESTAMP,
                      t2.DEVICE,
                      \@readingname                             AS READING,
                      cast(if(avg(t2.FACTOR) > 1.6, 1.6,
                              avg(t2.FACTOR) ) AS DECIMAL(2,1)) AS VALUE
                    FROM (
                      SELECT * FROM (
                        SELECT
                          t1.TIMESTAMP,
                          t1.HOUR,
                          t1.DEVICE,
                          t1.READING,
                          t1.VALUE,
                          if(\@diff = 0,NULL, \@temp:=cast((t1.VALUE-\@diff) AS DECIMAL(6,2))) AS DIFF,
                          cast((t1.VALUE/(t1.VALUE+(-1*\@temp))*\@corr) AS DECIMAL(2,1))       AS FACTOR,
                          \@diff:=t1.VALUE                                                     AS curr_V
                        FROM (
                          SELECT
                            TIMESTAMP,
                            date(TIMESTAMP) AS DATE,
                            hour(TIMESTAMP) AS HOUR,
                            DEVICE,
                            READING,
                            VALUE
                          FROM history
                          WHERE DEVICE    =  \@device
                            AND (READING  =  \@reading1 OR READING = \@reading2)
                            AND TIMESTAMP >= DATE_SUB(DATE(now()),INTERVAL \@days DAY)
                            AND TIMESTAMP <= CURDATE()
                            AND MINUTE(TIMESTAMP) = 0
                            AND VALUE >= 0
                          GROUP BY DATE,HOUR,READING
                         )t1
                       )tx
                        WHERE
                          READING != \@reading2
                     )t2
                      GROUP BY t2.HOUR
                   )t3
                    WHERE
                      t3.VALUE != 0
                    ON DUPLICATE KEY UPDATE
                      VALUE=t3.VALUE;
           ") # Ende sprintf()
         );   # Ende CommandSet()



==============================================================================
Moin,
dann habe ich noch ein sqlCmd :-) Okay, es ist schon ein Skript :-)


SET @device='PV_1';
SET @reading1='Total_DC_Power_(sumOfAllPVInputs)';
SET @reading2='Solar_Calculation_fc0';
SET @readingname='Solar_Correction_Faktor_auto';

DELETE FROM history WHERE DEVICE=@device AND READING=@readingname AND TIMESTAMP >= CURDATE();

SET @diff=0;SET @temp=0;
INSERT INTO history (TIMESTAMP,DEVICE,READING,VALUE)
  SELECT TIMESTAMP,DEVICE,READING,VALUE
    FROM (

SELECT DATE_ADD(CURDATE(),INTERVAL t2.HOUR HOUR) AS TIMESTAMP,
       t2.DEVICE,
       @readingname                              AS READING,
       cast(if(avg(t2.FACTOR) > 1.6, 1,
               avg(t2.FACTOR) ) AS DECIMAL(2,1)) AS VALUE
  FROM
    (
     SELECT t1.TIMESTAMP,
            t1.HOUR,
            t1.DEVICE,
            t1.READING,
            t1.VALUE,
            if(@diff  = 0,NULL, @temp:=cast((t1.VALUE-@diff) AS DECIMAL(6,2))) AS DIFF,
            cast((t1.VALUE/(t1.VALUE+(-1*@temp))*0.5) AS DECIMAL(2,1))         AS FACTOR,
            @diff:=t1.VALUE                                                    AS curr_V
       FROM
         (
          SELECT TIMESTAMP,
                 date(TIMESTAMP) AS DATE,
                 hour(TIMESTAMP) AS HOUR,
                 DEVICE,
                READING,
                 VALUE
            FROM history
            WHERE
              DEVICE    =    @device    AND
              (READING  =    @reading1  OR
               READING  =    @reading2) AND
              TIMESTAMP >=   DATE_SUB(DATE(now()),INTERVAL 30 DAY) AND
              TIMESTAMP <    CURDATE()  AND
              TIMESTAMP LIKE '%:00:%'   AND
              VALUE >= 0
           GROUP BY DATE,HOUR,READING
         )t1
       WHERE
         READING != @reading2 AND
         VALUE   != 0
    )t2
    GROUP BY t2.HOUR

  )t3
  WHERE
    t3.VALUE != 0;

SELECT * FROM history WHERE DEVICE=@device AND READING=@readingname AND TIMESTAMP >= CURDATE();

+---------------------+--------+------+-------+------------+-------+------+
| TIMESTAMP           | DEVICE | TYPE | EVENT | READING    | VALUE | UNIT |
+---------------------+--------+------+-------+------------+-------+------+
| 2021-02-09 08:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 0.1   | NULL |
| 2021-02-09 09:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 1.0   | NULL |
| 2021-02-09 10:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 1.0   | NULL |
| 2021-02-09 11:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 1.0   | NULL |
| 2021-02-09 12:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 0.7   | NULL |
| 2021-02-09 13:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 0.5   | NULL |
| 2021-02-09 14:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 0.5   | NULL |
| 2021-02-09 15:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 0.4   | NULL |
| 2021-02-09 16:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 0.2   | NULL |
| 2021-02-09 17:00:00 | PV_1   | NULL | NULL  | fc0_Factor | 0.1   | NULL |
+---------------------+--------+------+-------+------------+-------+------+


Aber DbRep sagt syntax Error

Internals:
   CFGFN     
   DATABASE   fhem
   DEF        LogDB
   FUUID      6022bc3d-f33f-61a8-b1e2-254f5e37a3bd4fbd
   FVERSION   93_DbRep.pm:v8.42.3-s23462/2021-01-03
   LASTCMD    sqlCmd SET @device='PV_1'; SET @reading1='Total_DC_Power_(sumOfAllPVInputs)'; SET @reading2='Solar_Calculation_fc0'; SET @readingname='fc0_Factor'; SET @diff=0;SET @temp=0; DELETE from history where DEVICE=@device AND READING=@readingname AND TIMESTAMP >= CURDATE(); INSERT INTO history (TIMESTAMP,DEVICE,READING,VALUE)  SELECT TIMESTAMP,DEVICE,READING,VALUE  FROM (  SELECT DATE_ADD(CURDATE(),INTERVAL t2.HOUR HOUR) AS TIMESTAMP,  t2.DEVICE,  @readingname AS READING,  cast(if(avg(t2.FACTOR) > 1.6, 1,  avg(t2.FACTOR) ) AS DECIMAL(2,1)) AS VALUE  FROM  (  SELECT t1.TIMESTAMP,  t1.HOUR,  t1.DEVICE,  t1.READING,  t1.VALUE,  if(@diff = 0,NULL, @temp:=cast((t1.VALUE-@diff) AS DECIMAL(6,2))) AS DIFF,  cast((t1.VALUE/(t1.VALUE+(-1*@temp))*0.5) AS DECIMAL(2,1)) AS FACTOR,  @diff:=t1.VALUE AS curr_V  FROM   (  SELECT TIMESTAMP,  date(TIMESTAMP) AS DATE,  hour(TIMESTAMP) AS HOUR,  DEVICE,  READING,  VALUE  FROM history  WHERE  DEVICE = @device AND  (READING = @reading1 OR  READING = @reading2) AND  TIMESTAMP >= DATE_SUB(DATE(now()),INTERVAL 30 DAY) AND  TIMESTAMP < CURDATE() AND  TIMESTAMP LIKE '%:00:%' AND  VALUE >= 0  GROUP BY DATE,HOUR,READING  )t1  WHERE  READING != @reading2 AND  VALUE != 0  )t2  GROUP BY t2.HOUR   )t3  WHERE  t3.VALUE != 0;  SELECT * from history where DEVICE=@device AND READING=@readingname AND TIMESTAMP >= CURDATE();
   MODEL      Client
   NAME       LogDBRep_insert_PV_Forecast_correction
   NOTIFYDEV  global,LogDBRep_insert_PV_Forecast_correction
   NR         148652
   NTFY_ORDER 50-LogDBRep_insert_PV_Forecast_correction
   ROLE       Client
   STATE      error
   TYPE       DbRep
   UTF8       1
   HELPER:
     DBLOGDEVICE LogDB
     GRANTS     USAGE,ALL PRIVILEGES
     IDRETRIES  2
     MINTS      2019-04-03 00:23:42
     PACKAGE    main
     SQLHIST   
     VERSION    8.42.3
     DBREPCOL:
       COLSET     1
       DEVICE     64
       EVENT      0
       READING    64
       TYPE       64
       UNIT       32
       VALUE      128
   Helper:
     DBLOG:
       state:
         LogDB:
           TIME       1612889149.94504
           VALUE      initialized
   OLDREADINGS:
   READINGS:
     2021-02-09 17:52:40   errortext       DBD::mysql::st execute failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO history (TIMESTAMP,DEVICE,READING,VALUE)  SELECT TIMESTAMP,DEVICE,RE' at line 1 at ./FHEM/93_DbRep.pm line 6414.

     2021-02-09 17:52:40   state           error
Attributes:
   DbLogExclude .*
   allowDeletion 1
   room       System
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Hi, ich nochmal mit einer weiteren Frage.

Ich verwende DbReadingsVal() zum Auslesen einzelner Werte aus der DB, jedoch stimmen die Rückgabewerte nicht.
Wenn ein Eintrag nicht vorhanden ist, soll 1 als Default kommen, jedoch wird 0.1 geliefert.

{ DbReadingsVal("LogDBRep_select_PV_Forecast","PV_1:Solar_Correction_Faktor_auto","2021-02-10_09:00:00",1) }


Die Daten

select * FROM history WHERE DEVICE=@device AND READING='Solar_Correction_Faktor_auto' AND TIMESTAMP >= CURDATE();
+---------------------+--------+------+-------+------------------------------+-------+------+
| TIMESTAMP           | DEVICE | TYPE | EVENT | READING                      | VALUE | UNIT |
+---------------------+--------+------+-------+------------------------------+-------+------+
| 2021-02-10 08:00:00 | PV_1   | NULL | NULL  | Solar_Correction_Faktor_auto | 0.1   | NULL |
| 2021-02-10 09:00:00 | PV_1   | NULL | NULL  | Solar_Correction_Faktor_auto | 1.5   | NULL |
| 2021-02-10 10:00:00 | PV_1   | NULL | NULL  | Solar_Correction_Faktor_auto | 1.0   | NULL |
| 2021-02-10 11:00:00 | PV_1   | NULL | NULL  | Solar_Correction_Faktor_auto | 1.0   | NULL |
| 2021-02-10 12:00:00 | PV_1   | NULL | NULL  | Solar_Correction_Faktor_auto | 0.7   | NULL |
| 2021-02-10 13:00:00 | PV_1   | NULL | NULL  | Solar_Correction_Faktor_auto | 0.5   | NULL |
| 2021-02-10 14:00:00 | PV_1   | NULL | NULL  | Solar_Correction_Faktor_auto | 0.5   | NULL |
| 2021-02-10 15:00:00 | PV_1   | NULL | NULL  | Solar_Correction_Faktor_auto | 0.4   | NULL |
| 2021-02-10 16:00:00 | PV_1   | NULL | NULL  | Solar_Correction_Faktor_auto | 0.2   | NULL |
| 2021-02-10 17:00:00 | PV_1   | NULL | NULL  | Solar_Correction_Faktor_auto | 0.1   | NULL |
+---------------------+--------+------+-------+------------------------------+-------+------+
10 rows in set (0.026 sec)

{ DbReadingsVal("LogDBRep_select_PV_Forecast","PV_1:Solar_Correction_Faktor_auto","2021-02-10_09:00:00",1) }
==> 1.5

MySQL [fhem]> delete FROM history WHERE DEVICE=@device AND READING='Solar_Correction_Faktor_auto' AND TIMESTAMP >= CURDATE();
Query OK, 10 rows affected (0.036 sec)

MySQL [fhem]> select * FROM history WHERE DEVICE=@device AND READING='Solar_Correction_Faktor_auto' AND TIMESTAMP >= CURDATE();
Empty set (0.021 sec)

{ DbReadingsVal("LogDBRep_select_PV_Forecast","PV_1:Solar_Correction_Faktor_auto","2021-02-10_09:00:00",1) }
==> 0.1


Das verwendete SELECT findet wohl den letzen Eintrag in der Datenbank, also bei mir vom Vortag.

select * FROM history WHERE DEVICE=@device AND READING='Solar_Correction_Faktor_auto'  AND TIMESTAMP >= '2021-02-09' and TIMESTAMP < '2021-02-10';
+---------------------+--------+------+-------+------------------------------+-------+------+
| TIMESTAMP           | DEVICE | TYPE | EVENT | READING                      | VALUE | UNIT |
+---------------------+--------+------+-------+------------------------------+-------+------+
...snip...
| 2021-02-09 17:00:00 | PV_1   | NULL | NULL  | Solar_Correction_Faktor_auto | 0.1   | NULL |
+---------------------+--------+------+-------+------------------------------+-------+------+

select value from (
                 ( select *, TIMESTAMPDIFF(SECOND, '2021-02-10 09:00:00', timestamp) as diff from history
                   where device='PV_1' and reading='Solar_Correction_Faktor_auto' and timestamp >= '2021-02-10 09:00:00' order by timestamp asc limit 1
                 )
                 union
                 ( select *, TIMESTAMPDIFF(SECOND, timestamp, '2021-02-10 09:00:00') as diff from history
                   where device='PV_1' and reading='Solar_Correction_Faktor_auto' and timestamp < '2021-02-10 09:00:00' order by timestamp desc limit 1
                 )
               ) x order by diff limit 1;
+-------+
| value |
+-------+
| 0.1   |
+-------+


select *, TIMESTAMPDIFF(SECOND, timestamp, '2021-02-10 09:00:00') as diff from history
                    where device='PV_1' and reading='Solar_Correction_Faktor_auto' and timestamp < '2021-02-10 09:00:00' order by timestamp desc limit 1 ;
+---------------------+--------+------+-------+------------------------------+-------+------+-------+
| TIMESTAMP           | DEVICE | TYPE | EVENT | READING                      | VALUE | UNIT | diff  |
+---------------------+--------+------+-------+------------------------------+-------+------+-------+
| 2021-02-09 17:00:00 | PV_1   | NULL | NULL  | Solar_Correction_Faktor_auto | 0.1   | NULL | 57600 |
+---------------------+--------+------+-------+------------------------------+-------+------+-------+


Ich denke die Art der SQL Abfrage wird eine besondere Bewandtnis haben, bzw mit der Datenbank Kompatibilität zusammen hängen.

Gruß
    Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

DS_Starter

Hallo Christian,

ZitatWenn ein Eintrag nicht vorhanden ist, soll 1 als Default kommen, jedoch wird 0.1 geliefert.
Dann gibt es wahrscheinlich noch einen Wert in der zeitlichen "Nähe".

Commandref sagt dazu:

(*) Es wird der zeitlich zu <timestamp> passendste Readingwert zurück geliefert, falls kein Wert exakt zu dem angegebenen Zeitpunkt geloggt wurde.

Grüße,
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

ch.eick

EDIT: Ich habe nun nochmal diverse Abfragen getestet.

1.) Wenn es das reading überhaupt nicht gibt, wird der Defaultwerte zurück gegeben.
2.) Wenn ich in einem Zeitraum weit vor dem ersten Eintrag abfrage wird 0.1 , was wohl der erste oder letzte Eintrag ist, zurückgemeldet.

Es scheint mir so, als ob immer der nächstliegende Wert ermittelt wird, egal wie weit er entfernt ist.
Das ist leider nichts, was ich für meine Anwendung verwenden könnte, da es nur Einträge gibt, die >0 sind und auch meistens 12h auseinander, oder auch mal Tagelang gar keine.

Wenn die Funktion so gedacht ist und es sich um keinen Fehler handelt würde ich für mich nach einer anderen Lösung suchen.
EDIT: Als Workaround verwende ich nun folgendes

$Solar_Correction_Faktor_auto = CommandGet(undef, $logdbrep." sqlCmdBlocking SELECT VALUE FROM history WHERE DEVICE='".$logdevice."' AND READING='Solar_Correction_Faktor_auto' AND TIMESTAMP='2021-02-16 12:00:00';") ;
if($Solar_Correction_Faktor_auto eq "") { $Solar_Correction_Faktor_auto = 1; };

Hierbei ist jedoch etwas unschön, das das Attribut sqlCmdVars wohl beim sqlCmd, jedoch nicht beim sqlCmdBlocking eine Wirkung hat.
Das bewirkt, dass man die Variablen dann doch wieder aus dem Perl Code heraus setzen muss.

Für meine Anforderung läuft es nun, ich stehe jedoch für eventuelle tests zur Verfügung :-)

VG
   Christian

====================================================================================
Hallo Heiko,
da biste ja wieder :-)

Zitat von: DS_Starter am 15 Februar 2021, 20:42:20
Dann gibt es wahrscheinlich noch einen Wert in der zeitlichen "Nähe".

Commandref sagt dazu:

(*) Es wird der zeitlich zu <timestamp> passendste Readingwert zurück geliefert, falls kein Wert exakt zu dem angegebenen Zeitpunkt geloggt wurde.
Das war mir schon bekannt und ich habe direkt mal nachgesehen. Der letzte Eintrag war am Vortag, ich versuche es morgen nochmal nachzustellen.
Wenn ich aber einen Wert um 7:00 abfrage darf nicht der letzte Wert vom Vortag kommen. Wofür ist ansonsten der Default Wert in der Funktion.
Wie soll man denn "passendste" definieren? Minuten,Stunden; der letze in der Datenbank?
Es ist natürlich schön, wenn man nicht exact die Zeit treffen muss, das macht es etwas einfacher bei den häufigen Werten.
In meinem Fall ist der Wert jedoch 12 Stunden alt und ich hatte erwartet, dass dann die 1 als Default kommt, die ich der Funktion mitgegeben hatte.

Das sollte nochmal geklärt werden, oder ich muss es halt wieder als eigenes SQL abbilden, da ich ja nicht überblicken kann, wie es andere verwenden.

Gibt es eventuell eine Abfrage, die ich alternativ verwenden könnte?

VG Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

kobi1980

Grünlandtemperaturberechnung:

Moin

ich habe es jetzt soweit, dass die Grünladtemperatur ausgegeben wird.
Mit dem manuellen Befehl set Rep.Temp.greenland writetodb werden n verschiedene Readings geschrieben, die ich aber nicht auswerten kann.

Wie kann man das nun einstellen, dass der die Berechnung jeden Tag macht und für dieses Datum einen Wert ablegt?
Ziel ist es, das für jeden Tag die Grünladtemperatur in die Datenbank geschrieben werden soll, damit ich auch ein Plot daraus erstellen kann. Also die Entwicklung der Werte visualisieren.
Danke für die Unterstützung.

Gruß
Kobi

ch.eick

Zitat von: kobi1980 am 25 Februar 2021, 10:54:39
Wie kann man das nun einstellen, dass der die Berechnung jeden Tag macht und für dieses Datum einen Wert ablegt?
Ziel ist es, das für jeden Tag die Grünladtemperatur in die Datenbank geschrieben werden soll, damit ich auch ein Plot daraus erstellen kann. Also die Entwicklung der Werte visualisieren.
Über eine Timer das DbRep aufrufen :-)
Ich mag DOIF und verwende das für Scheduling Aufgaben, oder halt WeekdayTimer, oder was auch immer.

VG Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

kobi1980

Moin

Das mit dem DOIF macht schon Sinn :-)

Und wie bekomme ich das hin, dass diese Werte für nen Plot genutzt werden können ?

Die ermittelten Readings sehen ja so aus:
2021-02-16__WEEWX__Aussentemperatur__GrasslandTemperatureSum 1.8
2021-02-17__WEEWX__Aussentemperatur__GrasslandTemperatureSum 5.9
2021-02-18__WEEWX__Aussentemperatur__GrasslandTemperatureSum 11.5
2021-02-19__WEEWX__Aussentemperatur__GrasslandTemperatureSum 16.2

Es müsste doch jeden Tag solch ein Wert gespeichert werden, damit man auch einen Plot erstellen kann
Timestamp = DOIF Datum/Zeit
Reading = z.B. Gruenlandtemperatursumme


@Heiko warum wird die GrasslandTemperatureSum nicht richtig ermittelt?

READINGS:
     2021-02-25 11:46:35   2021-02-15__WEEWX__Aussentemperatur__AVGDMGWS__2021-02-15 -0.7
     2021-02-25 11:46:35   2021-02-15__WEEWX__Aussentemperatur__GrasslandTemperatureSum 0.0
     2021-02-25 11:46:35   2021-02-16__WEEWX__Aussentemperatur__AVGDMGWS__2021-02-16 2.3
     2021-02-25 11:46:35   2021-02-16__WEEWX__Aussentemperatur__GrasslandTemperatureSum 1.8
     2021-02-25 11:46:35   2021-02-17__WEEWX__Aussentemperatur__AVGDMGWS__2021-02-17 5.5
     2021-02-25 11:46:35   2021-02-17__WEEWX__Aussentemperatur__GrasslandTemperatureSum 5.9
     2021-02-25 11:46:35   2021-02-18__WEEWX__Aussentemperatur__AVGDMGWS__2021-02-18 7.5
     2021-02-25 11:46:35   2021-02-18__WEEWX__Aussentemperatur__GrasslandTemperatureSum 11.5
     2021-02-25 11:46:35   2021-02-19__WEEWX__Aussentemperatur__AVGDMGWS__2021-02-19 6.2
     2021-02-25 11:46:35   2021-02-19__WEEWX__Aussentemperatur__GrasslandTemperatureSum 16.2
     2021-02-25 11:46:35   2021-02-20__WEEWX__Aussentemperatur__AVGDMGWS__2021-02-20 8.6
     2021-02-25 11:46:35   2021-02-20__WEEWX__Aussentemperatur__GrasslandTemperatureSum 22.6
     2021-02-25 11:46:35   2021-02-21__WEEWX__Aussentemperatur__AVGDMGWS__2021-02-21 10.3
     2021-02-25 11:46:35   2021-02-21__WEEWX__Aussentemperatur__GrasslandTemperatureSum 30.3
     2021-02-25 11:46:35   2021-02-22__WEEWX__Aussentemperatur__AVGDMGWS__2021-02-22 10.4
     2021-02-25 11:46:35   2021-02-22__WEEWX__Aussentemperatur__GrasslandTemperatureSum 38.1
     2021-02-25 11:46:35   2021-02-23__WEEWX__Aussentemperatur__AVGDMGWS__2021-02-23 11.5
     2021-02-25 11:46:35   2021-02-23__WEEWX__Aussentemperatur__GrasslandTemperatureSum 46.8
     2021-02-25 11:46:35   2021-02-24__WEEWX__Aussentemperatur__AVGDMGWS__2021-02-24 13.5
     2021-02-25 11:46:35   2021-02-24__WEEWX__Aussentemperatur__GrasslandTemperatureSum 56.9
     2021-02-25 11:46:35   background_processing_time 0.5401
     2021-02-25 11:46:35   db_lines_processed 20
     2021-02-25 11:46:35   sql_processing_time 0.5175
     2021-02-25 11:46:35   state           done
Attributes:
   averageCalcForm avgDailyMeanGWSwithGTS
   devStateIcon connected:10px-kreis-gelb .*disconnect:10px-kreis-rot .*done:10px-kreis-gruen
   device     WEEWX
   fastStart  1
   reading    Aussentemperatur
   showproctime 1
   timestamp_begin previous_week_begin
   timestamp_end previous_day_end
   verbose    3



Gruß
Korbinian

ch.eick

Zitat von: kobi1980 am 25 Februar 2021, 10:54:39
Mit dem manuellen Befehl set Rep.Temp.greenland writetodb werden n verschiedene Readings geschrieben, die ich aber nicht auswerten kann.

writetodb schreibt die Werte doch in die Datenbank, dort wird jedoch ein neuer Name für READING verwendet.
Im Diagramm kannst Du dann diesen neuen Namen verwenden.

Um Dir alle readings anzuzeigen, die zuletzt geschrieben wurden habe ich mal ein SQL geschrieben, was Du unter sqlSpecial findest,
falls Du selber kein SQL kannst.

attr Rep.Temp.greenland device <Dein Device Name>
set Rep.Temp.greenland sqlSpecial recentReadingsOfDevice

Dort sollten dann auch die neuen readings zu erkennen sein.

EDIT: Sorry, ich habe jetzt erst das Bild angeschaut ;-)
     Man kann wohl auch den Basis Namen für die neuen readings überschreiben.   >>> Attribut readingNameMap
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

kobi1980

hmm.. klappt so leider nicht

readingNameMap GTS

alt:   2021-02-25 11:46:35   2021-02-24__WEEWX__Aussentemperatur__AVGDMGWS__2021-02-24 13.5
neu: 2021-02-25__GTS__2021-02-25


ch.eick

Zitat von: kobi1980 am 25 Februar 2021, 12:54:26
hmm.. klappt so leider nicht

readingNameMap GTS

alt:   2021-02-25 11:46:35   2021-02-24__WEEWX__Aussentemperatur__AVGDMGWS__2021-02-24 13.5
neu: 2021-02-25__GTS__2021-02-25
Beschreibe bitte mal, wo genau das Problem ist? Eventuell meldet sich dann noch jemand zu Wort :-)
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

DS_Starter

Hallo Korbinian,

gehen wir mal schrittweise vor ...

Zitat
@Heiko warum wird die GrasslandTemperatureSum nicht richtig ermittelt?
Wieso denkst du dass die GrasslandTemperatureSum nicht richtig ermittelt wird ?

Hinweis: Du musst timestamp_begin auf den Jahresanfang setzen (z.B. current_year_begin). Steht auch so in der Hilfe zum Attribut averageCalcForm = avgDailyMeanGWSwithGTS.

writeToDb kann in diesem Fall nicht verwendet weren, da es nur ein Zusatz zu avgDailyMeanGWS ist. Aber auch dafür gibt es eine Lösung. Aber das im zweiten Schritt.

Grüße,
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

kobi1980

Hi

bei mit wird die Grünlandtemperatursumme täglich immer nur größer und hat bei "0" angefangen:
Die beiden Start / Ende Attribute hatte ich gesetzt, habe es jetzt aber auf current_year_begin gestellt.


Zitat von: kobi1980 am 25 Februar 2021, 12:04:56
     2021-02-25 11:46:35   2021-02-15__WEEWX__Aussentemperatur__GrasslandTemperatureSum 0.0
     2021-02-25 11:46:35   2021-02-16__WEEWX__Aussentemperatur__GrasslandTemperatureSum 1.8
     2021-02-25 11:46:35   2021-02-17__WEEWX__Aussentemperatur__GrasslandTemperatureSum 5.9
     2021-02-25 11:46:35   2021-02-18__WEEWX__Aussentemperatur__GrasslandTemperatureSum 11.5
     2021-02-25 11:46:35   2021-02-19__WEEWX__Aussentemperatur__GrasslandTemperatureSum 16.2
     2021-02-25 11:46:35   2021-02-20__WEEWX__Aussentemperatur__GrasslandTemperatureSum 22.6
     2021-02-25 11:46:35   2021-02-21__WEEWX__Aussentemperatur__GrasslandTemperatureSum 30.3
     2021-02-25 11:46:35   2021-02-22__WEEWX__Aussentemperatur__GrasslandTemperatureSum 38.1
     2021-02-25 11:46:35   2021-02-23__WEEWX__Aussentemperatur__GrasslandTemperatureSum 46.8
     2021-02-25 11:46:35   2021-02-24__WEEWX__Aussentemperatur__GrasslandTemperatureSum 56.9

Attributes:
   averageCalcForm avgDailyMeanGWSwithGTS
   devStateIcon connected:10px-kreis-gelb .*disconnect:10px-kreis-rot .*done:10px-kreis-gruen
   device     WEEWX
   fastStart  1
   reading    Aussentemperatur
   showproctime 1
   timestamp_begin previous_week_begin
   timestamp_end previous_day_end
   verbose    3