Run EspruinoHub as a systemd service
This is a guide how to run the EspruinoHub as a service controled by systemd on an rasperrypi using raspbian.
You need espruino hub for connecting a Puck.js bluetooth device to a mqtt broker like mosqito.
First get the EspruinoHub software at https://github.com/espruino/EspruinoHub.
Install it according the guide.
Start the EspruinoHub using the
./start.sh
to check if the installation worked.
Then create a service user called 'EspruinoHub' using the command
sudo useradd -r EspruinoHub
Move the directory /home/pi/EspruinoHub to /opt by
sudo mv /home/pi/EspruinoHub /opt
I do this because I do not want to have the service files in the pi home directory.
Now change the the owner of the directory '/opt/EspruinoHub' to the service user created. By
sudo chown -R EspruinoHub /opt/EsprionoHub
Then create the file startService.sh that hast this content:
#!/bin/bash
cd `dirname $0`
BLENO_ADVERTISING_INTERVAL=300
NOBLE_MULTI_ROLE=1
/usr/bin/node index.js
Now create the service configuration insprired by the how you find at https://nodesource.com/blog/running-your-node-js-app-with-systemd-part-1/
go to '/etc/systemd/system', open a text editor, for example nano and create the file 'espruinoHub.service'. Using
sudo nano espruinoHub.service
Add
[Unit]
Description=EspruinoHub service
After=network.target
[Service]
Type=simple
Restart=on-failure
ExecStart=/bin/sh /opt/EspruinoHub/startService.sh
User=EspruinoHub
[Install]
WantedBy=multi-user.target
after the file has bee saved run
sudo systemctl enable espruinoHub.service
and then start the service with
sudo systemctl start espruinoHub.service
Note:
There seems to be a problem with the status output that prevents the service to run. Fix this I changed the file lib/status.js so that it looks like this:
function dumpStatus() {
var inRange = require("./discovery.js").inRange;
// clear screen
var status = '\033c';
//process.stdout.write('\x1B[2J\x1B[0f');
// ...
status += logHistory.join("\n")+"\n\n";
status += (new Date()).toString()+"\n\n";
// sort by most recent
var arr = [];
for (var id in inRange)
arr.push(inRange[id]);
//arr.sort(function(a,b) { return a.rssi - b.rssi; });
arr.sort(function(a,b) { return a.id.localeCompare(b.id); });
// output
var amt = 3;
/*var maxAmt = process.stdout.getWindowSize()[1];
for (var i in arr) {
var p = arr[i];
if (++amt > maxAmt) { console.log("..."); return; }
status += p.id+" - "+p.name+" (RSSI "+p.rssi+")\n";
for (var j in p.data) {
if (++amt > maxAmt) { console.log("..."); return; }
var n = attributes.getReadableAttributeName(j);
var v = p.data[j].payload;
status += " "+n+" => "+JSON.stringify(attributes.decodeAttribute(n,v))+"\n";
}
}
console._log(status);*/
}
// -----------------------------------------
exports.init = function() {
//console._log = console.log;
/** Replace existing console.log with something that'll let us
report status alongside evrything else */
/*console.log = function() {
//var args = Array.from(arguments);
var args = Array.prototype.slice.call(arguments);
if (logHistory.length>10)
logHistory = logHistory.slice(-5);
logHistory.push(args.join("\t"));
dumpStatus();
};*/
The lines 22, 35 to 47, 53 and 56 to 63 are commented out