Benutzer-Werkzeuge

Webseiten-Werkzeuge


hardware:channels:meters:power:drs155m

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
drs155m [2013/08/24 12:27] – [offene Punkte] ollirhardware:channels:meters:power:drs155m [2018/03/25 10:58] (aktuell) jau
Zeile 1: Zeile 1:
-====== Hutschienenzähler DRS110M ====== +#redirect /hardware/channels/meters/power/eastron_drs155m 
- +{{indexmenu_n>99}}
-Das Gerät ist ein Zähler mit einfacher Baubreite und Hutschinenmontage. Der Vorteil ist die integrierte RS485 Schnittstelle, die man elektronisch auslesen kann. +
- +
-Das Gerät gibt es bei Amazon für 30EUR.  +
- +
-{{ :2013-07-28_15.36.13.jpg?200 |}} +
- +
-====== Anschluss an den Computer: RS485 - USB Wandler ====== +
- +
-Für den Anschluss am Computer benötigt man eine RS485-USB Adapter. Ich habe hierzu von Ebay einen Adapter für 15EUR gekauft. +
- +
-Bei Ebay nach "RS-485 Adapter: USB auf RS485 Power One Aurora Inverter Web Data Logger" oder "RS-485 Interface Konverter Adapter: USB auf RS485" suchen. +
- +
-Elektrisch wird der Adapter mit dem Stromzähler A<->A , B<->B und G<->G verbunden. Ich habe keine Terminierung verwendet, bei mir ist das Kabel aber auch nur 50cm lang. +
- +
-====== Anschluss an den Computer: Software ====== +
- +
-Für den Zähler habe ich keine richtige Software zum auslesen gefunden. Im Internet kursieren einige Scripte in PHP und Python, um den Zähler auszulesen. +
- +
-Da ich ein Perl-Fan bin, habe ich das ganze unter perl zum laufen gebracht. +
- +
-Es wird noch ein perl-Paket für die serielle Schnittstelle benötigt: +
-<code> +
-„apt-get install libdevice-serialport-perl“ +
-</code> +
- +
-Das script gibt die Zählerdaten auf der Console aus, eine Speicherung in die Datenbank erfolgt auch. Zuvor muss über das Webinterface der Kanal angelegt sein. +
- +
-====== Hier dann das Perl-script ====== +
- +
-Das Script abspeichern, ausführbar machen. Das Script kann zum testen manuell aufgerufen werden. Falls alles gut läuft kann das Script im Cron zyklisch aufgerufen werden ( crontab -e ). +
- +
-Der serielle Port und die uuid(die uuid bekommt man über das Webinterface von volkszähler) müssen im Script angepasst werden. +
- +
-<code> +
-#!/usr/bin/perl -w +
- +
-# teile von http://www.ip-symcon.de/forum/threads/21407-Stromz%C3%A4hler-mit-RS485/page2 entnommen +
-# 20130802 : ollir +
- +
-use Device::SerialPort; +
- +
- +
-my $port = Device::SerialPort->new("/dev/ttyUSB0") || die $!; +
-$port->baudrate(9600); +
-$port->databits(7); +
-$port->parity("even"); +
-$port->stopbits(1); +
-$port->handshake("none"); +
-$port->write_settings; +
- +
-$port->purge_all(); +
-$port->read_char_time(0);     # don't wait for each character +
-$port->read_const_time(100); # 100 millisecond per unfulfilled "read" call +
- +
-my $serialID = "000000000000";        # auszulesende Zähler-ID (12 Stellen), Standard: "000000000000" +
-my $password = "00000000"; # Standartpasswort +
-my $uuid="84356400-f7b8-11e2-8431-07a5d66d6531"+
- +
-my $verbose = 2 ; +
- +
-# ======================================== +
-sub sendgetserial { +
-  my ($cmd) = @_; +
-  my $count; +
-  my $saw; +
-  my $x; +
- +
-  $port->lookclear; +
-  $port->write( $cmd ); +
- +
-  ($count,$saw)=$port->read(84);   # will read 84 chars +
-  $x=uc(unpack('H*',$saw)); # nach hex wandeln +
- +
-  $cmd =~ s/\n/\\n/mg; +
-  $cmd =~ s/\r/\\r/mg; +
- +
-  $saw =~ s/\n/\\n/mg; +
-  $saw =~ s/\r/\\r/mg; +
- +
-  if ( $verbose>10 ) { +
-    printf "+++ sendserial\n"+
-    print  " CMD: $cmd \n";  # gibt den Befehl in ASCII aus +
-    print  " COUNT: $count \n";  # gibt die Anzahl der empfangenen Daten aus +
-    print  " HEX: $x \n";  # gibt die empfangenen Daten in Hex aus +
-    print  " ASCII: $saw \n";  # gibt die empfangenen Daten aus +
-    printf "--- sendserial\n"+
-  } +
- +
-  return $saw; +
-+
-# ======================================== +
-sub decodeVAL { +
-  my ($val) = @_; +
- +
-  if ( $verbose>10 ) { +
-    printf "+++ decodeVAL\n"+
-    print " val = ( $val ) \n" ; +
-  } +
- +
-  if($val =~ m/\((\d+)\)/) { +
-    if ( $verbose>10 ) { +
-      print " decoded val = $1\n"; +
-      printf " --- decodeVAL\n"+
-    } +
-    return $1; +
-  } +
- +
-  print " val = ( $val ) \n" ; +
-  die "NICHTS gefunden!\n"; +
-  print "NICHTS gefunden!\n"; +
-  return -8888; +
-+
-# ======================================== +
- +
- +
-## Variablen +
-my $cmd; +
-my $res; +
-my %vals = (); +
- +
-# Abfrage der Initialisierung: hier bekommt man die $serialID raus !! +
-print("# INIT 1 #############\n") if ($verbose>8); +
-sendgetserial("/?!\r\n"); +
- +
- +
-# initalisierung ueberprüfen, jetzt mit ID, wenn die ID nicht passt, kommt keine Antwort! +
-print("# INIT 2 #############\n") if ($verbose>8); +
-sendgetserial("/?" . $serialID . "!\r\n"); +
- +
- +
-# ACK / Option Select Message senden ('Programming Mode'+
-# der programming modus muss auch bei einer einfachen Strom,Spgs-Abfrage gesetzt werden +
-if (1) { +
-  print("# PROGRAMMING MODE #############\n") if ($verbose>8); +
-  $cmd = chr(0x06).chr(0x30).":".chr(0x31).chr(0x0D).chr(0x0A); +
-  sendgetserial( $cmd); +
-  $cmd = chr(0x01)."P1".chr(0x02)."(".$password.")".chr(0x03).chr(0x61); +
-  sendgetserial( $cmd); +
-+
- +
-# ****************** Werte lesen +
-print("# SPANNUNG #############\n") if ($verbose>8); +
-$res = sendgetserial( chr(0x01)."R1".chr(0x02)."00000000()".chr(0x03).chr(0x63) ); +
-$vals { 'Spannung' } = ( decodeVAL $res  ) / 10; +
- +
-print("# STROM #############\n") if ($verbose>8); +
-$res = sendgetserial( chr(0x01)."R1".chr(0x02)."00000001()".chr(0x03).chr(0x62) ); +
-$vals { 'Strom' } = ( decodeVAL $res  ) / 10; +
- +
-print("# FREQUENZ #############\n") if ($verbose>8); +
-$res = sendgetserial( chr(0x01)."R1".chr(0x02)."00000002()".chr(0x03).chr(0x61) ); +
-$vals { 'Frequenz' } = ( decodeVAL $res  ) / 10; +
- +
-print("# Wirkleistung #############\n") if ($verbose>8); +
-$res = sendgetserial( chr(0x01)."R1".chr(0x02)."00000003()".chr(0x03).chr(0x60) ); +
-$vals { 'PWirk' } = ( decodeVAL $res  ) * 10; +
- +
-print("# Blindleistung #############\n") if ($verbose>8); +
-$res = sendgetserial( chr(0x01)."R1".chr(0x02)."00000004()".chr(0x03).chr(0x67) ); +
-$vals { 'PBlind' } = ( decodeVAL $res  ) * 10; +
- +
-print("# Scheinleistung #############\n") if ($verbose>8); +
-$res = sendgetserial( chr(0x01)."R1".chr(0x02)."00000005()".chr(0x03).chr(0x66) ); +
-$vals { 'PSchein' } = ( decodeVAL $res  ) * 10; +
- +
-print("# Leistungsfaktor #############\n") if ($verbose>8); +
-$res = sendgetserial( chr(0x01)."R1".chr(0x02)."00000006()".chr(0x03).chr(0x65) ); +
-$vals { 'cosphi' } = ( decodeVAL $res  ) / 1000 ; +
- +
-print("# Zaehlerstand 1 #############\n") if ($verbose>8); +
-$res = sendgetserial( chr(0x01)."R1".chr(0x02)."00000010()".chr(0x03).chr(0x62) ); +
-$vals { 'Zaehler1' } = ( decodeVAL $res  ) * 1 ; +
-$res = sendgetserial( chr(0x01)."R1".chr(0x02)."00000011()".chr(0x03).chr(0x63) ); +
-$vals { 'Zaehler1b' } = ( decodeVAL $res  ) * 1 ; +
- +
-print("# Zaehlerstand 2 #############\n") if ($verbose>8); +
-$res = sendgetserial( chr(0x01)."R1".chr(0x02)."00000020()".chr(0x03).chr(0x61) ); +
-$vals { 'Zaehler2' } = ( decodeVAL $res  ) * 1  ; +
-$res = sendgetserial( chr(0x01)."R1".chr(0x02)."00000021()".chr(0x03).chr(0x60) ); +
-$vals { 'Zaehler2b' } = ( decodeVAL $res  ) * 1  ; +
- +
-print("# Temperatur #############\n") if ($verbose>8) ; +
-$res = sendgetserial( chr(0x01)."R1".chr(0x02)."00000032()".chr(0x03).chr(0x62) ); +
-$vals { 'Temperatur' } = ( decodeVAL $res  )  * 1.0 ; +
- +
- +
-# ****************** LOGOUT +
-print("# LOGOUT #############\n") if ($verbose>8); +
-$cmd = chr(0x01)."B0".chr(0x03).chr(0x71) . "/?!\r\n"+
-$res = sendgetserial( $cmd); +
- +
- +
- +
-# ****************** Werte plotten +
-if ($verbose>1) { +
-  print("# Werte plotten #############\n"); +
-  while ( my ($key, $value) = each(%vals) ) { +
-    print " --> $key = $value\n"; +
-  } +
-+
- +
- +
-# ****************** Wert in die Datenbank schreiben +
- +
-use LWP::UserAgent; +
- +
-$val =  $vals{ "Zaehler1" } ; +
-print "ZAEHLERSTAND: " . $uuid . " = " . $val . "\n"; +
- +
-my $server_endpoint = "http://localhost/middleware.php/data/${uuid}.json?value=" . $val; +
-print "serverget = " .  $server_endpoint . "\n"; +
- +
-my $ua = LWP::UserAgent->new; +
- +
-# set custom HTTP request header fields +
-my $req = HTTP::Request->new(POST => $server_endpoint); +
-$req->header('content-type' => 'application/json'); +
-$req->header('x-auth-token' => 'kfksj48sdfj4jd9d'); +
- +
-# add POST data to HTTP request body +
-$req->content(" "); +
- +
-if (1) { +
-  my $ua = LWP::UserAgent->new; +
-  my $resp = $ua->request($req); +
-    if ($resp->is_success) { +
-      my $message = $resp->decoded_content; +
-      print "Received reply: $message\n"; +
-    } else { +
-      print "HTTP GET error code: ", $resp->code, "\n"; +
-      print "HTTP GET error message: ", $resp->message, "\n"; +
-    } +
-+
- +
- +
- +
- +
-</code> +
- +
- +
- +
- +
-===== Beispielausgabe ===== +
- +
-Falls das Script läuft, bekommt man folgende Ausgaben: +
-<code> +
- --> Zaehler2b = 7450 +
- --> Temperatur = 22 +
- --> Zaehler1 = 3040 +
- --> Frequenz = 50 +
- --> Zaehler2 = 7450 +
- --> Zaehler1b = 3040 +
- --> cosphi = 0 +
- --> PWirk = 0 +
- --> PSchein = 0 +
- --> Spannung = 234.2 +
- --> PBlind = 0 +
- --> Strom = 0 +
-</code> +
- +
-Die Zählerangabe sind Wh. +
-===== Bugs ===== +
-Ich habe mit meinem Zähler das Problem, dass der Zähler 1x am Tag für 60min nicht zählt. Die Datenkommunikation funktioniert, aber der Zähler sendet scheinbar immer die gleichen Daten. Der Fehler betrifft nur die Zählerstände, die Istwerte von Leistung, Spannung und Strom sind nicht betroffen.  +
- +
-Ich habe das Problem an einem zweiten Zähler verifizieren können. Das Problem tritt immer zwischen 0Uhr und 1Uhr (zählerinterne Zeit) auf.  +
- +
-Die Zeit kann allerdings gesetzt werden, so daß das Problem "schiebbar" ist. Da ich den Zähler für die Solaranlage nutze, kann ich den Bug einfach auf Mitternacht schieben. +
- +
- +
-===== Todos ===== +
-  * <del>Werte in die Datenbank schreiben</del> +
-  * prüfen, ob das script auch bei mehreren Zähler an einem RS485 läuft +
-  * die ID der Zähler setzen +
-  * die Passwörter der Zähler setzen +
- +
- +
- +
- +
- +
- +
- +
- +
hardware/channels/meters/power/drs155m.1377340046.txt.gz · Zuletzt geändert: 2013/08/24 12:27 von ollir