Hauptmenü

IR Lesekopf Zähler

Begonnen von Inputsammler, 18 April 2014, 22:08:11

Vorheriges Thema - Nächstes Thema

Inputsammler

Hallo zusammen.

Ich habe es geschafft unter Windows meine Zähler auszulesen mit folgenden Einstellungen
Baud: 300
Data: 7
Stop: 1
Parity: Even
input control": Send on Enter auf ,,CR-LF"
befehl: 2F 3F 21 0D 0A 00 00 00 00 00 00 00 06 30 30 30 0D 0A

Dann moppt auch eine Rückmeldung im terminal.

Aber leider schaffe ich es nicht auf den RPi den kopf zum reden zu bringen.
geschweige den mit mincom die Daten zu senden und empfangen.

Mit den Modulen hier habe ich es (Schnittstelle und die Baut speed angepasst)
- Modul 70_USBEHZ.pm kill meine FHEM komplett (fhem.cfg mit nano editieren und das device wieder entfernen)
- Modul 70_SMLUSB.pm will er auch nicht reden

Jetzt meine Frage (bitte) gibt es eine art Test Script in Perl  damit ich testen kann ob der iR ausleskopf unter Linux richtig funktioniert.

Gruß Gerd
Rpi's und Bpi's und Hw von Dirk und locutus
CCU2,F20,Ks300,1-Wire,Homematic usw ...
vitodens 300 & IstrkrM372 auslesen über USB und FHEM
RUHE IN FRIEDEN AHA1805 RIP Mallorca +29.08.16
I miss you and your Family H.H.L.L.

PeMue

Hallo Gerd,

warum brauchst Du ein Test Skript? Wenn ich das richtig sehe, würde ein Terminal ausreichen.
Beim Raspberry Pi heißt das minicom.
Ggf. musst Du noch die serielle Schnittstelle vorher freischalten.

Gruß PeMue
RPi3Bv1.2 rpiaddon 1.66 6.0 1xHM-CC-RT-DN 1.4 1xHM-TC-IT-WM 1.1 2xHB-UW-Sen-THPL-O 0.15 1x-I 0.14OTAU  1xCUNO2 1.67 2xEM1000WZ 2xUniroll 1xASH2200 3xHMS100T(F) 1xRFXtrx 90 1xWT440H 3xTFA30.3150 5xFA21
RPi1Bv2 LCDCSM 1.63 5.8 2xMAX HKT 1xMAX RT V200KW1 Heizung Wasser

Inputsammler

Hey PuMue,

genau da liegt auch das Problem. Ich komm mit dem minicom nicht klar.
Deswegen dachte ich (mit Phython oder Perl) mit einen script das ich ber cron job ausführe.
Dabei einen Hex wert an die /dev/ttyUSB0 schickt und dann das gelesene einfach in eine datei schreibten lass.

Das schwierige ist dabei das ich einen Hex String schicken muss und diesen auch als Hex wert kennzeichnen (glaub ich) und dann ein sehr langer String zurück kommt.

Unter Visual Basic habe ich mir ein kleine Programm gezaubert das das macht.
Ich will deswegen eben kein c Programm schreiben weil es ja auch per script gehen muss.
Es gibt ja so was ähnliches fur FHEM (70_SMLUSB.pm) aber ich versteh nicht wie es funktioniert.

Gruß Gerd

Rpi's und Bpi's und Hw von Dirk und locutus
CCU2,F20,Ks300,1-Wire,Homematic usw ...
vitodens 300 & IstrkrM372 auslesen über USB und FHEM
RUHE IN FRIEDEN AHA1805 RIP Mallorca +29.08.16
I miss you and your Family H.H.L.L.

Inputsammler

HAllo zusammen.

Also mit Udo´s hilfe habe ich mit dem Script (Python) und seinen IR Kopf meinen Stromzähler ISKRA MT 372 auszulesen.
Das Script legt eine logdatei an, die will ich nun von meinen 2. Rpi weiterleiten an mein Master FHEM.

Werde hier mal auf dem laufenden Halten was meine Projekt so angeht.

Logdatei

['meter ID', 'datum & tijd', 'EigentumNr9-16', 'EigentumNr1-8', 'Uhr', 'Datum', 'Verbrauch totaal', 'Verbrauch tarief1', 'Verbrauch tarief2', 'Verbrauch tarief3', 'Verbrauch tarief4', 'Nix1', 'Nix2', 'Nix3', 'Nix4']
['12345678', '2014-04-20 22:37:52', '12345678', '12345678', '223425', '140420', '25922.236*kWh', '15798.415*kWh', '10123.821*kWh', '00000.000*kWh', '00000.000*kWh', '00000000', '016', '00000000', '']
['12345678', '2014-04-20 22:38:06', '12345678', '12345678', '223438', '140420', '25922.237*kWh', '15798.415*kWh', '10123.822*kWh', '00000.000*kWh', '00000.000*kWh', '00000000', '016', '00000000', '']
['12345678', '2014-04-20 22:38:19', '12345678', '12345678', '223451', '140420', '25922.240*kWh', '15798.415*kWh', '10123.825*kWh', '00000.000*kWh', '00000.000*kWh', '00000000', '016', '00000000', '']
['12345678', '2014-04-20 22:38:33', '12345678', '12345678', '223505', '140420', '25922.241*kWh', '15798.415*kWh', '10123.826*kWh', '00000.000*kWh', '00000.000*kWh', '00000000', '016', '00000000', '']
['12345678', '2014-04-20 22:38:46', '12345678', '12345678', '223519', '140420', '25922.243*kWh', '15798.415*kWh', '10123.828*kWh', '00000.000*kWh', '00000.000*kWh', '00000000', '016', '00000000', '']


Das Script
from __future__ import print_function
import serial
import time

def send(port, bytes, tr):
  """ sends an command to serial and reads and checks the echo
      port  - the open serial port
      bytes - the string to be send
      tr    - the responce time
  """
  #print("start send") 
  port.write(bytes)
  time.sleep(tr)
  echo = port.read(len(bytes))
  if (echo != bytes):
    print("echo is not same as send:", bytes, " vs ", echo)
  #print("end send")

def read_datablock():
  ACK = '\x06'
  STX = '\x02'
  ETX = '\x03'
  tr = 0.3
  """ does all that's needed to get meter data from the meter device """
  try:
    IskraMT171=serial.Serial(port='/dev/ttyUSB0', baudrate=300, bytesize=7, parity='E', stopbits=1, timeout=1.5); # open port at specified speed
    # 1 ->
    time.sleep(tr)
    Request_message='/?!\r\n' + ACK + '000\r\n' # IEC 62056-21:2002(E) 6.3.1
    send(IskraMT171, Request_message, tr)
    # 2 <-
    time.sleep(tr)
    Identification_message=IskraMT171.readline() # IEC 62056-21:2002(E) 6.3.2
    if (Identification_message[0] != '/'):
      print("no Identification message")
      IskraMT171.close()
      return ""
    if (len(Identification_message) < 7):
      print("Identification message to short")
      IskraMT171.close()
      return ""
    if (Identification_message[4].islower()):
      tr = 0.02
    manufacturers_ID = Identification_message[1:4]
    if (Identification_message[5] == '\\'):
      identification = Identification_message[7:-2]
    else:
      identification = Identification_message[5:-2]
    speed = Identification_message[4]
    #print("speed = ", speed)
    if (speed == "1"): new_baud_rate = 600
    elif (speed == "2"): new_baud_rate = 1200
    elif (speed == "3"): new_baud_rate = 2400
    elif (speed == "4"): new_baud_rate = 4800
    #elif (speed == "5"): new_baud_rate = 9600
    elif (speed == "6"): new_baud_rate = 19200
    else:
      new_baud_rate = 300
      speed = "0"
    #print(manufacturers_ID, " ", identification, " speed=", speed, )
    # 3 ->
    Acknowledgement_message=ACK + '0' + speed + '0\r\n' # IEC 62056-21:2002(E) 6.3.3
    send(IskraMT171, Acknowledgement_message, tr)
    IskraMT171.baudrate=new_baud_rate
    time.sleep(tr)
    # 4 <-
    datablock = ""
    if (IskraMT171.read() == STX):
      x = IskraMT171.read()
      BCC = 0
      while (x  != '!'):
        BCC = BCC ^ ord(x)
        datablock = datablock + x
        x = IskraMT171.read()
      while (x  != ETX):
        BCC = BCC ^ ord(x) # ETX itself is part of block check
        x = IskraMT171.read()
      BCC = BCC ^ ord(x)
      x = IskraMT171.read() # x is now the Block Check Character
      # last character is read, could close connection here
      if (BCC != ord(x)): # received correctly?
        datablock = ""
        print("Result not OK, try again")
    else:
      print("No STX found, not handled.")
    IskraMT171.close()
    return datablock
  except:
    print("Some error reading data")
    if (IskraMT171.isOpen()):
      IskraMT171.close()
    return ""

def meter_data(datablock, map, header):
  """ takes a datablock as received from the meter and returns a list with requested meter data as set in map
      if header != 0 a list with data type and units is returned """
  line = []
  ## initialise line
  for l in range(len(map)):
    if (header == 1):
      line.append(map[l][1])
    elif (map[l][0] == "time"):
      line.append(time.strftime("%Y-%m-%d %H:%M:%S"))
    else:
      line.append("")
  datasets = datablock.split('\n')
  for dataset in datasets:
    if (dataset != ""):
      x = dataset.split('(')
      address = x[0]
      x = x[1][:-2].split(' ') # the standard seems to have a '*' instead of ' ' here
      value = x[0]
      try:
        unit = '['+x[1]+']'
      except:
        unit = ""
      for l in range(len(map)):
        if (map[l][0] == address):
          if (header == 0):
            line[l] = value
          else:
            line[l] = map[l][1] + unit
          break;
  return line

def output(filename, line):
  f = open(filename, "a")
  print(line, file=f)
  f.close()

map = [
  # The structure of the meter_data() output can be set with this variable
  # first string on each line is the cosim adress of the data you want to safe or "time" to insert the time
  # the second string on each line is a description of the type of data belonging to the cosim address
  # the order of the lines sets the order of the meter_data() output
  # example
  # header: ['meter ID', 'datum & tijd', 'verbruik totaal[kWh]', 'verbruik tarief1[kWh]', 'verbruik tarief2[kWh]', 'terug totaal[kWh]', 'terug tarief1[kWh]', 'terug tarief2[kWh]']
  # data: ['12345678', '2013-02-08 10:08:41', '0054321', '0000000', '0054321', '0000000', '0000000', '0000000']
["0.0.0", "meter ID"],
  ["time", "datum & tijd"],
  ["C.1.0", "EigentumNr9-16"],
  ["C.1.1", "EigentumNr1-8"],
  ["0.9.1", "Uhr"],
  ["0.9.2", "Datum"], 
  ["1.8.0", "Verbrauch totaal"],
  ["1.8.1", "Verbrauch tarief1"],
  ["1.8.2", "Verbrauch tarief2"], 
  ["1.8.3", "Verbrauch tarief3"],
  ["1.8.4", "Verbrauch tarief4"],
  ["F.97.0", "Nix1"],
  ["C.241.0", "Nix2"],
  ["C.244.0", "Nix3"],
  ["C.2.0", "Nix4"]
]

example_datablock = """
0.0.0(12345678)
C.1.0(12345678)
C.1.1(90123456)
0.9.1(114138)
0.9.2(140420)
1.8.0(25915.768*kWh)
1.8.1(15798.415*kWh)
1.8.2(10117.353*kWh)
1.8.3(00000.000*kWh)
1.8.4(00000.000*kWh)
F.97.0(00000000)
C.241.0(016)
C.244.0(00000000)
0.2.0((ER11))
"""

#print(meter_data(example_datablock , map, 1))
#print(meter_data(example_datablock , map, 0))


file = "meterdata.txt"
previous_data = ""
data = read_datablock()

output(file, meter_data(data , map, 1)) # header
while (1):
  if (data == ""):
    print(time.strftime("%Y-%m-%d %H:%M:%S"), "No data received")
  elif (previous_data != data):
    output(file, meter_data(data , map, 0))
    previous_data = data
  time.sleep(3) # minimum waiting time is 3 seconds, less and the meter doesn't return data
  data = read_datablock()

Rpi's und Bpi's und Hw von Dirk und locutus
CCU2,F20,Ks300,1-Wire,Homematic usw ...
vitodens 300 & IstrkrM372 auslesen über USB und FHEM
RUHE IN FRIEDEN AHA1805 RIP Mallorca +29.08.16
I miss you and your Family H.H.L.L.

Inputsammler

#4
Hallo zusammen,

Ich habe nun das Script umgebaut.
Nun habe ich ein fast FEHM taugliche log Datei.

2014-10-10_17:22:00 141010 171755 28084.004 17097.221 10986.783
2014-10-10_17:27:11 141010 172306 28084.106 17097.323 10986.783
2014-10-10_17:32:21 141010 172816 28084.244 17097.461 10986.783
2014-10-10_17:37:32 141010 173327 28084.354 17097.571 10986.783
2014-10-10_17:42:43 141010 173837 28084.483 17097.700 10986.783
2014-10-10_17:47:53 141010 174348 28084.722 17097.939 10986.783
2014-10-10_17:53:04 141010 174859 28084.894 17098.111 10986.783
2014-10-10_17:58:14 141010 175409 28084.985 17098.202 10986.783
2014-10-10_18:03:25 141010 175920 28085.102 17098.319 10986.783


https://www.dropbox.com/s/f7yrhc809cma14x/Screenshot%202014-10-12%2013.12.50.png?dl=0
jetzt muss ich nur noch eine Möglichkeit finden
Zeit Differenz und die Stromwert Differenz in das Log zu schreiben oder so ähnlich
Vielleicht mit eine DUMMY

Hat da jemand einen Denkanstoß für mich ..

Gruß Gerd
Rpi's und Bpi's und Hw von Dirk und locutus
CCU2,F20,Ks300,1-Wire,Homematic usw ...
vitodens 300 & IstrkrM372 auslesen über USB und FHEM
RUHE IN FRIEDEN AHA1805 RIP Mallorca +29.08.16
I miss you and your Family H.H.L.L.