Search code examples
bluetoothraspberry-pibluetooth-lowenergygateway

Raspberry Pi: send bluetooth readings to local server


I am new to Raspberry Pi developing and I am involved in a project in which we need to take Bluetooth readings sent from different sensors (e.g. temperature sensors, wearable health sensors, etc.) previously paired with our Pi, and send them to a server using Pi as a gateway.

How can I access the port receiving the Bluetooth readings? From there on I suppose it's as simple as writing a script that takes the important information, like device ID and the measurement value, places them inside a formatted message and sends it to the server, but again I need advice.

Any help, even providing links to forums or similar sites, will be very appreciated.

UPDATE:

I am now able to read from every handle in the BLE device and parse the data into a JSON file using a bash script. However, I don't know how to tell Node that I need to update the information every 5 seconds. Here's the code I'm using:

// required modules
var http = require('http');
var fs = require('fs');
var exec = require('child_process').exec;

// for executing bash/shell scripts
function execute(command, callback){
    exec(command, function(error, stdout, stderr){ callback(stdout); });
};

// executes script that updates JSON file with new readings
module.exports.getJSONFile = function(callback){
    execute("./Scripts/BLEreadingsJSON.sh");
};

// creates HTTP server
http.createServer(function(request, response){
    response.writeHead(200,{
            'Content-Type': 'text/json' });
    setInterval(function(){
            var contents = fs.readFile('Scripts/nodeJS/readings.json', function(err, contents){
                    response.write(contents);
                    response.end();
            });
    }, 5*1000);
}).listen(8080); // listen for connections on this port
console.log('Listening to port 8080...');

When I execute this I get the following error:

pi@raspberrypi ~/Scripts $ node nodeJS/sendFileToServer.js 
Listening to port 8080...

http.js:851
    throw new TypeError('first argument must be a string or Buffer');
              ^
TypeError: first argument must be a string or Buffer
    at ServerResponse.OutgoingMessage.write (http.js:851:11)
    at /home/pi/Scripts/nodeJS/sendFileToServer.js:22:13
    at fs.js:207:20
    at Object.oncomplete (fs.js:107:15)

I suppose this happens because it is trying to access the file before it has been created. How can I do this using a callback?


Solution

  • I got it to work! For those still interested, I ended up using socket.io. I have a script that updates the data with new BLE readings. This node.js code listens for those updates and sends the file to the client:

    var app = require('express')();
    var http = require('http').Server(app);
    var io = require('socket.io')(http);
    var fs = require('fs')
    
    app.get('/', function(req, res){
        var index = "index.html";
        res.sendFile(index, {root: "absolute_path_to_index"});
    });
    
    var text;
    fs.readFile('absolute_path_to_file', function(err, data){
        text = data;
    });
    
    io.on('connection', function(socket){
        console.log("User connected");
        socket.emit('news', text);
        socket.on('disconnect', function(){
            console.log("User disconnected");
        });
        // this line waits for changes in the file and uploads the new data
        fs.watchFile('absolute_path_to_file', function(curr, prev){
            fs.readFile('absolute_path_to_file', function(err, data){
                socket.emit('news', data.toString());
            });
        });
    });
    
    http.listen(4321, function(){
        console.log("Listening on port 4321...");
    });