Also, habe mal getestet und getüftelt.
Dein Script hat bei mir irgendwie immer wieder das Gegenteil getoggelt, also Schalter drücken - Licht an, nach kurzer Zeit (ca. 1 Sek) Licht wieder aus.
Aber: Dein Script hat mir den Weg geleuchtet. Wo ich selbst noch am rumbasteln war, um mir eine eigene Semaphore zu bauen (die dann aber gleichzeitig ein „Last Run mit Parameter [ID]“ gespeichert hätte, hat mich Dein Script auf die Idee gebracht, die IPS Semaphoren zu benutzen.
Über eine empfindliche Schwachstelle dieser Methode (wiederholen des Sendebefehls) bin ich per Zufall gestossen, weil ich zwei Geräte unterschiedlichen Namens mit derselben FS20 Adresse belegt hatte (was ja vorkommen kann).
Sind diese beiden Geräte „out of synch“, dann toggeln sie sich gegenseitig und es kommt zu sehr seltsamem Verhalten.
Besonders dramatisch ist das bei den Steckdosen. Irgendwie sind die wohl schneller (oder langsamer) als andere Emfänger, jedenfalls ergab sich da ein „Stottereffekt“.
Hier mal mein Script in Version 0.1. Lauffähig (ein paar -zig mal getestet) aber noch nicht ganz fertig, weil ich im Moment nur die Statusvariable behandle und nicht den Fall abprüfe, ob Intensity oder Data gegsetzt wurde.
Mal sehen, wann ich dazu komme, das noch einzubauen.
<?
/*******************************************************************************
GLOBAL SCRIPT:
SHOULD BE INVOKED ON USE OF ANY FS20 SYSTEM COMPONENT
SENDS OUT LAST STATUS AGAIN
!! BE SURE TO HAVE THE EVENTS SET ACCORDINGLY !!
!! PROBLEMS CAN OCCUR IF TWO DEVICES SHARE THE SAME FS20 ADRESS!!
!! IF OUT OF SYNCH THE WILL TOGGLE EACH OTHER WITH ODD RESULTS!!
Version: 0.1
Author: JW
Last Edit: 2009-10-04
Caveats:
At the moment, this script does ONLY adress the TOGGLE and ON/OFF commands of s sender
NOT COVERED YET:
- Timer Events
- Dimm telegrams
- Key pressed long (Data =18)
*******************************************************************************/
// SIMULATE EVENT VARIABLE IF RUN BY USER FROM CONSOLE - FOR TEST PURPOSE
if ($IPS_SENDER == "Execute") {
echo "Running from Execute";
$IPS_VARIABLE = 36112 /*[9-Test\zzFS20-TestGerät 4CH - 2331\Status]*/;
$IPS_SENDER = "Variable";
};
// ############# ADJUST HERE IF NECESARY ####################
// Time the 2nd instance of this script will wait and try again - in an ideal world
// where the FS20 telegram would need no time), this would be at least 1 less than RunSleep
// to ensure that it waits less time than the 1st instance would take to finish it's work
// In the real world, we need to have a difference of some ms to ensure the send of a telegram
// will be thru before we release the semaphore
// !! This "base time" will need to be increased when Repeaters are in the air !!
$RunSemaphoreTimeOut = 200;
// Have a break until the FS20 telegram will be sent.
// Add time here if Repeaters are installed
$RunSleep = $RunSemaphoreTimeOut + 300;
// Time the 2nd instance of this script will wait until the report is written to the logfile
// This is just to make sure the report of the 2nd (timed out) script will be before the 1st one
$RunSleepTimeout = $RunSleep + 50;
// ############# ADJUST HERE END ####################
/*******************************************************************************
// EVENT - SCRIPT DO NOT CHANGE AFTER THIS LINE
*******************************************************************************/
$ScriptID = $IPS_SELF; // ID of this script
$ScriptName = IPS_GetName($ScriptID);
$InvokerEventID = $IPS_EVENT; // ID of the event that invoked the script
$InvokerType = $IPS_SENDER; // What type invoked the script i.e. "Variable" / "TimerEvent"
$InvokerVarID = $IPS_VARIABLE; // ID of the variable that invoked the script
$InvokerVarVal = $IPS_VALUE; // Value of the variable when event is triggered (after change)
/* ALTERNATIVE USE vs. IPS_TRIGGER ???
$InvokerEvent = IPS_GetEvent( $InvokerEventID); // Infos about the event
$InvokerTrigger = $InvokerEvent["TriggerType"];
switch ($InvokerTrigger){
case 0: $InvokerTriggerTx = "Update" ; break;
case 1: $InvokerTriggerTx = "Change" ; break;
case 2: $InvokerTriggerTx = "Threshold undercut" ; break;
case 3: $InvokerTriggerTx = "Threshold overstep" ; break;
case 4: $InvokerTriggerTx = "Threshold match" ; break;
}
*/
// TO BE COMPLETED HERE FOR OTHER INVOKER TYPES MAYBE DIFFERENT THINGS TO DO
// SAME MAY APPLY FOR THE RUNSEND BELOW
// IN THIS SCRIPT; WE NEED TO ADDRESS ALSO IF THE DATA-VAR IS SET TO 18 IF KEY IS PRESSED **LONG**
switch ($InvokerType){
case "Variable":
$InvokerVarValTxt = "FALSE";
if( $InvokerVarVal ) $InvokerVarValTxt = "TRUE";
if (true) {
$InvokerVarInfo = IPS_GetObject($InvokerVarID);
$InvokerInstanceID = $InvokerVarInfo["ParentID"];
}
break;
}
$InvokerInstanceName = IPS_GetName($InvokerInstanceID);
// NOW TRY TO DO THE JOB OR WAIT-EXIT
$RunSemaphoreName = "RepeatSemaphore" + $InvokerVarID; // Use a separate semaphore per ID that triggers this script
$RunSend = IPS_SemaphoreEnter($RunSemaphoreName, $RunSemaphoreTimeOut); // Check if no other script instance currently runs on same event
if ($RunSend) {
FS20_SwitchMode($InvokerInstanceID, $IPS_VALUE);
IPS_Sleep($RunSleep);
IPS_SemaphoreLeave($RunSemaphoreName);
$RunMessage = " REPEATED Telegram";
}
else {
$RunMessage = " NO SEND - semaphore timed out";
IPS_Sleep($RunSleepTimeout);
}
$ScrIdentifier = "SCR " . $ScriptName . "[" . $ScriptID . "]";
$ScrMessage = "E-ID: [". $InvokerEventID . "]" . " E-TYPE: [" . $InvokerType .
"] E-INST: [" . $InvokerInstanceName .
"] MON: [" . $InvokerVarID . "] VAL: [" . $InvokerVarValTxt .
"] IPS-TRG: [" . $IPS_TRIGGER . "] *** " . $RunMessage . "***";
// PROTOCOL TO LOGFILE
IPS_LogMessage( $ScrIdentifier, $ScrMessage);
// BEEP TO SEND AUDIO ACKNOWLEDGE
IPS_ExecuteEx( "D:/IPS/01 externals/ton.exe", "3500", false, false,1 );
?>