#!/usr/bin/perl -w
# This is for interfacing directly with the SMA WebBox
use strict;
use Carp;
# Local config
my $webboxIP = "83.105.91.192";
# Hardcoded password digest (see below for how to generate it)
my $md5Passwd = "22a57394810fd219eb7bbd163021c270";
# Here's a Perl snippet to generate an md5 digest of your password:
# use Digest::MD5
# my $ctx = Digest::MD5->new;
# $ctx->add("MyPassword");
# my $md5Passwd = $ctx->hexdigest;
# Standard Perl modules
use IO::Socket::INET;
use Data::Dumper;
use IO::Handle;
# Nonstandard Perl modules
use JSON;
# Package globals
my $json = new JSON;
STDOUT->autoflush(1);
STDERR->autoflush(1);
sub responseForRequestString {
my $request = shift;
$request =~ s/\s//go;
$request =~ s/(.)/$1\0/go;
my $myRecvSocket = new IO::Socket::INET->new(LocalPort=>34268,Proto=>'udp');
my $mySendSocket = new IO::Socket::INET->new(PeerPort=>34268,Proto=>'udp',PeerAddr=>"$webboxIP");
my $timeoutSeconds = 5; # 5-second timeout
$myRecvSocket->sockopt(SO_RCVTIMEO, pack('LL', $timeoutSeconds, 0));
my $sentCharacters = $mySendSocket->send($request);
if (defined $sentCharacters) {
# print "Sent $sentCharacters characters\n";
} else {
print "Error in send\n";
}
my $response;
my $responder = $myRecvSocket->recv($response,1000000);
$response =~ s/\0//go;
return $response;
}
sub responseForRequest {
my $requestHash = shift;
$requestHash->{version} = "1.0" unless defined $requestHash->{version};
$requestHash->{id} = sprintf("%d", int(rand(100000))) unless defined $requestHash->{id};
$requestHash->{format} = "JSON" unless defined $requestHash->{format};
$requestHash->{passwd} = $md5Passwd unless defined $requestHash->{passwd};
my $request = $json->encode($requestHash);
my $response;
my $responseString;
my $firstTime = 1;
do {
if ($firstTime) {
$firstTime = 0;
} else {
sleep 1;
}
$responseString = responseForRequestString $request;
if ($responseString ne "") { # timeout?
$response = $json->decode($responseString);
}
} while ($responseString eq "") || ($response->{id} ne $requestHash->{id});
return $response;
}
my @channels = ("Pac", "Fac");
my @devices;
my $response = responseForRequest( { "proc" => "GetDevices" } );
foreach my $device (@{$response->{result}->{devices}}) {
push @devices, { "key" => $device->{key},
"channels" => \@channels };
}
$response = responseForRequest( { "proc" => "GetProcessData",
"params" => { "devices" => \@devices } } );
print Dumper($response); # Unnecessary but lets you see the structure of the output
@devices = @{$response->{result}->{devices}};
my $totalPower = 0;
foreach my $device (@devices) {
my @channels = @{$device->{channels}};
foreach my $channel (@channels) {
if ($channel->{name} eq "Pac") {
my $power = $channel->{value};
print "Device $device->{key}: Power $power\n";
$totalPower += $power;
}
}
}
print "Total power: $totalPower\n";