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/03 20:42] – [Hier dann das Perl-script] 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. +
-===== offene Punkte ===== +
-Ich habe mit meinem Zähler das Problem, dass der Zähler 1x am Tag für ca.80min nicht zählt. Die Datenkommunikation funktioniert, aber der Zähler sendet scheinbar immer die gleichen Daten.  +
- +
---> Kann das Problem jemand bestätigen? +
- +
-===== 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.1375555363.txt.gz · Zuletzt geändert: 2013/08/03 20:42 von ollir