Nuki lock setup

Others (MiLight, Hue, Toon etc...)

Moderator: leecollings

User avatar
heggink
Posts: 972
Joined: Tuesday 08 September 2015 21:44
Target OS: Raspberry Pi / ODroid
Domoticz version: 12451
Location: NL
Contact:

Nuki lock setup

Post by heggink »

Due to popular demand, here's my setup for the nuki locks. There really should be a wiki but then the scripts really need a tidy up as they are a bit of a hack (but a working one).

Here goes nothing :-):

Nuki door lock integration

Scrips assume you have multiple devices (front door, side door) with multiple bridges (since bridges work through bluetooth, 1 bridge won't cover both locks) although its fairly easy to adapt the script such that you can use 1 bridge.

Scripts are tested on rasbian ONLY. They probably work on other linux distros as well. In order to function correctly, you need to install jq (sudo apt-get install jq) to parse json messages from the lock.

The concept is as follows: the bridge will transmit any lock status update for a lock to an ip/port through a json message as per the nuki published API (callback hook).

The below uses 2 scripts: 1 to listen to messages on that port (doorlock_change.sh) and 1 to handle accordingly (update domoticz: handle_doorlock_event.sh)). The first process gets started through cron

Both scripts sit in /usr/local/bin.

Following steps need to be performed:
  • Install bridges and locks. Check through the mobile app. Make sure you give the bridges a static IP or figure out how to replace the static IP below with a device name.
    2 Install jq if need be
    3 Create a switch device for each lock. I don't use lock devices since these do not support timers. I have timers on the devices in domoticz to lock at night.
    4 Put the bridges in developer mode (can be done from the nuki app). This allows you to tell the bridge where to send status updates. Write down the data from the bridge/lock (API token)
    for each bridge issue the following command via curl:
    curl -s "http://BRIDGE IP:8080/callback/add?url=http%3A%2F%2F[IP_OF_YOUR_DOMO_SYSTEM]%3A[PORT_TO_LISTEN_ON_SUGGEST_15003]%2Fnuki&token=[API_TOKEN]"
    from now on, any change of lock state is sent as a json message to the domoticz system on port 15003
  • Now we need to listen on that port. Put the following script in /usr/local/bin/doorlock_change.sh:

Code: Select all

#!/bin/bash
# doorlock_change.sh
# listens on a port for nuki lock change messages

while :
do
	res=`nc -d -l 15003`
	ret=$?
	if [ -z "$res" ]; then
		logger Doorlock change received NULL response $ret and $res
	else
		logger Doorlock change Received message $res
		echo ${res} | /usr/local/bin/handle_doorlock_event.sh &
	fi
done 
note that this script logs everything in the syslog
  • Now install the following in /usr/local/bin/handle_doorlock_event.sh but replace the API tokens with your API tokens and the corresponding IDX (123 and 456) with your device idx of your locks in domoticz

Code: Select all

#!/bin/bash
#logger handle_doorlock_change called with $line

while read in
do
	line=`echo ${in} | sed -n 's/^.*{/{/p'`
	nukiId=0
	logger "handle_doorlock_event: received ${line}"

	stateName=`echo $line | jq -r '.stateName'`
	nukiId=`echo $line | jq -r '.nukiId'`

	logger "handle_doorlock_event: got ${stateName} for ${nukiId}"

	case "${nukiId}" in
	"[API_TOKEN_1]")
		idx=[123]
		;;

	"[API_TOKEN_2]")
		idx=[456]
		;;
	esac

	case "${stateName}" in
	"unlocked")
		logger "handle_doorlock_event: setting mode to ON for ${nukiId}"
		mode="1"
		curl -s "http://127.0.0.1:8080/json.htm?type=command&param=udevice&idx=${idx}&nvalue=${mode}&svalue="
		;;

	"undefined")
		logger "handle_doorlock_event: got state undefined for ${nukiId}"
		/usr/local/bin/mailIP "handle_doorlock_event: got state undefined for ${nukiId}"
		;;

	"locked")
		logger "handle_doorlock_event: setting mode to OFF for ${nukiId}"
		mode="0"
		curl -s "http://127.0.0.1:8080/json.htm?type=command&param=udevice&idx=${idx}&nvalue=${mode}&svalue="
		;;

	"unlocking")
		logger "handle_doorlock_event: got unlocking for ${nukiId} so ignore"
		;;

	"locking")
		logger "handle_doorlock_event: got locking for ${nukiId} so ignore"
		;;

	"motor blocked")
		logger "handle_doorlock_event: ERROR: Motor blocked for ${nukiId}"
		;;

	*)
		logger "handle_doorlock_event: ERROR: INVALID EVENT ${stateName} for ${nukiId}"
		;;
	esac

done
  • now install a 3rd script in your domoticz/script folder. This script is called when you change the device in domoticz in order to switch the lock open or closed:

Code: Select all

#!/bin/bash
#
# lockscript.sh
# script that switches the door lock 
# called from Domoticz
#
#

opt=$1
lock=$2
res=0

if [ $lock = [NUKI ID of the lock] ]
then
	idx=[domoticz idx of the lock]
	token=[API TOKEN]
	ip=[BRIDGE ip OF THE NUKI BRIDGE]
else
	idx=[OTHER IDX OF OTHER LOCK]
	token=[other api token in case of another bridge]
	ip=[IP of the other bridge]
fi

logger "lockscript: Domoticz wants to $opt $lock"

case ${opt} in

	Unlock)
# test if the lock is closed. If so, open.
		state=`curl -s "http://${ip}:8080/lockState?nukiId=${lock}&token=${token}"|jq -r '.stateName'`
		logger "lockscript: lock status is $state"
		if [ ${state} = "" ]
		then
			sleep 2
			state=`curl -s "http://${ip}:8080/lockState?nukiId=${lock}&token=${token}"|jq -r '.stateName'`
			logger "lockscript: lock status is $state"
		fi

		if [ ${state} = "uncalibrated" ]
		then
			sleep 10
			state=`curl -s "http://${ip}:8080/lockState?nukiId=${lock}&token=${token}"|jq -r '.stateName'`
			logger "lockscript: lock status is $state"
		fi

		if [ ${state} = "locked" ]
		then
			logger "let's unlock ${lock}"
			res=`curl -s "http://${ip}:8080/lockAction?nukiId=${lock}&action=1&token=${token}"|jq -r '.success'`
			if [ ${res} != "true" ]
			then
				logger "Unlock lock ${lock} FAILED with ${res}, lock in FALSE state"
				res=-1
			else
				logger "Successfully unlocked lock ${lock}"
				res=0
			fi
		else
			logger "lockscript: Lock ${lock} unlocked already"
		fi
		logger "lockscript: exiting ${res}"
		exit $res
		;;

	Lock)
# test if the lock is open. If so, close.
		state=`curl -s "http://${ip}:8080/lockState?nukiId=${lock}&token=${token}"|jq -r '.stateName'`
		logger "lockscript: lock status is $state"
		if [ ${state} = "" ]
		then
			sleep 2
			state=`curl -s "http://${ip}:8080/lockState?nukiId=${lock}&token=${token}"|jq -r '.stateName'`
			logger "lockscript: lock status is $state"
		fi

		if [ ${state} = "uncalibrated" ]
		then
			sleep 10
			state=`curl -s "http://${ip}:8080/lockState?nukiId=${lock}&token=${token}"|jq -r '.stateName'`
			logger "lockscript: lock status is $state"
		fi

		if [ ${state} = "unlocked" ]
		then
			logger "let's lock ${lock}"
			res=`curl -s "http://${ip}:8080/lockAction?nukiId=${lock}&action=2&token=${token}"|jq -r '.success'`
			if [ ${res} != "true" ]
			then
				logger "Lock lock ${lock} FAILED with ${res}, lock in FALSE state"
				res=-1
			else
				logger "Successfully locked lock ${lock}"
				res=0
			fi
		else
			logger "lockscript: Lock ${lock} locked already"
		fi
		logger "lockscript: exiting ${res}"
		exit $res
		;;
esac

exit 0
  • [now add the lock and unlock commands under the lock devices in domoticz:
On Action: script://lockscript.sh Unlock [lock id]
Off action: script://lockscript.sh Lock [lock id]

Make sure you fill in the correct id's of your locks and then test. These scripts should work with/without the callback hook installed.
That should be it. Please note that these scripts really need tidying up and are a bit of a quick/dirty hack but they work for me.
If anyone has the time to tidy up and put these in a wiki then even better.

Let me know if you have issues or whether there are any mistakes in the above from my copy/paste.

the bridge http api can be found here: https://nuki.io/en/api/
Docker in Truenas scale, close to latest beta
DASHTICZ 🙃
RFXCOM, zwavejs2mqtt, zigbee2mqtt,
P1 meter & solar panel
Google home, Wifi Cams motion detection
Geofence iCloud, Bluetooth & Wifi ping
Harmony hub, Nest, lots more :-)
User avatar
heggink
Posts: 972
Joined: Tuesday 08 September 2015 21:44
Target OS: Raspberry Pi / ODroid
Domoticz version: 12451
Location: NL
Contact:

Re: Nuki lock setup

Post by heggink »

btw, I replaced the batteries for the nuki's with a 6v3A adapter so I don;t have to keep changing batteries, Other advantage is that I can now ping the locks without draining the batteries and I can set the locks to the most aggressive power setting (such that it informs me immediately).
Nuki confirmed that 1 6v3A adapter will work. YMMV as I have had some struggles with an underpowered mini 6V UPS before switching to a 6V3A power supply..

PROCEED AT YOUR OWN RISK.
Docker in Truenas scale, close to latest beta
DASHTICZ 🙃
RFXCOM, zwavejs2mqtt, zigbee2mqtt,
P1 meter & solar panel
Google home, Wifi Cams motion detection
Geofence iCloud, Bluetooth & Wifi ping
Harmony hub, Nest, lots more :-)
sanman
Posts: 2
Joined: Wednesday 02 April 2014 21:17
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Nuki lock setup

Post by sanman »

Thanks a lot for the Post,
I modify them a little bit because I have only one Nuki at the moment :-)
I had a second switch to do an alarm/push notification in case of battery low.
I invert on / off action on the domoticz switch (on=lock /off=unlock)
It work fine, just a remark it take few second to react in both ways.
Great job, thanks !
User avatar
heggink
Posts: 972
Joined: Tuesday 08 September 2015 21:44
Target OS: Raspberry Pi / ODroid
Domoticz version: 12451
Location: NL
Contact:

Re: Nuki lock setup

Post by heggink »

The bridge typically takes 6-10 seconds to inform on state changes. If you check the nuki slack, you will see that polling the lock drains the battery since the bridge will check the lock state through Bluetooth rather than relying on the latest state of knew. Now that I use an external power supply, I can check it as often as I want.
Docker in Truenas scale, close to latest beta
DASHTICZ 🙃
RFXCOM, zwavejs2mqtt, zigbee2mqtt,
P1 meter & solar panel
Google home, Wifi Cams motion detection
Geofence iCloud, Bluetooth & Wifi ping
Harmony hub, Nest, lots more :-)
dimk
Posts: 27
Joined: Sunday 17 September 2017 17:30
Target OS: -
Domoticz version:
Contact:

Re: Nuki lock setup

Post by dimk »

Hello all,

i have two Nuki locks, Domoticz running on raspberry pi 3.

Since one week i try with the 3 scrips above to get run nuki via domotiocs but it will not work.

1) I generate 2 switch
2) write down the api token of my two bridges and idx of the two switch
3) generate via putty "sudo nano /usr/local/bin/doorlock_change.sh" the first scrip, port 15003 is this correct? Domotics running on port 8080.
4) generate second script "sudo nano /usr/local/bin/handle_doorlock_event.sh" changed api token and idx of domoticz
5) generate the last script "sudo nano /home/pi/domoitcz/scripts/lockscript.sh" changed nothing
6) nuki callback via curl in putty and direct in the browser (answer bridge success)

I tried this ~5 times but nothing, please give me more details regarding the integration process in domoticz!!!!!

Thanks
Martin
RayAmsterdam
Posts: 115
Joined: Sunday 11 January 2015 16:40
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Nuki lock setup

Post by RayAmsterdam »

You have to start doorlock_change.sh at boot.
dimk
Posts: 27
Joined: Sunday 17 September 2017 17:30
Target OS: -
Domoticz version:
Contact:

Re: Nuki lock setup

Post by dimk »

Thanks for the fast answer.

I add /usr/local/bin/doorlock_change.sh in etc/rc.local and restart the pi.
It does not work.

Is port 15003 the correct port in the script because domoticz runs with port 8080.

How can i check if the script doorlock_change.sh runs?

Thanks in advance!!
Martin
User avatar
heggink
Posts: 972
Joined: Tuesday 08 September 2015 21:44
Target OS: Raspberry Pi / ODroid
Domoticz version: 12451
Location: NL
Contact:

Re: Nuki lock setup

Post by heggink »

Hi Martin,

Couple of things:
  • The scripts log status messages in the system log so you should see messages there.
  • The port (15003 or whatever you choose) has nothing to do with the domoticz web interface port (8080, 443). The Nuki lock needs an ip address and port to send status messages to. The scripts read on this port to receive these messages and update domoticz.
  • the process doorlock_change.sh needs to be running in order to receive messages from the lock. Check if it runs (ps ax|grep doorlock_change should give you a couple of processes)
  • you can start doorlock_change by hand to see if it works: sudo doorlock_change.sh

Let me know what you see.

H
Docker in Truenas scale, close to latest beta
DASHTICZ 🙃
RFXCOM, zwavejs2mqtt, zigbee2mqtt,
P1 meter & solar panel
Google home, Wifi Cams motion detection
Geofence iCloud, Bluetooth & Wifi ping
Harmony hub, Nest, lots more :-)
dimk
Posts: 27
Joined: Sunday 17 September 2017 17:30
Target OS: -
Domoticz version:
Contact:

Re: Nuki lock setup

Post by dimk »

Hello,

Both Nuki has an static IP and port.
In the Script i will use Port 15003
With ps ax|grep doorlock_change

I get the following:

pi@raspberrypi:~ $ ps ax|grep doorlock_change
  805 ?        S      0:00 /bin/bash /usr/local/bin/
doorlock_change
.sh
 1802 pts/1    S+     0:00 grep --color=auto 
doorlock_change

Thanks
Martin



Gesendet von meinem MHA-L29 mit Tapatalk

dimk
Posts: 27
Joined: Sunday 17 September 2017 17:30
Target OS: -
Domoticz version:
Contact:

Re: Nuki lock setup

Post by dimk »

Hello again,

When i start sudo doorlock_change.sh by hand via PuTTY i get the following:

NC: Address already in use (~100x)

Thanks
Martin

Gesendet von meinem MHA-L29 mit Tapatalk

User avatar
heggink
Posts: 972
Joined: Tuesday 08 September 2015 21:44
Target OS: Raspberry Pi / ODroid
Domoticz version: 12451
Location: NL
Contact:

Re: Nuki lock setup

Post by heggink »

ah, address in use means someone else is already listening on that port on your system. can you do the following please:
ps ax|grep nc
if you see a line that says nc -d -l 15003 then please kill that process and run doorlock_change by hand again.

if there is no process then something is locking that port. in that case, try to find out what process is locking the port:
install lsof: sudo atp-get install lsof
sudo lsof -i | grep 15003

that should show the process listening on that port.

alternatively, you can try: sudo netstat -lptu|grep 15003

That should also list the process that is listening on the port.

H
ps: anything in the syslog?
Docker in Truenas scale, close to latest beta
DASHTICZ 🙃
RFXCOM, zwavejs2mqtt, zigbee2mqtt,
P1 meter & solar panel
Google home, Wifi Cams motion detection
Geofence iCloud, Bluetooth & Wifi ping
Harmony hub, Nest, lots more :-)
dimk
Posts: 27
Joined: Sunday 17 September 2017 17:30
Target OS: -
Domoticz version:
Contact:

Re: Nuki lock setup

Post by dimk »

Hello,

at first i delete doorlock_change.sh from /etc/rc.local, restart raspberry pi.
With ps ax|grep nc none process with port 15003.
Try to start doorlock_change.sh with sudo doorlock_change.sh, the course jump to the next line and nothing with control C i came back.
ps ax|grep nc shows none process with port 15003. I can not start doorlock_change.sh. In Syslog nothing.

I generate doorlock_change.sh with sudo nano /usr/local/bin/doorlock_change.sh. With sudo chmod +x the right permission.

I don´t know what is wrong....

Thanks
User avatar
heggink
Posts: 972
Joined: Tuesday 08 September 2015 21:44
Target OS: Raspberry Pi / ODroid
Domoticz version: 12451
Location: NL
Contact:

Re: Nuki lock setup

Post by heggink »

Ah, so if you start by hand, it keeps waiting for nuki messages rather than starting a daemon. It then runs in foreground and you cancel it with control-c.

Run it again by hand (leave it) and switch the lock to see what it does.

H
Docker in Truenas scale, close to latest beta
DASHTICZ 🙃
RFXCOM, zwavejs2mqtt, zigbee2mqtt,
P1 meter & solar panel
Google home, Wifi Cams motion detection
Geofence iCloud, Bluetooth & Wifi ping
Harmony hub, Nest, lots more :-)
dimk
Posts: 27
Joined: Sunday 17 September 2017 17:30
Target OS: -
Domoticz version:
Contact:

Re: Nuki lock setup

Post by dimk »

I start with sudo doorlock_change.sh, control C, switch nuki (both) in syslog stands nothing.
User avatar
heggink
Posts: 972
Joined: Tuesday 08 September 2015 21:44
Target OS: Raspberry Pi / ODroid
Domoticz version: 12451
Location: NL
Contact:

Re: Nuki lock setup

Post by heggink »

don't control-c as you will kill it. Leave it running in foreground. Then switch the lock and see if it does anything. If you can open a second terminal, tail -f /var/log/syslog.

Probably easier, type
sudo doorlock_change.sh
CTRL-z
bg
tail -f /var/log/syslog
control-z stops doorlock_change.sh, bg moves it to background (you can bring it back to foreground with fg)

if you want to see doorlock_change.sh doing something, put a couple of echo statements in the script.

H
Docker in Truenas scale, close to latest beta
DASHTICZ 🙃
RFXCOM, zwavejs2mqtt, zigbee2mqtt,
P1 meter & solar panel
Google home, Wifi Cams motion detection
Geofence iCloud, Bluetooth & Wifi ping
Harmony hub, Nest, lots more :-)
dimk
Posts: 27
Joined: Sunday 17 September 2017 17:30
Target OS: -
Domoticz version:
Contact:

Re: Nuki lock setup

Post by dimk »

Hello,

I do not know why, it dose not Work....

I have an other idea, is it possible to check the current lock Status via http://192.168.1.50:8080/lockState?nuki ... ken=123456, you will get return

“state”: 1,
“stateName”: “locked”,
“batteryCritical”: false,
“success”: true

With statename it is possible to set the domoticz Switch on or off via Jos command.

This should run every one or two minutes.

I have no idea to write an bash Script.
Maybe someone can help me to realize such Script.

Thanks in advance!!!!!
Martin

Gesendet von meinem MHA-L29 mit Tapatalk

RayAmsterdam
Posts: 115
Joined: Sunday 11 January 2015 16:40
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Nuki lock setup

Post by RayAmsterdam »

dimk wrote: Tuesday 19 September 2017 19:19 I have an other idea, is it possible to check the current lock Status via http://192.168.1.50:8080/lockState?nuki ... ken=123456, you will get return
This will drain the battery of your Nuki because every poll activates bluetooth communication between the bridge and your Nuki.
RayAmsterdam
Posts: 115
Joined: Sunday 11 January 2015 16:40
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Nuki lock setup

Post by RayAmsterdam »

dimk wrote: Tuesday 19 September 2017 19:19 I do not know why, it dose not Work....
Is the callback url (ip and port) correctly saved in the bridge?
dimk
Posts: 27
Joined: Sunday 17 September 2017 17:30
Target OS: -
Domoticz version:
Contact:

Re: Nuki lock setup

Post by dimk »

Thanks for the feedback.
I used the following command via terminal curl -s "http://BRIDGE IP:8080/callback/add?url=http%3A%2F%2F[IP_OF_YOUR_DOMO_SYSTEM]%3A[PORT_TO_LISTEN_ON_SUGGEST_15003]%2Fnuki&token=[API_TOKEN]". I got back success. How can i Check if nuki send a command after lock or unlock?

Thanks
Martin

Gesendet von meinem MHA-L29 mit Tapatalk

User avatar
heggink
Posts: 972
Joined: Tuesday 08 September 2015 21:44
Target OS: Raspberry Pi / ODroid
Domoticz version: 12451
Location: NL
Contact:

Re: Nuki lock setup

Post by heggink »

Hi dimk,

replace your doorlock_change.sh with the following script and then start it by hand with:

nohup sudo doorlock_change.sh &

Code: Select all

#!/bin/bash
# doorlock_change.sh
# listens on a port for nuki lock change messages

echo starting doorlock_change daemon

while :
do
	echo doorlock_change daemon listening on port 15003
	res=`nc -d -l 15003`
	ret=$?
	if [ -z "$res" ]; then
		logger Doorlock change received NULL response $ret and $res
		echo Doorlock change received NULL response $ret and $res
	else
		logger Doorlock change received message $res
		echo doorlock_change received message $res
		echo sending message to handle_doorlock_event
		echo ${res} | /usr/local/bin/handle_doorlock_event.sh &
	fi
done
to check if the callback url installed correctly, you can issue the command:

curl -s "http://IPOFYOURBRIDGE:8080/callback/lis ... =[APITOKEN]"
replace above with the IP address of the bridge and the token of the bridge.

In my case, that gives:
curl -s "http://192.168.1.xxx:8080/callback/list?token=mytoken"
{"callbacks": [{"id": 0, "url": "http://192.168.1.105:15003"}]}

Please paste what you get.

H
Docker in Truenas scale, close to latest beta
DASHTICZ 🙃
RFXCOM, zwavejs2mqtt, zigbee2mqtt,
P1 meter & solar panel
Google home, Wifi Cams motion detection
Geofence iCloud, Bluetooth & Wifi ping
Harmony hub, Nest, lots more :-)
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest