mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-02 01:40:34 +00:00
05d5663ed6
git-svn-id: https://svn.fhem.de/fhem/trunk@18910 2b470e98-0d58-463d-a4d8-8e2adae1ed80
604 lines
18 KiB
Perl
604 lines
18 KiB
Perl
###############################################################################
|
|
# $Id$
|
|
#
|
|
# this module is part of fhem under the same license
|
|
# copyright 2015, joerg herrmann
|
|
#
|
|
# history
|
|
# initial checkin
|
|
#
|
|
###############################################################################
|
|
package main;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use Time::HiRes qw(time);
|
|
|
|
my %typeText = (
|
|
'62' => 'warm water', #
|
|
'72' => 'cold water', #
|
|
'43' => 'heat meter', # compact V
|
|
);
|
|
|
|
sub
|
|
TechemWZ_Initialize(@) {
|
|
my ($hash) = @_;
|
|
|
|
# require "Broker.pm";
|
|
|
|
$hash->{Match} = "^b..446850[\\d]{8}..(?:43|45|62|72).*";
|
|
|
|
$hash->{DefFn} = "TechemWZ_Define";
|
|
$hash->{UndefFn} = "TechemWZ_Undef";
|
|
$hash->{SetFn} = "TechemWZ_Set";
|
|
$hash->{GetFn} = "TechemWZ_Get";
|
|
$hash->{NotifyFn} = "TechemWZ_Notify";
|
|
$hash->{ParseFn} = "TechemWZ_Parse";
|
|
|
|
$hash->{AttrList} = "".$readingFnAttributes;
|
|
|
|
return undef;
|
|
}
|
|
|
|
sub
|
|
TechemWZ_Define(@) {
|
|
my ($hash, $def) = @_;
|
|
my ($name, $t, $id);
|
|
($name, $t, $id, $def) = split(/ /, $def,4);
|
|
|
|
return "ID must have 8 digits" if ($id !~ /^\d{8}$/);
|
|
return "ID $id already defined" if exists($modules{TechemWZ}{defptr}{$id});
|
|
|
|
# house keeping
|
|
if (exists($hash->{OLDDEF}) && ($hash->{DEF} ne $hash->{OLDDEF}) ) {
|
|
my @a = split(/ /, $hash->{OLDDEF});
|
|
delete($hash->{VERSION});
|
|
delete($hash->{METER});
|
|
delete($hash->{READINGS});
|
|
delete($modules{TechemWZ}{defptr}{$a[0]});
|
|
delete($hash->{helper}->{list});
|
|
}
|
|
|
|
# create crc table if required
|
|
$data{WMBUS}{crc_table_13757} = TechemWZ_createCrcTable() unless (exists($data{WMBUS}{crc_table_13757}));
|
|
|
|
$hash->{helper}->{listmode} = ($id eq '00000000')?1:0;
|
|
$hash->{ID} = $id;
|
|
$modules{TechemWZ}{defptr}{$id} = $hash;
|
|
$hash->{FRIENDLY} = $def if (defined($def));
|
|
|
|
# subscribe broadcast channels
|
|
# TechemWZ_subscribe($hash, 'foo');
|
|
TechemWZ_Run($hash) if $init_done;
|
|
return undef;
|
|
}
|
|
|
|
sub
|
|
TechemWZ_Undef(@) {
|
|
my ($hash) = @_;
|
|
my $id = $hash->{ID};
|
|
delete($modules{TechemWZ}{defptr}{$id});
|
|
return undef;
|
|
}
|
|
|
|
sub
|
|
TechemWZ_Set(@) {
|
|
my ($hash, $name, $cmd, @args) = @_;
|
|
my $cnt = @args;
|
|
|
|
return undef;
|
|
}
|
|
|
|
sub
|
|
TechemWZ_Get(@) {
|
|
my ($hash, $name, $cmd, @args) = @_;
|
|
return undef unless ($hash->{helper}->{listmode});
|
|
return "unknown command ($cmd): choose one of list" if ($cmd eq "?");
|
|
return "unknown command ($cmd): choose one of list" if ($cmd ne "list");
|
|
|
|
my $result = "";
|
|
|
|
my $l = $hash->{helper}->{list};
|
|
|
|
foreach my $key (sort { $l->{$a}->{msg}->{meter} <=> $l->{$b}->{msg}->{meter} } keys %{$l} ) {
|
|
$result .= "$l->{$key}->{msg}->{long}\t";
|
|
$result .= $typeText{$l->{$key}->{msg}->{type}}."\t";
|
|
$result .= "$l->{$key}->{msg}->{meter}\t";
|
|
$result .= "$l->{$key}->{msg}->{rssi}\t\n";
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
sub
|
|
TechemWZ_Notify (@) {
|
|
my ($hash, $ntfyDev) = @_;
|
|
return unless (($ntfyDev->{TYPE} eq 'CUL') || ($ntfyDev->{TYPE} eq 'Global'));
|
|
foreach my $event (@{$ntfyDev->{CHANGED}}) {
|
|
my @e = split(' ', $event);
|
|
next unless defined($e[0]);
|
|
TechemWZ_Run($hash) if ($e[0] eq 'INITIALIZED');
|
|
# patch CUL.pm
|
|
TechemWZ_IOPatch($hash, $e[1]) if (($e[0] eq 'ATTR') && ($e[2] eq 'rfmode') && ($e[3] eq 'WMBus_T'));
|
|
# disable receiver
|
|
if (($e[0] eq 'ATTR') && ($e[2] eq 'rfmode') && ($e[3] ne 'WMBus_T')) {
|
|
readingsBeginUpdate($hash);
|
|
readingsBulkUpdate($hash, "state", "standby (IO missing)", 1);
|
|
readingsEndUpdate($hash, 1);
|
|
}
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
sub
|
|
TechemWZ_Receive(@) {
|
|
my ($hash, $msg, $raw) = @_;
|
|
|
|
my @t = localtime(time);
|
|
my ($ats, $ts);
|
|
|
|
$hash->{VERSION} = $msg->{version};
|
|
$hash->{METER} = $typeText{$msg->{type}};
|
|
delete $hash->{CHANGETIME}; # clean up, workaround for fhem prior http://forum.fhem.de/index.php/topic,47474.msg391964.html#msg391964
|
|
|
|
# day period changed
|
|
$ats = ReadingsTimestamp($hash->{NAME},"current_period", "0");
|
|
$ts = sprintf ("%02d-%02d-%02d 00:00:00", $msg->{actual}->{year}, $msg->{actual}->{month}, $msg->{actual}->{day});
|
|
if ($ats ne $ts) {
|
|
my $i;
|
|
readingsBeginUpdate($hash);
|
|
$hash->{".updateTimestamp"} = $ts;
|
|
$i = $#{ $hash->{CHANGED} };
|
|
readingsBulkUpdate($hash, "meter", $msg->{meter});
|
|
$hash->{CHANGETIME}->[$#{ $hash->{CHANGED} }] = $ts if ($#{ $hash->{CHANGED} } != $i ); # only add ts if there is a event to
|
|
$i = $#{ $hash->{CHANGED} };
|
|
readingsBulkUpdate($hash, "current_period", $msg->{actualVal});
|
|
$hash->{CHANGETIME}->[$#{ $hash->{CHANGED} }] = $ts if ($#{ $hash->{CHANGED} } != $i ); # only add ts if there is a event to
|
|
readingsEndUpdate($hash, 1);
|
|
}
|
|
|
|
# billing period changed
|
|
$ats = ReadingsTimestamp($hash->{NAME},"previous_period", "0");
|
|
$ts = sprintf ("20%02d-%02d-%02d 00:00:00", $msg->{last}->{year}, $msg->{last}->{month}, $msg->{last}->{day});
|
|
if ($ats ne $ts) {
|
|
my $i;
|
|
readingsBeginUpdate($hash);
|
|
$hash->{".updateTimestamp"} = $ts;
|
|
$i = $#{ $hash->{CHANGED} };
|
|
readingsBulkUpdate($hash, "previous_period", $msg->{lastVal});
|
|
$hash->{CHANGETIME}->[$#{ $hash->{CHANGED} }] = $ts if ($#{ $hash->{CHANGED} } != $i ); # only add ts if there is a event to
|
|
readingsEndUpdate($hash, 1);
|
|
}
|
|
|
|
return undef;
|
|
}
|
|
|
|
sub
|
|
TechemWZ_Run(@) {
|
|
my ($hash) = @_;
|
|
# find a CUL
|
|
foreach my $d (keys %defs) {
|
|
# live patch CUL.pm
|
|
TechemWZ_IOPatch($hash, $d) if ($defs{$d}{TYPE} eq "CUL");
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
# live patch CUL.pm, aka THE HACK
|
|
sub
|
|
TechemWZ_IOPatch(@) {
|
|
my ($hash, $iodev) = @_;
|
|
return undef unless (AttrVal($iodev, 'rfmode', '') eq 'WMBus_T');
|
|
# see if already patched
|
|
readingsSingleUpdate($hash, 'state', 'listening', 1);
|
|
return undef if ($defs{$iodev}{Clients} =~ /TechemWZ/ );
|
|
$defs{$iodev}{Clients} = ':TechemWZ'.$defs{$iodev}{Clients};
|
|
$defs{$iodev}{'.clientArray'} = undef;
|
|
return undef;
|
|
}
|
|
|
|
sub
|
|
TechemWZ_Parse(@) {
|
|
|
|
my ($iohash, $msg) = @_;
|
|
my ($message, $rssi);
|
|
($msg, $rssi) = split (/::/, $msg);
|
|
$msg = TechemWZ_SanityCheck($msg);
|
|
return '' unless $msg;
|
|
|
|
my @m = ($msg =~ m/../g);
|
|
my @d;
|
|
|
|
# parse
|
|
($message->{long}, $message->{short}) = TechemWZ_ParseID(@m);
|
|
$message->{type} = TechemWZ_ParseSubType(@m);
|
|
$message->{version} = TechemWZ_ParseSubVersion(@m);
|
|
$message->{rssi} = ($rssi)?$rssi:"?";
|
|
|
|
# metertype specific adjustment
|
|
if ($message->{type} =~ /62|72/) {
|
|
$message->{lastVal} = TechemWZ_ParseLastPeriod(@m);
|
|
$message->{actualVal} = TechemWZ_ParseActualPeriod(@m);
|
|
($message->{actual}->{year}, $message->{actual}->{month}, $message->{actual}->{day}) = TechemWZ_ParseActualDate(@m);
|
|
($message->{last}->{year}, $message->{last}->{month}, $message->{last}->{day}) = TechemWZ_ParseLastDate(@m);
|
|
$message->{lastVal} /= 10;
|
|
$message->{actualVal} /= 10;
|
|
$message->{meter} = $message->{lastVal} + $message->{actualVal};
|
|
} elsif ($message->{type} =~ /43|45/) {
|
|
$message->{lastVal} = TechemWZ_WMZ_Type1_ParseLastPeriod(@m);
|
|
$message->{actualVal} = TechemWZ_WMZ_Type1_ParseActualPeriod(@m);
|
|
($message->{actual}->{year}, $message->{actual}->{month}, $message->{actual}->{day}) = TechemWZ_WMZ_Type1_ParseActualDate(@m);
|
|
($message->{last}->{year}, $message->{last}->{month}, $message->{last}->{day}) = TechemWZ_ParseLastDate(@m);
|
|
$message->{meter} = $message->{lastVal} + $message->{actualVal};
|
|
}
|
|
|
|
# list
|
|
if (exists( $modules{TechemWZ}{defptr}{'00000000'} ) && defined( $defs{$modules{TechemWZ}{defptr}{'00000000'}->{NAME}} )) {
|
|
my $listdev = $modules{TechemWZ}{defptr}{'00000000'};
|
|
$listdev->{helper}->{list}->{$message->{long}}->{msg} = $message;
|
|
push @d, $listdev->{NAME};
|
|
}
|
|
|
|
# dispatch
|
|
if (exists( $modules{TechemWZ}{defptr}{$message->{long}})) {
|
|
my $deviceHash = $modules{TechemWZ}{defptr}{$message->{long}};
|
|
TechemWZ_Receive($deviceHash, $message);
|
|
push @d, $deviceHash->{NAME};
|
|
}
|
|
|
|
if (defined($d[0])) {
|
|
return (@d);
|
|
} else {
|
|
return (''); # discard neighbor devices
|
|
}
|
|
}
|
|
|
|
sub
|
|
TechemWZ_SanityCheck(@) {
|
|
|
|
my ($msg) = @_;
|
|
my $rssi;
|
|
my $t;
|
|
my $dbg = 4;
|
|
|
|
#($msg, $rssi) = split (/::/, $msg);
|
|
my @m = ((substr $msg,1) =~ m/../g);
|
|
# at least 3 chars
|
|
if (length($msg) < 3) {
|
|
Log3 ("TechemWZ", $dbg, "msg incomplete $msg");
|
|
return undef;
|
|
}
|
|
# msg length without crc blocks
|
|
my $l = hex(substr $msg, 1, 2) + 1;
|
|
# full crc payload blocks
|
|
my $fb = int(($l - 10) / 16);
|
|
# remaining bytes ?
|
|
my $rb = ($l - 10) % 16;
|
|
# required len
|
|
my $rl = $l + 2 + ($fb * 2) + (($rb)?2:0);
|
|
|
|
if (($rl * 2) > (length($msg) -1)) {
|
|
Log3 ("TechemWZ", $dbg, "msg incomplete $msg");
|
|
return undef;
|
|
}
|
|
|
|
# CRC first 10 byte, then chunks of 16 byte then remaining
|
|
if ((substr $msg, 21, 4) ne TechemWZ_crc16_13757(substr $msg, 1, 20)) {
|
|
Log3 ("TechemWZ", $dbg, "crc error $msg");
|
|
return undef;
|
|
} else {
|
|
$t = substr $msg, 3, 18;
|
|
}
|
|
for (my $i = 0; $i<$fb; $i++) {
|
|
if ((substr $msg, 57 + ($i * 36), 4) ne TechemWZ_crc16_13757(substr $msg, 25 + ($i * 36), 32)) {
|
|
Log3 ("TechemWZ", $dbg, "crc error $msg");
|
|
return undef;
|
|
} else {
|
|
$t .= substr $msg, 25 + ($i * 36), 32;
|
|
}
|
|
}
|
|
if ($rb) {
|
|
if ((substr $msg, 25 + ($fb * 36) + ($rb * 2), 4) ne TechemWZ_crc16_13757(substr $msg, 25 + ($fb * 36), $rb * 2)) {
|
|
Log3 ("TechemWZ", $dbg, "crc error $msg");
|
|
return undef;
|
|
} else {
|
|
$t .= substr $msg, 25 + ($fb * 36), ($rb * 2);
|
|
}
|
|
}
|
|
return $t;
|
|
}
|
|
|
|
sub
|
|
TechemWZ_ParseID(@) {
|
|
my @m = @_;
|
|
return ("$m[6]$m[5]$m[4]$m[3]", "$m[4]$m[3]");
|
|
}
|
|
|
|
sub
|
|
TechemWZ_ParseSubType(@) {
|
|
my @m = @_;
|
|
return "$m[8]";
|
|
}
|
|
|
|
sub
|
|
TechemWZ_ParseSubVersion(@) {
|
|
my @m = @_;
|
|
return "$m[7]";
|
|
}
|
|
|
|
sub
|
|
TechemWZ_ParseLastPeriod(@) {
|
|
my @m = @_;
|
|
return hex("$m[14]$m[13]");
|
|
}
|
|
|
|
|
|
sub
|
|
TechemWZ_ParseActualPeriod(@) {
|
|
my @m = @_;
|
|
return hex("$m[18]$m[17]");
|
|
}
|
|
|
|
|
|
sub
|
|
TechemWZ_ParseActualDate(@) {
|
|
my @m = @_;
|
|
my @t = localtime(time);
|
|
my $b = hex("$m[16]$m[15]");
|
|
my $d = ($b >> 4) & 0x1F;
|
|
my $m = ($b >> 9) & 0x0F;
|
|
my $y = $t[5] + 1900;
|
|
return ($y, $m, $d);
|
|
}
|
|
|
|
sub
|
|
TechemWZ_ParseLastDate(@) {
|
|
my @m = @_;
|
|
my $b = hex("$m[12]$m[11]");
|
|
my $d = ($b >> 0) & 0x1F;
|
|
my $m = ($b >> 5) & 0x0F;
|
|
my $y = ($b >> 9) & 0x3F;
|
|
return ($y, $m, $d);
|
|
}
|
|
|
|
###############################################################################
|
|
#
|
|
# Compact 5 heatmeter
|
|
#
|
|
###############################################################################
|
|
|
|
sub
|
|
TechemWZ_WMZ_Type1_ParseLastPeriod(@) {
|
|
my @m = @_;
|
|
return hex("$m[15]$m[14]$m[13]");
|
|
}
|
|
|
|
sub
|
|
TechemWZ_WMZ_Type1_ParseActualPeriod(@) {
|
|
my @m = @_;
|
|
return hex("$m[19]$m[18]$m[17]");
|
|
}
|
|
|
|
sub
|
|
TechemWZ_WMZ_Type1_ParseActualDate(@) {
|
|
my @m = @_;
|
|
my @t = localtime(time);
|
|
my $b = hex("$m[21]$m[20]");
|
|
my $d = ($b >> 7) & 0x1F;
|
|
my $m = (hex("$m[16]") >> 3) & 0x0F;
|
|
my $y = $t[5] + 1900;
|
|
return ($y, $m, $d);
|
|
}
|
|
|
|
sub
|
|
TechemWZ_createCrcTable(@) {
|
|
|
|
my $poly = 0x3D65;
|
|
my $c;
|
|
my @table;
|
|
|
|
for (my $i=0; $i<256; $i++) {
|
|
$c = ($i << 8);
|
|
|
|
for (my $j=0; $j<8; $j++) {
|
|
if (($c & 0x8000) != 0) {
|
|
$c = 0xFFFF & (($c << 1) ^ $poly);
|
|
|
|
} else {
|
|
$c <<= 1;
|
|
|
|
}
|
|
}
|
|
$table[$i] = $c;
|
|
}
|
|
return \@table;
|
|
}
|
|
|
|
sub
|
|
TechemWZ_crc16_13757(@) {
|
|
|
|
my ($msg) = @_;
|
|
my @table = @{$data{WMBUS}{crc_table_13757}};
|
|
|
|
my @in = split '', pack 'H*', $msg;
|
|
my $crc = 0x0000;
|
|
for (my $i=0; $i<int(@in); $i++) {
|
|
$crc = 0xffff & ( ($crc << 8) ^ $table[(($crc >> 8) ^ ord($in[$i]))] );
|
|
|
|
}
|
|
return sprintf ("%04lX", $crc ^ 0xFFFF);
|
|
}
|
|
|
|
# message bus ahead
|
|
# sub
|
|
#TechemWZ_subscribe(@) {
|
|
# my ($hash, $topic) = @_;
|
|
# broker::subscribe ($topic, $hash->{NAME}, \&TechemWZ_rcvBCST);
|
|
# return undef;
|
|
#}
|
|
|
|
#sub
|
|
#TechemWZ_sendBCST(@) {
|
|
# my ($hash, $topic, $msg) = @_;
|
|
# broker::publish ($topic, $hash->{NAME}, $msg);
|
|
# return undef;
|
|
#}
|
|
|
|
#sub
|
|
#TechemWZ_rcvBCST(@) {
|
|
# my ($name, $topic, $sender, $msg) = @_;
|
|
# my $hash = $defs{$name};
|
|
# return undef;
|
|
#}
|
|
|
|
1;
|
|
|
|
=pod
|
|
=item summary This module reads the transmission of techem volume data meter.
|
|
=item summary_DE Das modul empfängt Daten von Techem Volumenzählern.
|
|
=begin html
|
|
|
|
<a name="TechemWZ"></a>
|
|
<h3>TechemWZ</h3>
|
|
<ul>
|
|
This module reads the transmission of techem volume data meter. Currently supported device:
|
|
<p>
|
|
<ul>
|
|
<li>Messkapsel-Wasserzähler radio 3 (cold, warm water)</li>
|
|
<li>Messkapsel-Wärmemengenzähler compact V (heating energy)</li>
|
|
</ul>
|
|
<br>
|
|
It will display
|
|
<ul>
|
|
<li>meter data for current billing period</li>
|
|
<li>meter data for previous billing period including date of request</li>
|
|
<li>cumulative meter data</li>
|
|
</ul>
|
|
<br>
|
|
It will require a CUL in WMBUS_T mode, although the CUL may temporary set into that mode.
|
|
The module keeps track of the CUL rfmode.
|
|
<br>
|
|
<br>
|
|
<a name="TechemWZ_preliminary"></a>
|
|
<b>preliminary</b>
|
|
<p>
|
|
Techem volume data meter does not transmit their printed meter ID. Instead they transmit the ID of the build in radio module.
|
|
<p>
|
|
Therefore a <b>"list-mode"</b> is available which collects all Techem meter device in range to help you find out the right one.
|
|
That "list-mode" will be activated by defining a TechemWZ device with id "00000000". Let it run for a while and do a "get <name> list".
|
|
You will see a list of available (received) Techem device with their ID and meter data. Choose the right one (keep in mind that the meter reading reflects last midnight), note down their ID and define the appropriate device. After done the device with ID "00000000" can be removed.
|
|
<br>
|
|
<br>
|
|
<a name="TechemWZ_Define"></a>
|
|
<b>Define</b>
|
|
<br>
|
|
<code>define <name> TechemWZ <8 digit ID> [<speaking name>]</code>
|
|
<ul>
|
|
<li>ID: 8 digit ID (see list mode above)</li>
|
|
<li>speaking name: (optional) human readable identification</li>
|
|
</ul>
|
|
<br>
|
|
<a name="TechemWZ_Readings"></a>
|
|
<b>Readings</b>
|
|
<ul>
|
|
<li>current_period: meter data for current billing period
|
|
<br><i>cumulated since the start of the current billing period. The reading will be updated once a day, after receiving the first update. Reading time will reflect the time of data (not the time where the data were received)</i></br>
|
|
</li>
|
|
<li>previous_period: meter data for last billing period
|
|
<br><i>meter rading at the end of the last billing period. The reading will be updated if a new billing period starts. Reading time will reflect the last day of previous billing period (not the time where the data were received)</i></br>
|
|
</li>
|
|
<li>meter: cumulative meter data.
|
|
<br><i>The same data that will be shown at the Techem (mechanical) display</i></br>
|
|
</li>
|
|
<br>
|
|
</ul>
|
|
<a name="TechemWZ_Get"></a>
|
|
<b>Get</b>
|
|
<ul>
|
|
<li>list: print a list of available (received) Techem device with their ID and meter data
|
|
<br><i><u>only available if device ID is "00000000" (list-mode)</u></i></br>
|
|
</li>
|
|
<br>
|
|
</ul>
|
|
<a name="TechemWZ_Internals"></a>
|
|
<b>Internals</b>
|
|
<ul>
|
|
<li>friendly: human readable identification of meter as specified by define</li>
|
|
<br>
|
|
</ul>
|
|
</ul>
|
|
=end html
|
|
=begin html_DE
|
|
|
|
<a name="TechemWZ"></a>
|
|
<h3>TechemWZ</h3>
|
|
<ul>
|
|
Das modul empfängt Daten von Techem Volumenzählern. Unterstützte Zählertypen sind
|
|
<p>
|
|
<ul>
|
|
<li>Messkapsel-Wasserzähler radio 3 (Kalt-, Warmwasser)</li>
|
|
<li>Messkapsel-Wärmemengenzähler compact V</li>
|
|
</ul>
|
|
<br>
|
|
Empfangen werden:
|
|
<ul>
|
|
<li>Wert des aktuellen Abrechnungszeitraumes</li>
|
|
<li>Wert des vorhergehenden Abrechnungszeitraumes einschließlich des Ablesedatums</li>
|
|
<li>Gesamter aufgelaufener Verbrauchswert</li>
|
|
</ul>
|
|
<br>
|
|
Zum Empfang wird ein CUL im WMBUS_T mode benötigt. Dabei ist es ausreichend ihn vorrübergehend in diesen Modus zu schalten. Das Modul überwacht den rfmode aller verfügbaren CUL
|
|
<br>
|
|
<br>
|
|
<a name="TechemWZ_preliminary"></a>
|
|
<b>Vorbereitung</b>
|
|
<p>
|
|
Leider übertragen die Techem Volumenzähler nicht die aufgedruckte Zählernummer. Übertragen wird nur die ID des eingebauten Funkmoduls.
|
|
<p>
|
|
Das Modul stellt daher einen <b>"list-mode"</b> zur Verfügung. Damit kann eine Liste aller empfangenen Techem Volumenzähler anzeigt werden. Der "list-mode" wird aktiviert indem ein TechemWZ device mit der ID "00000000" definiert wird.
|
|
Lassen Sie dieses device einige Zeit laufen damit es Informationen über die verfügbaren Zähler sammeln kann. Rufen Sie dann "get <name> list" auf um eine Liste der empfangenen Techem Volumenzähler, ihrer ID sowie der dazugehörigen Zählerstände zu sehen. Denken Sie daran das dies die Werte des letzten Tageswechsels sind.
|
|
Notieren Sie sich anhand dieser Angaben die ID der gesuchten Zähler und definieren sie damit die entsprechenden TechemWZ device. Das list-mode device mit der ID "00000000" kann danach gefahrlos gelöscht werden.
|
|
<br>
|
|
<br>
|
|
<a name="TechemWZ_Define"></a>
|
|
<b>Define</b>
|
|
<br>
|
|
<code>define <name> TechemWZ <8 digit ID> [<speaking name>]</code>
|
|
<ul>
|
|
<li>ID: 8 stellige ID des Funkmoduls(siehe "list-mode")</li>
|
|
<li>speaking name: (optional) Bezeichnung</li>
|
|
</ul>
|
|
<br>
|
|
<a name="TechemWZ_Readings"></a>
|
|
<b>Readings</b>
|
|
<ul>
|
|
<li>current_period: Wert des aktuellen Abrechnungszeitraumes
|
|
<br><i>Der kumulierte Verbrauch seid dem Start des aktuellen Abrechnungszeitraumes. Das reading wird einmal am Tag aktualisiert. Die Zeit kennzeichnet den Stand der Daten. (und nicht den Empfangszeitpunkt der Daten)</i></br>
|
|
</li>
|
|
<li>previous_period: Wert des letzten Ablesezeitpunktes
|
|
<br><i>Zählerstand zum letzten Abrechnungszeitpunkt. Das reading wird zum Ablesezeitpunkt aktualisiert. Die Zeit kennzeichnet das Ablesedatum (und nicht den Empfangszeitpunkt der Daten)</i></br>
|
|
</li>
|
|
<li>meter: gesamter Verbrauch.
|
|
<br><i>Der Zählerstand so wie er an der (mechanischen) Anzeige des Zählers abgelesen werden kann</i></br>
|
|
</li>
|
|
<br>
|
|
</ul>
|
|
<a name="TechemWZ_Get"></a>
|
|
<b>Get</b>
|
|
<ul>
|
|
<li>list: gibt eine Liste der empfangenen Techem Volumenzähler, ihrer ID sowie der dazugehörigen Zählerstände aus.
|
|
<br><i><u>nur im "list-mode" (ID "00000000") verfügbar</u></i></br>
|
|
</li>
|
|
<br>
|
|
</ul>
|
|
<a name="TechemWZ_Internals"></a>
|
|
<b>Internals</b>
|
|
<ul>
|
|
<li>friendly: die beim define übergebene, zusätzliche Bezeichnung</li>
|
|
<br>
|
|
</ul>
|
|
</ul>
|
|
=end html_DE
|
|
=cut
|