nodejs xbee not receiving message - node.js

I want nodejs to send and receive messages with xbee. I know that the xbee setup works because I tested it on x-ctu. I tried the following but can't receive the message. It says it's open.
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("COM7", {
baudrate: 9600,
parser: xbeeAPI.parseRaw(1000)
});
serialport.on("open", function() {
console.log("open");
});
// All frames parsed by the XBee will be emitted here
//I think this is the problem
xbeeAPI.on("frame_object", function(frame) {
console.log(">>", frame);
});

I figured it out a few day ago. I relized I could just use serial port library.

You need to listen to the serial port first and then parse the data with xbee-api
serialport.on('data', function (data) {
try {
xbeeAPI.parseRaw(data);
} catch (e) {
console.error(e);
}
xbeeAPI.on("frame_object", function (frame) {
console.log(frame);
// do what do you want with the frame
}
}
You need to process the frame switch his frame.type, is case of ZIGBEE_RECEIVE_PACKET you need to convert data to string frame.data.toString(), i don't know why using API1 mode but please try to use 57600 baud-rate or higher to avoid the checksum mismatch problems Good luck.

Related

variable no longer in scope within a socket message fuction?

This is a file that listens to messages on port 5000.
The console.log(status) within the function listen seems to be printing true and false
However when exporting status to other files , I still get "none" instead of true and false ... Any suggestions?
var dgram = require('dgram');
var net = require('net');
var status="none";
var num=0;
var LOCAL_UDP_PORT=5000;
exports.listen=function(){
// TCP and UDP listeners
var sock = dgram.createSocket('udp4');
sock.on('message', function(msg, rinfo) {
try{
var obj = JSON.parse(msg);
if (obj.class == ".Announce") {
if(obj.dev.id == "BLA") {
status=true;
}
else
status=false;
}
console.log(status);
}
} catch(e){
// do nothing an err
}
});
sock.bind(LOCAL_UDP_PORT);
}
//Initialize
exports.status=status;
listen();
I guess the reason is, status take a string object, and when you do status=true/false, the reference changes, but exports.status would hold the original reference
try
var status={val:"none"};
...
status.val = true;
...
// in the module reading the value,
var status = status.val;
The incoming socket messages are asynchronous. That means they arrive sometime in the future. If you want to notify another module when they come in, then you will need to create a notification system and export the notification system so the other module can register an interest in getting notified.
You could create the notification system using an eventEmitter, using callbacks, using promises, etc... Why technique you choose would determine exactly what you would export and how the caller would register their interest.

How can I mock serial port during development?

I am developing a node.js application for my Raspberry Pi which receives data from its serial port, but I don't directly develop the application on it, I use my main computer instead. So I have this code in my app.js :
var serialport = require("serialport");
var SerialPort = serialport.SerialPort;
var sp = new SerialPort("/dev/ttyACM0", {
parser: serialport.parsers.readline("\n")
});
sp.on("data", function (rawData) {
...
This works well on the Rasperry Pi but I want to be able to run the application on my development computer first without having to comment every block of code about the serial port.
What is the best way to achieve this ? Is there a way to mock the serial port ?
AFAIK, there aren't any libraries that do this natively right now. What I've done in the past is to use the node-serialport library's own test code as an example, eg: https://github.com/Manetos/node-serialport/blob/157e6f9df7989abd72d509c9827d13b2b10258de/test_mocks/linux-hardware.js
If you take a look at that file, they're mocking the serial port behavior for their own tests, you can simply copy what they're doing there and use it in your stuff, and you should be good to go.
Hope that helps!
I needed the same thing and wasn't able to find details of exactly how to do it, but I kept hitting this question in my searches. After a bit of researching and finding a few vague references in different areas, I was able to put together the following. Hopefully this will be helpful to others who might land here.
You can extend the SerialPort - MockBindings class with your own and then simply implement a custom write function that will receive the data, form a proper response, then emit it back to the caller.
const MockSerialBinding = require('#serialport/binding-mock');
class EmulatedDeviceSerialBinding extends MockSerialBinding {
constructor(opt = {}) {
super(opt);
}
// THIS IS THE METHOD THAT GETS TRIGGERED WHEN THE CODE TO TEST WRITES TO A DEVICE
async write(buffer) {
// Use this method to detect the supported commands and emulate a response
const cmd = Buffer.from(buffer).toString();
let response = 'Unknown Command!'; // Default response
// Custom logic here to determine the proper response
super.emitData(response);
}
}
module.exports = EmulatedDeviceSerialBinding;
For your test, prepare a fake serial device that can be targeted that uses the class above:
const SerialPort = require('serialport');
SerialPort.Binding = EmulatedDeviceSerialBinding;
// Setup a new mock serial device that can be the target
EmulatedDeviceSerialBinding.createPort('ttyUSB_TestTarget', {
echo: true,
readyData: '\r\nhostname#user:~$ ' // This will append a 'prompt' to the end of each response (like a linux terminal would)
});
Now your logic would be the same except you'd connect to the emulated device port instead of a real port. Here is a snippet from an Express Route Middleware:
const SerialPort = require('serialport');
const SerialRegexParser = require('#serialport/parser-regex');
const serialParser = new SerialRegexParser({regex: /(?<Prompt>.*[$#]\s*$)/m});
const serialPortOptions = {
baudRate: 115200
};
// The req.params.devicePort value be the name of the emulated port
const port = new SerialPort(req.params.devicePort, serialPortOptions, (err) => {
if (err) {
return res.status(400).send({error: err.message});
}
});
port.pipe(serialParser);
// THIS WILL BE TRIGGERED WHEN THE EmulatedDeviceSerialBinding does the emitData call
serialParser.once('data', (data) => {
if (res.headersSent) return; // We've already responded to the client, we can't send more
const dataString = Buffer.from(data).toString();
// Remove the command executed from the beginning if it was echoed
respDoc.data = dataString.replace(cmdToExecute, '').trimEnd();
return res.send(respDoc);
});
// Send the command to the device
// THIS WILL TRIGGER THE EmulatedDeviceSerialBinding.write() FUNCTION
port.write(cmdToExecute, (err) => {
if (err) {
return res.status(400).send({error: err.message});
}
});
The program flow is:
Express Middleware port.write(cmdToExecute)
-> EmulatedDeviceSerialBinding.write()
-> Express Middleware serialParser.once('data') callback
I was able to achieve this using the com0com modem emulator available at https://sourceforge.net/projects/com0com/
It will create two virtual COM ports (eg. COM5 and COM6) which map to each other. You can connect your application to one of the COM ports and your emulator code to the other COM port. The emulator can then be configured to read the input and write back out accordingly.

Read from DataOutputStream in NodeJS

I was wondering if there is a way to read from a stream the same way that the DataInputStream in java does?
I need this for two applications I am writing. One, written in Java, sends data using a DataOutputStream.
Something like this:
The Java client.
public static void main(String[] args) {
DataOutputStream out = ...;
out.writeByte((byte) 1);
}
The NodeJS server.
var net = require('net');
net.createServer(function (socket) {
socket.on("data", function (data) {
// Some way to read this?
}
}).listen(4444, '127.0.0.1');
I would like to add two bits of information:
No I am not sending just one byte, I am all the different types supported by the DataOutputStream.
I cannot change the method I am sending the data, I would like to find out how to use this.
In your socket.on() event, the data in the parenthesis is the output.
This should be your code.
var net = require('net');
net.createServer(function (socket) {
socket.on("data", function (data) {
var output = data.toString()
console.log(output)
}
}).listen(4444, '127.0.0.1');
If there are any errors, reply :D
Have a nice day

Send out real time data to webclients error trapping

Trying to send data from a serial device to web clients. I am using a serial to network proxy, ser2Net to make the data available to a server that acts on the data and sends a manipulated version of the data to web clients. The clients specify the location of the ser2net host and port. The core of this action is coded in node.js as shown here:
function getDataStream(socket, dataSourcePort, host) {
var dataStream = net.createConnection(dataSourcePort, host),
dataLine = "";
dataStream.on('error', function(error){
socket.emit('error',{message:"Source not found on host:"+ host + " port:"+dataSourcePort});
console.log(error);
});
dataStream.on('connect', function(){
socket.emit('connected',{message:"Data Source Found"});
});
dataStream.on('close', function(){
console.log("Close socket");
});
dataStream.on('end',function(){
console.log('socket ended');
dataConnection.emit('lost',{connectInfo:{host:host,port:dataSourcePort}});
});
dataStream.on('data', function(data) {
// Collect a line from the host
line += data.toString();
// Split collected data by delimiter
line.split(delimiter).forEach(function (part, i, array) {
if (i !== array.length-1) { // Fully delimited line.
//push on to buffer and emit when bufferSendCommand is present
dataLine = part.trim();
buffer.push(part.trim());
if(part.substring(0, bufferSendCommand.length) == bufferSendCommand){
gotALine.emit('new', buffer);
buffer=[];
}
}
else {
// Last split part might be partial. We can't announce it just yet.
line = part;
}
});
});
return dataStream;
}
io.sockets.on('connection', function(socket){
var stream = getDataStream(socket, dataSourcePort, host);
//dispense incoming data from data server
gotALine.on('new', function(buffer){
socket.emit('feed', {feedLines: buffer});
});
dataConnection.on('lost', function(connectInfo){
setTimeout(function(){
console.log("Trying --- to reconnect ");
stream = getDataStream(socket, connectInfo.port, connectInfo.host);
},5000);
});
// Handle Client request to change stream
socket.on('message',function(data) {
var clientMessage = JSON.parse(data);
if('connectString' in clientMessage
&& clientMessage.connectString.dataHost !== ''
&& clientMessage.connectString.dataPort !== '') {
stream.destroy();
stream = getDataStream(socket,
clientMessage.connectString.dataPort,
clientMessage.connectString.dataHost);
}
});
});
This works well enough until the serial device drops off and ser2net stops sending data. My attempt to catch the end of the socket and reconnect is not working. The event gets emitted properly but the setTimeout only goes once. I would like to find a way to keep on trying to reconnect while sending a message to the client informing or retry attempts. I am node.js newbie and this may not be the best way to do this. Any suggestions would be appreciated.
Ok I think I figured it out in the dataStream.on('data' ... I added a setTimeout
clearTimeout(connectionMonitor);
connectionMonitor = setTimeout(function(){doReconnect(socket);}, someThresholdTime);
The timeout executes if data stops coming in, as it is repeatedly cleared each time data comes in. The doReconnect function keeps trying to connect and sends a message to the client saying something bad is going on.

Writing data to a socket in Node

I'm getting a weird result when writing to a socket. I wrote a simple experiment with a client and a server:
server.js
var net = require('net');
net.createServer(function (connection) {
connection.on('data', function (data) {
console.log('data: ' + data);
});
}).listen(1337);
client.js
var net = require('net');
var client = net.connect({port: 1337}, function () {
var i = 0;
function send() {
client.write('a');
if (++i < 100) {
process.nextTick(send);
} else {
client.end();
}
}
send();
});
I expected the server to show 100 lines of data: a, but I ended up getting a smaller number of data: aaaaaaa lines. There's socket.setNoDelay() that seems to be what I want, but it doesn't seem to have any effect.
What am I missing?
Thanks a lot,
The TCP protocol only sends exactly the bytes you write in the socket. They will not be separated into messages, that's up to you. If you would like to get 100 lines of a then you would have to define 100 separate messages, and choose a delimiter for them. Usually people delimit messages sent to a TCP socket by \r\n.
So you would need to change your server to
var net = require('net');
net.createServer(function (connection) {
connection.on('data', function (buffer) {
var data = buffer.toString();
if (data.indexOf('\r\n') > -1) { // If there's more than one line in the buffer
var lines = data.split('\r\n'); // Split the lines
var i = lines.length;
while (i--) { // This will read your lines in reverse, be careful
console.log(lines[i]); // Print each line
}
} else {
console.log(data); // If only one line came through, print it
}
});
}).listen(1337);
And your client to
var net = require('net');
var client = net.connect({port: 1337}, function () {
var i = 0;
function send() {
client.write('a\r\n'); // Notice the \r\n part. This is what will help you separate messages on the server
if (++i < 100) {
process.nextTick(send);
} else {
client.end();
}
}
send();
});
And then I believe you would get 100 lines of a.
This module also provides a very interesting way to do it, and of course ZeroMQ would also shine in this because it already has a nice protocol that puts things in envelopes and sends them.
Also interestingly but out of the scope of your question, the messages you send write to the socket on one side will not arrive in the same order on the server. If you change your send function to
function send() {
if (++i < 100) {
client.write('a'+i+'\r\n');
process.nextTick(send);
} else {
client.end();
}
}
you can see them arriving not in the order you sent them.
By "The TCP protocol only sends exactly the bytes you write in the socket" I mean that if you do socket.write("1"); socket.write("2"), you will receive "12" on the server, because that's what you wrote on the socket. You have to explicitly separate your messages by something so that the server can know when a message starts and when a message ends.
About receiving things in order or not, you'll notice that if you remove the process.nexTick and have your client like:
var net = require('net');
var client = net.connect({port: 1337}, function () {
var i = 100;
while (i--) {
client.write('a'+i+'\r\n');
}
});
you'll get two messages on the server (at least I got): first numbers 83 - 99 and then 0 - 82, despite having wrote them in order.
Its because TCP splits it in packets in some magic way. The first package was actually larger than the second one, so it got there last. You can read more about how TCP works in the wikipedia page of course, and this video is probably going to say more than what you need to hear but its good to understand everything you're working with.

Resources