Create a gist now

Instantly share code, notes, and snippets.

Use your Debian System as an iBeacon for Home Automation

Use your Debian System with as an iBeacon for Home Automation

Introduction

I have been playing with using the https://Home-Assistant.io system at home to play with Home Automation.

One thing I've found is that the Raspberry Pi is perfect for quite a few of the monitoring things that I wanted it to do (see also https://github.com/JonTheNiceGuy/home-assistant-configs for more details of what I'm doing there!).

I'm using the http://OwnTracks.org application to talk to an MQTT server, but I could also do with it knowing where I am in the house, so I looked around for some details on iBeacons.

iBeacon is an Apple standard, but it's very easy to configure on Linux systems. I took some pointers from this article and wrote up this script.

Configuring the Script

When you first run it as root, it will pre-populate a config file in /etc/iBeacon.conf. Edit it and run the script again.

Running the script

This script needs to be run as root, so to test it, or to reconfigure the beacon, run sudo /root/iBeacon.sh (or wherever you put it!)

Making it persistent

To be honest, at this point, I'd probably just stick this into my root Crontab file by adding this line:

@reboot /root/iBeacon.sh | logger

Again, replace /root/iBeacon.sh with wherever you put it!

#! /bin/bash
# Based on http://www.wadewegner.com/2014/05/create-an-ibeacon-transmitter-with-the-raspberry-pi/
# This snip thanks to https://www.cyberciti.biz/tips/shell-root-user-check-script.html
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" 1>&2
exit 1
fi
######################################################################################
## Read Config Or Die
######################################################################################
if [ -f /etc/iBeacon.conf ]; then
. /etc/iBeacon.conf
else
echo "An /etc/iBeacon.conf file has been created for you with the following values:"
echo "###################################"
echo "# Config File"
echo "###################################"
echo " "
echo "Beacon_Name=NameOfBeacon" > /etc/iBeacon.conf
echo " " >> /etc/iBeacon.conf
echo "# A UUID has been generated for you, using the following command. Feel free" >> /etc/iBeacon.conf
echo "# to replace this with your own value, or run it again for your own values." >> /etc/iBeacon.conf
echo "# " >> /etc/iBeacon.conf
echo "# python -c 'import sys,uuid;sys.stdout.write(uuid.uuid4().hex)'" >> /etc/iBeacon.conf
echo " " >> /etc/iBeacon.conf
echo "Beacon_UUID=`python -c 'import sys,uuid;sys.stdout.write(uuid.uuid4().hex)'`" >> /etc/iBeacon.conf
echo " " >> /etc/iBeacon.conf
echo "# Major and minor can be 0-65534, set as two octets (01-FF)" >> /etc/iBeacon.conf
echo "# 1 = 00 01" >> /etc/iBeacon.conf
echo "# 255 = 00 ff" >> /etc/iBeacon.conf
echo "# 256 = 01 00" >> /etc/iBeacon.conf
echo "# 65535 = ff ff" >> /etc/iBeacon.conf
echo " " >> /etc/iBeacon.conf
echo "# Major represents new \"site\" or building. The default value here is \"1\"" >> /etc/iBeacon.conf
echo "major0=00" >> /etc/iBeacon.conf
echo "major1=01" >> /etc/iBeacon.conf
echo "# Minor is a specific place in that site. Again the default value here is \"1\"" >> /etc/iBeacon.conf
echo "minor0=00" >> /etc/iBeacon.conf
echo "minor1=01" >> /etc/iBeacon.conf
echo " " >> /etc/iBeacon.conf
echo "# RSSI is what the power should be seen as by the receiver at 1m from transmitter" >> /etc/iBeacon.conf
echo "# However, this is more-or-less a magic number until calibrated, and I have found" >> /etc/iBeacon.conf
echo "# no concrete details on how to calculate this. Run your own tests! The Locate app" >> /etc/iBeacon.conf
echo "# from https://play.google.com/store/apps/details?id=com.radiusnetworks.locate" >> /etc/iBeacon.conf
echo "# has a calibration feature. The value found in the script this code was derived from" >> /etc/iBeacon.conf
echo "# specifies this value, and it appears accurate for my RPi3." >> /etc/iBeacon.conf
echo " " >> /etc/iBeacon.conf
echo "rssi=c8" >> /etc/iBeacon.conf
echo " " >> /etc/iBeacon.conf
echo "## If you want to publish a \"waypoints\" file, please populate the following values" >> /etc/iBeacon.conf
echo "# Your Location Lat/Long" >> /etc/iBeacon.conf
echo "latitude=0.000000" >> /etc/iBeacon.conf
echo "longditude=0.000000" >> /etc/iBeacon.conf
echo "# The radius that this beacon is considered to be valid for" >> /etc/iBeacon.conf
echo "radius=2" >> /etc/iBeacon.conf
echo "# The timestamp this file was *FIRST* published" >> /etc/iBeacon.conf
echo "timestamp=`date +%s`" >> /etc/iBeacon.conf
echo " " >> /etc/iBeacon.conf
echo "# Where to output the result of this" >> /etc/iBeacon.conf
echo "OutputForIPhone=0" >> /etc/iBeacon.conf
echo "OutputWaypointsFile=1" >> /etc/iBeacon.conf
echo "OutputWaypointsFilePath=`find / -name www_static 2>/dev/null`" >> /etc/iBeacon.conf
cat /etc/iBeacon.conf
echo " "
echo "###################################"
echo "# End Config File"
echo "###################################"
echo "Please edit this file (/etc/iBeacon.conf) and run this script again."
exit 1
fi
######################################################################################
## Convert config to usable values
######################################################################################
# Explode the uuid into component parts
# based losely on http://stackoverflow.com/a/23664252
if [[ $Beacon_UUID =~ (..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..) ]]; then
H0=${BASH_REMATCH[1]}
H1=${BASH_REMATCH[2]}
H2=${BASH_REMATCH[3]}
H3=${BASH_REMATCH[4]}
H4=${BASH_REMATCH[5]}
H5=${BASH_REMATCH[6]}
H6=${BASH_REMATCH[7]}
H7=${BASH_REMATCH[8]}
H8=${BASH_REMATCH[9]}
H9=${BASH_REMATCH[10]}
HA=${BASH_REMATCH[11]}
HB=${BASH_REMATCH[12]}
HC=${BASH_REMATCH[13]}
HD=${BASH_REMATCH[14]}
HE=${BASH_REMATCH[15]}
HF=${BASH_REMATCH[16]}
fi
######################################################################################
## Render for output later
######################################################################################
strUUID="${H0}${H1}${H2}${H3}-${H4}${H5}-${H6}${H7}-${H8}${H9}-${HA}${HB}${HC}${HD}${HE}${HF}"
# thanks to http://stackoverflow.com/a/22863296
strMajor=$((0x${major0}${major1}))
strMinor=$((0x${minor0}${minor1}))
strConfigUrl="owntracks:///beacon?name=${Beacon_Name}&uuid=${strUUID}&major=${strMajor}&minor=${strMinor}"
######################################################################################
## Configure the HCI device
######################################################################################
hciconfig hci0 up > /dev/null
hciconfig hci0 leadv3 > /dev/null 2&> /dev/null
hciconfig hci0 noscan > /dev/null
hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 $H0 $H1 $H2 $H3 $H4 $H5 $H6 $H7 $H8 $H9 $HA $HB $HC $HD $HE $HF $major0 $major1 $min$
######################################################################################
## Produce Output
######################################################################################
NOOUTPUT=true
# Report
if [ "$OutputForIPhone" == "1" ]; then
echo "$strConfigUrl"
NOOUTPUT=false
if which qrencode >/dev/null; then
# thanks to http://www.linux-magazine.com/Online/Features/Generating-QR-Codes-in-Linux
qrencode -t ANSI256 "$strConfigUrl"
fi
fi
if [ "$OutputWaypointFile" == "1" ]; then
NOOUTPUT=true
# THIS ISN'T DONE YET!!
#
# Save this blob as waypoint.otrw
# according to http://owntracks.org/booklet/tech/json/#_typewaypoints
#{
# "_type": "waypoints",
# "_creator": "OTwpDraw",
# "waypoints": [
# {
# "_type": "waypoint",
# "tst": epochtime,
# "lat": x.xx,
# "lon": y.yy,
# "rad": zzz,
# "desc": "desc",
# "uuid": "",
# "major": xx,
# "minor": xx
# }
# ]
#}
fi
if [ "$NOOUTPUT" == "true" ]; then
echo "Beacon Name : ${Beacon_Name}"
echo "Beacon UUID : ${strUUID}"
echo "Beacon Major: ${strMajor}"
echo "Beacon Minir: ${strMinor}"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment