Temperatur in Farbe umsetzen

Begonnen von Prof. Dr. Peter Henning, 07 Dezember 2014, 22:18:23

Vorheriges Thema - Nächstes Thema

Prof. Dr. Peter Henning

Ich bin, wie gesagt, noch nicht zu einer Umsetzung in perl gekommen. Läuft bei mir immer noch als shellscript (weil es für die Bildgerenierung mit ImageMagick benötigt wird).

# Color function
colorfunction () {
   temp=$1

   startcolorR=0
   startcolorG=255
   startcolorB=255

   midcolor1R=30
   midcolor1G=80
   midcolor1B=255


   midcolor2R=40
   midcolor2G=255
   midcolor2B=60

   midcolor3R=160
   midcolor3G=128
   midcolor3B=10

   endcolorR=255
   endcolorG=69
   endcolorB=0

   starttemp=15
   midtemp1=18
   midtemp2=21
   midtemp3=24
   endtemp=27

if  [ $(bc <<< "$temp <= $starttemp") -eq 1 ]
   then
     retval="rgba($startcolorR,$startcolorG,$startcolorB,$opacity)"
   else
     if  [ $(bc <<< "$temp <= $midtemp2") -eq 1 ]
     then
       uval=`echo "scale=5;($temp - $starttemp)/($midtemp2 - $starttemp)" | bc`
       rval1=`echo "scale=5;(1-$uval)^2*$startcolorR" | bc`
       rval2=`echo "scale=5;2*(1-$uval)*$uval*$midcolor1R" | bc`
       rval3=`echo "scale=5;$uval^2*$midcolor2R" | bc`
       rval=`echo "scale=0;(100*($rval1+$rval2+$rval3)+0.5)/100" | bc`
 
       gval1=`echo "scale=5;(1-$uval)^2*$startcolorG" | bc`       
       gval2=`echo "scale=5;2*(1-$uval)*$uval*$midcolor1G" | bc`
       gval3=`echo "scale=5;$uval^2*$midcolor2G" | bc`
       gval=`echo "scale=0;(100*($gval1+$gval2+$gval3)+0.5)/100" | bc`

       bval1=`echo "scale=5;(1-$uval)^2*$startcolorB" | bc`       
       bval2=`echo "scale=5;2*(1-$uval)*$uval*$midcolor1B" | bc`
       bval3=`echo "scale=5;$uval^2*$midcolor2B" | bc`

       bval=`echo "scale=0;(100*($bval1+$bval2+$bval3)+0.5)/100" | bc`

       retval="rgba($rval,$gval,$bval,$opacity)"
     else
       if  [ $(bc <<< "$temp <= $endtemp") -eq 1 ]
       then
         uval=`echo "scale=5;($temp - $midtemp2)/($endtemp - $midtemp2)" | bc`
         rval1=`echo "scale=5;(1-$uval)^2*$midcolor2R" | bc`
         rval2=`echo "scale=5;2*(1-$uval)*$uval*$midcolor3R" | bc`
         rval3=`echo "scale=5;$uval^2*$endcolorR" | bc`
         rval=`echo "scale=0;(100*($rval1+$rval2+$rval3)+0.5)/100" | bc`
 
         gval1=`echo "scale=5;(1-$uval)^2*$midcolor2G" | bc`       
         gval2=`echo "scale=5;2*(1-$uval)*$uval*$midcolor3G" | bc`
         gval3=`echo "scale=5;$uval^2*$endcolorG" | bc`
         gval=`echo "scale=0;(100*($gval1+$gval2+$gval3)+0.5)/100" | bc`

         bval1=`echo "scale=5;(1-$uval)^2*$midcolor2B" | bc`       
         bval2=`echo "scale=5;2*(1-$uval)*$uval*$midcolor3B" | bc`
         bval3=`echo "scale=5;$uval^2*$endcolorB" | bc`

         bval=`echo "scale=0;(100*($bval1+$bval2+$bval3)+0.5)/100" | bc`

         retval="rgba($rval,$gval,$bval,$opacity)"   
       else
         retval="rgba($endcolorR,$endcolorG,$endcolorB,$opacity)"
       fi
     fi
   fi
   echo $retval 
}


Im Unterschied zu der Version von Udo (stückweise lineare Interpolation) habe ich zwei Bezierkurven 2. Ordnung aneinandergesetzt. Das schafft einen glatteren Verlauf.

LG

pah

betateilchen

#16
Hallo Peter,


Zitat von: Prof. Dr. Peter Henning am 09 Februar 2015, 09:22:23
Ich bin, wie gesagt, noch nicht zu einer Umsetzung in perl gekommen.

da bin ich grade dran.


       retval="rgba($rval,$gval,$bval,$opacity)"


Woher nimmst Du $opacity und wie sieht ein output von rgba() aus - sind das 8 hex Ziffern?




Edit: Im Moment bekomme ich r/g/b Werte > 255 als Ergebnis - ist das so gewollt?

Edit 2: Frage erledigt, ich bin mal wieder darauf reingefallen, dass in perl ** statt ^ zum potenzieren verwendet werden muss  8)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

fertsch...

(http://debian.fhem.de/grafik/pahcolor.png)

Die Funktion wird mit maximal fünf Parametern aufgerufen:

  • Starttemperatur (Minimaltemperatur)
  • Mitte
  • Endtemperatur (Maximaltemperatur)
  • Temperatur (die dargestellt werden soll)
  • Transparenz (optional, Wertebereich 0..255, wenn nicht vorhanden = 255, voll deckend)

Im Beispiel wurde der Temperaturbereich von 14°-28° (jeweils einschließlich) in einem Bereich von 15°-27° mit 1° Schritten und 21° Mittenwert dargestellt:

pahColor(15,21,27,$temp)

Da die Werte 14 und 28 ausserhalb des Darstellungsbereiches liegen, werden sie mit den jeweiligen "Grenzfarben" der Minimal/Maximaltemperatur dargestellt.


sub pahColor {
   my ($starttemp,$midtemp2,$endtemp,$temp,$opacity) = @_;

   $opacity //= 255;

   my($uval,$rval,$rval1,$rval2,$rval3);
   my($gval,$gval1,$gval2,$gval3);
   my($bval,$bval1,$bval2,$bval3);

   my $startcolorR =   0;
   my $startcolorG = 255;
   my $startcolorB = 255;

   my $midcolor1R =  30;
   my $midcolor1G =  80;
   my $midcolor1B = 255;

   my $midcolor2R =  40;
   my $midcolor2G = 255;
   my $midcolor2B =  60;

   my $midcolor3R = 160;
   my $midcolor3G = 128;
   my $midcolor3B =  10;

   my $endcolorR = 255;
   my $endcolorG =  69;
   my $endcolorB =   0;

   return sprintf("%02X%02X%02X%02X",$startcolorR,$startcolorG,$startcolorB,$opacity) if ($temp <= $starttemp);
   return sprintf("%02X%02X%02X%02X",$endcolorR,$endcolorG,$endcolorB,$opacity)       if ($temp >  $endtemp);

   if ($temp <= $midtemp2) {
      $uval  = sprintf("%.5f",($temp - $starttemp) / ($midtemp2 - $starttemp));
      $rval1 = sprintf("%.5f",(1-$uval)**2 * $startcolorR);
      $rval2 = sprintf("%.5f",2*(1-$uval) * $uval * $midcolor1R);
      $rval3 = sprintf("%.5f",$uval**2 * $midcolor2R);
      $rval  = sprintf("%.0f",(100*($rval1 + $rval2 + $rval3)+0.5)/100);

      $gval1 = sprintf("%.5f",(1-$uval)**2 * $startcolorG);
      $gval2 = sprintf("%.5f",2*(1-$uval) * $uval * $midcolor1G);
      $gval3 = sprintf("%.5f",$uval**2 * $midcolor2G);
      $gval  = sprintf("%.0f",(100*($gval1 + $gval2 + $gval3)+0.5)/100);

      $bval1 = sprintf("%.5f",(1-$uval)**2 * $startcolorB);
      $bval2 = sprintf("%.5f",2*(1-$uval) * $uval * $midcolor1B);
      $bval3 = sprintf("%.5f",$uval**2 * $midcolor2B);
      $bval  = sprintf("%.0f",(100*($bval1 + $bval2 + $bval3)+0.5)/100);
      return sprintf("%02X%02X%02X%02X",$rval,$gval,$bval,$opacity);
   }

   if ($temp <= $endtemp) {
      $uval  = sprintf("%.5f",($temp - $midtemp2)/($endtemp - $midtemp2));
      $rval1 = sprintf("%.5f",(1-$uval)**2 * $midcolor2R);
      $rval2 = sprintf("%.5f",2 * (1-$uval) * $uval * $midcolor3R);
      $rval3 = sprintf("%.5f",$uval**2 * $endcolorR);
      $rval  = sprintf("%.0f",(100*($rval1+$rval2+$rval3)+0.5)/100);

      $gval1 = sprintf("%.5f",(1-$uval)**2 * $midcolor2G);
      $gval2 = sprintf("%.5f",2 * (1-$uval) * $uval * $midcolor3G);
      $gval3 = sprintf("%.5f",$uval**2 * $endcolorG);
      $gval  = sprintf("%.0f",(100*($gval1+$gval2+$gval3)+0.5)/100);

      $bval1 = sprintf("%.5f",(1-$uval)**2 * $midcolor2B);
      $bval2 = sprintf("%.5f",2*(1-$uval)*$uval*$midcolor3B);
      $bval3 = sprintf("%.5f",$uval**2 *$endcolorB);
      $bval  = sprintf("%.0f",(100*($bval1+$bval2+$bval3)+0.5)/100);
      return sprintf("%02X%02X%02X%02X",$rval,$gval,$bval,$opacity);
   }

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

P.A.Trick

#18
Cool! Wie erstellst du denn die Grafik?
Cubietruck,RPI,QNAP Ts-419p+, FS20, FRITZ!DECT200, 7 MAX! Thermostate, 3 MAX! Fensterkontakte, Kodi, CUL V3.3, EM1000S, LW12, LD382, HUE, HM-CFG-USB-2, 1x HM-LC-SW1-FM, 2x HM-LC-SW2-FM, 2x HM-LC-Sw1PBU-FM, 3xHM-LC-Bl1PBU-FM,HM-SEC-RHS, 2xHM-SEC-SD,HM-WDS30-T-O, 3x HM-LC-Dim1TPBU-FM, RPI+AddOn

betateilchen

Mittels eines InfoPanels.

Aber wieso musst Du für eine solche simple Frage einen kompletten Beitrag zitieren?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

P.A.Trick

Cubietruck,RPI,QNAP Ts-419p+, FS20, FRITZ!DECT200, 7 MAX! Thermostate, 3 MAX! Fensterkontakte, Kodi, CUL V3.3, EM1000S, LW12, LD382, HUE, HM-CFG-USB-2, 1x HM-LC-SW1-FM, 2x HM-LC-SW2-FM, 2x HM-LC-Sw1PBU-FM, 3xHM-LC-Bl1PBU-FM,HM-SEC-RHS, 2xHM-SEC-SD,HM-WDS30-T-O, 3x HM-LC-Dim1TPBU-FM, RPI+AddOn

betateilchen

ja, danke. Denn nicht jeder arbeitet mit einem 27" Monitor ;)

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

P.A.Trick

Nicht? Ich dachte das ist heute Standard?  :)
Nun aber BTT!
Cubietruck,RPI,QNAP Ts-419p+, FS20, FRITZ!DECT200, 7 MAX! Thermostate, 3 MAX! Fensterkontakte, Kodi, CUL V3.3, EM1000S, LW12, LD382, HUE, HM-CFG-USB-2, 1x HM-LC-SW1-FM, 2x HM-LC-SW2-FM, 2x HM-LC-Sw1PBU-FM, 3xHM-LC-Bl1PBU-FM,HM-SEC-RHS, 2xHM-SEC-SD,HM-WDS30-T-O, 3x HM-LC-Dim1TPBU-FM, RPI+AddOn

Prof. Dr. Peter Henning

@betateilchen: Prima. Ist das dann schon in Color.pm drin ?

LG

pah

betateilchen

#24
Dafür bin ich nicht zuständig, Color.pm "gehört" Andre. Bei mir ist die Funktion aktuell in der 99_myUtils.pm untergebracht.

Die Berechnung gefällt mir hervorragend - tolle Idee, die Du da umgesetzt hast.

So sieht das Ganze bei einer Skala von -10..+30 mit Mitte bei 18° aus:

(http://debian.fhem.de/grafik/farbskala2.png)

Damit kann ich nun direkt die LED-Balkonbeleuchtung per LW12-Controller mit dem temperaturabhängigen rgb Wert ansteuern und sehe schon vor dem Aufstehen, wie kalt es draußen ist  8)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Prof. Dr. Peter Henning

Das ist ein netter Use Case - den werde ich als Idee (mit Namensnennung, natürlich) gleich als Anwendungsfall in das Buch "Hacks für die Heimautomation" aufnehmen, das ich gerade schreibe. Dafür gibt es auch zwei Bonbons.

Probier mal die drei folgenden Fälle (Achtung,Mathematica-Code, muss man erst noch in Perl umsetzen):

Das ist der bisherige Fall

startcolor={0,255,255};
midcolor1={30,80,255};
midcolor2={40,255,60};
midcolor3={160,128,10};
endcolor={255,69,0};


Hier ist der eher düstere Braunton bei hohen Temperaturen etwas besser gewählt und die Spreizung bei niedrigen Temperaturen besser:

startcolor={0,255,255};
midcolor1={120,120,120};
midcolor2={40,255,60};
midcolor3={255,255,0};
endcolor={255,69,0};


Und das hier ist für diejenigen, die es richtig blau mögen

startcolor={0,69,255};
midcolor1={120,180,180};
midcolor2={40,255,60};
midcolor3={255,255,0};
endcolor={255,69,0};


Nachstehend noch die Temperaturskalen dazu, sowie Darstellungen in den drei Farbebenen des RGB-Farbmodells. Ich habe das auch dreidimensional - aber leider sind die Videoclips dazu jeweils ca. 40 MB groß und auch das animierte GIF hat immerhin noch 1.9 MB , das wollte ich dem Server hier nicht zumuten.

LG

pah

betateilchen

Zitat von: Prof. Dr. Peter Henning am 14 Februar 2015, 06:55:06
auch das animierte GIF hat immerhin noch 1.9 MB , das wollte ich dem Server hier nicht zumuten.

Sowas kann ich gerne auf debian.fhem.de ablegen und hierher verlinken. Du müsstest mir das gif nur per email schicken oder in irgendeiner Cloud freigeben, damit ich es auf den Server schieben kann.

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

Prof. Dr. Peter Henning

#27
Oh, das ist keine Frage von Webspace - ich glaube, insgesamt finanziere ich aus meinem Forschungsetat inzwischen 4 externe Server...

Als Erstes habe ich mal eine Wiki-Seite aufgesetzt http://www.fhemwiki.de/wiki/Temperaturfarbe.

Und hier die drei (in zeitlicher und räumlicher Auflösung abgespeckten) Animationen dazu. Mit transparenten Würfeln als Bausteinen des RGB-Farbraums.

LG

pah

betateilchen

Die drehenden Würfel sind hübsch. Mehr nicht.  8)


Zitat von: Prof. Dr. Peter Henning am 13 Februar 2015, 19:21:42
Ist das dann schon in Color.pm drin ?

*schubs* damit es nicht vergessen wird :)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

justme1968

ist eingecheckt als Color::pahColor
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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