Bluetooth / iBeacon Presence Sensor with Raspberry Pi scanner

[quote=“WhyMe, post:19, topic:192938”]The Windows Bluetooth stack does not work correctly with lookup_name. Once cached, it does not seem to get removed. Using find_service will respond if the device is in range. So changing the following line:

found = bluetooth.lookup_name(phone, timeout=5) is not None

to

found = len(bluetooth.find_service(address = phone)) > 0

Interesting, I’ll check that on the linux install too, that might make more sense.

Yes, the ‘phone’ variable is the MAC address as a string - it’s actually the dictionary key of the known_phones dict.

I plan on making it smarter by looking at the types of devices it finds on the Vera, so if you are not looking for any ibeacon devices it won’t start that portion of the code.

[quote=“Mike Yeager, post:18, topic:192938”][quote=“daemondazz, post:13, topic:192938”]Yep, thanks for checking that :slight_smile:

Next question, can you run Python on the Plus, or is it going to require re-writing in Lua?[/quote]

No, unfortunately it would have to written in LUA. Seeing as I’m hoping to bring my RPi into the OpenLuup fold for inclusion into my Vera network, might not be necessary…[/quote]

Yeah, I’d really not like to start down the path of doing low-level bluetooth interactions in Lua, so for now I’ll leave the polling up to an external tool, such as the Pi.

I’ve just pushed a updates to my scanner script and PyVera to GitHub.

The scanner script update changes from using lookup_name to find_services as suggested by WhyMe and also fills out the README file a bit including instructions on how to install and update.

The PyVera update adds a few serviceIDs to the ignore list, including the AltUI and Deus Ex Machina ones reported by konradwalsh.

I’ve also added the licence file for GPLv3.

Hi guys,

New to PI and new to this script.
I’ve managed to follow to directions in the readme.
I was in SRV, downloaded all 3 from GIT.
I copied it so it starts on run.

However when I run it manually:
pi@raspberrypi:/srv/scanner $ sudo ./run_scanner.py
Traceback (most recent call last):
File “./run_scanner.py”, line 6, in
import bluetooth
ImportError: No module named bluetooth

My PI has bluetooth and is Raspbian.

Hi Joer, you’ll need to install the python bluetooth library:

$ sudo apt-get install python-bluetooth

[quote=“daemondazz, post:25, topic:192938”]Hi Joer, you’ll need to install the python bluetooth library:

$ sudo apt-get install python-bluetooth[/quote]

Awesome that worked.
Do you know the package name for blescan?
That was the next error.

I tried python-blescan. No go.

Are you trying to just run the script or use the systemd service file to start it?

The issue is that the ibeacon-scanner and pyvera folders need to be in the python path. The systemd file takes care of that, but if you’re trying to run the scanner script directly you’ll need to:

export PYTHONPATH=/srv/ibeacon-scanner:/srv/pyvera

Note that if you run that as the ‘pi’ user, sudo will not pass it through to the script, so you’ll need to get a root bash shell and then run the export and script.

[quote=“daemondazz, post:27, topic:192938”]Are you trying to just run the script or use the systemd service file to start it?

The issue is that the ibeacon-scanner and pyvera folders need to be in the python path. The systemd file takes care of that, but if you’re trying to run the scanner script directly you’ll need to:

export PYTHONPATH=/srv/ibeacon-scanner:/srv/pyvera

Note that if you run that as the ‘pi’ user, sudo will not pass it through to the script, so you’ll need to get a root bash shell and then run the export and script.[/quote]

Oh gotcha. I will use the systemd and have used that to start it. I think there is an issue and trying to find the logs. I was hoping running it manually would spit out some detail. I’ll give this a go when I get home tonight.

Ok Seems like I am getting further.

root@raspberrypi:/srv/scanner# ./run_scanner.py
Traceback (most recent call last):
File “./run_scanner.py”, line 28, in
v = vera.VeraLocal(VERA_IP)
File “/srv/pyvera/vera.py”, line 1716, in init
Vera.init(self)
File “/srv/pyvera/vera.py”, line 1338, in init
self.update_state()
File “/srv/pyvera/vera.py”, line 1411, in update_state
s.definition = SceneDefinition.parse(self, i)
File “/srv/pyvera/vera.py”, line 1039, in parse
sd.triggers.append(Trigger.parse(vera, i))
File “/srv/pyvera/vera.py”, line 482, in parse
t.device = vera.get_device_by_id(s[“device”])
File “/srv/pyvera/vera.py”, line 1464, in get_device_by_id
raise RuntimeError, “Device not found”
RuntimeError: Device not found

I have setup 2 of your pluggins in Vera.
I edited run_scanner.py with my Vera IP address.
I am on UI5.

I am trying to search for another log to investigate.
It would appear to have an issue trying to connect to my Vera?

There should not be any issue with running it manually as long as you set the environment up, and it’s definitely easier for debugging!

[quote=“joer., post:29, topic:192938”]Ok Seems like I am getting further.

root@raspberrypi:/srv/scanner# ./run_scanner.py
Traceback (most recent call last):
File “./run_scanner.py”, line 28, in
v = vera.VeraLocal(VERA_IP)
File “/srv/pyvera/vera.py”, line 1716, in init
Vera.init(self)
File “/srv/pyvera/vera.py”, line 1338, in init
self.update_state()
File “/srv/pyvera/vera.py”, line 1411, in update_state
s.definition = SceneDefinition.parse(self, i)
File “/srv/pyvera/vera.py”, line 1039, in parse
sd.triggers.append(Trigger.parse(vera, i))
File “/srv/pyvera/vera.py”, line 482, in parse
t.device = vera.get_device_by_id(s[“device”])
File “/srv/pyvera/vera.py”, line 1464, in get_device_by_id
raise RuntimeError, “Device not found”
RuntimeError: Device not found

I have setup 2 of your pluggins in Vera.
I edited run_scanner.py with my Vera IP address.
I am on UI5.

I am trying to search for another log to investigate.
It would appear to have an issue trying to connect to my Vera?[/quote]

I haven’t tried against UI5, as I don’t have any Vera running it. One of the fixes I made to the PyVera codebase was to coerce the ID value for comparison to an integer in that section of code, so there might be something else needing to be done.

Can you add the following statement above the raise RuntimeError at line 1464 in /srv/pyvera/vera.py

print type(id), type(self.devices[0].id), id, self.devices.keys()

And then paste the output back here?

Forgot to add, that traceback shows that PyVera is trying to load all the configuration from the Vera when it connects, so it’s not gotten into my code yet. It builds a local structure of the rooms, scenes and devices. It looks like you have a device in a scene that it’s not handling properly.

Traceback (most recent call last): File "./run_scanner.py", line 28, in <module> v = vera.VeraLocal(VERA_IP) File "/srv/pyvera/vera.py", line 1718, in __init__ Vera.__init__(self) File "/srv/pyvera/vera.py", line 1338, in __init__ self.update_state() File "/srv/pyvera/vera.py", line 1411, in update_state s.definition = SceneDefinition.parse(self, i) File "/srv/pyvera/vera.py", line 1039, in parse sd.triggers.append(Trigger.parse(vera, i)) File "/srv/pyvera/vera.py", line 482, in parse t.device = vera.get_device_by_id(s["device"]) File "/srv/pyvera/vera.py", line 1464, in get_device_by_id print type(id), type(self.devices[0].id), id, self.devices.keys() KeyError: 0

I am trying to analyse that code as well.

1453 def get_device_by_id(self, id): 1454 """ 1455 Return a Device object if one exists matching the provided ID. 1456 :param id: Device ID, an integer 1457 :return: A Device object 1458 """ 1459 if not isinstance(id, int): 1460 id = int(id) 1461 for i in self.devices: 1462 if self.devices[i].id == id: 1463 return self.devices[i] 1464 print type(id), type(self.devices[0].id), id, self.devices.keys() 1465 1466 raise RuntimeError, "Device not found"

Hmm, it’s not able to load your devices. Can you send me the output from

http://VERA_IP:3480/data_request?id=user_data&output_format=json

Link it somewhere and send me the link via PM if it’s too long.

[quote=“daemondazz, post:34, topic:192938”]Hmm, it’s not able to load your devices. Can you send me the output from

http://VERA_IP:3480/data_request?id=user_data&output_format=json

Link it somewhere and send me the link via PM if it’s too long.[/quote]

Sent you the link via PM.
Once we figure this out, I am happy to remove all of my posts.
I don’t love when a thread grows to 130 pages, its near impossible to find info.

Got it, will work through it shortly.

Not fussed about the posts, the troubleshooting process may help others :slight_smile:

I’ve just pushed an update to my fork of PyVera which hopefully addresses your issue. Change into your checkout and run a git pull.

I’ve just pushed an update to the scanner repository with a couple of changes. The first is that there is now an env.sh file that sets up the python path environment vaiable for you, all you need to do is source the file in your bash session:

$ source env.sh

The second change is that the scanner script will now only look for the types of devices it’s configured to, so if you don’t have any ibeacons configured then it won’t look for any.

I’ve been looking into getting the RSSI value out of bluetooth devices, but as far as I can work out, I need to do an inquiry scan, but the devices will only respond to that if they are in discoverable mode.

I’ve also been thinking about how to handle multiple Pi’s working together to increase coverage and think I might have a way of doing this.

Thanks I will update tonight when I get back from work.
I need to run the git pull on your fork of pyvera and scanner?

Ok updated both repos on my PI.
Put my VERA IP in.

I still needed to do the python path piece, cause I wasnt sure exactly what to do with the source env.sh.
Didn’t want to pollute our troubleshooting (your doin all the hard work) with my lack of knowledge.

Anyways I think we are further. Its pretty obvious now what went wrong this time:

Traceback (most recent call last):
  File "./run_scanner.py", line 25, in <module>
    v = vera.VeraLocal(VERA_IP)
  File "/srv/pyvera/vera.py", line 1718, in __init__
    Vera.__init__(self)
  File "/srv/pyvera/vera.py", line 1338, in __init__
    self.update_state()
  File "/srv/pyvera/vera.py", line 1411, in update_state
    s.definition = SceneDefinition.parse(self, i)
  File "/srv/pyvera/vera.py", line 1047, in parse
    sd.actions.append(Group.parse(vera, i))
  File "/srv/pyvera/vera.py", line 955, in parse
    aset.actions.append(Action.parse(vera, i))
  File "/srv/pyvera/vera.py", line 592, in parse
    s["service"]
RuntimeError: Don't know how to handle service urn:futzle-com:serviceId:CountdownTimer1

That is my countdowntimer pluggin.
I have quite a list of custom plugins:
CountdownTimer
PLEG
SONOS
UPNP
Weather
Temperature
Multiswitch
CombinationSwitch

So I went ahead and added
“urn:futzle-com:serviceId:CountdownTimer1”,
“urn:micasaverde-com:serviceId:MediaNavigation1”,

in the line 581 function.
That got my even further to another error:

root@raspberrypi:/srv/scanner# ./run_scanner.py Traceback (most recent call last): File "./run_scanner.py", line 25, in <module> v = vera.VeraLocal(VERA_IP) File "/srv/pyvera/vera.py", line 1720, in __init__ Vera.__init__(self) File "/srv/pyvera/vera.py", line 1340, in __init__ self.update_state() File "/srv/pyvera/vera.py", line 1413, in update_state s.definition = SceneDefinition.parse(self, i) File "/srv/pyvera/vera.py", line 1040, in parse for i in s["triggers"]: KeyError: 'triggers'

So I added a print statement right before line 1040.
I attached a doc with those results.
I think it may be choking on the fact I have LUA in a lot of my scenes?

I wasnt sure how to debug:
for i in s[“triggers”]:
sd.triggers.append(Trigger.parse(vera, i))

Thanks in advance if you have time to look into this.