I have to dash away from the computer frequently, and I want to trigger some commands to run when my iPhone is close enough/far enough from my iMac (next to it vs. 2-3 metres away/other side of a wall). A couple of minutes latency is fine.
Partial solution: proximity
I've downloaded reduxcomputing-proximity and it works, but this only triggers when the device goes in to/out of range of bluetooth, but my desired range is much smaller.
(Proximity polls [IOBluetoothDevice -remoteNameRequest]
to see if the device is in bluetooth range or not.)
Enhancement: rawRSSI
I've used [IOBluetoothDevice -rawRSSI]
to get the RSSI when I am connected to the iPhone (when disconnected this just returns +127
), but in order to save the battery life of my iPhone I'd rather avoid establishing a full bluetooth connection.
Am I correct in thinking that maintaining a connection will consume more battery life than just polling every couple of minutes?
I've overridden the isInRange
method of proximity
here to give me a working solution that's probably relatively battery intensive compared to the previous remoteNameRequest:
method:
- (BOOL)isInRange {
BluetoothHCIRSSIValue RSSI = 127; /* Valid Range: -127 to +20 */
if (device) {
if (![device isConnected]) {
[device openConnection];
}
if ([device isConnected]) {
RSSI = [device rawRSSI];
[device closeConnection];
}
}
return (RSSI >= -60 && RSSI <= 20);
}
(Proximity uses synchronous calls - if and when I fit it to my needs I will edit it to be asynchronous but for now that's not important.)
Under Linux: l2ping - inquiry scan?
This SO post references getting an RSSI during an 'inquiry scan' which sounds like what I want, but it talks about using the Linux Bluez library, whilst I am on a Mac - I'd rather do it without having to stray too far if possible! (I have considered using a VM with USB pass-thru to hook up a second bluetooth device... But a simpler solution would be preferable!)
I see there is a IOBluetoothDeviceInquiry
class, but I am not sure if this is useful to me. I don't intend to learn bluetooth protocol just for this simple problem!
The commands
For interest, and not particularly relevant to the solution, here are the Apple Scripts I currently trigger when
in range:
tell application "Skype"
send command "SET USERSTATUS ONLINE" script name "X"
do shell script "afplay '/System/Library/Sounds/Blow.aiff'"
end tell
out of range:
tell application "Skype"
send command "SET USERSTATUS AWAY" script name "X"
do shell script "afplay '/System/Library/Sounds/Basso.aiff'"
end tell
Though these are likely to get longer!
isInRange
method above with a 30-60s delay between calls then that's a fairly efficient way of doing it? (I'm not worried about the iMac's power drain, only the iPhone.) I've been running it a few days now and it doesn't seem to be draining the battery much faster, but it's hard to tell. – Millesimal