Controlling danalock via openhab using old android phone

I’ve found the danalock v3 works unreliably on zwave and so wanted a backup system. Given the danalock bluetooth control is very reliable, I set up a bash script on a raspberry pi connected by USB to an old Nexus 4 phone.

Steps:

  1. Install the android debugging toolkit - sudo apt install android-tools-adb
  2. Build and install imagemagick - http://www.imagemagick.org/script/install-source.php - this is used by the bash script to check the colour of the lock icon in the app
  3. Put the android into developer mode and enable USB debugging
  4. Connect the android to the raspberry pi with a USB cable. I found for some weird reason only the cable that came with the phone worked
  5. The android will ask if you want to authorise the connection
  6. On the pi, enter “adb start-server”
  7. Check the connection with “adb devices”
  8. Install the danalock app on the android. Make sure bluetooth is on
  9. The following bash script will then start the danalock app, wait until the bluetooth connection is live, page through until it finds the specified lock, and then unlock it. This works for a Nexus 4 - for other phones with a different display resolution you will need to change the coordinates used for swiping and reading the lock icon colour.
#!/bin/bash

#quit app if running
adb shell am force-stop dk.polycontrol.ekey 

#restart app
adb shell monkey -p dk.polycontrol.ekey -c android.intent.category.LAUNCHER 1
sleep 1

echo now finding the lock called 'storage'

#Goes through the three locks (obviously if you have more/less than 3 then change the number below
 for i in `seq 1 3`; do
   echo Trying screen $i

   #read the text on each screen to see if the "storage" lock is there
   adb pull $(adb shell uiautomator dump | grep -oP '[^ ]+.xml') /tmp/view.xml
   if grep -q "storage" /tmp/view.xml; then

#    Keep running this loop until we have a bluetooth connection
     while true; do
      sleep 0.7    

#     Grab the screen
      adb shell screencap -p | perl -pe 's/\x0D\x0A/\x0A/g' > /tmp/screen.png
      output=$(convert /tmp/screen.png -crop '1x1+366+300' txt:-)
 
#     Check if the lock icon is red - if it is then unlock
      if [[ $output == *"59624"* ]]; then
         adb shell input tap 400 600
         echo unlocking
         sleep 5
         adb shell am force-stop dk.polycontrol.ekey 
         exit 1

#     And if the lock is already unlocked then do nothing
      elif [[ $output == *"42405"* ]]; then
         echo already unlocked
         break

#     And if the lock is greyed out then there is no connection, so retry
      elif [[ $output == *"64507"* ]]; then
        echo "App not yet ready - retrying"
      else
        echo "Some kind of error"
        # SET OPENHAB ERROR CODE HERE!
        break
      fi
    done
   else
    echo "Not storage"
  fi

# Swipe to next lock
  adb shell input swipe 750 600 300 600 500

done

Hope that’s helpful!

Dan

1 Like

And here’s a bash script to query the status of each of my three danalocks, updating openHAB items accordingly:

#!/bin/bash

#quit app if running
adb shell am force-stop dk.polycontrol.ekey	

#restart app
adb shell monkey -p dk.polycontrol.ekey -c android.intent.category.LAUNCHER 1
sleep 1

#Goes through the three locks
 for i in `seq 1 3`; do
	echo Trying $i

#	Find the colour
#	Keep pulling screen until not grey
	while true; do
		sleep 0.7
		adb shell screencap -p | perl -pe 's/\x0D\x0A/\x0A/g' > /tmp/screen.png

		output=$(convert /tmp/screen.png -crop '1x1+366+300' txt:-)
		echo "Reading is $output"
		if [[ $output == *"59624"* ]]; then
		  status="ON"
		  break
		elif [[ $output == *"42405"* ]]; then
		  status="OFF"
		  break
		elif [[ $output == *"64507"* ]]; then
		  echo "App not yet ready - retrying"
		else
		  echo "Some kind of error - will return with UNDEF"
		  status="UNDEF"
		  # SET OPENHAB ERROR CODE HERE!
		  break
		fi
	done

	#Which lock am I looking at?
	adb pull $(adb shell uiautomator dump | grep -oP '[^ ]+.xml') /tmp/view.xml
	if grep -q "door bottom" /tmp/view.xml; then
	    lock=DanaDoorStatus
	elif grep -q "door top" /tmp/view.xml; then
	    lock=DanaDoorStatus
	elif grep -q "storage" /tmp/view.xml; then
	    lock=DanaStorageStatus
	fi
	
	echo "Lock $lock set to $status"

#      now update openHAB
	wget -O /dev/null http://192.168.1.53:8080/classicui/CMD?$lock=$status

#      swipe to next lock
	adb shell input swipe 750 600 300 600 500
        
 done

# and quit app
adb shell am force-stop dk.polycontrol.ekey 

Hi Dan!
I’m new in commuity and making my first steps with openhab+mqtt+sonoff-tasmota.
Flashed some sonoffs, set up openhab on Raspberry 3 B+. Had configured openhab from zero 3-4 times and now I’m in state where I got 4 sonoffs working with Alexa and switching my lights! (Soo many hours till late night to get mqtt and sonoffs to work!). I have lately installed 3 Danalocks ( 2 v2 and 1 v3), managed by Android phone as bridge. Working over internet nicely. So, the next challenge would be to get them work with openhab (and Alexa) to order Alexa open or close all locks or more different choises…
My problem is, that my Danalocs have only bluetooth - is it possible to manage them with openhab thru this android phone and without z-wave? Hooked android phone to Raspberry, usb-debugging and adb-server running, Installed imagemagick on raspberry…But now I’m stuck - how to run bash script, where to put it, no clue… :slight_smile:
Is this job possible at all? If You have some time, can You help me? :wink:

how far did you get through the numbered steps above?

Hi!
Until step 8…
Dont know where to put bash script file and how to name it.
There must be switches/buttons in openhab, to open/close locks also?
Is it possible at all to make it work with only-bluetooth locks?

you can put the script anywhere.

I’d start by experimenting by running individual lines of the script and checking they are successfully controlling the danalock app. For example, does

adb shell monkey -p dk.polycontrol.ekey -c android.intent.category.LAUNCHER 1

start the app?

Also note that the above scripts were for the previous version of the danalock app. I am in the process of updating for the new one (the changes in the interface otherwise break the script)

Nice work, can’t wait? :slight_smile:
Will try scrip at home, in the evening!
I presume, the phones screen must be on?

[14:59:41] openhabian@openHABianPi:~$ adb shell monkey -p dk.polycontrol.ekey -c android.intent.category.LAUNCHER 1

  • daemon not running. starting it now on port 5037 *
  • daemon started successfully *
    bash arg: -p
    bash arg: dk.polycontrol.ekey
    bash arg: -c
    bash arg: android.intent.category.LAUNCHER
    bash arg: 1
    args: [-p, dk.polycontrol.ekey, -c, android.intent.category.LAUNCHER, 1]
    arg: “-p”
    arg: “dk.polycontrol.ekey”
    arg: “-c”
    arg: “android.intent.category.LAUNCHER”
    arg: “1”
    data=“dk.polycontrol.ekey”
    data=“android.intent.category.LAUNCHER”
    Events injected: 1

Network stats: elapsed time=42ms (0ms mobile, 0ms wifi, 42ms not connected)

Tried from work, thru SSH.

Danalock android app version 2.4.8

I think I turned screen off in the morning…

if the screen’s off you can use:

adb shell input keyevent 82 && adb shell input keyevent 66

But if it’s locked you’d need to unlock it - am not sure how to do that (I keep my dedicated android phone unlocked)

1 Like

you can then experiment sending commands, e.g.

Send text: adb shell input text "hello"
Make a single press on the screen: adb shell input tap 400 812 (or whichever pixel you want to push)

etc

and see the result by grabbing the text from the screen:

adb pull $(adb shell uiautomator dump | grep -oP '[^ ]+.xml') /tmp/view.xml

or capturing the image on the screen:

adb shell screencap -p | perl -pe 's/\x0D\x0A/\x0A/g' > /tmp/screen.png

I would play around with this and get a sense of what you can do before starting to put a bash script together.

Thanks, I’ll start immiedietly!

Yes, adb shell monkey -p dk.polycontrol.ekey -c android.intent.category.LAUNCHER 1
starts app on the phone!

Both bash scripts stop the app and not restart it…

sudo bash /etc/openhab2/scripts/danalock.sh

/etc/openhab2/scripts/danalock.sh: line 2: $’\r’: command not found
/etc/openhab2/scripts/danalock.sh: line 5: $’\r’: command not found
bash arg: -p
bash arg: dk.polycontrol.ekey
bash arg: -c
bash arg: android.intent.category.LAUNCHER
bash arg: 1
]rgs: [-p, dk.polycontrol.ekey, -c, android.intent.category.LAUNCHER, 1
arg: “-p”
arg: “dk.polycontrol.ekey”
arg: “-c”
arg: “android.intent.category.LAUNCHER”
"arg: "1
data=“dk.polycontrol.ekey”
data=“android.intent.category.LAUNCHER”
"* Error: Count is not a number: "1
sleep: invalid time interval ‘1\r’
Try ‘sleep --help’ for more information.
/etc/openhab2/scripts/danalock.sh: line 9: $’\r’: command not found
now finding the lock called KUUR
/etc/openhab2/scripts/danalock.sh: line 11: $’\r’: command not found
/etc/openhab2/scripts/danalock.sh: line 13: syntax error near unexpected token $'do\r'' 'etc/openhab2/scripts/danalock.sh: line 13: for i in seq 1 3; do

I think you may be using a Windows editor to create a text file, and Linux is rejecting the windows “end of line” character

See e.g. https://stackoverflow.com/questions/11616835/r-command-not-found-bashrc-bash-profile

I use Visual Studio Code, but I’ll check in the evening…
Could Android Studio ( ADB ) install on Windows help me find the problem?

it’s not an ADB problem - that error is definitely a bash error and usually caused by windows/dos line endings.

Try using a linux editor (e.g. nano) and see if that fixes it

How about openhab-danalock bluetoot addon, Z-wave connection to danalock exists…
Also is sort of working Alexa -IFTTT - Danalock connection, with 6-7 sec first attempt, usually 2-4 minutes! delay.
What possibility is to connect Danalock server straight to openhab Raspberry Pi - there is BT on board?
Mine 3 locks are all in 2-4 meters from Raspberry…In Openhab I see the BT adresses of locks…