Hier eine kurze Anleitung zum einbinden des Badgy E-Ink-Display in IP-Symcon.
Die Anleitung soll es möglichst jedem ermöglichen das Display einzubinden und mit eigenem Inhalt zu füllen.
Als Firmware auf dem Badgy dient die websocketDraw.ino von GitHub ohne Modifikationen.
Diese wird laut Anleitung auf GitHub aufgespielt.
Als nächstes benötigt man das Modul IPSNetwork von Nall-Chan.
-> Einen Websocket-Client anlegen mit der einzigen Einstellung: ws://BADGY_IP_ADRESSE:81
Jetzt ein Skript mit folgendem Inhalt anlegen:
<?php
$websocket_id = 49865;
$width = 296; //Displaysize x
$height = 128; // Displaysize y
$dest_image = imagecreatetruecolor($width, $height); // Create image
$white = imagecolorallocate($dest_image, 255, 255, 255); // Color white
$black = imagecolorallocate($dest_image, 0, 0, 0); // Color black
imagefill($dest_image,0,0,$white); // Fill image
$load = getvaluefloat(14333); // Variable load 0 to 100
$soc = getvalueinteger(58053); // State of charge 0 to 100
$current = getvaluefloat(48387); // Current -50 to 50
// -------------------- Edit image to create -----------------------------
// -------------------- Text ---------------------------------------------
$text = number_format ($current,1)."A"; // generate text for current
imagestring($dest_image, 5, 162, 48, $text, $black); // copy text to image
// --------------- Draw Lines --------------------------------------------
if ($load < 25){imageline ( $dest_image , 49 , 14 , 49 , 18 , $black );} // 25%
if ($load < 50){imageline ( $dest_image , 98 , 14 , 98 , 18 , $black );} // 50%
if ($load < 75){imageline ( $dest_image , 147 , 14 , 147 , 18 , $black );} // 75%
// ---------------- Draw rectangles --------------------------------------
$soc_y = 113 - round(($soc/100)*90,0); // Calculate rectangle for soc
imagefilledrectangle ( $dest_image , 224 , 113 , 279 , $soc_y , $black ) ; // Draw rectangle
if ($soc < 100){imagefilledrectangle ( $dest_image , 234 , 55 , 269 , 80 , $white ) ;} // White rectangle for text
imagerectangle($dest_image,2,2,194,20, $black); // frame 1 for load
imagerectangle($dest_image,3,3,193,19, $black); // frame 2 for load
$load_x = 4 + round(($load/100)*190,0); // Calculate rectangle for load
if ($load_x > 190){$load_x = 191;} // if calculated value is to big
imagefilledrectangle ( $dest_image , 5 , 5 , $load_x , 17 , $black ) ; // Draw load bar
imagefilledrectangle ( $dest_image , 90 , 7 , 112 , 15 , $white ); // white rectangle for text
$x_pos = 95; // Position for one digit
if ($load == 100){$x_pos = 91;} // Position for three digits
if ($load >= 10 and $load < 100){$x_pos = 93;} // Position for two digits
imagestring($dest_image, 1, $x_pos, 7, $load."%", $black); // copy text to image
// --------------- Place Images ------------------------------------------
// ImageCopy ( resource $dst_im , resource $src_im , int $dst_x , int $dst_y , int $src_x , int $src_y , int $src_w , int $src_h ) : int
// imagecopyresized ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h ) : bool
$image = imagecreatefrompng("/var/lib/symcon/media/battery.png"); // load image
imagecopy($dest_image, $image, 198, 0, 10, 0, 108, 128); // copy image to destination
imagedestroy($image); //destroy image
if ($current > 0 ){ // images for battery is loading
$image = imagecreatefrompng("/var/lib/symcon/media/arrow-right.png"); // load image
imagecopyresized($dest_image, $image, 160, 65, 0, 0, 50, 30, 64, 64); // copy resized image to destination
imagedestroy($image); //destroy image
$image = imagecreatefrompng("/var/lib/symcon/media/arrow-left.png"); // load image
imagecopyresized($dest_image, $image, 40, 65, 0, 0, 50, 30, 64, 64); // copy resized image to destination
imagedestroy($image); //destroy image
$image = imagecreatefrompng("/var/lib/symcon/media/solar-panel.png"); // load image
imagecopyresized($dest_image, $image, 90, 45, 0, 0, 70, 70, 128, 128); // copy resized image to destination
imagedestroy($image); //destroy image
$image = imagecreatefrompng("/var/lib/symcon/media/plug.png"); // load image
imagecopyresized($dest_image, $image,2, 65, 0, 0, 50, 50, 128, 128); // copy resized image to destination
imagedestroy($image); //destroy image
}
if ($current <= 0 and $current >= -1.4){ // images for battery is not loading - supply from grid
$image = imagecreatefrompng("/var/lib/symcon/media/power.png"); // load image
imagecopyresized($dest_image, $image, 0, 55, 0, 0, 45, 60, 128, 128); // copy resized image to destination
imagedestroy($image); //destroy image
$image = imagecreatefrompng("/var/lib/symcon/media/plug.png"); // load image
imagecopyresized($dest_image, $image, 105, 60, 0, 0, 50, 50, 128, 128); // copy resized image to destination
imagedestroy($image); //destroy image
$image = imagecreatefrompng("/var/lib/symcon/media/arrow-right.png"); // load image
imagecopyresized($dest_image, $image, 48, 65, 0, 0, 50, 30, 64, 64); // copy resized image to destination
imagedestroy($image); //destroy image
$image = imagecreatefrompng("/var/lib/symcon/media/arrow-left.png"); // load image
imagecopyresized($dest_image, $image, 160, 65, 0, 0, 50, 30, 64, 64); // copy resized image to destination
imagedestroy($image); //destroy image
}
if ($current < -1.4){ // images for load is on battery
$image = imagecreatefrompng("/var/lib/symcon/media/plug.png"); // load image
imagecopyresized($dest_image, $image, 105, 60, 0, 0, 50, 50, 128, 128); // copy resized image to destination
imagedestroy($image); //destroy image
$image = imagecreatefrompng("/var/lib/symcon/media/arrow-left.png"); // load image
imagecopyresized($dest_image, $image, 160, 65, 0, 0, 50, 30, 64, 64); // copy resized image to destination
imagedestroy($image); //destroy image
}
// --------------------- Text "True Type Font" --------------------------
// imagettftext ( resource $image , float $size , float $angle , int $x , int $y , int $color , string $fontfile , string $text ) : array
$font = '/var/lib/symcon/webfront/user/eInk/Arial.ttf'; // location of True Type Font
$text = getvaluestring(27105); // get string which contains remaining time
if ($text !== "INF:NAN"){ // if time is available copy it to image
imagettftext($dest_image, 14, 0, 14, 38, $black, $font, "Verbleibend: ".$text); // copy text to image
}
$pos_txt = 239; // position for two digits
if ($soc < 10){$pos_txt = 245;} // position for one digit
if ($soc < 100){imagettftext($dest_image, 18, 0, $pos_txt, 75, $black, $font, $soc);} // copy text to image if soc < 100
// ------------------- End create Image ------------------------
$sendstr = ""; // empty string for data to send
for ($ypos = 0; $ypos <= ($height -1); $ypos++){ // lines of display
for ($a = 0; $a <= ($width/8)-1; $a++) { // bytes per line (width divided by 8)
$outbyte = 0; // empty byte for pixels
for ($onebyte = 0; $onebyte <=7; $onebyte++) { // bits per byte
$xpos = ($a * 8)+$onebyte; // x-position to read
$rgb = imagecolorat($dest_image, $xpos, $ypos); // get the pixel color
if ($rgb > 0 ){ // if pixel is not white set bit
$outbyte = $outbyte + pow(2,7-$onebyte); // calculation of bit to set
}
}
$sendstr = $sendstr.chr($outbyte^0xFF); // append byte to string to send
}
}
// Generate jpeg image for prewiew
if ($_IPS['SENDER'] == "Execute"){ // only on script execute
ob_start(); // Turn on output buffering
header( "Content-type: image/jpeg" ); // set header
imagerectangle ( $dest_image , 0 , 0 , $width-1 , $height-1 , $black ) ; // image size
imagejpeg( $dest_image, NULL, 100 ); // generate jpeg from image data
$i = ob_get_clean(); // Get current buffer contents and delete current output buffer
echo "<img src='data:image/jpeg;base64," . base64_encode( $i )."'>"; // echo jpeg data
}
imagedestroy($dest_image); //destroy image
WSC_SendPacket($websocket_id, true, 2, $sendstr ); // send data with websocket
Dieses Skript dient als Beispiel und ist ohne Bearbeitung nicht lauffähig, da die Schriftart, die Grafiken und die Variablen bei euch fehlen.
Ist das Skript angepasst und wird ausgeführt, sieht man im Ausgabefenster (HTML) die Grafik für das Display als Vorschau.
Demnächst will ich das Skript auch noch mit anderen Displays testen.
Bis dahin.
Grüße
Stefan