mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-10 09:16:53 +00:00
Added modules ENECSYSGW and ENECSYSINV
git-svn-id: https://svn.fhem.de/fhem/trunk@5115 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
efabf6338e
commit
ed15c50a02
208
fhem/FHEM/30_ENECSYSGW.pm
Normal file
208
fhem/FHEM/30_ENECSYSGW.pm
Normal file
@ -0,0 +1,208 @@
|
||||
# 30_ENECSYSGW.pm
|
||||
# ENECSYS Gateway Device
|
||||
#
|
||||
# (c) 2014 Arno Willig <akw@bytefeed.de>
|
||||
#
|
||||
# $Id$
|
||||
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use POSIX;
|
||||
use MIME::Base64;
|
||||
use XML::Simple;
|
||||
|
||||
sub ENECSYSGW_Initialize($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
# Provider
|
||||
$hash->{ReadFn} = "ENECSYSGW_Read";
|
||||
$hash->{WriteFn} = "ENECSYSGW_Read";
|
||||
$hash->{Clients} = ":ENECSYSDevice:";
|
||||
|
||||
# Consumer
|
||||
$hash->{DefFn} = "ENECSYSGW_Define";
|
||||
$hash->{NOTIFYDEV} = "global";
|
||||
$hash->{NotifyFn} = "ENECSYSGW_Notify";
|
||||
$hash->{UndefFn} = "ENECSYSGW_Undefine";
|
||||
$hash->{AttrList} = "disable:1";
|
||||
}
|
||||
|
||||
sub ENECSYSGW_Read($@)
|
||||
{
|
||||
my ($hash,$name,$id,$obj)= @_;
|
||||
return ENECSYSGW_Call($hash);
|
||||
}
|
||||
|
||||
sub ENECSYSGW_Define($$)
|
||||
{
|
||||
my ($hash, $def) = @_;
|
||||
my @args = split("[ \t]+", $def);
|
||||
return "Usage: define <name> ENECSYSGW <host> [interval]" if(@args < 3);
|
||||
|
||||
my ($name, $type, $host, $interval) = @args;
|
||||
|
||||
$interval = 10 unless defined($interval);
|
||||
if ($interval < 5) { $interval = 5; }
|
||||
|
||||
$hash->{STATE} = 'Initialized';
|
||||
$hash->{Host} = $host;
|
||||
$hash->{INTERVAL} = $interval;
|
||||
|
||||
$hash->{Clients} = ":ENECSYSINV:";
|
||||
my %matchList = ( "1:ENECSYSINV" => ".*" );
|
||||
$hash->{MatchList} = \%matchList;
|
||||
|
||||
if( $init_done ) {
|
||||
ENECSYSGW_OpenDev( $hash ) if( !AttrVal($name, "disable", 0) );
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub ENECSYSGW_Notify($$)
|
||||
{
|
||||
my ($hash,$dev) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $type = $hash->{TYPE};
|
||||
|
||||
return if($dev->{NAME} ne "global");
|
||||
return if(!grep(m/^INITIALIZED|REREADCFG$/, @{$dev->{CHANGED}}));
|
||||
return undef if( AttrVal($name, "disable", 0) );
|
||||
|
||||
ENECSYSGW_OpenDev($hash);
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub ENECSYSGW_Undefine($$)
|
||||
{
|
||||
my ($hash,$arg) = @_;
|
||||
RemoveInternalTimer($hash);
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub ENECSYSGW_OpenDev($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
$hash->{STATE} = 'Connected';
|
||||
ENECSYSGW_GetUpdate($hash);
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub ENECSYSGW_GetUpdate($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
if(!$hash->{LOCAL}) {
|
||||
RemoveInternalTimer($hash);
|
||||
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "ENECSYSGW_GetUpdate", $hash, 0);
|
||||
}
|
||||
ENECSYSGW_Call($hash);
|
||||
}
|
||||
|
||||
sub ENECSYSGW_Call($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
return undef if($attr{$name} && $attr{$name}{disable});
|
||||
my $URL = "http://" . $hash->{Host} . "/ajax.xml";
|
||||
my $ret = GetFileFromURL($URL, 5, undef, 1 );
|
||||
|
||||
if( !defined($ret) ) {
|
||||
return undef;
|
||||
} elsif($ret eq '') {
|
||||
return undef;
|
||||
} elsif($ret =~ /^error:(\d){3}$/) {
|
||||
return "HTTP Error Code " . $1;
|
||||
}
|
||||
my $parser = new XML::Simple;
|
||||
my $data = $parser->XMLin($ret,SuppressEmpty => 1);
|
||||
my $rmsg = $data->{zigbeeData};
|
||||
my $ConnectionStatus = $data->{connectionStatus};
|
||||
my $ConnectionUptime = $data->{connectionUptime};
|
||||
my $devicesInNetwork = $data->{devicesInNetwork};
|
||||
my $timeSinceReset = $data->{timeSinceReset};
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate($hash,"ConnectionStatus",$ConnectionStatus);
|
||||
readingsBulkUpdate($hash,"ConnectionUptime",$ConnectionUptime);
|
||||
readingsBulkUpdate($hash,"devicesInNetwork",$devicesInNetwork);
|
||||
readingsBulkUpdate($hash,"timeSinceReset",$timeSinceReset);
|
||||
readingsEndUpdate($hash, 1);
|
||||
|
||||
# Testing $rmsg = "WS=F4_3BQCaxjQAABMIIQEAAAIrFDADiAAAEAANAywyAOUOApsBJAAAB8";
|
||||
|
||||
return undef unless defined $rmsg;
|
||||
|
||||
$rmsg =~ s/\r//g;
|
||||
$rmsg =~ s/\n//g;
|
||||
$rmsg =~ s/_/\//g;
|
||||
$rmsg =~ s/-/+/g;
|
||||
|
||||
readingsSingleUpdate($hash,"rawReading",$rmsg,1);
|
||||
|
||||
if ($rmsg =~ /^WS/ && length($rmsg)==57) {
|
||||
$rmsg = unpack('H*', decode_base64(substr($rmsg,3,54))).'A';
|
||||
|
||||
Log3 $name, 4, "$name: Zigbee raw: $rmsg";
|
||||
|
||||
my $serial = hex(unpack("H*", pack("V*", unpack("N*", pack("H*", substr($rmsg,0,8))))));
|
||||
|
||||
my $dmsg = $rmsg;
|
||||
Log3 $name, 4, "$name: $dmsg";
|
||||
$hash->{"${name}_MSGCNT"}++;
|
||||
$hash->{"${name}_TIME"} = TimeNow();
|
||||
$hash->{RAWMSG} = $rmsg;
|
||||
my %addvals = (RAWMSG => $rmsg);
|
||||
Dispatch($hash, $dmsg, \%addvals);
|
||||
}
|
||||
|
||||
if ($rmsg =~ /^WS/ && length($rmsg)!=57) { # other inverter strings (startup?)
|
||||
Log3 $name, 4, "$name: Zigbee unknown data";
|
||||
}
|
||||
|
||||
if ($rmsg =~ /^WZ/) { # gateway data
|
||||
Log3 $name, 4, "$name: Zigbee gateway data";
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
=begin html
|
||||
|
||||
<a name="ENECSYSGW"></a>
|
||||
<h3>ENECSYSGW</h3>
|
||||
<ul>
|
||||
Module to access the ENECSYS gateway (http://www.ENECSYS.com/products/gateway/).<br><br>
|
||||
|
||||
The actual micro-inverter devices are defined as <a href="#ENECSYSINV">ENECSYSINV</a> devices.
|
||||
|
||||
<br><br>
|
||||
All newly found inverter devices are autocreated and added to the room ENECSYSINV.
|
||||
|
||||
|
||||
<br><br>
|
||||
<a name="ENECSYSGW_Define"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
<code>define <name> ENECSYSGW [<host>] [<interval>]</code><br>
|
||||
<br>
|
||||
|
||||
Defines an ENECSYSGW device with address <host>.<br><br>
|
||||
|
||||
The gateway will be polled every <interval> seconds. The default is 10 and minimum is 5.<br><br>
|
||||
|
||||
Examples:
|
||||
<ul>
|
||||
<code>define gateway ENECSYSGW 10.0.1.1</code><br>
|
||||
</ul>
|
||||
</ul><br>
|
||||
</ul><br>
|
||||
|
||||
=end html
|
||||
=cut
|
179
fhem/FHEM/31_ENECSYSINV.pm
Normal file
179
fhem/FHEM/31_ENECSYSINV.pm
Normal file
@ -0,0 +1,179 @@
|
||||
# 30_ENECSYSINV.pm
|
||||
# ENECSYS Inverter Device
|
||||
#
|
||||
# (c) 2014 Arno Willig <akw@bytefeed.de>
|
||||
#
|
||||
# $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 <name> ENECSYSINV <serial>" 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
|
||||
|
||||
<a name="ENECSYSINV"></a>
|
||||
<h3>ENECSYSINV</h3>
|
||||
<ul>
|
||||
<br>
|
||||
<a name="ENECSYSINV_Define"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
<code>define <name> ENECSYSINV <id> [<interval>]</code><br>
|
||||
<br>
|
||||
|
||||
Defines an micro-inverter device connected to an <a href="#ENECSYSGW">ENECSYSGW</a>.<br><br>
|
||||
|
||||
Examples:
|
||||
<ul>
|
||||
<code>define SolarPanel1 ENECSYSINV 100123456</code><br>
|
||||
</ul>
|
||||
</ul><br>
|
||||
|
||||
<a name="ENECSYSINV_Readings"></a>
|
||||
<b>Readings</b>
|
||||
<ul>
|
||||
<li>acfrequency<br />
|
||||
the alternating current frequency reported from the device. Should be around 50 Hz in Europe.</li>
|
||||
<li>acpower<br />
|
||||
the alternating current power</li>
|
||||
<li>acvolt<br />
|
||||
the alternating current voltage</li>
|
||||
<li>dccurrent<br />
|
||||
the direct current</li>
|
||||
<li>dcpower<br />
|
||||
the direct current power</li>
|
||||
<li>dcvolt<br />
|
||||
the direct current voltage</li>
|
||||
<li>efficiency<br />
|
||||
the efficiency of the inverter</li>
|
||||
<li>lifetime<br />
|
||||
the sum of collected energy of the inverter</li>
|
||||
<li>temperature<br />
|
||||
the temperature of the inverter</li>
|
||||
<li>state<br />
|
||||
the current state (equal to dcpower) </li>
|
||||
</ul><br />
|
||||
|
||||
|
||||
</ul><br>
|
||||
|
||||
=end html
|
||||
=cut
|
@ -87,7 +87,9 @@ FHEM/23_WEBIO_12DIGITAL.pm sachag http://forum.fhem.de Sonstiges
|
||||
FHEM/23_WEBTHERM.pm betateilchen/sachag http://forum.fhem.de Sonstiges
|
||||
FHEM/24_NetIO230B.pm rudolfkoenig/orphan http://forum.fhem.de Sonstiges
|
||||
FHEM/30_HUEBridge.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/30_ENECSYSGW.pm akw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/31_HUEDevice.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/31_ENECSYSINV.pm akw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/31_LightScene.pm justme1968 http://forum.fhem.de Automatisierung
|
||||
FHEM/32_SYSSTAT.pm justme1968 http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/32_mailcheck.pm justme1968 http://forum.fhem.de Automatisierung
|
||||
|
Loading…
x
Reference in New Issue
Block a user