Page 3 of 6

Re: SolarEdge via LAN interface

Posted: Saturday 03 March 2018 11:00
by thecosmicgate
freijn wrote:Mischa

I am test running the perl script for the 2nd day now, BEAUTIFULL ! I have connected the incoming P1 meter event to read the
SolarEdge meters. So a SolarEdge update every 10 seconds :-)

I am still optimizing it.
The combined sensor.. Current power / Daily power / and lifetime power I am struggeling with at this moment.

Unless you are a hacker and can't wait ( I can share the current version ) please allow us a few day to optimize the script and create a
small installer document.

Again.. with the 10 sec update I am very very pleased using this Perl script , thanks to Mello !

Frank
I'am not a hacker, but can't wait ;)

Sent from my SM-G935F using Tapatalk


Re: SolarEdge via LAN interface

Posted: Sunday 04 March 2018 11:05
by Micha123
you Need to compile and install much thinks to run the script.


we waiting for the final Version.

@McMelloW

have you added the port config already ?
and have you added the Ampere sensors ?

Re: SolarEdge via LAN interface

Posted: Sunday 04 March 2018 15:08
by McMelloW
Micha123 wrote: Sunday 04 March 2018 11:05 you Need to compile and install much thinks to run the script.
we waiting for the final Version.
It is a bit of a struggle to install all perl dependencies. Take your time andinstall them one by one. Then the script from github will run if you have used the correct options. The script from freijn need adjustments to your system and devices.
@McMelloW

have you added the port config already ?
and have you added the Ampere sensors ?
Read this document from SolarEdge The best thing is to do after sunset. No powerproduction at that time. Be aware not to start pairing optimezers. This will only work when there is enough sunshine.
I don't no anything about Ampere Sensor. If they are SolarEdge Sensors, you can find all documentation at their site.
When you port config is ready, you can try the script in verbose mode on a commandline and see what happens.

Re: SolarEdge via LAN interface

Posted: Sunday 04 March 2018 15:15
by freijn
Hi Micha

I believe this is now a version which could work for others.

Please modify the IP Port and IDX to your environment.
Port and Amp now also included.

Also seach for dc_i and ac_i and uncomment the #senddomo ( remove the # at the beginning )

Please let me know how you are doing?

$idxActPwr2 is some test code as we would like to have a single sensor with all values in. As today that is not working yet :-(

Code: Select all



#!/usr/bin/perl
#
# sunspec-monitor
#
# Copyright (C) 2017-2018 Timo Kokkonen <[email protected]>
#
# This program 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, 
# Boston, MA  02110-1301, USA. 
#
#

use Data::Dumper;
use Device::Modbus::TCP::Client;
use Getopt::Long;
use strict;
use LWP::Simple;



my $TIMEOUT = 10;
my $PORT = 502;

my $SUNSPEC_I_COMMON_BLOCK_START = 40000;
my $SUNSPEC_I_MODEL_BLOCK_START = 40069;
my $SUNSPEC_M_COMMON_BLOCK_START = 40121;
my $SUNSPEC_M_MODEL_BLOCK_START = 40188;


#####################################################################
# For Domoticz, please edit below to your own environment           # 
#####################################################################
my $domoip ="192.168.1.155"; # Domoticz ipaddress.
my $dport = "8080"; #Domoticz port number.
my $idxSEstat = 232; # idx value of SolarEdge Status, Text device
my $idxActPwr = 240; # idx value of SolarEdge Actual Power / Total Production, General, Kwh device
my $idxActPwr2 = 239; # idx value of SolarEdge Actual Power / Total Production, General, Kwh device
my $idxACinv = 233;  # idx value of AC Inverter, Voltage device
my $idxac_i = 0;     # idx value of AC Inverter, Amp device
my $idxAC_f = 238;   # idx value of AC Inverter freqency text device
my $idxDCinv = 234;  # idx value of DC Inverter, Voltage device
my $idxdc_i = 0;     # idx value of DC Inverter, Amp device
my $idxEffin = 235;  # idx value of SolarEdge Efficiency, Percentage device
my $idxTemp  = 236;  # idx value of SalorEdge Temperature, Temperature device
my $idxTotPwr = 237; # idx value of Total LifTime Production, Custom Sensor
######################################################################
# Domoticz extra variables  used                                     #
######################################################################
my $version ="1.2";
my $url ="";
my $content="";
my $content="";
my $dwh=0;
my $deff=0;
my $dtemp=0;
my $dac_f=0;


my %I_STATUS = ( 
    0=>'Unknown', 
    1=>'OFF', 
    2=>'SLEEPING',
    3=>'STARTING',
    4=>'ON (MPPT)',
    5=>'THROTTLED',
    6=>'SHUTTING DOWN',
    7=>'FAULT',
    8=>'STANDBY'
    );

	
	
# get_inverter_common_block - return a hash containing Sunspec
#                             Common Block values
#
sub get_inverter_common_block(*) {
    my ($ctx) = @_;

    my $req = $ctx->read_holding_registers(unit=>1,
					   address=>$SUNSPEC_I_COMMON_BLOCK_START,
					   quantity=>69);
    $ctx->send_request($req) || die("send_request(): failed");

    my $adu = $ctx->receive_response();
    die("Read of Common block registers failed (device does not support SunSpec?)")
    	unless ($adu->success);


    my $data = pack("n*",@{$adu->values});
    my $cb;
    $cb->{C_SunSpec_ID} = unpack("a4",substr($data,0,4));
    $cb->{C_SunSpec_DID} = unpack("n",substr($data,4,2));
    $cb->{C_SunSpec_Length} = unpack("n",substr($data,6,2));
    $cb->{C_Manufacturer} = unpack("a*",substr($data,8,32));
    $cb->{C_Manufacturer} =~ s/\0+$//; 
    $cb->{C_Model} = unpack("a*",substr($data,40,32));
    $cb->{C_Model} =~ s/\0+$//; 
    $cb->{C_Version} = unpack("a*",substr($data,88,16));
    $cb->{C_Version} =~ s/\0+$//; 
    $cb->{C_SerialNumber} = unpack("a*",substr($data,104,32));
    $cb->{C_SerialNumber} =~ s/\0+$//; 
    $cb->{C_DeviceAddress} = unpack("n",substr($data,136,2));

    
    die("Non SunSpec common block received (not SunSpec compliant device?)")
    	     unless ($cb->{C_SunSpec_ID} eq "SunS" && $cb->{C_SunSpec_DID} == 1);

    return $cb;
}


# get_inverter_model_block - return a hash containing Sunspec Inverter
#                            Model Block values
#
sub get_inverter_model_block(*) {
    my ($ctx) = @_;

    my $req = $ctx->read_holding_registers(unit=>1,
					   address=>$SUNSPEC_I_MODEL_BLOCK_START,
					   quantity=>52);
    $ctx->send_request($req) || die("send_request(): failed");

    my $adu = $ctx->receive_response();
    die("Read of Inverter Model block registers failed (device does not support SunSpec?)")
    	unless ($adu->success);


    my $data = pack("n*",@{$adu->values});
    my $mb;
    $mb->{C_SunSpec_DID} = unpack("n",substr($data,0,2));
    $mb->{C_SunSpec_Length} = unpack("n",substr($data,2,2));
    $mb->{I_AC_Current} = unpack("n",substr($data,4,2));
    $mb->{I_AC_CurrentA} = unpack("n",substr($data,6,2));
    $mb->{I_AC_CurrentB} = unpack("n",substr($data,8,2));
    $mb->{I_AC_CurrentC} = unpack("n",substr($data,10,2));
    $mb->{I_AC_Current_SF} = unpack("n!",substr($data,12,2));
    $mb->{I_AC_VoltageAB} = unpack("n",substr($data,14,2));
    $mb->{I_AC_VoltageBC} = unpack("n",substr($data,16,2));
    $mb->{I_AC_VoltageCA} = unpack("n",substr($data,18,2));
    $mb->{I_AC_VoltageAN} = unpack("n",substr($data,20,2));
    $mb->{I_AC_VoltageBN} = unpack("n",substr($data,22,2));
    $mb->{I_AC_VoltageCN} = unpack("n",substr($data,24,2));
    $mb->{I_AC_Voltage_SF} = unpack("n!",substr($data,26,2));
    $mb->{I_AC_Power} = unpack("n!",substr($data,28,2));
    $mb->{I_AC_Power_SF} = unpack("n!",substr($data,30,2));
    $mb->{I_AC_Frequency} = unpack("n",substr($data,32,2));
    $mb->{I_AC_Frequency_SF} = unpack("n!",substr($data,34,2));
    $mb->{I_AC_VA} = unpack("n!",substr($data,36,2));
    $mb->{I_AC_VA_SF} = unpack("n!",substr($data,38,2));
    $mb->{I_AC_VAR} = unpack("n!",substr($data,40,2));
    $mb->{I_AC_VAR_SF} = unpack("n!",substr($data,42,2));
    $mb->{I_AC_PF} = unpack("n!",substr($data,44,2));
    $mb->{I_AC_PF_SF} = unpack("n!",substr($data,46,2));
    $mb->{I_AC_Energy_WH} = unpack("N",substr($data,48,4));
    $mb->{I_AC_Energy_WH_SF} = unpack("n!",substr($data,52,2));
    $mb->{I_DC_Current} = unpack("n",substr($data,54,2));
    $mb->{I_DC_Current_SF} = unpack("n!",substr($data,56,2));
    $mb->{I_DC_Voltage} = unpack("n",substr($data,58,2));
    $mb->{I_DC_Voltage_SF} = unpack("n!",substr($data,60,2));
    $mb->{I_DC_Power} = unpack("n!",substr($data,62,2));
    $mb->{I_DC_Power_SF} = unpack("n!",substr($data,64,2));
    # 40103 unused
    $mb->{I_Temp_Sink} = unpack("n!",substr($data,68,2));
    # 40105-40106 unused
    $mb->{I_Temp_Sink_SF} = unpack("n!",substr($data,74,2));
    $mb->{I_Status} = unpack("n",substr($data,76,2));
    $mb->{I_Status_Vendor} = unpack("n",substr($data,78,2));
    $mb->{I_Event_1} = unpack("N",substr($data,80,4));
    $mb->{I_Event_2} = unpack("N",substr($data,84,4));
    $mb->{I_Event_1_Vendor} = unpack("N",substr($data,88,4));
    $mb->{I_Event_2_Vendor} = unpack("N",substr($data,92,4));
    $mb->{I_Event_3_Vendor} = unpack("N",substr($data,96,4));
    $mb->{I_Event_4_Vendor} = unpack("N",substr($data,100,4));

    die("Non SunSpec Model block received (not SunSpec compliant device?)")
    	     unless ($mb->{C_SunSpec_Length} == 50);

    return $mb;
}



# Send URL to domoticz to update sensors
# para  idx ,value, verbose  
#
sub senddomo(***){
  my ($idx, $value,$verbose) = @_;
  $url = "http://$domoip:".$dport."/json.htm?type=command&param=udevice&idx=$idx&svalue=$value";
  $content = get($url);
  if ($verbose) {
    print "\n";
    print ($url);
	print "\n";
  }
  die "Can't GET $url" if (! defined $content);
}





# get_meter_common_block - return a has containing Sunspec
#                          Meter Common block values
#  meter = 1..3
#
sub get_meter_common_block(**) {
    my ($ctx,$meter) = @_;

    $meter=1 if ($meter < 1);
    $meter=3 if ($meter > 3);
    my $offset = ($meter - 1) * 174;

    my $req = $ctx->read_holding_registers(unit=>1,
					   address=>$SUNSPEC_M_COMMON_BLOCK_START + $offset,
					   quantity=>65);
    $ctx->send_request($req) || die("send_request(): failed");

    my $adu = $ctx->receive_response();
    die("Read of Meter $meter block registers failed (device does not support SunSpec?)")
    	unless ($adu->success);


    my $data = pack("n*",@{$adu->values});
    my $cb;
    $cb->{C_SunSpec_DID} = unpack("n",substr($data,0,2));
    $cb->{C_SunSpec_Length} = unpack("n",substr($data,2,2));
    $cb->{C_Manufacturer} = unpack("a*",substr($data,4,32));
    $cb->{C_Manufacturer} =~ s/\0+$//;
    $cb->{C_Model} = unpack("a*",substr($data,36,32));
    $cb->{C_Model} =~ s/\0+$//;
    $cb->{C_Option} = unpack("a*",substr($data,68,16));
    $cb->{C_Option} =~ s/\0+$//;
    $cb->{C_Version} = unpack("a*",substr($data,84,16));
    $cb->{C_Version} =~ s/\0+$//;
    $cb->{C_SerialNumber} = unpack("a*",substr($data,100,32));
    $cb->{C_SerialNumber} =~ s/\0+$//;


    die("Non SunSpec Meter Common block received (not SunSpec compliant device?)")
    	     unless ($cb->{C_SunSpec_Length} == 65);

    return $cb;
}


# get_meter_model_block - return a has containing Sunspec
#                         Meter Model block values
#  meter = 1..3
#
sub get_meter_model_block(**) {
    my ($ctx,$meter) = @_;

    $meter=1 if ($meter < 1);
    $meter=3 if ($meter > 3);
    my $offset = ($meter - 1) * 174;

    my $req = $ctx->read_holding_registers(unit=>1,
					   address=>$SUNSPEC_M_MODEL_BLOCK_START + $offset,
					   quantity=>107);
    $ctx->send_request($req) || die("send_request(): failed");

    my $adu = $ctx->receive_response();
    die("Read of Meter $meter block registers failed (device does not support SunSpec?)")
    	unless ($adu->success);


    my $data = pack("n*",@{$adu->values});
    my $mb;
    $mb->{C_SunSpec_DID} = unpack("n",substr($data,0,2));
    $mb->{C_SunSpec_Length} = unpack("n",substr($data,2,2));
    $mb->{M_AC_Current} = unpack("n!",substr($data,4,2));
    $mb->{M_AC_Current_A} = unpack("n!",substr($data,6,2));
    $mb->{M_AC_Current_B} = unpack("n!",substr($data,8,2));
    $mb->{M_AC_Current_C} = unpack("n!",substr($data,10,2));
    $mb->{M_AC_Current_SF} = unpack("n!",substr($data,12,2));
    $mb->{M_AC_Voltage_LN} = unpack("n!",substr($data,14,2));
    $mb->{M_AC_Voltage_AN} = unpack("n!",substr($data,16,2));
    $mb->{M_AC_Voltage_BN} = unpack("n!",substr($data,18,2));
    $mb->{M_AC_Voltage_CN} = unpack("n!",substr($data,20,2));
    $mb->{M_AC_Voltage_LL} = unpack("n!",substr($data,22,2));
    $mb->{M_AC_Voltage_AB} = unpack("n!",substr($data,24,2));
    $mb->{M_AC_Voltage_BC} = unpack("n!",substr($data,26,2));
    $mb->{M_AC_Voltage_CA} = unpack("n!",substr($data,28,2));
    $mb->{M_AC_Voltage_SF} = unpack("n!",substr($data,30,2));
    $mb->{M_AC_Freq} = unpack("n!",substr($data,32,2));
    $mb->{M_AC_Freq_SF} = unpack("n!",substr($data,34,2));
    $mb->{M_AC_Power} = unpack("n!",substr($data,36,2));
    $mb->{M_AC_Power_A} = unpack("n!",substr($data,38,2));
    $mb->{M_AC_Power_B} = unpack("n!",substr($data,40,2));
    $mb->{M_AC_Power_C} = unpack("n!",substr($data,42,2));
    $mb->{M_AC_Power_SF} = unpack("n!",substr($data,44,2));
    $mb->{M_AC_VA} = unpack("n!",substr($data,46,2));
    $mb->{M_AC_VA_A} = unpack("n!",substr($data,48,2));
    $mb->{M_AC_VA_B} = unpack("n!",substr($data,50,2));
    $mb->{M_AC_VA_C} = unpack("n!",substr($data,52,2));
    $mb->{M_AC_VA_SF} = unpack("n!",substr($data,54,2));
    $mb->{M_AC_VAR} = unpack("n!",substr($data,56,2));
    $mb->{M_AC_VAR_A} = unpack("n!",substr($data,58,2));
    $mb->{M_AC_VAR_B} = unpack("n!",substr($data,60,2));
    $mb->{M_AC_VAR_C} = unpack("n!",substr($data,62,2));
    $mb->{M_AC_VAR_SF} = unpack("n!",substr($data,64,2));
    $mb->{M_AC_PF} = unpack("n!",substr($data,66,2));
    $mb->{M_AC_PF_A} = unpack("n!",substr($data,68,2));
    $mb->{M_AC_PF_B} = unpack("n!",substr($data,70,2));
    $mb->{M_AC_PF_C} = unpack("n!",substr($data,72,2));
    $mb->{M_AC_PF_SF} = unpack("n!",substr($data,74,2));
    $mb->{M_Exported} = unpack("N",substr($data,76,4));
    $mb->{M_Exported_A} = unpack("N",substr($data,80,4));
    $mb->{M_Exported_B} = unpack("N",substr($data,84,4));
    $mb->{M_Exported_C} = unpack("N",substr($data,88,4));
    $mb->{M_Imported} = unpack("N",substr($data,92,4));
    $mb->{M_Imported_A} = unpack("N",substr($data,96,4));
    $mb->{M_Imported_B} = unpack("N",substr($data,100,4));
    $mb->{M_Imported_C} = unpack("N",substr($data,104,4));
    $mb->{M_Energy_W_SF} = unpack("n!",substr($data,108,2));
    $mb->{M_Exported_VA} = unpack("N",substr($data,110,4));
    $mb->{M_Exported_VA_A} = unpack("N",substr($data,114,4));
    $mb->{M_Exported_VA_B} = unpack("N",substr($data,118,4));
    $mb->{M_Exported_VA_C} = unpack("N",substr($data,122,4));
    $mb->{M_Imported_VA} = unpack("N",substr($data,126,4));
    $mb->{M_Imported_VA_A} = unpack("N",substr($data,130,4));
    $mb->{M_Imported_VA_B} = unpack("N",substr($data,134,4));
    $mb->{M_Imported_VA_C} = unpack("N",substr($data,138,4));
    $mb->{M_Energy_VA_SF} = unpack("n!",substr($data,142,2));
    $mb->{M_Import_VARh_Q1} = unpack("N",substr($data,144,4));
    $mb->{M_Import_VARh_Q1A} = unpack("N",substr($data,148,4));
    $mb->{M_Import_VARh_Q1B} = unpack("N",substr($data,152,4));
    $mb->{M_Import_VARh_Q1C} = unpack("N",substr($data,156,4));
    $mb->{M_Import_VARh_Q2} = unpack("N",substr($data,160,4));
    $mb->{M_Import_VARh_Q2A} = unpack("N",substr($data,164,4));
    $mb->{M_Import_VARh_Q2B} = unpack("N",substr($data,168,4));
    $mb->{M_Import_VARh_Q2C} = unpack("N",substr($data,172,4));
    $mb->{M_Import_VARh_Q3} = unpack("N",substr($data,176,4));
    $mb->{M_Import_VARh_Q3A} = unpack("N",substr($data,180,4));
    $mb->{M_Import_VARh_Q3B} = unpack("N",substr($data,184,4));
    $mb->{M_Import_VARh_Q3C} = unpack("N",substr($data,188,4));
    $mb->{M_Import_VARh_Q4} = unpack("N",substr($data,192,4));
    $mb->{M_Import_VARh_Q4A} = unpack("N",substr($data,196,4));
    $mb->{M_Import_VARh_Q4B} = unpack("N",substr($data,200,4));
    $mb->{M_Import_VARh_Q4C} = unpack("N",substr($data,204,4));
    $mb->{M_Energy_VAR_SF} = unpack("n!",substr($data,208,2));
    $mb->{M_Events} = unpack("N",substr($data,210,4));


    die("Non SunSpec Meter Common block received (not SunSpec compliant device?)")
    	     unless ($mb->{C_SunSpec_DID} >= 201 && $mb->{C_SunSpec_DID} <= 204);

    return $mb;
}


# scale_value - scale input value using scale factor (SF)
#
sub scale_value(**) {
  my ($val,$sf) = @_;

  return $val * (10 ** $sf);
}


###################################################################################
# main program

my $verbose_mode = 0;
my $debug_mode = 0;
my $numeric_mode = 0;
my $json_mode = 0;
my $meter = 1;
my $port = $PORT;
my $timeout = $TIMEOUT;
my $domoticz = 0;

GetOptions("verbose|v" => \$verbose_mode,
	   "debug|d" => \$debug_mode,
	   "port|p=s" => \$port,
	   "meter|m=s" => \$meter,
	   "numeric|n" => \$numeric_mode,
	   "json|j" => \$json_mode,
	   "timeout|t=s" => \$timeout,
	   "domoticz|z" => \$domoticz);

my $host = shift;

unless ($host) {
  print STDERR "syntax: $0 [options] <host>\n\n",
    "Options:\n",
    " --port=<port>, -p <port>      Use port (default $PORT)\n",
    " --meter=<meter>, -m <meter>   Query meter (default 1) \n",
    "                               (meter = 1..3  or 0 = no meter)\n",
    " --numeric, -n                 Numeric output mode (time, status)\n",
    " --json, -j                    Output in JSON (instead of CSV) format\n",
    " --timeout=<sec>, -t <sec>     Timeout (default $TIMEOUT)\n",
    " --verbose, -v                 Verbose mode\n",
	" --domoticz, -z                Domoticz mode\n",
    " --debug, -d                   Debug mode\n";
	print "Version : $version\n\n";
  exit(1);
}

die("invalid port ($port) specified") unless ($port > 0 && $port < 65536);
die("invalid meter ($meter) specified") unless ($meter >= 0 && $meter <= 3);


my $c = Device::Modbus::TCP::Client->new(host=>$host,port=>$port,timeout=>$timeout);
my $tstamp = time();
my $cb = get_inverter_common_block($c);

my $fw_ver = $cb->{C_Version};

$fw_ver =~ s/^0+//;

if ($verbose_mode) {
  print "INVERTER:\n";
  print "             Model: $cb->{C_Manufacturer} $cb->{C_Model}\n";
  print "  Firmware version: $fw_ver\n";
  print "     Serial Number: $cb->{C_SerialNumber}\n";
  print Dumper($cb) if ($debug_mode);
  print "\n";
}





my $mb = get_inverter_model_block($c);

my $status = $I_STATUS{$mb->{I_Status}};
my $ac_power = scale_value($mb->{I_AC_Power},$mb->{I_AC_Power_SF});
my $dc_power = scale_value($mb->{I_DC_Power},$mb->{I_DC_Power_SF});
my $temp = scale_value($mb->{I_Temp_Sink},$mb->{I_Temp_Sink_SF});
my $eff = ($dc_power > 0 ? $ac_power/$dc_power*100 : 0);
my $dc_v = scale_value($mb->{I_DC_Voltage},$mb->{I_DC_Voltage_SF});
my $ac_v = scale_value($mb->{I_AC_VoltageAB},$mb->{I_AC_Voltage_SF});
my $ac_i = scale_value($mb->{I_AC_Current},$mb->{I_AC_Current_SF});
my $dc_i = scale_value($mb->{I_DC_Current},$mb->{I_DC_Current_SF});
my $ac_f = scale_value($mb->{I_AC_Frequency},$mb->{I_AC_Frequency_SF});
my $wh = scale_value($mb->{I_AC_Energy_WH},$mb->{I_AC_Energy_WH_SF});

if ($verbose_mode) {
  print  "            Status: $status\n\n";
  printf(" Power Output (AC): %12.0f W\n",$ac_power);
  printf("  Power Input (DC): %12.0f W\n",$dc_power);
  printf("        Efficiency: %12.2f %\n",$eff);
  printf("  Total Production: %12.3f kWh\n",$wh/1000);
  printf("      Voltage (AC): %12.2f V (%.2f Hz)\n",$ac_v,$ac_f);
  printf("      Current (AC): %12.2f A\n",$ac_i);
  printf("      Voltage (DC): %12.2f V\n",$dc_v);
  printf("      Current (DC): %12.2f A\n",$dc_i);
  printf("       Temperature: %12.2f C (heatsink)\n",$temp);
  print Dumper($mb) if ($debug_mode);
  print "\n";
}

# Domoticz update to sensor routine
#  idx is the domoticz idx sensor value, value, verbose mode
#  
#
if ($domoticz){
  if ($verbose_mode) {	
	print ("********************************************\n");
	print("domo update mode entered  \n",);
  }
  
  ## SolarEdge SolarEdge Status, Text device
  senddomo ($idxSEstat,$status,$verbose_mode);
  
  ## SolarEdge AC Inverter, Voltage device
  senddomo ($idxACinv ,$ac_v,$verbose_mode);
  
    
  ## SolarEdge AC Inverter, Amp device
  #senddomo ($idxac_i ,$ac_i,$verbose_mode);
  
  ## SolarEdge AC Inverter, Hertz device
  $dac_f = sprintf("%.2f Hz", $ac_f);
  senddomo ($idxAC_f ,$dac_f,$verbose_mode);
     
  ## SolarEdge DC Inverter, Voltage device
  senddomo ($idxDCinv ,$dc_v,$verbose_mode);
  
  ## SolarEdge DC Inverter, Amp device
  #senddomo ($idxdc_i ,$dc_i,$verbose_mode);
 
  ## SolarEdge Actual Power / Total Production, General, Kwh device
  senddomo ($idxActPwr ,$ac_power,$verbose_mode);
  
  
  ## SolarEdge Effinciency, Percentage device
  $deff = sprintf("%.2f", $eff);
  senddomo ($idxEffin,$deff,$verbose_mode);
  
  ## SolarEdge Temparetuur, Temperature device
  $dtemp = sprintf("%.2f", $temp);
  senddomo ($idxTemp  ,$dtemp,$verbose_mode);
  
  ## SolarEdge Total Production, General, Kwh device
  $dwh = sprintf("%.3f", ($wh / 1000));
  senddomo ($idxTotPwr,$dwh,$verbose_mode); 
  
  ####################################
  ## test for combined sensor (not working!) SolarEdge Actual Power / Total Production, General, Kwh device
  $ac_power = $ac_power . ";" . $dwh;
  #print "\ncombinetest :";
  #print $ac_power;
  #print "\n";
  #senddomo ($idxActPwr2 ,$ac_power,$verbose_mode);
  
  
}



my ($m_i, $m_e);

if ($meter > 0) {
  if ($verbose_mode) {
    my $mcb = get_meter_common_block($c,$meter);
    print "METER (#".$meter."):\n";
    print "             Model: $mcb->{C_Manufacturer} $mcb->{C_Model}\n";
    print "            Option: $mcb->{C_Option}\n";
    print "  Firmware version: $mcb->{C_Version}\n";
    print "     Serial Number: $mcb->{C_SerialNumber}\n";
    print Dumper($mcb) if ($debug_mode);
    print "\n";
  }

  my $mmb = get_meter_model_block($c,1);
  $m_e = scale_value($mmb->{M_Exported},$mmb->{M_Energy_W_SF});
  $m_i = scale_value($mmb->{M_Imported},$mmb->{M_Energy_W_SF});
  my $m_c = scale_value($mmb->{M_AC_Current},$mmb->{M_AC_Current_SF});
  my $m_f = scale_value($mmb->{M_AC_Freq},$mmb->{M_AC_Freq_SF});
  my $m_v = scale_value($mmb->{M_AC_Voltage_AB},$mmb->{M_AC_Voltage_SF});
  my $m_p = scale_value($mmb->{M_AC_Power},$mmb->{M_AC_Power_SF});
  my $m_pa = scale_value($mmb->{M_AC_VA},$mmb->{M_AC_VA_SF});
  my $m_pf = scale_value($mmb->{M_AC_PF}/100,$mmb->{M_AC_PF_SF});

  if ($verbose_mode) {
    printf("   Exported Energy: %12.3f kWh\n",$m_e/1000);
    printf("   Imported Energy: %12.3f kWh\n",$m_i/1000);
    printf("        Real Power: %12.0f W\n",$m_p);
    printf("    Apparent Power: %12.0f VA\n",$m_pa);
    printf("      Power Factor: %12.2f\n",$m_pf);
    printf("      Voltage (AC): %12.2f V (%.2f Hz)\n",$m_v,$m_f);
    printf("      Current (AC): %12.2f A\n",$m_c);
    print Dumper($mmb) if ($debug_mode);
    print "\n";
  }
}



unless ($verbose_mode) {
    print("timestamp,status,ac_power,dc_power,total_production,ac_voltage,ac_current,dc_voltage,dc_current,temperature,exported_energy,imporoted_energy\n") if ($debug_mode);

    if ($numeric_mode) {
	$status=$mb->{I_Status};
    } else {
	my($sec,$min,$hour,$day,$month,$year) = (localtime($tstamp))[0,1,2,3,4,5];
	$tstamp=sprintf("%04d-%02d-%02d %02d:%02d:%02d",$year+1900,$month+1,$day,$hour,$min,$sec);
    }
    
    if ($json_mode) {
	unless ($numeric_mode) {
	    $status="\"$status\"";
	    $tstamp="\"$tstamp\"";
	}
	printf("{\n" .
	       "\t\"timestamp\": %s,\n" .
	       "\t\"status\": %s,\n" .
	       "\t\"ac_power\": %d,\n" .
	       "\t\"dc_power\": %d,\n" .
	       "\t\"total_production\": %d,\n" .
	       "\t\"ac_voltage\": %.2f,\n" .
	       "\t\"ac_current\": %.2f,\n" .
	       "\t\"dc_voltage\": %.2f,\n" .
	       "\t\"dc_current\": %.2f,\n" .
	       "\t\"temperature\": %.2f,\n" .
	       "\t\"exported_energy\": %d,\n" .
	       "\t\"imported_energy\": %d\n" .
	       "}\n",
	       $tstamp,$status,$ac_power,$dc_power,$wh,
	       $ac_v,$ac_i,$dc_v,$dc_i,
	       $temp,$m_e,$m_i);
    } else {
	unless($domoticz){
	  printf("%s,%s,%d,%d,%d,%.2f,%.2f,%.2f,%.2f,%.2f,%d,%d\n",
	       $tstamp,$status,$ac_power,$dc_power,$wh,
	       $ac_v,$ac_i,$dc_v,$dc_i,
	       $temp,$m_e,$m_i);
	  }	   
    }
}

$c->disconnect;

# eof :-)

Re: SolarEdge via LAN interface

Posted: Sunday 04 March 2018 17:35
by Micha123
it is not realy working for me,


the combined sensor (actual production and total production) i have running in my script like that


http://192.168.102.57:8081/json.htm?typ ... _power;$wh

Re: SolarEdge via LAN interface

Posted: Sunday 04 March 2018 19:39
by freijn
What is the error message you get when you run it from the command line?

Re: SolarEdge via LAN interface

Posted: Monday 05 March 2018 0:33
by Micha123
There is not an error,

But my sensor in domoticz dont show aktual usage and as total usage 0.22.5 or something like that

Re: SolarEdge via LAN interface

Posted: Monday 05 March 2018 20:56
by ericje
I've implemented the script and it works

Code: Select all

pi@raspberrypi:~/domoticz-scripts $ /home/pi/domoticz-scripts/solaredge-sunspec -v -m 0 x.y.z.a
INVERTER:
             Model: SolarEdge  SE3500
  Firmware version: 3.2173
     Serial Number: xXXXXXXX

            Status: SLEEPING

 Power Output (AC):            0 W
  Power Input (DC):            0 W
        Efficiency:         0.00 %
  Total Production:      289.108 kWh
      Voltage (AC):       225.90 V (50.05 Hz)
      Current (AC):         0.00 A
      Voltage (DC):         0.00 V
      Current (DC):         0.00 A
       Temperature:        26.33 C (heatsink)
Now waiting for the sun :D

Re: SolarEdge via LAN interface

Posted: Tuesday 06 March 2018 21:48
by ErnstPD
I have 2 questions:
1. Is it also possible to get the values for each panel?
On the SolarEdge website I can see these values per panel, but they don't report it back to me when I use the SolarEdge web API in Domoticz.

2. Is there a step by step guide to use LAN interface agian?

Re: SolarEdge via LAN interface

Posted: Tuesday 06 March 2018 23:03
by freijn
Hi Ernst

I can't find it in the script. So I guess not.
Might be the next step an scrape it from the website....

There is an install manual for the Inverter. There you have the menu's explained.
What is your inverter model and type? Perhaps I can help you.

Cheers,

Frank

Re: SolarEdge via LAN interface

Posted: Tuesday 06 March 2018 23:18
by ErnstPD
Hi Frank,

I have the manual for my SolarEdge SE3500H, that is not the issue.
My question was more (or less) about how to get it running in Domoticz, I have no experience with scripting.
I don't want to use the SE website but keep all the data inside my own home :mrgreen:

When I get it working maybe I can do something back and make a installation manual.

Re: SolarEdge via LAN interface

Posted: Wednesday 07 March 2018 8:09
by freijn
Hi Ernst,

See my post @ Sunday 04 March 2018 15:15

That is the script you need.

I will write some quick notes on how to install, as you probably need to load additional libraries. ( just some extra commands )
Then you can run it from the command line.

Do you mind if : I make the quick notes. You exe them and write down if it works like that, so making the notes into real life working plan?

Deal ? :-)

Re: SolarEdge via LAN interface

Posted: Wednesday 07 March 2018 9:55
by McMelloW
@ErnstPD

The step by step LAN config for your SolarEdge is in this document

Re: SolarEdge via LAN interface

Posted: Wednesday 07 March 2018 20:10
by ErnstPD
freijn wrote: Wednesday 07 March 2018 8:09 Hi Ernst,

See my post @ Sunday 04 March 2018 15:15

That is the script you need.

I will write some quick notes on how to install, as you probably need to load additional libraries. ( just some extra commands )
Then you can run it from the command line.

Do you mind if : I make the quick notes. You exe them and write down if it works like that, so making the notes into real life working plan?

Deal ? :-)
Hi Frank,

Deal!!
That's exactly what I want.

Re: SolarEdge via LAN interface

Posted: Friday 20 April 2018 11:31
by ArnieO
This looks very interesting! On my installation the SolarEdge inverter is not on my LAN directly, but connected wirelessly (Zigbee) via a Gateway that is on my LAN: https://www.solaredge.com/us/products/c ... ateway-kit#/

Will I be able to use this script and talk with the inverter via the Gateway, or to I need to cable-connect the inverter to my LAN?

Re: SolarEdge via LAN interface

Posted: Friday 20 April 2018 17:27
by freijn
The script is expecting the inverter on the other site. A gateway would not work I am afraid for :-(

Re: SolarEdge via LAN interface

Posted: Saturday 21 April 2018 16:08
by McMelloW
ArnieO wrote: Friday 20 April 2018 11:31 This looks very interesting! On my installation the SolarEdge inverter is not on my LAN directly, but connected wirelessly (Zigbee) via a Gateway that is on my LAN: https://www.solaredge.com/us/products/c ... ateway-kit#/

Will I be able to use this script and talk with the inverter via the Gateway, or to I need to cable-connect the inverter to my LAN?
According to the Solaredge doc, you need a LAN cable connection. I don't know or a LAN cable-connection wil work together a zigbee gateway. You have to contact SolarEdge support for that.

Re: SolarEdge via LAN interface

Posted: Wednesday 24 April 2019 7:54
by mcmikev
freijn wrote: Thursday 22 February 2018 21:54 small update :

I managed to enable my modbus on lan connection and the windows software is now able to connect to port 502

However.. making the perl script run will require some more googeling :-(

Anybody any ideas?

pi@raspberrypi:~/solarreader/Device-Modbus-TCP $ perl Makefile.PL
Checking if your kit is complete...
Looks good
Warning: prerequisite Device::Modbus 0.021 not found.
Warning: prerequisite Net::Server 2.008 not found.
Warning: prerequisite Role::Tiny 2 not found.
Generating a Unix-style Makefile
Writing Makefile for Device::Modbus::TCP
Writing MYMETA.yml and MYMETA.json
pi@raspberrypi:~/solarreader/Device-Modbus-TCP $ sudo perl Makefile.PL
Warning: prerequisite Device::Modbus 0.021 not found.
Warning: prerequisite Net::Server 2.008 not found.
Warning: prerequisite Role::Tiny 2 not found.
Generating a Unix-style Makefile
Writing Makefile for Device::Modbus::TCP
Writing MYMETA.yml and MYMETA.json
pi@raspberrypi:~/solarreader/Device-Modbus-TCP $
Can you please tell me how you fixed these errors? I too have these but cannot figure out what to do. Many thanks

Re: SolarEdge via LAN interface

Posted: Wednesday 24 April 2019 16:06
by mcmikev
found it. Never mind. On the link that was posted with all these dependecies you can see a install button on the left. Missed that before.
clicking that shows the install options.

Re: SolarEdge via LAN interface

Posted: Wednesday 14 August 2019 15:22
by Ameliusvtwil
Im totally new to Domoticz/raspbian.

i want to see my solar information in my domoticz. I've tried the API setting, but i get no devices. But also i prefer the Lan way. I've downloaded the sunspec but i dont know how to install such program on my raspberry. So it should be nice if someone can help me with installing the modbus and all the other software that's needed for sunspec and can tell me how i get the information in domoticz.

Thx for being patient and for helping me.

I'm a dutch speaking man, so you may also sent me a direct message in dutch when thats easier.