We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I am trying to port over the Perl script below to processing. I only know a little about Processing Java and even less about Perl. Where I am having issues is with Perl unpack and dig. Please, will someone help me port the below Perl segment to Processing?
Thank you.
#!/usr/bin/perl
use IO::Socket::INET;
use Math::BaseCnv;
use Math::BaseCnv dig; # enable the dig option
use LWP::Simple;
dig('url'); # select the right alphabet for the base64
$apikey="YOUR-API-KEY-HERE";
# auto-flush on socket
$| = 1;
# creating a listening socket
my $socket = new IO::Socket::INET (
LocalHost => '0.0.0.0',
LocalPort => '5040',
Proto => 'tcp',
Listen => 5,
Reuse => 1
);
die "cannot create socket $!\n" unless $socket;
print "Server waiting for client connections...check log file EnecsysLogfile.txt for details.\n";
while(1)
{
# waiting for a new client connection
my $client_socket = $socket->accept();
# get information about a newly connected client
my $client_address = $client_socket->peerhost();
my $client_port = $client_socket->peerport();
open WRITEFILE, ">>", "EnecsysLogfile.txt" or die $!; # define outputfile
# read up to 1024 characters from the connected client
my $data = "";
$client_socket->recv($data, 1024);
print WRITEFILE "connection from $client_address:$client_port $data\n";
$ZigbeeRaw = $data;
chomp $ZigbeeRaw;
$Zigbee = substr($ZigbeeRaw,18);
$Zigbee =~ s/\r//g; #Remove lifefeed and CR from the string
$Zigbee =~ s/\n//g; #Usually chomp is used for that, but there are issues between platforms with that
if ($Zigbee =~ /^WZ/) #Gateway strings will just be logged
{
#open WRITEFILE, ">>", "EnecsysLogfile.txt" or die $!; # define outputfile
#print WRITEFILE $date, "\t", $time, "\t", $Zigbee, "\n";
#close WRITEFILE;
}
# START OF PROBLEM
if ($Zigbee =~ /^WS/ && length($Zigbee)==59 ) #Normal inverter strings are parsed
{
dig('url');
$DecZigbee = cnv('A'.substr($Zigbee,3,54),64,10); #decimal representation of whole Zigbee string
dig('HEX'); #the url alphabet messes up de dec hex conversions, so change to HEX
$HexZigbee = cnv($DecZigbee,10,16); #Hex representation of zigbeestring
if (length($HexZigbee) ==80) # if we have a leading 0 it gets chopped off, this is a fix for that.
{
$HexZigbee="0".$HexZigbee;
}
$HexID = substr($HexZigbee,0,8); #Device ID in hex
$IDEndian = unpack("H*", pack("V*", unpack("N*", pack("H*", $HexID)))); # some magic to convert from little to big endian
# END OF PROBLEM
$IDDec = cnv($IDEndian,16,10); #Device ID in decimal numbers. Should match Enecsys monitor site
$HexTime1 = cnv(substr($HexZigbee,18,4),16,10);
$HexTime2 = cnv(substr($HexZigbee,30,6),16,10);
$HexDCCurrent = 0.025*cnv(substr($HexZigbee,46,4),16,10); #25 mA units?
$HexDCPower = cnv(substr($HexZigbee,50,4),16,10);
$HexEfficiency = 0.001*cnv(substr($HexZigbee,54,4),16,10);#expressed as fraction
$HexACFreq = cnv(substr($HexZigbee,58,2),16,10);
$HexACVolt = cnv(substr($HexZigbee,60,4),16,10);
$HexTemperature = cnv(substr($HexZigbee,64,2),16,10);
$HexWh = cnv(substr($HexZigbee,66,4),16,10);
$HexkWh = cnv(substr($HexZigbee,70,4),16,10);
$LifekWh = (0.001*$HexWh)+$HexkWh;
$ACpower = $HexDCPower * $HexEfficiency;
$HexDCVolt = sprintf("%0.2f",$HexDCPower / $HexDCCurrent);
my $url = "http://" . "emoncms.org/input/post.json?node=1&json={$IDDec:$ACpower}&apikey=$apikey";
my $content = get $url or print WRITEFILE "Unable to get $url\n";
print WRITEFILE "sent data".$url."-".$content."\n";
#open WRITEFILE, ">>", "EnecsysLogfile.txt" or die $!; # define outputfile
#print $IDDec, "\t",$HexDCPower, "W\t",$LifekWh, "kWh\t",$HexTemperature, "C\n";
# print WRITEFILE $date, "\t", $time, "\t", $Zigbee, "\t", $deviceID, "\t",$Zdcpower, "\t",$ZEfficiency, "\t", $ACpower, "\t",$Zdccurrent, "\t",$ZDCenergy, "\t",$Zmonth, "\t",$Ztime, "\t",$Zacvolt, "\t",$Zacfreq, "\t",$Ztemperature, "\t",$ZUptime, "\t",$LifekWh, "\t",$HexZigbee, "\t",$IDDec,"\n";
#print WRITEFILE $Zigbee, "\t", $IDDec, "\t",$HexDCPower, "\t",$HexEfficiency, "\t", $ACpower, "\t",$HexDCCurrent, "\t",$HexDCVolt, "\t",$LifekWh, "\t",$HexTime1, "\t",$HexTime2, "\t",$HexACVolt, "\t",$HexACFreq, "\t",$HexTemperature, "\t",$HexZigbee,"\n";
#print $IDDec, "\t",$HexDCPower, "\t",$HexEfficiency, "\t", $ACpower, "\t",$HexDCCurrent, "\t",$HexDCVolt, "\t",$LifekWh, "\t time1=",$HexTime1, "\t time2=",$HexTime2, "\t",$HexACVolt, "\t",$HexACFreq, "\t",$HexTemperature, "\t",$HexZigbee,"\n";
# close WRITEFILE;
}
if ($Zigbee =~ /^WS/ && length($Zigbee)!=57 ) #other inverter strings (startup?)
{
#print $date, "\t", $time, "\t", $Zigbee, "\n";
# open WRITEFILE, ">>", "EnecsysLogfile.txt" or die $!; # define outputfile
# print WRITEFILE $date, "\t", $time, "\t", $Zigbee, "\n";
# close WRITEFILE;
}
# notify client that response has been sent
shutdown($client_socket, 1);
}
$socket->close();
Answers
is that doing something specific with zigbee or is it just general?
try searching for a java version, it'll be easier to convert.
(it is, based on the filename - Enecsys are a range of solar panels)
There is no Java version that I am aware of, the zigbee is really unimportant, a rose by any other name etc. What I need is a Java version of unpack and dig. Because I don't really know Perl, I am not sure how they work.
Thanks for your response.
That unpack command is just converting from big endian to little endian, or vice versa, it's not doing a lot. (Basically you get 4 bytes from the device, lowest first, and it conveys then too highest first. In decimal it would be sending the number 1234 as 4, 3, 2, 1 and needs converting)
Dig, I don't know.
here's the dig documentation
http://search.cpan.org/~pip/Math-BaseCnv-1.4.75O6Pbr/BaseCnv.pm#dig(\@newd)
dig('hex') appears to put it into hex mode.
dig('url') puts it into url mode.
the problem with this is that it'll be easy enough to convert the data from the input to the output but we've no way of getting the input data without access to a zigbee / inverter. (unless you could dump it into a file somewhere and upload it for us to test with - it only looks like 60 bytes of data...)
running this little perl script:
prints "04030201080706050c0b0a09". it's swapping the order of each group of bytes.
AWE!! Thank you, the feed works, I can read a string using the following code.
I need the following ported to Java
//The following is very crude but I can read the input stream with it