1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
| #!/usr/bin/perl
#Copyright (c) 2012 Martijn van Duijn
#PollEnecsys is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#You should have received a copy of the GNU General Public License
#along with this program. If not, see <http://www.gnu.org/licenses/>.
use Math::BaseCnv;
use Math::BaseCnv dig; # enable the dig option
use XML::Simple;
use LWP::Simple;
use DateTime;
dig('url'); # select the right alphabet for the base64
#Write headers for the columns
open WRITEFILE, ">>", "EnecsysLogfile.txt" or die $!; # define outputfile
print "Enecsys Logging Script\n";
print WRITEFILE "date", "\t", "time", "\t", "ZigbeeString", "\t", "deviceID", "\t","DCpower", "\t","Efficiency", "\t", "ACpower", "\t","DCcurrent", "\t","DCVolt", "\t","LifetimeProduction", "\t","Time1", "\t","Time2", "\t","ACvolt", "\t","ACfreq", "\t","Temperature", "\t","HexZigbee","\n";
close WRITEFILE;
for ($i=0; $i<50000; $i++) #This defines the number of reading loops. An infinite loop would also work, if you are not afraid of large logfiles
{
#print $i,"\n";
my $parser = new XML::Simple;
my $url = 'http://192.168.1.110/ajax.xml'; #Put IP address of the gateway
my $content = get $url or die "Unable to get $url\n";
my $data = $parser->XMLin($content);
my $dt=DateTime->now(time_zone => 'Europe/Amsterdam' ); #adjust timezone if desired. If unspecified time is UTC.
$Zigbee=$data->{zigbeeData}; #pick out the zigbee field
$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
{
$time = $dt->hms(':');
$date = $dt->mdy('-');
open WRITEFILE, ">>", "EnecsysLogfile.txt" or die $!; # define outputfile
print WRITEFILE $date, "\t", $time, "\t", $Zigbee, "\n";
close WRITEFILE;
}
if ($Zigbee =~ /^WS/ && length($Zigbee)==57 ) #Normal inverter strings are parsed
{
dig('url');
# $deviceID = substr($Zigbee,3,6); #This converts fields from base64 to decimal
# $Ztime = cnv(substr($Zigbee,14,4),64,10); #
# $ZUptime = cnv(substr($Zigbee,22,5),64,10);
# $Zdccurrent = cnv(substr($Zigbee,35,2),64,10)/500;
# $Zdcpower = cnv(substr($Zigbee,37,2),64,10);
# $ZEfficiency = cnv(substr($Zigbee,39,3),64,10)/4000;
# $Zacfreq = cnv(substr('A'.$Zigbee,42,1),64,10);
# $Zacvolt = cnv(substr($Zigbee,43,3),64,10)/4;
# $Ztemperature = cnv(substr('A'.$Zigbee,46,1),64,10);
# $ZDCenergy = cnv(substr($Zigbee,47,3),64,10)/4;
# $Zmonth = cnv(substr($Zigbee,50,2),64,10);
$time = $dt->hms(':');
$date = $dt->mdy('-');
$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
$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);
open WRITEFILE, ">>", "EnecsysLogfile.txt" or die $!; # define outputfile
print $date, "\t", $time, "\t", $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 $date, "\t", $time, "\t", $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";
close WRITEFILE;
}
if ($Zigbee =~ /^WS/ && length($Zigbee)!=57 ) #other inverter strings (startup?)
{
$time = $dt->hms(':');
$date = $dt->mdy('-');
#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;
}
sleep 2;
} |