Sonntag, 20. Oktober 2013

Licht an! - Die erste Version - Python

Licht an! V0.01:)


Hier ist mal die erste Version des "Licht an!" Programms in Python.
Wichtig für mich bei dieser Version war der Reconnect und das automatische erkennen der UID der TK Module. Bis jetzt habe ich die immer "von Hand" eingetragen. Das ist hier nicht mehr so und wird auch bei allen anderen Programmen geändert.

1. Die entsprechenden Module werden geladen:
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.brick_master import Master
from tinkerforge.bricklet_ambient_light import AmbientLight
from tinkerforge.bricklet_distance_ir import DistanceIR
from tinkerforge.bricklet_dual_relay import DualRelay

2. Die Auflistung aller TK Module und der Connect.
Hier werden zwei Funktionen aufgerufen. 1. cb_enumerate 2. cb_connect

def __init__(self):
self.ipcon = IPConnection()
while True:
try:
self.ipcon.connect(tuer.host, tuer.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)

2.1 Funktion cb_enumerate
  • Hier zu ist beachten das bei dem Lichtsensor nur die IP Verbindung hergestellt. Es wird kein Callback erstellt. 
  • Bei den IR Sensoren habe ich noch die Position an dem Master Brick abgefragt da zwei dieser Bricklets angeschlossen sind.
  • Bei dern IR wird ein Callback gestartet der aktiv wird wenn eine bestimmte Entfernung unterschritten wird. 

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:
try:
#Lichtsensor
if device_identifier == AmbientLight.DEVICE_IDENTIFIER:
try:
self.al = AmbientLight(uid, self.ipcon)
log.info('Ambient Light initialized')
except Error as e:
log.error('Ambient Light init failed: ' + str(e.description))
self.al = None
#Aktivieren des IRLong Sensors
elif device_identifier == DistanceIR.DEVICE_IDENTIFIER and position == 'a':
try:
self.irlong = DistanceIR(uid, self.ipcon)
#Abfrage alle 10 Sekunden
self.irlong.set_debounce_period(3000)
#Callback Register --- führt cb_reached als Funktion aus
self.irlong.register_callback(self.irlong.CALLBACK_DISTANCE_REACHED, self.cb_reached)
#Callback wird aktiv wenn Distanz kleiner 200mm ist
self.irlong.set_distance_callback_threshold('<', 450, 0)
log.info('IRLong Aktiv')
except Error as e:
log.error('Init IRLong faild: ' +str(e.description))
self.irlong = None
#Aktivieren des IR Sensors
elif device_identifier == DistanceIR.DEVICE_IDENTIFIER and position == 'b':
try:
self.ir = DistanceIR(uid, self.ipcon)
#Abfrage alle 10 Sekunden
self.ir.set_debounce_period(3000)
#Callback Register --- führt cb_reached als Funktion aus
self.ir.register_callback(self.ir.CALLBACK_DISTANCE_REACHED, self.cb_reached)
#Callback wird aktiv wenn Distanz kleiner 200mm ist
self.ir.set_distance_callback_threshold('<', 200, 0)
log.info('IR Aktiv')
except Error as e:
log.error('Init IR faild: ' +str(e.description))
self.irlong = None
#Dual Relay Modul finden und aktivieren
elif device_identifier == DualRelay.DEVICE_IDENTIFIER:
try:
self.dr = DualRelay(uid, self.ipcon)
log.info('DualRelay aktiv')
text = self.dr.get_state()
log.info('Aktueller Relay Status: ' +str(text))
#Alles ausschalten
self.dr.set_state(False, False)
except Error as e:
log.error('DualRelay faild: ' + str(e.description))
self.dr = None
except Error as e:
log.error('Fehler im Code bei Device Auflistung: ' +str(e.description))


2.2 Funktion cb_connect

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)

3. Funktion cb_reached
Diese Funktion wird ausgeführt wenn eine bestimmte Entfernung bei den IR Sensoren unterschritten ist.
Es wird geprüft wie hell es in dem Raum ist. Wenn es dunkel ist wird das Relay geschaltet. 

def cb_reached(self, distance):
# Get current illuminance (unit is Lux/10)
illuminance = self.al.get_illuminance()/10.0
if illuminance < 25:
print('Illuminance: ' + str(illuminance) + ' Lux')
print('Distance is smaller than 20cm: ' + str(distance/10.0) + ' cm')
print('Schalte Relay ein!')
#Schalte das Licht ein 
self.dr.set_state(True, False)
print('Relay state: ', self.dr.get_state())
else:
print('Illuminance: ' + str(illuminance) + ' Lux')


Alles zusammen sieht dann so aus: 

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Garagen Licht Steuerung
# 2 IR Sensoren
# 1 Lichtsensor
# 1 Dual Relay
#
# Wenn die Tür oder das Gragentor geöffnet wird soll das Licht angehen, sofern es in der
# Garage dunkel ist.
#
# Einer der IR Sensoren wird so befestigt das er eine Änderung des Geragentors mitbekommt
# der andere so das er eine Änderung der Tür mitbekommt.
#
# Der Lichtsensor wird in der Garage angebracht.
# Das DualRelay Modul schaltet dann das Licht. Nach X Minuten soll das dann wieder ausgehen.

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.brick_master import Master
from tinkerforge.bricklet_ambient_light import AmbientLight
from tinkerforge.bricklet_distance_ir import DistanceIR
from tinkerforge.bricklet_dual_relay import DualRelay

class tuer:
host = 'localhost'
port = 4223

ipcon = None
al = None #Licht
dl = None #DualRelay
ir = None #IR bis 40cm
irlong = None #IR bis 150cm

def __init__(self):
self.ipcon = IPConnection()
while True:
try:
self.ipcon.connect(tuer.host, tuer.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_reached(self, distance):
# Get current illuminance (unit is Lux/10)
illuminance = self.al.get_illuminance()/10.0
if illuminance < 25:
print('Illuminance: ' + str(illuminance) + ' Lux')
print('Distance is smaller than 20cm: ' + str(distance/10.0) + ' cm')
print('Schalte Relay ein!')
#Schalte das Licht ein
self.dr.set_state(True, False)
print('Relay state: ', self.dr.get_state())
else:
print('Illuminance: ' + str(illuminance) + ' Lux')

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:
try:
#Lichtsensor
if device_identifier == AmbientLight.DEVICE_IDENTIFIER:
try:
self.al = AmbientLight(uid, self.ipcon)
log.info('Ambient Light initialized')
except Error as e:
log.error('Ambient Light init failed: ' + str(e.description))
self.al = None
#Aktivieren des IRLong Sensors
elif device_identifier == DistanceIR.DEVICE_IDENTIFIER and position == 'a':
try:
self.irlong = DistanceIR(uid, self.ipcon)
#Abfrage alle 10 Sekunden
self.irlong.set_debounce_period(3000)
#Callback Register --- führt cb_reached als Funktion aus
self.irlong.register_callback(self.irlong.CALLBACK_DISTANCE_REACHED, self.cb_reached)
#Callback wird aktiv wenn Distanz kleiner 200mm ist
self.irlong.set_distance_callback_threshold('<', 450, 0)
log.info('IRLong Aktiv')
except Error as e:
log.error('Init IRLong faild: ' +str(e.description))
self.irlong = None
#Aktivieren des IR Sensors
elif device_identifier == DistanceIR.DEVICE_IDENTIFIER and position == 'b':
try:
self.ir = DistanceIR(uid, self.ipcon)
#Abfrage alle 10 Sekunden
self.ir.set_debounce_period(3000)
#Callback Register --- führt cb_reached als Funktion aus
self.ir.register_callback(self.ir.CALLBACK_DISTANCE_REACHED, self.cb_reached)
#Callback wird aktiv wenn Distanz kleiner 200mm ist
self.ir.set_distance_callback_threshold('<', 200, 0)
log.info('IR Aktiv')
except Error as e:
log.error('Init IR faild: ' +str(e.description))
self.irlong = None
#Dual Relay Modul finden und aktivieren
elif device_identifier == DualRelay.DEVICE_IDENTIFIER:
try:
self.dr = DualRelay(uid, self.ipcon)
log.info('DualRelay aktiv')
text = self.dr.get_state()
log.info('Aktueller Relay Status: ' +str(text))
#Alles ausschalten
self.dr.set_state(False, False)
except Error as e:
log.error('DualRelay faild: ' + str(e.description))
self.dr = None
except Error as e:
log.error('Fehler im Code bei Device Auflistung: ' +str(e.description))




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('Tuer: Start')

    tuer = tuer()

    input('Press key to exit\n')

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

    log.info('Tuer: End')