2014-08-10 19:25:32 +00:00
#
2019-08-31 16:54:50 +00:00
# kaihs@FHEM_Forum (forum.fhem.de)
2014-08-10 19:25:32 +00:00
#
2014-09-06 17:21:57 +00:00
# $Id$
2014-08-10 19:25:32 +00:00
#
#
package main ;
use strict ;
use warnings ;
use SetExtensions ;
use WMBus ;
2014-08-21 19:49:11 +00:00
2014-08-10 19:25:32 +00:00
sub WMBUS_Parse ($$) ;
sub WMBUS_SetReadings ($$$) ;
2014-09-06 17:21:57 +00:00
sub WMBUS_SetRSSI ($$$) ;
2014-09-15 19:31:21 +00:00
sub WMBUS_RSSIAsRaw ($) ;
2014-08-10 19:25:32 +00:00
sub WMBUS_Initialize ($) {
my ( $ hash ) = @ _ ;
$ hash - > { Match } = "^b.*" ;
2019-08-31 16:54:50 +00:00
$ hash - > { SetFn } = "WMBUS_Set" ;
2014-08-10 19:25:32 +00:00
#$hash->{GetFn} = "WMBUS_Get";
$ hash - > { DefFn } = "WMBUS_Define" ;
$ hash - > { UndefFn } = "WMBUS_Undef" ;
#$hash->{FingerprintFn} = "WMBUS_Fingerprint";
$ hash - > { ParseFn } = "WMBUS_Parse" ;
$ hash - > { AttrFn } = "WMBUS_Attr" ;
$ hash - > { AttrList } = "IODev" .
" AESkey" .
2014-08-18 16:18:57 +00:00
" ignore:0,1" .
2015-01-18 18:38:30 +00:00
" rawmsg_as_reading:0,1" .
2018-12-18 19:20:02 +00:00
" ignoreUnknownDataBlocks:0,1" .
2019-03-10 12:48:20 +00:00
" ignoreMasterMessages:0,1" .
2019-08-31 16:54:50 +00:00
" useVIFasReadingName:0,1" .
" $readingFnAttributes"
;
2014-08-10 19:25:32 +00:00
}
2016-11-08 19:34:33 +00:00
sub
WMBUS_HandleEncoding ( $$ )
{
my ( $ mb , $ msg ) = @ _ ;
my $ encoding = "CUL" ;
my $ rssi ;
( $ msg , $ rssi ) = split ( /::/ , $ msg ) ;
if ( substr ( $ msg , 1 , 3 ) eq "AMB" ) {
# Amber Wireless AMB8425-M encoding, does not include CRC16
$ encoding = "AMB" ;
$ mb - > setCRCsize ( 0 ) ;
# message length (first byte) contains 1 byte for rssi,
# remove it
my $ msglen = sprintf ( "%1x" , hex ( substr ( $ msg , 4 , 1 ) ) - 1 ) ;
$ msg = "b" . $ msglen . substr ( $ msg , 5 ) ;
} else {
2018-06-24 19:58:13 +00:00
if ( substr ( $ msg , 1 , 1 ) eq "Y" ) {
$ mb - > setFrameType ( WMBus:: FRAME_TYPE_B ) ;
$ msg = "b" . substr ( $ msg , 2 ) ;
}
2016-11-08 19:34:33 +00:00
$ msg . = WMBUS_RSSIAsRaw ( $ rssi ) ;
}
return ( $ msg , $ rssi , $ encoding ) ;
}
2014-08-10 19:25:32 +00:00
sub
WMBUS_Define ( $$ )
{
my ( $ hash , $ def ) = @ _ ;
my @ a = split ( "[ \t][ \t]*" , $ def ) ;
2019-08-31 16:54:50 +00:00
my $ mb ;
my $ rssi ;
2014-08-10 19:25:32 +00:00
if ( @ a != 6 && @ a != 3 ) {
2019-08-31 16:54:50 +00:00
my $ msg = "wrong syntax: define <name> WMBUS <ManufacturerID> <SerialNo> <Version> <Type> [<MessageEncoding>]|b[<MessageEncoding>]<HexMessage>" ;
2014-08-10 19:25:32 +00:00
Log3 undef , 2 , $ msg ;
return $ msg ;
}
my $ name = $ a [ 0 ] ;
if ( @ a == 3 ) {
2019-08-31 16:54:50 +00:00
# unparsed message
my $ msg = $ a [ 2 ] ;
$ mb = new WMBus ;
( $ msg , $ rssi , $ hash - > { MessageEncoding } ) = WMBUS_HandleEncoding ( $ mb , $ msg ) ;
my $ minSize = ( $ mb - > getCRCsize ( ) + WMBus:: TL_BLOCK_SIZE ) * 2 ;
2016-11-08 19:34:33 +00:00
my $ reMinSize = qr/b[a-zA-Z0-9]{${minSize},}/ ;
2019-08-31 16:54:50 +00:00
2021-11-01 16:43:20 +00:00
return "a WMBus message must match the pattern b[<MessageEncoding>]<HexMessage> and <HexMessage> must be a least $minSize bytes long: $msg" if $ msg !~ m/${reMinSize}/ ;
2019-08-31 16:54:50 +00:00
if ( $ mb - > parseLinkLayer ( pack ( 'H*' , substr ( $ msg , 1 ) ) ) ) {
$ hash - > { Manufacturer } = $ mb - > { manufacturer } ;
$ hash - > { IdentNumber } = $ mb - > { afield_id } ;
$ hash - > { Version } = $ mb - > { afield_ver } ;
$ hash - > { DeviceType } = $ mb - > { afield_type } ;
if ( $ mb - > { errormsg } ) {
$ hash - > { Error } = $ mb - > { errormsg } ;
} else {
delete $ hash - > { Error } ;
}
WMBUS_SetRSSI ( $ hash , $ mb , $ rssi ) ;
} else {
2017-11-07 19:33:20 +00:00
my $ error = "failed to parse msg: $mb->{errormsg}" ;
2019-08-31 16:54:50 +00:00
if ( $ mb - > { errorcode } == WMBus:: ERR_MSG_TOO_SHORT && $ hash - > { MessageEncoding } eq 'CUL' ) {
2017-11-07 19:33:20 +00:00
$ error . = ". Please make sure that TTY_BUFSIZE in culfw is at least two times the message length + 1" ;
}
return $ error ;
2019-08-31 16:54:50 +00:00
}
2014-08-10 19:25:32 +00:00
2019-08-31 16:54:50 +00:00
} else {
my $ encoding = "CUL" ;
# manual specification
2014-08-14 19:04:34 +00:00
if ( $ a [ 2 ] !~ m/[A-Z]{3}/ ) {
2019-08-31 16:54:50 +00:00
return "$a[2] is not a valid WMBUS manufacturer id" ;
}
2014-08-10 19:25:32 +00:00
2014-08-14 19:04:34 +00:00
if ( $ a [ 3 ] !~ m/[0-9]{1,8}/ ) {
2019-08-31 16:54:50 +00:00
return "$a[3] is not a valid WMBUS serial number" ;
}
2014-08-10 19:25:32 +00:00
2014-08-14 19:04:34 +00:00
if ( $ a [ 4 ] !~ m/[0-9]{1,2}/ ) {
2019-08-31 16:54:50 +00:00
return "$a[4] is not a valid WMBUS version" ;
}
2014-08-10 19:25:32 +00:00
2014-08-14 19:04:34 +00:00
if ( $ a [ 5 ] !~ m/[0-9]{1,2}/ ) {
2019-08-31 16:54:50 +00:00
return "$a[5] is not a valid WMBUS type" ;
}
if ( defined ( $ a [ 6 ] ) ) {
2016-11-08 19:34:33 +00:00
$ encoding = $ a [ 6 ] ;
}
if ( $ encoding ne "CUL" && $ encoding ne "AMB" ) {
return "$a[6] isn't a supported encoding, use either CUL or AMB" ;
}
2019-08-31 16:54:50 +00:00
$ hash - > { Manufacturer } = $ a [ 2 ] ;
$ hash - > { IdentNumber } = sprintf ( "%08d" , $ a [ 3 ] ) ;
$ hash - > { Version } = $ a [ 4 ] ;
$ hash - > { DeviceType } = $ a [ 5 ] ;
$ hash - > { MessageEncoding } = $ encoding ;
2014-08-10 19:25:32 +00:00
}
my $ addr = join ( "_" , $ hash - > { Manufacturer } , $ hash - > { IdentNumber } , $ hash - > { Version } , $ hash - > { DeviceType } ) ;
return "WMBUS device $addr already used for $modules{WMBUS}{defptr}{$addr}->{NAME}." if ( $ modules { WMBUS } { defptr } { $ addr }
&& $ modules { WMBUS } { defptr } { $ addr } - > { NAME } ne $ name ) ;
2014-09-06 17:21:57 +00:00
$ hash - > { addr } = $ addr ;
2014-08-10 19:25:32 +00:00
$ modules { WMBUS } { defptr } { $ addr } = $ hash ;
AssignIoPort ( $ hash ) ;
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" ;
}
$ hash - > { DEF } = join ( " " , $ hash - > { Manufacturer } , $ hash - > { IdentNumber } , $ hash - > { Version } , $ hash - > { DeviceType } ) ;
2019-08-31 16:54:50 +00:00
$ hash - > { DeviceMedium } = WMBus:: - > type2string ( $ hash - > { DeviceType } ) ;
if ( defined ( $ mb ) ) {
if ( $ mb - > parseApplicationLayer ( ) ) {
WMBUS_SetReadings ( $ hash , $ name , $ mb ) ;
} else {
$ hash - > { Error } = $ mb - > { errormsg } ;
}
}
2014-08-10 19:25:32 +00:00
return undef ;
}
#####################################
sub
WMBUS_Undef ( $$ )
{
my ( $ hash , $ arg ) = @ _ ;
my $ name = $ hash - > { NAME } ;
my $ addr = $ hash - > { addr } ;
2014-08-22 15:55:19 +00:00
delete ( $ modules { WMBUS } { defptr } { $ addr } ) ;
2014-08-10 19:25:32 +00:00
return undef ;
}
#####################################
sub
WMBUS_Get ( $@ )
{
my ( $ hash , $ name , $ cmd , @ args ) = @ _ ;
return "\"get $name\" needs at least one parameter" if ( @ _ < 3 ) ;
my $ list = "" ;
return "Unknown argument $cmd, choose one of $list" ;
}
sub
WMBUS_Fingerprint ( $$ )
{
my ( $ name , $ msg ) = @ _ ;
return ( "" , $ msg ) ;
}
sub
WMBUS_Parse ( $$ )
{
2016-11-08 19:34:33 +00:00
my ( $ hash , $ rawMsg ) = @ _ ;
2014-08-10 19:25:32 +00:00
my $ name = $ hash - > { NAME } ;
my $ addr ;
my $ rhash ;
2014-09-06 17:21:57 +00:00
my $ rssi ;
2016-11-08 19:34:33 +00:00
my $ msg ;
2014-08-10 19:25:32 +00:00
# $hash is the hash of the IODev!
2016-11-08 19:34:33 +00:00
if ( $ rawMsg =~ m/^b/ ) {
2019-08-31 16:54:50 +00:00
# WMBus message received
Log3 $ name , 5 , "WMBUS raw msg " . $ rawMsg ;
$ hash - > { internal } { rawMsg } = $ rawMsg ;
my $ mb = new WMBus ;
( $ msg , $ rssi , $ hash - > { MessageEncoding } ) = WMBUS_HandleEncoding ( $ mb , $ rawMsg ) ;
if ( uc ( substr ( $ msg , 0 , 8 ) ) eq "1144FF03" ) {
2019-03-10 12:48:20 +00:00
Log3 $ name , 2 , "received possible KNX-RF message, ignoring it" ;
return undef ;
}
2019-08-31 16:54:50 +00:00
if ( $ mb - > parseLinkLayer ( pack ( 'H*' , substr ( $ msg , 1 ) ) ) ) {
$ addr = join ( "_" , $ mb - > { manufacturer } , $ mb - > { afield_id } , $ mb - > { afield_ver } , $ mb - > { afield_type } ) ;
$ rhash = $ modules { WMBUS } { defptr } { $ addr } ;
if ( ! $ rhash ) {
Log3 $ name , 3 , "WMBUS Unknown device $rawMsg, please define it" ;
return "UNDEFINED WMBUS_$addr WMBUS $rawMsg" ;
}
2014-12-07 21:08:53 +00:00
my $ rname = $ rhash - > { NAME } ;
return "" if ( IsIgnored ( $ rname ) ) ;
2019-08-31 16:54:50 +00:00
2018-07-05 18:37:28 +00:00
$ rhash - > { model } = join ( "_" , $ mb - > { manufacturer } , $ mb - > { afield_type } , $ mb - > { afield_ver } ) ;
2019-08-31 16:54:50 +00:00
WMBUS_SetRSSI ( $ rhash , $ mb , $ rssi ) ;
my $ aeskey ;
if ( $ aeskey = AttrVal ( $ rname , 'AESkey' , undef ) ) {
$ mb - > { aeskey } = pack ( "H*" , $ aeskey ) ;
} else {
$ mb - > { aeskey } = undef ;
}
if ( $ mb - > parseApplicationLayer ( ) ) {
return WMBUS_SetReadings ( $ rhash , $ rname , $ mb ) ;
} else {
Log3 $ rname , 2 , "WMBUS $rname Error during ApplicationLayer parse:" . $ mb - > { errormsg } ;
readingsSingleUpdate ( $ rhash , "state" , $ mb - > { errormsg } , 1 ) ;
return $ rname ;
}
} else {
# error
Log3 $ name , 2 , "WMBUS Error during LinkLayer parse:" . $ mb - > { errormsg } ;
if ( $ mb - > { errorcode } == WMBus:: ERR_MSG_TOO_SHORT && $ hash - > { MessageEncoding } eq 'CUL' ) {
2017-11-08 19:27:50 +00:00
Log3 $ name , 2 , "Please make sure that TTY_BUFSIZE in culfw is at least two times the message length + 1" ;
}
2019-08-31 16:54:50 +00:00
return undef ;
}
2014-08-10 19:25:32 +00:00
} else {
2016-11-08 19:34:33 +00:00
DoTrigger ( $ name , "UNKNOWNCODE $rawMsg" ) ;
Log3 $ name , 3 , "$name: Unknown code $rawMsg, help me!" ;
2014-08-10 19:25:32 +00:00
return undef ;
}
}
2014-09-15 19:31:21 +00:00
2016-11-08 19:34:33 +00:00
# if the culfw doesn't send the RSSI value (because it is an old version that doesn't implement this) but 00_CUL.pm already expects it
2014-09-15 19:31:21 +00:00
# one byte is missing from the data which leads to CRC errors
# To avoid this calculate the raw data byte from the RSSI and append it to the data.
# If it is a valid RSSI it will be ignored by the WMBus parser (the data contains the length of the data itself
# and only that much is parsed).
sub WMBUS_RSSIAsRaw ($) {
2019-08-31 16:54:50 +00:00
my $ rssi = shift ;
if ( defined $ rssi ) {
if ( $ rssi < - 74 ) {
$ b = ( $ rssi + 74 ) * 2 + 256 ;
} else {
$ b = ( $ rssi + 74 ) * 2 ;
}
return sprintf ( "%02X" , $ b ) ;
} else {
return "" ;
}
2014-09-15 19:31:21 +00:00
}
2014-09-06 17:21:57 +00:00
sub WMBUS_SetRSSI ($$$) {
2019-08-31 16:54:50 +00:00
my ( $ hash , $ mb , $ rssi ) = @ _ ;
if ( defined $ mb - > { remainingData } && length ( $ mb - > { remainingData } ) >= 2 ) {
# if there are trailing bytes after the WMBUS message it is the LQI and the RSSI
readingsBeginUpdate ( $ hash ) ;
my ( $ lqi , $ rssi ) = unpack ( "CC" , $ mb - > { remainingData } ) ;
2014-09-15 19:31:21 +00:00
$ rssi = ( $ rssi >= 128 ? ( ( $ rssi - 256 ) /2-74) : ($rssi/ 2 - 74 ) ) ;
2019-08-31 16:54:50 +00:00
readingsBulkUpdate ( $ hash , "RSSI" , $ rssi ) ;
readingsBulkUpdate ( $ hash , "LQI" , unpack ( "C" , $ mb - > { remainingData } ) ) ;
readingsEndUpdate ( $ hash , 1 ) ;
}
2014-09-06 17:21:57 +00:00
}
2014-09-10 19:07:59 +00:00
sub WMBUS_SetReadings ($$$)
2014-08-10 19:25:32 +00:00
{
2019-08-31 16:54:50 +00:00
my ( $ hash , $ name , $ mb ) = @ _ ;
my @ list ;
push ( @ list , $ name ) ;
if ( $ mb - > { cifield } == WMBus:: CI_RESP_12 ) {
$ hash - > { Meter_Id } = $ mb - > { meter_id } ;
$ hash - > { Meter_Manufacturer } = $ mb - > { meter_manufacturer } ;
$ hash - > { Meter_Version } = $ mb - > { meter_vers } ;
$ hash - > { Meter_Dev } = $ mb - > { meter_devtypestring } ;
$ hash - > { Access_No } = $ mb - > { access_no } ;
$ hash - > { Status } = $ mb - > { status } ;
}
readingsBeginUpdate ( $ hash ) ;
if ( $ mb - > { decrypted } &&
# decode messages sent from master to slave/meter only if it is explictly enabled
( $ mb - > { sent_from_master } == 0 || AttrVal ( $ name , "ignoreMasterMessages" , 1 ) )
2019-03-10 12:48:20 +00:00
)
{
2019-08-31 16:54:50 +00:00
my $ dataBlocks = $ mb - > { datablocks } ;
my $ dataBlock ;
my $ readingBase ;
my $ useVIFasReadingName = defined ( $ hash - > { internal } { useVIFasReadingName } ) ?
$ hash - > { internal } { useVIFasReadingName } : AttrVal ( $ name , "useVIFasReadingName" , 0 ) ;
for $ dataBlock ( @$ dataBlocks ) {
2018-12-18 19:20:02 +00:00
next if AttrVal ( $ name , "ignoreUnknownDataBlocks" , 0 ) && $ dataBlock - > { type } eq 'MANUFACTURER SPECIFIC' ; #WMBus::VIF_TYPE_MANUFACTURER_SPECIFIC
2019-08-31 16:54:50 +00:00
if ( $ useVIFasReadingName ) {
$ readingBase = "$dataBlock->{storageNo}_$dataBlock->{type}" ;
if ( defined ( $ dataBlock - > { extension_value } ) ) {
$ readingBase . = "_$dataBlock->{extension_value}" ;
}
} else {
$ readingBase = $ dataBlock - > { number } ;
readingsBulkUpdate ( $ hash , "${readingBase}_type" , $ dataBlock - > { type } ) ;
readingsBulkUpdate ( $ hash , "${readingBase}_storage_no" , $ dataBlock - > { storageNo } ) ;
if ( defined ( $ dataBlock - > { extension_value } ) ) {
readingsBulkUpdate ( $ hash , "${readingBase}_extension_value" , $ dataBlock - > { extension_value } ) ;
}
}
readingsBulkUpdate ( $ hash , "${readingBase}_value" , $ dataBlock - > { value } ) ;
readingsBulkUpdate ( $ hash , "${readingBase}_unit" , $ dataBlock - > { unit } ) ;
readingsBulkUpdate ( $ hash , "${readingBase}_value_type" , $ dataBlock - > { functionFieldText } ) ;
if ( defined ( $ dataBlock - > { extension_unit } ) ) {
readingsBulkUpdate ( $ hash , "${readingBase}_extension_unit" , $ dataBlock - > { extension_unit } ) ;
2015-01-18 18:38:30 +00:00
}
2019-08-31 16:54:50 +00:00
if ( $ dataBlock - > { errormsg } ) {
readingsBulkUpdate ( $ hash , "${readingBase}_errormsg" , $ dataBlock - > { errormsg } ) ;
}
}
2018-05-23 18:42:34 +00:00
readingsBulkUpdate ( $ hash , "batteryState" , $ mb - > { status } & 4 ? "low" : "ok" ) ;
2014-10-25 14:54:42 +00:00
WMBUS_SetDeviceSpecificReadings ( $ hash , $ name , $ mb ) ;
}
2019-08-31 16:54:50 +00:00
readingsBulkUpdate ( $ hash , "is_encrypted" , $ mb - > { isEncrypted } ) ;
readingsBulkUpdate ( $ hash , "decryption_ok" , $ mb - > { decrypted } ) ;
if ( $ mb - > { decrypted } ) {
readingsBulkUpdate ( $ hash , "state" , $ mb - > { statusstring } ) ;
} else {
readingsBulkUpdate ( $ hash , "state" , 'decryption failed' ) ;
}
if ( AttrVal ( $ name , "rawmsg_as_reading" , 0 ) ) {
2018-12-18 19:20:02 +00:00
readingsBulkUpdate ( $ hash , "rawmsg" , $ mb - > getFrameType ( ) eq WMBus:: FRAME_TYPE_B ? "Y" : "" . unpack ( "H*" , $ mb - > { msg } ) ) ;
2015-01-18 18:38:30 +00:00
}
2019-08-31 16:54:50 +00:00
readingsEndUpdate ( $ hash , 1 ) ;
2014-08-10 19:25:32 +00:00
2019-08-31 16:54:50 +00:00
return @ list ;
2014-08-10 19:25:32 +00:00
}
2014-10-25 14:54:42 +00:00
sub WMBUS_SetDeviceSpecificReadings ($$$)
{
my ( $ hash , $ name , $ mb ) = @ _ ;
if ( $ mb - > { manufacturer } eq 'FFD' ) {
# Fast Forward AG
if ( $ mb - > { afield_ver } == 1 ) {
#EnergyCam
if ( $ mb - > { afield_type } == 2 ) {
# electricity
readingsBulkUpdate ( $ hash , "energy" , ReadingsVal ( $ name , "1_value" , 0 ) / 1000 ) ;
readingsBulkUpdate ( $ hash , "unit" , "kWh" ) ;
} elsif ( $ mb - > { afield_type } == 3 || $ mb - > { afield_type } == 7 ) {
# gas/water
readingsBulkUpdate ( $ hash , "volume" , ReadingsVal ( $ name , "1_value" , 0 ) ) ;
readingsBulkUpdate ( $ hash , "unit" , "m³" ) ;
}
}
2015-02-17 20:40:38 +00:00
} elsif ( $ mb - > { afield_type } == 3 || $ mb - > { afield_type } == 7 ) {
# general gas/water meter
my $ dataBlock ;
my $ dataBlocks = $ mb - > { datablocks } ;
for $ dataBlock ( @$ dataBlocks ) {
# search for VIF_VOLUME
2016-11-08 19:34:33 +00:00
if ( $ dataBlock - > { type } eq 'VIF_VOLUME' && $ dataBlock - > { functionFieldText } eq "Instantaneous value" ) {
2015-02-17 20:40:38 +00:00
readingsBulkUpdate ( $ hash , "volume" , $ dataBlock - > { value } ) ;
readingsBulkUpdate ( $ hash , "unit" , $ dataBlock - > { unit } ) ;
}
}
2014-10-25 14:54:42 +00:00
}
}
2014-08-10 19:25:32 +00:00
#####################################
sub
WMBUS_Set ( $@ )
{
my ( $ hash , @ a ) = @ _ ;
my $ name = shift @ a ;
my $ cmd = shift @ a ;
my $ arg = join ( " " , @ a ) ;
2019-08-31 16:54:50 +00:00
my $ list = "rawmsg" ;
2014-08-10 19:25:32 +00:00
2019-08-31 16:54:50 +00:00
# only for Letrika solar inverters
$ list . = " requestCurrentPower requestTotalEnergy" if $ hash - > { Manufacturer } eq 'LET' and $ hash - > { DeviceType } == 2 ;
2014-08-10 19:25:32 +00:00
return $ list if ( $ cmd eq '?' || $ cmd eq '' ) ;
2019-08-31 16:54:50 +00:00
if ( $ cmd eq 'rawmsg' ) {
WMBUS_Parse ( $ hash , 'b' . $ arg ) ;
} elsif ( $ cmd eq "requestCurrentPower" ) {
IOWrite ( $ hash , "" , "bss" ) ;
} elsif ( $ cmd eq "requestTotalEnergy" ) {
}
2014-08-10 19:25:32 +00:00
else {
return "Unknown argument $cmd, choose one of " . $ list ;
}
return undef ;
}
sub
WMBUS_Attr ( @ )
{
my ( $ cmd , $ name , $ attrName , $ attrVal ) = @ _ ;
2019-08-31 16:54:50 +00:00
my $ hash = $ defs { $ name } ;
my $ msg = '' ;
if ( $ attrName eq 'AESkey' ) {
if ( $ attrVal =~ /^[0-9A-Fa-f]{32}$/ ) {
$ hash - > { wmbus } - > { aeskey } = $ attrVal ;
} else {
$ msg = "AESkey must be a 32 digit hexadecimal value" ;
}
} elsif ( $ attrName eq 'useVIFasReadingName' ) {
if ( $ attrVal ne AttrVal ( $ name , 'useVIFasReadingName' , '0' ) ) {
# delete all readings on change of namimg format
fhem "deletereading $name .*" ;
# and recreate them
if ( defined ( $ hash - > { internal } { rawMsg } ) ) {
$ hash - > { internal } { useVIFasReadingName } = $ attrVal ;
WMBUS_Parse ( $ hash , $ hash - > { internal } { rawMsg } ) ;
delete $ hash - > { internal } { useVIFasReadingName } ;
}
}
}
return ( $ msg ) ? $ msg : undef ;
2014-08-10 19:25:32 +00:00
}
1 ;
= pod
2016-09-06 18:36:36 +00:00
= item device
= item summary Reception of Wireless M - Bus messages from e . g . electicity meters
= item summary_DE Empfang von Wireless M - Bus Nachrichten z . B . von Stromzählern
2014-08-10 19:25:32 +00:00
= begin html
2021-11-01 16:43:20 +00:00
< a id = "WMBUS" > </a>
2014-08-10 19:25:32 +00:00
<h3> WMBUS - Wireless M - Bus </h3>
<ul>
This module supports Wireless M - Bus meters for e . g . water , heat , gas or electricity .
2014-08-12 20:36:46 +00:00
Wireless M - Bus is a standard protocol supported by various manufacturers .
2014-08-10 19:25:32 +00:00
It uses the 868 MHz band for radio transmissions .
2016-11-08 19:34:33 +00:00
Therefore you need a device which can receive Wireless M - Bus messages , e . g . a < a href = "#CUL" > CUL </a> with culfw >= 1.59 or an AMBER Wireless AMB8465M .
2014-08-10 19:25:32 +00:00
<br>
2018-06-24 19:58:13 +00:00
WMBus uses three different radio protocols , T - Mode , S - Mode and C - Mode . The receiver must be configured to use the same protocol as the sender .
In case of a CUL this can be done by setting < a href = "#rfmode" > rfmode </a> to WMBus_T , WMBus_S or WMBus_C respectively .
2014-08-10 19:25:32 +00:00
<br>
WMBus devices send data periodically depending on their configuration . It can take days between individual messages or they might be sent
every minute .
<br>
WMBus messages can be optionally encrypted . In that case the matching AESkey must be specified with attr AESkey . Otherwise the decryption
2019-08-18 14:50:47 +00:00
will fail and no relevant data will be available . The module can decrypt messages encrypted according to security profile A or B ( mode 5 and 7 ) .
2014-08-10 19:25:32 +00:00
<br> <br>
2014-08-12 20:36:46 +00:00
<b> Prerequisites </b> <br>
2019-08-18 14:50:47 +00:00
This module requires the perl modules Digest:: CRC , Crypt::Mode:: CBC , Crypt::Mode:: CTR and Digest:: CMAC ( last three only if encrypted messages should be processed ) . <br>
2014-08-12 20:36:46 +00:00
On a debian based system these can be installed with <br>
<code>
2018-06-24 19:58:13 +00:00
sudo apt - get install libdigest - crc - perl <br>
2019-08-18 14:50:47 +00:00
sudo cpan - i Crypt::Mode:: CBC Crypt:: Mode:CTR Digest:: CMAC
2014-08-12 20:36:46 +00:00
</code>
<br> <br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-define" > </a>
2014-08-10 19:25:32 +00:00
<b> Define </b>
<ul>
2019-08-18 14:50:47 +00:00
<code> define & lt ; name & gt ; WMBUS [ & lt ; manufacturer id & gt ; & lt ; identification number & gt ; & lt ; version & gt ; & lt ; type & gt ; [ & lt ; MessageEncoding & gt ; ] ] | & lt ; b [ & lt ; MessageEncoding & gt ; ] HexCode & gt ; </code> <br>
2014-08-10 19:25:32 +00:00
<br>
2014-08-18 16:18:57 +00:00
Normally a WMBus device isn ' t defined manually but automatically through the < a href = "#autocreate" > autocreate </a> mechanism upon the first reception of a message .
2014-08-10 19:25:32 +00:00
<br>
2014-08-12 20:36:46 +00:00
For a manual definition there are two ways .
2014-08-10 19:25:32 +00:00
<ul>
2019-08-31 16:54:50 +00:00
<li>
2019-08-18 14:50:47 +00:00
By specifying a raw WMBus message as received by an IODev . Such a message starts with a lower case 'b' and contains at least 24 hexadecimal digits .
2019-08-31 16:54:50 +00:00
The WMBUS module extracts all relevant information from such a message .
</li>
<li>
2014-08-12 20:36:46 +00:00
Explictly specify the information that uniquely identifies a WMBus device . <br>
2014-08-10 19:25:32 +00:00
The manufacturer code , which is is a three letter shortcut of the manufacturer name . See
2019-08-18 14:50:47 +00:00
< a href = "https://www.dlms.com/flag-id/flag-id-list" > dlms . com </a> for a list of registered ids . <br>
2014-08-10 19:25:32 +00:00
The identification number is the serial no of the meter . <br>
version is the version code of the meter <br>
2016-11-08 19:34:33 +00:00
type is the type of the meter , e . g . water or electricity encoded as a number . <br>
2019-08-18 14:50:47 +00:00
MessageEncoding is either CUL or AMB , depending on which kind of IODev is used . The default encoding is CUL .
2014-08-10 19:25:32 +00:00
</li>
<br>
</ul>
</ul>
<br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-set" > </a>
2019-08-31 16:54:50 +00:00
<b> Set </b>
<ul>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-set-rawmsg" > </a>
2019-08-31 16:54:50 +00:00
<li>
rawmsg hexadecimal contents of a raw message ( without the leading b ) <br>
Will be parsed as if the message has been received by the IODev . Mainly useful for debugging .
</li>
</ul> <br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-get" > </a>
2014-08-10 19:25:32 +00:00
<b> Get </b> <ul> N /A</ ul > <br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-attr" > </a>
2014-08-10 19:25:32 +00:00
<b> Attributes </b>
<ul>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-attr-IODev" > </a>
2014-08-10 19:25:32 +00:00
<li> < a href = "#IODev" > IODev </a> <br>
2021-11-01 16:43:20 +00:00
Set the IO or physical device which should be used for receiving signals
for this "logical" device . An example for the physical device is a CUL .
2019-08-31 16:54:50 +00:00
</li> <br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-attr-AESkey" > </a>
2019-08-18 14:50:47 +00:00
<li> AESkey <br>
2021-11-01 16:43:20 +00:00
A 16 byte AES - Key in hexadecimal digits . Used to decrypt messages from meters which have encryption enabled .
</li> <br>
<li>
< a id = "WMBUS-attr-ignore" > </a>
< a href = "#ignore" > ignore </a>
</li> <br>
< a id = "WMBUS-attr-rawmsg_as_reading" > </a>
<li> rawmsg_as_reading <br>
2015-01-18 18:38:30 +00:00
If set to 1 , received raw messages will be stored in the reading rawmsg . This can be used to log raw messages to help with debugging .
2021-11-01 16:43:20 +00:00
</li> <br>
< a id = "WMBUS-attr-ignoreUnknownDataBlocks" > </a>
<li> ignoreUnknownDataBlocks <br>
2018-12-18 19:20:02 +00:00
If set to 1 , datablocks containing unknown / manufacturer specific data will be ignored . This is useful if a meter sends data in different
formats of which some can be interpreted and some not . This prevents the unknown data overwriting the readings of the data that can be
interpreted .
2019-08-18 14:50:47 +00:00
</li> <br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-attr-ignoreMasterMessages" > </a>
2019-08-18 14:50:47 +00:00
<li> ignoreMasterMessages <br>
2019-03-10 12:48:20 +00:00
Some devices ( e . g . Letrika solar inverters ) only send data if they have received a special message from a master device .
The messages sent by the master are ignored unless explictly enabled by this attribute .
2019-08-31 16:54:50 +00:00
</li> <br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-attr-useVIFasReadingName" > </a>
2019-08-31 16:54:50 +00:00
<li> useVIFasReadingName <br>
Some devices send several types of messages with different logical content . As the readings are normally numbered consecutively they will be overwitten
by blocks with a different semantic meaning .
If ths attribute is set to 1 the naming of the readings will be changed to start with storage number and VIF ( Value Information Field ) name .
Therefor each semantically different value will get a unique reading name . <br>
Example: <br>
<pre>
2020-02-09 18:41:03 +00:00
1 _storage_no 0
1 _type VIF_ENERGY_WATT
1 _unit Wh
2019-08-31 16:54:50 +00:00
1 _value 1234.5
</pre>
will be changed to <br>
<pre>
2020-02-09 18:41:03 +00:00
0 _VIF_ENERGY_WATT_unit Wh
2019-08-31 16:54:50 +00:00
0 _VIF_ENERGY_WATT_value 1234.5
</pre>
2019-03-10 12:48:20 +00:00
</li>
2014-08-10 19:25:32 +00:00
</ul>
2019-08-31 16:54:50 +00:00
<br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-readings" > </a>
2014-08-10 19:25:32 +00:00
<b> Readings </b> <br>
<ul>
Meters can send a lot of different information depending on their type . An electricity meter will send other data than a water meter .
2014-08-12 20:36:46 +00:00
The information also depends on the manufacturer of the meter . See the WMBus specification on < a href = "http://www.oms-group.org" > oms - group . org </a> for details .
2014-08-10 19:25:32 +00:00
<br> <br>
The readings are generated in blocks starting with block 1 . A meter can send several data blocks .
Each block has at least a type , a value and a unit , e . g . for an electricity meter it might look like <br>
<ul>
2015-01-18 18:38:30 +00:00
<code> 1 _type VIF_ENERGY_WATT </code> <br>
2014-10-25 14:54:42 +00:00
<code> 1 _unit Wh </code> <br>
<code> 1 _value 2948787 </code> <br>
2019-08-31 16:54:50 +00:00
</ul>
<br>
2014-08-10 19:25:32 +00:00
There is also a fixed set of readings .
<ul>
<li> <code> is_encrypted </code> is 1 if the received message is encrypted . </li>
2014-08-12 20:36:46 +00:00
<li> <code> decryption_ok </code> is 1 if a message has either been successfully decrypted or if it is unencrypted . </li>
2014-08-10 19:25:32 +00:00
<li> <code> state </code> contains the state of the meter and may contain error message like battery low . Normally it contains 'no error' . </li>
2018-05-23 18:42:34 +00:00
<li> <code> batteryState </code> contains ok or low . </li>
2014-08-10 19:25:32 +00:00
</ul>
2014-10-25 14:54:42 +00:00
For some well known devices specific readings like the energy consumption in kWh created .
2014-08-10 19:25:32 +00:00
</ul>
</ul>
= end html
2014-08-12 20:36:46 +00:00
= begin html_DE
2021-11-01 16:43:20 +00:00
< a id = "WMBUS" > </a>
2014-08-12 20:36:46 +00:00
<h3> WMBUS - Wireless M - Bus </h3>
<ul>
2014-08-14 19:04:34 +00:00
Dieses Modul unterst & uuml ; tzt Z & auml ; hler mit Wireless M - Bus , z . B . f & uuml ; r Wasser , Gas oder Elektrizit & auml ; t .
Wireless M - Bus ist ein standardisiertes Protokoll das von unterschiedlichen Herstellern unterst & uuml ; tzt wird .
2014-08-12 20:36:46 +00:00
2019-08-31 16:54:50 +00:00
Es verwendet das 868 MHz Band f & uuml ; r Radio & uuml ; bertragungen .
Daher wird ein Ger & auml ; t ben & ouml ; tigt das die Wireless M - Bus Nachrichten empfangen kann , z . B . ein < a href = "#CUL" > CUL </a> mit culfw >= 1.59 oder ein AMBER Wireless AMB8465 - M .
2014-08-12 20:36:46 +00:00
<br>
2018-06-24 19:58:13 +00:00
WMBus verwendet drei unterschiedliche Radioprotokolle , T - Mode , S - Mode und C - Mode . Der Empf & auml ; nger muss daher so konfiguriert werden , dass er das selbe Protokoll
verwendet wie der Sender . Im Falle eines CUL kann das erreicht werden , in dem das Attribut < a href = "#rfmode" > rfmode </a> auf WMBus_T , WMBus_S bzw . WMBus_C gesetzt wird .
2014-08-12 20:36:46 +00:00
<br>
2014-08-14 19:04:34 +00:00
WMBus Ger & auml ; te senden Daten periodisch abh & auml ; ngig von ihrer Konfiguration . Es k & ouml ; nnen u . U . Tage zwischen einzelnen Nachrichten vergehen oder sie k & ouml ; nnen im
2014-08-12 20:36:46 +00:00
Minutentakt gesendet werden .
<br>
2014-08-14 19:04:34 +00:00
WMBus Nachrichten k & ouml ; nnen optional verschl & uuml ; sselt werden . Bei verschl & uuml ; sselten Nachrichten muss der passende Schl & uuml ; ssel mit dem Attribut AESkey angegeben werden .
2019-08-18 14:50:47 +00:00
Andernfalls wird die Entschl & uuml ; sselung fehlschlagen und es k & ouml ; nnen keine relevanten Daten ausgelesen werden . Das Modul kann mit Security Profile A oder B ( Mode 5 und 7 ) verschl & uuml ; sselte Nachrichten entschl & uuml ; sseln .
2014-08-12 20:36:46 +00:00
<br> <br>
<b> Voraussetzungen </b> <br>
2019-08-31 16:54:50 +00:00
Dieses Modul ben & ouml ; tigt die perl Module Digest:: CRC , Crypt::Mode:: CBC , Crypt::Mode:: CTR und Digest:: CMAC ( die letzten drei Module werden nur ben & ouml ; tigt wenn verschl & uuml ; sselte Nachrichten verarbeitet werden sollen ) . <br>
2014-08-14 19:04:34 +00:00
Bei einem Debian basierten System k & ouml ; nnen diese so installiert werden <br>
2014-08-12 20:36:46 +00:00
<code>
2018-06-24 19:58:13 +00:00
sudo apt - get install libdigest - crc - perl <br>
2019-08-18 14:50:47 +00:00
sudo cpan - i Crypt::Mode:: CBC Crypt::Mode:: CTR Digest:: CMAC
2014-08-12 20:36:46 +00:00
</code>
<br> <br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-define" > </a>
2014-08-12 20:36:46 +00:00
<b> Define </b>
<ul>
2019-08-18 14:50:47 +00:00
<code> define & lt ; name & gt ; WMBUS [ & lt ; manufacturer id & gt ; & lt ; identification number & gt ; & lt ; version & gt ; & lt ; type & gt ; [ & lt ; MessageEncoding & gt ; ] ] | & lt ; b [ <MessageEncoding> ] HexCode & gt ; </code> <br>
2014-08-12 20:36:46 +00:00
<br>
2014-08-14 19:04:34 +00:00
Normalerweise wird ein WMBus Device nicht manuell angelegt . Dies geschieht automatisch bem Empfang der ersten Nachrichten eines Ger & auml ; tes & uuml ; ber den
2014-08-18 16:18:57 +00:00
fhem < a href = "#autocreate" > autocreate </a> Mechanismus .
2014-08-12 20:36:46 +00:00
<br>
2014-08-14 19:04:34 +00:00
F & uuml ; r eine manuelle Definition gibt es zwei Wege .
2014-08-12 20:36:46 +00:00
<ul>
2019-08-31 16:54:50 +00:00
<li>
Durch Verwendung einer WMBus Rohnachricht wie sie vom IODev empfangen wurde . So eine Nachricht beginnt mit einem kleinen 'b' und enth & auml ; lt mindestens
24 hexadezimale Zeichen .
Das WMBUS Modul extrahiert daraus alle ben & ouml ; tigten Informationen .
</li>
<li>
Durch explizite Angabe der Informationen die ein WMBus Ger & auml ; t eindeutig identfizieren . <br>
Der Hersteller Code , besteht aus drei Buchstaben als Abk & uuml ; rzung des Herstellernamens . Eine Liste der Abk & uuml ; rzungen findet sich unter
2019-08-18 14:50:47 +00:00
< a href = "https://www.dlms.com/flag-id/flag-id-list" > dlms . com </a> <br>
2014-08-14 19:04:34 +00:00
Die Idenitfikationsnummer ist die Seriennummer des Z & auml ; hlers . <br>
Version ist ein Versionscode des Z & auml ; hlers . <br>
2016-11-08 19:34:33 +00:00
Typ ist die Art des Z & auml ; hlers , z . B . Wasser oder Elektrizit & auml ; t , kodiert als Zahl . <br>
2019-08-18 14:50:47 +00:00
MessageEncoding ist entweder CUL oder AMB , je nachdem welche Art von IODev verwendet wird . Wird kein Encoding angegeben so wird CUL verwendet .
2014-08-12 20:36:46 +00:00
</li>
<br>
</ul>
</ul>
<br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-set" > </a>
2019-08-31 16:54:50 +00:00
<b> Set </b>
<ul>
<li>
rawmsg Hexadezimaler Inhalt einer Rohnachricht ( ohne f & uuml ; hrendes b ) <br>
Wird interpretiert als ob die Nachricht von einem IODev empfangen worden w & auml ; re . Haupts & auml ; chlich n & uuml ; tzlich zum debuggen .
</li>
</ul> <br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-get" > </a>
<b> Get </b>
<ul> N /A</ ul > <br>
2014-08-12 20:36:46 +00:00
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-attr" > </a>
2014-08-12 20:36:46 +00:00
<b> Attributes </b>
<ul>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-attr-IODev" > </a>
2014-08-12 20:36:46 +00:00
<li> < a href = "#IODev" > IODev </a> <br>
2021-11-01 16:43:20 +00:00
Setzt den IO oder physisches Ger & auml ; t welches f & uuml ; r den Empfang der Signale f & uuml ; r dieses 'logische' Ger & auml ; t verwendet werden soll .
Ein Beispiel f & uuml ; r ein solches Ger & auml ; t ist ein CUL .
2019-08-31 16:54:50 +00:00
</li> <br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-attr-AESkey" > </a>
2019-08-31 16:54:50 +00:00
<li> AESKey <br>
Ein 16 Bytes langer AES - Schl & uuml ; ssel in hexadezimaler Schreibweise . Wird verwendet um Nachrichten von Z & auml ; hlern zu entschl & uuml ; sseln bei denen
die Verschl & uuml ; sselung aktiviert ist .
</li> <br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-attr-ignore" > </a>
2014-08-18 16:18:57 +00:00
<li>
< a href = "#ignore" > ignore </a>
2015-01-18 18:38:30 +00:00
</li> <br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-attr-rawmsg_as_reading" > </a>
2015-01-18 18:38:30 +00:00
<li> rawmsg_as_reading <br>
2021-11-01 16:43:20 +00:00
Wenn auf 1 gesetzt so werden empfangene Nachrichten im Reading rawmsg gespeichert . Das kann verwendet werden um Rohnachrichten zu loggen und beim Debugging zu helfen .
2019-08-18 14:50:47 +00:00
</li> <br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-attr-ignoreUnknownDataBlocks" > </a>
<li>
ignoreUnknownDataBlocks <br>
2018-12-18 19:20:02 +00:00
Wenn auf 1 gesetzt so werden Datenblocks die unbekannte / herstellerspezifische Daten enthalten ignoriert . Das ist hilfreich wenn ein Z & auml ; hler Daten in unterschiedlichen
Formaten sendet von denen einige nicht interpretiert werden k & ouml ; nnen . Es verhindert , dass die unbekannten Daten die Readings der interpretierbaren Daten & uuml ; berschreiben .
2019-08-18 14:50:47 +00:00
</li> <br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-attr-ignoreMasterMessages" > </a>
2019-03-10 12:48:20 +00:00
<li> ignoreMasterMessages
Einige Geräte ( z . B . Letrika Wechselrichter ) senden nur dann Daten wenn sie eine spezielle Nachricht von einem Mastergerät erhalten haben .
Die Nachrichten von dem Master werden ignoriert es sei denn es wird explizit mit diesem Attribut eingeschaltet .
</li>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-attr-useVIFasReadingName" > </a>
2019-08-31 16:54:50 +00:00
<li> useVIFasReadingName <br>
Einige Ger & auml ; te senden verschiedene Arten von Nachrichten mit logisch unterschiedlichem Inhalt . Da die Readings normalerweise aufsteigend nummeriert werden
k & ouml ; nnen Readings durch semantisch unterschiedliche Readings & uuml ; berschrieben werden .
Wenn dieses Attribut auf 1 gesetzt ist & auml ; ndert sich die Namenskonvention der Readings . Die Namen setzen sich dann aus der Storagenumber und dem
VIF ( Value Information Field ) zusammen . Dadurch bekommt jeder semantisch unterschiedliche Wert einen eindeutigen Readingnamen .
Beispiel: <br>
<pre>
2020-02-09 18:41:03 +00:00
1 _storage_no 0
1 _type VIF_ENERGY_WATT
1 _unit Wh
2019-08-31 16:54:50 +00:00
1 _value 1234.5
</pre>
wird zu <br>
<pre>
2020-02-09 18:41:03 +00:00
0 _VIF_ENERGY_WATT_unit Wh
2019-08-31 16:54:50 +00:00
0 _VIF_ENERGY_WATT_value 1234.5
</pre>
</li>
2015-01-18 18:38:30 +00:00
</ul>
2019-08-31 16:54:50 +00:00
<br>
2021-11-01 16:43:20 +00:00
< a id = "WMBUS-readings" > </a>
2014-08-12 20:36:46 +00:00
<b> Readings </b> <br>
<ul>
2014-08-14 19:04:34 +00:00
Z & auml ; hler k & ouml ; nnen sehr viele unterschiedliche Informationen senden , abh & auml ; ngig von ihrem Typ . Ein Elektrizit & auml ; tsz & auml ; hler wird andere Daten senden als ein
Wasserz & auml ; hler . Die Information h & auml ; ngt auch vom Hersteller des Z & auml ; hlers ab . F & uuml ; r weitere Informationen siehe die WMBus Spezifikation unter
2014-08-12 20:36:46 +00:00
< a href = "http://www.oms-group.org" > oms - group . org </a> .
<br> <br>
2014-08-14 19:04:34 +00:00
Die Readings werden als Block dargestellt , beginnend mit Block 1 . Ein Z & auml ; hler kann mehrere Bl & ouml ; cke senden .
Jeder Block enth & auml ; lt zumindest einen Typ , einen Wert und eine Einheit . F & uuml ; r einen Elektrizit & auml ; tsz & auml ; hler k & ouml ; nnte das z . B . so aussehen <br>
2014-08-12 20:36:46 +00:00
<ul>
2015-01-18 18:38:30 +00:00
<code> 1 _type VIF_ENERGY_WATT </code> <br>
2014-10-25 14:54:42 +00:00
<code> 1 _unit Wh </code> <br>
<code> 1 _value 2948787 </code> <br>
2019-08-31 16:54:50 +00:00
</ul>
<br>
Es gibt auch eine Anzahl von festen Readings .
2014-08-12 20:36:46 +00:00
<ul>
2014-08-14 19:04:34 +00:00
<li> <code> is_encrypted </code> ist 1 wenn die empfangene Nachricht verschl & uuml ; sselt ist . </li>
<li> <code> decryption_ok </code> ist 1 wenn die Nachricht entweder erfolgreich entschl & uuml ; sselt wurde oder gar nicht verschl & uuml ; sselt war . </li>
<li> <code> state </code> enth & auml ; lt den Status des Z & auml ; hlers und kann Fehlermeldungen wie 'battery low' enthalten . Normalerweise ist der Wert 'no error' . </li>
2018-05-23 18:42:34 +00:00
<li> <code> batteryState </code> enth & auml ; lt ok oder low . </li>
2014-08-12 20:36:46 +00:00
</ul>
2014-10-25 14:54:42 +00:00
Für einige bekannte Gerätetypen werden zusätzliche Readings wie der Energieverbrauch in kWh erzeugt .
2014-08-12 20:36:46 +00:00
</ul>
</ul>
= end html_DE
2017-11-07 19:33:20 +00:00
= cut