Proplanta Min-Max Temperatur als Bereich

Begonnen von vocaris, 23 November 2017, 12:58:39

Vorheriges Thema - Nächstes Thema

vocaris

Hallo zusammen,

irgendwo hier im Forum hatte ich die Funktion logProxy_proplanta2Plot gefunden, mit der sich Werte von Proplanta als Chart anzeigen lassen. Da ich aber nicht eine Kurve für Min und eine für Max anzeigen möchte, sondern einen Bereich habe ich diese Funktion entsprechend umgearbeitet. Bei der Anzeige lasse ich mir dann die Min-Kurve anzeigen und gestapelt dadrauf die Differenzwerte zu Max.
Die Berechnungen funktionieren auch tadellos, sodass ich folgende Ergebnisse erhalte:

Max-Werte:

2017-11-23_06:00:00 15
2017-11-24_06:00:00 13
2017-11-25_06:00:00 5
2017-11-26_06:00:00 5
2017-11-27_06:00:00 6
2017-11-28_06:00:00 7
2017-11-29_06:00:00 4
2017-11-30_00:00:00 4.75


Min-Werte:

2017-11-23_06:00:00 9
2017-11-24_06:00:00 5
2017-11-25_06:00:00 4
2017-11-26_06:00:00 2
2017-11-27_06:00:00 2
2017-11-28_06:00:00 3
2017-11-29_06:00:00 2
2017-11-30_00:00:00 1.25


Meine berechneten Diferenzwerte sind:

2017-11-23_06:00:00 6
2017-11-24_06:00:00 8
2017-11-25_06:00:00 1
2017-11-26_06:00:00 3
2017-11-27_06:00:00 4
2017-11-28_06:00:00 4
2017-11-29_06:00:00 2
2017-11-30_00:00:00 3.5


Die Anzeige funktioniert für alle Werte korrekt, lediglich der letzte Wert wird falsch visualisiert, wie man im Anhang sehen kann. Die Definition des Charts ist folgende:

<div data-type="chart"
                class="cell nobuttons fullsize"
                data-logdevice='[
                    "logProxy",
                    "logProxy",
                    "logProxy"
                ]'
                data-columnspec='[
                    "Func:logProxy_proplanta2Plot(\\x22weather#weather-city#Proplanta\\x22,\\x22tempMin\\x22,$from,$to,6,\\x22day\\x22)",
                    "Func:logProxy_proplanta2PlotSubstractEx(\\x22weather#weather-city#Proplanta\\x22,\\x22tempMax\\x22,\\x22tempMin\\x22,$from,$to,6,\\x22day\\x22)",
                    "Func:logProxy_proplanta2Plot(\\x22weather#weather-city#Proplanta\\x22,\\x22tempMax\\x22,$from,$to,6,\\x22day\\x22)"
                ]'
                data-style='[
                    "ftui l6",
                    "ftui l1fill",
                    "ftui l2"
]'
                 data-ptype='[
"lines",
"lines:0",
                        "lines"
]'
                 data-uaxis='[
"primary",
"primary",
                        "primary"
]'
                data-legend='[
                        "Min.",
                        "dif",
                        "Max."
                ]'
                data-yunit=" °C"
                data-ytext="Temperatur °C"
                data-yunit_sec=" °C"
                data-ytext_sec="Temperatur °C"
                data-timeformat="eeee"
                data-minvalue="auto"
                data-maxvalue="auto"
                data-minvalue_sec="auto"
                data-maxvalue_sec="auto"
                data-daysago_start = "0"
                data-daysago_end = "-7"
                data-xticks="1440"
                data-yticks="auto"
                data-showlegend="true"
                data-crosshair="true">
        </div>


Wieso wird der letzte Wert falsch angezeigt? Ist das ein Fehler im chart oder (was ich viel mehr vermute) mache ich noch was falsch?

vocaris

eki

um das richtig beurteilen zu können, wäre es gut, wenn Du Deine geänderte Funktion hier mal postest. Grundsätzlich ist Deine Chart Definition OK, und sollte funktionieren. Ich schau mal ob da im Chart Widget noch was falsch ist.

Ich habe auch noch eine gute Neuigkeit, ich bin im Moment dabei eine neue Version des Chart Widgets fertig zu machen (sollte nächste Woche kommen). In der genau das was Du hier machst, nämlichdas Ausfüllen zwischen zwei Readings direkt möglich ist. Also noch ein bisschen Geduld.

vocaris

Das klingt ja super, also ich freue mich auf die neue Version :)

Bis dahin zeige ich dir gerne meine Anpassungen:

sub logProxy_proplanta2PlotSubstractEx($$$$$;$$) {
    my ($device, $fcValue1, $fcValue2, $from, $to, $fcHour, $expMode) = @_;
    my $regex1;
    my $regex2;
    my @rl;

    return undef if(!$device);
   
    if($fcValue1 =~ s/_$//) {
        $regex1 = "^fc[\\d]+_".$fcValue1."[\\d]{2}\$";
    }
    else {
        $regex1 = "^fc[\\d]+_".$fcValue1."\$";
    }
    if($fcValue2 =~ s/_$//) {
        $regex2 = "^fc[\\d]+_".$fcValue2."[\\d]{2}\$";
    }
    else {
        $regex2 = "^fc[\\d]+_".$fcValue2."\$";
    }
   
    $fcHour = 12 if(!defined $fcHour);
    $expMode = "point" if(!defined $expMode);

    if( defined($defs{$device}) ) {
        if( $defs{$device}{TYPE} eq "PROPLANTA" ) {
            @rl = sort{
                my ($an) = ($a =~ m/fc(\d+)_.*/);
                my ($bn) = ($b =~ m/fc(\d+)_.*/);

                my ($value1) = $an . ( index($a, $fcValue1) ne -1 ? 0 : 1 );
                my ($value2) = $bn . ( index($b, $fcValue1) ne -1 ? 0 : 1 );

                $value1 <=> $value2;
                }( grep /${regex1}|${regex2}/,keys %{$defs{$device}{READINGS}} );
            return undef if( !@rl );
        } else {
            Log3 undef, 2, "logProxy_proplanta2Plot: $device is not a PROPLANTA device";
            return undef;
        }
    }

    my %values = ();
   
    my $fromsec = SVG_time_to_sec($from);
    my $tosec   = SVG_time_to_sec($to);
    my $sec = $fromsec;
    my ($h,$fcDay,$mday,$mon,$year);
    my $timestamp;
   
    my $reading;
    my $value;
    my $prev_value;
    my $prev_day;
    my $min = 999999;
    my $max = -999999;
    my $ret = "";

    # while not end of plot range reached
    while(@rl) {
        #remember previous value for start of plot range
        $prev_value = $value;

        $reading = shift @rl;
        ($fcDay) = $reading =~ m/^fc(\d+).*/;
           $h = ($reading =~ m/.*(\d\d)$/)?$1:$fcHour;
        $value = ReadingsVal($device,$reading,undef);
       
        ($mday,$mon,$year) = split('\.',ReadingsVal($device,"fc".$fcDay."_date",undef));
        $timestamp = sprintf("%04d-%02d-%02d_%02d:%02d:%02d", $year, $mon, $mday, $h, 0, 0);
        $sec = SVG_time_to_sec($timestamp);
       
        # skip all values before start of plot range
        # all values before start of plot as [0]
        if( SVG_time_to_sec($timestamp) < $fromsec ){
            $min = $value if( $value < $min );
            $max = $value if( $value > $max );
       
            if (!(exists $values{$from})){
                $values{$from} = ( );
            }

            if (index($reading, $fcValue1) ne -1){
                $values{$from}[0] = $value;
            } elsif (index($reading, $fcValue2) ne -1){
                $values{$from}[1] = $value;
            } else {
                Log3 undef, 0, "myUtils !!! DAS KANN NICHT SEIN !!!";
            }
            next;
        }

        $min = $value if( $value < $min );
        $max = $value if( $value > $max );

        if($sec > $tosec){
            $timestamp = $to;
        }

        # add actual controll point
        if (!(exists $values{$timestamp})){
            $values{$timestamp} = ( );
        }
       
        if (index($reading, $fcValue1) ne -1){
            $values{$timestamp}[0] = $value;
        } elsif (index($reading, $fcValue2) ne -1){
            $values{$timestamp}[1] = $value;
        } else {
            Log3 undef, 0, "myUtils !!! DAS KANN NICHT SEIN !!!";
        }
       
        # done if after end of plot range
        if(($sec > $tosec) and (defined $values{$timestamp}[0]) and (defined $values{$timestamp}[1])){
            last;
        }
    }

    if(($sec < $tosec) && !@rl && ($expMode eq "day")) {
        $timestamp = sprintf("%04d-%02d-%02d_%02d:%02d:%02d", $year, $mon, $mday, 23, 59, 59);
        if(SVG_time_to_sec($timestamp) < $tosec) {
            $ret .= "$timestamp $value\n";
        }
        else {
            $ret .= "$to $value\n";
        }
    }
    elsif(($sec > $tosec) && ($expMode eq "day")) {
        my @keys = sort {$a cmp $b} keys %values;

        my $lastTimestamp = @keys[scalar(@keys) - 1];
        my $prevTimestamp = @keys[scalar(@keys) - 2];

        # letzten Timestamp umrechnen
        # values[0]
        $value = $values{$lastTimestamp}[0];
        $prev_value = $values{$prevTimestamp}[0];
        $value = $prev_value + ($value - $prev_value)*(86400 + ($tosec - $sec))/86400;

        $values{$lastTimestamp}[0] = $value;
        # values[1]
        $value = $values{$lastTimestamp}[1];
        $prev_value = $values{$prevTimestamp}[1];
        $value = $prev_value + ($value - $prev_value)*(86400 + ($tosec - $sec))/86400;

        $values{$lastTimestamp}[1] = $value;
           
        foreach my $key(sort {$a cmp $b} keys %values){
            Log3 undef, 0, "myUtils !!! timestamp: $key   value1: " . $values{$key}[0]. "   value2: " . $values{$key}[1];
        }
       
        foreach my $key(sort {$a cmp $b} keys %values){
            $ret .= $key . " " . ($values{$key}[0] - $values{$key}[1]) . "\n";
        }
    }

    return ($ret,$min,$max,$prev_value);
}


Ich hatte gehoft, dass die Wertreihen reichen, weil der Code ja doch etwas mehr ist...

eki