Commit d5d3a4b3 authored by David Mondou's avatar David Mondou
Browse files

Initial commit

parents
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
**********************
Node-Red Noble Connect
**********************
A Node-Red node that will scan for and connect to BlueTooth Low-Energy devices.
Installation
============
Per https://nodered.org/docs/creating-nodes/packaging#testing-a-node-module-locally, run the following commands
.. code-block:: console
$ cd <path to node-red-contrib-noble-connect>
$ npm link
...
$ cd ~/.node-red
$ npm link node-red-contrib-noble-connect
...
Running
=======
Once the node is linked, it should be available once you start Node-RED. With Node-RED installed globally, you should be able to run ``node-red`` from the command-line. If Node-RED is only installed locally to your project directory, you will need to run ``node node_modules/node-red/red.js``.
Examples
========
This node includes an example flow. To access it, open the settings menu at the top right corner of the page. Hover over "Import", then "Examples", then "noble connect".
- The ``demo-kit`` example flow will use a noble-connect node to scan for and connect to Nordic Thingy\:52 devices. It will show the Thingy data on a dashboard (accessible at ``/ui`` from the Node-RED URL), as well as optionally sending it to an Amazon Lambda.
- The ``sensorkit-to-dynamodb`` example flow will use a ``node-red-contrib-noble`` node to scan for nearby devices. It will use their broadcast data and push it up to a configured DynamoDB instance. For more information about this flow, see Rigado's tutorial documentation at https://developer.rigado.com/docsets/Working-with-the-Rigado-Vesta-Gateway/v1.0.5/tutorials/node-red.html
[
{
"id": "f1d953a9.52377",
"type": "tab",
"label": "Flow 1"
},
{
"id": "270e7872.13bc98",
"type": "ui_tab",
"z": "",
"name": "Home",
"icon": "dashboard"
},
{
"id": "fae3b769.37ce28",
"type": "ui_base",
"theme": {
"name": "theme-dark",
"lightTheme": {
"default": "#0094CE",
"baseColor": "#0094CE",
"baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif",
"edited": true,
"reset": false
},
"darkTheme": {
"default": "#097479",
"baseColor": "#097479",
"baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif",
"edited": true,
"reset": false
},
"customTheme": {
"name": "Untitled Theme 1",
"default": "#4B7930",
"baseColor": "#4B7930",
"baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"
},
"themeState": {
"base-color": {
"default": "#097479",
"value": "#097479",
"edited": false
},
"page-titlebar-backgroundColor": {
"value": "#097479",
"edited": false
},
"page-backgroundColor": {
"value": "#111111",
"edited": false
},
"page-sidebar-backgroundColor": {
"value": "#000000",
"edited": false
},
"group-textColor": {
"value": "#0eb8c0",
"edited": false
},
"group-borderColor": {
"value": "#555555",
"edited": false
},
"group-backgroundColor": {
"value": "#333333",
"edited": false
},
"widget-textColor": {
"value": "#eeeeee",
"edited": false
},
"widget-backgroundColor": {
"value": "#097479",
"edited": false
},
"widget-borderColor": {
"value": "#333333",
"edited": false
},
"base-font": {
"value": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"
}
}
},
"site": {
"name": "Node-RED Dashboard",
"hideToolbar": "false",
"allowSwipe": "false",
"dateFormat": "DD/MM/YYYY",
"sizes": {
"sx": 120,
"sy": 120,
"gx": 6,
"gy": 6,
"cx": 6,
"cy": 6,
"px": 0,
"py": 0
}
}
},
{
"id": "12c9781e.aa9368",
"type": "ui_group",
"z": "",
"name": "Gateway Status",
"tab": "270e7872.13bc98",
"order": 1,
"disp": true,
"width": "6"
},
{
"id": "3c0d9fd8.080e6",
"type": "ui_group",
"z": "",
"name": "Sensor Data",
"tab": "270e7872.13bc98",
"order": 2,
"disp": true,
"width": "6"
},
{
"id": "91cff1a4.7433c",
"type": "ui_group",
"z": "",
"name": "Send Data",
"tab": "270e7872.13bc98",
"disp": true,
"width": "6"
},
{
"id": "283c2c99.fd3464",
"type": "inject",
"z": "f1d953a9.52377",
"name": "Start Scanning",
"topic": "",
"payload": "{\"command\":\"scan\", \"value\":true}",
"payloadType": "json",
"repeat": "",
"crontab": "",
"once": false,
"x": 140,
"y": 520,
"wires": [
[
"2ae1004.b2bd3"
]
]
},
{
"id": "822a054.fa366f8",
"type": "inject",
"z": "f1d953a9.52377",
"name": "Stop Scanning",
"topic": "",
"payload": "{\"command\":\"scan\", \"value\":false}",
"payloadType": "json",
"repeat": "",
"crontab": "",
"once": false,
"x": 140,
"y": 560,
"wires": [
[
"2ae1004.b2bd3"
]
]
},
{
"id": "2ae1004.b2bd3",
"type": "noble-connect",
"z": "f1d953a9.52377",
"uuids": "",
"name": "",
"x": 340,
"y": 540,
"wires": [
[
"c65fc47.870b738",
"f0ca820c.9f71c"
],
[
"a3a1a2b.0ff7d6"
],
[
"fdda9133.b655b"
]
],
"inputLabels": [
"control command"
],
"outputLabels": [
"sensor-data",
"peripherals",
"status"
]
},
{
"id": "801caa9a.2db608",
"type": "function",
"z": "f1d953a9.52377",
"name": "format for graphs",
"func": "if (typeof msg.payload === \"undefined\") {\n return [null, null, null];\n}\n\nuuid = msg.payload.peripheralUuid;\naccmsgs = [{\n \"topic\": uuid+\"-x\",\n \"payload\": msg.payload.data.accel[0]\n},{\n \"topic\": uuid+\"-y\",\n \"payload\": msg.payload.data.accel[1]\n},{\n \"topic\": uuid+\"-z\",\n \"payload\": msg.payload.data.accel[2]\n}];\ngyrmsgs = [{\n \"topic\": uuid+\"-x\",\n \"payload\": msg.payload.data.gyro[0]\n},{\n \"topic\": uuid+\"-y\",\n \"payload\": msg.payload.data.gyro[1]\n},{\n \"topic\": uuid+\"-z\",\n \"payload\": msg.payload.data.gyro[2]\n}];\nmagmsgs = [{\n \"topic\": uuid+\"-x\",\n \"payload\": msg.payload.data.mag[0]\n},{\n \"topic\": uuid+\"-y\",\n \"payload\": msg.payload.data.mag[1]\n},{\n \"topic\": uuid+\"-z\",\n \"payload\": msg.payload.data.mag[2]\n}];\nreturn [accmsgs, gyrmsgs, magmsgs];",
"outputs": "3",
"noerr": 0,
"x": 810,
"y": 800,
"wires": [
[
"31841c22.6bd9c4"
],
[
"f995f0e0.b64e6"
],
[
"50321922.928158"
]
],
"outputLabels": [
"accelerometer",
"gyroscope",
"magnetometer"
]
},
{
"id": "31841c22.6bd9c4",
"type": "ui_chart",
"z": "f1d953a9.52377",
"name": "Accelerometer",
"group": "3c0d9fd8.080e6",
"order": 2,
"width": 0,
"height": 0,
"label": "Accelerometer",
"chartType": "line",
"legend": "true",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "Waiting for data...",
"dot": false,
"ymin": "",
"ymax": "",
"removeOlder": "1",
"removeOlderPoints": "60",
"removeOlderUnit": "60",
"cutout": 0,
"useOneColor": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"useOldStyle": false,
"x": 1220,
"y": 760,
"wires": [
[],
[]
]
},
{
"id": "f995f0e0.b64e6",
"type": "ui_chart",
"z": "f1d953a9.52377",
"name": "Gyroscope",
"group": "3c0d9fd8.080e6",
"order": 5,
"width": 0,
"height": 0,
"label": "Gyroscope",
"chartType": "line",
"legend": "true",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "Waiting for data...",
"dot": false,
"ymin": "",
"ymax": "",
"removeOlder": "1",
"removeOlderPoints": "60",
"removeOlderUnit": "60",
"cutout": 0,
"useOneColor": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"useOldStyle": false,
"x": 1210,
"y": 800,
"wires": [
[],
[]
]
},
{
"id": "50321922.928158",
"type": "ui_chart",
"z": "f1d953a9.52377",
"name": "Magnetometer",
"group": "3c0d9fd8.080e6",
"order": 7,
"width": 0,
"height": 0,
"label": "Magnetometer",
"chartType": "line",
"legend": "true",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "Waiting for data...",
"dot": false,
"ymin": "",
"ymax": "",
"removeOlder": "1",
"removeOlderPoints": "60",
"removeOlderUnit": "60",
"cutout": 0,
"useOneColor": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"useOldStyle": false,
"x": 1220,
"y": 840,
"wires": [
[],
[]
]
},
{
"id": "a3a1a2b.0ff7d6",
"type": "ui_template",
"z": "f1d953a9.52377",
"group": "12c9781e.aa9368",
"name": "Device List",
"order": 2,
"width": 0,
"height": 0,
"format": "<h2>Device List</h2>\n<md-button ng-click=\"send({payload:{command:'peripherals'}})\">\n Refresh\n</md-button>\n<table width=\"100%\" style=\"margin: 0px;\">\n <thead>\n <tr>\n <th>Device UUID</th>\n <th>Last Updated</th>\n <th>Connected</th>\n <th>RSSI</th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat=\"(key, value) in msg.payload\">\n <td>{{key}}</td>\n <td>{{value.lastUpdated}}</td>\n <td>{{value.connected}}</td>\n <td>{{value.rssi}}</td>\n </tr>\n </tbody>\n</table>\n<p>Note: This list will not show results if you Deploy the flow. Devices will still connect, but will not show up here. To see the list again, Deploy (to save flow changes to file) and then stop and restart the app.</p>",
"storeOutMessages": false,
"fwdInMessages": false,
"templateScope": "local",
"x": 370,
"y": 720,
"wires": [
[
"2ae1004.b2bd3"
]
]
},
{
"id": "fdda9133.b655b",
"type": "ui_template",
"z": "f1d953a9.52377",
"group": "12c9781e.aa9368",
"name": "NoBLE Status",
"order": 1,
"width": 0,
"height": 0,
"format": "<h2>NoBLE Status</h2>\n<div>\n State: {{msg.state}}<br />\n State change: {{msg.stateChange}}<br />\n Status update: {{msg.stateUpdate}}<br />\n Error: {{msg.error}}\n</div>",
"storeOutMessages": true,
"fwdInMessages": true,
"templateScope": "local",
"x": 380,
"y": 680,
"wires": [
[]
]
},
{
"id": "f93c2da3.8282",
"type": "ui_template",
"z": "f1d953a9.52377",
"group": "3c0d9fd8.080e6",
"name": "Clear Acc",
"order": 4,
"width": 0,
"height": 0,
"format": "<md-button ng-click=\"send({payload:[]})\">\n Clear Accelerometer Chart\n</md-button>",
"storeOutMessages": false,
"fwdInMessages": false,
"templateScope": "local",
"x": 1020,
"y": 760,
"wires": [
[
"31841c22.6bd9c4"
]
]
},
{
"id": "48e11e78.d01b5",
"type": "ui_template",
"z": "f1d953a9.52377",
"group": "3c0d9fd8.080e6",
"name": "Clear Gyr",
"order": 6,
"width": 0,
"height": 0,
"format": "<md-button ng-click=\"send({payload:[]})\">\n Clear Gryoscope Chart\n</md-button>",
"storeOutMessages": false,
"fwdInMessages": false,
"templateScope": "local",
"x": 1020,
"y": 800,
"wires": [
[
"f995f0e0.b64e6"
]
]
},
{
"id": "be414a26.144398",
"type": "ui_template",
"z": "f1d953a9.52377",
"group": "3c0d9fd8.080e6",
"name": "Clear Mag",
"order": 8,
"width": 0,
"height": 0,
"format": "<md-button ng-click=\"send({payload:[]})\">\n Clear Magnetometer Chart\n</md-button>",
"storeOutMessages": false,
"fwdInMessages": false,
"templateScope": "local",
"x": 1030,
"y": 840,
"wires": [
[
"50321922.928158"
]
]
},
{
"id": "c65fc47.870b738",
"type": "delay",
"z": "f1d953a9.52377",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": true,
"x": 610,
"y": 800,
"wires": [
[
"801caa9a.2db608"
]
]
},
{
"id": "f0ca820c.9f71c",
"type": "delay",
"z": "f1d953a9.52377",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": true,
"x": 550,
"y": 340,
"wires": [
[
"3ecd3007.43533",
"df3605ea.3708c8"
]
]
},
{
"id": "3ecd3007.43533",
"type": "function",
"z": "f1d953a9.52377",
"name": "format for AWS",
"func": "if (!flow.get(\"unitSerialNumber\")) {\n return null;\n}\nmsg.payload.unitSerialNumber = flow.get(\"unitSerialNumber\");\nreturn {\n \"sendPayload\": msg.payload\n};",
"outputs": "1",
"noerr": 0,
"x": 840,
"y": 380,
"wires": [
[
"3b36987e.9bacd8",
"545cf821.785bb8"
]
]
},
{
"id": "d5b8a1f0.daa9d",
"type": "debug",
"z": "f1d953a9.52377",
"name": "",
"active": true,
"console": "false",
"complete": "true",