Victron Energy munin plugins for Cerbo GX monitoring
Friday, February 28th, 2025Charger amps
#!/usr/bin/perluse Device::Modbus::TCP::Client;
my $client = Device::Modbus::TCP::Client->new(
host => ‘put your GX ip or name here’
);$config = 1 if(“config” ~~ @ARGV);
$chargers = [ 223, 224, 226, 238, 239 ]; # devicesif($config) {
print “graph_title charger amps\n”;
print “graph_category victron\n”;
foreach $charger (@{$chargers}) {
print $charger . “_amps.label Amps\n”;
}
} else {
foreach $charger (@{$chargers}) {
my $req = $client->read_holding_registers( unit => $charger, address => 772, quantity => 1 );
$client->send_request($req) || die “Send error: $!”;
my $response = $client->receive_response;
print $charger . “_amps.value ” . uint16_to_int( @{$response->{‘message’}->{‘values’}}[0]) / 10 . “\n”;}
}sub uint16_to_int {
my $uint16 = shift;
return $uint16 > 0x7FFF ? $uint16 – 0x10000 : $uint16;
}
Charger overall power
#!/usr/bin/perluse Device::Modbus::TCP::Client;
my $client = Device::Modbus::TCP::Client->new(
host => ‘put your GX ip or name here’
);$config = 1 if(“config” ~~ @ARGV);
$chargers = [ 223, 224, 226, 238, 239 ]; # adjust with your actual list. See Settings -> Services -> Modbus for a list
if($config) {
print “graph_title charger total watts\n”;
print “graph_category victron\n”;
print “total_watts.label watts\n”;
} else {
my $total = 0;foreach $charger (@{$chargers}) {
my $req = $client->read_holding_registers( unit => $charger, address => 789, quantity => 1 );
$client->send_request($req) || die “Send error: $!”;
my $response = $client->receive_response;
$total += uint16_to_int( @{$response->{‘message’}->{‘values’}}[0]) / 10;
}print “total_watts.value $total\n”;
}sub uint16_to_int {
my $uint16 = shift;
return $uint16 > 0x7FFF ? $uint16 – 0x10000 : $uint16;
}
Charger individual power
#!/usr/bin/perluse Device::Modbus::TCP::Client;
my $client = Device::Modbus::TCP::Client->new(
host => ‘put your GX name or IP here’
);$config = 1 if(“config” ~~ @ARGV);
$chargers = [ 223, 224, 226, 238, 239 ];
if($config) {
print “graph_title charger watts\n”;
print “graph_category victron\n”;
foreach $charger (@{$chargers}) {
print $charger . “_watts.label Amps\n”;
}
} else {
foreach $charger (@{$chargers}) {
my $req = $client->read_holding_registers( unit => $charger, address => 789, quantity => 1 );
$client->send_request($req) || die “Send error: $!”;
my $response = $client->receive_response;
print $charger . “_watts.value ” . uint16_to_int( @{$response->{‘message’}->{‘values’}}[0]) / 10 . “\n”;}
}sub uint16_to_int {
my $uint16 = shift;
return $uint16 > 0x7FFF ? $uint16 – 0x10000 : $uint16;
}
inverter state of charge
#!/usr/bin/perluse Device::Modbus::TCP::Client;
my $client = Device::Modbus::TCP::Client->new(
host => ‘put your GX name or IP here’
);$config = 1 if(“config” ~~ @ARGV);
my $req = $client->read_holding_registers( unit => 227, address => 30, quantity => 1 );
$client->send_request($req) || die “Send error: $!”;
my $response = $client->receive_response;if($config) {
print “graph_title state of charge\n”;
print “graph_category victron\n”;
print “inv_soc.label SOC\n”;
} else {
print “inv_soc.value ” . uint16_to_int( @{$response->{‘message’}->{‘values’}}[0]) / 10 . “\n”;
}sub uint16_to_int {
my $uint16 = shift;
return $uint16 > 0x7FFF ? $uint16 – 0x10000 : $uint16;
}
Inverter bus voltage
#!/usr/bin/perl
use Device::Modbus::TCP::Client;my $client = Device::Modbus::TCP::Client->new(
host => ‘your GX device goes here’
);$config = 1 if(“config” ~~ @ARGV);
my $req = $client->read_holding_registers( unit => 227, address => 26, quantity => 2 );
$client->send_request($req) || die “Send error: $!”;
my $response = $client->receive_response;if($config) {
print “graph_title battery volts\n”;
print “graph_category victron\n”;
print “inv_volts.label Volts\n”;
} else {
print “inv_volts.value ” . @{$response->{‘message’}->{‘values’}}[0] /100 . “\n”;
}