Getting started detecting Bluetooth LE Devices on OH2

Tags: #<Tag:0x00007f6182926720> #<Tag:0x00007f6182926658>

I’ve just installed BlueZ onto my Pi3, and I’d like to get a switch in OH2 to operate when a particular device is present. I can see the devices I want using

sudo hcitool lescan

and also using a Bluetooth LE scanner on my phone. it seems that my tiles may be broadcasting every few seconds which makes them ideal for presence detection.
I’m unsure how to progress further. I found sensorReporter by @rlkoshak which could do the trick but for some reason I can’t get it working on my pi.

I’ve also found an openhab binding that is being worked on

Has anyone else got Bluetooth LE Device detection working, or can help me with this? I’m happy to test things too.

Ideally I’d like to detect the presence of Tiles from their broadcast packets so I can use them as presence information.

Personally I run a nodejs script via cron that checks the status of predefined BT devices - both BT & BTLE. If the script finds any it then pushes the info into my MQTT broker where I can pick it up in OH2.

1 Like

What exactly is the problem you have installing it? From the readme:

The install script shows the install steps to get the dependencies using using apt-get and pip and to copy and enable the start script to init.d so sensorReporter will start as a service during boot. You must edit the script to match your system. This script is intended to be informational, not to be executed as is.

Did you edit the script to work for your system or just try to run it blindly without editing it?

What error(s) are you seeing?

I get after starting the service and then checking the status

sensorReporter.service - Reports status and sensor readings over MQTT and REST
Loaded: loaded (/etc/systemd/system/sensorReporter.service; enabled)
Active: failed (Result: exit-code) since Tue 2017-07-18 07:29:18 NZST; 3s ago
Process: 30428 ExecStart=/opt/sensorReporter/sensorReporter.py /opt/sensorReporter/sensorReporter.ini (code=exited, status=1/FAILURE)
Main PID: 30428 (code=exited, status=1/FAILURE)

Jul 18 07:29:18 jessie sensorReporter.py[30428]: main()
Jul 18 07:29:18 jessie sensorReporter.py[30428]: File "/opt/sensorReporter/sensorReporter.py", line 71, in main
Jul 18 07:29:18 jessie sensorReporter.py[30428]: loadConfig(sys.argv[1])
Jul 18 07:29:18 jessie sensorReporter.py[30428]: File "/opt/sensorReporter/sensorReporter.py", line 178, in loadConfig
Jul 18 07:29:18 jessie sensorReporter.py[30428]: configLogger(config.get("Logging", "File"),
Jul 18 07:29:18 jessie sensorReporter.py[30428]: File "/usr/lib/python2.7/ConfigParser.py", line 607, in get
Jul 18 07:29:18 jessie sensorReporter.py[30428]: raise NoSectionError(section)
Jul 18 07:29:18 jessie sensorReporter.py[30428]: ConfigParser.NoSectionError: No section: 'Logging'
Jul 18 07:29:18 jessie systemd[1]: sensorReporter.service: main process exited, code=exited, status=1/FAILURE
Jul 18 07:29:18 jessie systemd[1]: Unit sensorReporter.service entered failed state.

I ran the following commands from the install script

pip install paho-mqtt    # it was already installed
sudo apt-get install bluez python-bluez #blues was already installed, python-bluez was added
sudo cp ./config/sensorReporter.service /etc/systemd/system
sudo systemctl enable sensorReporter.service
cd ..
sudo ln -s `pwd` /opt/sensorReporter
chmod a+x /opt/sensorReporter/sensorReporter.py
ln -s $HOSTNAME.ini /opt/sensorReporter/sensorReporter.ini
sudo cp ./config/sensorReporter.service /etc/systemd/system
sudo systemctl enable sensorReporter.service

I haven’t changed anything in the config file yet, and I’m assuming I don’t need to load “scapy” or “subprocess32” for bluetooth use only?

If you look at the third line from the bottom you will see that it created a link from $HOSTNAME.ini to sensorReporter.ini and the start script will pass sensorReporter.ini as the configuration file.

I suspect you didn’t have a $HOSTNAME.ini file to link from so your are passing an empty file to sensorReporter which will lack certain required initialization sections, including the Logging section.

That is correct, you do not need scapy or subprocess32 if you will only use Bluetooth sensors.

OK, I’ve deleted the link and created /opt/sensorReporter/sensorReporter.ini with my hostname in it as for some reason the link was saying it couldn’t access the file. Now I have

 Jul 18 08:06:41 jessie sensorReporter.py[4059]: config.read(configFile)
Jul 18 08:06:41 jessie sensorReporter.py[4059]: File "/usr/lib/python2.7/ConfigParser.py", line 305, in read
Jul 18 08:06:41 jessie sensorReporter.py[4059]: self._read(fp, filename)
Jul 18 08:06:41 jessie sensorReporter.py[4059]: File "/usr/lib/python2.7/ConfigParser.py", line 512, in _read
Jul 18 08:06:41 jessie sensorReporter.py[4059]: raise MissingSectionHeaderError(fpname, lineno, line)
Jul 18 08:06:41 jessie sensorReporter.py[4059]: ConfigParser.MissingSectionHeaderError: File contains no section headers.
Jul 18 08:06:41 jessie sensorReporter.py[4059]: file: /opt/sensorReporter/sensorReporter.ini, line: 1
Jul 18 08:06:41 jessie sensorReporter.py[4059]: 'jessie\n'
Jul 18 08:06:41 jessie systemd[1]: sensorReporter.service: main process exited, code=exited, status=1/FAILURE
Jul 18 08:06:41 jessie systemd[1]: Unit sensorReporter.service entered failed state.

Does sensorReporter,ini have to be a link or is just recreating the file OK. I’ve used the hostname that comes up in the command prompt, is this correct? In the logs above the hostname is “jessie”

You can just create sensorReporter.ini directly. The step that makes the link was a trick I used because I deploy sensorReporter to half a dozen machines each with its own separate config file. So I link the config file for a given host to sensorReporter.ini and can reuse the same start script.

So what you need to do is just copy what ever .ini file you want to use to sensorReporter.ini and just use that one file.

That is because the link pointed to a file that doesn’t exist.

That makes sense, so sensorReporter.ini should just contain the hostname?
Any idea what the rest of the errors mean? To my very untrained eye it seems that the config file has a problem with missing headers, but is this in /opt/sensorReporter/sensorReporter.ini or /opt/sensorReporter/default.ini?

No. sensorReporter.ini should contain your configuration.

Use default.ini, which provides an example of all the sections and configuration options to populate sensorReporter.ini with a proper config for your setup.

NOTE: there is one bug which I thought I checked in but apparently have not. There is a missing Syslog parameter under Logging in default.ini that is required.

Here is an example sensorReporter.ini from one of my systems:

[Sensor1]
Class = rpiGPIOSensor.rpiGPIOSensor
Pin = 7
Connection = MQTT
Destination = entry_sensors/main/garage/door1
PUD = DOWN
Poll = 0.5

[Sensor2]
Class = rpiGPIOSensor.rpiGPIOSensor
Pin = 8
Connection = MQTT
Destination = entry_sensors/main/garage/door2
PUD = DOWN
Poll = 0.5

[Sensor3]
Class = bluetoothScanner.btSensor
Address = FF:EE:DD:CC:BB:AA
Connection = MQTT
Destination = presence_sensors/bluetooth/garageRich
Poll = 15
Mode = RSSI
Max = 20
Near = 3
Far = 15

[Sensor4]
Class = bluetoothScanner.btSensor
Address = AA:BB:CC:DD:EE:FF
Connection = MQTT
Destination = presence_sensors/bluetooth/garageJenn
Poll = 15
Mode = RSSI
Max = 20
Near = 3
Far = 15

[Sensor5]
Class: heartbeat.heartbeat
Type: Heartbeat
Connection: MQTT
Poll: 300
Num-Dest: status/cerberos/heartbeat/number
Str-Dest: status/cerberos/heartbeat/string

[Actuator1]
Class = rpiGPIOActuator.rpiGPIOActuator
Connection = MQTT
Pin = 17
Topic = actuators/garage1
Toggle = True
; The 0 indicates no polling and no separate thread is needed to run the listener
Poll = 0

[Actuator2]
Class = rpiGPIOActuator.rpiGPIOActuator
Connection = MQTT
Pin = 22
Topic = actuators/garage2
Toggle = True
; The 0 indicates no polling and no separate thread is needed to run the listener
Poll = 0

[Logging]
File = /opt/sensorReporter/log/sensorReporter.log
MaxSize = 67108864
NumFiles = 10
Syslog = NO

[Connection1]
Class = mqttConn.mqttConnection
Name = MQTT
User = user
Password = passwd
Host = mosquitto-host
Port = 1883
TLS = NO
Keepalive = 60
Topic = entry_sensors/getUpdate
LWT-Topic = status/sensor-reporters
LWT-Msg = cerberos sensorReporter is dead

Thanks, I’ve copied your file into sensorReporter.ini and changed the logging to a valid location on my system /var/log/sensorReporter.log and it is started.

I can now detect my phone when it is in pairing mode with inquiry.py

Is it possible to detect the presence of BLE stuff with this? I can see them in my phone using a BLE Scanner app, that just gives me a UUID rather than a MAC address. Ultimately I’d like to detect the presence of BLE devices such as Tiles and cheap iBeacon.

I think so but don’t know for sure. If the Python-Bluez library supports it then yes.

A quick google suggests that the support depends on the version. There is something on GIT here
https://github.com/IanHarvey/bluepy but getting it to work with your script is way beyond my knowledge!
Does the stuff on GIT make sense to you? Is it likely to give access to UUID’s without rewriting?
If I can find a way of getting iBeacon presence into OpenHAB I can buy a couple of cheap beacons off AliExpress, chuck them in the car glovebox and I will have easy car presence detection, or at least that’s the theory!

I don’t have time right now to study it. The script as written detects devices based on their MAC address. If the device isn’t transmitting or its MAC cannot be detected the script will not work with it.

No worries, thanks again for helping me get this far. I’ll experiment to see whether it can reliably find the car bluetooth phone interface.

To update this a bit I’ve combined it with the Network Binding to see whether my iPhone is present or not. The combination of both detection types is enough to steer my presence logic better than using either of them alone. I couldn’t detect the cars bluetooth systems when they were out of pairing mode.

Could you share the scripts you ended up using which are working for you?

I got one Bluetooth Beacon for each of my rooms and want to realize an indoor localization.
I use iPhone.

I no longer use BT for presence detection. Recent changes to the Network binding are sufficient for my needs.

The script discussed above is https://github.com/rkoshak/sensorReporter

But this works backwards from what you are describing. You would need one BT receiver (e.g. a Raspberry Pi) in each room. To use beacons you need to run something on your iPhone.

I’ve gone the same route as @rlkoshak for presence detection, although I did do a bit of testing with OwnTracks and bluetooth beacons along the way.
The problem with using an iphone to detect what room you are in is that it spends a lot of its time sleeping without detecting anything other than incoming phone calls / txts etc. Owntracks can detect bluetooth beacons and pass this on to OpenHAB via the Owntracks binding, however when I tried it there was a lag and also a very noticeable battery penalty because the iphone spends less of its time sleeping. The battery penalty may be OK if you have one of the latest phones, but on my iPhone 6 the 2 problems combined meant I gave up on detecting what room I was in. There is a good article to read on room detection with Owntracks here http://jpmens.net/2015/06/03/beacons-in-the-office/
Please update the thread if you get anything that works well.
I’ve also found these https://www.happybubbles.tech/presence/detector along the way that can detect what room you are in and report the signal strength using MQTT. They have a presence server that uses a combination of signal strength from more than one beacon to guess where you are. You do need to carry a bluetooth beacon however, and the MQTT server receives a lot of messages which may impact its reliability if you use it for a lot of other things.