Buderus Logamatic 2107 Revision 3 2019

User stellen ihre Haussteuerung vor

Moderator: Co-Administratoren

marc25111
Beiträge: 10
Registriert: 27.10.2016, 11:37

Re: Buderus Logamatic 2107 an CCU2 (Projekt abgeschlossen)

Beitrag von marc25111 » 16.01.2017, 23:40

Hallo zusammen,
hallo Black,

vielleicht ist es jetzt auch schon ein bisschen spät, aber ich glaube ich hab den Thread jetzt 4x gelesen und ich habe das Gefühl, dass mir noch was fehlt...

Ich habe eine Logomatic 2107 mit einem Kommunikationsmodul KM271. Somit sollte das Setup grundsätzlich identisch sein mit Deinem...

Nen TTL Wandler haben wir wir jetzt an ein Kabel für die KM gelötet und an einen PI3 B angeschlossen. Wenn ich das mit dem TX und RX auf Deiner Homepage richtig verstanden habe, müsste das auch korrekt sein.

Und jetzt hab ich gerade so einen GAP:
Auf Deiner Homepage liegt das 3964r.py (bei mir mag er zwar die Umlaute nicht, aber die lassen sich ja ersetzten)
sinnigerweise fragt der Treiber nach der stepchain -> schritte.py hier aus dem Thread kopiert.

Und da verließen sie ihn jetzt auch langsam:

Code: Alles auswählen

pi@raspberrypi3:~ $ python3 3964r.py
pi@raspberrypi3:~ $
Öhm, wie bekomm ich jetzt gleich die schicke Übersicht mit den ganzen werten?
Kann ich auch irgendwie genau prüfen ob das Kabel richtig ist und funzt?
Hab ich vielleicht vergessen an der Seriellen Schnittstelle vom PI etwas zu konfigurieren?

Ist es richtig nach dem bild hier:
https://www.elektronik-kompendium.de/si ... 907101.htm
den PIN 4,6,8,10 zu benutzen (1:1 mit GND, RX, TX, VCC am TTL konverter verbunden?)

Danke, wenn ihr etwas Licht in mein verwirrtest dunkles bringen könntet und viele Grüße

Marc

Benutzeravatar
Black
Beiträge: 5480
Registriert: 12.09.2015, 22:31
System: Alternative CCU (auf Basis OCCU)
Wohnort: Wegberg
Hat sich bedankt: 424 Mal
Danksagung erhalten: 1074 Mal
Kontaktdaten:

Re: Buderus Logamatic 2107 an CCU2 (Projekt abgeschlossen)

Beitrag von Black » 17.01.2017, 12:47

hi,

da tun sich glaub ich gleich mal mehrere probleme auf. Das ganze ist nicht gerade ein Plug & Play project.

Bei einem Pi3 sag ich mal Blind, das auf /dev/ttyAMA0 der Bluetooth drauf laufen wird.
da muss erstmal was umgeschrieben werden, das die On Board schnittstelle nichtr mehr benutzt wird und vor allen dingen auch nicht zum logg bzw login benutz wird (ist standartmäßig so konfiguriert)

Wenn das erledigt ist, dann kannst mal beginnen, erste Tests zu machen:
heisst: grafische oberfläche auf dem PI starten, dort mit phyton arbeiten.

der c3964r ist nur eine Treiberklasse. das ist noch nicht ein fertiges Programm.
das wächst bei mir auhc noch wöchentlich weiter quasi

du brauchst noch eine klasse, jetzt gehts aber in multi threading unter python rein.

Code: Alles auswählen

from datetime import datetime
from urllib.request import urlopen
from http.server import BaseHTTPRequestHandler, HTTPServer
import RPi.GPIO as GPIO
import time as t
import binascii
import c3964r
import threading
import http.client
import socket
import re
import logging
import json
import math
import os

class logamatic2107 (c3964r.Dust3964r,threading.Thread):
 message = True
    timeout = False
    # Array für die Betriebsstunden
    #[0]= minuten
    #[1]= minuten * 256
    #[2]= minuten * 65536
    aHour   = [0,0,0]

    # Installations Konstruktor für den Treiber und für die Threads
    def __init__ (self):
        self.timeout = False
        c3964r.Dust3964r.__init__ (self,port='/dev/ttyAMA0',baudrate=2400,SLP=0.1,PRIO=self.HIPRIO)
        threading.Thread.__init__ (self)
        self.TimeStampMessage= t.time()
    
    # Das hier ist die eigentliche Routine die vom Thread aufgerufen wird
    def run (self):
        global ende
        while not ende:
            t.sleep (0.1)
            # Test auf Message TimeOut
            self.timeout= (t.time () - self.TimeStampMessage)>20
            self.running ()
        log ("error", "Logamatic Thread closed")     

# WriteSucces wird aufgerufen, wenn ein Schreibbefehl über den 3964r erfolgreich an die Logamatic abgesetzt wurde
    def WriteSuccess (self,telegram):
        global LCDmode
        global lcd
        if self.message:
            # Hier analysieren wir für den Debugger das Telegram
            if telegram==b"\xEE\x00\x00": # Logmode.
                log ("error","CMD: LOGMODE eingeleitet")


    def WriteFail (self,telegram):
        log ("error","SENDEJOB NICHT ERFOLGREICH ABGEBROCHEN")
        #logging.error ("SENDEJOB %s NICHT ERFOLGREICH ABGEBROCHEN", telegram)       
        pass

# Read Success wird vom child aufgerufen, wenn Telegramm erfolgreich von der Logamatik gelesen
    def ReadSuccess (self,telegram):
        log ("error",telegram)

logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%d.%m.%Y %H:%M:%S ', level=logging.WARNING)        
a=logamatic2107 ()
a.CFG_PRINT=False  # Einzeltelegramm Hex DEBUG Aus
a.newJob (b"\xee\x00\x00")
a.RealRun= True
a.start ()
ende=False
try:
    while not ende:
        t.sleep (0.1)
except (KeyboardInterrupt,SystemExit):
    ende=True
    pass
t.sleep (4)
log ("error","Programmende")
Ich hab das mal eben aus meinem Main Prog rauskopiert.
Wenn er startet, setzt er die das Kommando Logmode ab, sagt dir auch, wenn er es erfolgreich besztätigt bekommen hat und stellt die dann die telegramme da, die er empfängt.

ich würde aber vorher mal mit dem PI und nem Laptop ne verbindung aufbauen, aufm Laptop ein Terminal programm startet, einstellung 2400 Baud, 8 bit, rest standart.

dann aufm pi in python die schnittstelle initialieren und via write ("Hallo Welt") mal gucken, obs auf dem Laptop ankommt.
wenn das schon nicht geht, ist der Fehler noch auf PI-Seite zu Suchen.

Gruss & viel Erfolg, Black
Wenn das Fernsehprogramm immer mehr durch nervende Werbung unterbrochen wird und der Radiomoderator nur noch Müll erzählt, ist es besser, die Zeit für sinnvolle Dinge zu nutzen -
mal aufs Klo zu gehen, ein Bier zu holen oder einfach mal den roten AUS-Knopf zu drücken. Klick - und weg

Script Time Scheduler V1.3
AstroSteuerung über Zeitmodul flexibel mit Offset / spätestens, frühestens
SDV 5.03.01 Das umfassende Entwicklungs und Diagnosetool für Homematik
Selektive Backups - Nützliche Dinge, die die WebUI nicht kann

Intel NUC6 Celeron 16GB mit 512GB SSD unter Proxxmox mit insgesamt 5 VM: 2 x bloatwarebefreiter Raspberrymatik, 2 x IOBroker als Middleware und einer MariaDB zur Archivierung. Verbrauch: 6W

technical contribution against annoying advertising

marc25111
Beiträge: 10
Registriert: 27.10.2016, 11:37

Re: Buderus Logamatic 2107 an CCU2 (Projekt abgeschlossen)

Beitrag von marc25111 » 17.01.2017, 19:41

Hi,

in der Tat ist das mit dem Pi3 und der RS232 so eine Sache... hab in der Tat mehr mit der BT als mit dem GPIO gesprochen...

Um das jetzt vollständig zu eliminieren hab ich mir nen Pi1 geschnappt und bin mal mit Deiner anfangs - Testroutine gestartet:

Code: Alles auswählen

import serial

s = serial.Serial(port = '/dev/ttyAMA0',
                  baudrate = 9600)
                  #timeout=5.0)

post=False
print (s.name )

#0xEE 0x00 0x00 0x10 0x03 0xFD
s.flushInput ()
s.flushOutput ()
s.write (b"\x02")
while True:
    if s.inWaiting ():
        char= s.read ()
        if len (char):
            print ("%3.2X"% ord (char))
            if ord (char)== 0x10:
                s.write (b"\xEE\x00\x00\x10\x03\xFD")
                post=True
            elif ord (char)== 0x02:
                if post:
                    s.write (b"\x10")
            elif not post:
                s.write (b"\x02")


Am RX und TX vom TTL Wandler hab ich je eine LED. Somit sehe ich jetzt auch bei dem Testscript auch genau ein Aufblinken von (je nach dem wie ich es anstecke) RX / TX.

Somit sollte an der Stelle Pi - seitig alles funktionieren Und zuminest der Teil i.O. sein.

Antwort kommt leider gar keiner aus dem KM271. Wobei ich jetzt davon ausgehe, dass ich die PIN - Belegung nicht passt:

am TTL hab ich 3 Kabel,

Pin 2
Pin 3
Pin 5

diese gehen an die KM271.

Wenn ich jetzt dieses Bild zu grunde lege:
http://vermessung.drbertges.com/images/ ... buchse.jpg

dann gehen vom TTL die Pins linear von:

2 -> 2
3 -> 3
und
5 -> 5

Oder hab ich gerade einen kaptitalen Denkfehler (was immer möglich ist).

Und ja, ich bin mir sicher, dass das ganze nicht Plug and Play ist :-). Aber ich denke ich brauch nur die initiale Kommunikation und dann komm ich weiter vorwärts...

Danke schon mal für die Hilfe und Grüße

marc25111
Beiträge: 10
Registriert: 27.10.2016, 11:37

Re: Buderus Logamatic 2107 an CCU2 (Projekt abgeschlossen)

Beitrag von marc25111 » 17.01.2017, 20:37

Update:

wenn ich jetzt den Pin 2 & 3 am Ausgang vom TTL brücke und mit nem trivial Script mir selber was schickt, dann funzt das immerhin:

Code: Alles auswählen

#!/usr/bin/env python
          
import time
import serial
          
      
ser = serial.Serial(            
               port='/dev/ttyAMA0',
               baudrate = 9600,
               parity=serial.PARITY_NONE,
               stopbits=serial.STOPBITS_ONE,
               bytesize=serial.EIGHTBITS,
               timeout=1
           )
counter=0
          
      
while 1:
    ser.write(b"\x02")
    x= ser.readline()
    print (x)
    time.sleep(1)
    counter += 1

Code: Alles auswählen

pi@raspberrypi:~ $ sudo python3 sertest.py
b''
b''
b''
b'\x02'
b'\x02'
b'\x02'
b'\x02'
b''
b''
Sieht man also schön wann die Kabel zusammen sind ...

Kann jetzt nur noch die Pin Belegung sein, oder ein defektes KM271 :-(

Edit: Nur noch eine weitere blöde Frage am Rande:
An das KM muss ich an den 2 Pins oben neben der RS232 keinen Strom anschließen, oder doch ?!?

Edit2:
Wollte Dein Script auch noch Testen, allerdings fehlt mir die
c2964r

File "main.py", line 7, in <module>
import c3964r
ImportError: No module named 'c3964r'

Dake & Grüße

Benutzeravatar
Black
Beiträge: 5480
Registriert: 12.09.2015, 22:31
System: Alternative CCU (auf Basis OCCU)
Wohnort: Wegberg
Hat sich bedankt: 424 Mal
Danksagung erhalten: 1074 Mal
Kontaktdaten:

Re: Buderus Logamatic 2107 an CCU2 (Projekt abgeschlossen)

Beitrag von Black » 17.01.2017, 21:57

du, die 2107 arbeitet mit 2400 baud !!!

das hier war damals für den kollegen mit der Buderus EMS steuerung, die geht mit 9600 !
für die 2107 muss du 2400 nehmen

Code: Alles auswählen

ser = serial.Serial(           
               port='/dev/ttyAMA0',
               baudrate = 2400,
               parity=serial.PARITY_NONE,
               stopbits=serial.STOPBITS_ONE,
               bytesize=serial.EIGHTBITS,
               timeout=1
dann probier nochmal

so, das hier ist die aktuelle Version von c3964r, gerade frisch via putty vom pi abgezogen

Code: Alles auswählen

#!usr/bin/python3
# -*-coding:Utf-8 -*

# 3964r Protokoll Treiber für RS232
# Michael Thelen OKT 2015

from serial import Serial
from datetime import datetime
import time as t
import binascii
import threading
from schritte import stepchain

#---------------------------------------------------------------------------
# Schrittkette für 3964r Protokoll
# Grundklasse ist Stepchain, elementare Schrittkette
#
# Die Prozedur 3964R ist ein asynchrones, bitserielles Übertragungsverfahren. Über die Verbindung werden
# Steuer- und Nutzinformationszeichen gesendet. Um jedes Zeichen beim Empfänger wiederzuerkennen,
# und um die fehlerfreie Übertragung zu kontrollieren, werden den gesendeten Zeichen weitere Bits voranbzw.
# nachgestellt. Die Reihenfolge der Bits auf der Leitung ist:
# SA I0 I1 I2 I3 I4 I5 I6 I7 SO
# SA = Startbit
# In = Informationsbit Nr.
# SO = Stoppbit
#
# Die Steuerzeichen für die Prozedur 3964R sind der Norm DIN 66003 für den 7-Bit-Code entnommen. Sie
# werden allerdings mit der Zeichenlänge 8 Bit übertragen (Bit I7 = 0). Am Ende jedes Datenblocks wird zur
# Datensicherung ein Prüfzeichen(BCC) gesendet.
# Das Blockprüfzeichen wird durch eine exklusiv-oder-Verknüpfung über alle Datenbytes der
# Nutzinformation, inclusive der Endekennung DLE, ETX gebildet.
# Für die Informationszeichen ist kein Code vorgeschrieben (Codetransparenz).
#
# *****************************
# Senden mit der Prozedur 3964R
# Zum Aufbau der Verbindung sendet die Prozedur 3964R das Steuerzeichen STX aus. Antwortet das
# Peripheriegerät vor Ablauf der Quittungsverzugzeit (QVZ) von 2 sec mit dem Zeichen DLE, so geht die
# Prozedur in den Sendebetrieb über. Antwortet das Peripheriegerät mit NAK, einem beliebigen anderen
# Zeichen (außer DLE) oder die Quittungsverzugszeit verstreicht ohne Reaktion, so ist der
# Verbindungsaufbau gescheitert. Nach insgesamt drei vergeblichen Versuchen bricht die Prozedur das
# Verfahren ab und meldet dem Interpreter den Fehler im Verbindungsaufbau.
#
# Gelingt der Verbindungsaufbau, so werden nun die im aktuellen Ausgabepuffer enthaltenen
# Nutzinformationszeichen mit der gewählten Übertragungsgeschwindigkeit an das Peripheriegerät
# gesendet. Das Peripheriegerät soll die ankommenden Zeichen in Ihrem zeitlichen Abstand überwachen.
# Der Abstand zwischen zwei Zeichen darf nicht mehr als die Zeichenverzugszeit (ZVZ) von 220 ms
# betragen.
#
# Jedes im Puffer vorgefundene Zeichen DLE wird als zwei Zeichen DLE gesendet. Dabei wird das Zeichen
# DLE zweimal in die Prüfsumme übernommen.
#
# Nach erfolgtem senden des Pufferinhalts fügt die Prozedur die Zeichen DLE, ETX und BCC als
# Endekennung an und wartet auf ein Quittungszeichen. Sendet das Peripheriegerät innerhalb der
# Quittungsverzugszeit QVZ das Zeichen DLE, so wurde der Datenblock fehlerfrei übernommen. Antwortet
# das Peripheriegerät mit NAK, einem beliebigen anderen Zeichen (außer DLE), einem gestörten Zeichen
# oder die Quittungsverzugszeit verstreicht ohne Reaktion, so wiederholt die Prozedur das Senden des
# Datenblocks. Nach insgesamt sechs vergeblichen Versuchen, den Datenblock zu senden, bricht die
# Prozedur das Verfahren ab und meldet dem Interpreter den Fehler im Verbindungsaufbau.
#
# Sendet das Peripheriegerät während einer laufenden Sendung das Zeichen NAK, so beendet die
# Prozedur den Block und wiederholt in der oben beschriebenen Weise.
#
# Beispiel für einen fehlerlosen Datenverkehr:
# Prozedur 3964R Peripheriegerät
# STX           ->
#               <- DLE
# 1. Zeichen    ->
#               ->
#               ->
#               ->
# n. Zeichen    ->
# DLE           ->
# ETX           ->
# BCC           ->
#               <- DLE
#
# ********************************
# Empfangen mit der Prozedur 3964R
# Im Ruhezustand, wenn kein Sendeauftrag und kein Warteauftrag des Interpreters zu bearbeiten ist, wartet
# die Prozedur auf den Verbindungsaufbau durch das Peripheriegerät. Empfängt die Prozedur ein STX und
# steht ihr ein leerer Eingabepuffer zur Verfügung, wird mit DLE geantwortet.
#
# Nachfolgende Empfangszeichen werden nun in dem Eingabepuffer abgelegt. Werden zwei aufeinander
# folgende Zeichen DLE empfangen, wird nur ein DLE in den Eingabepuffer übernommen.
# Nach jedem Empfangszeichen wird während der Zeichenverzugszeit (ZVZ) auf das nächste Zeichen
# gewartet. Verstreicht die Zeichenverzugszeit ohne Empfang, wird das Zeichen NAK an das
# Peripheriegerät gesendet und der Fehler an den Interpreter gemeldet.
#
# Mit erkennen der Zeichenfolge DLE, ETX und BCC beendet die Prozedur den Empfang und sendet DLE
# für einen fehlerfrei (oder NAK für einen fehlerhaft) empfangenen Block an das Peripheriegerät.
# Treten während des Empfangs Übertragungsfehler auf (verlorenes Zeichen, Rahmenfehler), wird der
# Empfang bis zum Verbindungsabbau weitergeführt und NAK an das Peripheriegerät gesendet. Dann wird
# eine Wiederholung des Blocks erwartet. Kann der Block auch nach insgesamt sechs Versuchen nicht
# fehlerfrei empfangen werden, oder wird die Wiederholung vom Peripheriegerät nicht innerhalb der
# Blockwartezeit von 4 sec gestartet, bricht die Prozedur 3964R den Empfang ab und meldet den Fehler an
# den Interpreter.
#
# Beispiel für einen fehlerlosen Datenverkehr:
# Prozedur 3964R       Peripheriegerät
#                 <-      STX
#   DLE           -> 
#                 <-    1. Zeichen
#                 <-
#                 <-
#                 <-
#                 <-    n. Zeichen
#                 <-      DLE
#                 <-      ETX
#                 <-      BCC
#   DLE           ->
#
# ************************
# Initialisierungskonflikt
# Antwortet ein Gerät auf den Sendewunsch (Zeichen STX) seines Peripheriegerätes innerhalb der
# Quittungsverzugszeit QVZ nicht mit der Quittung DLE oder NAK, sondern ebenfalls mit dem Zeichen STX,
# liegt ein Initialisierungskonflikt vor. Beide Geräte möchten einen vorliegenden Sendeauftrag ausführen.
# Das Gerät mit der niederen Priorität stellt seinen Sendeauftrag zurück und antwortet mit dem Zeichen
# DLE. Das Gerät mit der höheren Priorität sendet daraufhin seine Daten in der vorher beschriebenen
# Weise. Nach dem Verbindungsabbau kann das Gerät mit der niederen Priorität seinen Sendeauftrag
# ausführen.
#
# niedrige Priorität     höhere Priorität
#   STX           ->
#                 <-     STX  (Konflikt)
#   DLE           -> 
#                 <-    1. Zeichen
#                 <-
#                 <-
#                 <-
#                 <-    n. Zeichen
#                 <-      DLE
#                 <-      ETX
#                 <-      BCC
#   DLE           ->
#
#
# Klassendifinition für den 3964r Treiber
# Der Treiber bedient eine Schnittstelle, welche definiert werden muss
class Dust3964r (stepchain,Serial):
    lock = threading.Lock()
    
    sendtry     = 0       # Anzahl der Sendeversuche
    sendbuff    = b""     # Sendepuffer ist leer
    readbuff    = b""     # Empfangspuffer
    telegrammOut= []      # Sendetelegramm (Puffer)
    MODE        = True    # Mit Blockprüfzeichen
    CFG_PRIO    = True    # Treiber läuft mit hoher Priorität
    CFG_PRINT   = True    # Modus Print eingeschalet (
    ETX_EN      = False   # Sequenzer erkennt, ob ein ETX nach einem DLE gültig ist
    BCC_EN      = False   # Sequenzer erkennt, das nach DLE, ETX nun das BCC folgen muss
    RealRun     = True    # Lauf im Simulator = false, in Realität True
    RUN         = False   # Der treiber läuft
    STX         = b"\x02" # chr(0x02)
    ETX         = b"\x03" # chr(0x03)
    DLE         = b"\x10" # chr(0x10)
    NAK         = b"\x15" # chr(0x15)
    LOPRIO      = False   # niedrige Prio
    HIPRIO      = True    # hohe Priorität
    M3964       = False   # Treiber läuft als 3964 ohne BCC Blocksumme
    M3964R      = True    # Treiber läuft als 3964r mit BCC Blocksumme

    def __init__ (self,port=None,baudrate=9600,QVZ=2.0,ZVZ=0.22,BWZ=4.0,CWZ = 3.0,SPZ=0.5,SLP= 1.4,MAXSEND=6,MAXCONNECT=6,PRIO=HIPRIO, MODE=M3964R):
        # Initialisierung der Schrittkettenklasse
        stepchain.__init__ (self)
        # Initialisierung der SchnrittstellenKlasse
        self.RS232     = Serial (port=port,baudrate=baudrate)
        self.QVZ       = QVZ        # Quittungsverzug ist 2.0 Sekunden (Buderus Doku)
        self.ZVZ       = ZVZ        # Zeichenverzugszeit 220ms (Buderus Doku)
        self.BWZ       = BWZ        # Blockwartezeit 4.0 Sekunden (Buderus Doku)
        self.CWZ       = CWZ        # Connectwartezeit 2.0 Sekunden (Wartezeit nach versuch fehlerhafter Verbindungsaufbau
        self.SPZ       = SPZ        # SendePause zeit (nach einem erfolgreichem Senden warten bis nächstes Senden
        self.SLP       = SLP        # Schlafenszeit vor dem Absenden vom DLE (muss klener als QVZ der Gegenseite sein)
        self.MAXSEND   = MAXSEND    # Maximalanzahl Sendeversuche, danach wird das Telegramm verworfen
        self.MAXCONNECT= MAXCONNECT # Anzahl maximaler Verbindungsaufbau Versuche
        self.sendERR   = 0          # Sendefehler auf 0
        self.connectERR= 0          # Verbindungsaufbau Fehler auf 0
        self.RUN       = False      # Treiber in Stop
        self.SendAtTime= 0          # Erlaube Senden ab dem Zeitpunkt
        self.MODE      = MODE       # Treibermodus einstellen (Serienmäßig nach dem Start: 3964r mit Blocksumme
        self.CFG_PRIO  = PRIO       # Modus einstellen
        self.telegrammOut= []       # Ausgangspuffer ist leer
        self.RS232.flushOutput ()   # puffer tillen
        self.RS232.flushInput ()
        self.RS232.write (self.NAK) # auf der schnittstelle mal blind am anfang ein NAK raushauen
        

    # hiermit kann der Modus des Treibers umgeschaltet werden. der Aufruf kann nur nach dem INIT gemacht werden, nicht während des Laufens
    # Mögliche Mode sind: PRIO = LO   : Bei einem INIT Konflikt stellt Treiber seinen Sendewunsch zurück
    #                     PRIO = HI   : Bei einem Init Konflikt besteht der Treiber auf Bestätigung Sendebereitschaft durch die Gegenseite
    #                     MODUS= 3964 : Übertragung ohne Blockprüfkennung BCC
    #                     MODUS= 3964r: Übertragung mit Blockprüfkennung BCC
    def mode (self,PRIO,MODE):
        if not self.RUN:
            self.CFG_PRIO= PRIO
            self.MODE    = MODE

    # Berechnet das XOR CRC für den übergebenen buff
    # buffer sollte ein bytestring sein
    # der Rückgabewert ist ein bytestring
    def crc (self,buffer):
        bcc= 0x00
        for c in buffer:
            bcc ^= c
        return bytes([bcc])

    # wandelt den buffer in den auszugebenen bytestring um
    # erwartet buffer als bytestrng
    # Rückgabewert ist ebenfalls ein bytestring
    def outframe (self,buffer):
        # Ein DLE in Datenstring führt zur Verdopplung von DLE
        # DLE und ETX sind der Frame vom 3964r Protokoll
        puffer= buffer.replace (self.DLE,self.DLE+self.DLE)+ self.DLE + self.ETX
        # prüfen, welches Protokoll: 3964= ohne BCC, 3964r mit BCC
        if self.MODE:
            puffer+=self.crc (puffer)
        return puffer

    # Befreit das Telegramm von dem 3964r Frame, prüft die Checksumme
    # Der buffer muss ein bytestring sein
    # Rückgabe: NONE, wenn irgendein Fehler aufgetreten ist, Telegramm verstümmelt, Checksum falsch
    # Wenn alles OK, Rückgabe des Telegramms als Bytestring
    def inframe (self,buffer):
        stream= buffer
        # BCC Kontrolle nur im 3964r modus
        if self.MODE:
            try:
                bufferBCC= stream[-1:]
                stream= buffer[:-1]
            except: return None
            # testen ob der Checksumme zu dem Stream passt
            if bufferBCC!=self.crc (stream):
                return None
        try:
            # Nun prüfen, ob am Ende vom Stream DLW und ETX drinsind
            if stream[-2:]!=self.DLE+self.ETX:
                return None
        except: # Inframe buffer zu klein
            return None
        return stream [:-2].replace (self.DLE+self.DLE,self.DLE)    
    
    def sendstream (self,sendepuffer):       
        buffer= self.outframe (sendepuffer)
        self.RS232.write (buffer)
        if self.CFG_PRINT:
            print (" 10r",end="")
            for c in buffer:
                print("%3.2X"% c + "s",end="")
        # der puffer wurde über die rs232 ausgegeben

    # Fehler in der Kommunikation: NAK ausgeben
    # Bei einem NAK wird immer auch ein flush ausgeführt
    def errNAK (self):
        self.RS232.flushOutput ()
        self.RS232.flushInput ()
        self.RS232.write (self.NAK+self.NAK+self.NAK)
        self.setnewstep (0)

    # eine Verzögerungszeit für das nächste Senden wird definiert
    def SetSendDelay (self,sec):
        self.SendAtTime= t.time ()+sec

    # Read Success wird aufgerufen, wenn ein Telegramm erfolgreich eingelesen wurde
    # Virtuelle Routine, muss überladen werden vom child    
    def ReadSuccess (self,telegram):
        pass

    # WriteFail wird aufgerufen, wenn win Telegramm verworfen wurde nach 6 Sendeversuchen
    # Virtuelle Routine, muss überladen werden vom child    
    def WriteFail (self,telegram):     
        pass

    # Write Success wird aufgerufen, wenn ein Telegram erfolgreich versendet worden ist
    # Virtuelle Routine, muss überladen werden vom child
    def WriteSuccess (self,telegram):
        pass

    # Routine Prüft, ob im Sendepuffer ein Auftrag vorhanden ist
    def isJob (self):
        return self.telegrammOut!=[]

    # Routine fügt einen neunen Sendeauftrag in den Puffer ein
    def newJob (self,job):
        Dust3964r.lock.acquire() # Thread blockieren, der part nun hier muss atomar sein
        self.telegrammOut.append (job)
        Dust3964r.lock.release() #
        if self.CFG_PRINT:
            print ("NEUER JOB EINGEGANGEN: ",job)

    # Routine nimmt den ältesten Sendeauftrag aus der Liste und gibt diesen Zurück
    # existiert kein Job, wird NONE zurückgegeben
    def getJob (self):    
        if not self.isJob ():
            return None   # Kein Job in der Liste
        Dust3964r.lock.acquire() # Thread blockieren, der part nun hier muss atomar sein
        job= self.telegrammOut [0]
        self.telegrammOut= self.telegrammOut [1:]
        Dust3964r.lock.release() #
        if self.CFG_PRINT:
            print ("JOB WIRD BEARBEITET: ", job)
        return job
        

    # Schritt 0: Der Grundschritt:
    # Steht kein aktuelles Kommando zur Ausführung an und ist inWaiting() <>0 (Zeichen im Buffer)
    # Dann neuer Schritt = 1 (Empfang überprüfen)
    def schritt_0 (self):
        if self.newstep: # Einmaliger Durchlauf in dem Schritt
            # Initialisierung der Werte
            if (self.sendERR==self.MAXSEND) or (self.connectERR==self.MAXCONNECT):
                self.WriteFail (self.sendbuff)
                self.sendbuff=b""        #
                if self.CFG_PRINT:
                    print(t.strftime("%H:%M:%S")+"."+ "%6.6d"% datetime.now().microsecond + ": Telegramm verworfen nach " , self.MAXSEND , " Fehlversuchen")
        if (self.sendbuff==b"") and self.isJob ():
            job= self.getJob ()
            self.sendERR=0
            self.connectERR=0            
            if not (job is None):
                self.sendbuff=job
        self.SEND_EN= (len(self.sendbuff)!=0) and (t.time ()>self.SendAtTime)        
        if self.RS232.inWaiting () and self.RealRun:
            # Es ist ein Zeichen im Empfangspuffer
            # An dieser Stelle kann und darf es höchstens das Zeichen STX sein
            char= self.RS232.read ()
            if char != self.STX:
                # Es war kein STX, das ist auf jedenfall mal ein Fehler also: NAK senden
                if self.CFG_PRINT:
                    print(t.strftime("%H:%M:%S")+"."+ "%6.6d"% datetime.now().microsecond + ":[RX]"+ "%3.2X"% ord (char) + "r 15s [NAK: STX-START]")                  
                self.errNAK ()
            else: # Es war ein STX
                if not self.CFG_PRIO or not self.SEND_EN: # Treiber hat niedrige PRIO oder nix zum senden
                    if self.CFG_PRINT:
                        print(t.strftime("%H:%M:%S")+"."+ "%6.6d"% datetime.now().microsecond + ":[RX] 02r",end="")
                    t.sleep (self.SLP) # Für die erlaubte Antwortzeit legt sich der Prozess schlafen    
                    self.setnewstep (4) # Verbindungsaufbau 3964r läuft nun ready to receive
                elif self.SEND_EN:
                    if self.CFG_PRINT:
                        print(t.strftime("%H:%M:%S")+"."+ "%6.6d"% datetime.now().microsecond + ":[TX] 02r 02s",end="")
                    self.RS232.flushOutput ()
                    self.RS232.write (self.STX)
                    self.setnewstep (1) # verbindungsaufbau mit Konflikt: wir wollen Senden mit Hiprio
        else: # Es gibt kein Zeichen im Empfangspuffer
            if self.SEND_EN: # wir haben was zu senden
                if self.CFG_PRINT:
                    print(t.strftime("%H:%M:%S")+"."+ "%6.6d"% datetime.now().microsecond + ":[TX] 02s",end="")
                self.RS232.flushInput ()    
                self.RS232.flushOutput ()
                self.RS232.write (self.STX)
                self.setnewstep (3) # Verbindungsaufbau von uns kommt

    # Schritt 1: Senden (wir haben STX gesenden und erwarten ein DLE
    # Es muss ein DLE innerhalb der quittungsverzugszeit kommen
    # Alles was nicht DLE ist grund für ein NAK (Hi prio)
    def schritt_1 (self):
        if self.stepdauer>self.QVZ:
            # Quittungsverzugszeit ist abgelaufen
            if self.CFG_PRINT:
                print (" 15s [NAK: QVZ-START]")
            self.connectERR +=1 # Verbindungsaufbaufehler um 1 erhöhen
            self.SetSendDelay (self.CWZ)
            self.errNAK ()
        elif self.RS232.inWaiting ():
            # Zeichen wurde eingelesen, es muss ein DLE sein
            c= self.RS232.read ()
            if c!= self.DLE:
                # Es war aber kein DLE
                if self.CFG_PRINT:
                    print ("%3.2X"% ord (c) + "r 15s [NAK: DLE-START]")
                self.connectERR +=1 # Verbindungsaufbaufehler um 1 erhöhen
                self.SetSendDelay (self.CWZ)
                self.errNAK ()
            else: # es war ein DLE, senden ausführen
                self.sendstream (self.sendbuff)
                self.setnewstep (2)

    # Schritt 2: Gesendeter Datenstream muss mit DLE vom Empfänger bestätigt werden
    # DLE muss innerhalt der QVZ kommen
    def schritt_2 (self):
        if self.stepdauer>self.QVZ:
            # Quittungsverzugszeit ist abgelaufen
            if self.CFG_PRINT:
                print (" 15s [NAK: QVZ-BCC]")
            self.sendERR +=1 # sendefehler um 1 erhöhen
            self.SetSendDelay (self.BWZ)
            self.errNAK ()
        elif self.RS232.inWaiting ():
            # Zeichen wurde eingelesen, es muss ein DLE sein
            c= self.RS232.read ()
            if c!= self.DLE:            
                # Es war aber kein DLE
                if self.CFG_PRINT:
                    print ("%3.2X"% ord (c) + "r 15s [NAK: DLE-BCC]")
                self.sendERR +=1 # Verbindungsaufbaufehler um 1 erhöhen
                self.SetSendDelay (self.BWZ)
                self.errNAK ()
            else: # es war ein DLE, Telegramm wurde erfolgreich versendet
                if self.CFG_PRINT:
                    print (" 10r [OK]")
                self.WriteSuccess (self.sendbuff) # Virtuelle Routine
                self.sendbuff=b"" # Sendepuffer löschen, das telegramm austragen
                self.SetSendDelay (self.SPZ)
                self.setnewstep (0)

    # Schritt 3: Verbindungsaufbau von uns angestossen, wir wollen senden
    # Von uns wurde ein STX gesendet, es darf nun als Antwort kommen:
    # STX: Der Partner will selber senden
    # DLE: Alles ok, wir senden
    def schritt_3 (self):
        if self.stepdauer>self.QVZ:
            # Quittungsverzugszeit ist abgelaufen
            if self.CFG_PRINT:
                print (" 15s [NAK: QVZ-DLE START]")
            self.sendERR +=1 # sendefehler um 1 erhöhen
            self.SetSendDelay (self.CWZ)
            self.errNAK ()
        elif self.RS232.inWaiting ():
            c= self.RS232.read ()
            if c== self.DLE:
                # Das eingelesene Zeichen ist ein DLE
                # wunderbar, alles, ok, wir können senden
                self.sendstream (self.sendbuff)
                # Nach dem Senden muss mit DLE vom empfänger bestätigt werden
                self.setnewstep (2)
            elif c== self.STX:
                # Wir bekommen als Antwort auf unser STX ebenfalls ein STX zurück
                # der Klassische Initialisierungskonflikt
                if not self.CFG_PRIO:
                    # Unser Treiber hat Low Prio also alles OK, wir müssen mit DLE antworten
                    # Es folgt nun ganz normales Empfangen
                    if self.CFG_PRINT:
                        print (" 02r",end="")
                    self.setnewstep (4)
                else: # Nu gibts ein Problem.
                    # Unserer Treiber läuft auf High Prio, und die Gegenseite setzte auch ein STX ab
                    # Die Gegenseite ist also auch im High Prio Mode
                    # das ist eine etwas unkluge Sache in dem Moment
                    # wir geben ein NAK raus und initialieren neu
                    # REV 2. wir geben trotz High Prio nach und senden ein DLE
                    #if self.CFG_PRINT:
                    #    print (" 02r",end="")
                    #self.setnewstep (4)   
                    
                    if self.CFG_PRINT:
                        print (" 02r 15s [NAK: STX-STX PRIO]")
                    self.connectERR +=1 # connectfehler um 1 erhöhen
                    self.SetSendDelay (0)
                    self.errNAK ()
            else:
                if self.CFG_PRINT:
                    print ("%3.2X"% ord (c) + "r 15s [NAK: DLE-START]")
                self.connectERR +=1 # Verbindungsaufbaufehler um 1 erhöhen             
                self.SetSendDelay (self.CWZ)                
                self.errNAK ()
      

    # Schritt 4: Empfangen der Daten, Verbindungsaufbau
    # Es wird das DLE gesendet f+r_ wir sind empfangsbereit
    # Danach muss innerhalb der QVZ der Stream beginnen
    def schritt_4 (self):
        if self.newstep:
            if self.CFG_PRINT:
                print (" 10s",end="")
            self.RS232.flushOutput ()
            self.RS232.flushInput ()
            self.RS232.write (self.DLE)          
        # Nach dem DLE muss nun innerhalt der ZVZ der Datenstream beginnen
        if self.stepdauer>self.ZVZ:
            # Zeichenverzugszeit ist abgelaufen NAK fehler
            if self.CFG_PRINT:
                print (" 15s [NAK: ZVZ-START]")            
            self.errNAK ()  
        elif self.RS232.inWaiting ():
            # Zeichen innerhalb der Zeit im Puffer, alles ist gut
            self.setnewstep (5)  

    # Schritt 5: Empfangen Datenstream
    # der Datenstream wird empfangen, bis der Parser die Sequenz DLE ETX erkennt
    def schritt_5 (self):
        # Wenn der Schritt neu aufgerufen wird, dann STX_EN auf False setzen
        if self.newstep:
            self.STX_EN  =False
            self.BCC_EN  =False
            self.readbuff=b""
        # Abfrage der Zeichenverzugszeit
        # Zeichenverzug ist aufgetreten (NAK wird gesendet)
        # Empfangsfehler hochzählen
        if t.time ()-self.starttime > self.ZVZ:
            if self.CFG_PRINT:
                print (" 15s [NAK: ERR-ZVZ]")
            self.errNAK ()
        else:    
            #solange wie zeichen im puffer oder EndeStream nicht erkannt    
            while self.RS232.inWaiting():
                #zeichen aus dem puffer lesen
                c=self.RS232.read ()
                self.starttime=t.time () # Zeit setzen beim letzten Empfangenen Zeichen
                if self.CFG_PRINT:
                    print("%3.2X"% ord (c) + "r",end="")
                self.readbuff=self.readbuff+c    
                if self.BCC_EN:
                    rec=self.inframe (self.readbuff)
                    if rec is None:
                        # Fehler beim Zerlegen vom Inframe oder Checksum fehler
                        if self.CFG_PRINT:
                            print (" 15s [NAK: ERR-BCC]")
                        self.errNAK ()
                    else:    
                        if self.CFG_PRINT:
                            print (" 10s [DLE: OK]")
                        self.ReadSuccess (rec)                               
                        self.RS232.flushInput ()
                        self.RS232.flushOutput ()                      
                        t.sleep (self.SLP) # Für die erlaubte Quittungsverzugszeit legt sich der Prozess mal schlafen
                        self.RS232.write (self.DLE)
                    self.setnewstep (0)    
                    break
                elif (c==self.DLE):
                    self.STX_EN= not (self.STX_EN)
                elif ((c==self.ETX) and self.STX_EN):
                    self.BCC_EN= True # Endekennung gültig erkannt, nun das BCC als letztes Zeichen
                else:
                    self.STX_EN=False
                    self.BCC_EN=False
        return

    
    # Wird immer ausgeführt vor den Schritten
    def schritt (self):
        options = {0 : self.schritt_0,1: self.schritt_1, 2: self.schritt_2, 3: self.schritt_3, 4: self.schritt_4, 5: self.schritt_5}
        options [self.step]()



dieses Teil unter python als c3964r.py abspeichern.

wenn ers dann nicht findet, stimmt das import verzeichnis nicht, bei mir liegts im gateway unter /home/pi



ähm, und die KM271 steckt wie auf dem bild auf meiner page im richtigen Slot der 2107 ? dumme frage sorry. aber die einfachsten fehler sind meist die die man übersieht
Wenn das Fernsehprogramm immer mehr durch nervende Werbung unterbrochen wird und der Radiomoderator nur noch Müll erzählt, ist es besser, die Zeit für sinnvolle Dinge zu nutzen -
mal aufs Klo zu gehen, ein Bier zu holen oder einfach mal den roten AUS-Knopf zu drücken. Klick - und weg

Script Time Scheduler V1.3
AstroSteuerung über Zeitmodul flexibel mit Offset / spätestens, frühestens
SDV 5.03.01 Das umfassende Entwicklungs und Diagnosetool für Homematik
Selektive Backups - Nützliche Dinge, die die WebUI nicht kann

Intel NUC6 Celeron 16GB mit 512GB SSD unter Proxxmox mit insgesamt 5 VM: 2 x bloatwarebefreiter Raspberrymatik, 2 x IOBroker als Middleware und einer MariaDB zur Archivierung. Verbrauch: 6W

technical contribution against annoying advertising

marc25111
Beiträge: 10
Registriert: 27.10.2016, 11:37

Re: Buderus Logamatic 2107 an CCU2 (Projekt abgeschlossen)

Beitrag von marc25111 » 17.01.2017, 23:00

Hey,

cool und Danke für die abendliche Antwort!

OK, das mit den 2400 hatte ich in der Tat übersehen... Danke.

Ja,
vielleicht noch mal zu den basics (und dumme Fragen erleuchten meist ungemein *gg*):
vor der Heizung stehend (auf das Display der Logo schauend):

Aus dieser Sicht steckt das KM im hintersten Slot (hätte ich jetzt Deinem Bild so entnommen).

Wenn ich dabei auf den D-Sup Stecker schaue ist in der 5er - Reihe (von meiner Perspektive die hintere) die linkeste Buchse die Nr. 5 Für GND und der 2. & 3. von rechts sind TX und RX, richtig?
-> Nur um sicher zu gehen!

Das KM - modul braucht keinen Strom o.ä. extra -> Habe ich Deinen Fotos so entnommen...
Irgendwo auf der Serviceebene oder sonst wo muss das auch nicht aktiviert werden, richtig?

Mich wundert jetzt beim Ausführen Deiner main:

Code: Alles auswählen

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner
    self.run()
  File "main.py", line 36, in run
    while not ende:
NameError: name 'ende' is not defined
Und zu guter letzt um mich komplett zu verwirren:
im Treiber auf der HP (3964r.py) sehe ich:
def __init__ (self,port=None,baudrate=9600 ...

müssen da auch die 2400 rein ?

Unabhängig davon, wenn ich jetzt das korrigierte test Script ausführe:

Code: Alles auswählen

import serial

s = serial.Serial(           
               port='/dev/ttyAMA0',
               baudrate = 2400,
               parity=serial.PARITY_NONE,
               stopbits=serial.STOPBITS_ONE,
               bytesize=serial.EIGHTBITS,
               timeout=1)

post=False
print (s.name )

#0xEE 0x00 0x00 0x10 0x03 0xFD
s.flushInput ()
s.flushOutput ()
s.write (b"\x02")
while True:
    if s.inWaiting ():
        char= s.read ()
        if len (char):
            print ("%3.2X"% ord (char))
            if ord (char)== 0x10:
                s.write (b"\xEE\x00\x00\x10\x03\xFD")
                post=True
            elif ord (char)== 0x02:
                if post:
                    s.write (b"\x10")
            elif not post:
                s.write (b"\x02")
Sollte ich doch zumindest eine Antwort bekommen, oder?

DANKE

Benutzeravatar
Black
Beiträge: 5480
Registriert: 12.09.2015, 22:31
System: Alternative CCU (auf Basis OCCU)
Wohnort: Wegberg
Hat sich bedankt: 424 Mal
Danksagung erhalten: 1074 Mal
Kontaktdaten:

Re: Buderus Logamatic 2107 an CCU2 (Projekt abgeschlossen)

Beitrag von Black » 17.01.2017, 23:19

wenn du nur ein listen auf der schnittstelle machst solltest du von der logamatik so alle 2 sekunden ein STX bekommen, heisst, sie stellt gemäs 3964r spezifikation eine sendeanforderung. die 2107 hat aber low prio.

wenn du nun selber ein STX sendest, muss die logamatik mit DLE antworten.

wenn das kam, kannst den logmode string absetzen, sobald sie den mit DLE quittiert hat, fängt die an zu quasseln.

wenn vorher kein STX bekommst stimmt irgendwas nicht.

deiner beschreibung nach hast die richtig eingebaut. die KM271 braucht auch keine separate spannung, ich hoffe, du hast die nicht unter spannung ein gesteckt, sondern bei hauptschalter aus.
du kannst erkennen, ob die KM erkannt wird, wenn ins konfig menu der 2107 gehst, musst du auch ein neues menü haben, und zwar die abgastemperatur (mal ins handbuch schauen wo das steht). natürlich auf "aus" belassen, da du ja keinen fühler angeschlossen hast, sonst kommt direkt eine störung. das menü bekommst du nur, wenn eine KM271 steckt. hast das nicht, wird die KM nicht erkannt.

ist das eine originale oder der nachbau aus dem Mikrocontroller.net forum ? die tuts nämlich net so 100 % ig

Zu deiner Frage mit den Baudraten:
das:
"..Und zu guter letzt um mich komplett zu verwirren:
im Treiber auf der HP (3964r.py) sehe ich:
def __init__ (self,port=None,baudrate=9600 ..."

ist die abstrakte default initialisierung. ich hab ja oben schon mal geschrieben, das c3964r ist nur die treiberklasse:

in dem übergeordneten klasse, die dann die eigenschaften der c3964r erbt,
erfolgt dann die scharfe und richtige Einstellung im constructor der abgeleiteten Klasse

Code: Alles auswählen

class logamatic2107 (c3964r.Dust3964r,threading.Thread):
    message = True
    timeout = False
    # Array für die Betriebsstunden
    #[0]= minuten
    #[1]= minuten * 256
    #[2]= minuten * 65536
    aHour   = [0,0,0]

    # Installations Konstruktor für den Treiber und für die Threads
    def __init__ (self):
        self.timeout = False
        c3964r.Dust3964r.__init__ (self,port='/dev/ttyAMA0',baudrate=2400,SLP=0.1,PRIO=self.HIPRIO)
        threading.Thread.__init__ (self)
        self.TimeStampMessage= t.time()


gruss, black
Wenn das Fernsehprogramm immer mehr durch nervende Werbung unterbrochen wird und der Radiomoderator nur noch Müll erzählt, ist es besser, die Zeit für sinnvolle Dinge zu nutzen -
mal aufs Klo zu gehen, ein Bier zu holen oder einfach mal den roten AUS-Knopf zu drücken. Klick - und weg

Script Time Scheduler V1.3
AstroSteuerung über Zeitmodul flexibel mit Offset / spätestens, frühestens
SDV 5.03.01 Das umfassende Entwicklungs und Diagnosetool für Homematik
Selektive Backups - Nützliche Dinge, die die WebUI nicht kann

Intel NUC6 Celeron 16GB mit 512GB SSD unter Proxxmox mit insgesamt 5 VM: 2 x bloatwarebefreiter Raspberrymatik, 2 x IOBroker als Middleware und einer MariaDB zur Archivierung. Verbrauch: 6W

technical contribution against annoying advertising

marc25111
Beiträge: 10
Registriert: 27.10.2016, 11:37

Re: Buderus Logamatic 2107 an CCU2 (Projekt abgeschlossen)

Beitrag von marc25111 » 20.01.2017, 22:51

Schönen guten Abend,

:D Klar, natürlich hab ich das Modul bei ausgeschalteter Heizung reingeschoben. Bin sogar auf Nummer sicher gegangen und hab die Sicherung raus, da ich nicht drauf gewettet hätte das da noch irgendwo Spannung rum geistert :lol:

heute abends hab ich mir jetzt noch einmal intensiv Zeit genommen mich mit dem Thema zu beschäftigen. Das Ergebnis ist jetzt, dass ich denke, dass es eine gewisse Kommunikation gibt (Jetzt sind alle Kabel PINs wirklich richtig und auch der Pi müsste passen).

Getestet hab ich mit folgendem Script:

Code: Alles auswählen

#!/usr/bin/env python
          
import time
import serial
          
      
ser = serial.Serial(            
               port='/dev/ttyAMA0',
               baudrate = 2400,
               parity=serial.PARITY_NONE,
               stopbits=serial.STOPBITS_ONE,
               bytesize=serial.EIGHTBITS,
               timeout=1
           )
counter=0
ser.flushInput ()
ser.flushOutput ()          
ser.write (b"\x02")  
post=False    
while 1:
    if ser.inWaiting ():
        char= ser.read()
        if len (char):
            print ("%3.2X"% ord (char))
            ser.write (b"\xEE\x00\x00\x10\x03\xFD")
            post=True 
        elif ord (char)==0x02:
            if post:
                ser.write (b"\x10")
        elif not post:
                ser.write (b"\x02") 
Und da kommt dann auch tatsächlich eine Antwort:

Code: Alles auswählen

pi@raspberrypi:~ $ sudo python3 new_sertest.py
 FF
 FE
 FE
 FF
 FE
 CF
 9F
 9F
 9F
 9F
 9F
 9F
 9F
 9F
 9F
 9F
Wobei mich 2 Dinge irritieren:

1. danach ist "Sendepause" und auch wenn ich das Script ein 2. Mal ausführe ist Ruhe auf der Schnittstelle bis ich den Pi neu starte (wobei ich an meinen LEDs sehe, dass die 2107 durchaus immer weider ein längeres oder kürzeres Paket sendet) ?!?

2. Aber Grundsätzlich ist das HW - seitig jetzt schon richtig, oder kann es sein, dass hier jetzt noch etwas nicht passt?

Viele Grüße und schönen Start in das Wochenende

Marc

Benutzeravatar
Black
Beiträge: 5480
Registriert: 12.09.2015, 22:31
System: Alternative CCU (auf Basis OCCU)
Wohnort: Wegberg
Hat sich bedankt: 424 Mal
Danksagung erhalten: 1074 Mal
Kontaktdaten:

Re: Buderus Logamatic 2107 an CCU2 (Projekt abgeschlossen)

Beitrag von Black » 21.01.2017, 09:56

ne, das sieht nicht so gut aus...

aber das hier hast du berücksichtigt ?

Serielle Schnittstelle freischalten

Per Voreinstellung ist auf der Schnittstelle, die unter Linux auf /dev/ttyAMA0 angesprochen wird, eine serielle Login-Konsole konfiguriert, auf der auch der gesamte Bootvorgang protokolliert wird. Deshalb kann man diese Schnittstelle nicht so ohne Weiteres für andere Zwecke verwenden. Das bedeutet, dass Sie zuerst die serielle Konsole abschalten müssen. Maßgeblich dafür sind zwei Dateien:

/boot/cmdline.txt
/etc/inittab

Bearbeiten /boot/cmdline.txt

Die Datei /boot/cmdline.txt regelt den Bootvorgang des Pi. Dort werden diverse Boot-Optionen eingestellt, so auch die serielle Konsole. Per Default steht relativ wenig in der Datei, wobei es bei kommenden Versionen schon wieder anders aussehen kann (für die Darstellung hier wurde die Zeile umbrochen!):

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200
console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

Aus diesen Optionen müssen Sie nun die Angaben zur Konsole "ttyAMA0" löschen, aber alles andere unbedingt unverändert lassen. Am Besten machen Sie zuerst ein Backup der Datei (cp /boot/cmdline.txt /boot/cmdline.bak). Dann ändern Sie in der Originaldatei die Zeile:

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200
console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

in die folgende Zeile (oben sind die zu löschenden Teile farbig hervorgehoben):

dwc_otg.lpm_enable=0
console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

Bearbeiten /etc/inittab

Nun wird die Datei /etc/inittab bearbeitet. In ihr ist die serielle Schnittstelle als Login-Schnittstelle definiert. Dazu Öffnen Sie die Datei und bearbeiten den folgenden Eintrag:

#Spawn a getty on Raspberry Pi serial line
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

Ändern Sie die Zeile durch ein davor gestelltes Kommentarzeichen in

#Spawn a getty on Raspberry Pi serial line
# T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

Damit ist die Login-Funktion abgeschaltet. Wenn Sie den Pi nun neu starten, können Sie die serielle Schnittstelle beliebig nutzen.

Damit der User pi auch auf die Schnittstelle zugreifen darf, muss er zusätzlich in die Gruppe "dialout" aufgenommen werden. Das erreichet man mit dem Kommando

sudo usermod -a -G dialout pi

Bei neueren Versionen des Raspian-Betriebssystems kann die Aktivierung/Deaktivierung der Schnittstelle auch über raspi-config erfolgen.

Änderungen beim Raspberry Pi Modell 3

Die neue Bluetooth-4.2-Schnittstelle des Modells 3 wird leider über den PL011-UART angebunden. Dieser UART war bei den Vorgängermodellen für die serielle Schnittstelle auf den GPIO-Pins 8 und 10 zuständig. Nun ist der Mini-UART an diesen GPIO-Pins verfügbar. Der Mini-UART ist eine kleine Variante des ursprünglichen UART, die neben einem geringen Durchsatz auch nicht mehr so stabil ist wie zuvor. Die Baud-Rate des Mini-UART wird vom System-Takt (Videocore IV) abgeleitet. Das bedeutet, dass die Baud-Rate nicht mehr stabil bleibt, sondern je nach CPU-Auslastung stark schwankt. Deshalb schlagen die Entwickler vor, den Core-Takt fest auf 250 MHz einzustellen. Alternativ kann, falls nicht benötigt, Bluetooth mittels Devicetree-Overlay abgeschaltet werden. Dazu fügen Sie am Ende der Datei /boot/config.txt die Zeile

dtoverlay=pi3-miniuart-bt

hinzu. Nach einem Neustart funktioniert der UART wieder wie in den Vorgängerversionen.

weil diese werte die du da sieht sagen erstmal gar nix , ich sehe in deiner Kommunikation kein STX und auch kein DLE

greetz, Black
Wenn das Fernsehprogramm immer mehr durch nervende Werbung unterbrochen wird und der Radiomoderator nur noch Müll erzählt, ist es besser, die Zeit für sinnvolle Dinge zu nutzen -
mal aufs Klo zu gehen, ein Bier zu holen oder einfach mal den roten AUS-Knopf zu drücken. Klick - und weg

Script Time Scheduler V1.3
AstroSteuerung über Zeitmodul flexibel mit Offset / spätestens, frühestens
SDV 5.03.01 Das umfassende Entwicklungs und Diagnosetool für Homematik
Selektive Backups - Nützliche Dinge, die die WebUI nicht kann

Intel NUC6 Celeron 16GB mit 512GB SSD unter Proxxmox mit insgesamt 5 VM: 2 x bloatwarebefreiter Raspberrymatik, 2 x IOBroker als Middleware und einer MariaDB zur Archivierung. Verbrauch: 6W

technical contribution against annoying advertising

hermanthegerman2
Beiträge: 11
Registriert: 09.10.2015, 16:13

Re: Buderus Logamatic 2107 an CCU2 (Projekt abgeschlossen)

Beitrag von hermanthegerman2 » 02.02.2017, 20:36

Hallo Black,

hast Du eigentlich vor Deinen genialen Python-Code mal zu veröffentlichen bzw. weiterzugeben?
Ich würde den Code immer noch gerne für meine Logamatic4000 anpassen und bin eben wieder über diesen Thread "gestolpert".
Vor allem die Klassen für das Logging und die weitere Kommuniation über Socket an die CCU (soll bei mir dann Symcon sein) wäre interessant.

Gruß,
hermanthegerman2

Antworten

Zurück zu „Projektvorstellungen“