Dienstag, 29. Oktober 2013

Siemens Logo! Online Kurs von Siemens

Im Zuge der Automatisierung von verschiedenen Komponenten im Haus (Pumpen, Licht, usw.) bin ich neben den Geräten wie dem Raspberry PI und Arduino auch über die Siemens Logo! Steuerung gefallen.
Wie weit man die wirklich in diesen Bereichen Einsetzten kann weiß ich noch nicht. Ich habe aber einen Online Kurs von Siemens gefunden der einen Einblick in die Logo! Technik geben soll.

https://sitrain.automation.siemens.com/sitrain/open_wbt/logo/index.html
Wer Interesse hat!

Montag, 28. Oktober 2013

Was ist alles auf dem Raspberry PI?

Ich setzte den Raspberry Pi nun schon einige Zeit ein und es kommen immer neue Aufgaben auf das System zu. Weiß ich aber noch was alles Installiert wurde wenn mal die Speicherkarte defekt ist?
Natürlich habe ich eine Sicherung der Karte mit "dd" erstellt die ich in einem solchen Fall benutzen kann aber das macht man nicht immer wenn eine neue Installation durchgeführt wird.

Konfiguration (Dienste) des Raspberry PI

  1. Das Grundsystem 
  2. Anpassung Netzwerk (IP und Name)
  3. TinkerForge Komponenten (BrickD und BrickV)
  4. SMB Freigaben 
  5. NSF Freigaben
  6. BL Komponenten 
  7. SMASpot für Solaranlage
  8. Printserver CUPS


Mittwoch, 23. Oktober 2013

Neuer Name für den Raspberry PI

Nachdem in dem Beitrag die feste IP Adresse eingestellt wurde soll nun das Gerät auch noch einen anderen Namen im Netzwerk bekommen. Wenn man mehr als einen Raspberry PI einsetzt ist das wichtig.
Das ändern des Namens wird an zwei Dateien durchgeführt:

1. Die Datei
/etc/hostname
Beispiel:
pi@pikeller /etc $ cat hostname
pikeller

2. Die Datei
/etc/hosts
pi@pikeller /etc $ cat hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
127.0.1.1 pikeller

Beide Dateien können mit
sudo nano <Datei> 
geändert werden.

Feste IP für den Raspberry PI

Es kommt oft vor das der Raspberry PI nach dem Neustart eine neue IP Adresse bekommt. Da mein Router leider keine festen IP Adressen vergeben (verwalten) kann möchte ich dem Raspberry PI eine feste IP Adresse geben.
Das ganze ist in wenigen Schritten erledigt.

In der Datei
/etc/network/interfaces 
ist die IP Konfiguration der Netzwerkkarte zu finden.
In dieser Datei muss der Abschnitt:
iface eth0 inet dhcp
ersetzt werden. Solltet eine andere Netzwerkkarte, zum Beispiel WLAN, die Verbindung in das Netzwerk aufbauen muss natürlich der entsprechende Adapter geändert werden.
Neuer Eintrag:
iface eth0 inet static
    address 192.168.1.120
    netmask 255.255.255.0
    gateway 192.168.1.1
Als letztes kann man den noch den "Network" Dienst durchstarten oder den Raspberry PI neu starten. 
Nun sollte sich die IP Adresse nicht mehr ändern und das Gerät ist im Netzwerk immer unter der gleichen IP Adresse zu finden. 

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')

Montag, 14. Oktober 2013

Licht an! - Teil 1 - Hardware

Ich habe das Problem das ich gerne das Licht in der Garage automatisch Ein und Ausschalten würde wenn ich das Garagentor oder die Tür vom Haus in die Garage öffne.
Eine Lösung wäre ein Bewegungsmelder der eine Steckdose bzw. eine Lampe Steuern kann. Um dies zu Realisieren benutze ich die RWE SmartHome Anlage die ihren Dienst an vielen Stellen im Haus hervorragend erledigt.

In diesem Fall ist mir das aber zu "einfach". Ich baue mir das selber. 
Hier kommt die entsprechende Anleitung.

Stückliste
  • 1 x Raspberry PI
  • 1 x TinkerForge Master Brick
  • 2 x TinkerForge Distance IR Bricklet
  • 1 x TinkerForge Dual Relay Bricklet
  • 1 x TinkerForge Lichtsensor
  • Diverse Kabel und Gehäuse
Die einzel Teile: 


 Alle Bauteile in entsprechenden Gehäusen













TinkerForge Master Brick












 Lichtsensor










Die IR Sensoren

Das Dual Relay Bricklet zum schalten des Lichtes










Alle Komponenten mit Kabeln.












Hier ein erster Test mit den IR Sensoren: 




Thread abbrechen

Wie kann ich in Python einen Thread vorzeitig abbrechen?

Ich benötige in einem Programm die Möglichkeit einen Thread abzubrechen. Soweit ich mich eingelesen habe gibt es diese Funktion im "threading" Modul von Python nicht.

Meine Lösung

import time
import threading
from tinkerforge.ip_connection import IPConnection
from tinkerforge.bricklet_io16 import IO16

threadBreak = False #Variable zum abbruch

def schalten():
while not threadBreak: #solange die Variable nicht auf True steht wird läuft die Schleife
                #Die Ports des TinkerForge Moduls werden ein und ausgeschaltet.
io.set_port_configuration('a', 1, 'o', True)
time.sleep(2)
io.set_port_configuration('a', 1, 'o', False)
time.sleep(2)


#Connect zu den TinkerForge Modulen
#Kommt so aus den Beispielen der Webseite
ipcon = IPConnection() # Create IP connection
io = IO16(UID, ipcon) # Create device object

ipcon.connect(HOST, PORT) # Connect to brickd
# Don't use device before ipcon is connected

print('start')

threading.Thread(target = schalten).start() #starte den Thread

time.sleep(20) #Warte
print('Habe mal geschlafen')
threadBreak = True #Ändere Variable
print('Fertig!')