+ Antworten
Seite 1 von 2 1 2 LetzteLetzte
Ergebnis 1 bis 10 von 19
  1. #1
    Registriert seit
    Nov 2016
    Beiträge
    167

    Question Chamberlain Garagentor Antrieb + Starter Kit

    Hallo,

    ich wollte euch mal fragen ob das überhaupt möglich wäre.

    Ich habe mit diesen Antrieb gekauft: (Ps. den gibt es nur heute für 165,55 mit Gutschein)

    Chamberlain ML1000EV Premium Garagentorantrieb - Plus.de Online Shop


    Hierzu gibt es das MyQ Starter-Kit womit man das Tor über eine App /Handy/PC /Tablet steuern kann.

    Chamberlain 830REV MyQ Starter-Kit - Plus.de Online Shop

    Jetzt meine Frage wäre es möglich dieses MyQ in IPS einzubinden ? so das ich das Tor über PS steuern kann mit diesem Gateway. Habe keine lust später immer zwischen den Apps hin und Herr zu switchen.

    Vielen Dank.

    Vielleicht hat auch der eine oder andere bereits das Tor in Betrieb und kann mir seine Lösung sagen.

  2. #2
    Registriert seit
    Oct 2014
    Beiträge
    31

    Standard MyQ Gateway

    Hallo zusammen,

    Ich schließe mich, wenn auch schon etwas Zeit vergangen ist, meinem Vorredner an.

    Hat denn jemand von euch bereits eine Lösung gefunden?


    Gruß
    Steffen

  3. #3
    Registriert seit
    Oct 2011
    Ort
    Hattersheim (Hessen)
    Beiträge
    6,596

    Zitat Zitat von SteffenK Beitrag anzeigen
    Hat denn jemand von euch bereits eine Lösung gefunden?
    Ohne da jetzt explizit etwas dafür zu schreiben kannst Du das auf alle Fälle aus IP-Symcon über IFTTT steuern.

    Dazu nimmst Du das IFTTT Modul und MyQ in IFTTT.

  4. #4
    Registriert seit
    Oct 2007
    Ort
    Villach,Kärnten,Österreich
    Beiträge
    2,975

    Hi
    gibts denn keine Hardwarebastler mehr ?
    Einfach einen der Handsender opfern und die entsprechnden Tasten mit einem potentialfreiem Kontakt deines bevorzugten System "drücken".

    Ich hab hier einen älteren Chamberlain, da war ein Taster zur Innenmontage dabei. Dieser wird per 1Wire überbrückt.
    Funktioniert problemlos seit vielen vielen Jahren.

    Alles über zig Server/Dienste/Gateways welche womöglich irgendwo in der Cloud rumschwirren zu steuern ist doch gaga.
    Viel zu anfällig und wartungsintensiv. Heute weißt du was du einrichtest, in fünf Jahren kriegst Haarausfall wenn plötzlich nichts mehr geht.

    Keep it simple, insbesondere bei der Home Automation.

    gruß
    bb

  5. #5
    Registriert seit
    Oct 2011
    Ort
    Hattersheim (Hessen)
    Beiträge
    6,596

    Zitat Zitat von bbernhard Beitrag anzeigen
    Alles über zig Server/Dienste/Gateways welche womöglich irgendwo in der Cloud rumschwirren zu steuern ist doch gaga.
    Viel zu anfällig und wartungsintensiv. Heute weißt du was du einrichtest, in fünf Jahren kriegst Haarausfall wenn plötzlich nichts mehr geht.

    Keep it simple, insbesondere bei der Home Automation.
    Da gebe ich Dir vollkommen Recht dieses ganz Cloud Zeug ist auch immer nur ein Notnagel, vor allem hat man da immer eine Zeitverzögerung drinnen. Nachteil ist halt nicht jeder kann löten und es sollte auch nicht jemand ohne Fachkentniss von elektrischen Schaltungen eine Gehäuse öffnen und das Innenleben modifizieren. Wenn man sich mit so was auskennt ist das aber ganz sicher der zu bevorzugende Weg.

  6. #6
    Registriert seit
    Oct 2010
    Ort
    Schwarzwald-Baar-Kreis
    Beiträge
    93

    Bei mir habe ich ein Sonoff Basic mit Tasmota geflasht und umgebaut, damit der Ausgang potentialfrei ist.
    Der potentialfrei Kontakt ist parallel zum "Tastereingang" am Garagentorantrieb angeschlossen.
    Somit könntest du mit dem Tasmota Modul von Kai dein Garagentor aus IPS öffnen bzw. schließen.

    Sollte noch ein potentialfreier Ausgang am Garagentorantrieb vorhanden sein, welcher bei geöffnetem bzw. geschlossenem Tor geschaltet wird, kann dieser über den GPIO 4 am Sonoff mit abgefragt werden.
    IPS 5.2 Unlimited @ Tinkerboard S | Enocean | TCM310 | FritzBox 6590 | Fritzbox 6490 | Sonos | Tecalor TTL18e | DM 900 UHD | Sonnenbatterie | Philips Hue

  7. #7
    Registriert seit
    Aug 2009
    Ort
    Lippe
    Beiträge
    2,026

    Genau so wie Tkg sagt,
    habe ich auch meine 3 Tore angebunden, aber mit je einem LCN Relais, welches den Taster kurz "überbrückt".
    Da braucht es das ganze Cloud Zeug nicht, und alles ist im lokalem Netz.
    Und Rückmeldung kommt von einem Reedkontakt am Tor, wenn geschlossen. Besser wäre aber beide Endlagen zu überwachen.
    lg Thomas
    IPS Raspberry Pi2(3) mit LCN, HM, Sonoff+Shelly per MQTT, SONOS und viel Eigenbau + Pi2(3) mit Heizungssteuerung über GPIO per IPS

  8. #8
    Registriert seit
    Oct 2014
    Beiträge
    31

    Danke euch erstmal für die Inspirationen. Ein Schaltaktor wäre natürlich eine elegante Alternative, jedoch für mich nicht praktikabel da mit zu viel Aufwand verbunden. Vor allem die Rückmeldung müsste man wie beschrieben erfassen.

    Ich habe eine Lösung mittels PHP und jetzt freier API gefunden. Den Code konnte ich jedoch nur kurz testen. Wenn ich fertig bin, werde ich euch diesen selbstverständlich in den nächsten Tagen hier bereit stellen.
    Aktuell fehlt noch die Rückmeldung, falls die teuflische Cloud mal nicht erreichbar / das Gateway down / oder der Funkkontakt schlicht und einfach abbricht, implementiert ist.

    Vielen Dank
    Steffen

  9. #9
    Registriert seit
    Nov 2016
    Beiträge
    167

    Hi Steffen,

    da wäre ich auch dran interesiert, da ich ebenfalls diese Steuerung von Chamberlain habe.

    Wäre natürlich das non + ultra wenn man die visu von der Webseite mit dem Tor auch ins WF bekommt

  10. #10
    Registriert seit
    Oct 2014
    Beiträge
    31

    Na dann, ich hab da zwar noch ein bisschen mehr mit gemacht aber hier mal alles was man zur korrekten Funktion benötigt.
    So kann man darauf aufbauen und seiner Fantasie freien lauf lassen.


    los geht es mit der Klasse.



    Code:
    <?php
    /**
     * MyQ Klasse
     *
     * open/close/status Funktion
     *
     */
    
    
    const MYQ_DOOR_ACTION_CLOSE = 0;
    
    const MYQ_DOOR_ACTION_OPEN = 1;
    
    const MYQ_DOOR_STATE_UNKNOWN = -1;
    
    const MYQ_DOOR_STATE_OPEN = 1;
    
    const MYQ_DOOR_STATE_CLOSED = 2;
    
    const MYQ_DOOR_STATE_OPENING = 4;
    
    const MYQ_DOOR_STATE_CLOSING = 5;
    
    
    class MyQException extends Exception {}
    
    class MyQState {
    
        protected $_state = MYQ_DOOR_STATE_UNKNOWN;
    
        protected $_stateTime = 0;
    
        protected $_stateDescriptions = array (
            MYQ_DOOR_STATE_UNKNOWN => 'unknown',
            MYQ_DOOR_STATE_OPEN => 'offen',
            MYQ_DOOR_STATE_CLOSED => 'geschlossen',
            MYQ_DOOR_STATE_OPENING => 'wird geöffnet',
            MYQ_DOOR_STATE_CLOSING => 'wird geschlossen',
        );
    
        public function __construct ($state=false, $timestamp=false) {
            if ($state) {
                $this->_state = $state;
            }
            $this->_stateTime = time();
            if ($timestamp) {
                $this->_stateTime = (int)$timestamp / 1000;            
            }
            return $this;
        }
    
        public function __get ($attr) {
            switch ($attr) {
                case 'desc':
                    return $this->_stateDescriptions[$this->_state];
                case 'time':
                case 'updated':
                case 'date':
                    return $this->_stateTime;
                case 'delta':
                    return $this->_getTimeDelta('str');
                case 'seconds':
                    return $this->_getTimeDelta();
            }
            $trace = debug_backtrace();
            trigger_error(
                'Undefined property via __get(): ' . $name .
                ' in ' . $trace[0]['file'] .
                ' on line ' . $trace[0]['line'],
                E_USER_NOTICE);
            return null;
        }
    
        public function __toString () {
            return $this->_stateDescriptions[$this->_state];
        }
    
        private function _getTimeDelta($opt=null) {
            $currentTz = date_default_timezone_get();
            date_default_timezone_set('UTC');
            $delta = time() - $this->_stateTime;
    
            if ($opt != 'str') {
                return $delta;
            }
    
            // Convert delta in human-readable format
            // via https://stackoverflow.com/a/43956977/98030
            $secondsInAMinute = 60;
            $secondsInAnHour = 60 * $secondsInAMinute;
            $secondsInADay = 24 * $secondsInAnHour;
    
            // Extract days
            $days = floor($delta / $secondsInADay);
    
            // Extract hours
            $hourSeconds = $delta % $secondsInADay;
            $hours = floor($hourSeconds / $secondsInAnHour);
    
            // Extract minutes
            $minuteSeconds = $hourSeconds % $secondsInAnHour;
            $minutes = floor($minuteSeconds / $secondsInAMinute);
    
            // Extract the remaining seconds
            $remainingSeconds = $minuteSeconds % $secondsInAMinute;
            $seconds = ceil($remainingSeconds);
    
            // Format and return
            $timeParts = [];
            $sections = [
                'Tag' => (int)$days,
                'Stunde' => (int)$hours,
                'Minute' => (int)$minutes,
                'Sekunde' => (int)$seconds,
            ];
    
            foreach ($sections as $name => $value){
                if ($value > 0){
                    $timeParts[] = $value. ' '.$name.($value == 1 ? '' : 'n');
                }
            }
    
            return sizeof($timeParts) ? implode(', ', $timeParts) : '0 Sekunden';
        }
    
    }
    
    class MyQ {
        
        /** @var string|null $username contains the username used to authenticate with the MyQ API */
        protected $username = null;
    
        /** @var string|null $password contains the password used to authenticate with the MyQ API */
        protected $password = null;
    
        /** @var string|null $appId is the application ID used to register with the MyQ API */
        protected $appId = 'Vj8pQggXLhLy0WHahglCD4N1nAkkXQtGYpq2HrHD7H1nvmbT55KqtN6RSF4ILB/i';
    
        /** @var string|null $securityToken is the auth token returned after a successful login */
        protected $securityToken = null;
    
        /** @var string|null $userAgent is the User-Agent header value sent with each API request */
        protected $userAgent = 'Chamberlain/3.4.1';
    
        /** @var string|null $culture is the API culture code for the API */
        protected $culture = 'en';
    
        /** @var string|null $contentType is the content type used for all cURL requests */
        protected $contentType = 'application/json';
    
        /** @var array $headers contain HTTP headers for cURL requests */
        protected $_headers = array();
    
        protected $_deviceId = null;
    
        protected $_locationName = null;
    
        protected $_doorName = null;
    
        protected $_doorState = null;
    
        protected $_baseUrl = 'https://myqexternal.myqdevice.com/api/v4';
    
        protected $_loginUri = '/User/Validate';
    
        protected $_getDeviceDetailUri = '/UserDeviceDetails/Get';
    
        protected $_putDeviceStateUri = '/DeviceAttribute/PutDeviceAttribute';
    
        /** @var resource|null $_conn is the web connection to the MyQ API */
        protected $_conn = null;
    
        /**
         * Initializes class. Optionally allows user to override variables
         *
         * @param array $params A associative array for overwriting class variables
         *
         * @return MyQ
         */
        public function __construct ($params = array()) {
            // Overwrite class variables
            foreach ($params as $k => $v) {
                $this->$k = $v;
            }
    
            // Initialize cURL request headers
            if (sizeof($this->_headers) == 0) {
                $this->_headers = array (
                    'MyQApplicationId' => $this->appId,
                    'Culture' => $this->culture,
                    'Content-Type' => $this->contentType,
                    'User-Agent' => $this->userAgent,
                );
            }
    
            // Initialize cURL connection
            $this->_init();
    
            return $this;
        }
    
        public function __get ($attr) {
            if ($attr == 'state') {
                return $this->_doorState;
            }
            if (isset($this->$attr)) {
                return $this->$attr;
            }
            $trace = debug_backtrace();
            trigger_error(
                'Undefined property via __get(): ' . $name .
                ' in ' . $trace[0]['file'] .
                ' on line ' . $trace[0]['line'],
                E_USER_NOTICE);
            return null;
        }
    
        public function __set ($attr, $value) {
    
            switch ($attr) {
                case 'open':
                    return ($value) ? $this->open() : $this->close();
                    break;
                case 'close':
                    return ($value) ? $this->close() : $this->open();
                    break;
            }
    
            $trace = debug_backtrace();
            trigger_error(
                'Undefined property via __set(): ' . $name .
                ' in ' . $trace[0]['file'] .
                ' on line ' . $trace[0]['line'],
                E_USER_NOTICE);
            return null;
        }
    
        /**
         * Perform a login request
         *
         * @param string|null $username Username to use when logging in
         * @param string|null $password Password to use for logging in
         *
         * @return MyQ
         */
        public function login ($username = null, $password = null) {
            // Set username/password if not null
            if (!is_null($username)) {
                $this->username = $username;
            }
            if (!is_null($password)) {
                $this->password = $password;
            }
    
            // confirm that we have a valid username/password
            $error = array();
            if (is_null($this->username)) {
                $error[] = 'username';
            }
            if (is_null($this->password)) {
                $error[] = 'password';
            }
            if (sizeof($error) > 0) {
                throw new MyQException('Missing required auth credential: ' . implode(',', $error));
            }
    
            return $this->_login();
        }
    
        public function refresh () {
            $this->_getDetails();
            return $this;
        }
    
        public function open () {
            return $this->_requestState(MYQ_DOOR_ACTION_OPEN);
        }
    
        public function close () {
            return $this->_requestState(MYQ_DOOR_ACTION_CLOSE);
        }
    
        private function _requestState ($action) {
            // Fetch current device information
            $this->_getDetails();
    
            curl_setopt($this->_conn, CURLOPT_CUSTOMREQUEST, 'PUT');
            curl_setopt($this->_conn, CURLOPT_URL, $this->_baseUrl . $this->_putDeviceStateUri);
            $payload = array (
                'AttributeName' => 'desireddoorstate',
                'AttributeValue' => $action,
                'MyQDeviceId' => $this->_deviceId,
            );
            curl_setopt($this->_conn, CURLOPT_POSTFIELDS, json_encode($payload));
            $output = curl_exec($this->_conn);
            $err = curl_error($this->_conn);
    
            if ($err) {
               throw new MyQException("cURL Error #:" . $err);
            }
    
            $data = json_decode($output);
            if ($data == false) {
                throw new MyQException("Error updating device state: $output");
            }
    
            if (strlen($data->ErrorMessage) > 0 || $data->ReturnCode != 0) {
                throw new MyQException("Error returned from API: " . var_export($data));
            }
    
            // Update was successful, fetch the new status and report
            return $this->refresh();
    
        }
    
        private function _init () {
            if (!isset($this->_conn)) {
                $this->_conn = curl_init();
                curl_setopt_array($this->_conn, array (
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_ENCODING => "",
                    CURLOPT_MAXREDIRS => 10,
                    CURLOPT_TIMEOUT => 30,
                    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                    CURLOPT_FAILONERROR => true,
                    CURLOPT_FOLLOWLOCATION => true,
                    CURLOPT_FRESH_CONNECT => true,
                    CURLOPT_FORBID_REUSE => true,
                    CURLOPT_USERAGENT => $this->userAgent,
                ));
            }
            $this->_setHeaders();
        }
    
        private function _setHeaders () {
            $headers = array();
            foreach ($this->_headers as $k => $v) {
                $headers[] = "$k: $v";
            }
            curl_setopt($this->_conn, CURLOPT_HTTPHEADER, $headers);
        }
    
        private function _login () {
            $this->_init();
    
            curl_setopt($this->_conn, CURLOPT_CUSTOMREQUEST, 'POST');
            curl_setopt($this->_conn, CURLOPT_URL, $this->_baseUrl . $this->_loginUri);
    
            $post = json_encode(array('username' => $this->username, 'password' => $this->password));
            curl_setopt($this->_conn, CURLOPT_POSTFIELDS, $post);
            $output = curl_exec($this->_conn);
            $data = json_decode($output);
            if ($data == false || !isset($data->SecurityToken)) {
                throw new MyQException("Error processing login request: $output");
            }
            $this->_headers['SecurityToken'] = $data->SecurityToken;
            return $this;
        }
    
        private function _getDetails ($getState = false, $forceUpdate = false) {
            $this->_init();
    
            // always fetch state info from API. Location data is not expected to have changed
            $cachedLocation = true;
            if ($getState === false && $forceUpdate !== true) {
                // get the location information
                // check to see if we have this information cached already
                if ( $forceUpdate === false && ! (is_null($this->_doorName) || is_null($this->_locationName) ) ) {
                    return;
                }
                $cachedLocation = false;
            }
    
            curl_setopt($this->_conn, CURLOPT_CUSTOMREQUEST, 'GET');
            curl_setopt($this->_conn, CURLOPT_URL, $this->_baseUrl . $this->_getDeviceDetailUri);
    
            $output = curl_exec($this->_conn);
            $data = json_decode($output);
            if ($data == false || !isset($data->Devices)) {
                throw new MyQException("Error fetching device details: $output");
            }
    
            // Find our door device ID
            // (we only look at the first listed device - later we can look for a device by name)
            foreach ($data->Devices as $device) {
                if ( $cachedLocation === false && stripos($device->MyQDeviceTypeName, "Gateway") !== false ) {
                    // Find location name
                    foreach ($device->Attributes as $attr) {
                        if ($attr->AttributeDisplayName == 'desc') {
                            $this->_locationName = $attr->Value;
                        }
                    }
                    continue; // we don't want device info on the location
                }
                
                // we should be looking at just our WGDO unit
                $this->_deviceId = $device->MyQDeviceId;
                
                foreach ($device->Attributes as $attr) {
                    switch ($attr->AttributeDisplayName) {
                        case 'desc':
                            $this->_doorName = $attr->Value;
                            break;
                        case 'doorstate':
                            $this->_doorState = new MyQState($attr->Value, $attr->UpdatedTime);
                            break;
                        default:
                            continue;
                    }
                }
    
                break; // skip any other devices
            }
    
        }
    
    }
    ?>
    (keine Eigenentwicklung, vielen Dank an den Entwickler)

    und hier der Aufruf:

    Code:
    <?php
    
    //absoluter Pfad zur Klasse
    require_once('C:\IP-Symcon\scripts\47161 /*[Scripte\Eigenentwicklung\Garagentor\MyQ-Class]*/.ips.php');
    
    $door = new MyQ();
    $door->login("<EMAIL>", "<Passwort>");
    
    //Aktueller Status ermitteln
    $report = function() {
        global $door;
    	$status = "{$door->refresh()->state}";
    	$zeit = "{$door->state->delta}";
    
    //Variablen für Zustand setzen
    
     $subst = "Garagentor seit $zeit $status";
     setvalue(42271 /*[Wohnung DG\Garage\Garage Status]*/,$subst);
    
    };
    // Current state aufruf
    $report();
    //--------------------
    
    
    //Ein Beispiel Tor öffnen
    $door->open();
    //--------------------
    
    //Ein Beispiel zum Tor schließen
    $door->close = true;
    //--------------------
    
    ?>
    Wenn man jetzt je ein Script für "open", "close" und "status" (alle Sekunden ausführen) erstellt, hat man eigentlich alles was man braucht. Selbstverständlich wird der Status auch bei einem bsp.. per Handsender ausgelösten öffnen aktualisiert.

    Einen Bug gibt es aktuell natürlich auch.
    die Zeiten beim öffnen und schließen (also nur die paar Sekunden bis das Tor in Endstellung ist) werden noch wirr dargestellt. Mich stört dies jedoch nicht, da ich nur offen, geschlossen, öffnen und schließen anzeigen / bzw. per TTS ausgeben lassen.

    und das beste dran. der berühmt berüchtigte WAF kann bei der all abendlichen Ansage "Die Garagentür wird geöffnet" gleich das kühle Blonde bereitstellen. Das schlägt wohl alle Argumente gegen Cloud und Co....


    Bei Fragen, fragen.

    Viel Spaß mit dem Script

    Gruß Steffen
    Geändert von SteffenK (17.01.19 um 22:07 Uhr)

Ähnliche Themen

  1. Antworten: 4
    Letzter Beitrag: 26.09.14, 09:51
  2. Antworten: 11
    Letzter Beitrag: 09.07.13, 10:59
  3. 1-Wire Starter Kit
    Von bronsky im Forum 1-Wire, M-BUS
    Antworten: 6
    Letzter Beitrag: 04.06.07, 12:48