diff --git a/fhem/contrib/DS_Starter/70_PylonLowVoltage.pm b/fhem/contrib/DS_Starter/70_PylonLowVoltage.pm
index 712950831..ac93e6191 100644
--- a/fhem/contrib/DS_Starter/70_PylonLowVoltage.pm
+++ b/fhem/contrib/DS_Starter/70_PylonLowVoltage.pm
@@ -4,20 +4,12 @@
#
# 70_PylonLowVoltage.pm
#
-# A FHEM module to read BMS values from a
-# Pylontech US2000plus/US3000 LiFePo04 battery
+# A FHEM module to read BMS values from Pylontech Low Voltage LiFePo04 batteries.
#
-# This module is based on 70_Pylontech.pm written 2019 by Harald Schmitz
-# Code modifications and extensions: (c) 2023 by Heiko Maaz e-mail: Heiko dot Maaz at t-online dot de
+# This module is based on 70_Pylontech.pm written 2019 by Harald Schmitz.
+# Code further development and extensions (c) 2023 by Heiko Maaz e-mail: Heiko dot Maaz at t-online dot de
#
-# Forumlinks:
-# https://forum.fhem.de/index.php?topic=117466.0 (Source of original module)
-# https://forum.fhem.de/index.php?topic=126361.0
-# https://forum.fhem.de/index.php?topic=112947.0
-# https://forum.fhem.de/index.php?topic=32037.0
-#
-# Photovoltaik Forum:
-# https://www.photovoltaikforum.com/thread/130061-pylontech-us2000b-daten-protokolle-programme
+# Credits to FHEM user: satprofi, Audi_Coupe_S, abc2006
#
#########################################################################################################################
# Copyright notice
@@ -41,6 +33,16 @@
# This copyright notice MUST APPEAR in all copies of the script!
#
#########################################################################################################################
+# Forumlinks:
+# https://forum.fhem.de/index.php?topic=117466.0 (Source of module 70_Pylontech.pm)
+# https://forum.fhem.de/index.php?topic=126361.0
+# https://forum.fhem.de/index.php?topic=112947.0
+# https://forum.fhem.de/index.php?topic=32037.0
+#
+# Photovoltaik Forum:
+# https://www.photovoltaikforum.com/thread/130061-pylontech-us2000b-daten-protokolle-programme
+#
+#########################################################################################################################
#
# Leerzeichen entfernen: sed -i 's/[[:space:]]*$//' 70_PylonLowVoltage.pm
#
@@ -54,6 +56,7 @@ use Time::HiRes qw(gettimeofday ualarm);
use IO::Socket::INET;
use Errno qw(ETIMEDOUT EWOULDBLOCK);
use Scalar::Util qw(looks_like_number);
+use Carp qw(croak carp);
eval "use FHEM::Meta;1" or my $modMetaAbsent = 1; ## no critic 'eval'
eval "use IO::Socket::Timeout;1" or my $iostAbsent = 1; ## no critic 'eval'
@@ -113,9 +116,10 @@ BEGIN {
# Versions History intern (Versions history by Heiko Maaz)
my %vNotesIntern = (
+ "0.1.2" => "20.08.2023 commandref revised, analogValue -> use 'user defined items' ",
"0.1.1" => "16.08.2023 integrate US3000C, add print request command in HEX to Logfile, attr timeout ".
- "change validation of received data, change DEF format, extend evaluation of chargeManagmentInfo ".
- "add evaluate systemParameters, additional own values packImbalance, packState ",
+ "change validation of received data, change DEF format, extend evaluation of chargeManagmentInfo ".
+ "add evaluate systemParameters, additional own values packImbalance, packState ",
"0.1.0" => "12.08.2023 initial version, switch to perl package, attributes: disable, interval, add command hashes ".
"get ... data command, add meta support and version management, more code changes ",
);
@@ -174,7 +178,6 @@ my $definterval = 30; # default A
my $defto = 0.5; # default connection Timeout zum RS485 Gateway
my @blackl = qw(state nextCycletime); # Ausnahmeliste deleteReadingspec
-
# Steuerhashes
###############
my %hrtnc = ( # RTN Codes
@@ -470,7 +473,8 @@ sub Update {
my %readings = ();
my $protocol = 'tcp';
my $rtnerr = q{};
- my $socket;
+
+ my ($socket, $success);
if(!$interval) {
$hash->{OPMODE} = 'Manual';
@@ -486,8 +490,8 @@ sub Update {
Log3 ($name, 4, "$name - start request cycle to battery number >$hash->{BATADDRESS}< at host:port $hash->{HOST}:$hash->{PORT}");
- eval {
- local $SIG{ALRM} = sub { die 'gatewaytimeout' };
+ eval { ## no critic 'eval'
+ local $SIG{ALRM} = sub { croak 'gatewaytimeout' };
ualarm ($timeout * 1000000); # ualarm in Mikrosekunden
$socket = IO::Socket::INET->new( Proto => $protocol,
@@ -516,14 +520,18 @@ sub Update {
}
IO::Socket::Timeout->enable_timeouts_on ($socket); # nur notwendig für read or write timeout
- $socket->read_timeout ($timeout - 0.2); # Lesetimeout immer kleiner als Sockettimeout
+ my $rwto = $timeout - 0.05;
+ $rwto = $rwto <= 0 ? 0.005 : $rwto;
+
+ $socket->read_timeout ($rwto); # Read/Writetimeout immer kleiner als Sockettimeout
+ $socket->write_timeout ($rwto);
$socket->autoflush(1);
my $res;
# relativ statische Werte abrufen
###################################
- if (ReadingsAge ($name, "serialNumber", 601) >= 0) {
+ if (ReadingsAge ($name, "serialNumber", 601) >= 60) {
# Abruf serialNumber
#####################
$res = Request($hash, $socket, $hrsnb{$hash->{BATADDRESS}}{cmd}, 'serialNumber');
@@ -598,33 +606,6 @@ sub Update {
$readings{moduleSoftwareVersion_manufacture} = 'V'.hex (substr ($res, 15, 2)).'.'.hex (substr ($res, 17, 2));
$readings{moduleSoftwareVersion_mainline} = 'V'.hex (substr ($res, 19, 2)).'.'.hex (substr ($res, 21, 2)).'.'.hex (substr ($res, 23, 2));
- # Abruf alarmInfo
- ##################
- $res = Request($hash, $socket, $hralm{$hash->{BATADDRESS}}{cmd}, 'alarmInfo');
-
- $rtnerr = respStat ($res);
- if ($rtnerr) {
- doOnError ({ hash => $hash,
- readings => \%readings,
- sock => $socket,
- state => $rtnerr
- }
- );
- return;
- }
-
- $readings{packCellcount} = hex (substr($res, 17, 2));
-
- if (substr($res, 19, 30)=="000000000000000000000000000000" &&
- substr($res, 51, 10)=="0000000000" &&
- substr($res, 67, 2) =="00" &&
- substr($res, 73, 4) =="0000") {
- $readings{packAlarmInfo} = "ok";
- }
- else {
- $readings{packAlarmInfo} = "failure";
- }
-
# Abruf Systemparameter
########################
$res = Request($hash, $socket, $hrspm{$hash->{BATADDRESS}}{cmd}, 'systemParameters');
@@ -654,6 +635,33 @@ sub Update {
$readings{paramDischargeCurrentLimit} = sprintf "%.3f", (65535 - (hex substr ($res, 59, 4))) * 100 / 1000; # mit Symbol (-)
}
+ # Abruf alarmInfo
+ ##################
+ $res = Request($hash, $socket, $hralm{$hash->{BATADDRESS}}{cmd}, 'alarmInfo');
+
+ $rtnerr = respStat ($res);
+ if ($rtnerr) {
+ doOnError ({ hash => $hash,
+ readings => \%readings,
+ sock => $socket,
+ state => $rtnerr
+ }
+ );
+ return;
+ }
+
+ $readings{packCellcount} = hex (substr($res, 17, 2));
+
+ if (substr($res, 19, 30) eq "000000000000000000000000000000" &&
+ substr($res, 51, 10) eq "0000000000" &&
+ substr($res, 67, 2) eq "00" &&
+ substr($res, 73, 4) eq "0000") {
+ $readings{packAlarmInfo} = "ok";
+ }
+ else {
+ $readings{packAlarmInfo} = "failure";
+ }
+
# Abruf chargeManagmentInfo
############################
$res = Request($hash, $socket, $hrcmi{$hash->{BATADDRESS}}{cmd}, 'chargeManagmentInfo');
@@ -677,8 +685,8 @@ sub Update {
my $cdstat = sprintf "%08b", hex substr ($res, 31, 2); # Rohstatus
$readings{chargeEnable} = substr ($cdstat, 0, 1) == 1 ? 'yes' : 'no'; # Bit 7
$readings{dischargeEnable} = substr ($cdstat, 1, 1) == 1 ? 'yes' : 'no'; # Bit 6
- $readings{chargeImmediatelySOC5} = substr ($cdstat, 2, 1) == 1 ? 'yes' : 'no'; # Bit 5 - SOC 5~9% -> für Wechselrichter, die aktives Batteriemanagement bei gegebener DC-Spannungsfunktion haben oder Wechselrichter, der von sich aus einen niedrigen SOC/Spannungsgrenzwert hat
- $readings{chargeImmediatelySOC10} = substr ($cdstat, 3, 1) == 1 ? 'yes' : 'no'; # Bit 4 - SOC 9~13% -> für Wechselrichter hat keine aktive Batterieabschaltung haben
+ $readings{chargeImmediatelySOC05} = substr ($cdstat, 2, 1) == 1 ? 'yes' : 'no'; # Bit 5 - SOC 5~9% -> für Wechselrichter, die aktives Batteriemanagement bei gegebener DC-Spannungsfunktion haben oder Wechselrichter, der von sich aus einen niedrigen SOC/Spannungsgrenzwert hat
+ $readings{chargeImmediatelySOC09} = substr ($cdstat, 3, 1) == 1 ? 'yes' : 'no'; # Bit 4 - SOC 9~13% -> für Wechselrichter hat keine aktive Batterieabschaltung haben
$readings{chargeFullRequest} = substr ($cdstat, 4, 1) == 1 ? 'yes' : 'no'; # Bit 3 - wenn SOC in 30 Tagen nie höher als 97% -> Flag = 1, wenn SOC-Wert ≥ 97% -> Flag = 0
# Abruf analogValue
@@ -700,25 +708,7 @@ sub Update {
return;
}
- $readings{packCellcount} = hex (substr($res, 17, 2));
- $readings{packVolt} = hex (substr($res, 105, 4)) / 1000;
- my $current = hex (substr($res, 101, 4));
-
- if ($current & 0x8000) {
- $current = $current - 0x10000;
- }
-
- $readings{packCurrent} = sprintf "%.2f", $current / 10;
-
- if (length($res) == 128) {
- $readings{packCapacity} = hex (substr($res, 115, 4)) / 1000;
- $readings{packCapacityRemain} = hex (substr($res, 109, 4)) / 1000;
- }
- else {
- $readings{packCapacity} = hex (substr($res, 129, 6)) / 1000;
- $readings{packCapacityRemain} = hex (substr($res, 123, 6)) / 1000;
- }
-
+ $readings{packCellcount} = hex (substr($res, 17, 2));
$readings{cellVoltage_01} = sprintf "%.3f", hex(substr($res,19,4)) / 1000;
$readings{cellVoltage_02} = sprintf "%.3f", hex(substr($res,23,4)) / 1000;
$readings{cellVoltage_03} = sprintf "%.3f", hex(substr($res,27,4)) / 1000;
@@ -733,13 +723,43 @@ sub Update {
$readings{cellVoltage_12} = sprintf "%.3f", hex(substr($res,63,4)) / 1000;
$readings{cellVoltage_13} = sprintf "%.3f", hex(substr($res,67,4)) / 1000;
$readings{cellVoltage_14} = sprintf "%.3f", hex(substr($res,71,4)) / 1000;
- $readings{cellVoltage_15} = sprintf "%.3f", hex(substr($res,75,4)) / 1000;
- $readings{packCycles} = hex (substr($res, 119, 4));
- $readings{bmsTemperature} = (hex (substr($res, 81, 4)) - 2731) / 10;
- $readings{cellTemperature_0104} = (hex (substr($res, 85, 4)) - 2731) / 10;
- $readings{cellTemperature_0508} = (hex (substr($res, 89, 4)) - 2731) / 10;
- $readings{cellTemperature_0912} = (hex (substr($res, 93, 4)) - 2731) / 10;
- $readings{cellTemperature_1315} = (hex (substr($res, 97, 4)) - 2731) / 10;
+ $readings{cellVoltage_15} = sprintf "%.3f", hex(substr($res,75,4)) / 1000;
+ # $readings{numberOfTempPos} = hex(substr($res,79,2)); # Anzahl der jetzt folgenden Teperaturpositionen -> 5
+ $readings{bmsTemperature} = (hex (substr($res, 81, 4)) - 2731) / 10; # 1
+ $readings{cellTemperature_0104} = (hex (substr($res, 85, 4)) - 2731) / 10; # 2
+ $readings{cellTemperature_0508} = (hex (substr($res, 89, 4)) - 2731) / 10; # 3
+ $readings{cellTemperature_0912} = (hex (substr($res, 93, 4)) - 2731) / 10; # 4
+ $readings{cellTemperature_1315} = (hex (substr($res, 97, 4)) - 2731) / 10; # 5
+ my $current = hex (substr($res, 101, 4));
+ $readings{packVolt} = hex (substr($res, 105, 4)) / 1000;
+
+ if ($current & 0x8000) {
+ $current = $current - 0x10000;
+ }
+
+ $readings{packCurrent} = sprintf "%.3f", $current / 10;
+ my $udi = hex substr($res, 113, 2); # user defined item: 2: Batterien <= 65Ah, 4: Batterien > 65Ah
+ $readings{packCycles} = hex substr($res, 119, 4);
+$udi = 0;
+ if ($udi == 2) {
+ $readings{packCapacityRemain} = hex (substr($res, 109, 4)) / 1000;
+ $readings{packCapacity} = hex (substr($res, 115, 4)) / 1000;
+ }
+ elsif ($udi == 4) {
+ $readings{packCapacityRemain} = hex (substr($res, 123, 6)) / 1000;
+ $readings{packCapacity} = hex (substr($res, 129, 6)) / 1000;
+ }
+ else {
+ doOnError ({ hash => $hash,
+ readings => \%readings,
+ sock => $socket,
+ state => 'wrong value retrieve analogValue -> user defined items: '.$udi
+ }
+ );
+ return;
+ }
+
+ $success = 1;
}; # eval
if ($@) {
@@ -763,13 +783,14 @@ sub Update {
ualarm(0);
close ($socket) if($socket);
- Log3 ($name, 4, "$name - got fresh values from battery number >$hash->{BATADDRESS}<");
+ if ($success) {
+ Log3 ($name, 4, "$name - got fresh values from battery number >$hash->{BATADDRESS}<");
+
+ additionalReadings (\%readings); # zusätzliche eigene Readings erstellen
+ $readings{state} = 'connected';
+ }
- additionalReadings (\%readings); # zusätzliche eigene Readings erstellen
-
- $readings{state} = 'connected' if(!defined $readings{state});
-
- createReadings ($hash, \%readings); # Readings erstellen
+ createReadings ($hash, \%readings); # Readings erstellen
return;
}
@@ -809,7 +830,7 @@ sub Reread {
$socket->read ($singlechar, 1);
if (!$singlechar && (0+$! == ETIMEDOUT || 0+$! == EWOULDBLOCK)) { # nur notwendig für read timeout
- die 'Timeout reading data from battery';
+ croak 'Timeout reading data from battery';
}
$res = $res . $singlechar if (!(length($res) == 0 && ord($singlechar) == 13)) # ord 13 -> ASCII dezimal für CR (Hex 0d)
@@ -817,7 +838,7 @@ sub Reread {
} while (length($res) == 0 || ord($singlechar) != 13);
Log3 ($name, 5, "$name - data returned raw: ".$res);
- Log3 ($name, 5, "$name - data returned:\n" .Hexdump($res));
+ Log3 ($name, 5, "$name - data returned:\n" .Hexdump ($res));
return $res;
}
@@ -836,13 +857,15 @@ return;
# PylonLowVoltage Hexdump
###############################################################
sub Hexdump {
+ my $res = shift;
+
my $offset = 0;
my $result = "";
- for my $chunk (unpack "(a16)*", $_[0]) {
+ for my $chunk (unpack "(a16)*", $res) {
my $hex = unpack "H*", $chunk; # hexadecimal magic
$chunk =~ tr/ -~/./c; # replace unprintables
- $hex =~ s/(.{1,8})/$1 /gs; # insert spaces
+ $hex =~ s/(.{1,8})/$1 /gxs; # insert spaces
$result .= sprintf "0x%08x (%05u) %-*s %s\n", $offset, $offset, 36, $hex, $chunk;
$offset += 16;
}
@@ -901,8 +924,8 @@ sub additionalReadings {
my ($vmax, $vmin);
- $readings->{averageCellVolt} = sprintf "%.3f", $readings->{packVolt} / $readings->{packCellcount};
- $readings->{packSOC} = sprintf "%.2f", ($readings->{packCapacityRemain} / $readings->{packCapacity} * 100);
+ $readings->{averageCellVolt} = sprintf "%.3f", $readings->{packVolt} / $readings->{packCellcount} if(defined $readings->{packCellcount});
+ $readings->{packSOC} = sprintf "%.2f", ($readings->{packCapacityRemain} / $readings->{packCapacity} * 100) if(defined $readings->{packCapacity});
$readings->{packPower} = sprintf "%.2f", $readings->{packCurrent} * $readings->{packVolt};
for (my $i=1; $i <= $readings->{packCellcount}; $i++) {
@@ -966,7 +989,7 @@ return;
=pod
=item device
-=item summary Integration of pylontech LiFePo4 low voltage batteries (incl. BMS) over RS485 via ethernet gateway (ethernet interface)
+=item summary Integration of Pylontech LiFePo4 low voltage batteries (incl. BMS) over RS485 via ethernet gateway (ethernet interface)
=item summary_DE Integration von Pylontech Niedervolt Batterien (mit BMS) über RS485 via Ethernet-Gateway (Ethernet Interface)
=begin html
@@ -974,43 +997,61 @@ return;
PylonLowVoltage
-Module for the integration of batteries with battery management system (BMS) from manufacturer Pylontech via RS485 via RS485 / Ethernet gateway.
-The test was carried out with a US2000plus Pylontech battery, which was connected via a USRiot "USR-TCP" low-cost Ethernet gateway.
-In principle, any other RS485 / Ethernet gateway should also be possible here.
-The module thus only communicates via an Ethernet connection.
+Module for integration of low voltage batteries with battery management system (BMS) of the manufacturer Pylontech via
+RS485/Ethernet gateway. Communication to the RS485 gateway takes place exclusively via an Ethernet connection.
+The module has been successfully used so far with Pylontech batteries of the following types:
+
+
+ - US2000
+ - US2000plus
+ - US3000
+ - US3000C
+
+
+The following devices have been successfully used as RS485 Ethernet gateways to date:
+
+ - USR-TCP232-304 from the manufacturer USRiot
+ - Waveshare RS485 to Ethernet Converter
+
+
+In principle, any other RS485/Ethernet gateway should also be compatible.
Requirements
This module requires the Perl modules:
- - IO::Socket::INET (apt-get install libio-socket-multicast-perl)
- - IO::Socket::Timeout (Installation e.g. via the CPAN shell)
+ - IO::Socket::INET (apt-get install libio-socket-multicast-perl)
+ - IO::Socket::Timeout (Installation e.g. via the CPAN shell or the FHEM Installer module)
-
-
Definition
- define <name> PylonLowVoltage <bataddress> <hostname/ip> <port> [<timeout>]
+ define <name> PylonLowVoltage <hostname/ip>:<port> [<bataddress>]
- - bataddress:
- Device address of the Pylontech battery. Up to 6 pylon tech batteries can be connected via a Pylontech specific link link.
- The first battery in the network (to which the RS485 cable is connected) has the address 1, the next battery has the address 2 and so on.
- The individual batteries can thus be addressed individually.
- hostname/ip:
- Host name oder IP address of the RS485/Ethernet gateways
+ Host name or IP address of the RS485/Ethernet gateway
+
+
- port:
- Port number of the port configured in the RS485 / Ethernet Gateway
- - timeout:
- Timeout in seconds for a query (optional, default 10)
+ Port number of the port configured in the RS485/Ethernet gateway
+
+
+ - bataddress:
+ Device address of the Pylontech battery. Up to 6 Pylontech batteries can be connected via a Pylontech-specific
+ link connection.
+ The first battery in the network (to which the RS485 connection is connected) has the address 1, the next battery
+ then has address 2 and so on.
+ If no device address is specified, address 1 is used.
+
+
-Working method
+Mode of operation
-The module cyclically reads values that the battery management system provides via the RS485 interface.
-All data is read out at the interval specified in the definition.
+Depending on the setting of the "Interval" attribute, the module cyclically reads values provided by the battery
+management system via the RS485 interface.
@@ -1018,7 +1059,7 @@ All data is read out at the interval specified in the definition.
- data
- The data query of the battery management system is executed. The timer of the cyclic query is reinitialized according
+ The data query of the battery management system is executed. The timer of the cyclic query is reinitialized according
to the set value of the "interval" attribute.
@@ -1031,46 +1072,80 @@ All data is read out at the interval specified in the definition.
- disable 0|1
- Activates/deactivates the device.
+ Enables/disables the device definition.
- interval <seconds>
- Interval of data retrieval from the battery in seconds. If "interval" is explicitly set to the value "0", there is no
- automatic data query.
+ Interval of the data request from the battery in seconds. If "interval" is explicitly set to the value "0", there is
+ no automatic data request.
(default: 30)
+
+
+ - timeout <seconds>
+ Timeout for establishing the connection to the RS485 gateway.
+ (default: 0.5)
+
+
Readings
-- serialNumber
Serial number (is read only once a minute)
-- batteryVoltage
Battery voltage of the entire battery [in V]
-- averageCellVoltage
Mean cell voltage [in V]
-- batteryCurrent
Battery current [in A]
-- SOC
State of charge [in%]
-- cycles
Number of Cycles - The number of cycles is a measure of battery wear.
-A complete load and unload is considered a cycle. If the battery is discharged and recharged 50%, it will only count as half a cycle.
-The manufacturer specifies a lifetime of several 1000 cycles (see data sheet).
-- cellVoltage_1
Cell voltage of the 1st cell pack [in V] - In the battery 15 cell packs
-are connected in series. Each cell pack consists of parallel cells.
-- cellVoltage_2
Cell voltage of the 2nd cell pack [in V]
-.
-.
-.
-
-- cellVoltage_15
Cell voltage of the 15th cell pack [in V]
-- bmsTemperature
Temperature of the battery management system (BMS) [in ° C]
-- cellTemperature_0104
Temperature of cell packs 1 to 4 [in ° C]
-- cellTemperature_0508
Temperature of cell packs 5 to 8 [in ° C]
-- cellTemperature_0912
Temperature of cell packs 9 to 12 [in ° C]
-- cellTemperature_1315
Temperature of cell packs 13 to 15 [in ° C]
-- alarmInfo
Alarm status [ok - battery module is OK, failure - there is a fault in the battery module]
(is read only once a minute)
-- alarmInfoRaw
Alarm raw data for more detailed analysis
(is read only once a minute)
-- state
Status [ok, failure, offline]
+- averageCellVolt
Average cell voltage (V)
+- bmsTemperature
Temperature (°C) of the battery management system
+- cellTemperature_0104
Temperature (°C) of cell packs 1 to 4
+- cellTemperature_0508
Temperature (°C) of cell packs 5 to 8
+- cellTemperature_0912
Temperature (°C) of the cell packs 9 to 12
+- cellTemperature_1315
Temperature (°C) of the cell packs 13 to 15
+- cellVoltage_XX
Cell voltage (V) of the cell pack XX. In the battery module "packCellcount"
+ cell packs are connected in series. Each cell pack consists of single cells
+ connected in parallel.
+- chargeCurrentLimit
current limit value for the charging current (A)
+- chargeEnable
current flag loading allowed
+- chargeFullRequest
current flag charge battery module fully (from the mains if necessary)
+- chargeImmediatelySOCXX
current flag charge battery module immediately
+ (05: SOC limit 5-9%, 09: SOC limit 9-13%)
+- chargeVoltageLimit
current charge voltage limit (V) of the battery module
+- dischargeCurrentLimit
current limit value for the discharge current (A)
+- dischargeEnable
current flag unloading allowed
+- dischargeVoltageLimit
current discharge voltage limit (V) of the battery module
+- packAlarmInfo
Alarm status (ok - battery module is OK, failure - there is a fault in the
+ battery module)
+- packCapacity
nominal capacity (Ah) of the battery module
+- packCapacityRemain
current capacity (Ah) of the battery module
+- packCellcount
Number of cell packs in the battery module
+- packCurrent
current charge current (+) or discharge current (-) of the battery module (A)
+- packCycles
Number of full cycles - The number of cycles is, to some extent, a measure of the
+ wear and tear of the battery. A complete charge and discharge is counted as one
+ cycle. If the battery is discharged and recharged 50%, it only counts as one
+ half cycle. Pylontech specifies a lifetime of several 1000 cycles
+ (see data sheet).
+- packImbalance
current imbalance of voltage between the single cells of the
+ battery module (%)
+- packPower
current drawn (+) or delivered (-) power (W) of the battery module
+- packSOC
State of charge (%) of the battery module
+- packState
current working status of the battery module
+- packVolt
current voltage (V) of the battery module
+
+- paramCellHighVoltLimit
System parameter upper voltage limit (V) of a cell
+- paramCellLowVoltLimit
System parameter lower voltage limit (V) of a cell (alarm limit)
+- paramCellUnderVoltLimit
System parameter undervoltage limit (V) of a cell (protection limit)
+- paramChargeCurrentLimit
System parameter charging current limit (A) of the battery module
+- paramChargeHighTempLimit
System parameter upper temperature limit (°C) up to which the battery charges
+- paramChargeLowTempLimit
System parameter lower temperature limit (°C) up to which the battery charges
+- paramDischargeCurrentLimit
System parameter discharge current limit (A) of the battery module
+- paramDischargeHighTempLimit
System parameter upper temperature limit (°C) up to which the battery discharges
+- paramDischargeLowTempLimit
System parameter lower temperature limit (°C) up to which the battery discharges
+- paramModuleHighVoltLimit
System parameter upper voltage limit (V) of the battery module
+- paramModuleLowVoltLimit
System parameter lower voltage limit (V) of the battery module (alarm limit)
+- paramModuleUnderVoltLimit
System parameter undervoltage limit (V) of the battery module (protection limit)
+- protocolVersion
PYLON low voltage RS485 protocol version
+- serialNumber
Serial number
+- softwareVersion
Firmware version of the battery module
@@ -1080,7 +1155,7 @@ are connected in series. Each cell pack consists of parallel cells.
PylonLowVoltage
-Modul zur Einbindung von Batterien mit Batteriemanagmentsystem (BMS) des Herstellers Pylontech über RS485 via
+Modul zur Einbindung von Niedervolt-Batterien mit Batteriemanagmentsystem (BMS) des Herstellers Pylontech über RS485 via
RS485/Ethernet-Gateway. Die Kommunikation zum RS485-Gateway erfolgt ausschließlich über eine Ethernet-Verbindung.
Das Modul wurde bisher erfolgreich mit Pylontech Batterien folgender Typen eingesetzt:
@@ -1090,26 +1165,23 @@ Das Modul wurde bisher erfolgreich mit Pylontech Batterien folgender Typen einge
- US3000
- US3000C
-
-Als RS485-Ethernet-Gateways wurden bisher folgende Geräte eingesetzt:
+Als RS485-Ethernet-Gateways wurden bisher folgende Geräte erfolgreich eingesetzt:
- USR-TCP232-304 des Herstellers USRiot
- Waveshare RS485 to Ethernet Converter
-
-Prinzipiell sollte hier auch jedes andere RS485/Ethernet-Gateway möglich sein.
+Prinzipiell sollte auch jedes andere RS485/Ethernet-Gateway kompatibel sein.
Voraussetzungen
Dieses Modul benötigt die Perl-Module:
- - IO::Socket::INET (apt-get install libio-socket-multicast-perl)
- - IO::Socket::Timeout (Installation z.B. über die CPAN-Shell)
+ - IO::Socket::INET (apt-get install libio-socket-multicast-perl)
+ - IO::Socket::Timeout (Installation z.B. über die CPAN-Shell oder das FHEM Installer Modul)
-
Definition
@@ -1136,8 +1208,8 @@ Dieses Modul benötigt die Perl-Module:
Arbeitsweise
-Das Modul liest zyklisch Werte aus, die das Batteriemanagementsystem über die RS485-Schnittstelle zur Verfügung stellt.
-Alle Daten werden mit dem bei der Definition angegebene Intervall ausgelesen.
+Das Modul liest entsprechend der Einstellung des Attributes "interval" zyklisch Werte aus, die das
+Batteriemanagementsystem über die RS485-Schnittstelle zur Verfügung stellt.
@@ -1158,7 +1230,7 @@ Alle Daten werden mit dem bei der Definition angegebene Intervall ausgelesen.
- disable 0|1
- Aktiviert/deaktiviert das Gerät.
+ Aktiviert/deaktiviert die Gerätedefinition.
@@ -1181,29 +1253,57 @@ Alle Daten werden mit dem bei der Definition angegebene Intervall ausgelesen.
Readings
-- serialNumber
Seriennummer
-- batteryVoltage
Batterie Spannung (V) der gesamten Batterie
-- averageCellVoltage
mittlere Zellenspannung (V)
-- batteryCurrent
Batteriestrom (A)
-- SOC
Ladezustand (%)
-- cycles
Anzahl der Zyklen - Die Anzahl der Zyklen ist in gewisserweise ein Maß für den Verschleiß der Batterie.
- Eine komplettes Laden und Entladen wird als ein Zyklus gewertet.
- Wird die Batterie 50% Entladen und wieder aufgeladen, zählt das nur als ein halber Zyklus.
- Der Hersteller gibt eine Lebensdauer von mehreren 1000 Zyklen an (siehe Datenblatt).
-- cellVoltage_1
Zellenspannung (V) des 1. Zellenpacks - In der Batterie sind 15 Zellenpacks in Serie geschaltet.
- Jedes Zellenpack besteht aus parallel geschalten Einzelzellen.
-- cellVoltage_2
Zellenspannung (V) des 2. Zellenpacks
- .
- .
- .
-
-- cellVoltage_15
Zellenspannung (V) des 15. Zellenpacks
-- bmsTemperature
Temperatur (°C) des Batteriemanagementsystems
-- cellTemperature_0104
Temperatur (°C) der Zellenpacks 1 bis 4
-- cellTemperature_0508
Temperatur (°C) der Zellenpacks 5 bis 8
-- cellTemperature_0912
Temperatur (°C) der Zellenpacks 9 bis 12
-- cellTemperature_1315
Temperatur (°C) der Zellenpacks 13 bis 15
-- alarmInfo
Alarmstatus (ok - Batterienmodul ist in Ordnung, failure - im Batteriemodul liegt eine Störung vor)
+- averageCellVolt
mittlere Zellenspannung (V)
+- bmsTemperature
Temperatur (°C) des Batteriemanagementsystems
+- cellTemperature_0104
Temperatur (°C) der Zellenpacks 1 bis 4
+- cellTemperature_0508
Temperatur (°C) der Zellenpacks 5 bis 8
+- cellTemperature_0912
Temperatur (°C) der Zellenpacks 9 bis 12
+- cellTemperature_1315
Temperatur (°C) der Zellenpacks 13 bis 15
+- cellVoltage_XX
Zellenspannung (V) des Zellenpacks XX. In dem Batteriemodul sind "packCellcount"
+ Zellenpacks in Serie geschaltet verbaut. Jedes Zellenpack besteht aus parallel
+ geschalten Einzelzellen.
+- chargeCurrentLimit
aktueller Grenzwert für den Ladestrom (A)
+- chargeEnable
aktuelles Flag Laden erlaubt
+- chargeFullRequest
aktuelles Flag Batteriemodul voll laden (notfalls aus dem Netz)
+- chargeImmediatelySOCXX
aktuelles Flag Batteriemodul sofort laden
+ (05: SOC Grenze 5-9%, 09: SOC Grenze 9-13%)
+- chargeVoltageLimit
aktuelle Ladespannungsgrenze (V) des Batteriemoduls
+- dischargeCurrentLimit
aktueller Grenzwert für den Entladestrom (A)
+- dischargeEnable
aktuelles Flag Entladen erlaubt
+- dischargeVoltageLimit
aktuelle Entladespannungsgrenze (V) des Batteriemoduls
+- packAlarmInfo
Alarmstatus (ok - Batterienmodul ist in Ordnung, failure - im Batteriemodul liegt
+ eine Störung vor)
+- packCapacity
nominale Kapazität (Ah) des Batteriemoduls
+- packCapacityRemain
aktuelle Kapazität (Ah) des Batteriemoduls
+- packCellcount
Anzahl der Zellenpacks im Batteriemodul
+- packCurrent
aktueller Ladestrom (+) bzw. Entladstrom (-) des Batteriemoduls (A)
+- packCycles
Anzahl der Vollzyklen - Die Anzahl der Zyklen ist in gewisserweise ein Maß für den
+ Verschleiß der Batterie. Eine komplettes Laden und Entladen wird als ein Zyklus
+ gewertet. Wird die Batterie 50% entladen und wieder aufgeladen, zählt das nur als ein
+ halber Zyklus. Pylontech gibt eine Lebensdauer von mehreren 1000 Zyklen an
+ (siehe Datenblatt).
+- packImbalance
aktuelles Ungleichgewicht der Spannung zwischen den Einzelzellen des
+ Batteriemoduls (%)
+- packPower
aktuell bezogene (+) bzw. gelieferte (-) Leistung (W) des Batteriemoduls
+- packSOC
Ladezustand (%) des Batteriemoduls
+- packState
aktueller Arbeitsstatus des Batteriemoduls
+- packVolt
aktuelle Spannung (V) des Batteriemoduls
+
+- paramCellHighVoltLimit
Systemparameter obere Spannungsgrenze (V) einer Zelle
+- paramCellLowVoltLimit
Systemparameter untere Spannungsgrenze (V) einer Zelle (Alarmgrenze)
+- paramCellUnderVoltLimit
Systemparameter Unterspannungsgrenze (V) einer Zelle (Schutzgrenze)
+- paramChargeCurrentLimit
Systemparameter Ladestromgrenze (A) des Batteriemoduls
+- paramChargeHighTempLimit
Systemparameter obere Temperaturgrenze (°C) bis zu der die Batterie lädt
+- paramChargeLowTempLimit
Systemparameter untere Temperaturgrenze (°C) bis zu der die Batterie lädt
+- paramDischargeCurrentLimit
Systemparameter Entladestromgrenze (A) des Batteriemoduls
+- paramDischargeHighTempLimit
Systemparameter obere Temperaturgrenze (°C) bis zu der die Batterie entlädt
+- paramDischargeLowTempLimit
Systemparameter untere Temperaturgrenze (°C) bis zu der die Batterie entlädt
+- paramModuleHighVoltLimit
Systemparameter obere Spannungsgrenze (V) des Batteriemoduls
+- paramModuleLowVoltLimit
Systemparameter untere Spannungsgrenze (V) des Batteriemoduls (Alarmgrenze)
+- paramModuleUnderVoltLimit
Systemparameter Unterspannungsgrenze (V) des Batteriemoduls (Schutzgrenze)
+- protocolVersion
PYLON low voltage RS485 Prokollversion
+- serialNumber
Seriennummer
+- softwareVersion
Firmware Version des Batteriemoduls