diff --git a/.DS_Store b/.DS_Store index 010b7c1..45d56e3 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/bluetest/bluetest/.editorconfig b/bluetest/bluetest/.editorconfig new file mode 100644 index 0000000..e86f5fa --- /dev/null +++ b/bluetest/bluetest/.editorconfig @@ -0,0 +1,32 @@ +; http://editorconfig.org + +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 2 + +[*.txt] +insert_final_newline = false +trim_trailing_whitespace = false + +[*.py] +indent_size = 4 + +[*.m] +indent_size = 4 + +[Makefile] +indent_style = tab +indent_size = 8 + +[*.{js,json}] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false diff --git a/bluetest/bluetest/.gitignore b/bluetest/bluetest/.gitignore new file mode 100644 index 0000000..277dd4b --- /dev/null +++ b/bluetest/bluetest/.gitignore @@ -0,0 +1,79 @@ +# Created by .ignore support plugin (hsz.mobi) +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio + +*.iml + +/dist +## Directory-based project format: +.idea/ +# if you remove the above rule, at least ignore the following: + +# User-specific stuff: +# .idea/workspace.xml +# .idea/tasks.xml +# .idea/dictionaries + +# Sensitive or high-churn files: +# .idea/dataSources.ids +# .idea/dataSources.xml +# .idea/sqlDataSources.xml +# .idea/dynamic.xml +# .idea/uiDesigner.xml + +# Gradle: +# .idea/gradle.xml +# .idea/libraries + +# Mongo Explorer plugin: +# .idea/mongoSettings.xml + +## File-based project format: +*.ipr +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +### Node template +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git +node_modules + diff --git a/bluetest/bluetest/.jscsrc b/bluetest/bluetest/.jscsrc new file mode 100644 index 0000000..3b76c52 --- /dev/null +++ b/bluetest/bluetest/.jscsrc @@ -0,0 +1,46 @@ +{ + "disallowKeywords": ["with"], + "disallowKeywordsOnNewLine": ["else"], + "disallowMixedSpacesAndTabs": true, + "disallowMultipleVarDecl": "exceptUndefined", + "disallowNewlineBeforeBlockStatements": true, + "disallowQuotedKeysInObjects": true, + "disallowSpaceAfterObjectKeys": true, + "disallowSpaceAfterPrefixUnaryOperators": true, + "disallowSpacesInFunction": { + "beforeOpeningRoundBrace": true + }, + "disallowSpacesInsideParentheses": true, + "disallowTrailingWhitespace": true, + "maximumLineLength": 120, + "requireCamelCaseOrUpperCaseIdentifiers": false, + "requireCapitalizedComments": true, + "requireCapitalizedConstructors": true, + "requireCurlyBraces": true, + "requireSpaceAfterKeywords": [ + "if", + "else", + "for", + "while", + "do", + "switch", + "case", + "return", + "try", + "catch", + "typeof" + ], + "requireSpaceAfterLineComment": true, + "requireSpaceAfterBinaryOperators": true, + "requireSpaceBeforeBinaryOperators": true, + "requireSpaceBeforeBlockStatements": true, + "requireSpaceBeforeObjectValues": true, + "requireSpacesInFunction": { + "beforeOpeningCurlyBrace": true + }, + "requireTrailingComma": false, + "requireEarlyReturn": false, + "validateIndentation": 2, + "validateLineBreaks": "LF", + "validateQuoteMarks": "'" +} diff --git a/bluetest/bluetest/.jshintrc b/bluetest/bluetest/.jshintrc new file mode 100644 index 0000000..2d1e301 --- /dev/null +++ b/bluetest/bluetest/.jshintrc @@ -0,0 +1,41 @@ +{ + "predef": [ + "Promise" + ], + "node": true, + "browser": false, + "boss": true, + "curly": true, + "debug": false, + "devel": true, + "eqeqeq": true, + "evil": true, + "forin": false, + "immed": false, + "laxbreak": false, + "newcap": true, + "noarg": true, + "noempty": false, + "nonew": false, + "nomen": false, + "onevar": false, + "plusplus": false, + "regexp": false, + "undef": true, + "sub": true, + "strict": false, + "white": false, + "eqnull": true, + "esnext": true, + "unused": true, + "supernew": true, + "globals": { + "$": false, + "EJS": false, + "MicroEvent": false, + "express":false, + "http":false, + "request":false, + "cheerio":false + } +} diff --git a/bluetest/bluetest/bin/cli.js b/bluetest/bluetest/bin/cli.js new file mode 100644 index 0000000..c17a505 --- /dev/null +++ b/bluetest/bluetest/bin/cli.js @@ -0,0 +1,12 @@ +#!/usr/bin/env node +/* +var isEs2015; +try { + isEs2015 = new Function('() => {}'); +} catch (e) { + isEs2015 = false; +} +isEs2015 ? require('../lib/cli') : require('../lib-es5/cli');*/ + + +require('../lib/cli') diff --git a/bluetest/bluetest/index.js b/bluetest/bluetest/index.js new file mode 100644 index 0000000..93ec53c --- /dev/null +++ b/bluetest/bluetest/index.js @@ -0,0 +1,4 @@ +var spawn = require('child_process').spawn; +var EventEmitter = require('events').EventEmitter; +var util = require('util'); + diff --git a/bluetest/bluetest/lib/cli.js b/bluetest/bluetest/lib/cli.js new file mode 100644 index 0000000..8774fc4 --- /dev/null +++ b/bluetest/bluetest/lib/cli.js @@ -0,0 +1,29 @@ +#!/usr/bin/env node +'use strict'; + +const meow = require('meow'); +const bluetest = require('./index'); + +const cli = meow({ + help: ` + Usage + $ bluetest + + Mac + Mac address of bluetooth device. + + `}, + { + + default: { + mac: process.cwd() + + } + }); + + +const options = { + mac:cli.input[0] +}; + +bluetest(options); diff --git a/bluetest/bluetest/lib/index.js b/bluetest/bluetest/lib/index.js new file mode 100644 index 0000000..6008818 --- /dev/null +++ b/bluetest/bluetest/lib/index.js @@ -0,0 +1,159 @@ +/** + * + * User: Martin Donnelly + * Date: 2016-07-06 + * Time: 13:37 + * + */ + +var cp = require('child_process'); +var spawn = cp.spawn; + +var EventEmitter = require('events'); +var busEmitter = new EventEmitter(); + +var util = require('util'); + +var logger = require('log4js').getLogger(); + +var bluetest; +bluetest = module.exports = function(options) { + 'use strict'; + + var core = { + mac: '', gatt: null + }; + + core.processLuxData = function(data) { + console.log('+ processLuxData'); + var m, e, lux; + var p = data.indexOf(10); + + var _data = data.toString('ascii',0, p - 1); + // Var _data = data.toString('ascii'); + // logger.debug('buffer:', data); + // logger.warn('ascii:', _data); + + logger.debug('>--',_data); + var wH = _data.slice(-5).split(' '); + var wB = []; + wB[0] = parseInt(wH[0], 16); + wB[1] = parseInt(wH[1], 16); + logger.debug(wH); + logger.debug(wB); + + var word = (wB[0] << 16) + wB[1]; + + var raw = new Uint16Array(1); + raw[0] = word; + + logger.debug(word); + + m = raw & 0x0FFF; + e = (raw & 0xF000) >> 12; + + lux = m * (0.01 * Math.pow(2.0, e)); + + logger.info('Lux: ', lux); + console.log('- processLuxData'); + }; + + core.enableLuxNotification = function() { + logger.info('Enable Luxomity Notifications...'); + core.gatt.stdin.write('char-write-req 0x0042 0100\n'); + core.gatt.stdin.write('char-write-req 0x0044 01\n'); + }; + + core.gattConnected = function() { + logger.debug('Gatt connected!!!!!'); + + core.enableLuxNotification(); + // Core.gatt.stdin.write('primary\n'); + }; + + core.connectGatt = function() { + logger.info('trying to connect using gatttool'); + core.gatt = spawn('gatttool', ['-b', core.mac, '-I']); + var cStr; + core.gatt.on('error', function(err) { + logger.error(err); + }); + core.gatt.on('exit', function(code) { + + logger.debug('gatt exit code', code); + }); + + core.gatt.on('message', function(m) { + logger.info('message:', m); + }); + + core.gatt.stdout.on('data', (data) => { + + // Logger.info(`stdout: ${data}`); + + if (data.indexOf('Connection successful') > -1) { + + busEmitter.emit('connected'); + } + + if (data.indexOf('Notification handle = 0x0041') > -1) { + busEmitter.emit('processLux', data); + } + + }); + + core.gatt.stderr.on('data', (data) => { + logger.info(`stderr: ${data}`); + }); + + core.gatt.on('close', (code) => { + logger.warn(`child process exited with code ${code}`); + }); + + logger.info('Trying to connect to ', core.mac); + cStr = 'connect\n'; + core.gatt.stdin.write(cStr); + + }; + + core.init = function(options) { + + var tool_path = ''; + var hcidev = 'hvi0'; + + if (typeof options.mac !== 'undefined') { + core.mac = options.mac; + } else { + console.log('You need to pass a mac address.'); + process.exit(1); + } + logger.info('Working with:', options); + + var hciconfig = spawn(tool_path + 'hciconfig', [hcidev, 'up']); + + hciconfig.on('exit', function(code) { + + logger.debug('code', code); + + if (code !== 0) { + + // Could not get the device UP, maybe due to permissions, should run with sudo. + busEmitter.emit('error', + 'hciconfig: failed to bring up device ' + hcidev + '. Try running with sudo.'); + return; + + } else { + + core.connectGatt(); + + } + + }); + + }; + + busEmitter.on('connected', core.gattConnected); + busEmitter.on('processLux', core.processLuxData); + core.init(options); +}; +util.inherits(bluetest, EventEmitter); diff --git a/bluetest/bluetest/lib/ti_index.js b/bluetest/bluetest/lib/ti_index.js new file mode 100644 index 0000000..1f1c882 --- /dev/null +++ b/bluetest/bluetest/lib/ti_index.js @@ -0,0 +1,163 @@ +/** + * + * User: Martin Donnelly + * Date: 2016-07-06 + * Time: 13:37 + * + */ + +var cp = require('child_process'); +var spawn = cp.spawn; +var fork = cp.fork; +var spawnP = require('child-process-promise').spawn; + +var EventEmitter = require('events'); +var busEmitter = new EventEmitter(); + +var util = require('util'); + +var logger = require('log4js').getLogger(); + +var bluetest; +bluetest = module.exports = function(options) { + 'use strict'; + + var core = { + mac: '', gatt: null + }; + + core.processLuxData = function(data) { + console.log('+ processLuxData'); + var m, e, lux; + var p = data.indexOf(10); + var l = data.length - (p + 1); + + + var _data = data.toString('ascii',0, p-1); + //var _data = data.toString('ascii'); + //logger.debug('buffer:', data); + //logger.warn('ascii:', _data); + +logger.debug('>--',_data); + var wH = _data.slice(-5).split(' '); + var wB = []; + wB[0] = parseInt(wH[0], 16); + wB[1] = parseInt(wH[1], 16); + logger.debug(wH); + logger.debug(wB); + + var word = (wB[0] << 16) + wB[1]; + + var raw = new Uint16Array(1); + raw[0] = word; + + logger.debug(word); + + m = raw & 0x0FFF; + e = (raw & 0xF000) >> 12; + + lux = m * (0.01 * Math.pow(2.0, e)); + + logger.info('Lux: ', lux); + console.log('- processLuxData'); + }; + + core.enableLuxNotification = function() { + logger.info('Enable Luxomity Notifications...'); + core.gatt.stdin.write('char-write-req 0x0042 0100\n'); + core.gatt.stdin.write('char-write-req 0x0044 01\n'); + }; + + core.gattConnected = function() { + logger.debug('Gatt connected!!!!!'); + + core.enableLuxNotification(); + // Core.gatt.stdin.write('primary\n'); + }; + + core.connectGatt = function() { + logger.info('trying to connect using gatttool'); + core.gatt = spawn('gatttool', ['-I']); + var cStr; + core.gatt.on('error', function(err) { + logger.error(err); + }); + core.gatt.on('exit', function(code) { + + logger.debug('gatt exit code', code); + }); + + core.gatt.on('message', function(m) { + logger.info('message:', m); + }); + + core.gatt.stdout.on('data', (data) => { + + //logger.info(`stdout: ${data}`); + + if (data.indexOf('Connection successful') > -1) { + + busEmitter.emit('connected'); + } + + if (data.indexOf('Notification handle = 0x0041') > -1) { + busEmitter.emit('processLux', data); + } + + }); + + core.gatt.stderr.on('data', (data) => { + logger.info(`stderr: ${data}`); + }); + + core.gatt.on('close', (code) => { + logger.warn(`child process exited with code ${code}`); + }); + + logger.info('Trying to connect to ', core.mac); + cStr = 'connect ' + core.mac + '\n'; + core.gatt.stdin.write(cStr); + + }; + + core.init = function(options) { + + var tool_path = ''; + var hcidev = 'hvi0'; + + if (typeof options.mac !== 'undefined') { + core.mac = options.mac; + } else { + console.log('You need to pass a mac address.'); + process.exit(1); + } + logger.info('Working with:', options); + + var hciconfig = spawn(tool_path + 'hciconfig', [hcidev, 'up']); + + hciconfig.on('exit', function(code) { + + logger.debug('code', code); + + if (code !== 0) { + + // Could not get the device UP, maybe due to permissions, should run with sudo. + busEmitter.emit('error', + 'hciconfig: failed to bring up device ' + hcidev + '. Try running with sudo.'); + return; + + } else { + + core.connectGatt(); + + } + + }); + + }; + + busEmitter.on('connected', core.gattConnected); + busEmitter.on('processLux', core.processLuxData); + core.init(options); +}; +util.inherits(bluetest, EventEmitter); diff --git a/bluetest/bluetest/package.json b/bluetest/bluetest/package.json new file mode 100644 index 0000000..463a980 --- /dev/null +++ b/bluetest/bluetest/package.json @@ -0,0 +1,18 @@ +{ + "name": "bluetest", + "version": "1.0.0", + "description": "", + "main": "lib", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Martin Donnelly ", + "license": "ISC", + "devDependencies": { + "log4js": "^0.6.37", + "meow": "^3.7.0" + }, + "bin": { + "bluetest": "bin/cli.js" + } +}