Hauptmenü

neue svg-Funktion: card

Begonnen von Damian, 04 April 2021, 12:58:15

Vorheriges Thema - Nächstes Thema

Aeroschmelz

#360
Hallo Damian,

gibt es über die card Funktion die Möglichkeit sich den Verlauf eines Wertes z.B. in den letzten 6 Stunden als Balkendiagramm ohne Beschriftung der x- und y-Achse anzeigen zu lassen, d.h. die es werden immer nur 6 Balken angezeigt, 1 pro Jede stunde. In Excel gibt es eine Funktion dafür die Sparklines. Man sieht zwar keine genauen Werte, aber zumindest die Tendenz. Mit "colX" als Parameter kann ich auch die Periode < 1 Tag definieren, mit barX geht das scheinbar nicht? Ich habe dazu im WIKI leider nichts gefunden.


"Raumname"|"Helligkeit"|"Temperatur"|"Luftfeuchtigkeit"|"Batterie"
"Abstellkammer"|card([Schlafzimmer:luminosity:col1],undef,undef,0,undef,90,0,"lum",undef,"0","75,0,0,1,1,0,80")|
ring([Abstellkammer:temperature],15,30,220,0,"°C","120,1",undef,1)|
ring([Abstellkammer:humidity],30,70,undef,undef,'%',"120,1",[(30,240,40,180,45,140,50,120,55,75,70,0)],0,'0,0,1,10')|
icon_label("measure_battery_100\@".([Abstellkammer:batVoltage] < 2.0 ? "red":"green"),[Abstellkammer:batVoltage],([Abstellkammer:batVoltage] < 2.0 ? "red":"green"),"white",-10)


Man könnte sicherlich die Funktion cylinder_bars nehmen, aber da es sich um einen Sensor handelt, müsste man einen Mittelwert in einem bestimmten Zeitraum bilden und das macht die card Funktion ja bereits.

Danke im voraus.

Viele Grüsse
Marcus




Damian

Zitat von: Aeroschmelz am 06 März 2023, 10:08:15
Hallo Damian,

gibt es über die card Funktion die Möglichkeit sich den Verlauf eines Wertes z.B. in den letzten 6 Stunden als Balkendiagramm ohne Beschriftung der x- und y-Achse anzeigen zu lassen, d.h. die es werden immer nur 6 Balken angezeigt, 1 pro Jede stunde. In Excel gibt es eine Funktion dafür die Sparklines. Man sieht zwar keine genauen Werte, aber zumindest die Tendenz. Mit "colX" als Parameter kann ich auch die Periode < 1 Tag definieren, mit barX geht das scheinbar nicht? Ich habe dazu im WIKI leider nichts gefunden.


"Raumname"|"Helligkeit"|"Temperatur"|"Luftfeuchtigkeit"|"Batterie"
"Abstellkammer"|card([Schlafzimmer:luminosity:col1],undef,undef,0,undef,90,0,"lum",undef,"0","75,0,0,1,1,0,80")|
ring([Abstellkammer:temperature],15,30,220,0,"°C","120,1",undef,1)|
ring([Abstellkammer:humidity],30,70,undef,undef,'%',"120,1",[(30,240,40,180,45,140,50,120,55,75,70,0)],0,'0,0,1,10')|
icon_label("measure_battery_100\@".([Abstellkammer:batVoltage] < 2.0 ? "red":"green"),[Abstellkammer:batVoltage],([Abstellkammer:batVoltage] < 2.0 ? "red":"green"),"white",-10)


Man könnte sicherlich die Funktion cylinder_bars nehmen, aber da es sich um einen Sensor handelt, müsste man einen Mittelwert in einem bestimmten Zeitraum bilden und das macht die card Funktion ja bereits.

Danke im voraus.

Viele Grüsse
Marcus

Der bar-Datentyp kann z. Zt. nur eine ganze Periode darstellen (Tag, Woche, Monat, Jahr, Decade). Eine Anzeige der letzten X-Werte ist z. Zt. nicht möglich, da muss man auf col ausweichen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

hajo23

Hi, ich habe Card genutzt, um die Temperatur-forecast-Werte aus dem Weather-Modul anzuzeigen. Getriggert wird DOIF durch Weather. Die Daten werden dann per Perl in DOIF in zwei Strings (Höchst/Tiefsttemperaturen) geladen, die ich dann mit set_card_data in DOIF_Readings lade. Soweit funktioniert es. Für die Card musste ich aber die Daten per Offset um 7 Tage zurückverlegen damit die Zeitachse wieder passt, bzw. lädt sonst set_card_data die Daten nicht. Geht das irgendwie auch ohne Offset?

VG
Hajo

Damian

Zitat von: hajo23 am 07 März 2023, 14:30:38
Hi, ich habe Card genutzt, um die Temperatur-forecast-Werte aus dem Weather-Modul anzuzeigen. Getriggert wird DOIF durch Weather. Die Daten werden dann per Perl in DOIF in zwei Strings (Höchst/Tiefsttemperaturen) geladen, die ich dann mit set_card_data in DOIF_Readings lade. Soweit funktioniert es. Für die Card musste ich aber die Daten per Offset um 7 Tage zurückverlegen damit die Zeitachse wieder passt, bzw. lädt sonst set_card_data die Daten nicht. Geht das irgendwie auch ohne Offset?

VG
Hajo

Mit set werden vorherige Daten gelöscht, daher verstehe ich die Vorgehensweise nicht. Wenn die anderen Werte im Diagramm erhalten bleiben sollen, dann musst du die modify-Funktion nutzen. Das Problem mit dem Offset musst du mit konkreten Daten zum Nachvollziehen belegen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

hajo23

#364
Zitat von: Damian am 07 März 2023, 15:14:50
Mit set werden vorherige Daten gelöscht, daher verstehe ich die Vorgehensweise nicht. Wenn die anderen Werte im Diagramm erhalten bleiben sollen, dann musst du die modify-Funktion nutzen. Das Problem mit dem Offset musst du mit konkreten Daten zum Nachvollziehen belegen.

Das Speichern oder Sammeln der forecast-Daten macht keinen Sinn, weil die Daten nach dem nächsten Update (für die folgenden 7 Tage) völlig anders sein können. Deshalb werden die alten Daten beim Triggern durch die neuen ersetzt. Da es sich aber um eine Vorhersage handelt, liegt der Zeitstempel in der "Zukunft" und damit scheint set_card_data nicht umgehen zu können. Als Workaround nutze ich nun offset um die Zeitstempel um eine Woche in die Vergangenheit zu legen.

Die verwendeten Daten:
2023.03.07 19:02:31 3: 2023-03-07_16:36 4,2023-03-08_16:26 5,2023-03-09_15:40 7,2023-03-10_15:27 7,2023-03-11_13:19 6,2023-03-12_13:02 6,2023-03-13_14:41 13, 2023-03-08_04:59 -1,2023-03-09_06:54 -1,2023-03-09_23:44 3,2023-03-11_05:55 1,2023-03-12_06:11 -2,2023-03-12_19:00 4,2023-03-14_07:00 6

Damian

#365
Zitat von: hajo23 am 07 März 2023, 18:41:13
Das Speichern oder Sammeln der forecast-Daten macht keinen Sinn, weil die Daten nach dem nächsten Update (für die folgenden 7 Tage) völlig anders sein können. Deshalb werden die alten Daten beim Triggern durch die neuen ersetzt. Da es sich aber um eine Vorhersage handelt, liegt der Zeitstempel in der "Zukunft" und damit scheint set_card_data nicht umgehen zu können. Als Workaround nutze ich nun offset um die Zeitstempel um eine Woche in die Vergangenheit zu legen.

OK. Die Idee ist ja fortlaufende Daten per Event abhängig der Zeit zu visualisieren. Daher wird die Zukunft nicht abgebildet. Daten in der Zukunft können also nur über negative Offsetverschiebung in die Vergangenheit verschoben werden. Sie werden dann in der aktuellen Zeitperiode oder in der Vergangenheit dargestellt. Das Ausblenden der X-Achsenbeschriftung ist nicht vorgesehen.

Alternativ kannst du cylinder bars verwenden:
https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg#Balkendarstellung_mehrerer_Zahlenwerte_mit_Hilfe_der_universellen_SVG-Funktion_cylinder_bars

Dann muss du dich selbst zum die Wertebeschriftung kümmern und die Werte den einzelnen Säulen zuordnen.

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Tobias

HI Damian,

ich versuche das Beispiel aus dem Wiki, card data ändern umzusetzen, bekomme aber einen Fehler:

{DOIF_modify_card_data('DOIF_counter_new','PM_Solardach','PM_Solardach.Consumption.year','bar1decade',-300,'2023.01.01_00:10 2959.067,2023.03.27_00:01 330')}
Can't use string ("") as a HASH ref while "strict refs" in use at ./FHEM/98_DOIF.pm line 1489.
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Damian

#367
Im Device DOIF_counter_new gibt es die Definition nicht: [PM_Solardach:PM_Solardach.Consumption.year:bar1decade]

Edit: Wahrscheinlich aber: [DOIF_counter_new:PM_Solardach.Consumption.year:bar1decade]
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Tobias

Danke, hab es verstanden und sofort hat es funktioniert.

Ich habe meinen Counter mit den Card´s neu aufgesetzt. Dummerweise fängt aber mein Counter für die Monats- und Jahreszähler bei 0 an zu zählen und ich bekomme es nicht hin einen Aufsatzpunkt vorzugeben.
Zb. einfach das Reading überschreiben bringt leider nichts:
setreading DOIF_counter_new PM_Solardach.Consumption.year 333
Hast du eine Idee wie ich das anstellen könnte?
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Damian

#369
Zitat von: Tobias am 27 März 2023, 11:52:09Danke, hab es verstanden und sofort hat es funktioniert.

Ich habe meinen Counter mit den Card´s neu aufgesetzt. Dummerweise fängt aber mein Counter für die Monats- und Jahreszähler bei 0 an zu zählen und ich bekomme es nicht hin einen Aufsatzpunkt vorzugeben.
Zb. einfach das Reading überschreiben bringt leider nichts:
setreading DOIF_counter_new PM_Solardach.Consumption.year 333
Hast du eine Idee wie ich das anstellen könnte?


In dieser Routine wird u. a. der Jahresverbrauch berechnet:

sub midnight { ## Diese Funktion wird um Mitternacht ausgeführt
  my ($device,$reading,$mday,$yday)=@_;
  set_Reading("$device.$reading.day_counter",ReadingsVal($device, $reading,1));  
  set_Reading("$device.$reading.last_day",get_Reading("$device.$reading.day",0),1);
  set_Reading("$device.$reading.day",0,1);
  set_Reading ("$device.$reading.month",int((ReadingsVal($device, $reading,0)-(get_Reading("$device.$reading.month_counter",0)))*1000)/1000,1);
  set_Reading ("$device.$reading.year",int((ReadingsVal($device, $reading,0)-(get_Reading("$device.$reading.year_counter",0)))*1000)/1000,1);

  if ($mday == 1) {
    set_Reading("$device.$reading.month_counter",ReadingsVal($device, $reading,0));
    set_Reading("$device.$reading.last_month",get_Reading("$device.$reading.month",0),1);
    set_Reading("$device.$reading.month",0,1);
    if ($yday == 0) {
      set_Reading("$device.$reading.year_counter",ReadingsVal($device, $reading,0));
      set_Reading("$device.$reading.last_year",get_Reading("$device.$reading.year",0),1);
      set_Reading("$device.$reading.year",0,1);
    }
  }
}

Du müsstest beim Berechnen des Jahresverbrauchs den letzten Monat drauf addieren:

statt:

set_Reading ("$device.$reading.year",int((ReadingsVal($device, $reading,0)-(get_Reading("$device.$reading.year_counter",0)))*1000)/1000,1);
if ($mday == 1) {
   set_Reading ("$device.$reading.year",int((get_Reading($device.$reading.last_month)+get_Reading("$device.$reading.year",0))*1000)/1000,1);


Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Tobias

#370
HI Damian,
bei mir ist ja alles 0, bzw wurde heute von 0 angefangen zu zählen. Dementsprechend ist last_month/year = 0 und der aktuelle monat und Jahr identisch bei dem aktuellen Tageswert.

Ich würde gerne mit einem Befehl einmalig(!) und manuell gerne die Werte korrigieren. Also einen offset vorgeben,

Bei jedem Event wird das Jahres-Reading ebenfalls aktualisiert und hochgezählt. Ändere ich das Reading manuell, wird es beim nächsten Event wieder überschrieben...

Edit: Ich häng dir mal ein scrrenshot an, oben an den Halbringen siehst du das es heute bzw gestern bei 0 anfing. Monat und Jahr
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Damian

Die ganze Berechnung geht von einem fortlaufenden Zähler aus, der immer weiter zählt. Bei dir funktioniert dann die tägliche Berechnung aufgrund der Zählerstände nicht.

Deswegen muss du die tägliche Berechnung des year-Readings und des month rausnehmen:

  set_Reading ("$device.$reading.month",int((ReadingsVal($device, $reading,0)-(get_Reading("$device.$reading.month_counter",0)))*1000)/1000,1);
  set_Reading ("$device.$reading.year",int((ReadingsVal($device, $reading,0)-(get_Reading("$device.$reading.year_counter",0)))*1000)/1000,1);

dann kannst du das year-Reading manuell setzen und wie vorgeschlagen am Monatsende hochzählen lassen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Tobias

#372
danke für die Hinweise, zwischenzeitlich hatte ich mal weiter herumprobiert:

setreading DOIF_counter PM_Solardach.Consumption.year_counter <year - ZielWert>
also in meinem Fall:
setreading DOIF_counter PM_Solardach.Consumption.year_counter 2959
Damit konnte ich zumindest den aktuellen Wert anpassen. Ich hoffe ich habe damit nichts anderes kaputt gemacht ;)
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Damian

ja, aber wenn dein Zähler am Monatsende auf Null gesetzt wird (es sei denn wir reden von mehreren Zählern), dann wird es nicht funktionieren, weil bei allen Berechnungen Differenzen von absoluten Zählerständen gebildet werden. Das hat den Vorteil, dass auch wenn FHEM zwischendurch offline ist und etwas nicht mitbekommt, die Verbräuche am Ende des Tages stimmten, solange der Zähler selbst weiter zählt.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Tobias

Hi Damian,

eine neue Frage: die in einer Card, die Bars, möchte ich ich dynamisch nach oben, aber fix bei 0 setzen.
In der Card definition, bei den Properties -> # <y-scaling>: "fixedscaling" (1), "autoscaling" (undef)

Setze ich autoscaling, ist für den kleinesten Wert keine Bar zu sehen weil der unterste Wert der kleinste Wert ist.
Setze ich fixedscaling, fängt zwar die y-Achse bei 0 an, aber der obere Wert ist auch fix.

siehe fotos. Was ich gerne möchte ist, das die y-achse bei 0 anfängt, aber bei oben im autoscaling arbeitet. Geht das irgendwie?
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter