Chart widget feature vorhanden?

Begonnen von Eisix, 28 Januar 2020, 10:13:50

Vorheriges Thema - Nächstes Thema

Eisix

Hallo eki,

irrelevant ist hier der falsche Ausdruck. Für die Berechnung der Kurven sind die X-Werte natürlich relevant. Ich hatte das auf einen Punkt auf der X-Achse bezogen an dem die Werte in Y-addiert werden. Denke du bist da Mathematisch weit besser in dem ganzen drin als ich.

Hab noch zwei screenshots angehängt die das ganze zeigen.

Gruß
Eisix

eki

Könntest Du mir noch ein Stück Logfile und die dazugehörige Chart Definition posten (ich weiß, es sollte gleich wie vorher sein, aber der Teufel steckt bekanntlich im Detail). Kann schon sein, dass da noch was schief ist, das mit dem Stapeln ist ein bisschen "tricky", weil die verschiedenen Kurven ja nicht die gleichen Punkte auf der Zeitachse haben.

Eisix

Hallo eki,

hier der aktuelle HTML-Code den ich nutze. Angehängt ein Log von einem Tag.

<div data-type="chart"
      data-device="Schalter_Server"
data-logdevice='["logdb"]'
                                        data-logfile='["history"]'
                                        data-columnspec='["Luefter:PowerUSED_Licht:::","Schalter_Server:PowerUSED_Licht:::","Schalter_PC_L:PowerUSED_Licht:::","Aquarium_T:PowerUSED_Licht:::","Schalter_Aquarium_L:PowerUSED_Licht:::","Schalter_TV:PowerUSED_Licht:::","Schalter_Receiver:PowerUSED_Licht:::","Schalter_Aquarium_A:PowerUSED_Licht:::","Heizung_VR_1:PowerUSED_Licht:::","Schalter_Waschmaschine:PowerUSED_Licht:::","Schalter_Trockner:PowerUSED_Licht:::","Schalter_Gefrierschrank_VR:PowerUSED_Licht:::","Schalter_Gefrierschrank_KG:PowerUSED_Licht:::","Schalter_Kuehlschrank_Kueche:PowerUSED_Licht:::","Schalter_Kaffemaschine:PowerUSED_Licht:::","Schalter_PS4_A:PowerUSED_Licht:::","Schalter_TV_A:PowerUSED_Licht:::","Stromzaehler:PowerUSED_Licht:::"]'
                                        data-style='["ftui l6fill","ftui l3fill","ftui l1fill","ftui l9fill","ftui l7fill","ftui l4fill","ftui l0fill","ftui l5fill","ftui l1fill","ftui l2fill","ftui l6fill","ftui l3fill","ftui l9fill","ftui l7fill","ftui l4fill","ftui l2fill","ftui l6fill","ftui l10"]'
                                        data-ptype='["lines","lines:0","lines:1","lines:2","lines:3","lines:4","lines:5","lines:6","lines:7","lines:8","lines:9","lines:10","lines:11","lines:12","lines:13","lines:14","lines:15","lines"]'
                                        data-uaxis='["primary"]'
                                        data-legend='["Lüfter","Server","PC L","Aquarium T","Aquarium L","TV","Receiver","Aquarium A","Heizung_VR","Waschmaschine","Trockner","Gefrierschrank_VR","Gefrierschrank KG","Kuehlschrank","Kaffemaschine","PS4 A","TV A","Lichtstrom"]'
        data-legend_stacking="true"
    data-yunit="W"
        data-minvalue="0"
        data-maxvalue="auto"
        data-yunit_sec=""
        data-minvalue_sec="auto"
        data-maxvalue_sec="auto"
        data-height="350"
        data-width="700"
data-nofulldays="true"
data-daysago_start="6h"
data-daysago_end="now"
        data-crosshair="true"
        data-cursorgroup="1"
        data-scrollgroup="1"
        data-showlegend="false"
        data-yticks="auto"
        data-xticks="auto"
class="bottom"
></div>


Gruß
Eisix

eki

Ich habe eine Version gebaut (angehängt), die versucht das Problem zu umgehen. Ist ein relativ einfacher Ansatz, der mit der Interpolation der darunter liegenden Kurve arbeitet. Dadurch ist der "Verschiebeeffekt" weg, allerdings liegen die Kurven dadurch nicht mehr perfekt übereinander. Schau's Dir mal an und melde Dich.

Eisix

Hallo eki,

danke für die Umsetzung.
Sieht jetzt auf jeden Fall viel besser aus.
Die Version scheint aber ein Problem mit nicht gestapelten Linien zu haben die aus logdb kommen.  Filelog und lp funktionieren und werden angezeigt.

Gruß
Eisix

eki

#20
Bist Du sicher, dass das logdb Thema mit dieser Version reingekommen ist? Bitte schick mal Deine Definition. Und ein list Deiner Logdb.

Eisix

Ja, bin sicher, kann zwischen dem Verhalten durch tauschen des widgets hin und her schalten. Meine vorherige Version ist allerdings die von hier aus dem Thread mit dem refresh der Linien beim ausblenden. Eventuell bist du bei der Version von heute von einer anderen gestartet.

diff widget_chart.js.bak widget_chart.js.neu

5c5
< /* Version 2.8.1
---
> /* Version 2.10.0
1429c1429
< if (!data.nofulldays) ddiff = parseInt(ddiff);
---
> if (!data.nofulldays) ddiff = parseInt(ddiff+(ddiff<0?-0.5:0.5));
1546c1546
< roundXticks: function(round_in, x, xrange, startdate) { // helper function to support correct xtick positions (rounded time values)
---
> roundXticks: function(round_in, x, xrange, startdate, asize) { // helper function to support correct xtick positions (rounded time values)
1580,1581c1580,1585
< var xstart = startdate.getMinutes()+startdate.getHours()*60+startdate.getDay()*60*24; // correction needed to be sure that hours inside full day are skipped
< xret = parseInt(x/60/24/7+0.5)*60*24*7-xstart; // correct xret to number of minutes to closest first day of week since start date/time
---
> if (asize == 7) {
> var xstart = startdate.getMinutes()+startdate.getHours()*60+startdate.getDay()*60*24; // correction needed to be sure that hours inside full day are skipped
> } else if (asize == 3.5) {
> var xstart = startdate.getMinutes()+startdate.getHours()*60+startdate.getDay()/2*60*24; // correction needed to be sure that hours inside full day are skipped
> }
> xret = parseInt(x/60/24/asize+0.5)*60*24*asize-xstart; // correct xret to number of minutes to closest first day of week since start date/time
1585,1586c1589,1590
< if (actdate.getDate()<actdate.getDaysInMonth()/2) actdate.setTime(actdate.getTime()-actdate.getDate()*24*60*60*1000); // be sure to search for closest 1st of month
< var startmonth = (startdate.getDate()<startdate.getDaysInMonth()/2)?startdate.getMonth():startdate.getMonth()+1;
---
> if (actdate.getDate()<actdate.myGetDaysInMonth()/2) actdate.setTime(actdate.getTime()-actdate.getDate()*24*60*60*1000); // be sure to search for closest 1st of month
> var startmonth = (startdate.getDate()<startdate.myGetDaysInMonth()/2)?startdate.getMonth():startdate.getMonth()+1;
1588c1592
< xret = parseInt(x/60/24/mdays+0.5)*60*24*(mdays+1)-xstart; // correct xret to number of minutes to closest first day of month since start date/time
---
> xret = parseInt(x/60/24/mdays+0.5)*60*24*(mdays)-xstart; // correct xret to number of minutes to closest first day of month since start date/time
1641a1646,1652
> } else if (mode==3) { // x-axis clip path, keep a bit of non clipped space on the right and left side.
> var y0 = 0;
> var y1 = 1000000;
> var y2 = 1000000;
> var y3 = 0;
> x0 -= (data.graphArea.left-data.chartArea.left);
> x1 += ((data.chartArea.left+data.chartArea.width)-(data.graphArea.left+data.graphArea.width));
1691c1702
< diff =  time.getDaysInMonth()*24*60/2;
---
> diff =  time.myGetDaysInMonth()*24*60/2;
1736a1748,1798
> zoomTime: function(event) {
> var elem = $(event.delegateTarget);
> var baseobject = elem.closest("[class^=basesvg]").parent();
> var data = baseobject.data();
> var xleft = elem.data('xleft');
> var xright = elem.data('xright');
>
> if (!xleft.getDate) return;
> if (!xright.getDate) return;
>
> data.daysago_start_old = data.daysago_start;
> data.daysago_start = xleft.getDateStringFHEM();
>
> data.daysago_end_old = data.daysago_end;
> data.daysago_end = xright.getDateStringFHEM();
>
> baseobject.data(data);
>
> widget_chart.zoomTimeAnimated(baseobject,0,50);
>
> return;
> },
> zoomTimeAnimated: function(elem,index,steps) {
> var data = elem.data();
> data.offsetX = 0; // offset for shifting arbitrarily due to mousemove and touchmove handling
> data.scaleX = 1; // scale for scaling arbitrarily due to mousemove and touchmove handling
> data.scaleDeltaX = 0; // scale for scaling arbitrarily due to mousemove and touchmove handling
>
> var days_start_old = widget_chart.getDaysAgo(data.daysago_start_old,data);
> var days_start = widget_chart.getDaysAgo(data.daysago_start,data);
> var days_end_old = widget_chart.getDaysAgo(data.daysago_end_old,data);
> var days_end = widget_chart.getDaysAgo(data.daysago_end,data);
>
>
> setTimeout(function() {
> if (index <= steps) {
> var ds = days_start_old*(steps-index)/steps+days_start*index/steps;
> var de = days_end_old*(steps-index)/steps+days_end*index/steps;
> var scl = (days_end_old - days_start_old)/(de - ds);
> var dlt = -(days_start_old-ds)*scl*24*60; // new delta in minutes
> dlt = dlt/data.xrange*data.basewidth*data.graphWidth/100-data.getGraphLeft()*(scl-1); // new delta in pixels
>
> widget_chart.shiftXContent(elem,data.offsetX,scl,dlt,data)
> index++;
> widget_chart.zoomTimeAnimated(elem,index,steps);
> } else {
> widget_chart.refresh(elem,'start reset',0);
> }
> },1);
>
> },
2280c2342
< if (width >= tstart.getDaysInMonth()) { // difference is bigger than current month care for correct treatment
---
> if (width >= tstart.myGetDaysInMonth()) { // difference is bigger than current month care for correct treatment
2283,2286c2345,2348
< var dds = (mdiff*offset-md)*tstart.getDaysInMonth();
< var dde = (mdiff*offset-md)*tend.getDaysInMonth();
< var dateS = (tstart.getDate()==tstart.getDaysInMonth())?new Date(tstart.getFullYear(),tstart.getMonth()-md,1,0,0,0,0).getDaysInMonth():tstart.getDate();
< var dateE = (tend.getDate()==tend.getDaysInMonth())?new Date(tend.getFullYear(),tend.getMonth()-md,1,0,0,0,0).getDaysInMonth():tend.getDate();
---
> var dds = (mdiff*offset-md)*tstart.myGetDaysInMonth();
> var dde = (mdiff*offset-md)*tend.myGetDaysInMonth();
> var dateS = (tstart.getDate()==tstart.myGetDaysInMonth())?new Date(tstart.getFullYear(),tstart.getMonth()-md,1,0,0,0,0).myGetDaysInMonth():tstart.getDate();
> var dateE = (tend.getDate()==tend.myGetDaysInMonth())?new Date(tend.getFullYear(),tend.getMonth()-md,1,0,0,0,0).myGetDaysInMonth():tend.getDate();
2952c3014
< var logfile = widget_chart.getArrayValue(data.logfile,k,'-');
---
> var logfile = widget_chart.getArrayValue(data.logfile,k,'CURRENT');
3409a3472,3479
> var interpolate = function(leftx,lefty,rightx,righty,x) {
> var ret = 0;
> if (leftx!=undefined && lefty!=undefined && rightx!=undefined && righty!=undefined && x!=undefined) {
> ret = lefty + (x-leftx)/(rightx-leftx)*(righty-lefty);
> }
> return ret;
> }
>
3417c3487,3491
< points[i1][1] += pointsarray[iv][i2-1][1]; // add value of underlying graph to acutal value
---
> points[i1][1] += interpolate( pointsarray[iv][i2-1][0],
> pointsarray[iv][i2-1][1],
> pointsarray[iv][i2][0],
> pointsarray[iv][i2][1],
> points[i1][0]); // add value of underlying graph to acutal value
3424,3431c3498,3505
< points[points.length] = [];
< points[points.length-1][0] = points[points.length-2][0];
< points[points.length-1][1] = -Infinity;
< points[points.length] = [];
< points[points.length-1][0] = pointsarray[iv][orig_PA_lengths[iv]-1][0];
< points[points.length-1][1] = -Infinity;
< for (var i2=orig_PA_lengths[iv]-1, i2l=0; i2>=i2l; i2--) { // add underlying graph as lower bound of new graph
< points[points.length] = pointsarray[iv][i2].clone();
---
> points[points.length] = [];
> points[points.length-1][0] = points[points.length-2]?points[points.length-2][0]:0;
> points[points.length-1][1] = -Infinity;
> points[points.length] = [];
> points[points.length-1][0] = pointsarray[iv][orig_PA_lengths[iv]-1]?pointsarray[iv][orig_PA_lengths[iv]-1][0]:0;
> points[points.length-1][1] = -Infinity;
> for (var i2=orig_PA_lengths[iv]-1, i2l=0; i2>=i2l; i2--) { // add underlying graph as lower bound of new graph
> points[points.length] = pointsarray[iv][i2].clone();
3686a3761
> var dst = 0;
3693c3768
< } else if (ddiff<=data.tstart.getDaysInMonth()) { // check if we have less than one month between ticks
---
> } else if (ddiff<=data.tstart.myGetDaysInMonth()) { // check if we have less than one month between ticks
3721a3797,3798
> var dateTemp = new Date(data.tstart.getFullYear(),9,1);
> dst = dateTemp.dst()/60/24;
3724c3801
< xticksArray = [31,28+lF,31,30,31,30,31,31,30,31,30,31]; // set array for months
---
> xticksArray = [31,28+lF,31-dst,30,31,30,31,31,30,31+dst,30,31]; // set array for months
3728c3805
< xticksArray = [31+28+lF,31+30,31+30,31+31,30+31,30+31]; // set array for months
---
> xticksArray = [31+28+lF,31-dst+30,31+30,31+31,30+31+dst,30+31]; // set array for months
3732c3809
< xticksArray = [31+28+lF+31+30,31+30+31+31,30+31+30+31]; // set array for months
---
> xticksArray = [31+28+lF+31-dst+30,31+30+31+31,30+31+dst+30+31]; // set array for months
3766c3843
< '<linearGradient id="gr_8" x1="0%" y1="0%" x2="0%" y2="100%">    <stop offset="0%"   style="stop-color:#000; stop-opacity:.6"/>    <stop offset="100%" style="stop-color:;#ccc; stop-opacity:.4"/>  </linearGradient>'+
---
> '<linearGradient id="gr_8" x1="0%" y1="0%" x2="0%" y2="100%">    <stop offset="0%"   style="stop-color:#000; stop-opacity:.6"/>    <stop offset="100%" style="stop-color:#ccc; stop-opacity:.4"/>  </linearGradient>'+
3768d3844
< '<linearGradient id="gr_10" x1="0%" y1="0%" x2="0%" y2="100%">    <stop offset="0%"   style="stop-color:#000; stop-opacity:.6"/>    <stop offset="100%" style="stop-color:#ccc; stop-opacity:.4"/>  </linearGradient>'+
3822,3825d3897
< '<linearGradient id="gr_ftui10" x1="0%" y1="0%" x2="0%" y2="100%">'+
< '<stop offset="0%"  style="stop-color:#ff99bb; stop-opacity:1"/>'+
< '<stop offset="100%"   style="stop-color:#ff0055; stop-opacity:1"/>'+
< '</linearGradient>'+
3868a3941
> '<defs><clipPath id="clipingRectXAxis'+instance+'">'+widget_chart.getClipPath(data,0,theObj,3)+widget_chart.getClipPath(data,0,theObj,3)+'</clipPath></defs>'+
4222c4295
< if (!cxaxis) {cxaxis = widget_chart.createElem('g').attr({'style':'clip-path: url(#clipingRect'+data.instance+');'});}
---
> if (!cxaxis) {cxaxis = widget_chart.createElem('g').attr({'style':'clip-path: url(#clipingRectXAxis'+data.instance+');'});}
4581a4655
> var xlast = new Date(tstart);
4587,4593c4661,4668
< if (data.xticks_round !== '') x = widget_chart.roundXticks(data.xticks_round,x,data.xrange,tstart);
< if (!cachetype && (x>=data.xrange || x<=0)) continue; // we have to care that nothing is written beyond end of chart
< if (cachetype && (x>data.xrange+xticks || x<0)) continue; // we have to care that nothing is written beyond end of chart
<
< tx.setMinutes(tstart.getMinutes() + x);
< xtext_offset = widget_chart.getXTOffset(x,xold,tx,timeformat,data.xtext_offset);
< xold = x;
---
> var xc = x;
> if (data.xticks_round !== '' && !$.isArray(xticksArray)) xc = widget_chart.roundXticks(data.xticks_round,x,data.xrange,tstart,((data.basewidth>200)?3.5:7));
> if (!cachetype && (xc>=data.xrange || xc<=0)) continue; // we have to care that nothing is written beyond end of chart
> if (cachetype && (xc>data.xrange+xticks || xc<0)) continue; // we have to care that nothing is written beyond end of chart
>
> tx.setTime(tstart.getTime() + xc*60*1000);
> xtext_offset = widget_chart.getXTOffset(xc,xold,tx,timeformat,data.xtext_offset);
> xold = xc;
4595c4670
< posX = data.graphWidth*(x+(xtext_offset))/data.xrange*data.basewidth/100 + data.getGraphLeft();
---
> posX = data.graphWidth*(xc+(xtext_offset))/data.xrange*data.basewidth/100 + data.getGraphLeft();
4618c4693,4697
< if (!cachetype || (cachetype && ((x>0) && (x<data.xrange))))txaxis.append(textX2);
---
> if (!cachetype || (cachetype && ((xc>0) && (xc<data.xrange))))txaxis.append(textX2);
> textX2.data('xleft',xlast)
> textX2.data('xright',tx);
> xlast = tx;
> textX2.click(function(evt) {widget_chart.zoomTime(evt);});
4621,4622c4700,4701
< p1 = data.transD2W([x,min],uaxis);
< p2 = data.transD2W([x,max],uaxis);
---
> p1 = data.transD2W([xc,min],uaxis);
> p2 = data.transD2W([xc,max],uaxis);
4634,4635c4713,4714
< p1 = widget_chart.getTransformedPoint(data,theObj,{x:data.graphWidth/100*data.basewidth*x/data.xrange,y:data.graphHeight/100*data.baseheight,z:0});
< p2 = widget_chart.getTransformedPoint(data,theObj,{x:data.graphWidth/100*data.basewidth*x/data.xrange,y:data.graphHeight/100*data.baseheight,z:data.DDD.BackplaneZ(data.DDD,data.nGraphs)});
---
> p1 = widget_chart.getTransformedPoint(data,theObj,{xc:data.graphWidth/100*data.basewidth*xc/data.xrange,y:data.graphHeight/100*data.baseheight,z:0});
> p2 = widget_chart.getTransformedPoint(data,theObj,{xc:data.graphWidth/100*data.basewidth*xc/data.xrange,y:data.graphHeight/100*data.baseheight,z:data.DDD.BackplaneZ(data.DDD,data.nGraphs)});
4647c4726
< xtext_offset = widget_chart.getXTOffset(x,xold,data.tend,timeformat,data.xtext_offset);
---
> xtext_offset = widget_chart.getXTOffset(xc,xold,data.tend,timeformat,data.xtext_offset);
4649c4728
< posX = data.graphWidth*(data.xrange+(xtext_offset))/data.xrange*data.basewidth/100 + data.getGraphLeft()
---
> posX = data.graphWidth*((data.xrange+(xtext_offset))/data.xrange)*data.basewidth/100 + data.getGraphLeft()
4969a5049
> container.find("[id=clipingRectXAxis"+data.instance+"]").attr('id','clipingRectXAxis-'+cachetype+data.instance);
5242c5322
< Date.prototype.getDaysInMonth = function(inmonth) {
---
> Date.prototype.myGetDaysInMonth = function(inmonth) {
5246a5327,5329
> Date.prototype.getDateStringFHEM = function() {
> return this.getFullYear()+'-'+(this.getMonth()+1).pad()+'-'+this.getDate().pad()+'T'+this.getHours().pad()+':'+this.getMinutes().pad()+':'+this.getSeconds().pad();
> };
5252c5335
< ret+=this.getDaysInMonth(i);
---
> ret+=this.myGetDaysInMonth(i);


Chart das mit der neuen Version nicht angezeigt wird

<div data-type="chart"
        data-logdevice='["logdb","logdb","logdb"]'
        data-columnspec='["InternetSpeed:ping:::","InternetSpeed:upload:::","InternetSpeed:download:::"]'
        data-style='["ftui l3","ftui l6fill","ftui l4fill"]'
        data-ptype='["lines","lines","lines"]'
        data-uaxis='["secondary","primary","primary"]'
        data-legend='["ping","upload","download"]'
        data-yunit="Mbit"
        data-minvalue="auto"
        data-maxvalue="auto"
        data-yunit_sec="ms"
        data-minvalue_sec="auto"
        data-maxvalue_sec="auto"
        data-height="150"
        data-width="350"
        data-daysago_start="1"
        data-daysago_end="-1"
        data-crosshair="true"
        data-cursorgroup="1"
        data-scrollgroup="1"
        data-showlegend="false"
        data-yticks="auto"
        data-xticks="auto">
</div>



list logdb


Internals:
   COLUMNS    field length used for Device: 64, Type: 64, Event: 512, Reading: 64, Value: 128, Unit: 32
   CONFIGURATION ./contrib/dblog/db.conf
   DEF        ./contrib/dblog/db.conf (Schalter_.*|EinschaltTemp_.*|Heizung_.*|Sensor_.*|sysmon|Rauchmelder_.*|Garage_.*|InternetSpeed|Terrassentuer_WZ|Aquarium_.*|EinschaltTemp1|Steckerleiste_AQ|EnO_4BS_019C4E20|Schildis_.*|myHOMEMODE|Wetter|Luefter|Stromzaehler|Lichtstrom_Verbrauch):(state|PowerUSED_Licht|PowerUSED_WP|PowerUSED_LS|temperature|CleanTemp|humidity|Zaehlerstand_.*|download|ping|upload|stufe).*
   FUUID      5e0cc30f-f33f-9eb9-0eb4-cd0d4e763f6da65c
   FVERSION   93_DbLog.pm:v4.9.11-s21483/2020-03-22
   MODE       asynchronous
   MODEL      MYSQL
   NAME       logdb
   NR         518
   NTFY_ORDER 50-logdb
   PID        2313
   REGEXP     (Schalter_.*|EinschaltTemp_.*|Heizung_.*|Sensor_.*|sysmon|Rauchmelder_.*|Garage_.*|InternetSpeed|Terrassentuer_WZ|Aquarium_.*|EinschaltTemp1|Steckerleiste_AQ|EnO_4BS_019C3420|Schildis_.*|myHOMEMODE|Wetter|Luefter|Stromzaehler|Lichtstrom_Verbrauch):(state|PowerUSED_Licht|PowerUSED_WP|PowerUSED_LS|temperature|CleanTemp|humidity|Zaehlerstand_.*|download|ping|upload|stufe).*
   STATE      connected
   TYPE       DbLog
   UTF8       1
   dbconn     mysql:database=fhem;host=10.10.10.1;port=3306
   dbuser     fhemuser
   HELPER:
     COLSET     1
     DEVICECOL  64
     EVENTCOL   512
     OLDSTATE   connected
     PACKAGE    main
     READINGCOL 64
     TC         current
     TH         history
     TYPECOL    64
     UNITCOL    32
     VALUECOL   128
     VERSION    4.9.11
   READINGS:
     2020-04-15 13:06:06   CacheUsage      1
     2020-04-15 13:06:02   NextSync        2020-04-15 13:06:32 or if CacheUsage 500 reached
     2020-04-15 13:06:02   background_processing_time 0.1312
     2020-03-17 22:43:20   countCurrent    0
     2020-03-17 22:43:20   countHistory    624336
     2020-04-15 13:06:02   sql_processing_time 0.0933
     2020-04-15 13:06:02   state           connected
   

   powerMap:
   readingsDesc:
     energy:
       rtype      whr
     power:
       rtype      w
Attributes:
   asyncMode  1
   bulkInsert 1
   room       System
   showproctime 1


Gruß
Eisix

eki

Kannst Du bitte mal in Deiner Definition folgende Zeile dazufügen und noch mal testen.

data-logfile = "-"

Eisix

Funktioniert!
Danke!

Ist irgendwann geplant das in deine Main Version einzubauen? Wenn ja dann gib mir bitte bescheid damit ich das Widget aus exclude from update nehmen kann.

Gruß
Eisix


eki

Ich bin dabei noch ein paar Kleinigkeiten zu reparieren, dann kommt die aktuelle Version ins standard FTUI.