+ Antworten
Seite 1 von 3 1 2 3 LetzteLetzte
Ergebnis 1 bis 10 von 26
  1. #1
    Registriert seit
    Sep 2011
    Ort
    Solingen
    Beiträge
    65

    Standard ShutterControl während Fahrt unterbrechen

    Nabend!
    Ich suche jetzt schon etwas länger und habe auch 1-2 vermutlich nicht funktionierende Konzepte im Kopf:
    wie kann man ein Rollo stoppen, welches durch den ShutterControl an eine bestimmte Position gefahren wird?
    Szenario während: Druck auf Taster fährt das Rollo normalerweise ganz zu. Nach x% drückt man nocheinmal, Rollo hält an. Das ist ja kein Problem...aber wie erklärt man der ShutterControl, dass es sich diese Position merken soll?

    Hintergrund: EnOcean-System mit Eltako FSB12. Die Shuttercontrol läuft, die Taster setzen bisher einfach Position 100 oder 0.

  2. #2
    Registriert seit
    Mar 2010
    Ort
    S-H
    Beiträge
    629

    Hallo,

    auch wenn schon ein wenig her, habe hier (http://www.ip-symcon.de/forum/f50/sh...tml#post139386) das gleiche Problem bzw. die gleiche Anfrage. Allerdings mit Homematic.

    Hast Du da schon eine (zwischenzeitliche) Lösung?
    Gruß Andreas.
    -----------------------------------------------------------------
    IP-Symcon 5.3, Windows x64, 28.11.2019, 321402ec4fe0 - virt. W2k8 R2, CCU2, HM-Funk-und Wired-Komponenten, Tasmota-Geräte, FB7390 (Telefonie), 1-wire-Temp.fühler, Pokeys, RPi, Sophos-UTM, Ubiquiti-APs

  3. #3
    Registriert seit
    Sep 2011
    Ort
    Solingen
    Beiträge
    65

    Nein, noch nicht wirklich, aber eine Idee. Es ist möglich, per Skript auf die gespeicherten Laufzeiten zuzugreifen. Anschliessend kann man bei erneutem Drücken der Taste mit PHP auswerten, wie weit das Teil gefahren ist, den neuen Ist-Zustand schreiben und den Rolladen anhalten.

    Es liesse sich auch so anpassen, dass man bis zum nächsten anzeigbaren Wert der Variable fährt (z.B. 25%).

    Das wird wohl die nächste grössere Baustelle, die ich in der Hütte bearbeite.

  4. #4
    Registriert seit
    Sep 2011
    Ort
    Solingen
    Beiträge
    65

    Ich gehe das Problem derzeit an und ich verspreche, dass es etwas umständlicher ist als gedacht. Aber es funktioniert soweit. Die Skripts zeige ich, wenn ich das aufgeräumt habe. Ausserdem fürchte ich, dass es ein wenig Erklärungsbedarf hat, wenn ihr das Zeug einsetzen möchtet.

    Grundsätzlich funktioniert es so, dass man die Anforderungen (SC_Move()) nicht direkt an die SC sendet, sondern an ein Script, welches alle Rahmenbedingen prüfen kann (darf es überhaupt fahren? Wenn ja, wohin? Fährt es bereits, soll man es anhalten?). Über zur Laufzeit erstellte Variablen wird der Zustand über die Laufzeit hinaus aufrecht erhalten. Zur Steuerung setze ich Timer ein, sonst hat man keine Chance, die Fahrt zu unterbrechen.
    Ich denke, das löst auch das ein oder andere weitere Problem, welches in Bezug auf die Shutter erwähnt wurde (z.B. Abfahrverhinderung mit Nicht-Aktualisieren des Status).

    Ich melde mich, wenns fertig ist.

  5. #5
    Registriert seit
    Sep 2011
    Ort
    Solingen
    Beiträge
    65

    Lightbulb ShutterControl erweitert um Fahrtunterbrechung

    Soo, es ist vollbracht. Ich werde versuchen, die Lösung hier zu präsentieren.
    Dazu werden aber ein paar Anmerkungen notwendig sein, weil unsere IPS-Umgebung vermutlich ein wenig speziell ist.

    Grundsätzlich ist die Lösung in 2 Skripts versteckt: eines stellt ein PHP-Objekt bereit, welches quasi das Umfeld einer ShutterControl-Instanz darstellt und bequem alle möglichen Eigenschaften und Methoden bereitstellt. Vorteil ist die gute Lesbarkeit und Strukturierbarkeit von objektorientierten Ansätzen und auch die gute Zugänglichkeit von Daten bei der Verwendung in eigenen Skripts.

    Ziel ist, dass ein Shutter bei Druck auf die obere Taste z.B. nach ganz oben fahren will, aber bei einem Druck auf die andere Taste während der Fahrt der Shutter an der nächsten der Standardposition anhält.

    Zuerst gibts mal die Objektdefinition, die bei mir in einem Skript steht, welches vom 2.5er autoload automatisch eingebunden wird und daher immer zur Verfügung steht:
    PHP-Code:
    <?
    // Class definition for a shutter actuator
    class actuator_shutter
    // Erweitern um den zugehörigen Antrieb und dessen daten
    // Am Ende erweitern um transiente Info (gerade in Betrieb, aktuelle Fahrrichtung, Fahrzeit)(ermöglicht die Überprüfung beim wiederholten Drücken des Knopfes)

    {
        private 
    $instance_id 0;                            // ID der IPS-Instanz
        
    public $actuator_id 0;
        public 
    $interface_id 0;
        public 
    $position false;                            // Shutter Control StatusVariable Position
        
    public $name "";                                // Shutter Control Name
        
    public $state "unknown";                            // Shutter Actuator active?
        
    public $addEndTime 5;                                // SC adds 5s when going to end position
        
    public $driveTiming;

        
    // These properties are only relevant when shutter is moving:
        
    public $direction false;                            // Shutter moving direction (true: up; false: down)

        // These properties are only relevant when override is set:
        
    public $override false;                            // true, wenn override aktiv

        // Constructor erstellen, der Daten füllt
        
    function __construct() {
            if (
    func_num_args() === 1) {
                
    $this->instance_id func_get_arg(0);
                
    $this->actuator_id SC_GetTransmitDevice($this->instance_id);
                
    $this->interface_id SC_GetHandlerScript($this->instance_id);
                
    $this->getProps();
               }
               else {
                  throw new 
    Exception('Only one argument allowed!');
               }
        }

    // Private functions
        
    private function getProps() {
            
    $this->name IPS_GetName($this->instance_id);
            
    $this->position GetValue(IPS_GetStatusVariableID($this->instance_id"StatusVariable"));

            
    $event_id = @IPS_GetEventIDByName("StopTimer"$this->actuator_id);
            if (
    $event_id !== false) {
                
    $this->state "moving";
            }
            else {
                
    $this->state "idle";
            }

            
    $this->direction GetValue(IPS_GetStatusVariableID($this->actuator_id"StatusVariable"));
            
    $this->getDriveTiming($this->direction);                // Get drive timings of current direction

            
    $override_id = @IPS_GetVariableIDByName("Override"$this->actuator_id);
            if (
    $override_id !== false) {                        // Override state hat highest priority
                
    $this->state "override";
            }
        }

        private function 
    getDriveTiming($direction) {
            
    $info IPS_GetVariableProfile("~ShutterAssociation");            // Select the position definition used in this environment (may be changed by user)
            
    if ($direction) {                            // driving up
                
    $timing SC_GetDriveUpTimings($this->instance_id);
                foreach (
    $info['Associations'] as $value) {
                    
    $pos $value['Value'];
                    switch (
    $pos) {
                        case 
    100$timings[$pos] = 0; break;
                        case 
    99$timings[$pos] = $timing['Down']; break;
                        case 
    0$timings[$pos] = $timing['Open'] + $this->addEndTime; break;
                        default:
                            if (
    $pos <= 50) {
                                
    $timings[$pos] = $pos 50 * ($timing['Half'] - $timing['Open']) + $timing['Open'];
                            }
                            else {

                                
    $timings[$pos] = ($pos 50 1) * ($timing['Down'] - $timing['Half']) + $timing['Half'];
                            }
                            break;
                    }
                }
            }
            else {                                    
    // driving down
                
    $timing SC_GetDriveDownTimings($this->instance_id);
                foreach (
    $info['Associations'] as $value) {
                    
    $pos $value['Value'];
                    switch (
    $pos) {
                        case 
    99$timings[$pos] = $timing['Down']; break;
                        case 
    100$timings[$pos] = $timing['Close'] + $this->addEndTime; break;
                        default:
                            if (
    $pos <= 50) {
                                
    $timings[$pos] = $pos 50 $timing['Half'];
                            }
                            else {
                                
    $timings[$pos] = ($pos 50 1) * ($timing['Down'] - $timing['Half']) + $timing['Half'];
                            }
                            break;
                    }
                }
            }
            
    $this->driveTiming $timings;                        // Save as property
        
    }

        private function 
    setStopTimer($target_time) {
        
    // Funktion erstellt oder aktualisiert den Anhaltetimer

            
    $id_timer = @IPS_GetEventIDByName("StopTimer"$this->actuator_id);    // Search for an event named StopTimer on the actuator
            
    if ($id_timer === false) {                        // Neuen Timer anlegen
                
    $id_timer IPS_CreateEvent(1);                    // Create new cyclic event
                
    IPS_SetName($id_timer"StopTimer");                // Set new name - always the same
                
    IPS_SetParent($id_timer$this->actuator_id);            // Attach the event to the corresponding actuator
                
    IPS_SetEventCyclic($id_timer000000);        // Run single event
                
    IPS_SetEventScript($id_timer"IPS_RunScriptEx($this->interface_id, array(\"INSTANCE\" => $this->instance_id));");
                
    IPS_SetEventActive($id_timertrue);                // Activate the timer.
            
    }
            
    IPS_SetEventCyclicTimeBounds($id_timer$target_time0);        // Set time some seconds away from now
        
    }
        public function 
    clearStopTimer() {                        // Called by interface script
            
    $id_timer = @IPS_GetEventIDByName("StopTimer"$this->actuator_id);
            
    IPS_DeleteEvent($id_timer);
            
    $override_id = @IPS_GetVariableIDByName("Override"$this->actuator_id);// 
            
    if ($override_id !== false) { IPS_DeleteVariable($override_id); }
        }

        private function 
    startShutter($position) {
            
    // Check the validity of target position and direction
            
    if ($position == $this->position) { return true; }            // nothing to do.
            
    SC_Move($this->instance_id$position);                    // Erlaubnis, die SC zu triggern.

            
    if ($position $this->position) { $newDirection true; }        // up
            
    else { $newDirection false; }                        // down
            
            
    $this->getDriveTiming($newDirection);                    // Read the corresponding timing from SC instance
            
    $runtime time() + $this->driveTiming[$position] - $this->driveTiming[$this->position];            // Fahrzeit zu "jetzt" addieren
            
    $this->setStopTimer($runtime);
            return 
    true;
        }

        private function 
    interruptShutter($position) {
            
    // Aktuelle Position bestimmen, Timer updaten, override aktivieren und SC aufrufen.
            
    $event_id = @IPS_GetEventIDByName("StopTimer"$this->actuator_id);
            if (
    $event_id !== false && $position != $this->position) {        // Wenns fährt und nicht dahin, wo wir schon hinfahren
                
    $targetPos $this->position;                    // Set current target as initial destination
                
    $info IPS_getEvent($event_id);
                
    $stopduration $info['CyclicTimeFrom'] - time();        // Duration until stop event
                
                
    $targetTime $this->driveTiming[$this->position];        // Initial duration to target
                
    asort($this->driveTiming);
                    
                
    reset($this->driveTiming);                    // Set pointer to the beginning...jedenfalls fürs runterfahren..
                
    while (1) {
                    
    $test current($this->driveTiming);
                    
    $compare = ($targetTime $test +1) - $stopduration;    // +1 ist Toleranz zum durchfahren...
                    
    if ($compare 0) {
                        
    $targetPos key($this->driveTiming);
                        break;
                    }

                    if (!
    next($this->driveTiming)) { break; }        // Stop if all positions checked.
                
    }
                if (
    $targetPos != $this->position) {
                    
    $override_id IPS_CreateVariable(0);            // Create Boolean override signal
                    
    IPS_SetName($override_id"Override");            // Set the name...
                    
    IPS_SetParent($override_id$this->actuator_id);    // Set the hierarchy...
                    
    SetValueBoolean($override_idtrue);            // And set true.

                    
    $this->setStopTimer(time() + round(abs($compare)) + 1);    // Update the timer

                    
    SC_move($this->instance_id$targetPos);        // Call the SC instance
                
    }
            }
            return 
    true;
        }

    // Public functions
        
    function move($position) {                            // No comment
            
    switch ($this->state) {
                case 
    "idle"$this->startShutter($position); break;        // Langeweile -> abfahren.
                
    case "moving"$this->interruptShutter($position); break;    // Oha, schnell anhalten.
                
    case "override": break;                        // Da machen wir schön garnix.
            
    }
            return 
    true;
        }
    }

    function 
    moveShutter($id$position) {
        
    $myShutter = new actuator_shutter($id);
        
    $myShutter->move($position);
        return 
    true;
    }
    ?>
    In eurem Variablenevent oder einer Standardaktion muss nur noch die Funktion moveShutter(id, zielposition) aufgerufen werden und los gehts.

    Der entsprechende Interface-Skript vereinfacht sich ein wenig. Ich habe es abgespeckt auf den Einsatz von EnOcean. Die anderen Systeme lassen sich aber vermutlich recht easy wieder hinzufügen. Wie bei jeder Timer-basierten Lösung kann das Skript von zwei Dingen gestartet werden: RunScript und ShutterControl.

    PHP-Code:
    <?

    //Variables provided by ShutterControl Module
    //IPS_LogMessage("InstanceID", $_IPS['INSTANCE']); /* InstanceID of the actuator! */
    //IPS_LogMessage("Direction", $_IPS['DIRECTION']); /* {0..2} Stop, Up, Down */
    //IPS_LogMessage("Duration", $_IPS['DURATION']); /* ms */

    //Modified By Markus Loeben 2010
    //Modified by Tobias Schluer, 2011 for local EnOcean Equipment
    //Modified by Tobias Schluer, 2012 for new features (event driven and interrupt)

    switch ($_IPS['SENDER']) {
        case 
    "ShutterControl":
            
    define("SC_DIRECTION_STOP"0);
            
    define("SC_DIRECTION_UP"1);
            
    define("SC_DIRECTION_DOWN"2);

            
    $info IPS_GetInstance($_IPS['INSTANCE']);
            
    $direction GetValue(IPS_GetStatusVariableID($_IPS['INSTANCE'], "StatusVariable"));
            
    $override = @IPS_GetVariableIDByName("Override"$_IPS['INSTANCE']);
            if (
    $override !== false) { break; }                                          // Abbrechen, wenn es einen Override hat
                
    switch($info['ModuleInfo']['ModuleID']) {
                     case (
    "{8492CEAF-ED62-4634-8A2F-B09A7CEDDE5B}" || "{FD46DA33-724B-489E-A931-C00BFD0166C9}"): //EnOcean RCM100 || Eltako Switch
                        
    switch($_IPS['DIRECTION']) {                                      // Wunschrichtung der SC
                            
    case SC_DIRECTION_UP:
                                
    ENO_SwitchMode($_IPS['INSTANCE'], true);                            // Taster "oben" simulieren für Öffnen
                                
    break;
                            case 
    SC_DIRECTION_DOWN:
                                
    ENO_SwitchMode($_IPS['INSTANCE'], false);                      // Taster "unten" simulieren für Schliessen
                                
    break;
                            case 
    SC_DIRECTION_STOP:
                                
    ENO_SwitchMode($_IPS['INSTANCE'], $direction);                   // Anhalten Taster in gleiche Richtung
                                
    break;
                      }
                      break;
                    default: die(
    "No supported module used.");
                }
            break;
        case 
    "RunScript":
            
    $mySC = new actuator_shutter($_IPS['INSTANCE']);
            
    $info IPS_GetInstance($mySC->actuator_id);
            switch(
    $info['ModuleInfo']['ModuleID']) {
                 case (
    "{8492CEAF-ED62-4634-8A2F-B09A7CEDDE5B}" || "{FD46DA33-724B-489E-A931-C00BFD0166C9}"): //EnOcean RCM100 || Eltako Switch
                  
    ENO_SwitchMode($mySC->actuator_id$mySC->direction);                //FSA12 stoppen bei gleicher Richtung
                    
    $mySC->clearStopTimer();
                    break;
            }
           break;
        default: die(
    "Script may only be called by ShutterControl or RunScript!");
    }
    ?>
    Probierts mal ein wenig aus. Bei Bedarf helfe ich gerne weiter. Bin grad schreibfaul.

    Grüsse,
    Tobias

    PS: grundsätzlich wäre es natürlich geil, wenn die ShutterControl-Instanz diese Funktionalität direkt implementieren würde...die Möglichkeiten wären vermutlich alle vorhanden.
    Geändert von schluer (01.05.12 um 19:44 Uhr)

  6. #6
    Registriert seit
    Sep 2011
    Ort
    Solingen
    Beiträge
    65

    Am Wochenende konnte ich ein paar Tests mit der neuen Steuerungen machen. Dabei fiel eine zu kurze Fahrzeit beim Interrupt auf.

    In der Funktion interruptShutter() wurde eine Zeile angepasst:
    PHP-Code:
    $this->setStopTimer(time() + round(abs($compare)) + 1);    // Update the timer 

  7. #7
    Registriert seit
    Nov 2016
    Ort
    Bockenem westlicher Harzrand
    Beiträge
    162

    Standard Immer noch (4.1) up to date ?

    Hallo Schluer,

    ich bin erst vor relativ kurzer Zeit neu zu IPS gestossen. Deshalb möchte ich darum bitten meine Unerfahrenheit zu entschuldigen. Eines meiner Hauptanliegen ist die zentrale Steuerung meiner Rolläden mit Hilfe von IPS. Da ich im Haus eine vollständig eigenkreierte Ansteuerung der Rolläden implementiert habe, habe ich mich zunächst damit beschäftigt diese Hardwaremäßig anzubinden. Das ist mir mittlerweile gelungen und mit einem modifiziertem Shutter Script kann ich meine Rolläden zum Öffnen und Schließen bewegen. Alles gut soweit. Nur leider ist es auch aus meiner Sicht so, dass dem Standard Script wesentliche Möglichkeiten fehlen.
    Die offensichtlich aber durch deine Lösung nachgereicht werden. Eine deutliche Aufwertung also...
    Da du ja geschrieben hast bei Bedarf gerne weiterzuhelfen... nun ja der ist da.. :-)

    Einige Fragen hätte ich da schon...

    - Erstens das mit dem Autoload deiner Klasse. Leider konnte ich in der Doku nichts dazu finden. Könntest du die notwendigen Schritte näher erleutern, wie ich die Klasse in IPS integriere... oder falls ich etwas in der Doku übersehen habe, mich darauf stoßen...

    - Zweitens, ich kann gerade nicht erkennen, wie in deinem Ersatz Shutter Script (das zweite also...) im Case Fall 'ShutterControl' bezug auf deine Klasse genommen wird. Weil du ja im Gegensatz zu 'RunScript' ein neues Objekt, deiner Klasse instanziirst.
    Dazu gleich noch eine Anfänger Frage... Müssten deine Objekte nicht persistent am Anfang einmal für jeden Rolladen angelegt werden? Das heißt eine Variable in Symcon angelegt werden um die Referenz ID zu speichern....?

    ...ich weiß, ich schwimme gerade ganz gewaltig...

    Lieben Dank...

    Grüße

    Ralf

  8. #8
    Registriert seit
    Dec 2012
    Ort
    Großraum Stuttgart ...
    Beiträge
    887

    Hallo,

    kann mir jemand sagen was das für eine Funktion ist

    SC_GetTransmitDevice


    Gruß

  9. #9
    Registriert seit
    Sep 2011
    Ort
    Solingen
    Beiträge
    65

    Ich habe leider gerade keine Möglichkeit, das Script mit dem aktuellsten IPS zu testen...sehe aber keinen Grund, wieso es nicht gehen sollte. Den Part muss ich also euch überlassen.

    Zu den übrigen Fragen werde ich heute abend eine Antwort posten...nach der Arbeit. :-)
    IPS 3.3 auf Win8.1 auf Intel NUC, 2x Thermokon STC Ethernet, 1x IPS-868, nen Haufen EnOcean-Gedöns von Eltako (FAM14, BiDi) und Thermokon. :-)

  10. #10
    Registriert seit
    Dec 2012
    Ort
    Großraum Stuttgart ...
    Beiträge
    887

    Hi,

    ok passt ... dann warten ich :-) ...

    Gruß

Ähnliche Themen

  1. Shuttercontrol und 2.3
    Von Bernardo71 im Forum Allgemeine Diskussion (2.x/3.x)
    Antworten: 2
    Letzter Beitrag: 19.08.10, 21:16
  2. nur Zeitweises funktionieren von ShutterControl
    Von Rainulf im Forum Skripte, PHP, SQL
    Antworten: 4
    Letzter Beitrag: 11.03.10, 21:57
  3. Shuttercontrol für Dummies
    Von mest im Forum Allgemeine Diskussion (2.x/3.x)
    Antworten: 11
    Letzter Beitrag: 14.05.09, 17:11
  4. ShutterControl
    Von qs9000 im Forum Allgemeine Diskussion (2.x/3.x)
    Antworten: 5
    Letzter Beitrag: 08.02.09, 13:26
  5. WebFront + ShutterControl
    Von sn00py im Forum WebFront
    Antworten: 1
    Letzter Beitrag: 19.01.09, 21:08