Node: SerialPort is not a constructor - node.js

I'm trying to connect to my Raspberry pi's serialport via node but when i run the js file it comes up with this error:
var serialport = new SerialPort("/dev/ttyAMA0", {
^
TypeError: SerialPort is not a constructor
at Object.<anonymous> (/home/pi/exploringrpi/chp13/xbee/nodejs/test.js:12:18)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:191:16)
at bootstrap_node.js:612:3
node is at version 8.11.4
serialport is at version 7.0.2
This is the code:
// From the example code at www.npmjs.com/package/xbee-api
var util = require('util');
var SerialPort = require('serialport').SerialPort;
var xbee_api = require('xbee-api');
var C = xbee_api.constants;
var xbeeAPI = new xbee_api.XBeeAPI({
api_mode: 1
});
var serialport = new SerialPort("/dev/ttyAMA0", {
baudRate: 115200});
serialport.on("open", function() {
var frame_obj = { // AT Request to be sent to
type: C.FRAME_TYPE.AT_COMMAND, // Prepare for an AT command
command: "NI", // Node identifer command
commandParameter: [], // No parameters needed
};
serialport.write(xbeeAPI.buildFrame(frame_obj));
});
// The data frames are outputted by this function
xbeeAPI.on("frame_object", function(frame) {
console.log(">>", frame);
});
Hope you can help

You should probably remove the .SerialPort at the end of the require line:
var SerialPort = require('serialport').SerialPort;
The serial port documentation shows how it should be used, and it doesn't include that .SerialPort at the end:
var SerialPort = require('serialport');
var port = new SerialPort('/dev/ttyAMA0', {
baudRate: /dev/ttyAMA0
});

Another error was shown to me:
throw new TypeError("path" is not defined: ${settings.path});
I created the port object like this:
const sp = new SerialPort("/dev/ttyACM0", {baudRate: 4800});
It was wrong way.
Try to create port and define the path inside curl brackets:
const sp = new SerialPort({path: "/dev/ttyACM0", baudRate: 4800});
const SerialPort = require('serialport').SerialPort;
const sp = new SerialPort({path: "/dev/ttyACM0", baudRate: 4800});
const sent_data = '\x45';
sp.on("open", function() {
console.log("port has opened");
sp.write(sent_data, function(err){
if(err){
return console.log('Error on write', err.message);
}
console.log('Port.write: ', sent_data);
});
});
sp.on('data', function(data){
// decoding uint8Array to string
var enc = new TextDecoder();
var arr = new Uint8Array(data);
ready = enc.decode(arr)
console.log('Data received: ', ready);
});
// Read data that is available but keep the stream from entering "flowing mode"
sp.on('readable', function () {
console.log('Data2:', sp.read());
});

Related

This Node.js program is working, It uses serialport, and ws

The project boards are:
Raspberry Pi 3
Arduino Uno rev3
The Git file: https://github.com/artikcloud/sample-iot-MonitorFlameTemp
var webSocketUrl = "wss://api.artik.cloud/v1.1/websocket?ack=true";
var device_id = "<00840e8c030c4482b29c01bb431aa41ee>";
var device_token = "<9e973185912d4680b8cbaa34098c7f67>";
var isWebSocketReady = false;
var ws = null;
var serialport = require("serialport")
var SerialPort = serialport.SerialPort;
var sp = new SerialPort("/dev/ttyACM0", {
baudrate: 9600,
parser: serialport.parsers.readline("\n")
});
var WebSocket = require('ws');
/**
* Gets the current time in millis
*/
function getTimeMillis(){
return parseInt(Date.now().toString());
}
/**
* Create a /websocket bi-directional connection
*/
function start() {
//Create the websocket connection
isWebSocketReady = false;
ws = new WebSocket(webSocketUrl);
ws.on('open', function() {
console.log("Websocket connection is open ....");
register();
});
ws.on('message', function(data, flags) {
console.log("Received message: " + data + '\n');
});
ws.on('close', function() {
console.log("Websocket connection is closed ....");
});
}
/**
* Sends a register message to the websocket and starts the message flooder
*/
function register(){
console.log("Registering device on the websocket connection");
try{
var registerMessage = '{"type":"register", "sdid":"'+device_id+'", "Authorization":"bearer '+device_token+'", "cid":"'+getTimeMillis()+'"}';
console.log('Sending register message ' + registerMessage + '\n');
ws.send(registerMessage, {mask: true});
isWebSocketReady = true;
}
catch (e) {
console.error('Failed to register messages. Error in registering message: ' + e.toString());
}
}
/**
* Send one message to ARTIK Cloud
*/
function sendData(onFire){
try{
ts = ', "ts": '+getTimeMillis();
var data = {
"onFire": onFire
};
var payload = '{"sdid":"'+device_id+'"'+ts+', "data": '+JSON.stringify(data)+', "cid":"'+getTimeMillis()+'"}';
console.log('Sending payload ' + payload);
ws.send(payload, {mask: true});
} catch (e) {
console.error('Error in sending a message: ' + e.toString());
}
}
/**
* All start here
*/
start(); // create websocket connection
sp.on("open", function () {
sp.on('data', function(data) {
if (!isWebSocketReady){
console.log("Websocket is not ready. Skip sending data to ARTIK Cloud (data:" + data +")");
return;
}
console.log("Serial port received data:" + data);
var flameDigitalValue = parseInt(data);
// flameDigitalValue = 1 ==> no fire is detected
// flameDigitalValue = 0 ==> fire is detected
var onFire = false;
if (flameDigitalValue == 0) {
onFire = true;
}
sendData(onFire);
});
});
And for some reason it is not working I got the code from this website: https://www.artik.io/blog/2016/05/monitor-fire-temperature-using-artik-cloud-open-source-iot-hardware-android/
But is is giving me this error:
pi#raspberrypi:~ $ node index.js
/home/pi/index.js:12
parser: serialport.parsers.readline("\n")
^
TypeError: serialport.parsers.readline is not a function
at Object.<anonymous> (/home/pi/index.js:12:32)
at Module._compile (internal/modules/cjs/loader.js:654:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
at Module.load (internal/modules/cjs/loader.js:566:32)
at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
at Function.Module._load (internal/modules/cjs/loader.js:498:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:695:10)
at startup (internal/bootstrap/node.js:201:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:516:3)
What am I doing wrong?
The serialport module (the parser implementation) has changed after version 4.x.
You have 2 options.
a) downgrade your serialport module; if you know which version number has been used (ask author of the GitHub project)
npm uninstall serialport
npm install serialport#<version>
b) upgrade your code to current version of the serialport module (usage of parser), see https://node-serialport.github.io/parsers/ReadLineParser.html
Looking at your code you need to replace the serial port creation with something like this:
const SerialPort = require('serialport');
const Readline = require('parser-readline');
const sp = new SerialPort('/dev/ttyACM0', {
baudRate: 9600
});
const parser = sp.pipe(new Readline({ delimiter: "\n"}));
Note, in end of your code you need to replace
sp.on('data' ...
with
parser.on('data' ...
Hope this helps.

Load and modify svg files from node.js

We have an API that should send png files. This png files are composition of several svg files and some changes in attributes: background-color, image size..
We are using node.js on the server.
I've tried without success using d3 in order to modify SVG files & Jsdom to use d3 on the backend:
var fs = require('fs');
var d3 = require('d3');
var JSDOM = require('jsdom').JSDOM;
var outputLocation = 'test.svg';
const window = (new JSDOM(`<html><head></head><body></body></html>`, { pretendToBeVisual: true })).window;
window.d3 = d3.select(window.document); //get d3 into the dom
d3.xml("./react02.svg").mimeType("image/svg+xml").get(function(error, xml) {
var importedNode = document.importNode(xml.documentElement, true);
if (error) throw error;
console.log(xml);
window.d3.select('body')
.append('div').attr('class', 'container')
.appendChild(importedNode);
});
fs.writeFileSync(outputLocation, window.d3.select('.container').html()) //using sync to keep the code simple
But I always get an error:
TypeError: Cannot read property 'innerHTML' of null
at Selection.selection_html [as html] (/home/juanda/kk2/node_modules/d3-selection/build/d3-selection.js:793:20)
at Object.<anonymous> (/home/juanda/kk2/test2.js:18:65)
at Module._compile (module.js:624:30)
at Object.Module._extensions..js (module.js:635:10)
at Module.load (module.js:545:32)
at tryModuleLoad (module.js:508:12)
at Function.Module._load (module.js:500:3)
at Function.Module.runMain (module.js:665:10)
at startup (bootstrap_node.js:201:16)
at bootstrap_node.js:626:3
Can't find any example / library reading and modifing svg files on server side.
Moved from d3 to snapsvg as I don't need data analysis, just play with the svg itself.
This is my code:
let {JSDOM} = require('jsdom')
var resolve = require('resolve');
resolve('snapsvg', { basedir: __dirname }, function (err, resource) {
if (err) console.error(err)
else {
const options = {
runScripts: "dangerously",
resources: "usable",
url: "file:///prueba.html" // avoid cors error reading svg file
};
const dom = new JSDOM(`
<!DOCTYPE html><html><body><div id="test"></div></body></html>
`, options);
var script = dom.window.document.createElement('script');
script.src = `file://${resource}`;
var head= dom.window.document.getElementsByTagName('head')[0];
head.appendChild(script);
// console.log(dom.serialize())
script.onload = function () {
// console.log("Script loaded and ready");
// console.log(dom.window)
var s = dom.window.Snap("#test");
dom.window.Snap.load("file:///Users/juandaniel/Code/prueba/2375.svg", onSVGLoaded);
function onSVGLoaded(data) {
s.append(data);
console.log(s.node.innerHTML)
}
};
}
});

"Learning Node JS" example - 'The super constructor to "inherits" must not ' +'

I'm fowolling along to exercise in the O'Reilly "Learning Node JS" book and I've run into an unrunnable example. My code is as follows:
"use strict";
var util = require('util');
var eventEmitter = require('events').eventEmitter;
var fs = require('fs')
function InputChecker(name, file) {
this.name = name;
this.writeStream = fs.createWriteStream('./' + file + '.txt',
{'flags': 'a',
'encoding': 'utf8',
'mode' : 0o666});
};
util.inherits(InputChecker, eventEmitter);
InputChecker.prototype.check = function check(input) {
let command = input.trim().substr(0,3);
if (command == 'wr') {
this.emit('write', input.substr(3, input.length));
} else if (command == 'en:') {
this.emit('end');
} else {
this.emit('echo', input);
}
};
let ic = new InputChecker('Shelley', 'output');
ic.on('write', function(data) {
this.writeStream.write(data, 'utf8');
});
ic.on('echo', function(data) {
process.stdout.write(ict.name + ' wrote ' + data);
});
ic.on('end', function() {
process.exit();
});
process.stdin.setEncoding('utf8');
process.stdin.on('readable', function() {
let input = process.stdin.read();
if (input != null)
ic.check(input);
});
The error is:
[user#MacBook-Pro NodeJS]$ node fileevent.js
util.js:957
throw new TypeError('The super constructor to "inherits" must not ' +
^
TypeError: The super constructor to "inherits" must not be null or undefined
at Object.exports.inherits (util.js:957:11)
at Object.<anonymous> (/Users/user/Documents/NodeJS/fileevent.js:15:6)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:389:7)
at startup (bootstrap_node.js:149:9)`
Any help is appreciated! TIA!
Your mistake is here:
var eventEmitter = require('events').eventEmitter;
The EventEmitter object is title-case, since it is a class name. It could be corrected by rewriting it as:
var EventEmitter = require('events').EventEmitter;
but that is the obsolete way of importing the EventEmitter class for Node.js v0.10.x and earlier, which is only supported now for backwards compatibility. The recommended way to import it is:
const EventEmitter = require('events');
and refactor the rest of your references from eventEmitter to EventEmitter in order to follow the convention of naming classes with a capital letter.

use node-redis with node 8 util.promisify

node -v : 8.1.2
I use redis client node_redis with node 8 util.promisify , no blurbird.
the callback redis.get is ok, but promisify type get error message
TypeError: Cannot read property 'internal_send_command' of undefined
at get (D:\Github\redis-test\node_modules\redis\lib\commands.js:62:24)
at get (internal/util.js:229:26)
at D:\Github\redis-test\app.js:23:27
at Object. (D:\Github\redis-test\app.js:31:3)
at Module._compile (module.js:569:30)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:503:32)
at tryModuleLoad (module.js:466:12)
at Function.Module._load (module.js:458:3)
at Function.Module.runMain (module.js:605:10)
my test code
const util = require('util');
var redis = require("redis"),
client = redis.createClient({
host: "192.168.99.100",
port: 32768,
});
let get = util.promisify(client.get);
(async function () {
client.set(["aaa", JSON.stringify({
A: 'a',
B: 'b',
C: "C"
})]);
client.get("aaa", (err, value) => {
console.log(`use callback: ${value}`);
});
try {
let value = await get("aaa");
console.log(`use promisify: ${value}`);
} catch (e) {
console.log(`promisify error:`);
console.log(e);
}
client.quit();
})()
changing let get = util.promisify(client.get);
to let get = util.promisify(client.get).bind(client);
solved it for me :)
If you are using node v8 or higher, you can promisify node_redis with
util.promisify as in:
const {promisify} = require('util');
const getAsync = promisify(client.get).bind(client); // now getAsync is a promisified version of client.get:
// We expect a value 'foo': 'bar' to be present
// So instead of writing client.get('foo', cb); you have to write:
return getAsync('foo').then(function(res) {
console.log(res); // => 'bar'
});
or using async await:
async myFunc() {
const res = await getAsync('foo');
console.log(res);
}
culled shamelessly from redis official repo
You can also use Blue Bird Library plus monkey patching will do the trick for you.
For example:
const bluebird = require('bluebird')
const redis = require('redis')
async connectToRedis() {
// use your url to connect to redis
const url = '//localhost:6379'
const client = await redis.createClient({
url: this.url
})
client.get = bluebird.promisify(client.get).bind(client);
return client
}
// To connect to redis server and getting the key from redis
connectToRedis().then(client => client.get(/* Your Key */)).then(console.log)

Piping stdout from one command into stdin for another, and then to a writable stream

With the code in app.js I am able to pipe the output from the raspistill command spawned in camera() in camerautil.js to a writable stream. But instead of the writable stream, I want to pipe the output into the convert command spawned in resize() and then pipe stdout from that command to a writable stream.
What I have tried:
var streamOut = fs.createWriteStream('./image.jpg');
camerautil.camera().pipe(camerautil.resize(streamOut, 1, 1));
It throws the following error:
events.js:85
throw er; // Unhandled 'error' event
^
Error: Cannot pipe. Not readable.
at WriteStream.Writable.pipe (_stream_writable.js:162:22)
at Object.exports.resize (/home/pi/dev/app/camerautil.js:27:14)
at Object.<anonymous> (/home/pi/dev/app/index3.js:5:37)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3
This is my (working) code:
app.js
var camerautil = require('./camerautil'),
fs = require('fs');
var streamOut = fs.createWriteStream('./image.jpg');
camerautil.camera().pipe(streamOut);
camerautil.js
var spawn = require('child_process').spawn,
Stream = require('stream');
exports.camera = function() {
var child = spawn('raspistill', ['-w', 320, '-h', 240, '-n', '-t', 1, '-o', '-']);
var stream = new Stream();
child.stderr.on('data', stream.emit.bind(stream, 'error'));
child.stdout.on('data', stream.emit.bind(stream, 'data'));
child.stdout.on('end', stream.emit.bind(stream, 'end'));
child.on('error', stream.emit.bind(stream, 'error'));
return stream;
}
exports.resize = function(streamIn, width, height) {
var child = spawn('convert', ['-', '-resize', width + 'x' + height, '-']);
var stream = new Stream();
child.stderr.on('data', stream.emit.bind(stream, 'error'));
child.stdout.on('data', stream.emit.bind(stream, 'data'));
child.stdout.on('end', stream.emit.bind(stream, 'end'));
child.on('error', stream.emit.bind(stream, 'error'));
streamIn.pipe(child.stdin);
return stream;
}
I should mention that I'm running node v0.12.0 on a Raspberry Pi. The raspistill command is for taking pictures with the camera module. The convert command is part of ImageMagick.
It could be simpler to stream into the gm module (A wrapper for Imagemagick). If that will install on a Raspberry PI that is.
var gm = require('gm')
gm(camerautil.camera())
.resize('100', '100')
.stream('jpg')
.pipe(streamOut)
https://github.com/aheckmann/gm#streams
After some fiddling, I found the solution.
var camerautil = require('./camerautil'),
fs = require('fs');
var streamOut = fs.createWriteStream('./image.jpg');
camerautil.resize(camerautil.camera(), 1, 1).pipe(streamOut);

Resources