mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-10 03:06:37 +00:00
89_ESPEInk.pm:
# Änderungen eki - 2021-10-07 # Zusammenstellunge aller Änderungen aus dem Forum Chat # - neues Device mit 5.65 inch und 6 Farben # - neues Attribut mininterval (es wird mindestens mininterval sekunden gewartet, bis ein neues Bild hochgeladen werden kann) # - neues Attribut uploadTimeout (timeout bevor abgebrochen und ein Fehler bezüglich der upload Kommunikation gemeldet wird) # - Korrektur zum Setzen von Farben in icons # - Korrektur bezüglich Warnungen beim Start git-svn-id: https://svn.fhem.de/fhem/trunk@25054 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
20f48faecb
commit
69b8e31837
@ -4,6 +4,15 @@
|
||||
# Umstellung verzögerte berechnung der Pixel erst beim upload
|
||||
# blocktext (ESPEInk_FormatBlockText) korrigiert für Behandlung von \\n
|
||||
# text height ($th) is potentially wrong if text is wrapped to multiple lines so text height shoul dbe calced from one char only (addobjects)
|
||||
#
|
||||
# Änderungen eki - 2021-10-07
|
||||
# Zusammenstellunge aller Änderungen aus dem Forumschat
|
||||
# - neues Device mit 5.65 inch und 6 Farben
|
||||
# - neues Attribut mininterval (es wird mindestens mininterval sekunden gewartet, bis ein neues Bild hochgeladen werden kann)
|
||||
# - neues Attribut uploadTimeout (timeout bevor abgebrochen und ein Fehler bezüglich der upload Kommunikation gemeldet wird)
|
||||
# - Korrektur zum Setzen von Farben in icons
|
||||
# - Korrektur bezüglich Warnungen beim Start
|
||||
|
||||
|
||||
package main;
|
||||
use strict;
|
||||
@ -38,7 +47,8 @@ my @ESPEInk_palettes = (
|
||||
[3,[0,0,0],[255,255,255],[127,127,127]],
|
||||
[4,[0,0,0],[255,255,255],[127,127,127],[127,0,0]],
|
||||
[2,[0,0,0],[255,255,255]],
|
||||
[3,[0,0,0],[255,255,255],[220,180,0]]
|
||||
[3,[0,0,0],[255,255,255],[220,180,0]],
|
||||
[7,[0,0,0],[255,255,255],[0,255,0],[0,0,255],[255,0,0],[255,255,0],[255,128,0]]
|
||||
);
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
@ -49,32 +59,32 @@ my %ESPEInk_devices = (
|
||||
# "9.7inch_e-Paper_HAT" => {width => 200, height => 200, pindex => 10, id => 24},
|
||||
# "7.8inch_e-Paper_HAT" => {width => 200, height => 200, pindex => 10, id => 23},
|
||||
# "6inch_e-Paper_HAT" => {width => 200, height => 200, pindex => 10, id => 22},
|
||||
# "2.9inch_e-Paper_HAT_(D)" => {width => 200, height => 200, pindex => 10, id => 21},
|
||||
"7.5inch_e-Paper_HAT_(B)_HD" => {width => 880, height => 528, pindex => 1, id => 24},
|
||||
"7.5inch_e-Paper_HAT_V2_(B)" => {width => 800, height => 480, pindex => 1, id => 23},
|
||||
"7.5inch_e-Paper_HAT_V2" => {width => 800, height => 480, pindex => 0, id => 22},
|
||||
"7.5inch_e-Paper_HAT_(C)" => {width => 640, height => 384, pindex => 5, id => 21},
|
||||
"7.5inch_e-Paper_HAT_(B)" => {width => 640, height => 384, pindex => 1, id => 20},
|
||||
"7.5inch_e-Paper_HAT" => {width => 640, height => 384, pindex => 0, id => 19},
|
||||
"5.83inch_e-Paper_HAT_(C)" => {width => 600, height => 448, pindex => 5, id => 18},
|
||||
"5.83inch_e-Paper_HAT_(B)" => {width => 600, height => 448, pindex => 1, id => 17},
|
||||
"5.83inch_e-Paper_HAT" => {width => 600, height => 448, pindex => 0, id => 16},
|
||||
"4.2inch_e-Paper_Module_(C)" => {width => 400, height => 300, pindex => 5, id => 15},
|
||||
"4.2inch_e-Paper_Module_(B)" => {width => 400, height => 300, pindex => 1, id => 14},
|
||||
"4.2inch_e-Paper_Module" => {width => 400, height => 300, pindex => 0, id => 13},
|
||||
"2.9inch_e-Paper_Module_(D)" => {width => 128, height => 296, pindex => 0, id => 12},
|
||||
"2.9inch_e-Paper_Module_(C)" => {width => 128, height => 296, pindex => 5, id => 11},
|
||||
"2.9inch_e-Paper_Module_(B)" => {width => 128, height => 296, pindex => 1, id => 10},
|
||||
"2.9inch_e-Paper_Module" => {width => 128, height => 296, pindex => 0, id => 9},
|
||||
"2.7inch_e-Paper_HAT_(B)" => {width => 176, height => 264, pindex => 1, id => 8},
|
||||
"2.7inch_e-Paper_HAT" => {width => 176, height => 264, pindex => 0, id => 7},
|
||||
"2.13inch_e-Paper_HAT_(D)" => {width => 104, height => 212, pindex => 0, id => 6},
|
||||
"2.13inch_e-Paper_HAT_(C)" => {width => 104, height => 212, pindex => 5, id => 5},
|
||||
"2.13inch_e-Paper_HAT_(B)" => {width => 104, height => 212, pindex => 1, id => 4},
|
||||
"2.13inch_e-Paper_HAT" => {width => 122, height => 250, pindex => 0, id => 3},
|
||||
"1.54inch_e-Paper_Module_(C)" => {width => 152, height => 152, pindex => 5, id => 2},
|
||||
"1.54inch_e-Paper_Module_(B)" => {width => 200, height => 200, pindex => 3, id => 1},
|
||||
"1.54inch_e-Paper_Module" => {width => 200, height => 200, pindex => 0, id => 0}
|
||||
"5.65inch_e-Paper_HAT_(F)" => {width => 600, height => 448, pindex => 6, updateint => 35, id => 25},
|
||||
"7.5inch_e-Paper_HAT_(B)_HD" => {width => 880, height => 528, pindex => 1, updateint => 21, id => 24},
|
||||
"7.5inch_e-Paper_HAT_V2_(B)" => {width => 800, height => 480, pindex => 1, updateint => 16, id => 23},
|
||||
"7.5inch_e-Paper_HAT_V2" => {width => 800, height => 480, pindex => 0, updateint => 5, id => 22},
|
||||
"7.5inch_e-Paper_HAT_(C)" => {width => 640, height => 384, pindex => 5, updateint => 21, id => 21},
|
||||
"7.5inch_e-Paper_HAT_(B)" => {width => 640, height => 384, pindex => 1, updateint => 16, id => 20},
|
||||
"7.5inch_e-Paper_HAT" => {width => 640, height => 384, pindex => 0, updateint => 5, id => 19},
|
||||
"5.83inch_e-Paper_HAT_(C)" => {width => 600, height => 448, pindex => 5, updateint => 26, id => 18},
|
||||
"5.83inch_e-Paper_HAT_(B)" => {width => 600, height => 448, pindex => 1, updateint => 20, id => 17},
|
||||
"5.83inch_e-Paper_HAT" => {width => 600, height => 448, pindex => 0, updateint => 5, id => 16},
|
||||
"4.2inch_e-Paper_Module_(C)" => {width => 400, height => 300, pindex => 5, updateint => 15, id => 15},
|
||||
"4.2inch_e-Paper_Module_(B)" => {width => 400, height => 300, pindex => 1, updateint => 15, id => 14},
|
||||
"4.2inch_e-Paper_Module" => {width => 400, height => 300, pindex => 0, updateint => 4, id => 13},
|
||||
"2.9inch_e-Paper_Module_(D)" => {width => 128, height => 296, pindex => 0, updateint => 2, id => 12},
|
||||
"2.9inch_e-Paper_Module_(C)" => {width => 128, height => 296, pindex => 5, updateint => 15, id => 11},
|
||||
"2.9inch_e-Paper_Module_(B)" => {width => 128, height => 296, pindex => 1, updateint => 15, id => 10},
|
||||
"2.9inch_e-Paper_Module" => {width => 128, height => 296, pindex => 0, updateint => 2, id => 9},
|
||||
"2.7inch_e-Paper_HAT_(B)" => {width => 176, height => 264, pindex => 1, updateint => 15, id => 8},
|
||||
"2.7inch_e-Paper_HAT" => {width => 176, height => 264, pindex => 0, updateint => 6, id => 7},
|
||||
"2.13inch_e-Paper_HAT_(D)" => {width => 104, height => 212, pindex => 0, updateint => 2, id => 6},
|
||||
"2.13inch_e-Paper_HAT_(C)" => {width => 104, height => 212, pindex => 5, updateint => 15, id => 5},
|
||||
"2.13inch_e-Paper_HAT_(B)" => {width => 104, height => 212, pindex => 1, updateint => 15, id => 4},
|
||||
"2.13inch_e-Paper_HAT" => {width => 122, height => 250, pindex => 0, updateint => 2, id => 3},
|
||||
"1.54inch_e-Paper_Module_(C)" => {width => 152, height => 152, pindex => 5, updateint => 28, id => 2},
|
||||
"1.54inch_e-Paper_Module_(B)" => {width => 200, height => 200, pindex => 3, updateint => 8, id => 1},
|
||||
"1.54inch_e-Paper_Module" => {width => 200, height => 200, pindex => 0, updateint => 2, id => 0}
|
||||
);
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
@ -141,6 +151,8 @@ sub ESPEInk_Initialize($) {
|
||||
. "disable:0,1 "
|
||||
. "definition:textField-long "
|
||||
. "definitionFile "
|
||||
. "mininterval "
|
||||
. "uploadTimeout "
|
||||
. $readingFnAttributes;
|
||||
|
||||
$hash->{STATE} = "Initialized";
|
||||
@ -379,6 +391,31 @@ sub ESPEInk_Set($@) {
|
||||
}
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
# Attr function, check attribute setting, conversion to readings and error handling
|
||||
sub ESPEInk_FetchReadings(@) {
|
||||
my @values = @_;
|
||||
my @outvalues;
|
||||
my $outvalue;
|
||||
|
||||
foreach my $value (@values) {
|
||||
if ($value =~ m/\[/) {
|
||||
$value =~ s/[\[\]]//g;
|
||||
my ($dev,$reading) = split(":",$value);
|
||||
$value = ReadingsVal($dev,$reading,'');
|
||||
}
|
||||
push(@outvalues,$value);
|
||||
$outvalue = $value;
|
||||
}
|
||||
|
||||
if ((scalar @outvalues) > 1) {
|
||||
return @outvalues;
|
||||
} else {
|
||||
return $outvalue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
# Attr function, check attribute setting, conversion to readings and error handling
|
||||
sub ESPEInk_Attr(@) {
|
||||
@ -405,7 +442,7 @@ sub ESPEInk_Attr(@) {
|
||||
my $colormode = ESPEInk_GetSetting($name,"colormode");
|
||||
my $ipal = $ESPEInk_devices{$attr_value}{"pindex"};
|
||||
$hash->{DEVICETYPE} = $attr_value;
|
||||
if (($colormode eq "color") && (($ipal&1)==0) && $ESPEInk_InitializationDone) {
|
||||
if (($colormode eq "color") && ($ipal==0 or $ipal==4) && $ESPEInk_InitializationDone) {
|
||||
$err = "Inconsistent setting for device type $attr_value. Device does not support color mode, setting colormode attribute to monochrome.";
|
||||
fhem("attr $name colormode monochrome");
|
||||
fhem("attr $name devicetype $attr_value");
|
||||
@ -416,18 +453,18 @@ sub ESPEInk_Attr(@) {
|
||||
} elsif($attr_name eq "colormode") {
|
||||
my $devtype = ESPEInk_GetSetting($name,"devicetype");
|
||||
my $ipal = $ESPEInk_devices{$devtype}{"pindex"};
|
||||
if (($attr_value eq "color") && (($ipal&1)==0) && $ESPEInk_InitializationDone) {
|
||||
if (($attr_value eq "color") && ($ipal==0 or $ipal==4) && $ESPEInk_InitializationDone) {
|
||||
$err = "Invalid argument $attr_value to $attr_name. Device does not support color mode.";
|
||||
return $err;
|
||||
}
|
||||
$hash->{COLORMODE} = $attr_value;
|
||||
} elsif($attr_name =~ '^\d+-.*') {
|
||||
if ($attr_name =~ '(x$|y$|size$)') {
|
||||
return "Invalid argument $attr_value to $attr_name must be an interger number" if ($attr_value !~ '-?\d+');
|
||||
return "Invalid argument $attr_value to $attr_name must be an interger number" if ($attr_value !~ '-?\d+' && $attr_value !~ '^\[.*');
|
||||
} elsif ($attr_name =~ '(size)') {
|
||||
return "Invalid argument $attr_value to $attr_name must be a positive interger number" if ($attr_value !~ '\d+');
|
||||
return "Invalid argument $attr_value to $attr_name must be a positive interger number" if ($attr_value !~ '\d+' && $attr_value !~ '^\[.*');
|
||||
} elsif ($attr_name =~ '(angle)') {
|
||||
return "Invalid argument $attr_value to $attr_name must be an integer number between -180 and +180" if ($attr_value !~ '-?\d+' || int($attr_value) < -180 || int($attr_value) > 180);
|
||||
return "Invalid argument $attr_value to $attr_name must be an integer number between -180 and +180" if (($attr_value !~ '-?\d+' && $attr_value !~ '^\[.*') || int($attr_value) < -180 || int($attr_value) > 180);
|
||||
} elsif ($attr_name =~ '(color)') {
|
||||
return "Invalid argument $attr_value to $attr_name must be a valid rgb hex string" if (!ESPEInk_CheckColorString($attr_value));
|
||||
} elsif ($attr_name =~ '(font)') {
|
||||
@ -451,6 +488,8 @@ sub ESPEInk_Attr(@) {
|
||||
} elsif($attr_name eq "coloroffset") {
|
||||
} elsif($attr_name eq "maxretries") {
|
||||
} elsif($attr_name eq "timeout") {
|
||||
} elsif($attr_name eq "mininterval") {
|
||||
} elsif($attr_name eq "uploadTimeout") {
|
||||
} elsif($attr_name eq "definition") {
|
||||
ESPEInk_ResetNotifies({hash=>$hash,definition=>$attr_value});
|
||||
} elsif($attr_name eq "definitionFile") {
|
||||
@ -675,6 +714,7 @@ sub ESPEInk_ResetNotifies($) {
|
||||
my $eval;
|
||||
($text,$eval) = split("{",$text);
|
||||
($device,$reading) = split(':',$text);
|
||||
next if (($type eq 'iconreading') && (length($text) == 0)); # nothing to do, just skip - Hajo 2
|
||||
if ($device) {
|
||||
$reading = "state" if (!$reading);
|
||||
$notifies .= $device.":".$reading."|" if ($defs{$device});
|
||||
@ -722,7 +762,7 @@ sub ESPEInk_Cleanup($) {
|
||||
# Check color setting for validity
|
||||
sub ESPEInk_CheckColorString($) {
|
||||
my ($color) = @_;
|
||||
return $color =~ '^(?:[0-9a-fA-F]{3}){1,2}$';
|
||||
return ($color =~ '^(?:[0-9a-fA-F]{3}){1,2}$') || ($color =~ '^\[');
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
@ -795,6 +835,7 @@ sub ESPEInk_CorrectXY($$$$$$$$$$) {
|
||||
sub ESPEInk_CheckFontString($) {
|
||||
my ($font) = @_;
|
||||
my $ret = 0;
|
||||
$ret = 1 if ($font =~ '^\['); # reading:value format
|
||||
$ret = 1 if ($font && $font =~ '(small|medium|large|giant)');
|
||||
$ret = ($font && -e $font) if (!$ret);
|
||||
return $ret;
|
||||
@ -807,6 +848,10 @@ sub ESPEInk_CheckIconString($) {
|
||||
my $ret = 0;
|
||||
my $picdata = undef;
|
||||
|
||||
if ($icon =~ '^\[') {
|
||||
return($ret,$icon) if ($ret);
|
||||
}
|
||||
|
||||
if ($icon =~ /http(?:s)\:\/\//) { # Web link, check if it can be downloaded
|
||||
($ret, $picdata) = HttpUtils_BlockingGet({url=>$icon,timeout=>30});
|
||||
$ret = defined $picdata;
|
||||
@ -1232,11 +1277,17 @@ sub ESPEInk_AddObjects($$) {
|
||||
|
||||
if ($definition) { # work on all definitions if definition attribute is defined
|
||||
foreach my $line (split(/\n/,$definition)) { # go through the definition line by line
|
||||
Log3 $hash, 4, "check1: $line" . " - " . length($line);
|
||||
next if (length($line) <1); # Hajo 5
|
||||
next if ($line =~ /^\s*\#.*/); # check for comment lines
|
||||
my ($type, $text, $x, $y, $size, $ang, $col, $fnt,$linegap,$blockwidth,$docolor);
|
||||
$type = undef;
|
||||
$text = undef;
|
||||
($type, $text, $x, $y, $size, $ang, $col, $fnt, $linegap, $blockwidth) = split("#",$line);
|
||||
if (!defined $fnt) {$fnt = ''}; # Hajo 6
|
||||
if (!defined $linegap) {$linegap = ''}; # Hajo 7
|
||||
if (!defined $blockwidth) {$blockwidth = ''}; # Hajo 8
|
||||
($x, $y, $size, $ang, $col, $fnt,$linegap,$blockwidth) = ESPEInk_FetchReadings($x, $y, $size, $ang, $col, $fnt,$linegap,$blockwidth);
|
||||
$linegap = int($linegap) if ($linegap);
|
||||
$blockwidth = int($blockwidth) if ($blockwidth);
|
||||
|
||||
@ -1259,6 +1310,7 @@ sub ESPEInk_AddObjects($$) {
|
||||
my ($device,$reading) = split(':',$text,2);
|
||||
$reading = "state" if (!$reading);
|
||||
$text = ReadingsVal($device,$reading,'');
|
||||
next if (($type eq 'iconreading') && (length($text) == 0)); # nothing to do, just skip - Hajo 2
|
||||
if ($eval) {
|
||||
$eval =~ s/\}//g;
|
||||
$text = sprintf($eval,ReadingsVal($device,$reading,""));
|
||||
@ -1332,9 +1384,11 @@ sub ESPEInk_AddObjects($$) {
|
||||
if ($docolor) {
|
||||
for (my $iy=0; $iy<$sh; $iy++) {
|
||||
for (my $ix=0; $ix<$sw; $ix++) {
|
||||
($r,$g,$b) = $icon_img->rgb($icon_img->getPixel($ix,$iy)); # get color values in source file
|
||||
($r,$g,$b) = $icon_img->rgb($icon_img->getPixel($ix,$iy)); # get color values in source file
|
||||
(my $alpha) = $icon_img->alpha($icon_img->getPixel($ix,$iy)); # get alpha-channel
|
||||
$icon_img->setPixel($ix,$iy,$color) if ($alpha == 0 && $r<180 && $g<180 && $b<180); # set color to given color if original color is black *your favorite tresholds may be different $icon_img->setPixel($ix,$iy,$color) if ($r>0 && $g>0 && $b>0); # set color to given color if original color is black
|
||||
#Log3 $hash, 1, "$r, $g, $b";
|
||||
$icon_img->setPixel($ix,$iy,$color) if ($r>0 && $g>0 && $b>0); # set color to given color if original color is black
|
||||
#$icon_img->setPixel($ix,$iy,$color) if ($r>0 && $g>0 && $b>0); # set color to given color if original color is black
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1430,12 +1484,13 @@ sub ESPEInk_AddObjects($$) {
|
||||
}
|
||||
|
||||
for (my $itext=1; $itext<=$deftexts; $itext++) {
|
||||
my $docolor = (ReadingsVal($name,"$itext-color",0) ne 0) && (ReadingsVal($name,"$itext-color",0) ne '000000');
|
||||
$r= hex(substr(ReadingsVal($name,"$itext-color","000000"),0,2));
|
||||
$g= hex(substr(ReadingsVal($name,"$itext-color","000000"),2,2));
|
||||
$b= hex(substr(ReadingsVal($name,"$itext-color","000000"),4,2));
|
||||
my $ccolor = ESPEInk_FetchReadings(ReadingsVal($name,"$itext-color",'000000'));
|
||||
my $docolor = ($ccolor ne 0) && ($ccolor ne '000000');
|
||||
$r= hex(substr($ccolor,0,2));
|
||||
$g= hex(substr($ccolor,2,2));
|
||||
$b= hex(substr($ccolor,4,2));
|
||||
$color = $image->colorResolve($r,$g,$b);
|
||||
$angle = ReadingsVal($name,"$itext-angle",0)/180*(4*atan2(1,1));
|
||||
$angle = ESPEInk_FetchReadings(ReadingsVal($name,"$itext-angle",0))/180*(4*atan2(1,1));
|
||||
if (ReadingsVal($name,"$itext-isIcon",0)) {
|
||||
my ($ret,$path) = ESPEInk_CheckIconString(ReadingsVal($name,"$itext-icon",""));
|
||||
my ($ext) = $path =~ /(\.[^.]+)$/;
|
||||
@ -1494,8 +1549,10 @@ sub ESPEInk_AddObjects($$) {
|
||||
if ($docolor) {
|
||||
for (my $iy=0; $iy<$sh; $iy++) {
|
||||
for (my $ix=0; $ix<$sw; $ix++) {
|
||||
($r,$g,$b) = $icon_img->rgb($icon_img->getPixel($ix,$iy)); # get color values in source file
|
||||
$icon_img->setPixel($ix,$iy,$color) if ($r>0 && $g>0 && $b>0); # set color to given color if original color is black
|
||||
($r,$g,$b) = $icon_img->rgb($icon_img->getPixel($ix,$iy)); # get color values in source file
|
||||
(my $alpha) = $icon_img->alpha($icon_img->getPixel($ix,$iy)); # get alpha-channel
|
||||
$icon_img->setPixel($ix,$iy,$color) if ($alpha == 0 && $r<180 && $g<180 && $b<180); # set color to given color if original color is black *your favorite tresholds may be different $icon_img->setPixel($ix,$iy,$color) if ($r>0 && $g>0 && $b>0); # set color to given color if original color is black
|
||||
#$icon_img->setPixel($ix,$iy,$color) if ($r>0 && $g>0 && $b>0); # set color to given color if original color is black
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1505,35 +1562,37 @@ sub ESPEInk_AddObjects($$) {
|
||||
my $icon_img_rot = GD::Image->new($srw,$srh,1);
|
||||
$icon_img_rot->alphaBlending(0);
|
||||
$icon_img_rot->fill($srw/2,$srh/2,$icon_img_rot->colorAllocateAlpha(0,0,0,127));
|
||||
$icon_img_rot->copyRotated($icon_img,$srw/2,$srh/2,0,0,$sw,$sh,ReadingsVal($name,"$itext-angle",0));
|
||||
my $dh = ReadingsVal($name,"$itext-size",10);
|
||||
$icon_img_rot->copyRotated($icon_img,$srw/2,$srh/2,0,0,$sw,$sh,ESPEInk_FetchReadings(ReadingsVal($name,"$itext-angle",0)));
|
||||
my $dh = ESPEInk_FetchReadings(ReadingsVal($name,"$itext-size",10));
|
||||
my $dw = $srw*$dh/$srh;
|
||||
my ($iw,$ih) = $image->getBounds;
|
||||
my ($x,$y) = ESPEInk_CorrectXY($name,"icon","$dw#$dh",ReadingsVal($name,"$itext-font",""),ReadingsVal($name,"$itext-angle",""),ReadingsVal($name,"$itext-size",""),$iw,$ih,ReadingsVal($name,"$itext-x",0),ReadingsVal($name,"$itext-y",0));
|
||||
my ($x,$y) = ESPEInk_CorrectXY($name,"icon","$dw#$dh",ESPEInk_FetchReadings(ReadingsVal($name,"$itext-font","")),ESPEInk_FetchReadings(ReadingsVal($name,"$itext-angle","")),ESPEInk_FetchReadings(ReadingsVal($name,"$itext-size","")),$iw,$ih,ESPEInk_FetchReadings(ReadingsVal($name,"$itext-x",0)),ESPEInk_FetchReadings(ReadingsVal($name,"$itext-y",0)));
|
||||
$image->copyResized($icon_img_rot,$x,$y,0,0,$dw,$dh,$srw,$srh);
|
||||
}
|
||||
} elsif (!ReadingsVal($name,"$itext-isSymbol",0)) {
|
||||
my $cfont = ESPEInk_FetchReadings(ReadingsVal($name,"$itext-font",""));
|
||||
$font = undef;
|
||||
$font = gdGiantFont if (ReadingsVal($name,"$itext-font","") eq "giant");
|
||||
$font = gdLargeFont if (ReadingsVal($name,"$itext-font","") eq "large");
|
||||
$font = gdMediumBoldFont if (ReadingsVal($name,"$itext-font","") eq "medium");
|
||||
$font = gdSmallFont if (ReadingsVal($name,"$itext-font","") eq "small");
|
||||
|
||||
$font = gdGiantFont if ($cfont eq "giant");
|
||||
$font = gdLargeFont if ($cfont eq "large");
|
||||
$font = gdMediumBoldFont if ($cfont eq "medium");
|
||||
$font = gdSmallFont if ($cfont eq "small");
|
||||
my ($dw,$dh) = $image->getBounds;
|
||||
my $ly = ReadingsVal($name,"$itext-y",0);
|
||||
# Do not use full text here, since only height is relevant here and this can be calced from one char
|
||||
#
|
||||
my ($tw, $th) = ESPEInk_GetStringPixelWidth($name,"A",ReadingsVal($name,"$itext-font","small"),ReadingsVal($name,"$itext-angle",0),ReadingsVal($name,"$itext-size",10));
|
||||
my ($tw, $th) = ESPEInk_GetStringPixelWidth($name,"A",ESPEInk_FetchReadings(ReadingsVal($name,"$itext-font","small")),ESPEInk_FetchReadings(ReadingsVal($name,"$itext-angle",0)),ESPEInk_FetchReadings(ReadingsVal($name,"$itext-size",10)));
|
||||
$th += int(ReadingsVal($name,"$itext-linegap",0));
|
||||
|
||||
my $text = ESPEInk_FormatBlockText($name,ReadingsVal($name,"$itext-text",""),ReadingsVal($name,"$itext-font","small"),ReadingsVal($name,"$itext-angle",0),ReadingsVal($name,"$itext-size",10),int(ReadingsVal($name,"$itext-blockwidth",0)),$th);
|
||||
my $text = ESPEInk_FormatBlockText($name,ReadingsVal($name,"$itext-text",""),ESPEInk_FetchReadings(ReadingsVal($name,"$itext-font","small")),ESPEInk_FetchReadings(ReadingsVal($name,"$itext-angle",0)),ESPEInk_FetchReadings(ReadingsVal($name,"$itext-size",10)),int(ESPEInk_FetchReadings(ReadingsVal($name,"$itext-blockwidth",0))),$th);
|
||||
foreach my $tline (split(/\\n/,$text)) {
|
||||
my ($x,$y) = ESPEInk_CorrectXY($name,"text",$tline,ReadingsVal($name,"$itext-font",""),ReadingsVal($name,"$itext-angle",""),ReadingsVal($name,"$itext-size",""),$dw,$dh,ReadingsVal($name,"$itext-x",0),$ly);
|
||||
my ($x,$y) = ESPEInk_CorrectXY($name,"text",$tline,ESPEInk_FetchReadings(ReadingsVal($name,"$itext-font","")),ESPEInk_FetchReadings(ReadingsVal($name,"$itext-angle","")),ESPEInk_FetchReadings(ReadingsVal($name,"$itext-size","")),$dw,$dh,ESPEInk_FetchReadings(ReadingsVal($name,"$itext-x",0)),$ly);
|
||||
|
||||
if (!$font) { #use TTF from file given
|
||||
my $fontfile = ReadingsVal($name,"$itext-font","");
|
||||
my @bounds = $image->stringFT($color,ReadingsVal($name,"$itext-font",""),ReadingsVal($name,"$itext-size",10),$angle,$x,ReadingsVal($name,"$itext-size",10)+$y,$tline);
|
||||
my @bounds = $image->stringFT($color,ESPEInk_FetchReadings(ReadingsVal($name,"$itext-font","")),ESPEInk_FetchReadings(ReadingsVal($name,"$itext-size",10)),$angle,$x,ESPEInk_FetchReadings(ReadingsVal($name,"$itext-size",10))+$y,$tline);
|
||||
} else {
|
||||
if ((ReadingsVal($name,"$itext-angle",0) < -45) || (ReadingsVal($name,"$itext-angle",0) > 45)) {
|
||||
if ((ESPEInk_FetchReadings(ReadingsVal($name,"$itext-angle",0)) < -45) || (ESPEInk_FetchReadings(ReadingsVal($name,"$itext-angle",0)) > 45)) {
|
||||
$image->stringUp($font,$x,$y,$tline,$color);
|
||||
} else {
|
||||
$image->string($font,$x,$y,$tline,$color);
|
||||
@ -1544,13 +1603,13 @@ sub ESPEInk_AddObjects($$) {
|
||||
} else {
|
||||
my ($sym,$s1,$s2) = ("","","");
|
||||
($sym,$s1,$s2) = split("-",ReadingsVal($name,"$itext-symbol",""));
|
||||
my $size = ReadingsVal($name,"$itext-size","");
|
||||
my $width = ReadingsVal($name,"$itext-width",0);
|
||||
my $height = ReadingsVal($name,"$itext-height",0);
|
||||
my $ang = ReadingsVal($name,"$itext-angle",0);
|
||||
my $arc = ReadingsVal($name,"$itext-arc",0);
|
||||
my $x = ReadingsVal($name,"$itext-x",0);
|
||||
my $y = ReadingsVal($name,"$itext-y",0);
|
||||
my $size = ESPEInk_FetchReadings(ReadingsVal($name,"$itext-size",""));
|
||||
my $width = ESPEInk_FetchReadings(ReadingsVal($name,"$itext-width",0));
|
||||
my $height = ESPEInk_FetchReadings(ReadingsVal($name,"$itext-height",0));
|
||||
my $ang = ESPEInk_FetchReadings(ReadingsVal($name,"$itext-angle",0));
|
||||
my $arc = ESPEInk_FetchReadings(ReadingsVal($name,"$itext-arc",0));
|
||||
my $x = ESPEInk_FetchReadings(ReadingsVal($name,"$itext-x",0));
|
||||
my $y = ESPEInk_FetchReadings(ReadingsVal($name,"$itext-y",0));
|
||||
$image->setStyle($color);
|
||||
if ($sym eq "line") {
|
||||
my $angle = atan2($height,$width);
|
||||
@ -1627,6 +1686,7 @@ sub ESPEInk_ConvertAborted(@) {
|
||||
# if wanted, Floyd-Steinberg-Dithering is performed to better represent pictures with many colors
|
||||
sub ESPEInk_Convert(@) {
|
||||
my ($hash,$upload) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
if (defined ($hash->{helper}{RUNNING_PID}))
|
||||
{
|
||||
BlockingKill($hash->{helper}{RUNNING_PID});
|
||||
@ -1640,12 +1700,12 @@ sub ESPEInk_Convert(@) {
|
||||
$hash->{helper}{DO_UPLOAD} = $upload;
|
||||
$hash->{helper}{RUNNING_PID} =
|
||||
BlockingCall(
|
||||
"ESPEInk_DoConvert", # callback worker task
|
||||
$hash, # hash of the device and upload trigger
|
||||
"ESPEInk_ConvertDone", # callback result method
|
||||
120, # timeout seconds
|
||||
"ESPEInk_ConvertAborted", # callback for abortion
|
||||
$hash ); # parameter for abortion
|
||||
"ESPEInk_DoConvert", # callback worker task
|
||||
$hash, # hash of the device and upload trigger
|
||||
"ESPEInk_ConvertDone", # callback result method
|
||||
AttrVal($name,"uploadTimeout",290), # timeout seconds
|
||||
"ESPEInk_ConvertAborted", # callback for abortion
|
||||
$hash ); # parameter for abortion
|
||||
Log3 $hash, 4, "Start forked process to convert output picture";
|
||||
return "Starting conversion in background";
|
||||
}
|
||||
@ -1811,6 +1871,27 @@ sub ESPEInk_getPixel($$$$) {
|
||||
return ($r==0&&$g==0)?0:(($r==255&&$g==255)?1:(($r==127&&$g==127)?2:3)); #convert color values to values between 0 and 3
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
# get pixel from image
|
||||
sub ESPEInk_getPixel7C($$$$) {
|
||||
my ($image, $w, $h, $indx ) = @_;
|
||||
|
||||
my $iy = int( $indx / $w );
|
||||
my $ix = $indx % $w;
|
||||
my ($r,$g,$b) = $image->rgb($image->getPixel($ix,$iy));
|
||||
my $retval = 7;
|
||||
|
||||
#convert color values to values between 0 and 6
|
||||
$retval = 0 if ($r==0&&$g==0&&$b==0);
|
||||
$retval = 1 if ($r==255&&$g==255&&$b==255);
|
||||
$retval = 2 if ($r==0&&$g==255&&$b==0);
|
||||
$retval = 3 if ($r==0&&$g==0&&$b==255);
|
||||
$retval = 4 if ($r==255&&$g==0&&$b==0);
|
||||
$retval = 5 if ($r==255&&$g==255&&$b==0);
|
||||
$retval = 6 if ($r==255&&$g==128&&$b==0);
|
||||
return $retval;
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
# helper function for coding picture pixels to EInk bit settings
|
||||
sub ESPEInk_CodePixel2BitsImage($$$$$$$$) {
|
||||
@ -1848,11 +1929,20 @@ sub ESPEInk_CodePixel2BitsImage($$$$$$$$) {
|
||||
}
|
||||
} elsif ($bits == 16) {
|
||||
$v = 0;
|
||||
for (my $i=0; $i<$bits; $i+=2) {
|
||||
if ($indx<$isize) {
|
||||
$v|=(ESPEInk_getPixel($image,$w,$h,$indx)<<$i);
|
||||
if ($comp == -2) {
|
||||
for (my $i=0; $i<$bits; $i+=4) {
|
||||
if ($indx<$isize) {
|
||||
$v|=(ESPEInk_getPixel7C($image,$w,$h,$indx)<<$i);
|
||||
}
|
||||
$indx++;
|
||||
}
|
||||
} else {
|
||||
for (my $i=0; $i<$bits; $i+=2) {
|
||||
if ($indx<$isize) {
|
||||
$v|=(ESPEInk_getPixel($image,$w,$h,$indx)<<$i);
|
||||
}
|
||||
$indx++;
|
||||
}
|
||||
$indx++;
|
||||
}
|
||||
return ($indx, ESPEInk_Word2String($v));
|
||||
}
|
||||
@ -1932,14 +2022,14 @@ sub ESPEInk_Encode4UploadImage($$$) {
|
||||
my $h = $param->{imageh};
|
||||
my $isize = $param->{imagesize};
|
||||
|
||||
if (($i+int($param->{maxulsize})*($bits==8?4:2)) > ($isize-1)) {
|
||||
if (($i+int($param->{maxulsize})*($bits==8?4:($comp==-2?1:2))) > ($isize-1)) {
|
||||
$imax = $isize-1;
|
||||
} else {
|
||||
$imax = $i+int($param->{maxulsize})*($bits==8?4:2);
|
||||
$imax = $i+int($param->{maxulsize})*($bits==8?4:($comp==-2?1:2));
|
||||
}
|
||||
|
||||
if ($param->{device} == 3) {
|
||||
$imax = $i+int($param->{maxulsize})*($bits==8?4:2)-(($param->{board} eq "ESP8266")?366:122);
|
||||
$imax = $i+int($param->{maxulsize})*($bits==8?4:($comp==-2?1:2))-(($param->{board} eq "ESP8266")?366:122);
|
||||
}
|
||||
|
||||
my $postdata = "";
|
||||
@ -2072,9 +2162,9 @@ sub ESPEInk_HTTPCallbackA(@) {
|
||||
} elsif ($param->{control}{stepindex} == 2) {
|
||||
$hash->{STATE} = "Successfully uploaded image to device";
|
||||
}
|
||||
} elsif (($param->{device} > 15) && ($param->{device} < 22)) { # special treatment for bigger displays, upload is done in one step for all colors
|
||||
if ($param->{control}{stepindex} == 0) { # we have different steps for uploading the different colors and closing the upload
|
||||
$comp = -1;
|
||||
} elsif ((($param->{device} > 15) && ($param->{device} < 22)) || $param->{device} == 25) { # special treatment for bigger displays, upload is done in one step for all colors
|
||||
if ($param->{control}{stepindex} == 0) { # we have different steps for uploading the different colors and closing the upload
|
||||
$comp = $param->{device}==25?-2:-1;
|
||||
$bits = 16;
|
||||
$param->{command} = "LOAD"; # start uploading black channel
|
||||
$cparams->{url} = 'http://'.ESPEInk_GetSetting($name,"url").'/'.$param->{command};
|
||||
@ -2254,6 +2344,18 @@ sub ESPEInk_Upload(@) {
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $devtype = ESPEInk_GetSetting($name,"devicetype");
|
||||
my $minint = AttrVal($name,"mininterval",0);
|
||||
if ($minint eq 'auto') {
|
||||
$minint = $ESPEInk_devices{$devtype}{"updateint"};
|
||||
}
|
||||
|
||||
my $dlastupdate = gettimeofday()-ReadingsVal($name,"updatestart",0);
|
||||
if ($dlastupdate < $minint) {
|
||||
Log3 ($hash, 3, "$name: Time $dlastupdate since last Upload too small, try again later or change mininterval ($minint)");
|
||||
return "Time since last Upload too small, try again later or change mininterval";
|
||||
}
|
||||
|
||||
my $url = ESPEInk_GetSetting($name,"url");
|
||||
if (!defined $url) {
|
||||
return "Error, missing url. Define url to device first";
|
||||
@ -2263,25 +2365,24 @@ sub ESPEInk_Upload(@) {
|
||||
Log3 ($hash, 2, "$name: Upload of image currently running, try again later");
|
||||
return $hash->{STATE};
|
||||
}
|
||||
|
||||
$hash->{STATE} = "Uploading image to device";
|
||||
|
||||
readingsSingleUpdate( $hash, "updatestart", gettimeofday(), 1 );
|
||||
my @outarray;
|
||||
|
||||
my $devtype = ESPEInk_GetSetting($name,"devicetype");
|
||||
my $boardtype = ESPEInk_GetSetting($name,"boardtype");
|
||||
my $devind = $ESPEInk_devices{$devtype}{"id"};
|
||||
|
||||
my $rootname = $FW_dir; #File::Spec->rel2abs($FW_dir); # get Filename of FHEMWEB root
|
||||
my $filename = catfile($rootname,$hash->{SUBFOLDER},$name,"result.png");
|
||||
my $image; # JV
|
||||
my $image; # JV
|
||||
if (!open(RESULT,$filename)) {
|
||||
Log3 $hash, 1, "File $filename cannot be opened";
|
||||
return "Error opening image file $filename for upload";
|
||||
} # else {
|
||||
close RESULT;
|
||||
close RESULT;
|
||||
# my $image = GD::Image->newFromPng($filename); # JV
|
||||
$image = GD::Image->newFromPng($filename); # JV
|
||||
$image = GD::Image->newFromPng($filename); # JV
|
||||
# my ($w,$h) = $image->getBounds;
|
||||
# my ($r,$g,$b);
|
||||
# my $i = 0;
|
||||
@ -2293,7 +2394,7 @@ sub ESPEInk_Upload(@) {
|
||||
# $i++;
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
|
||||
$ESPEInk_uploadcontrol{"retries"} = 0; # actual number of retries
|
||||
$ESPEInk_uploadcontrol{"maxretries"} = AttrVal($name,"maxretries",3); # maximum number of retries
|
||||
@ -2555,6 +2656,9 @@ sub ESPEInk_Upload(@) {
|
||||
The time interval for regular updates of the information to the eInk display. The device automatically converts the inputs and uploads the result to the eInk display in this interval.
|
||||
If this value is set to 0 there will be automatical updates in case a triggering device is specified (see set textreading). Otherwise 0 means no automatic updates.
|
||||
</li>
|
||||
<li><i>mininterval</i><br>
|
||||
The time interval that shall at least be elapsed since the last upload. If the interval since last upload is smaller than this value, not uploads will be performed.
|
||||
</li>
|
||||
<li><i>boardtype</i><br>
|
||||
The type of driver board to be used. Currently ESP8266 and ESP32 driver boards are supported.
|
||||
</li>
|
||||
|
Loading…
x
Reference in New Issue
Block a user