Da sich die Klingel bei mir am Gartentor befindet, der Fingerscanner aber an der Haustür, kommt es öfter vor, dass Besucher ihn für eine Klingel halten, darauf rumtatschen und sich dann wundern, warum keiner aufmacht...
Daher habe ich etwas recherchiert und gebastelt und eine Lösung erarbeitet, die ich hier kurz vorstellen möchte.
Dazu braucht man:
- Einen Linux-Rechner (z.B. RasPi) mit socat (kann unter Raspbian z.B. mit "apt-get install socat" nachinstalliert werden)
- Einen LAN Converter von ekey (Achtung, für ekey home oder multi muss es der mit der Produktnummer 100 460 sein. Ich hatte erst den falschen bestellt, der funktioniert nicht, weil er für das ekey net System ist.)
- Klingel über HomeMatic ansprechbar, bei mir ist es ein Wired 2-Fach-Aktor, könnte aber auch ein MP3-Funkgong sein, der am Besten mit einer Virt. Taste direktverknüpft ist
- Linux-Kenntnisse (man sollte in der Lage sein, auf der Shell Dateien anzulegen, Berechtigungen zu vergeben und Befehle auszuführen)
Nun kann man auf dem Linux-Rechner ein Script erstellen (bei mir /usr/local/bin/udp-datasink.sh) und ausführbar machen.
Das Script macht in Kurzform folgendes:
- Variable aus dem STDIN auslesen (die kommt dann später über den LAN Converter und socat)
- diese auswerten, ob korrekt formatiert
- wenn ja: bei erkanntem Finger nur einen Log-Eintrag schreiben, bei nicht erkanntem Finger über die Remote Script API den Klingeltaster betätigen
Werte müsst ihr natürlich beim Nachbau an eure Umgebung anpassen.
Code: Alles auswählen
#!/bin/bash
# --- ekey data sink ---
# The home protocol can only be used in ekey home systems. Data packets are created
# for each recognized finger and every time a refusal takes place at the finger
# scanner. The data fields within the data packet are ASCII-encoded. This protocol
# has the following structure:
# Base format: x_xxxx_x_xxxxxxxxxxxxxx_x_x
#
# Data field name | Number of digits | Data type | Value range | Meaning
# PACKET TYPE 1 String 1 *User data* packet type
# USER ID 4 String (decimal) 0000-9999 User number (default 0000)
# FINGER ID 1 String (decimal) 0-9 1 = left little finger
# 2 = left ring finger
# 3 = left middle finger
# 4 = left index finger
# 5 = left thumb
# 6 = right thumb
# 7 = right index finger
# 8 = right middle finger
# 9 = right ring finger
# 0 = right little finger
# R = RFID
# - = no finger
# SERIAL NO. FS 14 String xxxxxx xx xx xxxx Digits 1-6 = item number
# Digits 7-10 = week code
# Digits 11-14 = sequential number
# ACTION 1 String 1, 2 1 = Open
# 2 = Refuse unrecognized finger
# 8 = Digital input
# RELAY 1 String 1-4; - 1 = Relay 1
# 2 = Relay 2
# 3 = Relay 3
# 4 = Relay 4
# d = Double relay
# - = no relay
log="/usr/bin/logger -i -p local0.info -t udp-datasink.sh"
log_dbg="/usr/bin/logger -i -p local0.debug -t udp-datasink.sh"
log_err="/usr/bin/logger -i -p local0.warning -t udp-datasink.sh"
#debug=true
$log "Start udp-datasink.sh"
# get data from stdin
read MESSAGE
if [ ! -z "$MESSAGE" ]; then
$log " Message: '$MESSAGE'"
# check if MESSAGE has expected format
if [[ ${MESSAGE} =~ ^._.{4}_._.{14}_._.$ ]]; then
# split into array
IFS='_' read -a msg <<< "${MESSAGE}"
# arrays for naming etc.
name=('PAKETTYPE' 'USERID' 'FINGERID' 'SERIALNO' 'ACTION' 'RELAIS')
fingerids=('right little finger' 'left little finger' 'left ring finger' 'left middle finger' 'left index finger' 'left thumb' 'right thumb' 'right index finger' 'right middle finger' 'right ring finger')
fingerid=${msg[2]}
# resolve finger id to name
if [ $fingerid == "-" ]; then
fingername="None"
elif [ $fingerid == "R" ]; then
fingername="RFID"
else
fingername=${fingerids[$fingerid]}
fi
action=${msg[4]}
userid=${msg[1]}
# resolve userid to name
if [ $userid == "0001" ]; then
username="User1"
elif [ $userid == "0002" ]; then
username="User2"
else
username="Unknown"
fi
# debug output if debug is set
if [ $debug ]; then
for i in {0..5..1}; do
$log_dbg " ${name[i]}: ${msg[i]}"
done
fi
$log " User: $username (ID: $userid), Finger: $fingername (ID: $fingerid), Action: $action (1 = Open, 2 = Refuse unrecognized finger)"
# HomeMatic CCU and device to press
hm_server="192.168.1.220" #ccu ip or dns name
hm_channel="Klingeltaster_ekey" #name of hm device to press
hm_url="http://$hm_server:8181/ccu.exe?do=(dom.GetObject(ID_CHANNELS)).Get('$hm_channel').DPByHssDP('PRESS_SHORT').State(1)"
# check if unrecognized finger
if [ $action == "2" ]; then
$log " Unrecognized finger, running: /usr/bin/curl -s '$hm_url'"
/usr/bin/curl -s '$hm_url'
elif [ $action == "1" ]; then
$log " Finger accepted"
fi
else
$log_err " Message corrupted or incomplete, should be 'x_xxxx_x_xxxxxxxxxxxxxx_x_x'."
fi
else
$log_err " No input given, MESSAGE is empty"
fi
$log "End udp-datasink.sh"
# Done
/usr/local/bin/udp-datasink-starter.sh erstellen und ausführbar machen:
Code: Alles auswählen
#!/bin/bash
while true
do
/usr/bin/socat -u udp4-recvfrom:56000,keepalive,fork system:'/usr/local/bin/udp-datasink.sh'
done
/etc/systemd/system/udp-datasink.service:
Code: Alles auswählen
[Unit]
Description=Socat with ekey-converter data sink
[Service]
ExecStart='/usr/local/bin/udp-datasink-starter.sh'
RestartSec=5
Restart=always
[Install]
WantedBy=multi-user.target
Nun sollte beim Versuchen am Fingerscanner ein Log-Eintrag erstellt werden und bei nicht erkanntem Finger zusätzlich die Klingel klingeln.