Stromzähler ACE3000 Modul OBIS

Begonnen von hugo, 07 November 2016, 09:33:24

Vorheriges Thema - Nächstes Thema

hugo

Hallo, habe eien
Stromzähler ACE300 Typ 260 den ich derzeit mit dem IR-Kopf (Volkszähler) und einem Perlscript auslese.
Jetzt wollte ich das über FHEM realisieren um auch Auswertungen anstellen zu können.
Meine Definitiondefine Strom OBIS /dev/ttyUSB0@@300,7,E,1 VSM102 allerdings erhalte ich keine Readings.
Den Type VSM102 habe ich genommen, da das Anforderungstelegegramm ähnlich ist.

bestehendes Perlscriptmy $PORT='/dev/ttyUSB0';
my $anforderungstelegramm = "\n/?!\r\n";
use warnings;
use strict;
use utf8;
use Device::SerialPort;

my $tty = new Device::SerialPort($PORT) || die "can't open $PORT: $!";
$tty->baudrate(300)      || die 'fail setting baudrate';
$tty->databits(7)        || die 'fail setting databits';
$tty->stopbits(1)        || die 'fail setting stopbits';
$tty->parity("even")     || die 'fail setting parity';
$tty->write_settings     || die 'fail write settings';
#$tty->debug(1);
my $num_out = $tty->write($anforderungstelegramm);
die "write failed\n" unless ($num_out);
die "write inclomplete\n" unless ($num_out == length($anforderungstelegramm));   
# print "$num_out Bytes written\n";
my ($num_read, $s);
$tty->read_const_time(10);
my @lines;
my $curline = "";
eval {
    local $SIG{ALRM} = sub { die "Timeout beim Lesen von der Schnittstelle!\n" };
    alarm(15);
    while(1) {
        ($num_read, $s) = $tty->read(1);                                         
        $curline .= $s;
        if( $s eq "\n" )
        {
            push @lines, $curline;
            $curline = "";
        }
        last if( scalar(@lines) == 8 );
    }
    alarm(0);
};
if( $@ )
{
    warn $@;
    exit 1;
}
my( $bezug ) = grep { $_ =~ /^1.8./ } @lines;                                   
$bezug = sprintf("%.1f", substr($bezug, 6, 8));                                 
my( $einsp ) = grep { $_ =~ /^2.8./ } @lines;                                   
$einsp = sprintf("%.1f", substr($einsp, 6, 8));                                 
print "Bezug:        " . $now_string . " " . $bezug . " kWh\n";               
print "Einspeisung:  " . $now_string . " " . $einsp . " kWh\n";


Im Logfiel steht folgendes:
2016.11.07 09:04:45 3: Opening Strom device /dev/ttyUSB0
2016.11.07 09:04:45 3: Init done
2016.11.07 09:04:45 3: Strom device opened
2016.11.07 09:04:52 3: Init done
2016.11.07 09:04:52 1: /dev/ttyUSB0 reappeared (Strom)
2016.11.07 09:05:04 1: /dev/ttyUSB0 disconnected, waiting to reappear (Strom)
2016.11.07 09:05:04 3: Init done
2016.11.07 09:05:04 1: /dev/ttyUSB0 reappeared (Strom)

Hat schon jemand dies umgesetzt oder wo liegt bei mir der Fehler?

Raspi 3 mit CUL HM-MOD-UART; nanoCUL
Homematic: HM-SEC-SCo 5x;HM-LC-SW1-BA-PCB 3x;HM-Dis-EP-WM55; HM-LC-SW4-PCB; ARLO;
Somfy RTS Rollo 14x; Alexa; GardenaSmartDevice; Stromzähler(GPIO); shelly1; shelly2.5;Wasserzähler(GPIO);Brennerstuhlsteckdosen;

Frazi

Hallo Hugo,

hab mich die letzten Tage durch die Inbetriebnahme meines Easymeter Zählers über USB-Lesekopf gequält. An deinen Schritt bin ich auch mal hängen geblieben.

Wenn du Hier:
Zitat von: hugo am 07 November 2016, 09:33:24
Meine Definitiondefine Strom OBIS /dev/ttyUSB0@@300,7,E,1 VSM102 allerdings erhalte ich keine Readings.

..nur ein @ verwendest solltest du bis in den Parser kommen und Readings erhalten. Den musste ich für meinen Zähler Patchen. Hoffe bei dir klappt es so.

hugo

Hallo Franzi,
Danke für die Antwort, hatte das Problem inzwischen schon gelöst.
Raspi 3 mit CUL HM-MOD-UART; nanoCUL
Homematic: HM-SEC-SCo 5x;HM-LC-SW1-BA-PCB 3x;HM-Dis-EP-WM55; HM-LC-SW4-PCB; ARLO;
Somfy RTS Rollo 14x; Alexa; GardenaSmartDevice; Stromzähler(GPIO); shelly1; shelly2.5;Wasserzähler(GPIO);Brennerstuhlsteckdosen;

sven-voss

Hallo,
auch ich habe einen ITRON ACE3000 Type 260 C20D R1 A und möchte diesen gern mit FHEM direkt auslesen (ohne volkszaehler).

Funktioniert das define wie hier beschrieben mit dem OBIS Modul?
Oder muss ich den Zähler noch anderweitig zum "sprechen" überreden?

Ich würde folgenden IR Kopf verwenden wollen:
https://de.elv.com/elv-bausatz-lesekopf-mit-usb-schnittstelle-fuer-digitale-zaehler-usb-iec-155523?Gads_Shopping_CSS&gclid=EAIaIQobChMIjtfCpfWx7wIVjv93Ch3wgAy3EAQYBCABEgIGZ_D_BwE

Gruß Sven

vestaxb

Ich betreibe meine FHEM Instanz als Docker-Container und habe den USB-Lesekopf im Container bekanntgemacht.

Definiert habe ich meinen USB Lesekopf in FHEM folgendermaßen:

define Strom OBIS /dev/ttyUSB1@300,7,E,1 VSM102

Ich habe neben dem IR-Lesekopf noch einen LaCrosse USB-Stick dranhängen (ist '/dev/ttyUSB0'), daher habe  '/dev/ttyUSB1' zugewiesen. Je nachdem müsste hier ein anderes Gerät gesetzt werden.

Ich habe folgendes meiner 99_myUtils.pm hinzugefügt:

sub Strom () {

my $PORT='/dev/ttyUSB1';
my $anforderungstelegramm = "\n/?!\r\n";
my $now_string = strftime "%H:%M Uhr.", localtime;
use warnings;
use strict;
use utf8;
use Device::SerialPort;

my $tty = new Device::SerialPort($PORT) || die "can't open $PORT: $!";
$tty->baudrate(300)      || die 'fail setting baudrate';
$tty->databits(7)        || die 'fail setting databits';
$tty->stopbits(1)        || die 'fail setting stopbits';
$tty->parity("even")     || die 'fail setting parity';
$tty->write_settings     || die 'fail write settings';
#$tty->debug(1);
my $num_out = $tty->write($anforderungstelegramm);
die "write failed\n" unless ($num_out);
die "write inclomplete\n" unless ($num_out == length($anforderungstelegramm));   
# print "$num_out Bytes written\n";
my ($num_read, $s);
$tty->read_const_time(10);
my @lines;
my $curline = "";
eval {
    local $SIG{ALRM} = sub { die "Timeout beim Lesen von der Schnittstelle!\n" };
    alarm(15);
    while(1) {
        ($num_read, $s) = $tty->read(1);                                         
        $curline .= $s;
        if( $s eq "\n" )
        {
            push @lines, $curline;
            $curline = "";
        }
        last if( scalar(@lines) == 8 );
    }
    alarm(0);
};
if( $@ )
{
    warn $@;
    exit 1;
}
my( $bezug ) = grep { $_ =~ /^1.8./ } @lines;                                   
$bezug = sprintf("%.1f", substr($bezug, 6, 8));                                 
my( $einsp ) = grep { $_ =~ /^2.8./ } @lines;                                   
$einsp = sprintf("%.1f", substr($einsp, 6, 8));                                 
print "Bezug:        " . $now_string . " " . $bezug . " kWh\n";               
print "Einspeisung:  " . $now_string . " " . $einsp . " kWh\n";
}



Ich kann jetzt diese Routine mit Eingabe '{ Strom() }' von in FHEM aufrufen und erhalte im Log auch diesen Eintrag:

Bezug:        19:28 Uhr. 20024.0 kWh
Einspeisung:  19:28 Uhr. 0.0 kWh


Das ist ja schon mal sehr gut.

Doch wie kann ich das dem Device 'Strom' als Reading mitgeben? Und zweite Frage; Gibt es ggf. schon Routinen, die eine Differenz berechnen, sodass ich davon einen Stromverbrauch ableiten kann?

hugo

Hallo vextaxb,
Ich habe meinen Zähler so definiert und mit userreadings gearbeitet. Diese könntest du ja noch erweitern mit dem Verbrauch. Mir reicht ein täglicher Verbrauch und den lese ich kurz vor Mitternacht aus in schreibe die Werte in eine Datei. Bei mir kam es öfters vor, dass der Lesekopf keine richtigen Werte lieferte, deshalb die userreadings mit Der if.defmod Strom OBIS /dev/ttyUSB0@300,7,E,1 VSM102
attr Strom channels {"1.8.0"=>"Bezug","2.8.0"=>"Einspeise"}
attr Strom event-on-change-reading .*
attr Strom group Strom
attr Strom icon measure_power_meter@blue
attr Strom interval 600
attr Strom pollingMode on
attr Strom room Keller
attr Strom stateFormat { "Bezug: " . sprintf("%.1f". "kW" , ReadingsVal("Strom","myBezug",0) - ReadingsVal("Strom","myBezugVortag",0)) . " <br/>Einspeise: " . sprintf("%.1f". "kW" , ReadingsVal("Strom","myEinspeise",0) - ReadingsVal("Strom","myEinspeiseVortag",0)) }
attr Strom userReadings myBezug { if (ReadingsVal("Strom","Bezug",0) < ReadingsVal("Strom","myBezug",0)) { return ReadingsVal("Strom","myBezug",0)} else {return ReadingsVal("Strom","Bezug",0)}}, myEinspeise { if (ReadingsVal("Strom","Einspeise",0) < ReadingsVal("Strom","myEinspeise",0)) { return ReadingsVal("Strom","myEinspeise",0)} else {return ReadingsVal("Strom","Einspeise",0)}}\

attr Strom verbose 3

setstate Strom Bezug: 2.8kW <br/>Einspeise: 1.0kW
setstate Strom 2021-04-22 09:34:09 Bezug 24932.9
setstate Strom 2021-04-22 09:34:08 C.1 1126110052900187
setstate Strom 2021-04-22 09:34:08 C.5.0 1
setstate Strom 2021-04-22 09:34:10 Einspeise 52076.5
setstate Strom 2021-04-22 09:34:06 Version ACE0\3k260V01.18
setstate Strom 2021-04-22 09:34:10 myBezug 24932.9
setstate Strom 2021-04-21 23:50:00 myBezugVortag 24930.1
setstate Strom 2021-04-22 09:34:10 myEinspeise 52076.5
setstate Strom 2021-04-21 23:50:00 myEinspeiseVortag 52075.5
setstate Strom 2021-04-17 18:27:44 state opened


Die Routine für das logging .
sub STROMLOG()
{
   my $now_string = strftime "%Y-%m-%d_%H:%M:%S", localtime;
   my $mBezug = ReadingsVal('Strom','myBezug',0);
   $mBezug = sprintf("%.1f", $mBezug);
   fhem("setreading Strom myBezugVortag " . $mBezug );
   $mBezug =~ s/\./,/;
   my $mEinspeise = ReadingsVal('Strom','myEinspeise',0);
   $mEinspeise = sprintf("%.1f", $mEinspeise );
   fhem("setreading Strom myEinspeiseVortag " . $mEinspeise);
   $mEinspeise =~ s/\./,/;
   my $mOst = ReadingsVal('CN.SolarOst','mykW',0);
   $mOst = sprintf("%.1f", $mOst );
   $mOst =~ s/\./,/;
   my $mWest  = ReadingsVal('CN.SolarWest','mykW',0);
   $mWest  = sprintf("%.1f", $mWest  );
   $mWest =~ s/\./,/;
   open (DATEI, ">>/opt/fhem/log/STROMLOG.txt") or die $!;
     print DATEI $now_string . " Bezug: " . $mBezug . " Einspeise: " . $mEinspeise . " Ost: " . $mOst . " West: " . $mWest . "\n";
   close (DATEI);
}

Raspi 3 mit CUL HM-MOD-UART; nanoCUL
Homematic: HM-SEC-SCo 5x;HM-LC-SW1-BA-PCB 3x;HM-Dis-EP-WM55; HM-LC-SW4-PCB; ARLO;
Somfy RTS Rollo 14x; Alexa; GardenaSmartDevice; Stromzähler(GPIO); shelly1; shelly2.5;Wasserzähler(GPIO);Brennerstuhlsteckdosen;