diff --git a/fhem/CHANGED b/fhem/CHANGED
index 8aab0a7c9..0e8bad54e 100644
--- a/fhem/CHANGED
+++ b/fhem/CHANGED
@@ -1,5 +1,6 @@
 # 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
+ - bugfix:  76_SolarForecast: fix Warnings
  - change:  76_SolarForecast: set moduleAzimuth to attr setupStringAzimuth
                               set moduleDeclination to setupStringDeclination
                               set moduleRoofTops to attr setupRoofTops 
diff --git a/fhem/FHEM/76_SolarForecast.pm b/fhem/FHEM/76_SolarForecast.pm
index c79d69c7c..08a7c44cf 100644
--- a/fhem/FHEM/76_SolarForecast.pm
+++ b/fhem/FHEM/76_SolarForecast.pm
@@ -128,8 +128,6 @@ BEGIN {
           sunset_abs_dat
           FW_cmd
           FW_directNotify
-          FW_ME
-          FW_subdir
           FW_pH
           FW_room
           FW_detail
@@ -157,6 +155,7 @@ BEGIN {
 
 # Versions History intern
 my %vNotesIntern = (
+  "1.29.1" => "17.06.2024  fix Warnings, Forum: https://forum.fhem.de/index.php?msg=1315283, fix roofIdentPair ",
   "1.29.0" => "16.06.2024  _setreset: improve reset consumerMaster ".
                            "tranformed setter moduleAzimuth to setupStringAzimuth ".
                            "tranformed setter moduleDeclination to setupStringDeclination ".
@@ -575,6 +574,7 @@ my %hset = (                                                                # Ha
   pvCorrectionFactor_21     => { fn => \&_setpvCorrectionFactor        },
   pvCorrectionFactor_Auto   => { fn => \&_setpvCorrectionFactorAuto    },
   reset                     => { fn => \&_setreset                     },
+  roofIdentPair             => { fn => \&_setroofIdentPair             },
   setupStringDeclination    => { fn => \&_setstringDeclination         },
   setupStringAzimuth        => { fn => \&_setstringAzimuth             },
   operatingMemory           => { fn => \&_setoperatingMemory           },
@@ -5552,10 +5552,17 @@ sub _attrRoofTops {                      ## no critic "not used"
           }
       }
 
-      return if(_checkSetupNotComplete ($hash));                                      # keine Stringkonfiguration wenn Setup noch nicht komplett
+      my @istrings = split ",", AttrVal ($name, 'setupInverterStrings', '');                          # Stringbezeichner
 
-      #my $ret = createStringConfig ($hash);
-      #return $ret if($ret);
+      if (!@istrings) {
+          return qq{Define all used strings with command "attr $name setupInverterStrings" first.};
+      }
+
+      while (my ($strg, $pp) = each %$h) {
+          if (!grep /^$strg$/, @istrings) {
+              return qq{The stringname '$strg' is not defined as valid string in attribute 'setupInverterStrings'};
+          }
+      }
   }
   
   InternalTimer (gettimeofday() + 3, 'FHEM::SolarForecast::writeCacheToFile', [$name, 'plantconfig', $plantcfg.$name], 0);   # Anlagenkonfiguration File schreiben
@@ -11415,7 +11422,7 @@ sub entryGraphic {
   my $html_end   = AttrVal ($name, 'graphicEndHtml',   undef);                             # beliebige HTML Strings die nach der Grafik ausgegeben werden  my $w          = $width * $maxhours;                                                     # gesammte Breite der Ausgabe , WetterIcon braucht ca. 34px
   my $w          = $width * $maxhours;                                                     # gesammte Breite der Ausgabe , WetterIcon braucht ca. 34px
   my $offset     = -1 * AttrNum ($name, 'graphicHistoryHour', $histhourdef);
-  my $dlink      = qq{<a href="$FW_ME$FW_subdir?detail=$name">$alias</a>};
+  my $dlink      = qq{<a href="$::FW_ME$::FW_subdir?detail=$name">$alias</a>};
 
   if (!$gsel) {
       $gsel = AttrVal ($name, 'graphicSelect', 'both');                                    # Auswahl der anzuzeigenden Grafiken
@@ -11671,7 +11678,7 @@ sub _checkSetupNotComplete {
 
   my $pv0   = NexthoursVal ($hash, 'NextHour00', 'pvfc', undef);                          # der erste PV ForeCast Wert
 
-  my $link   = qq{<a href="$FW_ME$FW_subdir?detail=$name">$name</a>};
+  my $link   = qq{<a href="$::FW_ME$::FW_subdir?detail=$name">$name</a>};
   my $height = AttrNum ($name, 'graphicBeamHeightLevel1', 200);
   my $lang   = getLang ($hash);
 
@@ -11691,7 +11698,7 @@ sub _checkSetupNotComplete {
 
   ## Anlagen Check-Icon
   #######################
-  my $cmdplchk = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=get $name plantConfigCheck', function(data){FW_okDialog(data)})"};
+  my $cmdplchk = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=get $name plantConfigCheck', function(data){FW_okDialog(data)})"};
   my $img      = FW_makeImage('edit_settings@grey');
   my $chkicon  = "<a onClick=$cmdplchk>$img</a>";
   my $chktitle = $htitles{plchk}{$lang};
@@ -11838,7 +11845,7 @@ sub _graphicHeader {
          $lup = "$day.$month.$year&nbsp;$time";
       }
 
-      my $cmdplchk = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=get $name plantConfigCheck', function(data){FW_okDialog(data)})"};          # Plant Check Button generieren
+      my $cmdplchk = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=get $name plantConfigCheck', function(data){FW_okDialog(data)})"};          # Plant Check Button generieren
 
       if ($ftui eq 'ftui') {
           $cmdplchk = qq{"ftui.setFhemStatus('get $name plantConfigCheck')"};
@@ -12065,7 +12072,7 @@ sub _graphicHeader {
       ## erste Header-Zeilen
       #######################
       my $alias = AttrVal ($name, "alias", $name );                                               # Linktext als Aliasname
-      my $dlink = qq{<a href="$FW_ME$FW_subdir?detail=$name">$alias</a>};
+      my $dlink = qq{<a href="$::FW_ME$::FW_subdir?detail=$name">$alias</a>};
 
       $header  .= qq{<tr>};
       $header  .= qq{<td colspan="1" align="left"                    $dstyle> <b>$dlink</b>              </td>};
@@ -12147,7 +12154,7 @@ sub __createUpdateIcon {
   my $upstate = ReadingsVal ($name, 'state',         '');
   my $naup    = ReadingsVal ($name, 'nextCycletime', '');
 
-  my $cmdupdate = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction - 0 get $name data')"};                               # Update Button generieren
+  my $cmdupdate = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=set $name clientAction - 0 get $name data')"};                               # Update Button generieren
 
   if ($ftui eq 'ftui') {
       $cmdupdate = qq{"ftui.setFhemStatus('set $name clientAction - 0 get $name data')"};
@@ -12225,7 +12232,7 @@ sub __createQuaIcon {
   my ($pcf,$pcq) = split "/", $pvcorrf00;
   my $pvcanz     = qq{factor: $pcf / quality: $pcq};
 
-  my $cmdfcqal = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=get $name forecastQualities imgget', function(data){FW_okDialog(data)})"};
+  my $cmdfcqal = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=get $name forecastQualities imgget', function(data){FW_okDialog(data)})"};
 
   if ($ftui eq 'ftui') {
       $cmdfcqal = qq{"ftui.setFhemStatus('get $name forecastQualities imgget')"};
@@ -12753,11 +12760,11 @@ sub _graphicConsumerLegend {
       my $autord                  = ConsumerVal ($hash, $c, 'autoreading', '');                     # Readingname f. Automatiksteuerung
       my $auto                    = ConsumerVal ($hash, $c, 'auto',         1);                     # Automatic Mode
 
-      my $cmdon      = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction $c 0 set $dswname $oncom')"};
-      my $cmdoff     = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction $c 0 set $dswname $offcom')"};
-      my $cmdautoon  = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction $c 0 setreading $dswname $autord 1')"};
-      my $cmdautooff = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction $c 0 setreading $dswname $autord 0')"};
-      my $implan     = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction $c 0 consumerImmediatePlanning $c')"};
+      my $cmdon      = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=set $name clientAction $c 0 set $dswname $oncom')"};
+      my $cmdoff     = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=set $name clientAction $c 0 set $dswname $offcom')"};
+      my $cmdautoon  = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=set $name clientAction $c 0 setreading $dswname $autord 1')"};
+      my $cmdautooff = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=set $name clientAction $c 0 setreading $dswname $autord 0')"};
+      my $implan     = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=set $name clientAction $c 0 consumerImmediatePlanning $c')"};
 
       if ($ftui eq "ftui") {
           $cmdon      = qq{"ftui.setFhemStatus('set $name clientAction $c 0 set $dswname $oncom')"};
@@ -12793,7 +12800,7 @@ sub _graphicConsumerLegend {
       $pstate =~ s/\s+/&nbsp;/gxs         if($caicon eq "times");
 
       if ($clink) {
-          $calias = qq{<a title="$cname" href="$FW_ME$FW_subdir?detail=$cname" style="color: inherit !important;" target="_blank">$c - $calias</a>};
+          $calias = qq{<a title="$cname" href="$::FW_ME$::FW_subdir?detail=$cname" style="color: inherit !important;" target="_blank">$c - $calias</a>};
       }
 
       if ($caicon ne "none") {
diff --git a/fhem/contrib/DS_Starter/76_SolarForecast.pm b/fhem/contrib/DS_Starter/76_SolarForecast.pm
index c79d69c7c..08a7c44cf 100644
--- a/fhem/contrib/DS_Starter/76_SolarForecast.pm
+++ b/fhem/contrib/DS_Starter/76_SolarForecast.pm
@@ -128,8 +128,6 @@ BEGIN {
           sunset_abs_dat
           FW_cmd
           FW_directNotify
-          FW_ME
-          FW_subdir
           FW_pH
           FW_room
           FW_detail
@@ -157,6 +155,7 @@ BEGIN {
 
 # Versions History intern
 my %vNotesIntern = (
+  "1.29.1" => "17.06.2024  fix Warnings, Forum: https://forum.fhem.de/index.php?msg=1315283, fix roofIdentPair ",
   "1.29.0" => "16.06.2024  _setreset: improve reset consumerMaster ".
                            "tranformed setter moduleAzimuth to setupStringAzimuth ".
                            "tranformed setter moduleDeclination to setupStringDeclination ".
@@ -575,6 +574,7 @@ my %hset = (                                                                # Ha
   pvCorrectionFactor_21     => { fn => \&_setpvCorrectionFactor        },
   pvCorrectionFactor_Auto   => { fn => \&_setpvCorrectionFactorAuto    },
   reset                     => { fn => \&_setreset                     },
+  roofIdentPair             => { fn => \&_setroofIdentPair             },
   setupStringDeclination    => { fn => \&_setstringDeclination         },
   setupStringAzimuth        => { fn => \&_setstringAzimuth             },
   operatingMemory           => { fn => \&_setoperatingMemory           },
@@ -5552,10 +5552,17 @@ sub _attrRoofTops {                      ## no critic "not used"
           }
       }
 
-      return if(_checkSetupNotComplete ($hash));                                      # keine Stringkonfiguration wenn Setup noch nicht komplett
+      my @istrings = split ",", AttrVal ($name, 'setupInverterStrings', '');                          # Stringbezeichner
 
-      #my $ret = createStringConfig ($hash);
-      #return $ret if($ret);
+      if (!@istrings) {
+          return qq{Define all used strings with command "attr $name setupInverterStrings" first.};
+      }
+
+      while (my ($strg, $pp) = each %$h) {
+          if (!grep /^$strg$/, @istrings) {
+              return qq{The stringname '$strg' is not defined as valid string in attribute 'setupInverterStrings'};
+          }
+      }
   }
   
   InternalTimer (gettimeofday() + 3, 'FHEM::SolarForecast::writeCacheToFile', [$name, 'plantconfig', $plantcfg.$name], 0);   # Anlagenkonfiguration File schreiben
@@ -11415,7 +11422,7 @@ sub entryGraphic {
   my $html_end   = AttrVal ($name, 'graphicEndHtml',   undef);                             # beliebige HTML Strings die nach der Grafik ausgegeben werden  my $w          = $width * $maxhours;                                                     # gesammte Breite der Ausgabe , WetterIcon braucht ca. 34px
   my $w          = $width * $maxhours;                                                     # gesammte Breite der Ausgabe , WetterIcon braucht ca. 34px
   my $offset     = -1 * AttrNum ($name, 'graphicHistoryHour', $histhourdef);
-  my $dlink      = qq{<a href="$FW_ME$FW_subdir?detail=$name">$alias</a>};
+  my $dlink      = qq{<a href="$::FW_ME$::FW_subdir?detail=$name">$alias</a>};
 
   if (!$gsel) {
       $gsel = AttrVal ($name, 'graphicSelect', 'both');                                    # Auswahl der anzuzeigenden Grafiken
@@ -11671,7 +11678,7 @@ sub _checkSetupNotComplete {
 
   my $pv0   = NexthoursVal ($hash, 'NextHour00', 'pvfc', undef);                          # der erste PV ForeCast Wert
 
-  my $link   = qq{<a href="$FW_ME$FW_subdir?detail=$name">$name</a>};
+  my $link   = qq{<a href="$::FW_ME$::FW_subdir?detail=$name">$name</a>};
   my $height = AttrNum ($name, 'graphicBeamHeightLevel1', 200);
   my $lang   = getLang ($hash);
 
@@ -11691,7 +11698,7 @@ sub _checkSetupNotComplete {
 
   ## Anlagen Check-Icon
   #######################
-  my $cmdplchk = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=get $name plantConfigCheck', function(data){FW_okDialog(data)})"};
+  my $cmdplchk = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=get $name plantConfigCheck', function(data){FW_okDialog(data)})"};
   my $img      = FW_makeImage('edit_settings@grey');
   my $chkicon  = "<a onClick=$cmdplchk>$img</a>";
   my $chktitle = $htitles{plchk}{$lang};
@@ -11838,7 +11845,7 @@ sub _graphicHeader {
          $lup = "$day.$month.$year&nbsp;$time";
       }
 
-      my $cmdplchk = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=get $name plantConfigCheck', function(data){FW_okDialog(data)})"};          # Plant Check Button generieren
+      my $cmdplchk = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=get $name plantConfigCheck', function(data){FW_okDialog(data)})"};          # Plant Check Button generieren
 
       if ($ftui eq 'ftui') {
           $cmdplchk = qq{"ftui.setFhemStatus('get $name plantConfigCheck')"};
@@ -12065,7 +12072,7 @@ sub _graphicHeader {
       ## erste Header-Zeilen
       #######################
       my $alias = AttrVal ($name, "alias", $name );                                               # Linktext als Aliasname
-      my $dlink = qq{<a href="$FW_ME$FW_subdir?detail=$name">$alias</a>};
+      my $dlink = qq{<a href="$::FW_ME$::FW_subdir?detail=$name">$alias</a>};
 
       $header  .= qq{<tr>};
       $header  .= qq{<td colspan="1" align="left"                    $dstyle> <b>$dlink</b>              </td>};
@@ -12147,7 +12154,7 @@ sub __createUpdateIcon {
   my $upstate = ReadingsVal ($name, 'state',         '');
   my $naup    = ReadingsVal ($name, 'nextCycletime', '');
 
-  my $cmdupdate = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction - 0 get $name data')"};                               # Update Button generieren
+  my $cmdupdate = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=set $name clientAction - 0 get $name data')"};                               # Update Button generieren
 
   if ($ftui eq 'ftui') {
       $cmdupdate = qq{"ftui.setFhemStatus('set $name clientAction - 0 get $name data')"};
@@ -12225,7 +12232,7 @@ sub __createQuaIcon {
   my ($pcf,$pcq) = split "/", $pvcorrf00;
   my $pvcanz     = qq{factor: $pcf / quality: $pcq};
 
-  my $cmdfcqal = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=get $name forecastQualities imgget', function(data){FW_okDialog(data)})"};
+  my $cmdfcqal = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=get $name forecastQualities imgget', function(data){FW_okDialog(data)})"};
 
   if ($ftui eq 'ftui') {
       $cmdfcqal = qq{"ftui.setFhemStatus('get $name forecastQualities imgget')"};
@@ -12753,11 +12760,11 @@ sub _graphicConsumerLegend {
       my $autord                  = ConsumerVal ($hash, $c, 'autoreading', '');                     # Readingname f. Automatiksteuerung
       my $auto                    = ConsumerVal ($hash, $c, 'auto',         1);                     # Automatic Mode
 
-      my $cmdon      = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction $c 0 set $dswname $oncom')"};
-      my $cmdoff     = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction $c 0 set $dswname $offcom')"};
-      my $cmdautoon  = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction $c 0 setreading $dswname $autord 1')"};
-      my $cmdautooff = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction $c 0 setreading $dswname $autord 0')"};
-      my $implan     = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction $c 0 consumerImmediatePlanning $c')"};
+      my $cmdon      = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=set $name clientAction $c 0 set $dswname $oncom')"};
+      my $cmdoff     = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=set $name clientAction $c 0 set $dswname $offcom')"};
+      my $cmdautoon  = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=set $name clientAction $c 0 setreading $dswname $autord 1')"};
+      my $cmdautooff = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=set $name clientAction $c 0 setreading $dswname $autord 0')"};
+      my $implan     = qq{"FW_cmd('$::FW_ME$::FW_subdir?XHR=1&cmd=set $name clientAction $c 0 consumerImmediatePlanning $c')"};
 
       if ($ftui eq "ftui") {
           $cmdon      = qq{"ftui.setFhemStatus('set $name clientAction $c 0 set $dswname $oncom')"};
@@ -12793,7 +12800,7 @@ sub _graphicConsumerLegend {
       $pstate =~ s/\s+/&nbsp;/gxs         if($caicon eq "times");
 
       if ($clink) {
-          $calias = qq{<a title="$cname" href="$FW_ME$FW_subdir?detail=$cname" style="color: inherit !important;" target="_blank">$c - $calias</a>};
+          $calias = qq{<a title="$cname" href="$::FW_ME$::FW_subdir?detail=$cname" style="color: inherit !important;" target="_blank">$c - $calias</a>};
       }
 
       if ($caicon ne "none") {