NodeJS and Sending UDP Data

I am working on a script to send weather data to a Magic Mirror and will be doing so from a Raspberry Pi. I will take the data from the WFArchiver, convert it to my local values and send only the data necessary for the Magic Mirror. I want to show how esay it is to do this from the Pi.

The code is listed in the next post.

As you can see, I had to write more code to get the proper Broadcast address than to send the UDP packet.

3 Likes
const dgram = require('dgram'); 
const network = require('network');
const server = dgram.createSocket("udp4"); 
const PORT = 6024;

var broadcastIP;

network.get_active_interface(function(err, obj) {
	console.log(obj);
	console.log('');
	broadcastIP = IPv4_Address(obj.ip_address, obj.netmask);
	console.log('Broadcast IP = ' + broadcastIP);
});

server.bind(function() {
    server.setBroadcast(true);
    setInterval(broadcastNew, 3000);
});

function broadcastNew() {
    var message = new Buffer("Broadcast message!");
    server.send(message, 0, message.length, PORT, broadcastIP, function() {
        console.log("Sent '" + message + "'");
    });
} 

function IPv4_Address( addressDotQuad, netmaskDotQuad ) {
	var addressInteger = IPv4_dotquad_to_int( addressDotQuad.toString() );
	var addressBinStr  = IPv4_int_to_binstr( addressInteger );

	var netmaskInteger = IPv4_dotquad_to_int( netmaskDotQuad.toString() );
	var netmaskBinStr  = IPv4_int_to_binstr( netmaskInteger );
	
	var netbcastBinStr = IPv4_calc_netbcastBinStr( addressBinStr, netmaskBinStr );
	var netbcastInteger = IPv4_binstr_to_int( netbcastBinStr );	

	return IPv4_int_to_dotquad( netbcastInteger );
}

/* dotted-quad IP to integer */
function IPv4_dotquad_to_int( strbits ) {
	var split = strbits.split( '.', 4 );
	var myInt = (
		parseFloat( split[0] * 16777216 )	/* 2^24 */
	  + parseFloat( split[1] * 65536 )		/* 2^16 */
	  + parseFloat( split[2] * 256 )		/* 2^8  */
	  + parseFloat( split[3] )
	);
	return myInt;
}

/* integer IP to binary string representation */
function IPv4_int_to_binstr( strnum ) {
	var numStr = strnum.toString( 2 ); /* Initialize return value as string */
	var numZeros = 32 - numStr.length; /* Calculate no. of zeros */
	if (numZeros > 0) {	
		for (var i = 1; i <= numZeros; i++) {
			numStr = "0" + numStr 
		}	
	} 
	return numStr;
}

/* logical OR between address & NOT netmask */
function IPv4_calc_netbcastBinStr( addressBinStr, netmaskBinStr ) {
	var netbcastBinStr = '';
	var aBit = 0; var nmBit = 0;
	for( pos = 0; pos < 32; pos ++ ) {
		aBit = parseInt( addressBinStr.substr( pos, 1 ));
		nmBit = parseInt( netmaskBinStr.substr( pos, 1 ));
		if( nmBit ) {
			nmBit = 0;	/* flip netmask bits */
		} else {
			nmBit = 1;
		}
		if( aBit || nmBit ) {
			netbcastBinStr += '1';	
		} else {	
			netbcastBinStr += '0';	
		}
	}
	return netbcastBinStr;
}

/* binary string IP to integer representation */
function IPv4_binstr_to_int( binstr ) {
	return parseInt( binstr, 2 );
}

/* integer IP to dotted-quad */
function IPv4_int_to_dotquad( strnum ) {
	var byte1 = ( strnum >>> 24 );
	var byte2 = ( strnum >>> 16 ) & 255;
	var byte3 = ( strnum >>>  8 ) & 255;
	var byte4 = strnum & 255;
	return ( byte1 + '.' + byte2 + '.' + byte3 + '.' + byte4 );
}
2 Likes