Howdy, I’m Blaine Carter Oracle Corpora on Developer Advocate for Open Source Email:
[email protected] Blog: learncodeshare.net Twi er: @OraBlaineOS YouTube: www.youtube.com/blainecarter Team: community.oracle.com/docs/DOC-917690
Beacon Tracking on a Budget
Bluetooth Low Energy Beacon Typical broadcast data: Major: 4 Minor: 6597 UUID: 6b12c4274890 RSSI: -81 TX: -59
Calculate the distance to the beacon using tx and rssi
function calculateDistance(uuid, rssi) { var txPower = -59; var distance; if (rssi === 0) { return -1.0; } var ratio = rssi * 1.0 / txPower; if (ratio < 1.0) { distance = Math.pow(ratio, 10); } else { distance = (0.89976) * Math.pow(ratio, 7.7095) + 0.111; }
h ps://stackoverflow.com/a/20434019/1296150
Rolling Average var distanceQueues = {}; //Stored outside of the function if (distanceQueues.hasOwnProperty(uuid) === false) { distanceQueues[uuid] = (Array.apply(null, Array(5))) .map(function() {return distance;}); } else { distanceQueues[uuid].push(distance); distanceQueues[uuid].shift(); }
{ "0d60a289203": [2.3, 2.5, 2.1, 2.4, 2.4], "5a364a32456c": [1.7, 2.5, 1.6, 1.8, 1.4] }
Weighted Average ... var sum = 0; var weight = 0; for (var i = 0; i < distanceQueues[uuid].length; i++) { sum += (i + 1) * distanceQueues[uuid][i]; weight += i + 1; } var avg = sum / weight; return avg; }
Normal Average: (3 + 4 + 3 + 5 + 2) = 3.4 5
Weighted Average: ((0 + 1) ∗ 3 + (1 + 1) ∗ 4 + (1 + 2) ∗ 3 + (1 + 3) ∗ 5 + (1 + 4) ∗ 2) = 3.3 ((0 + 1) + (1 + 1) + (1 + 2) + (1 + 3) + (1 + 4))
Install Raspbian using Etcher
Enable SSH touch /boot/ssh
Authorize an RSA Key
Add your key to ~/.ssh/authorized_keys install -d -m 700 /rootfs/home/pi/.ssh cat ~/.ssh/id_rsa.pub >> /rootfs/home/pi/.ssh/authorized_keys
Setup WIFI Edit /roo s/etc/wpa_supplicant/wpa_supplicant.conf network={ ssid="Your SSID" psk="YourWPAPassword" key_mgmt=WPA-PSK }
Update Raspbian 1. Put the SD card in your Raspberry Pi 2. Boot it up 3. SSH to pi ssh
[email protected] 4. Change password (default password: raspberry) passwd
5. Run an update sudo apt-get update
Install Bluetooth Libraries sudo apt-get install -y bluetooth bluez libbluetooth-dev libudev-dev
Install Node.js Remove pre-installed Node (if any) sudo apt-get remove --purge npm node nodejs
Node Version Manager curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash source .bashrc nvm install node node -v npm -v
Allow Node to access bluetooth sudo setcap cap_net_raw+eip $(eval readlink -f `which node`)
Setup Environment Variables SCANNER_ID – The ID for this scanner. BEACON_UUID – UUID of the beacon you’re tracking. IFTTT_KEY – your account key for IFTTT ORDS_URI – http://example.com/ords/beacon/beacon/alert/
Scan For a Beacon var bu = require('./beaconUtil.js'); var bleacon = require('bleacon'); var beaconId = process.env.BEACON_UUID;
bleacon.startScanning(beaconId); bleacon.on('discover', function(bleacon) { var uuid = bleacon.uuid, major = bleacon.major, minor = bleacon.minor, rssi = bleacon.rssi, accuracy = bleacon.accuracy.toFixed(2), proximity = bleacon.proximity, distance = 0; distance = bu.calculateDistance(uuid, rssi).toFixed(2); console.log("UUID: " + uuid + "\nMajor:" + major + "\nMinor:" + minor + "\nrssi:" + bleacon.rssi + "\naccuracy:" + accuracy + "\nProximity:" + proximity + "\nDistance:" + distance + "\n\n"); });
Trigger an Ac on var var var var
bu = require('./beaconUtil.js'); bleacon = require('bleacon'); beaconId = process.env.BEACON_UUID; scannerID = process.env.SCANNER_ID;
bleacon.startScanning(process.env.BEACON_UUID); bleacon.on('discover', function(bleacon) { var uuid = bleacon.uuid, major = bleacon.major, minor = bleacon.minor, rssi = bleacon.rssi, accuracy = bleacon.accuracy.toFixed(2), proximity = bleacon.proximity, distance = 0; distance = bu.calculateDistance(bleacon.uuid, bleacon.rssi).toFixed(2); //Process the alert action if (distance < 2) { bu.iftttNotify('LeftRoom', scannerID, beaconId, distance); } });
Home Automa on Messages - IFTTT (If This Then That) - h ps://i
.com
Home Assistant - h ps://home-assistant.io Deadbolt Sonos
Oracle REST Data Services begin ords.enable_schema( p_enabled => true, p_schema => 'BEACON', p_url_mapping_type => 'BASE_PATH', p_url_mapping_pattern => 'beacon', p_auto_rest_auth => false); ords.define_module( p_module_name => 'Beacon', p_base_path => '/beacon/', p_items_per_page => 25, p_status => 'PUBLISHED'); ords.define_template( p_module_name => 'Beacon', p_pattern => 'scan', p_priority => 0, p_etag_type => 'HASH', p_etag_query => null); ords.define_handler( p_module_name => 'Beacon', p_pattern => 'scan', p_method => 'GET', p_source_type => 'json/query', p_items_per_page => 25,
p_mimes_allowed p_source commit; end;
=> '', => 'select * from reading order by created_on');
Consume Rest API var var var var var var
bu = require('./beaconUtil.js'); bleacon = require('bleacon'); beaconId = process.env.BEACON_UUID; scannerID = process.env.SCANNER_ID; request = require('request'); ordsUri = process.env.ORDS_URI;
//get the alerts for this scanner var alerts = []; request.get({ url: ordsUri + 'alert/' + scannerID, json: true }, function(err, res, body) { if (err) { console.log(err); } alerts = body; bleacon.startScanning(process.env.BEACON_UUID); console.log('Scanning:', alerts); }); bleacon.on('discover', function(bleacon) { var uuid = bleacon.uuid, major = bleacon.major, minor = bleacon.minor, i bl i
My beaconScan Repository h ps://github.com/bcarter/beaconScan
There's more we could do What if you want to map the beacon loca on?
Table Data scanner_id beacon_id distance created_on 5 myBeacon 4.72 27-AUG-17 04.19.58.082247 PM 7 myBeacon 6.57 27-AUG-17 04.19.58.780495 PM
6 7 6 5 7 5 6 6 7 5 6 7 7 6 5 7
myBeacon myBeacon myBeacon myBeacon myBeacon myBeacon myBeacon myBeacon myBeacon myBeacon myBeacon myBeacon myBeacon myBeacon myBeacon myBeacon
4.64 5.84 4.8 4.8 6.65 5.36 4.71 3.95 6.41 5.12 4.21 5.92 6.85 4.69 5.5 5.88
27-AUG-17 04.19.58.780855 PM 27-AUG-17 04.19.59.270639 PM 27-AUG-17 04.19.59.279716 PM 27-AUG-17 04.19.59.489140 PM 27-AUG-17 04.19.59.538878 PM 27-AUG-17 04.20.00.187193 PM 27-AUG-17 04.20.00.239919 PM 27-AUG-17 04.20.00.240297 PM 27-AUG-17 04.20.00.908366 PM 27-AUG-17 04.20.00.949043 PM 27-AUG-17 04.20.01.072711 PM 27-AUG-17 04.20.01.630422 PM 27-AUG-17 04.20.01.667588 PM 27-AUG-17 04.20.02.347791 PM 27-AUG-17 04.20.02.348201 PM 27-AUG-17 04.20.02.349190 PM
Round to the nearest X Round mestamps to the nearest 5 seconds select round(((cast(created_on as date) - date '1970-01-01') *24*60*60) /5) * 5 from reading order by 2;
1. (cast(created_on as date) - date '1970-01-01') 2. *24*60*60 3. round((...)/5) 4. * 5 h ps://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:13946369553642
Trilatera on r1
P1
r2
(0,0) d
P2 (d,0)
Intersections x positive right y positive down
r3
j i
(i,j) P3
Scanning with Raspberry Pi
Raspberry Pi Zero W
Raspberry Pi Zero W
Raspberry Pi 3
Oracle Spa al sdo_geometry OBJECT (SDO_GTYPE NUMBER, SDO_SRID NUMBER, SDO_POINT SDO_POINT_TYPE, SDO_ELEM_INFO SDO_ELEM_INFO_ARRAY, SDO_ORDINATES SDO_ORDINATE_ARRAY); sdo_geometry(2003, null, null, mdsys.sdo_elem_info_array(1, 1003, 3), mdsys.sdo_ordinate_array(x,y, x,y))
Draw a circle using x, y, radius Convert x, y + radius into 3 points on the circle mdsys.sdo_geometry( 2003, null, null, mdsys.sdo_elem_info_array(1, 1003, 4), mdsys.sdo_ordinate_array( (x - rad), y, x, (y + rad), (x + rad), y ));
Intersec ng Polygons
SDO_GEOM.SDO_INTERSECTION(sdo_geometry(2003, null, null, mdsys.sdo_elem_info_array(1, 1003, 3), mdsys.sdo_ordinate_array(0,0, 10,10)), beacon_tools.circle(0, 0, 5), 0.005)
Beacon Enters a Pre-Defined Zone Define zones using polygons. select zone from restricted_areas where SDO_OVERLAPBDYINTERSECT(zone, beacon_tools.location('beacon1','someTimestamp'));
Recap