Originally posted by: <email address deleted>
Moin!
Mit Hilfe eines Kumpels habe ich mich inzwischen wieder an den EHZ-
Stromzähler gemacht, der seriell an meinen Server angebunden ist. FHEM
steht ja auch für Friendly ... Energy Measurement und für EHZ gibt's
wohl noch nichts. Das Teil sendet ascii-Datensätze, etwa alle zwei
Sekunden einen. Der Inhalt ist herstellerabhängig. Einige geben die
Leistung aus, andere nicht etc.
Das folgende Skript gibt bei mir grundsätzlich alle Werte korrekt aus
(wobei ich nur die erste Phase brauche, ist ein Solarzähler), nur
führt es leider beim Einlesevorgang von der seriellen zu 100% Last.
Normalerweise ist der Spuk nach ein oder zwei Sekunden wieder vorbei,
aber fhem kommt wohl ins Stolpern und steht irgendwann. Meine Frau
beschwerte sich deshalb gestern, dass ein Lichtschalter abgestürzt
sei :) Ich brauche also Eure Hilfe. Irgendwie scheint man nämlich
RS232 indirekt auslesen zu können (nur den FIFO) und hat dann kaum
Last - aber ich verstehe nicht ansatzweise wie...
Nachfolgend das vorhandene Skript, das direkt auf die serielle
Schnittstelle greift. Was muss ich machen, um die FIFOs zu lesen?
Danke vielmals für Eure Hilfe!
Georg
-
package main;
use strict;
use warnings;
use Time::HiRes qw(gettimeofday);
my %gets = (
"Zaehlernummer" => "",
"Zaehlerstand" => "",
"StromL1" => "",
"StromL2" => "",
"StromL3" => "",
"LeistungL1" => "",
"LeistungL2" => "",
"LeistungL3" => "",
"SpannungL1" => "",
"SpannungL2" => "",
"SpannungL3" => "",
);
#####################################
sub
EHZ_Initialize($)
{
my ($hash) = @_;
$hash->{DefFn} = "EHZ_Define";
$hash->{UndefFn} = "EHZ_Undef";
$hash->{GetFn} = "EHZ_Get";
$hash->{AttrList}= "loglevel:0,1,2,3,4,5";
}
#####################################
sub
EHZ_Get($@)
{
my ($hash, @a) = @_;
# check syntax
return "argument is missing @a"
if(int(@a) != 2);
# check argument
return "Unknown argument $a[1], choose one of ".join(",", sort keys
%gets)
if(!defined($gets{$a[1]}));
# define vars
my $value;
# get value
$hash->{LOCAL} = 1;
$value = EHZ_GetUpdate($hash,$a[1]);
#$value = time();
delete $hash->{LOCAL};
my $reading = $a[1];
if(defined($hash->{READINGS}{$reading})) {
$value = $hash->{READINGS}{$reading}{VAL};
}
return "$a[0] $reading => $value";
}
#####################################
sub
EHZ_Define($$)
{
my ($hash, $def) = @_;
# define EHZ [interval]
# e.g.: define MyEHZ EHZ /dev/ttyUSB2 60
my @a = split("[ \t][ \t]*", $def);
return "syntax: define EHZ [interval]"
if(int(@a) < 3 && int(@a) > 4);
$hash->{STATE} = "Initialized";
my $name = $a[0];
my $port = $a[2];
my $interval = 3000;
if(int(@a)==4) { $interval= $a[3]; }
$hash->{PORT} = $port;
$hash->{INTERVAL} = $interval;
# $hash->{READINGS}{last_reading}{TIME}= TimeNow();
# $hash->{READINGS}{last_reading}{VAL}= "none";
$hash->{LOCAL} = 1;
EHZ_GetUpdate($hash);
delete $hash->{LOCAL};
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "EHZ_GetUpdate",
$hash, 0);
return undef;
}
#####################################
sub
EHZ_Undef($$)
{
my ($hash, $name) = @_;
delete($modules{EHZ}{defptr}{$hash->{NAME}});
RemoveInternalTimer($hash);
return undef;
}
###################################
sub EHZ_UpdateReading($$$$) {
my ($hash,$key,$tn,$value)= @_;
return 0 if(!defined($value) || $value eq "");
my $reading= $key;
my $r= $hash->{READINGS};
$r->{$reading}{TIME}= $tn;
$r->{$reading}{VAL} = $value;
# Log 5, "Weather $hash->{NAME}: $reading= $value";
return 1;
}
#####################################
sub
EHZ_GetUpdate($$)
{
my ($hash) = @_;
if(!$hash->{LOCAL}) {
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "EHZ_GetUpdate",
$hash, 1);
}
my $name = $hash->{NAME};
# time
my $tn = TimeNow();
my $StartString;
my $EndeString;
$StartString = "/HAG5eHZ_sernr";
$EndeString = "!";
# 1200 Zeichen vom Comport auslesen
use Device::SerialPort;
#log 5, "Port $hash->{Port}: trying to read";
my $port = Device::SerialPort->new("/dev/ttyUSB2");
#my $port = Device::SerialPort->new($hash->{Port});
return undef if(!$port);
$port->databits(7);
$port->baudrate(9600);
$port->parity("even");
$port->stopbits(1);
$port->handshake("none");
$port->write_settings;
my $input;
my $bytein;
$input="";
while(length($input) < 1200) {
my $bytein = $port->read(255);
if ($bytein ne "") {
$input.=$bytein;
}
}
# Genau ein Datensatz herausfischen
my $pos1;
my $pos2;
my $datensatz;
$pos1 = index($input,$StartString,0);
$pos2 = index($input,$EndeString,$pos1);
$datensatz = substr($input, $pos1,$pos2-$pos1);
# Datensatz in Array umwandeln (Vorsicht, fängt bei 0 an zu zählen!)
my @zeile;
@zeile=split(/\n/,$datensatz);
# Werte lesen und ausgeben
# Zaehlernummer
my $Zaehlernummer;
$Zaehlernummer = &GetWertEHZ($zeile[2]);
EHZ_UpdateReading($hash,"Zaehlernummer",$tn,$Zaehlernummer);
# Zaehlerstand
my $zaehlerstand;
$zaehlerstand = &GetWertEHZ($zeile[3]);
EHZ_UpdateReading($hash,"Zaehlerstand",$tn,$zaehlerstand);
my $SpannungL;
# Spannung L1
$SpannungL = &GetWertEHZ($zeile[6]);
$SpannungL = substr($SpannungL,0,length($SpannungL)-2);
EHZ_UpdateReading($hash,"SpannungL1",$tn,$SpannungL);
# Spannung L2
$SpannungL = &GetWertEHZ($zeile[7]);
$SpannungL = substr($SpannungL,0,length($SpannungL)-2);
EHZ_UpdateReading($hash,"SpannungL1",$tn,$SpannungL);
# Spannung L3
$SpannungL = &GetWertEHZ($zeile[8]);
$SpannungL = substr($SpannungL,0,length($SpannungL)-2);
EHZ_UpdateReading($hash,"SpannungL1",$tn,$SpannungL);
my $StromL;
# Strom L1
$StromL = &GetWertEHZ($zeile[9]);
$StromL = substr($StromL,0,length($StromL)-2);
EHZ_UpdateReading($hash,"StromL1",$tn,$StromL);
# Strom L2
$StromL = &GetWertEHZ($zeile[10]);
$StromL = substr($StromL,0,length($StromL)-2);
EHZ_UpdateReading($hash,"StromL2",$tn,$StromL);
# Strom L3
$StromL = &GetWertEHZ($zeile[11]);
$StromL = substr($StromL,0,length($StromL)-2);
EHZ_UpdateReading($hash,"StromL3",$tn,$StromL);
my $LeistungL;
# Leistung L1
$LeistungL = &GetWertEHZ($zeile[12]);
$LeistungL = substr($LeistungL,1,length($LeistungL)-3);
EHZ_UpdateReading($hash,"LeistungL1",$tn,$LeistungL);
# Leistung L2
$LeistungL = &GetWertEHZ($zeile[13]);
$LeistungL = substr($LeistungL,1,length($LeistungL)-3);
EHZ_UpdateReading($hash,"LeistungL1",$tn,$LeistungL);
# Leistung L3
$LeistungL = &GetWertEHZ($zeile[14]);
$LeistungL = substr($LeistungL,1,length($LeistungL)-3);
EHZ_UpdateReading($hash,"LeistungL1",$tn,$LeistungL);
if(!$hash->{LOCAL}) {
DoTrigger($name, undef) if($init_done);
}
return 1;
}
#####################################
sub
GetWertEHZ ($)
{
my $pos1;
my $pos2;
my $wert;
$pos1 = index($_[0],"(",0);
$pos2 = index($_[0],")",$pos1);
$wert = substr($_[0],($pos1+1), $pos2-$pos1-1);
return $wert;
}
1;
--
To unsubscribe from this group, send email to
fhem-users+unsubscribe@googlegroups.com