mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-29 23:47:10 +00:00
74_AutomowerConnect: Common.pm, automowerconnect.js, fix problem with empty positions array, java script cleanup
git-svn-id: https://svn.fhem.de/fhem/trunk@27706 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
02e95f4fbb
commit
01e1a0df67
@ -1,5 +1,7 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||||
# Do not insert empty lines here, update check depends on it.
|
# Do not insert empty lines here, update check depends on it.
|
||||||
|
- bugfix: 74_AutomowerConnect: Common.pm, automowerconnect.js, fix promlem
|
||||||
|
with empty positions array
|
||||||
- feature: 74_AutomowerConnect: Common.pm, add additional API polling
|
- feature: 74_AutomowerConnect: Common.pm, add additional API polling
|
||||||
- feature: 76_SMAInverter: bugfix DC-Power
|
- feature: 76_SMAInverter: bugfix DC-Power
|
||||||
- change: 74_AutomowerConnect: Common.pm, automowerconnect.js
|
- change: 74_AutomowerConnect: Common.pm, automowerconnect.js
|
||||||
|
@ -195,6 +195,7 @@ my $mapZonesTpl = '{
|
|||||||
maxLat => -90,
|
maxLat => -90,
|
||||||
imageHeight => 650,
|
imageHeight => 650,
|
||||||
imageWidthHeight => '350 650',
|
imageWidthHeight => '350 650',
|
||||||
|
map_init_delay => 2,
|
||||||
mapdesign => $mapAttr,
|
mapdesign => $mapAttr,
|
||||||
mapZonesTpl => $mapZonesTpl,
|
mapZonesTpl => $mapZonesTpl,
|
||||||
posMinMax => "-180 90\n180 -90",
|
posMinMax => "-180 90\n180 -90",
|
||||||
@ -447,87 +448,82 @@ sub FW_detailFn {
|
|||||||
my $type = $hash->{TYPE};
|
my $type = $hash->{TYPE};
|
||||||
return '' if( AttrVal($name, 'disable', 0) || !AttrVal($name, 'showMap', 1) );
|
return '' if( AttrVal($name, 'disable', 0) || !AttrVal($name, 'showMap', 1) );
|
||||||
|
|
||||||
if ( $hash->{helper} && $hash->{helper}{mower} && $hash->{helper}{mower}{attributes} && $hash->{helper}{mower}{attributes}{positions} && @{$hash->{helper}{mower}{attributes}{positions}} > 0 ) {
|
my $img = "$FW_ME/$type/$name/map";
|
||||||
|
my $zoom=AttrVal( $name,"mapImageZoom", 0.7 );
|
||||||
|
my $backgroundcolor = AttrVal($name, 'mapBackgroundColor','');
|
||||||
|
my $bgstyle = $backgroundcolor ? " background-color:$backgroundcolor;" : '';
|
||||||
|
my $design = AttrVal( $name, 'mapDesignAttributes', $hash->{helper}{mapdesign} );
|
||||||
|
my @adesign = split(/\R/,$design);
|
||||||
|
my $mapDesign = 'data-'.join("data-",@adesign);
|
||||||
|
|
||||||
my $img = "$FW_ME/$type/$name/map";
|
my ($picx,$picy) = AttrVal( $name,"mapImageWidthHeight", $hash->{helper}{imageWidthHeight} ) =~ /(\d+)\s(\d+)/;
|
||||||
my $zoom=AttrVal( $name,"mapImageZoom", 0.7 );
|
$picx=int($picx*$zoom);
|
||||||
my $backgroundcolor = AttrVal($name, 'mapBackgroundColor','');
|
$picy=int($picy*$zoom);
|
||||||
my $bgstyle = $backgroundcolor ? " background-color:$backgroundcolor;" : '';
|
|
||||||
my $design = AttrVal( $name, 'mapDesignAttributes', $hash->{helper}{mapdesign} );
|
|
||||||
my @adesign = split(/\R/,$design);
|
|
||||||
my $mapDesign = 'data-'.join("data-",@adesign);
|
|
||||||
|
|
||||||
my ($picx,$picy) = AttrVal( $name,"mapImageWidthHeight", $hash->{helper}{imageWidthHeight} ) =~ /(\d+)\s(\d+)/;
|
my ( $lonlo, $latlo, $dummy, $lonru, $latru ) = AttrVal( $name,"mapImageCoordinatesToRegister",$hash->{helper}{posMinMax} ) =~ /(-?\d*\.?\d+)\s(-?\d*\.?\d+)(\R|\s)(-?\d*\.?\d+)\s(-?\d*\.?\d+)/;
|
||||||
$picx=int($picx*$zoom);
|
my $mapx = $lonlo-$lonru;
|
||||||
$picy=int($picy*$zoom);
|
my $mapy = $latlo-$latru;
|
||||||
|
|
||||||
my ( $lonlo, $latlo, $dummy, $lonru, $latru ) = AttrVal( $name,"mapImageCoordinatesToRegister",$hash->{helper}{posMinMax} ) =~ /(-?\d*\.?\d+)\s(-?\d*\.?\d+)(\R|\s)(-?\d*\.?\d+)\s(-?\d*\.?\d+)/;
|
AttrVal($name,'scaleToMeterXY', $hash->{helper}{scaleToMeterLongitude} . ' ' .$hash->{helper}{scaleToMeterLatitude}) =~ /(-?\d+)\s+(-?\d+)/;
|
||||||
my $mapx = $lonlo-$lonru;
|
my $scalx = ( $lonru - $lonlo ) * $1;
|
||||||
my $mapy = $latlo-$latru;
|
my $scaly = ( $latlo - $latru ) * $2;
|
||||||
|
|
||||||
AttrVal($name,'scaleToMeterXY', $hash->{helper}{scaleToMeterLongitude} . ' ' .$hash->{helper}{scaleToMeterLatitude}) =~ /(-?\d+)\s+(-?\d+)/;
|
# CHARGING STATION POSITION
|
||||||
my $scalx = ( $lonru - $lonlo ) * $1;
|
my $csimgpos = AttrVal( $name,"chargingStationImagePosition","right" );
|
||||||
my $scaly = ( $latlo - $latru ) * $2;
|
my $xm = $hash->{helper}{chargingStation}{longitude} // 10.1165;
|
||||||
|
my $ym = $hash->{helper}{chargingStation}{latitude} // 51.28;
|
||||||
|
|
||||||
# CHARGING STATION POSITION
|
my ($cslo,$csla) = AttrVal( $name,"chargingStationCoordinates","$xm $ym" ) =~ /(-?\d*\.?\d+)\s(-?\d*\.?\d+)/;
|
||||||
my $csimgpos = AttrVal( $name,"chargingStationImagePosition","right" );
|
my $cslon = int(($lonlo-$cslo) * $picx / $mapx);
|
||||||
my $xm = $hash->{helper}{chargingStation}{longitude} // 10.1165;
|
my $cslat = int(($latlo-$csla) * $picy / $mapy);
|
||||||
my $ym = $hash->{helper}{chargingStation}{latitude} // 51.28;
|
my $csdata = 'data-csimgpos="'.$csimgpos.'" data-cslon="'.$cslon.'" data-cslat="'.$cslat.'"';
|
||||||
|
|
||||||
my ($cslo,$csla) = AttrVal( $name,"chargingStationCoordinates","$xm $ym" ) =~ /(-?\d*\.?\d+)\s(-?\d*\.?\d+)/;
|
# AREA LIMITS
|
||||||
my $cslon = int(($lonlo-$cslo) * $picx / $mapx);
|
my $arealimits = AttrVal($name,'mowingAreaLimits','');
|
||||||
my $cslat = int(($latlo-$csla) * $picy / $mapy);
|
my $limi = '';
|
||||||
my $csdata = 'data-csimgpos="'.$csimgpos.'" data-cslon="'.$cslon.'" data-cslat="'.$cslat.'"';
|
if ($arealimits) {
|
||||||
|
my @lixy = (split(/\s|,|\R$/,$arealimits));
|
||||||
# AREA LIMITS
|
$limi = int( ( $lonlo - $lixy[ 0 ] ) * $picx / $mapx ) . "," . int( ( $latlo - $lixy[ 1 ] ) * $picy / $mapy );
|
||||||
my $arealimits = AttrVal($name,'mowingAreaLimits','');
|
for (my $i=2;$i<@lixy;$i+=2){
|
||||||
my $limi = '';
|
$limi .= ",".int( ( $lonlo - $lixy[ $i ] ) * $picx / $mapx).",".int( ( $latlo-$lixy[$i+1] ) * $picy / $mapy);
|
||||||
if ($arealimits) {
|
|
||||||
my @lixy = (split(/\s|,|\R$/,$arealimits));
|
|
||||||
$limi = int( ( $lonlo - $lixy[ 0 ] ) * $picx / $mapx ) . "," . int( ( $latlo - $lixy[ 1 ] ) * $picy / $mapy );
|
|
||||||
for (my $i=2;$i<@lixy;$i+=2){
|
|
||||||
$limi .= ",".int( ( $lonlo - $lixy[ $i ] ) * $picx / $mapx).",".int( ( $latlo-$lixy[$i+1] ) * $picy / $mapy);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$limi = 'data-areaLimitsPath="'.$limi.'"';
|
|
||||||
|
|
||||||
# PROPERTY LIMITS
|
|
||||||
my $propertylimits = AttrVal($name,'propertyLimits','');
|
|
||||||
my $propli = '';
|
|
||||||
if ($propertylimits) {
|
|
||||||
my @propxy = (split(/\s|,|\R$/,$propertylimits));
|
|
||||||
$propli = int(($lonlo-$propxy[0]) * $picx / $mapx).",".int(($latlo-$propxy[1]) * $picy / $mapy);
|
|
||||||
for (my $i=2;$i<@propxy;$i+=2){
|
|
||||||
$propli .= ",".int(($lonlo-$propxy[$i]) * $picx / $mapx).",".int(($latlo-$propxy[$i+1]) * $picy / $mapy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$propli = 'data-propertyLimitsPath="'.$propli.'"';
|
|
||||||
|
|
||||||
my $ret = "";
|
|
||||||
$ret .= "<style>
|
|
||||||
.${type}_${name}_div{padding:0px !important;
|
|
||||||
$bgstyle background-image: url('$img');
|
|
||||||
background-size: ${picx}px ${picy}px;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
width: ${picx}px; height: ${picy}px;
|
|
||||||
position: relative;}
|
|
||||||
.${type}_${name}_canvas_0{
|
|
||||||
position: absolute; left: 0; top: 0; z-index: 0;}
|
|
||||||
.${type}_${name}_canvas_1{
|
|
||||||
position: absolute; left: 0; top: 0; z-index: 1;}
|
|
||||||
</style>";
|
|
||||||
$ret .= "<div id='${type}_${name}_div' class='${type}_${name}_div' $mapDesign $csdata $limi $propli >";
|
|
||||||
$ret .= "<canvas id='${type}_${name}_canvas_0' class='${type}_${name}_canvas_0' width='$picx' height='$picy' ></canvas>";
|
|
||||||
$ret .= "<canvas id='${type}_${name}_canvas_1' class='${type}_${name}_canvas_1' width='$picx' height='$picy' ></canvas>";
|
|
||||||
$ret .= "</div>";
|
|
||||||
$hash->{helper}{detailFnFirst} = 1;
|
|
||||||
InternalTimer( gettimeofday() + 2, \&FW_detailFn_Update, $hash, 0 );
|
|
||||||
|
|
||||||
return $ret;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
$limi = 'data-areaLimitsPath="'.$limi.'"';
|
||||||
|
|
||||||
return '';
|
# PROPERTY LIMITS
|
||||||
|
my $propertylimits = AttrVal($name,'propertyLimits','');
|
||||||
|
my $propli = '';
|
||||||
|
if ($propertylimits) {
|
||||||
|
my @propxy = (split(/\s|,|\R$/,$propertylimits));
|
||||||
|
$propli = int(($lonlo-$propxy[0]) * $picx / $mapx).",".int(($latlo-$propxy[1]) * $picy / $mapy);
|
||||||
|
for (my $i=2;$i<@propxy;$i+=2){
|
||||||
|
$propli .= ",".int(($lonlo-$propxy[$i]) * $picx / $mapx).",".int(($latlo-$propxy[$i+1]) * $picy / $mapy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$propli = 'data-propertyLimitsPath="'.$propli.'"';
|
||||||
|
|
||||||
|
my $ret = "";
|
||||||
|
$ret .= "<style>
|
||||||
|
.${type}_${name}_div{padding:0px !important;
|
||||||
|
$bgstyle background-image: url('$img');
|
||||||
|
background-size: ${picx}px ${picy}px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
width: ${picx}px; height: ${picy}px;
|
||||||
|
position: relative;}
|
||||||
|
.${type}_${name}_canvas_0{
|
||||||
|
position: absolute; left: 0; top: 0; z-index: 0;}
|
||||||
|
.${type}_${name}_canvas_1{
|
||||||
|
position: absolute; left: 0; top: 0; z-index: 1;}
|
||||||
|
</style>";
|
||||||
|
$ret .= "<div id='${type}_${name}_div' class='${type}_${name}_div' $mapDesign $csdata $limi $propli >";
|
||||||
|
$ret .= "<canvas id='${type}_${name}_canvas_0' class='${type}_${name}_canvas_0' width='$picx' height='$picy' ></canvas>";
|
||||||
|
$ret .= "<canvas id='${type}_${name}_canvas_1' class='${type}_${name}_canvas_1' width='$picx' height='$picy' ></canvas>";
|
||||||
|
$ret .= "</div>";
|
||||||
|
$hash->{helper}{detailFnFirst} = 1;
|
||||||
|
my $mid = $hash->{helper}{map_init_delay};
|
||||||
|
InternalTimer( gettimeofday() + $mid, \&FW_detailFn_Update, $hash, 0 );
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2504,7 +2500,8 @@ sub wsCb {
|
|||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $type = $hash->{TYPE};
|
my $type = $hash->{TYPE};
|
||||||
my $iam = "$type $name wsCb:";
|
my $iam = "$type $name wsCb:";
|
||||||
Log3 $name, 2, "$iam failed with error: $error" if( $error );
|
my $l = $hash->{devioLoglevel};
|
||||||
|
Log3 $name, ( $l ? $l : 1 ), "$iam failed with error: $error" if( $error );
|
||||||
return undef;
|
return undef;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -294,87 +294,79 @@ function AutomowerConnectUpdateDetail (dev, type, detailfnfirst, picx, picy, sca
|
|||||||
"L" : "leavingPath",
|
"L" : "leavingPath",
|
||||||
"G" : "goingHomePath"
|
"G" : "goingHomePath"
|
||||||
};
|
};
|
||||||
// log('loop: Start '+ type+' '+dev );
|
const div = document.getElementById(type+'_'+dev+'_div');
|
||||||
if (FW_urlParams.detail == dev || 1) {
|
const canvas_0 = document.getElementById(type+'_'+dev+'_canvas_0');
|
||||||
const canvas_0 = document.getElementById(type+'_'+dev+'_canvas_0');
|
const canvas = document.getElementById(type+'_'+dev+'_canvas_1');
|
||||||
const canvas = document.getElementById(type+'_'+dev+'_canvas_1');
|
|
||||||
const div = document.getElementById(type+'_'+dev+'_div');
|
|
||||||
|
|
||||||
if ( canvas && canvas_0 ) {
|
if ( div && canvas && canvas_0 ) {
|
||||||
|
|
||||||
// log('loop: canvas && canvas_0 true '+ type+' '+dev + ' detailfnfirst '+detailfnfirst);
|
// log('loop: div && canvas && canvas_0 true '+ type+' '+dev + ' detailfnfirst '+detailfnfirst);
|
||||||
|
|
||||||
if ( detailfnfirst ) {
|
if ( detailfnfirst ) {
|
||||||
|
|
||||||
const ctx0 = canvas_0.getContext( '2d' );
|
const ctx0 = canvas_0.getContext( '2d' );
|
||||||
ctx0.clearRect( 0, 0, canvas.width, canvas.height );
|
ctx0.clearRect( 0, 0, canvas.width, canvas.height );
|
||||||
const ctx = canvas.getContext( '2d' );
|
const ctx = canvas.getContext( '2d' );
|
||||||
|
|
||||||
// draw area limits
|
// draw area limits
|
||||||
const lixy = div.getAttribute( 'data-areaLimitsPath' ).split(",");
|
const lixy = div.getAttribute( 'data-areaLimitsPath' ).split(",");
|
||||||
if ( lixy.length > 0 ) AutomowerConnectLimits( ctx0, div, lixy, 'area' );
|
if ( lixy.length > 0 ) AutomowerConnectLimits( ctx0, div, lixy, 'area' );
|
||||||
// log('pos.length '+pos.length+' lixy.length '+lixy.length+', scalx '+scalx );
|
// log('pos.length '+pos.length+' lixy.length '+lixy.length+', scalx '+scalx );
|
||||||
|
|
||||||
// draw property limits
|
// draw property limits
|
||||||
const plixy = div.getAttribute( 'data-propertyLimitsPath' ).split( "," );
|
const plixy = div.getAttribute( 'data-propertyLimitsPath' ).split( "," );
|
||||||
if ( plixy.length > 0 ) AutomowerConnectLimits( ctx0, div, plixy, 'property' );
|
if ( plixy.length > 0 ) AutomowerConnectLimits( ctx0, div, plixy, 'property' );
|
||||||
|
|
||||||
// draw scale
|
// draw scale
|
||||||
AutomowerConnectScale( ctx0, picx, picy, scalx );
|
AutomowerConnectScale( ctx0, picx, picy, scalx );
|
||||||
|
|
||||||
// draw charging station
|
// draw charging station
|
||||||
var csx = div.getAttribute( 'data-cslon' );
|
var csx = div.getAttribute( 'data-cslon' );
|
||||||
var csy = div.getAttribute( 'data-cslat' );
|
var csy = div.getAttribute( 'data-cslat' );
|
||||||
var csrel = div.getAttribute( 'data-csimgpos' );
|
var csrel = div.getAttribute( 'data-csimgpos' );
|
||||||
AutomowerConnectIcon( ctx0, csx , csy, csrel, 'CS' );
|
AutomowerConnectIcon( ctx0, csx , csy, csrel, 'CS' );
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const ctx = canvas.getContext( '2d' );
|
|
||||||
ctx.clearRect( 0, 0, canvas.width, canvas.height );
|
|
||||||
|
|
||||||
if ( pos.length > 3 ) {
|
|
||||||
|
|
||||||
// draw mowing path color
|
|
||||||
if ( div.getAttribute( 'data-mowingPathUseDots' ) ) {
|
|
||||||
|
|
||||||
AutomowerConnectDrawDotColor ( ctx, div, pos, colorat );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
AutomowerConnectDrawPathColor ( ctx, div, pos, colorat );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw start
|
|
||||||
if ( div.getAttribute( 'data-mowingPathDisplayStart' ) ) {
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.setLineDash([]);
|
|
||||||
ctx.lineWidth=3;
|
|
||||||
ctx.strokeStyle = 'white';
|
|
||||||
ctx.fillStyle= 'black';
|
|
||||||
ctx.arc( parseInt( pos[ pos.length-3 ] ), parseInt( pos[ pos.length-2 ] ), 4, 0, 2 * Math.PI, false );
|
|
||||||
ctx.fill();
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw mower icon
|
|
||||||
AutomowerConnectIcon( ctx, pos[0], pos[1], AutomowerConnectTor ( pos[3], pos[4], pos[0], pos[1] ), 'M' );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw error icon and path
|
|
||||||
if ( errdesc[0] != '-' ) AutomowerConnectShowError( ctx, div, dev, picx, picy, errdesc, erray );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
setTimeout(()=>{
|
|
||||||
// log('loop: canvas false '+ type+' '+dev );
|
|
||||||
AutomowerConnectUpdateDetail (dev, type, detailfnfirst, picx, picy, scalx, errdesc, pos, erray);
|
|
||||||
}, 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ctx = canvas.getContext( '2d' );
|
||||||
|
ctx.clearRect( 0, 0, canvas.width, canvas.height );
|
||||||
|
|
||||||
|
if ( pos.length > 3 ) {
|
||||||
|
|
||||||
|
// draw mowing path color
|
||||||
|
if ( div.getAttribute( 'data-mowingPathUseDots' ) ) {
|
||||||
|
|
||||||
|
AutomowerConnectDrawDotColor ( ctx, div, pos, colorat );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
AutomowerConnectDrawPathColor ( ctx, div, pos, colorat );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw start
|
||||||
|
if ( div.getAttribute( 'data-mowingPathDisplayStart' ) ) {
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.setLineDash([]);
|
||||||
|
ctx.lineWidth=3;
|
||||||
|
ctx.strokeStyle = 'white';
|
||||||
|
ctx.fillStyle= 'black';
|
||||||
|
ctx.arc( parseInt( pos[ pos.length-3 ] ), parseInt( pos[ pos.length-2 ] ), 4, 0, 2 * Math.PI, false );
|
||||||
|
ctx.fill();
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw mower icon
|
||||||
|
AutomowerConnectIcon( ctx, pos[0], pos[1], AutomowerConnectTor ( pos[3], pos[4], pos[0], pos[1] ), 'M' );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw error icon and path
|
||||||
|
if ( errdesc[0] != '-' ) AutomowerConnectShowError( ctx, div, dev, picx, picy, errdesc, erray );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
setTimeout(()=>{
|
setTimeout(()=>{
|
||||||
// log('loop: detail false '+ type+' '+dev );
|
log('AutomowerConnectUpdateDetail loop: div && canvas && canvas_0 false '+ type+' '+dev );
|
||||||
AutomowerConnectUpdateDetail (dev, type, detailfnfirst, picx, picy, scalx, errdesc, pos, erray);
|
AutomowerConnectUpdateDetail (dev, type, detailfnfirst, picx, picy, scalx, errdesc, pos, erray);
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user