#!/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";