# 30_ENECSYSINV.pm # ENECSYS Inverter Device # # (c) 2014 Arno Willig # # $Id$ package main; use strict; use warnings; use POSIX; use SetExtensions; sub ENECSYSINV_Initialize($) { my ($hash) = @_; # Provider # Consumer $hash->{Match} = ".*"; $hash->{DefFn} = "ENECSYSINV_Define"; $hash->{UndefFn} = "ENECSYSINV_Undefine"; $hash->{ParseFn} = "ENECSYSINV_Parse"; $hash->{AttrList} = "IODev ".$readingFnAttributes; $hash->{AutoCreate} = { "ENECSYSINV.*" => { GPLOT => "power4:Power,", FILTER => "%NAME:dcpower:.*" #ATTR => "event-min-interval:dcpower:120" } }; } sub ENECSYSINV_Define($$) { my ($hash, $def) = @_; my @args = split("[ \t]+", $def); my $iodev; my $i = 0; foreach my $param ( @args ) { if ($param =~ m/IODev=(.*)/) { $iodev = $1; splice( @args, $i, 1 ); last; } $i++; } return "Usage: define ENECSYSINV " if(@args < 3); my ($name, $type, $code, $interval) = @args; $hash->{STATE} = 'Initialized'; $hash->{CODE} = $code; AssignIoPort($hash,$iodev) if (!$hash->{IODev}); if(defined($hash->{IODev}->{NAME})) { Log3 $name, 3, "$name: I/O device is " . $hash->{IODev}->{NAME}; } else { Log3 $name, 1, "$name: no I/O device"; } $modules{ENECSYSINV}{defptr}{$code} = $hash; return undef; } sub ENECSYSINV_Undefine($$) { my ($hash,$arg) = @_; my $code = $hash->{ID}; $code = $hash->{IODev}->{NAME} ."-". $code if( defined($hash->{IODev}->{NAME}) ); delete($modules{ENECSYSINV}{defptr}{$code}); return undef; } sub ENECSYSINV_Parse($$) { my ($iodev, $msg, $local) = @_; my $ioName = $iodev->{NAME}; my $serial = hex(unpack("H*", pack("V*", unpack("N*", pack("H*", substr($msg,0,8)))))); my $hash = $modules{ENECSYSINV}{defptr}{$serial}; if(!$hash) { my $ret = "UNDEFINED ENECSYSINV_$serial ENECSYSINV $serial"; Log3 $ioName, 3, "$ret, please define it"; DoTrigger("global", $ret); return ""; } foreach my $mod (keys %{$modules{ENECSYSINV}{defptr}}) { my $hash = $modules{ENECSYSINV}{defptr}{"$mod"}; if ($hash && $hash->{CODE} == $serial) { my $time1 = hex(substr($msg,18,4)); my $time2 = hex(substr($msg,30,6)); my $dcCurrent = 0.025*hex(substr($msg,46,4)); #25 mA units? my $dcPower = hex(substr($msg,50,4)); my $efficiency = 0.001*hex(substr($msg,54,4)); my $acFreq = hex(substr($msg,58,2)); my $acVolt = hex(substr($msg,60,4)); my $temperature = hex(substr($msg,64,2)); my $lifekWh = (0.001*hex(substr($msg,66,4)))+hex(substr($msg,70,4)); my $acPower = $dcPower * $efficiency; my $dcVolt = sprintf("%0.2f",$dcPower / $dcCurrent); readingsBeginUpdate($hash); readingsBulkUpdate($hash,"dccurrent",$dcCurrent); readingsBulkUpdate($hash,"dcpower",$dcPower); readingsBulkUpdate($hash,"dcvolt",$dcVolt); readingsBulkUpdate($hash,"acfrequency",$acFreq); readingsBulkUpdate($hash,"acvolt",$acVolt); readingsBulkUpdate($hash,"acpower",$acPower); readingsBulkUpdate($hash,"lifetime",$lifekWh); readingsBulkUpdate($hash,"efficiency",$efficiency); readingsBulkUpdate($hash,"temperature",$temperature); readingsBulkUpdate($hash,"state",$dcPower); readingsEndUpdate($hash, 1); return $hash->{NAME}; } } } 1; =pod =begin html

ENECSYSINV


    Define
      define <name> ENECSYSINV <id> [<interval>]

      Defines an micro-inverter device connected to an ENECSYSGW.

      Examples:
        define SolarPanel1 ENECSYSINV 100123456

    Readings
    • acfrequency
      the alternating current frequency reported from the device. Should be around 50 Hz in Europe.
    • acpower
      the alternating current power
    • acvolt
      the alternating current voltage
    • dccurrent
      the direct current
    • dcpower
      the direct current power
    • dcvolt
      the direct current voltage
    • efficiency
      the efficiency of the inverter
    • lifetime
      the sum of collected energy of the inverter
    • temperature
      the temperature of the inverter
    • state
      the current state (equal to dcpower)


=end html =cut