diff --git a/app/js/device/CC2650/cc2650_accelerometer.js b/app/js/device/CC2650/cc2650_accelerometer.js
index d724221..c7edec7 100644
--- a/app/js/device/CC2650/cc2650_accelerometer.js
+++ b/app/js/device/CC2650/cc2650_accelerometer.js
@@ -115,6 +115,7 @@ CC2650_ACCEL = function(p) {
this.startService = function() {
+ this.maxLength = 255;
if (this.deviceID !== null) {
console.log('Starting CC2650 Accelerometer Service on ', this.deviceID);
@@ -154,6 +155,114 @@ CC2650_ACCEL = function(p) {
};
+ this.advancedGraphFFT = function(mode, data, subID) {
+ var xstep;
+ var scalePos;
+ var lm;
+ var ceiling;
+ var elm;
+ var text2ID;
+ var ceilingLimit;
+ var calcArray;
+ var floor;
+ var _subID;
+ var _data;
+ var text1ID;
+ var lineID;
+ var max;
+
+ var reducer = function(p, v) {
+ return (Math.abs(p) > Math.abs(v) ? Math.abs(p) : Math.abs(v));
+ };
+
+
+ var parts = ['x', 'y', 'z'];
+ var _newData = {x: [],y: [],z: []};
+
+ _data = data || this.data;
+
+ _subID = subID || '';
+
+ // LineID = [this.frameID , _subID , '-line'].join('');
+ text1ID = [this.frameID, _subID, '-txt1'].join('');
+ text2ID = [this.frameID, _subID, '-txt2'].join('');
+ ceiling = 0;
+ if (_data.x.length > 0) {
+
+ max = 2;
+
+ for (var lineMode = 0; lineMode < parts.length; lineMode++) {
+
+
+ lm = parts[lineMode];
+
+ var data = new complex_array.ComplexArray(_data[lm]);
+
+
+ data.FFT();
+
+ data.forEach(function(c_value, i) {
+ ceiling = reducer(c_value.real ,ceiling);
+ _newData[lm].push(c_value.real);
+ });
+
+ //Ceiling = _data[lm].reduce(reducer);
+
+ console.log('ceiling:', ceiling);
+
+
+ }
+
+ if (ceiling > 500) {
+ max = (ceiling > max) ? (Math.ceil((Math.round(ceiling) + 1) / 50) * 50) : max;
+ } else {
+ max = (ceiling > max) ? (Math.ceil((Math.round(ceiling) + 1) / 10) * 10) : max;
+ }
+ ceiling = max;
+
+ floor = ceiling * -1;
+ ceilingLimit = ceiling;
+ console.log('ceiling:',ceiling);
+
+ scalePos = (124 / 2) / ceiling;
+
+ xstep = (680 - 46) / this.maxLength;
+
+ //Var xstep = 2.34;
+
+ for (lineMode = 0; lineMode < parts.length; lineMode++) {
+
+ lm = parts[lineMode];
+ var startX = 46 + (this.maxLength - _newData[lm].length) * xstep;
+
+ calcArray = [];
+
+ lineID = this.frameID + _subID + '-' + lm + '-line';
+ for (var x = 0; x < _newData[lm].length; x++) {
+
+ calcArray.push((startX + (x * xstep)).toFixed(2) + ',' + (71 - ((_newData[lm][x]) * scalePos)).toFixed(
+ 2));
+
+ }
+
+ elm = document.getElementById(lineID);
+
+ elm.setAttribute('points', calcArray.join(' '));
+
+ }
+
+ elm = document.getElementById(text1ID);
+ elm.textContent = ceilingLimit;
+
+ elm = document.getElementById(text2ID);
+ elm.textContent = floor;
+
+ }
+
+ this.previousCeil = ceiling;
+ };
+
+
this.advancedGraph = function(mode, data, subID) {
var xstep;
@@ -212,14 +321,14 @@ CC2650_ACCEL = function(p) {
scalePos = (124 / 2) / ceiling;
- xstep = (680 - 46) / 100;
+ xstep = (680 - 46) / this.maxLength;
//Var xstep = 2.34;
for (lineMode = 0; lineMode < parts.length; lineMode++) {
lm = parts[lineMode];
- var startX = 46 + (100 - _data[lm].length) * xstep;
+ var startX = 46 + (this.maxLength - _data[lm].length) * xstep;
calcArray = [];
@@ -252,7 +361,7 @@ CC2650_ACCEL = function(p) {
// Nothing to animate yet
// return -1;
- this.advancedGraph(0, this.data.gyro, 'gyro');
+ this.advancedGraphFFT(0, this.data.gyro, 'gyro');
this.advancedGraph(0, this.data.accel, 'accel');
this.advancedGraph(0, this.data.mag, 'mag');
// This.simpleGraph(this.data.temp, 'temp');
diff --git a/app/js/standards/capability.js b/app/js/standards/capability.js
index 7c108a8..ac9eab6 100644
--- a/app/js/standards/capability.js
+++ b/app/js/standards/capability.js
@@ -45,6 +45,7 @@ var CAPABILITY = function(p) {
this.target = null;
this.$frame = null;
+ this.maxLength = 99;
this.previousCeil = 0;
@@ -114,7 +115,7 @@ CAPABILITY.prototype.storeData = function(data, alt) {
}
var target = alt || this.data;
- if (target.length === 99) {
+ if (target.length === this.maxLength) {
target = target.slice(1);
}
diff --git a/gulpfile.js b/gulpfile.js
index 2e38c35..d6b8d6a 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -70,10 +70,17 @@ gulp.task('devices', function() {
.pipe(gulp.dest('www/js'));
});
+/*
+
+
+
+ */
gulp.task('vendor', function() {
return gulp.src(['app/libs/jquery/dist/jquery.min.js',
'app/libs/mui/packages/cdn/js/mui.min.js',
- 'app/libs/ejs/ejs_production.js'])
+ 'app/libs/ejs/ejs_production.js',
+ 'app/libs/jsfft/complex_array.js',
+ 'app/libs/jsfft/fft.js'])
.pipe(concat('vendor.js'))
.pipe(uglify({mangle: false}))
.pipe(gulp.dest('www/libs'));
diff --git a/platforms/android/.gradle/2.2.1/taskArtifacts/cache.properties.lock b/platforms/android/.gradle/2.2.1/taskArtifacts/cache.properties.lock
index 2792132..d061909 100644
Binary files a/platforms/android/.gradle/2.2.1/taskArtifacts/cache.properties.lock and b/platforms/android/.gradle/2.2.1/taskArtifacts/cache.properties.lock differ
diff --git a/platforms/android/.gradle/2.2.1/taskArtifacts/fileHashes.bin b/platforms/android/.gradle/2.2.1/taskArtifacts/fileHashes.bin
index 81da1bf..5102f1f 100644
Binary files a/platforms/android/.gradle/2.2.1/taskArtifacts/fileHashes.bin and b/platforms/android/.gradle/2.2.1/taskArtifacts/fileHashes.bin differ
diff --git a/platforms/android/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin b/platforms/android/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin
index 1655560..85a3161 100644
Binary files a/platforms/android/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin and b/platforms/android/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin differ
diff --git a/platforms/android/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin b/platforms/android/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin
index 550ce22..4f62d15 100644
Binary files a/platforms/android/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin and b/platforms/android/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin differ
diff --git a/www/js/index.js b/www/js/index.js
deleted file mode 100644
index 6056a88..0000000
--- a/www/js/index.js
+++ /dev/null
@@ -1,599 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/* global mui, bt_company_ids, ble, LocalFileSystem, capabilityManager, MANUFACTUREDECODER */
-
-var app;
-app = {
- mode: 0, stop: false, log: {}, activeServices: {},
-
- list: {}, foundDevices: {},
-
- manufactureDecoder: new MANUFACTUREDECODER(), // Application Constructor
- initialize: function() {
- this.bindEvents();
- },
-
- arrayBufferToIntArray: function(buffer) {
- var result;
-
- if (buffer) {
- var typedArray = new Uint8Array(buffer);
- result = [];
- for (var i = 0; i < typedArray.length; i++) {
- result[i] = typedArray[i];
- }
- }
-
- return result;
- },
-
- parseAdvertisingData: function(bytes) {
- var length;
- var type;
- var data;
- var i = 0;
- var advertisementData = {};
-
- while (length !== 0) {
-
- length = bytes[i] & 0xFF;
- i++;
-
- type = bytes[i] & 0xFF;
- i++;
-
- data = bytes.slice(i, i + length - 1); // Length includes type byte, but not length byte
- i += length - 2; // Move to end of data
- i++;
-
- advertisementData[type] = data;
- }
-
- return advertisementData;
- }, handle255: function(buffer) {
- 'use strict';
-
- var company;
- var cid;
- var manID;
- var bin = buffer;
- var decoded = {};
-
- console.log('Block255', bin);
- manID = app.manufactureDecoder.getManID(bin);
-
- console.log('ManID:', manID);
-
- cid = '0x' + manID;
-
- company = bt_company_ids.find(cid);
-
- switch (manID) {
- case '004C': {
- decoded = app.manufactureDecoder.decodeIbeacon(bin);
- decoded.company = company;
- break;
- }
- case '1235': {
- decoded = app.manufactureDecoder.decodeSiliconLabsSensorPuck(bin);
- decoded.company = company;
- break;
-
- }
- case '0060': {
- decoded = app.manufactureDecoder.decodeSansible(bin);
- decoded.company = company;
- break;
-
- }
- default: {
- console.log('Unknown manID: ', manID);
- decoded = {company: company};
-
- }
- }
- return decoded;
- }, makeHexBuffer: function(buffer) {
- 'use strict';
- return buffer.map(function(i) {
- return ('00' + i.toString(16)).slice(-2) + ',';
- });
- }, makeChars: function(buffer) {
- 'use strict';
- return buffer.map(function(i) {
- return String.fromCharCode(i);
- });
- }, calculateDistance: function(txPower, rssi) {
-
- // If there is 0 txPower then default it to -12dBm which appears to be a general default.
-
- var _txPower = (txPower !== 0) ? txPower : -12;
-
- var ratio_db = _txPower - rssi;
- var ratio_linear = Math.pow(10, ratio_db / 10);
-
- return Math.sqrt(ratio_linear);
-
- }, /**
- *
- * @param device
- * @param device.rssi
- * @param device.otherData
- * @param device.id
- * @param device.name
- * @param device.rssiBuffer
- * @returns {jQuery|HTMLElement|*}
- */
-
- buildNewDeviceResultPanel: function(device) {
- 'use strict';
- var dString;
- var accuracy;
- var avg;
- var sum;
- var newPanel, newRow;
- var otherData = device.otherData;
- var newId = 'd-' + device.id.replace(/:/g, '').split('-')[0];
- var title = device.hasOwnProperty('name') ? device.name : '*** Unknown';
-
- newPanel = $('
',
- {id: newId, class: 'mui-panel deviceRow', style: 'min-height:75px;'});
-
- newRow = $('
', {class: 'mui-row'});
-
- newRow.append($('
',
- {class: 'mui-col-xs-12 mui--text-title', text: device.id}));
-
- newPanel.append(newRow);
-
- newRow = $('
', {class: 'mui-row'});
- newRow.append($('
', {class: 'mui-col-xs-3', text: 'Name:'}));
- newRow.append($('
', {class: 'mui-col-xs-3', text: title}));
-
- if (typeof otherData !== 'undefined' && otherData !== null && otherData.hasOwnProperty(
- 'txpower')) {
- if (device.hasOwnProperty('rssiBuffer') && (device.rssiBuffer.length > 0)) {
- sum = device.rssiBuffer.reduce(function(a, b) { return a + b; });
- avg = sum / device.rssiBuffer.length;
- accuracy = app.calculateDistance(otherData.txpower, avg);
- } else {
- accuracy = app.calculateDistance(otherData.txpower, device.rssi);
- }
-
- dString = (accuracy <= 30.00) ? accuracy.toFixed(2) + ' m' : 'Far';
- newRow.append($('
', {class: 'mui-col-xs-3', text: 'Distance:'}));
- newRow.append($('
', {class: 'mui-col-xs-3', text: dString}));
-
- } else {
- newRow.append($('
', {class: 'mui-col-xs-3', text: 'RSSI:'}));
- newRow.append($('
',
- {class: 'mui-col-xs-3', text: device.rssi + ' dB'}));
-
- }
-
- newPanel.append(newRow);
-
- if (typeof otherData !== 'undefined' && otherData !== null) {
- if (otherData.hasOwnProperty('msg')) {
- newRow = $('
', {class: 'mui-row'});
- newRow.append($('
', {class: 'mui-col-xs-3', text: 'Details:'}));
- newRow.append($('
', {class: 'mui-col-xs-8', text: otherData.msg}));
- newPanel.append(newRow);
- }
- }
-
- return newPanel;
- }, extractPData: function(prev) {
- 'use strict';
-
- if (typeof prev === 'undefined' || prev === null) {
- return {};
- }
- return prev.pData;
-
- }, extractRSSIBuffer: function(prev) {
- 'use strict';
-
- if (typeof prev === 'undefined' || prev === null) {
- return [];
- }
- return prev.rssiBuffer;
-
- },
-
- processPData: function(newData, oldData) {
- 'use strict';
- var output = {};
- var wa = [];
- if (newData === null || newData.data === null) {
- return {};
- }
-
- for (var key in newData.data) {
-
- if (newData.data.hasOwnProperty(key)) {
-
- if (Object.keys(oldData).indexOf(key) !== -1) {
- wa = oldData[key];
- }
-
- if (wa.length === 99) {
- wa = wa.slice(1);
- }
-
- wa.push(newData.data[key]);
-
- output[key] = wa;
- }
- }
-
- return output;
- }, processRSSIData: function(rssi, oldBuffer) {
- 'use strict';
- if (typeof oldBuffer === 'undefined' || oldBuffer === null) {
- return [];
- }
- var wa = oldBuffer;
-
- if (wa.length === 10) {
- wa = wa.slice(1);
- }
-
- wa.push(rssi);
-
- return wa;
- }, doScan: function(mode) {
- 'use strict';
- app.mode = mode;
- $('#ripple').show();
- if (mode !== 2) {
- $('#tbody').empty();
- }
-
- ble.startScan([], app.foundDevice.bind(this), function(e) {
- console.error(e);
- });
-
- var _t = [5000, 60000, 200][mode];
-
- setTimeout(ble.stopScan, _t, app.scanComplete, function() {
- console.log('stopScan failed');
- $('#ripple').hide();
- });
-
- }, populateObject: function(source, dest) {
- var rObj = dest;
- for (var item in source) {
- if (source.hasOwnProperty(item)) {
- rObj[item] = source[item];
- }
- }
-
- return rObj;
- },
- /**
- *
- * @param device
- * @param device.advertising
- * @param device.rssi
- * @param device.id
- */
-
- foundDevice: function(device) {
- var rssiBuffer;
- var oldRSSIBuffer;
- var newPData;
- var oldPdata;
- var parsed;
- var hexBuffer;
- var advertBuffer;
- var newTR;
- var newId = 'd-' + device.id.replace(/:/g, '').split('-')[0];
- var _device = app.foundDevices[newId] || {};
- var $newID;
- var otherData;
-
- _device = app.populateObject(device, _device);
- // _device.pData = {};
-
- otherData = null;
- this.list[newId] = _device.id;
-
- if (_device.hasOwnProperty('advertising')) {
-
- advertBuffer = app.arrayBufferToIntArray(_device.advertising);
-
- hexBuffer = app.makeHexBuffer(advertBuffer);
-
- parsed = app.parseAdvertisingData(advertBuffer);
-
- if (parsed.hasOwnProperty('9')) {
-
- var name = app.makeChars(parsed['9']);
-
- _device.name = name.join('');
- console.log('Name: ', name.join(''));
-
- }
-
- if (parsed.hasOwnProperty('255')) {
-
- otherData = app.handle255(parsed['255']);
- console.log(otherData);
- _device.otherData = otherData;
- }
- _device.advertBuffer = advertBuffer;
- _device.hexBuffer = hexBuffer;
- _device.parsed = parsed;
- }
-
- // OldPdata = app.extractPData(app.log[newId]);
- oldPdata = app.extractPData(_device);
-
- newPData = app.processPData(otherData, oldPdata);
-
- // OldRSSIBuffer = app.extractRSSIBuffer(app.log[newId]);
- oldRSSIBuffer = app.extractRSSIBuffer(_device);
- rssiBuffer = app.processRSSIData(_device.rssi, oldRSSIBuffer);
-
- _device.pData = newPData;
- _device.rssiBuffer = rssiBuffer;
-
- newTR = app.buildNewDeviceResultPanel(_device);
-
- $newID = $('div#' + newId);
- if ($newID.length > 0) {
- $newID.replaceWith(newTR);
- } else {
- $('#scanResults').append(newTR);
- }
-
- app.log[newId] = _device;
- app.foundDevices[newId] = _device;
-
- console.log(JSON.stringify(_device));
-
- }, scanComplete: function() {
- console.log('Scan complete');
-
- if (app.mode === 1) {
- app.saveLog();
- $('#ripple').hide();
- }
-
- if (app.mode === 2) {
- if (!app.stop) {
- setTimeout(function() {
- app.doScan(2);
- }.bind(this), 200);
- } else {
- app.saveLog();
- $('#ripple').hide();
- }
-
- }
-
- }, writeFile: function(fileEntry, dataObj) {
- // Create a FileWriter object for our FileEntry (log.txt).
- fileEntry.createWriter(function(fileWriter) {
-
- fileWriter.onwriteend = function() {
- console.log('Successful file write...');
- // ReadFile(fileEntry);
- };
-
- fileWriter.onerror = function(e) {
- console.error('Failed file write: ' + e.toString());
- };
-
- // If data object is not passed in,
- // create a new Blob instead.
- if (!dataObj) {
- dataObj = new Blob(['some file data'], {type: 'text/plain'});
- }
-
- fileWriter.write(dataObj);
- });
- }, saveLog: function() {
- 'use strict';
- var dt = new Date().toISOString().replace(/:|-/g, '').replace(/(\.\w+)/g,
- '');
- var payload = JSON.stringify(app.log);
- var filename = 'sensortoy-' + dt + '.json';
-
- // Var dataObj = new Blob(payload, { type: 'text/plain' });
- window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {
-
- console.log('file system open: ' + fs.name);
- fs.root.getFile(filename,
- {create: true, exclusive: false},
- function(fileEntry) {
-
- console.log('fileEntry is file?' + fileEntry.isFile.toString());
- // FileEntry.name == 'someFile.txt'
- // fileEntry.fullPath == '/someFile.txt'
- console.log('Path: ', fileEntry.fullPath);
- app.writeFile(fileEntry, payload);
-
- app.log = [];
-
- },
- app.onError);
-
- }, app.onError);
- }, forceStop: function() {
- 'use strict';
- app.stop = true;
- $('#scan').show();
- $('#stop').hide();
- },
-
- // Bind Event Listeners
- //
- // Bind any events that are required on startup. Common events are:
- // 'load', 'deviceready', 'offline', and 'online'.
- bindEvents: function() {
- var self = this;
- document.addEventListener('deviceready', this.onDeviceReady, false);
- $('#scan').on('click', function() {
- 'use strict';
- this.stop = false;
- this.doScan(2);
- $('#scan').hide();
- $('#stop').show();
- }.bind(this));
-
- $('#stop').on('click', function() {
- 'use strict';
- app.forceStop();
-
- }.bind(this));
-
- $('#longScan').on('click', function() {
- 'use strict';
- this.doScan(1);
- }.bind(this));
-
- $('#scanResults').on('click', 'div.mui-panel.deviceRow', function() {
- 'use strict';
- var tID = $(this).context.id;
- var id = self.list[tID];
-
- console.log(tID, id);
-
- app.forceStop();
- self.connect(id);
- });
-
- }, addTab: function(tID) {
- var appTabs = $('#app-tabs');
- var panes = $('#tab-panes');
-
- var paneID = 'pane-' + tID;
-
- var _device = app.foundDevices[tID];
- var _name = _device.name || _device.id;
-
- console.log('Found:', _device);
-
- $('
', {class: 'mui-tabs__pane', id: paneID}).appendTo(panes);
-
- var li = $('
').append($('',
- {'data-mui-toggle': 'tab', 'data-mui-controls': paneID, text: _name}));
-
- appTabs.append(li);
-
- return paneID;
-
- },
-
- // Deviceready Event Handler
- //
- // The scope of 'this' is the event. In order to call the 'receivedEvent'
- // function, we must explicitly call 'app.receivedEvent(...);'
- onDeviceReady: function() {
-
- },
-
- doAnimate: function() {
- for (var item in app.activeServices) {
- if (app.activeServices.hasOwnProperty(item)) {
- var activeService = app.activeServices[item];
- for (var t = 0; t < activeService.length; t++) {
- activeService[t].animateGraph();
- }
- }
- }
- window.requestAnimFrame(app.doAnimate.bind(this));
- }, connect: function(deviceId) {
-
- $('#results').slideUp();
- console.log('Connect to ', deviceId);
-
- var tID = 'd-' + deviceId.replace(/:/g, '').split('-')[0];
-
- /**
- *
- * @param a
- * @param a.services
- */
- var onConnect = function(a) {
- var services = [];
-
- services = a.services;
-
- console.log('Searching services for ', tID);
- var usedServices = [];
-
- var target = app.addTab(tID);
-
- var _params = {
- deviceID: deviceId, target: target
- };
-
- for (var t = 0; t < services.length; t++) {
-
- var ident = services[t].toUpperCase();
-
- var SERVICE = capabilityManager.discover(ident);
-
- if (SERVICE !== null) {
-
- var newService = new SERVICE(_params);
- newService.startService();
- usedServices.push(newService);
- } else {
- console.error('Unknown service: ', ident);
- }
-
- }
-
- app.activeServices[tID] = usedServices;
-
- mui.tabs.activate(target);
- window.requestAnimFrame(app.doAnimate.bind(this));
- };
-
- if (!app.activeServices.hasOwnProperty(tID)) {
-
- ble.connect(deviceId, onConnect, function(e) {
- 'use strict';
- console.log(e);
- console.error(e);
-
- });
-
- }
-
- }, onError: function(reason) {
- console.error('ERROR: ' + reason); // Real apps should use notification.alert
- }
-};
-
-window.requestAnimFrame = (function() {
- return window.requestAnimationFrame ||
- window.webkitRequestAnimationFrame ||
- window.mozRequestAnimationFrame ||
- function(callback) {
- window.setTimeout(callback, 1000 / 60);
- };
-})();
-
-app.initialize();