mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-05-04 22:19:38 +00:00
initial EM1010 support
git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@64 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
5fbe0b13b6
commit
bac23e2e1f
1
CHANGED
1
CHANGED
@ -332,3 +332,4 @@
|
|||||||
- bugfix: deleted FS20 items are still logging (zombie) (Gerhard, 16.5)
|
- bugfix: deleted FS20 items are still logging (zombie) (Gerhard, 16.5)
|
||||||
- bugfix: added FS20S8, removed stty_parmrk (Martin, 24.5)
|
- bugfix: added FS20S8, removed stty_parmrk (Martin, 24.5)
|
||||||
- feature: added archivedir/archivecmd to the FileLog
|
- feature: added archivedir/archivecmd to the FileLog
|
||||||
|
- feature: added EM1010PC/EM1000WZ support
|
||||||
|
292
FHEM/60_EM.pm
Executable file
292
FHEM/60_EM.pm
Executable file
@ -0,0 +1,292 @@
|
|||||||
|
##############################################
|
||||||
|
package main;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Device::SerialPort;
|
||||||
|
|
||||||
|
sub EM_Write($$);
|
||||||
|
sub EmCrc($$);
|
||||||
|
sub EmCrcCheck($$);
|
||||||
|
sub EmEsc($);
|
||||||
|
sub EmGetData($$);
|
||||||
|
sub EmMakeMsg($);
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
sub
|
||||||
|
EM_Initialize($)
|
||||||
|
{
|
||||||
|
my ($hash) = @_;
|
||||||
|
|
||||||
|
|
||||||
|
# Provider
|
||||||
|
$hash->{WriteFn} = "EM_Write";
|
||||||
|
$hash->{Clients} = ":EMWZ:";
|
||||||
|
|
||||||
|
# Consumer
|
||||||
|
$hash->{DefFn} = "EM_Define";
|
||||||
|
$hash->{UndefFn} = "EM_Undef";
|
||||||
|
$hash->{GetFn} = "EM_Get";
|
||||||
|
$hash->{SetFn} = "EM_Set";
|
||||||
|
$hash->{AttrList}= "model:em1010pc loglevel:0,1,2,3,4,5,6";
|
||||||
|
}
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
sub
|
||||||
|
EM_Define($$)
|
||||||
|
{
|
||||||
|
my ($hash, $def) = @_;
|
||||||
|
my @a = split("[ \t][ \t]*", $def);
|
||||||
|
|
||||||
|
$hash->{STATE} = "Initialized";
|
||||||
|
|
||||||
|
delete $hash->{PortObj};
|
||||||
|
delete $hash->{FD};
|
||||||
|
|
||||||
|
my $dev = $a[2];
|
||||||
|
$attr{$a[0]}{savefirst} = 1;
|
||||||
|
|
||||||
|
if($dev eq "none") {
|
||||||
|
Log 1, "EM device is none, commands will be echoed only";
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log 3, "EM opening device $dev";
|
||||||
|
my $po = new Device::SerialPort ($dev);
|
||||||
|
return "Can't open $dev: $!\n" if(!$po);
|
||||||
|
Log 3, "EM opened device $dev";
|
||||||
|
$po->close();
|
||||||
|
|
||||||
|
$hash->{DeviceName} = $dev;
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
sub
|
||||||
|
EM_Undef($$)
|
||||||
|
{
|
||||||
|
my ($hash, $arg) = @_;
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
|
foreach my $d (sort keys %defs) {
|
||||||
|
if(defined($defs{$d}) &&
|
||||||
|
defined($defs{$d}{IODev}) &&
|
||||||
|
$defs{$d}{IODev} == $hash)
|
||||||
|
{
|
||||||
|
Log GetLogLevel($name,2), "deleting port for $d";
|
||||||
|
delete $defs{$d}{IODev};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
sub
|
||||||
|
EM_Set($@)
|
||||||
|
{
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
#########################
|
||||||
|
sub
|
||||||
|
b($$)
|
||||||
|
{
|
||||||
|
my ($t,$p) = @_;
|
||||||
|
return -1 if(length($t) < $p);
|
||||||
|
return ord(substr($t,$p,1));
|
||||||
|
}
|
||||||
|
|
||||||
|
sub
|
||||||
|
w($$)
|
||||||
|
{
|
||||||
|
my ($t,$p) = @_;
|
||||||
|
return b($t,$p+1)*256 + b($t,$p);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub
|
||||||
|
dw($$)
|
||||||
|
{
|
||||||
|
my ($t,$p) = @_;
|
||||||
|
return w($t,$p+2)*65536 + w($t,$p);
|
||||||
|
}
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
sub
|
||||||
|
EM_Get($@)
|
||||||
|
{
|
||||||
|
my ($hash, @a) = @_;
|
||||||
|
|
||||||
|
return "\"get EM\" needs only one parameter" if(@a != 2);
|
||||||
|
|
||||||
|
my $v;
|
||||||
|
if($a[1] eq "time") {
|
||||||
|
|
||||||
|
my $d = EmGetData($hash->{DeviceName}, "74");
|
||||||
|
$v = sprintf "%4d-%02d-%02d %02d:%02d:%02d",
|
||||||
|
b($d,5)+2006, b($d,4), b($d,3),
|
||||||
|
b($d,0), b($d,1), b($d,2);
|
||||||
|
|
||||||
|
} elsif($a[1] eq "version") {
|
||||||
|
|
||||||
|
my $d = EmGetData($hash->{DeviceName},"76");
|
||||||
|
$v = sprintf "%d.%d", b($d,0), b($d,1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return "Unknown argument $a[1], choose one of time,version";
|
||||||
|
}
|
||||||
|
|
||||||
|
$hash->{READINGS}{$a[1]}{VAL} = $v;
|
||||||
|
$hash->{READINGS}{$a[1]}{TIME} = TimeNow();
|
||||||
|
|
||||||
|
return "$a[0] $a[1] => $v";
|
||||||
|
}
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
sub
|
||||||
|
EM_Write($$)
|
||||||
|
{
|
||||||
|
my ($hash,$msg) = @_;
|
||||||
|
|
||||||
|
return EmGetData($hash->{DeviceName}, $msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
sub
|
||||||
|
EmCrc($$)
|
||||||
|
{
|
||||||
|
my ($in, $val) = @_;
|
||||||
|
my ($crc, $bits) = (0, 8);
|
||||||
|
my $k = (($in >> 8) ^ $val) << 8;
|
||||||
|
while($bits--) {
|
||||||
|
if(($crc ^ $k) & 0x8000) {
|
||||||
|
$crc = ($crc << 1) ^ 0x8005;
|
||||||
|
} else {
|
||||||
|
$crc <<= 1;
|
||||||
|
}
|
||||||
|
$k <<= 1;
|
||||||
|
}
|
||||||
|
return (($in << 8) ^ $crc) & 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#########################
|
||||||
|
sub
|
||||||
|
EmEsc($)
|
||||||
|
{
|
||||||
|
my ($b) = @_;
|
||||||
|
|
||||||
|
my $out = "";
|
||||||
|
$out .= chr(0x10) if($b==0x02 || $b==0x03 || $b==0x10);
|
||||||
|
$out .= chr($b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
sub
|
||||||
|
EmCrcCheck($$)
|
||||||
|
{
|
||||||
|
my ($otxt, $len) = @_;
|
||||||
|
my $crc = 0x8c27;
|
||||||
|
for(my $l = 2; $l < $len+4; $l++) {
|
||||||
|
my $b = ord(substr($otxt,$l,1));
|
||||||
|
$crc = EmCrc($crc, 0x10) if($b==0x02 || $b==0x03 || $b==0x10);
|
||||||
|
$crc = EmCrc($crc, $b);
|
||||||
|
}
|
||||||
|
return ($crc == w($otxt, $len+4));
|
||||||
|
}
|
||||||
|
|
||||||
|
#########################
|
||||||
|
sub
|
||||||
|
EmMakeMsg($)
|
||||||
|
{
|
||||||
|
my ($data) = @_;
|
||||||
|
my $len = length($data);
|
||||||
|
$data = chr($len&0xff) . chr(int($len/256)) . $data;
|
||||||
|
|
||||||
|
my $out = pack('H*', "0200");
|
||||||
|
my $crc = 0x8c27;
|
||||||
|
for(my $l = 0; $l < $len+2; $l++) {
|
||||||
|
my $b = ord(substr($data,$l,1));
|
||||||
|
$crc = EmCrc($crc, 0x10) if($b==0x02 || $b==0x03 || $b==0x10);
|
||||||
|
$crc = EmCrc($crc, $b);
|
||||||
|
$out .= EmEsc($b);
|
||||||
|
}
|
||||||
|
$out .= EmEsc($crc&0xff);
|
||||||
|
$out .= EmEsc($crc/256);
|
||||||
|
$out .= chr(0x03);
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
# This is the only
|
||||||
|
sub
|
||||||
|
EmGetData($$)
|
||||||
|
{
|
||||||
|
my ($dev, $d) = @_;
|
||||||
|
$d = EmMakeMsg(pack('H*', $d));
|
||||||
|
|
||||||
|
my $serport = new Device::SerialPort ($dev);
|
||||||
|
die "Can't open $dev: $!\n" if(!$serport);
|
||||||
|
$serport->reset_error();
|
||||||
|
$serport->baudrate(38400);
|
||||||
|
$serport->databits(8);
|
||||||
|
$serport->parity('none');
|
||||||
|
$serport->stopbits(1);
|
||||||
|
$serport->handshake('none');
|
||||||
|
|
||||||
|
Log 5, "EM: Sending " . unpack('H*', $d) . "\n";
|
||||||
|
|
||||||
|
my $rm = "EM timeout reading the answer";
|
||||||
|
for(my $rep = 0; $rep < 3; $rep++) {
|
||||||
|
|
||||||
|
$serport->write($d);
|
||||||
|
|
||||||
|
my $retval = "";
|
||||||
|
my $esc = 0;
|
||||||
|
my $started = 0;
|
||||||
|
my $complete = 0;
|
||||||
|
for(;;) {
|
||||||
|
my ($rout, $rin) = ('', '');
|
||||||
|
vec($rin, $serport->FILENO, 1) = 1;
|
||||||
|
my $nfound = select($rout=$rin, undef, undef, 1.0);
|
||||||
|
|
||||||
|
if($nfound < 0) {
|
||||||
|
$rm = "EM Select error $nfound / $!";
|
||||||
|
goto DONE;
|
||||||
|
}
|
||||||
|
last if($nfound == 0);
|
||||||
|
|
||||||
|
my $buf = $serport->input();
|
||||||
|
if(!defined($buf) || length($buf) == 0) {
|
||||||
|
$rm = "EM EOF on $dev";
|
||||||
|
goto DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(my $i = 0; $i < length($buf); $i++) {
|
||||||
|
my $b = ord(substr($buf,$i,1));
|
||||||
|
|
||||||
|
if(!$started && $b != 0x02) { next; }
|
||||||
|
$started = 1;
|
||||||
|
if($esc) { $retval .= chr($b); $esc = 0; next; }
|
||||||
|
if($b == 0x10) { $esc = 1; next; }
|
||||||
|
$retval .= chr($b);
|
||||||
|
if($b == 0x03) { $complete = 1; last; }
|
||||||
|
}
|
||||||
|
|
||||||
|
if($complete) {
|
||||||
|
my $l = length($retval);
|
||||||
|
if($l < 8) { $rm = "EM Msg too short"; goto DONE; }
|
||||||
|
if(b($retval,1) != 0) { $rm = "EM Bad second byte"; goto DONE; }
|
||||||
|
if(w($retval,2) != $l-7) { $rm = "EM Length mismatch"; goto DONE; }
|
||||||
|
if(!EmCrcCheck($retval,$l-7)) { $rm = "EM Bad CRC"; goto DONE; }
|
||||||
|
return substr($retval, 4, $l-7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DONE:
|
||||||
|
$serport->close();
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
165
FHEM/61_EMWZ.pm
Executable file
165
FHEM/61_EMWZ.pm
Executable file
@ -0,0 +1,165 @@
|
|||||||
|
##############################################
|
||||||
|
package main;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Time::HiRes qw(gettimeofday);
|
||||||
|
|
||||||
|
sub EMWZ_Get($@);
|
||||||
|
sub EMWZ_Set($@);
|
||||||
|
sub EMWZ_Define($$);
|
||||||
|
sub EMWZ_GetStatus($);
|
||||||
|
|
||||||
|
###################################
|
||||||
|
sub
|
||||||
|
EMWZ_Initialize($)
|
||||||
|
{
|
||||||
|
my ($hash) = @_;
|
||||||
|
|
||||||
|
$hash->{GetFn} = "EMWZ_Get";
|
||||||
|
$hash->{SetFn} = "EMWZ_Set";
|
||||||
|
$hash->{DefFn} = "EMWZ_Define";
|
||||||
|
|
||||||
|
$hash->{AttrList} = "dummy:1,0 model;EM1000WZ loglevel:0,1,2,3,4,5,6";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
###################################
|
||||||
|
sub
|
||||||
|
EMWZ_GetStatus($)
|
||||||
|
{
|
||||||
|
my ($hash) = @_;
|
||||||
|
|
||||||
|
if(!$hash->{LOCAL}) {
|
||||||
|
InternalTimer(gettimeofday()+300, "EMWZ_GetStatus", $hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
my $dnr = $hash->{DEVNR};
|
||||||
|
my $d = IOWrite($hash, sprintf("7a%02x", $dnr-1));
|
||||||
|
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
|
if($d eq ((pack('H*',"00") x 45) . pack('H*',"FF") x 6)) {
|
||||||
|
my $msg = "EMWZ no device no. $dnr present";
|
||||||
|
Log GetLogLevel($name,2), $msg;
|
||||||
|
return $msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $pulses=w($d,13);
|
||||||
|
my $ec=w($d,49) / 10;
|
||||||
|
if($ec <= 0) {
|
||||||
|
my $msg = "EMWZ read error";
|
||||||
|
Log GetLogLevel($name,2), $msg;
|
||||||
|
return $msg;
|
||||||
|
}
|
||||||
|
my $cur_energy = $pulses / $ec; # ec = U/kWh
|
||||||
|
my $cur_power = $cur_energy / 5 * 60; # 5minute interval scaled to 1h
|
||||||
|
|
||||||
|
if($cur_power > 100) {
|
||||||
|
my $msg = "EMWZ Bogus reading: curr. power is reported to be $cur_power";
|
||||||
|
Log GetLogLevel($name,2), $msg;
|
||||||
|
return $msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
my %vals;
|
||||||
|
$vals{"5min_pulses"} = $pulses;
|
||||||
|
$vals{"energy"} = sprintf("%0.3f", $cur_energy);
|
||||||
|
$vals{"power"} = sprintf("%.3f", $cur_power);
|
||||||
|
$vals{"alarm_PA"} = w($d,45) . " Watt";
|
||||||
|
$vals{"price_CF"} = sprintf("%.3f", w($d,47)/10000);
|
||||||
|
$vals{"RperKW_EC"} = $ec;
|
||||||
|
|
||||||
|
my $tn = TimeNow();
|
||||||
|
my $idx = 0;
|
||||||
|
foreach my $k (keys %vals) {
|
||||||
|
my $v = $vals{$k};
|
||||||
|
$hash->{CHANGED}[$idx++] = "$k: $v";
|
||||||
|
$hash->{READINGS}{$k}{TIME} = $tn;
|
||||||
|
$hash->{READINGS}{$k}{VAL} = $v
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$hash->{LOCAL}) {
|
||||||
|
DoTrigger($name, undef) if($init_done);
|
||||||
|
}
|
||||||
|
|
||||||
|
$hash->{STATE} = "$cur_power kWh";
|
||||||
|
|
||||||
|
return $hash->{STATE};
|
||||||
|
}
|
||||||
|
|
||||||
|
###################################
|
||||||
|
sub
|
||||||
|
EMWZ_Get($@)
|
||||||
|
{
|
||||||
|
my ($hash, @a) = @_;
|
||||||
|
|
||||||
|
return "argument is missing" if(int(@a) != 2);
|
||||||
|
|
||||||
|
my $d = $hash->{DEVNR};
|
||||||
|
my $msg;
|
||||||
|
|
||||||
|
if($a[1] ne "status") {
|
||||||
|
return "unknown get value, valid is status";
|
||||||
|
}
|
||||||
|
$hash->{LOCAL} = 1;
|
||||||
|
my $v = EMWZ_GetStatus($hash);
|
||||||
|
delete $hash->{LOCAL};
|
||||||
|
|
||||||
|
return "$a[0] $a[1] => $v";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub
|
||||||
|
EMWZ_Set($@)
|
||||||
|
{
|
||||||
|
my ($hash, @a) = @_;
|
||||||
|
|
||||||
|
return "argument is missing" if(int(@a) != 3);
|
||||||
|
|
||||||
|
my $v = $a[2];
|
||||||
|
my $d = $hash->{DEVNR};
|
||||||
|
my $msg;
|
||||||
|
|
||||||
|
if($a[1] eq "price") {
|
||||||
|
$v *= 10000; # Make display and input the same
|
||||||
|
$msg = sprintf("79%02x2f02%02x%02x", $d-1, $v%256, int($v/256));
|
||||||
|
} elsif($a[1] eq "alarm") {
|
||||||
|
$msg = sprintf("79%02x2d02%02x%02x", $d-1, $v%256, int($v/256));
|
||||||
|
} elsif($a[1] eq "rperkw") {
|
||||||
|
$v *= 10; # Make display and input the same
|
||||||
|
$msg = sprintf("79%02x3102%02x%02x", $d-1, $v%256, int($v/256));
|
||||||
|
} else {
|
||||||
|
return "unknown set value, use one of price,alarm,rperkw";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $ret = IOWrite($hash, $msg);
|
||||||
|
if(ord(substr($ret,0,1)) != 6) {
|
||||||
|
$ret = "EMWZ Error occured: " . unpack('H*', $ret);
|
||||||
|
Log GetLogLevel($hash->{NAME},2), $ret;
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
#############################
|
||||||
|
sub
|
||||||
|
EMWZ_Define($$)
|
||||||
|
{
|
||||||
|
my ($hash, $def) = @_;
|
||||||
|
my @a = split("[ \t][ \t]*", $def);
|
||||||
|
|
||||||
|
return "syntax: define <name> EMWZ devicenumber"
|
||||||
|
if(@a != 3 || $a[2] !~ m,^[1-4]$,);
|
||||||
|
$hash->{DEVNR} = $a[2];
|
||||||
|
AssignIoPort($hash);
|
||||||
|
|
||||||
|
|
||||||
|
# InternalTimer blocks if init_done is not true
|
||||||
|
my $oid = $init_done;
|
||||||
|
$init_done = 1;
|
||||||
|
EMWZ_GetStatus($hash);
|
||||||
|
$init_done = $oid;
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
2
HISTORY
2
HISTORY
@ -98,3 +98,5 @@
|
|||||||
- Rudi, Sun May 27 12:51:52 MEST 2007
|
- Rudi, Sun May 27 12:51:52 MEST 2007
|
||||||
- Archiving FileLogs. Added fhemweb.pl (pgm2) code, to show logs from the
|
- Archiving FileLogs. Added fhemweb.pl (pgm2) code, to show logs from the
|
||||||
archive directory. See the attributes archivedir/archivecmd.
|
archive directory. See the attributes archivedir/archivecmd.
|
||||||
|
- Added EM1010PC suppoort (right now only with EM1000WZ). Support added
|
||||||
|
for displaying logs in the fhemweb.pl (webfrontends/pgm2)
|
||||||
|
@ -647,6 +647,44 @@ split in multiple lines<br><br>
|
|||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
<a name="EM"></a>
|
||||||
|
<h4>Type EM</h4>
|
||||||
|
<ul>
|
||||||
|
<code>define <name> EM <em1010pc-device></code>
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
Define a EM1010PC USB device. From the software point of view there should
|
||||||
|
be no problems if you attach/define more than one EM1010PC, but it is
|
||||||
|
unknown if the low-level radio protocol supports this.<br> Currently there
|
||||||
|
is no way to read the internal log of the EM1010PC, use the program
|
||||||
|
em1010.pl in the contrib directory for this purpose.<br><br>
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
<ul>
|
||||||
|
<code>define em EM /dev/elv_em1010pc</code><br>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<a name="EMWZ"></a>
|
||||||
|
<h4>Type EMWZ</h4>
|
||||||
|
<ul>
|
||||||
|
<code>define <name> EMWZ <device-number></code>
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
Define up two 4 EM1000WZ attached to the EM1010PC. The device number must
|
||||||
|
be between 1 and 4 (else you have a differnt device connected to the
|
||||||
|
EM1010PC). Defining an EMWZ will schedule an internal task, which reads the
|
||||||
|
status of the device every 5 minutes, and triggers notify/filelog commands.
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
<ul>
|
||||||
|
<code>define emwz EMWZ 1</code><br>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
<a name="FileLog"></a>
|
<a name="FileLog"></a>
|
||||||
<h4>Type FileLog</h4>
|
<h4>Type FileLog</h4>
|
||||||
@ -877,8 +915,6 @@ split in multiple lines<br><br>
|
|||||||
fhtbuf</pre>
|
fhtbuf</pre>
|
||||||
Notes:
|
Notes:
|
||||||
<ul>
|
<ul>
|
||||||
<li>There is only one FHZ device (called FHZ), it is created automatically
|
|
||||||
at startup. </li>
|
|
||||||
<li>The mentioned codes are needed for initializing the FHZ1X00</li>
|
<li>The mentioned codes are needed for initializing the FHZ1X00</li>
|
||||||
<li>The answer for a command is also displayed by <code>list FHZ</code>
|
<li>The answer for a command is also displayed by <code>list FHZ</code>
|
||||||
</li>
|
</li>
|
||||||
@ -890,6 +926,20 @@ split in multiple lines<br><br>
|
|||||||
bytes).</code></li>
|
bytes).</code></li>
|
||||||
</ul>
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<h4>Type EM:</h4>
|
||||||
|
<ul>
|
||||||
|
<code>get EM <value></code>
|
||||||
|
<br><br>
|
||||||
|
where <code>value</code> is either version or time.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h4>Type EMWZ:</h4>
|
||||||
|
<ul>
|
||||||
|
<code>get EMWZ status</code>
|
||||||
|
<br><br>
|
||||||
|
This is the same command which is scheduled every 5 minutes internally.
|
||||||
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
@ -1289,6 +1339,28 @@ split in multiple lines<br><br>
|
|||||||
Set some WS300 configuration parameters.
|
Set some WS300 configuration parameters.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<a name="EMWZset"></a>
|
||||||
|
<h4>Type EMWZ:</h4>
|
||||||
|
<ul>
|
||||||
|
<code>set EMWZdevice <param> <value><br><br>
|
||||||
|
where param is one of:
|
||||||
|
<ul>
|
||||||
|
<li>rperkw<br>
|
||||||
|
Number of rotations for a KiloWatt of the EM1000WZ device (actually
|
||||||
|
of the device where the EM1000WZ is attached to). Without setting
|
||||||
|
this correctly, all other readings will be incorrect.
|
||||||
|
<li>alarm<br>
|
||||||
|
Alarm in WATT. if you forget to set it, the default value is
|
||||||
|
rediculously low (random), and if a value above this threshold is
|
||||||
|
received, the EM1010PC will start beeping once every minute. It can
|
||||||
|
be very annoying.
|
||||||
|
<li>price<br>
|
||||||
|
The price of one KW in EURO (use e.g. 0.20 for 20 Cents). It is used
|
||||||
|
only on the EM1010PC display, it is of no interest for FHEM.
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,34 +16,6 @@ fhz1000.pl
|
|||||||
<h2>News (as of =DATE=, Version =VERS=)</h2>
|
<h2>News (as of =DATE=, Version =VERS=)</h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>bugfix: deny at +{3}... (only +*{3} allowed), reported by Bernd, 25.01
|
|
||||||
<li>bugfix: allow numbers greater then 9 in at +{<number>}
|
|
||||||
<li>feature: new 50_WS300.pm from Martin (bugfix + rain statistics, 26.01)
|
|
||||||
<li>feature: renamed fhz1000 to fhem
|
|
||||||
<li>feature: added HISTORY and README.DEV
|
|
||||||
<li>doc: Added description of attribute "model".
|
|
||||||
<li>bugfix: delete the pidfile when terminating. (reported by Martin and Peter)
|
|
||||||
<li>feature: attribute showtime in web-pgm2 (show time instead of state)
|
|
||||||
<li>feature: defattr (default attribute for following defines)
|
|
||||||
<li>feature: added em1010.pl to the contrib directory
|
|
||||||
<li>doc: added linux.html (multiple devices, udev-links)
|
|
||||||
<li>REORGANIZATION:
|
|
||||||
<ul>
|
|
||||||
<li>at/notify "renamed" to "define <name> at/notify"
|
|
||||||
<li>logfile/modpath/pidfile/port/verbose "renamed" to "attr global xxx"
|
|
||||||
<li>savefile renamed to "attr global statefile"
|
|
||||||
<li>save command added, it writes the configfile and the statefile
|
|
||||||
<li>delattr added
|
|
||||||
<li>list/xmllist format changed
|
|
||||||
<li>disable attribute for at/notify/filelog</li>
|
|
||||||
See HISTORY for details and reasoning and the <a href="faq.html">FAQ</a>
|
|
||||||
for an uprading HOWTO.
|
|
||||||
</ul>
|
|
||||||
<li>added rename command
|
|
||||||
<li>webpgm2 adapted to the new syntax, added device specific attribute
|
|
||||||
and "set" support, gnuplot files are configurable, links to the
|
|
||||||
documentation added.
|
|
||||||
<li>bugfix: more thorough serial line initialization
|
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@ -65,6 +37,7 @@ Currently implemented features:<br>
|
|||||||
<li>reading HMS data (HMS100-T,-TF,-WD,-MG,-TFK and RM100-2)</li>
|
<li>reading HMS data (HMS100-T,-TF,-WD,-MG,-TFK and RM100-2)</li>
|
||||||
<li>reading KS300 data</li>
|
<li>reading KS300 data</li>
|
||||||
<li>reading WS300 data</li>
|
<li>reading WS300 data</li>
|
||||||
|
<li>reading EM1010PC/EM1000WZ data</li>
|
||||||
<li>logging events to files (or database), with regexp filters</li>
|
<li>logging events to files (or database), with regexp filters</li>
|
||||||
<li>notifying external programs or internal modules when receiving certain
|
<li>notifying external programs or internal modules when receiving certain
|
||||||
events</li>
|
events</li>
|
||||||
|
6
fhem.pl
6
fhem.pl
@ -119,6 +119,7 @@ use vars qw(%attr); # Attributes
|
|||||||
use vars qw(%value); # Current values, see commandref.html
|
use vars qw(%value); # Current values, see commandref.html
|
||||||
use vars qw(%oldvalue); # Old values, see commandref.html
|
use vars qw(%oldvalue); # Old values, see commandref.html
|
||||||
use vars qw($nextat); # used by the at module
|
use vars qw($nextat); # used by the at module
|
||||||
|
use vars qw($init_done); #
|
||||||
|
|
||||||
my $server; # Server socket
|
my $server; # Server socket
|
||||||
my $currlogfile; # logfile, without wildcards
|
my $currlogfile; # logfile, without wildcards
|
||||||
@ -132,10 +133,10 @@ my $devcount = 0; # To sort the devices
|
|||||||
my %defattr; # Default attributes
|
my %defattr; # Default attributes
|
||||||
my %intAt; # Internal at timer hash.
|
my %intAt; # Internal at timer hash.
|
||||||
my $intAtCnt=0;
|
my $intAtCnt=0;
|
||||||
my $init_done = 0;
|
|
||||||
my $reread_active = 0;
|
my $reread_active = 0;
|
||||||
my $AttrList = "room comment";
|
my $AttrList = "room comment";
|
||||||
|
|
||||||
|
$init_done = 0;
|
||||||
|
|
||||||
$modules{_internal_}{ORDER} = -1;
|
$modules{_internal_}{ORDER} = -1;
|
||||||
$modules{_internal_}{AttrList} = "configfile logfile lastinclude modpath " .
|
$modules{_internal_}{AttrList} = "configfile logfile lastinclude modpath " .
|
||||||
@ -395,8 +396,9 @@ IOWrite($@)
|
|||||||
}
|
}
|
||||||
|
|
||||||
no strict "refs";
|
no strict "refs";
|
||||||
&{$modules{$iohash->{TYPE}}{WriteFn}}($iohash, @a);
|
my $ret = &{$modules{$iohash->{TYPE}}{WriteFn}}($iohash, @a);
|
||||||
use strict "refs";
|
use strict "refs";
|
||||||
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#Sun May 27 10:25:14 2007
|
#Sun May 27 13:57:55 2007
|
||||||
setstate FHZ fhtbuf: 1c
|
setstate FHZ fhtbuf: 1c
|
||||||
setstate FHZ 2006-02-12 14:03:39 fhtbuf 23
|
setstate FHZ 2006-02-12 14:03:39 fhtbuf 23
|
||||||
setstate FHZ 2006-03-26 08:47:36 init2 deadbeefdeadbe
|
setstate FHZ 2006-03-26 08:47:36 init2 deadbeefdeadbe
|
||||||
@ -32,11 +32,13 @@ setstate fl 2006-03-26 08:50:55 unknown_85 4
|
|||||||
setstate fl 2006-03-26 08:50:46 wed-from1 06:00
|
setstate fl 2006-03-26 08:50:46 wed-from1 06:00
|
||||||
setstate fl 2006-03-26 08:50:46 wed-to1 23:00
|
setstate fl 2006-03-26 08:50:46 wed-to1 23:00
|
||||||
setstate fl 2006-03-26 08:50:55 windowopen-temp 12.0 (Celsius)
|
setstate fl 2006-03-26 08:50:55 windowopen-temp 12.0 (Celsius)
|
||||||
|
setstate fllog active
|
||||||
setstate floor.lamp ???
|
setstate floor.lamp ???
|
||||||
setstate global <no definition>
|
setstate global <no definition>
|
||||||
setstate marqee on
|
setstate marqee on
|
||||||
setstate marqee 2006-04-01 12:46:02 state on
|
setstate marqee 2006-04-01 12:46:02 state on
|
||||||
setstate n_btn4 disabled
|
setstate n_btn4 disabled
|
||||||
|
setstate outlog active
|
||||||
setstate tf1 T: 20.3 H: 31.3 Bat: ok
|
setstate tf1 T: 20.3 H: 31.3 Bat: ok
|
||||||
setstate tf1 2006-04-11 09:48:48 battery Bat: ok
|
setstate tf1 2006-04-11 09:48:48 battery Bat: ok
|
||||||
setstate tf1 2006-04-11 09:48:48 humidity 31.3 (%)
|
setstate tf1 2006-04-11 09:48:48 humidity 31.3 (%)
|
||||||
@ -68,3 +70,4 @@ setstate wz 2006-03-26 08:52:31 unknown_85 4
|
|||||||
setstate wz 2006-03-26 08:50:36 wed-from1 06:00
|
setstate wz 2006-03-26 08:50:36 wed-from1 06:00
|
||||||
setstate wz 2006-03-26 08:50:36 wed-to1 23:00
|
setstate wz 2006-03-26 08:50:36 wed-to1 23:00
|
||||||
setstate wz 2006-03-26 08:52:31 windowopen-temp 12.0 (Celsius)
|
setstate wz 2006-03-26 08:52:31 windowopen-temp 12.0 (Celsius)
|
||||||
|
setstate wzlog active
|
||||||
|
19
webfrontend/pgm2/em.gplot
Normal file
19
webfrontend/pgm2/em.gplot
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
############################
|
||||||
|
# Display the power reported by the EM1010
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
=================
|
||||||
|
set terminal png
|
||||||
|
set output '<OUT>.png'
|
||||||
|
set xdata time
|
||||||
|
set timefmt "%Y-%m-%d_%H:%M:%S"
|
||||||
|
set xlabel " "
|
||||||
|
|
||||||
|
set ytics nomirror
|
||||||
|
set y2tics
|
||||||
|
set title '<IN>'
|
||||||
|
set grid
|
||||||
|
set ylabel "KW"
|
||||||
|
|
||||||
|
plot "<IN>" using 1:4 title 'Power' with lines
|
Loading…
x
Reference in New Issue
Block a user