Andreas Andy Hofmann

Software-Entwickler, Westernreiter und Home Automator

Ritto Doorbell: Einfach smart gemacht mit Xiaomi Tür-/Fenstersensor

Nachdem ich kläglich gescheitert bin, meine Ritto Türklingel mittels eines ESP inkl. akzeptabler Stromversorgung zu realisieren, kam mir während eines anderen Projekts für smarte Regensensoren (über welches ich später noch berichten werde) endlich die ultimative Idee und damit auch Lösung des Problems.

Seit einiger Zeit nutze ich die (Zigbee) Xiaomi/Aqara Tür-/Fenstersensoren, wofür sie gemacht wurden: *Trommelwirbel* Als Tür-/Fenstersensor!! Für ca. 6€ das Stück auf AliExpress sind diese echt günstig für ein ganz nützliches Stück Hardware: Auf Basis eines kleines Reed-Switches, also einem auf Magnetfeld reagierenden Schalter, übertragen sie immer ihren Status (Auf/Zu) genau dann, wenn er sich ändert. Und das nur mit einer CR2023 Knopfzelle, welche Monate hält!

Und ist das nicht eigentlich genau das, was ich suche, bzw. was ich versucht habe, als Schaltung zu bauen?

  • Jemand klingelt: Statusänderung von “Keiner will was von dir” zu “Dein Paket ist da!”
  • Klingelsignal fällt wieder weg: Statusänderung von “Der Paketmann ist da” zu “Mach schnell, der ist gleich weg!”
  • Und das noch super Batteriesparend!
  • Und dann noch ganz simpel via Zigbee!

Nun müssen wir also einfach den Reed-Switch schalten, wenn wer klingelt! Also häng’ ich ne fette Magnetspule an die 5V direkt neben den Switch?? Nein, Blödsinn! 🙂 Wir machen genau das, was ich in dem Artikel für die Regensensoren gefunden habe: Wir brücken den Reed-Switch einfach und “schalten”, wenn Jemand klingelt. Und das geht ganz simpel mit einem Transistor, an den wir die 5V der Ritto als Base hängen!

Tadaaaaaa: Der ultimative, low cost, batteriesparende, super simple Türsensor!

Die Schaltung dafür ist genau so simpel:

v1 (und final) meines Türklingelsensors auf Basis eines Tür-/Fenstersensors
  • 5V der Ritto gehen an die Base des Transistors
  • Emitter des Transistors and die Plusseite des Sensors (die Seite des Reed-Switches unterhalb der Batterie)
  • Collector des Transistors an die Minusseite des Sensors
  • Und GND der Ritto ziehen wir auch die Minusseite des Sensors, um die Schaltung zu vervollständigen, damit auch Elektronen fließen können 🙂

Basteln!

Zunächst öffnen wir das Gehäuse des Sensors und holen die Platine heraus. Einfach in diese Öffnung mit nem kleinen Schraubenzieher und Aufhebeln:

Leider habe ich kein Foto der Platine mit Reed Switch gemacht, aber ihr kriegt das hin 🙂
Im nächsten Schritt löten wir den eigentlichen Reed-Switch heraus. Das ist für die Schaltung zwar nicht zwingend notwendig, denn wir können ihn auch einfach so überbrücken. Aber der Switch ist ziemlich empfindlich und ich löte ihn lieber raus, um keine falschen Klingelsignale durch Störungen oder dergleichen zu kriegen. Eure Entscheidung 🙂
Wenn ihr diesen rausgelötet habt, sieht das Ganze dann so aus:

Nun löten wir ein Käbelchen an beide Seiten (also wo wir gerade den Reed-Switch abgelötet haben) und verbinden das Ganze dann wie im Diagramm mit Transistor und Ritto. Ich habe immer ein paar kleine, geätzte Platinen zur Hand, die ich mir passen säge und löte das Ganze dann darauf.
Das sieht dann so aus:

Orange geht zur Ritto EXT und schwarz natürlich zur Ritto GND.

Das Ganze könnte man vielleicht noch in das Wohntelefon selber quetschen, aber ich hab mir lieber ein kleines Gehäuse daneben gehangen, welches eigentlich ein Raspberry Pi Gehäuse ist 😉

Das wars, zumindest für den Hardware-Teil. Nun fehlt noch die:

Home Assistant Konfiguration

Da dies ein Zigbee Xiaomi/Aqara Tür-/Fenstersensor ist, müsst ihr diesen auch ganz normal in HA mittels eures Zigbee Coordinators einbinden. Da ich ein Raspbee II Shield und ZHA benutze, geht das bei mir so:

HA => Configuration => Integrations => Zigbee Home Automation (ZHA) => Coordinator auswählen => “Add devices via this device”
Nun drückt ihr einfach alle zwei Sekunden auf den kleinen Schalter am Sensor, solange bis euer Coordinator den Sensor findet. Das dauert ca. 15-20 Sekunden.

Dies legt dann einen “binary_sensor” an, welchen wir in unserer Automation benutzen (Erklärung danach):

- id: doorbell_light_flicker
  alias: "[Apartment] Flicker lights on doorbell and notify"
  trigger:
  - entity_id: binary_sensor.corridor_doorbell_sensor
    platform: state
    to: 'off'
  condition: []
  action:
  - service: script.lights_set_effect_if_online
    data:
      effect: "Doorbell"
  - service: notify.all_phones
    data:
      title: "\ud83d\udd14 Ding Dong!"
      message: "Someone's at the door!"
      data:
        channel: Doorbell

Beim Trigger aufpassen: Der Sensor steht auf “off”, wenn die Tür / das Fenster geschlossen ist, also wenn der Reed-Switch geschaltet wäre. Bei uns ist das also, wenn es klingelt. Daher ist der Trigger “state to off”.

(*Kurzer emotionaler Moment*) Diese Automation ist für mich das Herzstück meines HA, weil es der Start in die Home Automation für mich war. Genau das hier wollte ich haben. Alles andere was danach kam, war einfach weils ging 🙂 Aber zu wissen, wenn wer klingelt, während ich Kopfhörer auf habe, oder die Anlage im Wohnzimmer zu laut ist: Das wollte ich 🙂

Und genau das macht sie:

  1. Lässt alle Lampen, die online sind, “flackern” / einen Effekt abspielen
  2. Schickt meiner Freundin und mir eine Notification aufs Handy.

Da ich die ganze Wohnung voller Yeelights habe, ist das hier der Yeelight Effekt in HA:

custom_effects:
  - name: 'Doorbell'
    flow_params:
      count: 3
      transitions:
        - RGBTransition: [255, 150, 0, 600, 75]
        - RGBTransition: [47, 0, 255, 600, 75]

Und das hier das Script, welches den Effekt für alle Lampen, die an sind abspielen lässt:

lights_set_effect_if_online:
  sequence:
  - service: python_script.lights_set_effect
    data_template:
      lights: >
        {% set lights = namespace(list="") %}
        {%- for light in ["light.bedroom_bedside_lamp_andy", "light.bedroom_bedside_lamp_kristina", "light.dining_room_pendant_light_ambilight", "light.living_room_ceiling_light_ambilight", "light.living_room_big_lamp", "light.living_room_small_lamp", "light.office_desk_lamp"] -%}
          {%- if is_state(light, "on") -%}
            {% set lights.list = lights.list + light + "," %}
          {%- endif -%}
        {%- endfor -%}
        {{ lights.list }}
      effect: "{{ effect }}"

Etwas optimierungsbedürftig ist die hardcoded Liste von Lampen. Aber so oft kauf ich keine neuen Lampen, also vertretbar 🙂

Da HA bis vor ein paar Tagen mit 0.117 in Templates nur Strings und keine Listen verarbeiten konnte, baue ich hier eine kommaseparierte Liste zusammen und schicke diese an ein mini Python-Script:

lights = data.get("lights").rstrip(",")
effect = data.get("effect")

if lights is not "":
  lights = lights.split(",")

  serviceData = {
    "entity_id": lights,
    "effect": effect
  }

  hass.services.call('light', 'turn_on', serviceData)

In den nächsten Tagen werde ich dies wohl abschaffen können, nun da HA nativ Listen in Templates unterstützt.

Und so sieht das dann z.B. auf meinem Bürotisch aus, wenn der Amazonfahrer klingelt 🙂

Hier noch ein Screenshot der Notification auf meinem Smartphone (das “Ding Dong” am Ende vom Video):

Zum Anzeigen des Sensors irgendwo in Lovelace habe ich noch einen kleinen Templatesensor gebaut, der etwas schöner aussieht, als der Sensor selber. Er nutzt den device type “sound”, welcher als eine Musiknote anzeigt wird:

- platform: template
  sensors:
    corridor_doorbell:
        friendly_name: "[Corridor] Doorbell"
        device_class: "sound"
        value_template: >
          {{ is_state("binary_sensor.corridor_doorbell_sensor", "off") }}

Diesen kann man dann einfach in Lovelace anzeigen:

Und das wars! Hoffentlich kann ich Jemandem mit dieser Lösung weiterhelfen 🙂 Wenn ihr Fragen habt, einfach in die Kommentare!

Bis zum nächsten Mal!

Ritto Doorbell: Wie ich kläglich versagte, es nach meinen Vorstellungen zu realisieren

First: This article will soon be available in English as well!

Zuallererst: Dies war mein allererstes Projekt mit dem ESP und seit ca 20 Jahren, dass ich “irgendwas mit Elektronik” gemacht habe.
Mein ESP Code und Wissen waren zu der Zeit sehr beschränkt, genauso wie mein Elektronikwissen.
Das ist aktuell alles besser und ich nutze in meinen Schaltungen bewusster Kondensatoren, etc. Aber zu dem Zeitpunkt dieses Projekts war ich sehr beschränkt!

Und nun: Die meiste Arbeit haben bereits Andere erledigt und ich habe lediglich versucht, deren Arbeit auf mich umzumünzen, bzw. etwas weiterzuentwickeln. Diesen Leuten hier gebührt erstmal Lob:

Bevor wir tiefer einsteigen, ein kurzer Überblick wie das Ganze hier eigentlich funktioniert, was die Leute vor mir schon gebaut haben.

Wie es funktioniert

Der Ritto Twinbus (so nennt sich die Platine / das System des Ritto Wohntelefons) hat einen Verbinder für externe Türklingeln, welche mit ihrem eigenen Extension Modul “Ritto 1764600” angeschlossen werden sollen: https://eref.se.com/de/de/scope/product-pdf/1764600

Dieses Modul brauchen wir (eigentlich) nicht, wir können einfach ein Käbelchen an den EXT und GND Pin löten und das Signal selber verarbeiten. Denn immer wenn Jemand klingelt, liegen an EXT ~5V (wirklich gemessen habe ich 4,937V@0,023A) für ~5 Sekunden an und fällt danach wieder auf 0V ab. 5V wären aber viel zu viel für jeden GPIO eines ESP und wir würden diesen rösten.
Also können wir entweder:

  1. Die 5V auf ~3V reduzieren, z.B. mittels eines simplen Spannungsteilers mithilfe ein paar Widerständen. Oder
  2. Wir nutzen einfach einen Transistor um irgendeinen GPIO (den wir auf PULLUP setzen) auf GND zu ziehen, womit wir keinen Stress mit Umwandeln der Spannung des Ritto haben. Denn die 5V nutzen wir dann einfach an der Base des Transistors.
    Genau so hat es zB auch Peter gemacht.

So sieht das dann aus (Stromversorgung des ESP ignorieren wir hier erst mal, darum gehts hier ja):

v1 meiner Ritto Schaltung, auf Basis von Peter / Robin

Es sei noch darauf hingewiesen, dass es mir lediglich um das Abgreifen des Klingelsignals geht. Peter/Robin haben auch den Türöffner angezapft, aber darum ging es mir nicht.

Die Probleme

Mein eigentliches “Problem” mit den Lösungen von Peter/Robin war, dass ich keine Stromversorgung in der Nähe der Ritto habe, mit der ich den ESP versorgen kann. Und wenn ich versucht habe, die 24V des Ritto anzuzapfen und auf 5V runter zu steppen, hatte ich unfassbare Störgeräusche im Hörer.
Also habe ich mich erstmal damit abfinden wollen, den ESP mit Batterie, bzw. Akkupack zu versorgen. Nur leider zieht der ESP ein kleines Akkupack mit ca 2000mA mal eben in ca 14h leer.
Ich will hier also über zwei Probleme und mein Versagen, diese zu lösen, berichten:

  1. Dauerhafte Stromversorgung des ESP über Ritto selbst
  2. Stromversorgung durch Batterie / Akkupack

1. Dauerhafte Stromversorgung des ESP über Ritto selbst

Zugegeben, habe ich hier leider nicht all zu viel zu berichten, da ich nach erstem Scheitern auch direkt aufgegeben habe, da ich (auch nach einigen Warnungen von anderen Bastlern) nicht irgendwas an der Ritto oder gar an der Hausverkabelung beschädigen wollte. Ich bin gerade erst hier eingezogen, das kommt nich so gut 😉

Ausprobiert habe ich dieses Modul: https://www.berrybase.de/raspberry-pi-co/raspberry-pi/stromversorgung/einbau-industrienetzteilmodule/netzteilmodul-4-5-40v-5v/2a-mit-spannungsanzeige

Der ESP wurde wunderbar versorgt und alles lief auch soweit. Nur wenn man den Hörer abnahm, drohte man an einem Tinitus zu verenden. Also habe ich das mal ganz schnell wieder zurückgebaut und seingelassen.

Ich hatte noch ein wenig geforscht und mit einem Elektrikerkumpel gequatscht. Er meinte, man könnte das Problem mit einer (Schottky)-Diode lösen zwischen Ritto und Netzteilmodul, die die Störspannung dann blockiert. Pure Theorie, habe es nie ausprobiert.

Eine weitere Alternative könnte das Anzapfen einer Steckdose in der Nähe sein und 230V auf 5V runterzuschrauben. Mir erschien das aber irgendwie Overkill und eine Steckdose habe ich leider auch nicht in der Nähe. Aber es ist eine mögliche Lösung.

Hier endet auch schon #1, da ich viel mehr Zeit in #2 gesteckt habe:

[EDIT] Gestern Abend habe ich eine Zeit mit Peter telefoniert und u.A. gerätselt, warum einige Leute (inkl. mir) diese Störgeräusche haben, da er sie eben nicht hat. In meinem konkreten Fall liegt es wahrscheinlich daran, dass ich nicht genau den Spannungswandler benutzt habe, den er nutzt, welcher laut Datenblatt galvanisch getrennt ist. Ich empfehle also jedem, der diese Probleme hat auf jeden Fall genau den Spannungswandler zu nehmen, den er empfohlen hat: Würth Elektronik 177920531 24 V 5 V 0.2 A 1 W
Wenn ihr dann immernoch Störgeräusche habt, lasst es uns/ihn in seinem Blog wissen.

2. Stromversorgung durch Batterie / Akkupack

Das eigentliche Problem ist jedoch nicht zwingend der ESP, sondern unser Code. Diesen haben ich von Peter großteils übernommen mit ein paar Ergänzungen. Zu finden hier: https://github.com/gman-php/esp8266-sketches/blob/master/ritto-doorbell/doorbell.ino

Wie man sieht, ist der ESP die ganze Zeit “wach”, pollt also ununterbrochen GPIO4 und wartet sehnsüchtig darauf, dass Jemand doch klingelt und er etwas tun kann. Da aber bei uns nicht ständig Jemand klingelt, verbrät der ESP also 99,99% der Zeit sinnlos Batterie. Also liegt es ja nahe, die vorhanden Sleep Modi des ESP zu benutzen.

Nach etwas Recherche und ein bißchen Fragerei im ESP8266 Forum, war wohl Deep Sleep die richtige Option. Im Deep Sleep verbraucht der ESP nur ca 20μA, also fast nichts.

Aber auch hier ergeben sich wiedereinmal Challenges:

  1. Den ESP wieder aufwecken, wenn jemand klingelt. Es gibt zwei Wege, wie man den ESP über eine externe Quelle aufwecken kann:
    1. Den RST Pin auf LOW / GND ziehen und wieder loslassen! Der ESP wacht erst auf, wenn man RST wieder “loslässt”!
    2. Denn EN Pin auf HIGH ziehen und wieder loslassen! Denn auch hier: Der ESP wacht erst auf, wenn man EN wieder “loslässt”!
  2. Die setup() Routine dramatisch verkürzen, denn egal ob EN oder RST: Der ESP bootet komplett neu (bei RST offensichtlich, steht “RST” doch für “Reset”), hat also Wi-Fi und alles vergessen.
    Denn wenn setup() noch 3-4 Sekunden dauert, dann ist ggf der DHL Mann schon wieder über alle Berge.

Während ich #2 lösen konnte (Ein extra Artikel wie ich das gemacht habe folgt in Kürze), konnte ich nie #1 lösen. Und das war auch letztlich das Ende für mich für diesen Ansatz.

Für die folgenden Ansätze nehmen wir an, dass wir den Code so verändert haben, dass die komplette Logik aus der loop() Funktion in die setup() verschoben haben und am Ende der setup() den ESP in den Deep Sleep schicken. Wenn der ESP aufwachen würde, rennt er durch die setup(), tut irgendwas, um irgendwen über das Klingeln zu informieren und geht dann wieder schlafen.

Die einfachste und offensichtlichste Schaltung mittels RST liegt ja auf der Hand, nämlich so:

v2, hier versuchen wir den ESP mittels RST aufzuwecken

Also wie unsere v1, nur eben an RST.

Aber: Das funktioniert leider nicht so ganz, denn: Der ESP wird erst aufwachen, wenn RST wieder HIGH geht (so funktioniert der ESP nunmal), also wir ihn loslassen, also: Wenn die 5V an der Ritto wieder abfallen. Und wir haben gelernt, das dauert ca. 5 Sekunden. Sprich: Wir kriegen erst nach 5 + setup() Sekunden mit, dass wer geklingelt hat: Viel zu lang!

Exaktes Problem auch mit EN, nur etwas andere Schaltung, da man EN auf HIGH ziehen muss:

v3, diesmal mit EN

Selbe Kiste: Tuts an sich, nur wacht der ESP erst auf, wenn die 5V wieder abfallen: Zu spät!

Nach etwas Suchen und überlegen fiel mir dann ein, dass die Welt Kondensatoren erfunden hat und man diese für Impulse benutzen kann. Ich bin leider kein Elektriker, sondern Programmierer und mein Elektronikwissen leider sehr eingerostet oder nicht mehr vorhanden. Und Kondensatoren hatten wir sowieso nie in der Schule.

Also mich wieder durch Foren gefragt, mit ziemlich vielen dummen Fragen. Aber leider habe ich es nie geschafft, eine funktionierende Schaltung hinzubekommen. Die Einzige, die am Nächsten kam, war diese:

v4, wieder RST aber mit Kondensator!

Sie funktioniert!! Aber leider nur genau einmal 😉 Denn dann ist der Kondensator aufgeladen und entlädt sich nie wieder, wie man in der Schaltung erkennt: Hat der Kondensator doch keine Verbindung zu GND.

Auch hier habe ich viel rumgefragt und sehr gute Hilfe von Leuten bekommen. Leider habe ich bis heute die zuletzt vorgeschlagene Lösung noch nicht ausprobiert, da ich sie zum Einen nicht korrekt verstanden habe und zum Anderen mir die genannten Kondensatoren fehlten. Irgendwann würde ich es aber mal ausprobieren, rein aus Interesse. Aber vielleicht ist Irgendwer schneller 🙂
Hier der Thread im Arduinoforum: https://www.arduinoforum.de/arduino-Thread-Hilfe-bei-Schaltung-f%C3%BCr-T%C3%BCrklingel?pid=75229#pid75229

Und hier endet auch eigentlich der Artikel, denn wie er schon sagt: Wie ich kläglich scheiterte 🙂 Das Obere ist auch nur die Kurzfassung. Es gibt noch ca 5 weitere Schaltungen mit leichten Veränderungen, die aber alle nichts brachten. Ein paar Wochen habe ich mich durch Foren gefragt und habe nichts wirklich geschafft.

Ich bin danach erstmal wieder auf mein Akkupack zurück und hab es einfach jeden Morgen geladen. Das war zwar fürchterlich frustrierend, aber ich hatte eine smarte Türklingel 😉

Meine finale und absolut geniale und super robuste Lösung auf einem komplett anderen Ansatz habe ich nun auch hier niedergeschrieben: Ritto Doorbell: Einfach smart gemacht mit Aqara Tür-/Fenstersensor

Home Assistant Sensoren und Automations

Natürlich will ich euch trotzdem nicht meine Konfiguration für diese Schaltung vorenthalten, egal welche Version ihr nehmt; letztlich droppen alle einfach eine MQTT Message in ein Topic.

Wie man im Code sieht, wird wenn es klingelt, eine MQTT Message in “home-assistant/doorbell/state” mit der Payload “on” gedroppt.

Vorausgesetzt ihr habt irgendeinen Broker mit HA konfiguriert (z.B. einfach das “Mosquitto broker” add-on), ist dies der Sensor:

binary_sensor:
  - platform: mqtt
    name: "[Corridor] Doorbell"
    device_class: sound
    state_topic: "home-assistant/doorbell/state"
    payload_on: "on"
    payload_off: "off"
    # availability_topic: "home-assistant/doorbell/availability"
    off_delay: 3

Relativ selbsterklärend: Wenn eine Message mit Payload “on” in das Topic droppt, is der Sensor “on” und nach drei Sekunden geht dieser automatisch wieder aus.

Die Automation und dazugehörigen Skripte habe ich heute noch in Benutzung mit meiner aktuellen Superlösung, daher könnt ihr diese im Beitrag über jene Welche finden: Ritto Doorbell: Einfach smart gemacht mit Aqara Tür-/Fenstersensor

Einzige Änderung ist der Trigger, diesen müsst ihr ändern auf:

trigger:
- entity_id: binary_sensor.corridor_doorbell
  platform: state
  to: 'on'

Das wars dann auch eigentlich 🙂 Ich hoffe, ich konnte euch einen Einblick in mein Versagen, meine Findings und meine HA Config geben und hoffe, es hilft irgendwem.
Wenn ihr Fragen / Feedback habt, lasst es mich in den Kommentaren wissen!