Doorbell Notifier using Python

For this project we are assuming, that you have a Python development environment set up and that you have a rudimentary understanding of the Python language.

If you are totally new to Python itself you should start here. If you are new to the Tinkerforge API, you should start here.

We are also assuming that you have a doorbell connected to an Industrial Digital In 4 Bricklet as described here.

Goals

In this project we modify the source code from the Read out Smoke Detectors with Python project just minimally to notify us if the doorbell is ringing. Of course this script can be extended such that it will send an email or text message to you.

Source Code

Download

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import socket
import sys
import time
import math
import logging as log
log.basicConfig(level=log.INFO)

from tinkerforge.ip_connection import IPConnection
from tinkerforge.ip_connection import Error
from tinkerforge.bricklet_industrial_digital_in_4 import IndustrialDigitalIn4


class DoorbellNotifier:
    HOST = 'localhost'
    PORT = 4223

    ipcon = None
    idi4 = None

    def __init__(self):
        self.ipcon = IPConnection()
        while True:
            try:
                self.ipcon.connect(DoorbellNotifier.HOST, DoorbellNotifier.PORT)
                break
            except Error as e:
                log.error('Connection Error: ' + str(e.description))
                time.sleep(1)
            except socket.error as e:
                log.error('Socket error: ' + str(e))
                time.sleep(1)

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        while True:
            try:
                self.ipcon.enumerate()
                break
            except Error as e:
                log.error('Enumerate Error: ' + str(e.description))
                time.sleep(1)

    def cb_interrupt(self, interrupt_mask, value_mask):
        if value_mask > 0:
            log.warn('Ring Ring Ring!')

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            if device_identifier == IndustrialDigitalIn4.DEVICE_IDENTIFIER:
                try:
                    self.idi4 = IndustrialDigitalIn4(uid, self.ipcon)
                    self.idi4.set_debounce_period(10000)
                    self.idi4.set_interrupt(15)
                    self.idi4.register_callback(IndustrialDigitalIn4.CALLBACK_INTERRUPT,
                                                self.cb_interrupt)
                    log.info('Industrial Digital In 4 initialized')
                except Error as e:
                    log.error('Industrial Digital In 4 init failed: ' + str(e.description))
                    self.idi4 = None

    def cb_connected(self, connected_reason):
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
            log.info('Auto Reconnect')

            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except Error as e:
                    log.error('Enumerate Error: ' + str(e.description))
                    time.sleep(1)

if __name__ == "__main__":
    log.info('Doorbell Notifier: Start')

    doorbell_notifier = DoorbellNotifier()

    if sys.version_info < (3, 0):
        input = raw_input # Compatibility for Python 2.x
    input('Press key to exit\n')

    if doorbell_notifier.ipcon != None:
        doorbell_notifier.ipcon.disconnect()

    log.info('Doorbell Notifier: End')