Inhalt
1. Vorwort
2. Installation des Nukis mit CH-Zylinder
3. Voraussetzungen zur Steuerung des Nuki via API
4. API-Befehle
5. Automatisches Sperren von manuell aufgesperrten Türen
6. Alarm bei offengelassener Türe
7. Abrufen des Protokolls (Activity-Log)
8. Erfahrungen mit dem Akku nach drei Monaten
9. Nuki Pro 5 fällt zu Boden und zerspringt in Einzelteile
1, Vorwort
Im Rahmen unseres Projektes Mosliboss SmartHome und in
Anbetracht der Tatsache, dass die Kinder gelegentlich das Haus verlassen, ohne
die Haustüre abzuschliessen, wurden Überlegungen in Richtung SmartLock gemacht
und nach etlichen Recherchestunden fiel unsere Wahl auf ein
Nuki Smart Lock Pro (5. Gen).
Gestaunt haben wir ob der Geschwindigkeit der Lieferung: Am Sonntag, 25. Mai
2025 wurde die Bestellung online aufgegeben und am Dienstag, 27. Mai 2025
lag das Paket bereits im Briefkasten!! Seltsamerweise wurde im Nuki-Club-Account
die Bestellung bis am 27. Mai 2025 stets nur als 'In Bearbeitung' angezeigt und
entsprechend gross war die Überraschung, als das Paket bereits weniger als
48 Stunden nach der Bestellung in Graz/Österreich bei uns in der
Schweiz angekommen war...
Zwar ist dieses Schloss für EU-Zylinder offiziell nur bedingt geeignet für
Schweizer
Rund-Schloss-Zylinder, doch im folgenden Abschnitt wird erklärt, wie dies bei
uns recht einfach erfolgreich realisiert worden ist.
2. Installation des Nukis mit CH-Zylinder
Wir haben ein Keso2000-Schloss mit einem Zylinder, der einen Durchmesser von
22mm aufweist und auf der Türinnenseite vom Schild ca. 14mm übersteht.
Die mit dem Nuki mitgelieferte
Klebe-Platte weist eine Dicke von ca. 4mm auf. Somit benötigen wir ein
Zwischenstück von ca. 10mm Dicke, damit das Zylinderende ungefähr bündig
mit der Oberfläche der Klebeplatte ist. Da wir heute im Jumbo keine passende
Scheibe in Metall oder Kunststoff gefunden haben, kauften wir ein kleines Stück
beschichtete Spanplatte mit 10mm Dicke. Davon wurde ein 5x5 cm grosses Stück
ausgesägt und in der Mitte mittels einem 25mm-Forstnerbohrer ein
Loch gebohrt. Das Türschild und das Holzstück wurden jeweils mittels
Brennsprit gereinigt und das Holzstück mittels dem sehr gut klebenden und
dünnen "tesa Powerbond" (beidseitig klebend, transparent, 5mx19mm) verbunden,
so, dass der Zylinder schön mittig im Loch platziert ist
(Foto 1).

Anschliessend wurde die gelieferte selbstklebende Nuki-Platte mit der aussen
befindlichen Kerbe
nach oben auf das (mit Brennsprit gereinigte) Holzstück geklebt (Foto 2)
und schliesslich das Nuki Pro
gemäss Anleitung darauf aufgesteckt, leicht im Uhrzeigersinn gedreht und
fixiert (Fotos 3 und 4, jeweils unten mit dem magnetischen Ladekabel
angeschlossen).
Mit diesem Vorgehen konnte das Nuki Pro 5 problemlos in Betrieb genommen werden!
3. Voraussetzungen zur Steuerung des Nuki via API
Um das Nuki Pro mittels API von einem Linux-Rechner anzusteuern, muss zuerst
ein Konto auf dem Nukiweb https://web.nuki.io eingerichtet werden.
Dort kann unter API ein API-Token generiert werden. Dieser sehr lange String
vom Typ (hier fiktiv) 87f095d9c2b390dbf5dbfd1e457848bc4bc4665315a3
sollte irgendwo sicher abgespeichert werden, solange er noch angezeigt wird.
Das Nuki-Gerät muss unbedingt via Nuki-App (Einstellungen -
Funktionen&Konfiguration - NukiWeb) in der Nuki Web API angemeldet werden.
Anschliessend muss noch der hexadezimale SmartLock-ID bestimmt werden.
Dazu geht man in der Nuki-App zuerst in folgendes Menu:
Einstellungen - Funktionen&Konfiguration - Allgemein - Dort findet man die Geräte ID: AB123CDFür die API wird jedoch die dezimale ID benötigt, wobei (nach Recherchen im Web) folgendes gilt:
4. API-Befehle
In diesem Abschnitt sollen einige Beispiele von API-Steuer-Befehlen
erklärt werden.
API_token="87f095d9c2b390dbf5dbfd1e457848bc4bc4665315a3"
Nuki_ID="1521558477"
# Status abfragen:
curl --no-sessionid -X GET \
--header "Accept: application/json" \
--header "Authorization: Bearer $API_token" \
"https://api.nuki.io/smartlock" \
--output out.out 2>/dev/null
Falls der Output im File out.out eine Fehlermeldung der Form
{"detailMessage":"Your access token is not authorized","stackTrace":[],"suppressedExceptions":[]}
enthält, ist irgendetwas schief gelaufen. Insbesondere ist es wichtig, dass
bei den curl-Parametern Gänsefüsschen (") und nicht Apostrophe (') verwendet
werden, weil letztere die Variablen wie $API_token und $Nuki_ID nicht
in die wahren Werte übersetzen!
Um nun z.B. den Status von zwei Nukis in entsprechenden Files zu listen und einige kritische Parameter in der Konsole darzustellen, kann folgendes Script namens get_nuki_status.sh verwendet werden:
#!/bin/bash
# get_nuki_status.sh 28May2025/uk Version vom 07Nov2025
OUTFILE="out.out"
API_token="87f095d9c2b390dbf5dbfd1e457848bc4bc4665315a3"
Nuki1="1521558477"
Nuki2="1521558488"
# Status abfragen
curl --no-sessionid -X GET \
-H "Accept: application/json" \
-H "Authorization: Bearer $API_token" \
"https://api.nuki.io/smartlock" \
--output $OUTFILE 2>/dev/null
if test $? -ne 0 ; then
echo "Fehler bei der curl-Abfrage - exit!"
exit
fi
# Die Daten der beiden Nukis extrahieren und jeweils in eine Datei speichern
jq '.[0]' "$OUTFILE" > Nuki1.status
jq '.[1]' "$OUTFILE" > Nuki2.status
#echo "Statusdateien erstellt: Nuki1.status und Nuki2.status"
# Kritische Parameter:
tuerstatus=$(jq '.[0].state.doorState' "$OUTFILE")
schlossstatus=$(jq '.[0].state.state' "$OUTFILE")
batteriestatus=$(jq '.[0].state.batteryCharge' "$OUTFILE")
batteriekritisch=$(jq '.[0].state.batteryCritical' "$OUTFILE")
echo "Nuki1:"
echo "Tuere: $tuerstatus (2: geschlossen, 3: offen)"
echo "Schloss: $schlossstatus (1: zugesperrt, 3: entsperrt)"
echo "Akku: $batteriestatus%"
echo "AkkuLadungKritisch: $batteriekritisch"
tuerstatus=$(jq '.[1].state.doorState' "$OUTFILE")
schlossstatus=$(jq '.[1].state.state' "$OUTFILE")
batteriestatus=$(jq '.[1].state.batteryCharge' "$OUTFILE")
batteriekritisch=$(jq '.[1].state.batteryCritical' "$OUTFILE")
echo " "
echo "Nuki2:"
echo "Tuere: $tuerstatus (2: geschlossen, 3: offen)"
echo "Schloss: $schlossstatus (1: zugesperrt, 3: entsperrt)"
echo "Akku: $batteriestatus%"
echo "AkkuLadungKritisch: $batteriekritisch"
#
Dies ergibt dann z.B. folgenden Output:
Nuki1: Tuere: 2 (2: geschlossen, 3: offen) Schloss: 1 (1: zugesperrt, 3: entsperrt) Akku: 100% AkkuLadungKritisch: false Nuki2: Tuere: 2 (2: geschlossen, 3: offen) Schloss: 3 (1: zugesperrt, 3: entsperrt) Akku: 20% AkkuLadungKritisch: trueund die gesamten Statusinformationen der Nukis sind in recht gut lesbarer Form in den Files Nuki1.status und Nuki2.status enthalten. Achtung: Mir ist aufgefallen, dass selbst als in der App ein Akku-Ladestand von nur noch 18% angegeben wurde, mittels dieser Script-Abfrage immer noch 20% gemeldet wurde, der Parameter AkkuLadungKritisch jedoch auf true stand (siehe Beispiel von 'Nuki2' oben!!
5. Automatisches Sperren von manuell aufgesperrten Türen
Es kann vorkommen, dass jemand ein Nuki von innen absichtlich aufsperrt, die
Türe dann jedoch nicht öffnet. In diesem Fall greift die Regel "Autolock"
nicht, welche nachdem Schliessen der Türe diese automatisch verriegelt
(zusperrt). Für diesen Fall wurde bei uns ein Script
check_locked_doors.sh implementiert, welches via Cron-Job
*/3 * * * * nice -n 15 $HOME/smarthome/nuki/check_locked_doors.sh >> $HOME/smarthome/nuki/check_locked_doors.log 2>>$HOME/smarthome/nuki/check_locked_doors.errlog
alle drei
Minuten kontrolliert, ob eine Türe zwar geschlossen,, aber nicht zugesperrt
ist. Falls dies der Fall ist, wird die Türe automatisch zugesperrt.
Bemerkung: In den folgenden Scripts ist jeweils eine Zeile
source $HOME/smarthome/HA/MASTER.file zu finden. Die steht deshalb
da, weil wir ein Hochverfügbarkeitssystem in Betrieb
haben und diverse Scripts nur dann ausgeführt werden sollen, wenn der
Rechner den Status MASTER hat. Zudem sind etliche Files, die sich öfters
ändern, in einer RAM-Disk abgespeichert - siehe dazu
"RAM-Disk auf Raspi einrichten zur Schonung der SD-Karte".
#!/bin/bash
# check_locked_doors.sh 29May2025/uk
#
source $HOME/smarthome/HA/MASTER.file
if test "$MASTER" = "no" ; then
# echo "Not MASTER - exit! `date +%d.%m.%Y_%H:%M`"
exit
fi
mkdir -p /mnt/ramdisk/Nuki
cd $HOME/smarthome/nuki
# Nicht, dass alle 3 Minuten 0 Sekunden mehrere Prozesse laufen:
sleep 13
#
OUTFILE="/mnt/ramdisk/Nuki/check.out"
#
API_token="87f095d9c2b390dbf5dbfd1e457848bc4bc4665315a3"
Nuki_EG_ID="1521558477"
Nuki_UG_ID="1521558488"
#
get_status() {
curl --no-sessionid -X GET \
-H "Accept: application/json" \
-H "Authorization: Bearer $API_token" \
"https://api.nuki.io/smartlock" \
--output $1 2>/dev/null
if test $? -ne 0 ; then
echo "check_locked_doors.sh - Fehler bei der curl-Status-Abfrage - exit! `date +%d.%m.%Y_%H:%M`"
exit 1
fi
EGtuerstatus=$(jq '.[0].state.doorState' "$OUTFILE")
EGschlossstatus=$(jq '.[0].state.state' "$OUTFILE")
UGtuerstatus=$(jq '.[1].state.doorState' "$OUTFILE")
UGschlossstatus=$(jq '.[1].state.state' "$OUTFILE")
}
#
lock_door() {
action="lock"
curl --no-sessionid -X POST \
-H "Authorization: Bearer $API_token" \
-H "Accept: application/json" \
"https://api.nuki.io/smartlock/$2/action/$action" \
--output $1 2>/dev/null
if test $? -ne 0 ; then
echo "check_locked_doors.sh - Fehler beim curl-Lock-Befehl - exit! `date +%d.%m.%Y_%H:%M`"
exit 1
fi
}
#
get_status $OUTFILE
if test $EGtuerstatus -eq 2 && test $EGschlossstatus -eq 1 ; then
# echo "Türe EG geschlossen und zugesperrt"
:
fi
if test $UGtuerstatus -eq 2 && test $UGschlossstatus -eq 1 ; then
# echo "Türe UG geschlossen und zugesperrt"
:
fi
#
if test $EGtuerstatus -eq 2 && test $EGschlossstatus -eq 3 ; then
echo "check_locked_doors.sh - EG-Türe geschlossen aber nicht zugesperrt - 10 Sek. warten `date +%d.%m.%Y_%H:%M`"
sleep 10
get_status $OUTFILE
if test $EGtuerstatus -eq 2 && test $EGschlossstatus -eq 3 ; then
lock_door $OUTFILE $Nuki_EG_ID
echo "check_locked_doors.sh - EG-Türe geschlossen aber nicht zugesperrt - wird zugesperrt `date +%d.%m.%Y_%H:%M`"
fi
fi
if test $UGtuerstatus -eq 2 && test $UGschlossstatus -eq 3 ; then
echo "check_locked_doors.sh - UG-Türe geschlossen aber nicht zugesperrt - 10 Sekunden warten `date +%d.%m.%Y_%H:%M`"
sleep 10
get_status $OUTFILE
if test $UGtuerstatus -eq 2 && test $UGschlossstatus -eq 3 ; then
lock_door $OUTFILE $Nuki_UG_ID
echo "check_locked_doors.sh - UG-Türe geschlossen aber nicht zugesperrt - wird zugesperrt `date +%d.%m.%Y_%H:%M`"
fi
fi
#
6. Alarm bei offengelassener Türe
Bei all diesen Automatismen kann in findiger Junior, der nur "kurz" draussen
ein bisschen Turnen woltle, auf die Idee kommen, die Haustüre einfach offen
stehen zu lassen, was verantwortliche Eltern natürlich nicht gutheissen können.
Aus diesem Grund wurde für jede Türe mit einem Nuki ein Cron-Job eingerichtet,
der jede Minute testet, ob eine Türe geöffnet ist:
* * * * * nice -n 15 $HOME/smarthome/nuki/check_closed_doors.sh EG >> $HOME/smarthome/nuki/check_closed_doors.log 2>>$HOME/smarthome/nuki/closed_doors.errlog
* * * * * nice -n 15 $HOME/smarthome/nuki/check_closed_doors.sh UG >> $HOME/smarthome/nuki/check_closed_doors.log 2>>$HOME/smarthome/nuki/closed_doors.errlog
Falls eine Türe längere Zeit offen bleibt, wurde mittels einem von früheren
Experimenten vorhandenen "Shelly Plug S" zum Schalten einer
günstigen kleinen Sirene und einem
12 Volt Netzteil eine Alarmeinheit beschafft.
Das Script namens check_closed_doors.sh sieht wie folgt aus:
#!/bin/bash
# check_closed_doors.sh 02Jun2025/uk - flexible Alarme
source $HOME/smarthome/HA/MASTER.file
if test "$MASTER" = "no" ; then
exit
fi
if test $# -ne 1 ; then
echo "Usage: $0 {EG|UG} `date +%d.%m.%Y_%H:%M`"
exit 1
fi
door="$1"
# Damit nicht zu viele Jobs um *:00 Minuten laufen:
if test "$door" = "EG" ; then
sleep 2
fi
if test "$door" = "UG" ; then
sleep 7
fi
mkdir -p /mnt/ramdisk/Nuki
cd $HOME/smarthome/nuki
OUTFILE="/mnt/ramdisk/Nuki/check_closed_doors_$door.out"
LOCKFILE="/mnt/ramdisk/Nuki/check_closed_doors_$door.lock"
STATEFILE="/mnt/ramdisk/Nuki/check_closed_doors_${door}.state"
ALARM_INDEX_FILE="/mnt/ramdisk/Nuki/alarm_index_${door}.txt"
API_token="87f095d9c2b390dbf5dbfd1e457848bc4bc4665315a3"
Nuki_EG_ID="1521558477"
Nuki_UG_ID="1521558488"
[ "$door" = "EG" ] && Nuki_ID="$Nuki_EG_ID"
[ "$door" = "UG" ] && Nuki_ID="$Nuki_UG_ID"
# Alarm- und Sirenenkonfiguration
Alarms_after=(60 120 180 240 300 360 420 480 540 600 660 720)
Siren_duration=(0 1.0 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 3.0)
# Längen vergleichen
if [ "${#Alarms_after[@]}" -ne "${#Siren_duration[@]}" ]; then
echo "<font color=orange>Fehler: Die Arrays Alarms_after und Siren_duration sind nicht gleich lang!"
echo "Länge Alarms_after: ${#Alarms_after[@]}"
echo "Länge Siren_duration: ${#Siren_duration[@]}"
exit 1
fi
get_status() {
curl --no-sessionid -X GET \
-H "Accept: application/json" \
-H "Authorization: Bearer $API_token" \
"https://api.nuki.io/smartlock" \
--output "$OUTFILE" 2>/dev/null
if test $? -ne 0 || ! test -s "$OUTFILE" ; then
echo "<font color=orange>Fehler bei curl - keine oder leere Antwort! - exit! `date`"
rm -f "$LOCKFILE"
exit 1
fi
# Prüfe, ob die Datei wirklich JSON ist
if ! jq . "$OUTFILE" >/dev/null 2>&1; then
echo "<font color=orange>Fehler: Ungültige JSON-Antwort in $OUTFILE (`date`)"
rm -f "$LOCKFILE"
exit 1
fi
if [ "$door" = "EG" ]; then
TuerStatus=$(jq '.[0].state.doorState' "$OUTFILE")
SchlossStatus=$(jq '.[0].state.state' "$OUTFILE")
else
TuerStatus=$(jq '.[1].state.doorState' "$OUTFILE")
SchlossStatus=$(jq '.[0].state.state' "$OUTFILE")
fi
# Prüfen, ob TuerStatus eine Zahl ist
if ! [[ "$TuerStatus" =~ ^[0-9]+$ ]]; then
echo "<font color=orange>Fehler: Kein gültiger Türstatus (doorState=$TuerStatus) - Abbruch! `date`"
rm -f "$LOCKFILE"
exit 1
fi
# Prüfen, ob SchlossStatus eine Zahl ist
if ! [[ "$SchlossStatus" =~ ^[0-9]+$ ]]; then
echo "<font color=orange>Fehler: Kein gültiger Schlossstatus (LockState=$SchlossStatus) - Abbruch! `date`"
rm -f "$LOCKFILE"
exit 1
fi
}
if test -e "$LOCKFILE" ; then
exit 0
else
touch "$LOCKFILE"
fi
get_status
# Prüfen, ob TuerStatus eine Zahl ist
if ! [[ "$TuerStatus" =~ ^[0-9]+$ ]]; then
echo "<font color=orange>Fehler: Kein gültiger Türstatus - wahrscheinlich Fehler bei der API/JSON. Türstatus: '$TuerStatus' (`date`)"
rm -f "$LOCKFILE"
exit 1
fi
# Prüfen, ob SchlossStatus eine Zahl ist
if ! [[ "$SchlossStatus" =~ ^[0-9]+$ ]]; then
echo "<font color=orange>Fehler: Kein gültiger Schlossstatus - wahrscheinlich Fehler bei der API/JSON. Schlossstatus: '$SchlossStatus' (`date`)"
rm -f "$LOCKFILE"
exit 1
fi
if [ "$TuerStatus" -ne 3 ]; then
# Tür nicht offen → alles ok, State-Dateien löschen
rm -f "$STATEFILE" "$ALARM_INDEX_FILE" "$LOCKFILE"
exit 0
fi
# Türe OFFEN und gleichzeitig GESCHLOSSEN - sollte nie der Fall sein --> Alarm!!
if test "$TuerStatus" -eq 3 && test "$SchlossStatus" -eq 1 ; then
siren_time=5
message="Türe $door OFFEN und gleichzeitig GESCHLOSSEN! (SD=$siren_time) `date +%d.%m.%Y_%H:%M`"
echo "<font color=yellow>$message"
/usr/local/bin/send_telegram "$message"
./sirene_schalten.sh $siren_time
rm -f "$STATEFILE" "$ALARM_INDEX_FILE" "$LOCKFILE"
exit 0
fi
now=$(date +%s)
if test -e "$STATEFILE"; then
start=$(cat "$STATEFILE")
else
start=$now
echo "$start" > "$STATEFILE"
echo "Tür $door seit jetzt offen: `date +%d.%m.%Y_%H:%M`"
fi
duration=$((now - start))
# Aktueller Alarm-Index
if test -e "$ALARM_INDEX_FILE"; then
ALARM_INDEX=$(cat "$ALARM_INDEX_FILE")
else
ALARM_INDEX=0
fi
# Prüfen, ob nächster Alarm fällig ist
if [ $ALARM_INDEX -lt ${#Alarms_after[@]} ]; then
next_alarm=${Alarms_after[$ALARM_INDEX]}
if [ $duration -ge $next_alarm ]; then
# Sende Alarm
minutes=$((duration / 60))
siren_time=${Siren_duration[$ALARM_INDEX]}
message="Türe $door seit $minutes Minuten offen! (SD=$siren_time) `date +%d.%m.%Y_%H:%M`"
echo "<font color=yellow>$message"
/usr/local/bin/send_telegram "$message"
./sirene_schalten.sh $siren_time
# Sirene auslösen (nur Beispiel, anpassen)
# /usr/local/bin/trigger_siren $siren_time
# Index erhöhen
ALARM_INDEX=$((ALARM_INDEX + 1))
echo "$ALARM_INDEX" > "$ALARM_INDEX_FILE"
fi
fi
rm -f "$LOCKFILE"
#
In diesem Script wird auch das Script sirene_schalten.sh verwendet,
welches wie folgt aussieht:
#!/bin/bash
# sirene_schalten.sh 02Jun2025/uk
#
# Schaltet einen Shelly-PlugS ein oder aus
# Einschalten kann auch nur für eine bestimmte Zeitdauer gelten
# Statusabfrage: EIN oder AUS
#
sirene_starten () {
taskON="http://$shelly/relay/0?turn=on"
taskOFF="http://$shelly/relay/0?turn=off"
#
curl --fail --silent --show-error --no-sessionid --request $request_method \
$taskON --output $OUTFILE
sleep 0.01
curl --fail --silent --show-error --no-sessionid --request $request_method \
$taskOFF --output $OUTFILE
sleep 1
#
curl --fail --silent --show-error --no-sessionid --request $request_method \
$taskON --output $OUTFILE
sleep 0.01
curl --fail --silent --show-error --no-sessionid --request $request_method \
$taskOFF --output $OUTFILE
sleep 1
#
curl --fail --silent --show-error --no-sessionid --request $request_method \
$taskON --output $OUTFILE
sleep $duration
curl --fail --silent --show-error --no-sessionid --request $request_method \
$taskOFF --output $OUTFILE
#
}
#
n=$#
if test $n -ne 1 ; then
echo "Usage: ./sirene_schalten.sh duration"
echo "Example: ./sirene_schalten.sh 0.3"
fi
duration=$1
#
shelly="shellyplugs"
request_method="get"
#
source $HOME/smarthome/HA/MASTER.file
if test "$MASTER" = "no" ; then
# echo "Nicht Master. shelly_schalten.sh - exit! `date +%d.%m.%Y_%H:%M`"
exit
fi
#
mkdir -p /mnt/ramdisk/Nuki
cd $HOME/smarthome/nuki
#
OUTFILE="/mnt/ramdisk/Nuki/${0##*/}.result"
#
# Set PlugS to default power-on state to OFF:
taskDefaultOFF="http://$shelly/settings/relay/0?default_state=off"
curl --fail --silent --show-error --no-sessionid --request $request_method \
$taskDefaultOFF --output $OUTFILE
#
sirene_starten
#
wobei der shellyplugs im File /etc/hosts mit dessen IP-Nummer
definiert ist. Das Script /usr/local/bin/send_telegram ist im
Beitrag Automatisierte Message an Handy erklärt.
7. Abrufen des Protokolls (Activity-Log)
Um die letzten Aktivitäten der Nukis abzurufen und auf einer Web-Seite
darzustellen, wurde ein entsprechendes Script get_activity_log.sh
geschrieben:
#!/bin/bash
# get_activity_log.sh 30May2025/uk
#
source $HOME/smarthome/HA/MASTER.file
if test "$MASTER" = "no" ; then
# echo "Not MASTER - exit! `date +%d.%m.%Y_%H:%M`"
exit
fi
mkdir -p /mnt/ramdisk/Nuki
cd $HOME/smarthome/nuki
#
OUTFILE="/mnt/ramdisk/Nuki/activity_log.out"
#
API_token="87f095d9c2b390dbf5dbfd1e457848bc4bc4665315a3"
Nuki_EG_ID="1521558477"
Nuki_UG_ID="1521558488"
#
echo "Nuki EG"
curl -X GET \
-H "Accept: application/json" \
-H "Authorization: Bearer $API_token" \
"https://api.nuki.io/smartlock/$Nuki_EG_ID/log?limit=50" \
--output $OUTFILE 2>/dev/null
#
if test $? -ne 0 ; then
echo "get_activity_log.sh - Fehler bei der curl-Status-Abfrage - exit! `date +%d.%m.%Y_%H:%M`"
exit 1
fi
# jq -r '.[] | "\(.date) - \(.action|tostring|gsub("1";"Lock")|gsub("2";"Unlock")|gsub("3";"Unlatch")) - \(.name)"' /mnt/ramdisk/Nuki/activity_log.out
INPUT="/mnt/ramdisk/Nuki/activity_log.out"
jq -c '.[]' "$INPUT" | while read -r entry; do
date_utc=$(echo "$entry" | jq -r '.date')
action=$(echo "$entry" | jq -r '.action')
name=$(echo "$entry" | jq -r '.name')
if test "$name" = "User1" ; then
name="<font color=blue>User1"
fi
if test "$name" = "User2" ; then
name="<font color=blue>User2"
fi
# if test "$name" = "- Nuki Keypad" ; then
# name="- Ungültiger Fingerprint"
# fi
source=$(echo "$entry" | jq -r '.source')
trigger=$(echo "$entry" | jq -r '.trigger')
if test $trigger -eq 6 ; then
name="AutoLock"
fi
if test $trigger -eq 1 || test $trigger -eq 2 ; then
name="manual_Nuki"
fi
# Aktion umsetzen
case $action in
1) action_txt="Unlock" ;;
2) action_txt="Lock" ;;
3) action_txt="Unlatch" ;;
4) action_txt="Lock'n'go" ;;
240) action_txt="Door opened"
name="" ;;
241) action_txt="Door closed"
name="" ;;
242) action_txt="<font color=yellow>DoorSensor jammed!!"
name="" ;;
*) action_txt="Other (action=$action)" ;;
esac
# Source umsetzen
source_nr=$source
case $source in
# 0) source_txt="default" ;;
0) source_txt=""
source_nr="" ;;
1) source_txt="KeypadCode" ;;
2) source_txt="Fingerprint" ;;
*) source_txt="Other (source=$source)" ;;
esac
if test "$source_txt" = "KeypadCode" && test "$name" = "Nuki Keypad" ; then
name="<font color=yellow>ungültig" # Fingerprint
fi
if test "$name" = "Zutrittscode" ; then
name="OK"
fi
if test "$name" = "Nuki Keypad" ; then
name="manual_Keypad"
fi
if test "$name" = "Nuki Web" ; then
name="<font color=blue>via_API"
fi
# UTC → Lokalzeit
date_local=$(date -d "$date_utc" +"%Y-%m-%d %H:%M:%S")
# Zeile MIT Codes:
# echo "$date_local $action $action_txt $source_nr $source_txt $name" | tr -s ' ' ' '
# Zeile OHNE Codes:
echo "$date_local $action_txt $source_txt $name" | tr -s ' ' ' '
done
#
echo " "
echo "Nuki UG"
curl -X GET \
-H "Accept: application/json" \
-H "Authorization: Bearer $API_token" \
"https://api.nuki.io/smartlock/$Nuki_UG_ID/log?limit=50" \
--output $OUTFILE 2>/dev/null
#
if test $? -ne 0 ; then
echo "get_activity_log.sh - Fehler bei der curl-Status-Abfrage - exit! `date +%d.%m.%Y_%H:%M`"
exit 1
fi
# jq -r '.[] | "\(.date) - \(.action|tostring|gsub("1";"Lock")|gsub("2";"Unlock")|gsub("3";"Unlatch")) - \(.name)"' /mnt/ramdisk/Nuki/activity_log.out
INPUT="/mnt/ramdisk/Nuki/activity_log.out"
jq -c '.[]' "$INPUT" | while read -r entry; do
date_utc=$(echo "$entry" | jq -r '.date')
action=$(echo "$entry" | jq -r '.action')
name=$(echo "$entry" | jq -r '.name')
if test "$name" = "Urs" ; then
name="<font color=blue>User1"
fi
if test "$name" = "Caro" ; then
name="<font color=blue>User2"
fi
source=$(echo "$entry" | jq -r '.source')
trigger=$(echo "$entry" | jq -r '.trigger')
if test $trigger -eq 6 ; then
name="AutoLock"
fi
if test $trigger -eq 1 || test $trigger -eq 2 ; then
name="manual_Nuki"
fi
# Aktion umsetzen
case $action in
1) action_txt="Unlock" ;;
2) action_txt="Lock" ;;
3) action_txt="Unlatch" ;;
4) action_txt="Lock'n'go" ;;
240) action_txt="Door opened"
name="" ;;
241) action_txt="Door closed"
name="" ;;
242) action_txt="DoorSensor jammed!!"
name="" ;;
*) action_txt="Other (action=$action)" ;;
esac
# Source umsetzen
source_nr=$source
case $source in
# 0) source_txt="default" ;;
0) source_txt=""
source_nr="" ;;
1) source_txt="KeypadCode" ;;
1) source_txt="KeypadCode" ;;
2) source_txt="Fingerprint" ;;
*) source_txt="Other (source=$source)" ;;
esac
if test "$source_txt" = "KeypadCode" && test "$name" = "Nuki Keypad" ; then
name="<font color=yellow>ungültig" # Zahlencode
fi
if test "$source_txt" = "Fingerprint" && test "$name" = "Nuki Keypad" ; then
name="<font color=yellow>ungültig" # Fingerprint
fi
if test "$name" = "Zutrittscode" ; then
name="OK"
fi
if test "$name" = "Nuki Keypad" ; then
name="manual_Keypad"
fi
if test "$name" = "Nuki Web" ; then
name="<font color=blue>via_API"
fi
# UTC → Lokalzeit
date_local=$(date -d "$date_utc" +"%Y-%m-%d %H:%M:%S")
# Zeile MIT Codes:
# echo "$date_local $action $action_txt $source_nr $source_txt $name" | tr -s ' ' ' '
# Zeile OHNE Codes:
echo "$date_local $action_txt $source_txt $name" | tr -s ' ' ' '
done
#
8. Erfahrungen mit dem Akku nach drei Monaten
9. Nuki Pro 5 fällt zu Boden und zerspringt in Einzelteile
Nachtrag vom 7. Nov. 2025: Gestern stand eine Türe derart blöd im Weg, dass beim
Öffnen einer Haustüre das Nuki Pro 5 zu Boden fiel und zwei Teile dort lagen:
Der silberne Zylinder und das Akku-Pack daneben, der sich jedoch nicht im
Zylinder einklicken liess. Heute fiel mir auf, dass an der Türe noch ein dünner
schwarzer Kunststoffring vorhanden war. Dieser liess sich mittels vorsichtiger
Drehbewegungen und etwas Zug entfernen.
Nun begann ich, das ganze Teil neu zusammenzusetzen (Reparatur):
1. Den Akkuteil so in den silbernen Zylinder setzen, dass die beiden
Kupferlaschen des Akkupacks auf die vier Kupferstreifen im Zylinder zu
liegen kommen
2. Den schwarzen Ring so aufsetzen, dass der schmalere Teil in Richtung Zylinder
zeigt und die etwas breitere und rundliche Stelle an der Aussparung zu
stehen kommt
3. Den schwarzen Ring vorsichtig auf den Zylinder pressen und - klick! - alles
ist fest zusammengebaut
4. Den Nuki mittels Drehbewegung wieder aufsetzen bis er arretiert
5. Mittels der App den Nuki neu kalibrieren und alles läuft wieder bestens
- hurra, Glück gehabt!