Habe schon länger ein kleines Script für FS20 Komponenten geschrieben. Mit der Einführung von MAPPINGs erscheint es mir heute noch ein wenig wertvoller, daher stelle ich es mal hier rein.
Das Script sucht ale FS20 Devices (Aktoren) und gibt deren Adresse, OID und Location Gruppiert nach HomeCode und sortiert nach Adresse aus. Doppelt benutze Adressen haben in dieser Liste schon ein Sternchen.
Wenn eine Device ein Mapping hat (weitere Adressen), so wird das in einer Zusatzzeile ausgegeben. So kann man solche Devices schnell erkennen.
Um die Frage zu beanworten, welche Adresse wo zusätzlich benutzt wird, gibt es den Block „Mappings“, wo dies aufgelistet wird.
Schliesslich werden Dubletten in der Adresse aufgezeigt.
Anpassungen an die individuellen Wünsche bzw. den Output:
1.) Was ausgegeben wird:
$OutputParts --> dort kann angegeben werden, welche Doku gelistet wird: Nur Adressen, Mappings, Dubletten oder alles bzw. mix.
2.) Zeilenformattierung:
Für die Ausgabe habe ich Formatstrings benutzt und pintf(). So kann jeder, ohne im script selbst rumwerkeln zu müssen, die Zeilenausgabe beliebig verändern.
Alle Anpassungen im entsprechend gekennzeichneten Bereich des Scripts.
[Änderung: fehlerhaftes script ersetzt - siehe nachfolgende Diskussion]
// #########################################################################
// FS20 DEVICES INFORMATION LIST
// READS FS20 DEVICES AND LISTS THE USED ADDRESSES
//
// Ver: 2.01
// Author: JW
//
// USES: nothing
// CAVEATS:
// nicht optimales script, da doppelte Verwendung von Arrays &
// Informationen --> kann optimiert auf ein Array werden
//
// Version Information:
// Ver 2.01: fixed bug when no mappings, minor change on output
// #########################################################################
// ******************************* STANDARD HEADER ***************************
$ScriptID = $IPS_SELF; // ID of this script
$ScriptName = IPS_GetName($ScriptID);
$LogMessageIdentifier = "SCR " . $ScriptName . "[" . $ScriptID . "]";
IPS_LogMessage( $LogMessageIdentifier, "Started");
// ******************************* STANDARD HEADER END ************************
// ################# CHANGE HERE ##########################
// DEFINES WHAT OUTPUT WILL BE PRODUCED (AD=Address List // MAP=Mapping List // DBL = Doublett List
$OutputParts = "AD,MAP,DBL";
$SectionDeli = "##########################################################################
";
$SectionDeliTxtFormat = "#%-72s#
";
$NoneFoundMessage = " *** NONE ***
";
// FORMAT STRINGS USED TO DEFINE THE OUTPUT FORMATTING
$HomeCodeLineFormat = "HomeCode: %1s
";
$HomeCodeEndLine = "
";
// LIST OF ADDRESSES WITH OID, LOCATION AND MAPPING
$AdrLineFormat = " Adr: %-5.5s OId: %s Loc: %s
";
$MapLineFormat = " Maps: %1s
";
$MapDeli = " | ";
$AdrOfMapLineFormat = " Adr: %1s is mapped at the following addresses:
";
$AdrUsesMapLineFormat = " --> %1s
";
// LIST OF MULTIPLE USED ADDRESSES
$DoubleLineFirstFormat = "DOUBLE HC: %1s ADR: %2s is used by
";
$DoubleLineNextFormat = " --> OID: %1s Loc: %2s
";
//################## CHANGE END ###########################
$IO_InstanceOIds = IPS_GetInstanceListByModuleType(3); // Array of OIDs of all I/O Instances
// ############################################################################
// PT1: LOOP COLLECTING & FORMATTING INFORMATION
// ############################################################################
$i=1;
foreach($IO_InstanceOIds AS $OId):
$Instance = IPS_GetInstance($OId);
$InstanceModuleInfo = $Instance['ModuleInfo'];
$InstanceModuleName = $InstanceModuleInfo['ModuleName'];
if ($InstanceModuleName == "FS20"):
$MyArray[$i]["Mapping"] = "";
// GET DEVICE INFORMATION (ADRESS, HOMECODE etc)
$DeviceAddress = FS20_GetDeviceAddress($OId);
$HomeCode = $DeviceAddress['HomeCode'];
$AddressGroup = $DeviceAddress['Address'];
$AddressItem = $DeviceAddress['SubAddress'];
$AddressFull = $AddressGroup . $AddressItem;
$DeviceLocation = IPS_GetLocation($OId);
$NewIndexKey = $HomeCode."-".$AddressFull;
if( $i >1 ): // check only if array exists after first run
$dbl = array_key_exists( $NewIndexKey, $AllAdrArray );
if( $dbl ):
// DOUBLE USED HC / ADR COMBINATION !!!!
$NewIndexKey = $NewIndexKey . "*" . $i;
$AddressFull = $AddressFull . "*" . $i;
endif;
endif;
$AllAdrArray[$NewIndexKey]["HC"] = $HomeCode;
$AllAdrArray[$NewIndexKey]["Adr"] = $AddressFull;
$AllAdrArray[$NewIndexKey]["OId"] = $OId;
$AllAdrArray[$NewIndexKey]["Loc"] = $DeviceLocation;
// STORE LOCATION AND OID
$FS20_Infos[$HomeCode][$AddressFull]["OId"] = $OId;
$FS20_Infos[$HomeCode][$AddressFull]["Loc"] = $DeviceLocation;
// GET ADRESS MAPPING OF ADDITIONAL ADDRESSES FOR THE DEVICE
$AddressMapping = $DeviceAddress['Mapping'];
if ( count( $AddressMapping ) >= 1):
foreach( $AddressMapping as $Map):
$AddressMGroup = $Map['Address'];
$AddressMItem = $Map['SubAddress'];
$AddressMFull = $AddressMGroup . $AddressMItem;
$FS20_Infos[$HomeCode][$AddressFull]["MAP"][] = $AddressMFull;
// $MapArr[$HomeCode][$AddressMFull][0] = $AddressMFull;
$MapArr[$HomeCode][$AddressMFull][] = $AddressFull;
endforeach;
endif;
$i++;
endif;
endforeach;
// ############################################################################
// PT2: PRODUCE OUTPUT
// ############################################################################
// ----------------------------------------------------------------------------
// 1st SECTION: ADDRESSES BY HOMECODE
// ----------------------------------------------------------------------------
$Identifier = "AD";
$do = stripos( $OutputParts, $Identifier );
if( $do===false ):
goto MAP;
endif;
printf($SectionDeli);
printf($SectionDeliTxtFormat, " ADDRESSES");
printf($SectionDeli);
ksort( $FS20_Infos );
//print_r( $FS20_Infos);
// EACH HOMECODE USED WILL GIVE ONE SUBSECTION --> OUTER LOOP
$HomeCodes = array_keys( $FS20_Infos );
foreach( $HomeCodes as $HomeCode ):
printf($HomeCodeLineFormat, $HomeCode);
$FS20_InfosOfHomeCode = $FS20_Infos[$HomeCode];
//print_r( $FS20_InfosOfHomeCode);
// PRINT INFO FOR EACH ADDRESS [IN ORDER OF ADRESS BY AZ]
ksort( $FS20_InfosOfHomeCode );
$AddressesOfHomeCode = array_keys( $FS20_InfosOfHomeCode );
foreach( $AddressesOfHomeCode as $Address ):
$FS20_InfoOfAddress = $FS20_InfosOfHomeCode[$Address];
printf($AdrLineFormat, $Address, $FS20_InfoOfAddress["OId"], $FS20_InfoOfAddress["Loc"]);
//print_r( $FS20_InfoOfAddress);
// EACH ADDRESS MIGHT HAVE A SUBSECTION IF MAPPING, IF SO PRINT AS ONE LINE
if ( array_key_exists( "MAP", $FS20_InfoOfAddress ) ):
$AddressMapping = $FS20_InfoOfAddress['MAP'];
if ( count( $AddressMapping ) >= 1):
foreach( $AddressMapping as $Map):
$MapStr = $Map . $MapDeli;
endforeach;
$MapStr = rtrim($MapStr, $MapDeli);
printf($MapLineFormat, $MapStr);
endif;
endif;
endforeach;
printf($HomeCodeEndLine);
endforeach;
// ----------------------------------------------------------------------------
// 2nd SECTION: ADDRESS MAPPING REVERSED OUTPUT
// ----------------------------------------------------------------------------
MAP:
$Identifier = "MAP";
$do = stripos( $OutputParts, $Identifier );
if( $do===false ):
goto DBL;
endif;
printf($SectionDeli);
printf($SectionDeliTxtFormat, " MAPPINGS");
printf($SectionDeli);
if( ! isset($MapArr ) ):
echo $NoneFoundMessage;
goto DBL;
endif;
ksort( $MapArr );
//print_r( $MapArr);
// EACH HOMECODE USED WILL GIVE ONE SUBSECTION --> OUTER LOOP
$HomeCodes = array_keys( $MapArr );
foreach( $HomeCodes as $HomeCode ):
// loop for all homecodes
printf($HomeCodeLineFormat, $HomeCode);
// get sub-array that holds all addresses that are used as map at other devices
$MapsOfHomeCode = $MapArr[$HomeCode];
ksort( $MapsOfHomeCode );
//print_r( $MapsOfHomeCode);
$AddressesUsedAsMaps = array_keys( $MapsOfHomeCode );
//print_r( $AddressesUsedAsMaps);
foreach( $AddressesUsedAsMaps as $Address ):
// loop for each MAP address
printf($AdrOfMapLineFormat, $Address);
// get sub-array that holds all addresses that use the map address
$MappedAtAddresses = $MapsOfHomeCode[$Address];
// print_r( $MappedAtAddresses);
//PRINT ONE LINE PER DEVICE THAT USES THE MAP ADDRESS
foreach( $MappedAtAddresses as $MappedAt ):
printf($AdrUsesMapLineFormat, $MappedAt);
endforeach;
endforeach;
printf($HomeCodeEndLine);
endforeach;
// ----------------------------------------------------------------------------
// 3rd SECTION: ADDRESSES MULTIPLY USED
// ----------------------------------------------------------------------------
DBL:
$Identifier = "DBL";
$do = stripos( $OutputParts, $Identifier );
if( $do===false ):
goto END;
endif;
printf($SectionDeli);
printf($SectionDeliTxtFormat, " CHECK DOUBLETTS");
printf($SectionDeli);
asort($AllAdrArray);
//print_r($AllAdrArray );
$AdrPrev = 0000;
$HomeCodePrev = 00000000;
$dblcnt=0;
$i=0;
foreach( $AllAdrArray as $Array):
//print_r($Array);
if( ($Array["HC"].substr($Array["Adr"],0,4) ) == ($HomeCodePrev.$AdrPrev) ):
// double use of address
$dblcnt++;
$i++;
if( $dblcnt == 1 ):
// first double --> print previous values
printf($DoubleLineFirstFormat, $HomeCodePrev, $AdrPrev, $OIdPrev, $LocPrev );
printf($DoubleLineNextFormat, $OIdPrev, $LocPrev );
endif;
printf($DoubleLineNextFormat, $Array["OId"], $Array["Loc"] );
else:
$dblcnt=0;
endif;
$HomeCodePrev = $Array["HC"];
$AdrPrev = substr($Array["Adr"],0,4);
$OIdPrev = $Array["OId"];
$LocPrev = $Array["Loc"];
endforeach;
if( $i = 0 ):
echo $NoneFoundMessage;
endif;
END: