Ankündigung

Einklappen
Keine Ankündigung bisher.

Anbindung Modbus / Nibe

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • DerSeppel
    antwortet
    Bei mir nähert sich der Bau langsam der Fertigstellung. Es ist eine Nibe F1145 verbaut.
    Da es sich um ein aktuelles Gerät handelt, habe ich überlegt Daten ggf. per Webcrawler aus dem Nibe Uplink Webinterface zu holen.
    Die hier beschriebene Methode sieht mir allerdings umfänglicher aus.
    Leider kann ich keine Info mehr finden, wo genau ich den Pin-Header finde.
    Hat jemand von euch mal ein Foto von seinem Aufbau an der WP?

    Einen Kommentar schreiben:


  • max3004
    antwortet
    Wenn ich mit 19.200 lese, dann bekomme ich bei meiner 1240 folgenden output:
    0004760 f6 fe 56 fa 00 7e 7e 54 7e d5 0e f6 fe 56 fa 00
    v ~ V z nul ~ ~ T ~ U so v ~ V z nul
    0005000 7e 7e 34 7e 7e 5c 00 34 7e 7e 5c 00 34 7e 25 0e
    ~ ~ 4 ~ ~ \ nul 4 ~ ~ \ nul 4 ~ % so
    0005020 fe 5e 00 fd 7e 25 1a e2 54 e4 b4 ec 54 bc dc 8c
    ~ ^ nul } ~ % sub b T d 4 l T < \ ff
    0005040 60 e4 00 34 7e cd 0e f2 fe fe fe 84 cc f2 00 54
    ` d nul 4 ~ M so r ~ ~ ~ eot L r nul T
    0005060 7e d5 0e f6 fe 56 fa 00 7e 7e 54 7e d5 0e f6 fe
    ~ U so v ~ V z nul ~ ~ T ~ U so v ~
    0005100 56 fa 00 7e 7e 34 7e d7 0e d2 7e fc fc fc 5c 3c
    V z nul ~ ~ 4 ~ W so R ~ | | | \ <
    0005120 8c 44 7c 91 f3 fe cc f2 00 34 7e d6 0e aa 3a 8c
    ff D | dc1 s ~ L r nul 4 ~ V so * : ff
    0005140 7c fc fc fc fc fc fc fc fc fc fc fc fc 6c 6c 2c
    | | | | | | | | | | | | | l l ,
    0005160 74 54 fe 52 60 f2 00 34 7e 6b 0e ba f6 6c f4 54
    t T ~ R ` r nul 4 ~ k so : v l t T
    0005200 e4 bc 44 f4 64 64 d4 6c 5c d4 94 7c fc 8a cc f2
    d < D t d d T l \ T dc4 | | nl L r

    Das sieht nicht wirklich nach einzelnen Frames aus, oder? Ich kann zumindest kein 06 03 00 erkennen.

    Was könnte hier falsch sein?

    Einen Kommentar schreiben:


  • max3004
    antwortet
    Wen ich dass nun auch mit smartVISU bzw. smarthome.py machen möchte fehlt mir irgendwie die Oberfläche dazu.
    Hat jemand da schon etwas gebastelt?

    Im logfile steht bei mir: 2015-02-20 14:25:35 WARNING nibe nibe: index out of range

    Einen Kommentar schreiben:


  • max3004
    antwortet
    So, kleiner Zwischenstand:

    Ich habe alles noch einmal auseinandergeschraubt und das Kabel neu gecrimpt.

    Jetzt bekomme ich Werte über /dev/ttyUSB0 und das Display friert auch nicht mehr ein (juhu!). (Hinweis: Raspi-User in Gruppe dialout aufnehmen)

    Eine GND-Verbindung ist nicht notwendig. Es sind nur D+ und D- verbunden.

    Nun geht es an die Auswertung :-)

    Einen Kommentar schreiben:


  • brandst
    antwortet
    Hast du in dem Menü Logging aktiviert? Bei mir ist das Display nur eingefroren, wenn ich probiert habe mich über den Raspberry mittels stty an den Datenstrom zu hängen. Das bloße Anstecken der Leitung hat bei mir keine Probleme gemacht. Deinem Link zu urteilen, gibt es bei dem Umwandler kein GND sondern nur die Datenbelegung - vielleicht ist es das?

    Vorgehensweise meiner Meinung nach:

    1. Logging Konfiguration überprüfen (siehe diesen Thread)
    2. Verkabelung überprüfen (steht glaub ich auf Seite 2)
    3. Kabeln anstecken - überprüfen ob das Display noch funktioniert und Komm-Fehler auswirft (passiert, wenn das Programm ohne "w" Parameter aufgerufen wurde.
    4. Programm starten

    Einen Kommentar schreiben:


  • max3004
    antwortet
    Wenn ich eine RS485/USB Konverter (J34 Free Shipping USB to RS485 485 Converter Adapter Support Win7 XP Vista Linux Mac OS WinCE5.0 on Aliexpress.com | Alibaba Group) an die Nibe 1250 und einen RasPi anschließe, dann friert bei mir sofort das Display ein (RCU=on).

    Wie habt ihr das umgangen? Muss man erst das Programm starten, damit die Acks gesendet werden? So ganz transparent ist mir dieser Punkt nicht.

    @brandst: wie hast Du das Problem gelöst?

    Einen Kommentar schreiben:


  • eddso
    antwortet
    Hier die benötigten Dateien

    smarthome/plugins/nibe/__init__py
    Code:
    #!/usr/bin/env python3
    # vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
    #########################################################################
    #  Copyright 2013 KNX-User-Forum e.V.           https://knx-user-forum.de/
    #########################################################################
    #  NIBE plugin for SmartHome.py.         http://mknx.github.io/smarthome/
    #
    #  This plugin is free software: you can redistribute it and/or modify
    #  it under the terms of the GNU General Public License as published by
    #  the Free Software Foundation, either version 3 of the License, or
    #  (at your option) any later version.
    #
    #  This plugin is distributed in the hope that it will be useful,
    #  but WITHOUT ANY WARRANTY; without even the implied warranty of
    #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    #  GNU General Public License for more details.
    #
    #  You should have received a copy of the GNU General Public License
    #  along with this plugin. If not, see <http://www.gnu.org/licenses/>.
    #########################################################################
    
    import logging
    import serial
    import re
    import time
    import termios
    from struct import *
    
    logger = logging.getLogger('NIBE')
    
    class NIBE():
        def __init__(self, smarthome, serialport):
            self._sh = smarthome
            self._nibe_regs = {}
            self._serial = serial.Serial(serialport, 19200, bytesize=serial.EIGHTBITS, stopbits=serial.STOPBITS_ONE, timeout=3)
            iflag, oflag, cflag, lflag, ispeed, ospeed, cc = termios.tcgetattr(self._serial)
            CMSPAR = 0x40000000
            cflag |= termios.PARENB | CMSPAR | termios.PARODD # to select MARK parity
            termios.tcsetattr(self._serial, termios.TCSANOW, [iflag, oflag, cflag, lflag, ispeed, ospeed, cc])
        
        def run(self):
            self.alive = True
            try:
                while self.alive:
                    #time.sleep(0.001)
                    if self._serial.read(1)[0] != 0x03:
                        continue
                    ret = self._serial.read(2)
                    if ret[0] != 0x00 or ret[1] != 0x14:
                        continue
                    
                    self._serial.write(b"\x06")
                    
                    frm = bytes()
                    frm += self._serial.read(4) #<C0> <00> <59> <len>
                    if frm[0] == 0x03:
                        continue
                    
                    l = int(frm[3])
                    frm += self._serial.read(l+1)
                    
                    self._serial.write(b"\x06")
                    
                    crc = 0
                    for i in frm[:-1]:
                        crc ^= i
                    if crc != frm[-1]:
                        logger.warning("frame crc error")
                        continue
                    
                    msg = frm[4:-1]
                    l = len(msg)
                    i = 4
                    while i <= l:
                        reg = msg[i-3]
                        if i != l and (msg[i] == 0x00 or i == (l-1)):
                            raw = bytes([msg[i-2],msg[i-1]])
                            i+=4
                        else:
                            raw = bytes([msg[i-2]])
                            i+=3
                        
                        if not reg in self._nibe_regs:
                            continue
                        
                        if self._nibe_regs[reg]['raw'] == raw:
                            continue
                            
                        value = self._decode(reg, raw)
                        logger.debug("update_item: reg:{0} = {1}".format(reg,value))
                        self._nibe_regs[reg]['raw'] = raw
                        for item in self._nibe_regs[reg]['items']:
                            item(value, 'NIBE', 'REG {}'.format(reg))
                            
            except Exception as e:
                logger.warning("nibe: {0}".format(e))
    
        def stop(self):
            self.alive = False
            self._serial.close()
            
        def parse_item(self, item):
            if 'nibe_reg' in item.conf:
                logger.debug("parse item: {0}".format(item))
                nibe_reg = int(item.conf['nibe_reg'])
                if not nibe_reg in self._nibe_regs:
                    self._nibe_regs[nibe_reg] = {'items': [item], 'logics': [], 'raw':0}
                else:
                    self._nibe_regs[nibe_reg]['items'].append(item)
            return None
        
        def _decode(self, reg, raw):
            if len(raw) == 2:
                value = unpack('>H',raw)[0]
            else:
                value = unpack('B',raw)[0]
                
            if reg in [0,32,33,34,35,36,38,44,45,46,48,100,101,102,103,104,105]:    
                #0    CPUID
                #32   Zusatzheizung erlaubt   
                #33   Max dF Commpressor   
                #34   Verd. Freq. regP   
                #35   Min Startzeit Freq min
                #36   Minzeit konst. Freq min
                #38   Verd. Freq. GradMin   
                #44   Pumpengeschwindigkeit %
                #45   Bw reg P   
                #46   Bw reg Q   
                #48   Bw reg Wert xP %
                #100  Datum - Jahr
                #101  Datum - Monat
                #102  Datum - Tag
                #103  Uhrzeit - Stunde
                #104  Uhrzeit - Minute
                #105  Uhrzeit - Sekunden
                return int(value)
                
            if reg == 31:
                #31   Status Heizung
                #1 Auto
                #3 Heizung
                #5 Brauchwasser
                #6 Zusatzheizung
                return int(value)
                
            if reg in [4,8]: #signed
                #4    Heizkurvenverschiebung
                #8    Gradminuten
                return int(unpack('h',pack('H',value))[0]/10)
                
            if reg == 25: #unsigned
                #25   Verdichterstarts
                return int(value/10)
                
            if reg in [1,5,6,7,11,12,13,14,15,16,17,18,21,23,27,37]: #signed
                #1    Aussentemp °C        
                #5    Vorlauf Soll °C
                #6    Vorlauf Ist °C
                #7    Ruecklauf °C
                #11   Kondensator aus (MAX) °C
                #12   Brauchwasser oben °C
                #13   Brauchwasser unten °C
                #14   Verd. Temp. Tho-R1 °C
                #15   Verd. Temp. Tho-R2 °C
                #16   Sauggas Temp. Tho-S °C
                #17   Heissgas Temp. Tho-D °C
                #18   Fluessigkeitstemp AMS °C
                #21   Atemp. am AMS Tho-A °C
                #23   Invertertemp. Tho-IP °C
                #27   Vorlauf °C
                #37   Max Diff. soll-ber °C
                return float(unpack('h',pack('H',value))[0]/10)
                
            if reg in [9,10,19,20,22,24]: #unsigned
                 #9    Verd. Freq. Soll Hz
                #10   Verd. Freq. Ist Hz
                #19   Hochdruck bar
                #20   Niederdruck bar
                #22   AMS Phase Ist A
                #24   Verdichterlaufzeit h
                return float(value/10)
                
            if reg in [40,47]: #unsigned
                #40   Hysterese °C
                #47   Bw reg xP
                return float(value/2)
                
            if reg in [43,49,50]:
                #43   Stopptemp. Heizen °C
                #49   Brauchwasser StartTemp °C 1.2
                #50   Brauchwasser StopTemp °C  1.3
                return float(value)
            
            #2    ?
            #3    ?
            #26   ?
            #28   ?
            #29   ?
            #30   ?
            #39   ?
            #41   ?
            #42   ?
            return value
    smarthome/items/nibe.conf
    Code:
    [heating]
    	[[operating_state]]
    		type = num
    		nibe_reg = 31
    	[[heating_curve]]
    		type = num
    		nibe_reg = 4
    	[[circ_pump_speed_heat_p]]
    		type = num
    		nibe_reg = 44
    	[[number_of_starts]]
    		type = num
    		nibe_reg = 25
    	[[outdoor_temp_c]]
    		type = num
    		nibe_reg = 1
    	[[supply_temp_c]]
    		type = num
    		nibe_reg = 6
    	[[return_temp_c]]
    		type = num
    		nibe_reg = 7
    	[[run_time_compressor_h]]
    		type = num
    		nibe_reg = 24
    	[[hot_water_temp_c]]
    		type = num
    		nibe_reg = 12
    	[[degree_minutes]]
    		type = num
    		nibe_reg = 8
    smarthome/etc/plugin.conf
    Code:
    [nibe]
        class_name = NIBE
        class_path = plugins.nibe
        serialport = /dev/ttyUSB0
    serialport natürlich anpassen.

    Gruß
    Eduard

    Einen Kommentar schreiben:


  • brandst
    antwortet
    Ja bitte, poste mal das Plugin. Wg. der Last ich habe dzt. auf meinem virtuellen Server auch eine Last von ca. 5% CPU (und das läuft auf einem Xeon). Allerdings glaube ich, dass mein USB-Passthrough ein wenig verbuggt ist, da auch das D&W KWL Plugin von sh.py über FTDI 99% Last verursacht.

    Einen Kommentar schreiben:


  • eddso
    antwortet
    Hi,
    Ich vermute du hast kein Zeilenumbruch in der letzter Zeile. Hinter jeder Zeile mus \n sein.

    Ich hatte mal für sh.py ein plugin gemacht https://knx-user-forum.de/414704-post13.html, funktioniert auch ganz gut aber macht zu viel last auf dem raspy etwa 10%. Wenn einer interesse hat kan ich hier mit config posten.

    NIBE über C Programm an sh.py anbinden ist zwar ein Umweg aber belastet ein System weniger.

    Gruß
    Eduard

    Einen Kommentar schreiben:


  • brandst
    antwortet
    Kommando zurück - Das Register 25 funktioniert. Allerdings darf es in der Konfiguration nicht als letztes Objekt stehen, da das Programm den letzten Parameter nicht ausliest. Kannst du das bei dir auch nachvollziehen?

    Einen Kommentar schreiben:


  • brandst
    antwortet
    Ok, anscheinend dürfte das dann nicht bei allen Nibe funktionieren - könntest du es bei dir mal antesten?

    Ich merke bei mir keine Veränderung der Reaktionszeiten am Display. Läuft alles wie gehabt. Der Komm-Fehler ist weg bei der Option "Write" also dem ACK.

    Einen Kommentar schreiben:


  • ctr
    antwortet
    Register 25 kannte ich noch gar nicht, das hatte edso erst herausgefunden und dokumentiert...
    Hast Du die Display-Freezer wenn das Programm läuft (und damit die ACKs gesendet werden) auch noch?

    Einen Kommentar schreiben:


  • brandst
    antwortet
    Danke für die Konfiguration,

    meine sieht so ähnlich aus. Dein Programm loggt auch schon munter - allerdings bekomme ich keine Werte der Verdichterstarts. Alles andere funktioniert nur dieser Wert nicht. Ging das bei dir schon mal? Ich habe dafür:

    25,1,12001,4/4/23

    Einen Kommentar schreiben:


  • ctr
    antwortet
    Ich verwende folgende Config:
    Code:
    1,0.1,9001,0/3/101
    5,0.1,9001,0/3/105
    6,0.1,9001,0/3/106
    7,0.1,9001,0/3/107
    12,0.1,9001,0/3/112
    13,0.1,9001,0/3/113
    Sorry für die späte Antwort, war im Urlaub...

    Einen Kommentar schreiben:


  • brandst
    antwortet
    So,

    ich habe meine Konfiguration mit deinem Programm getestet. Ich habe auch gleich den Fehler in der Parametrisierung geändert (bekam immer einen Fehler beim Config-File einlesen). Die Änderung werde ich dir als Patch-Request in GIT schicken. Zusätzlich arbeite ich auch daran den USB-RS485 Konverter über die Serial anzusprechen, da ich auf meinem Server zwei FDTI-Geräte mit gleicher Vendor- und Product-ID hängen habe, und es anscheinend trotz impliziter Angabe des Devices zu Kollisionen kommt.

    Eine Bitte hätte ich an dich - könntest du mir deine Konfigurationsdatei schicken bzw. hier online stellen, damit ich nicht alle Parameter zusammensuchen muss?

    Danke und Lg

    Thomas

    Einen Kommentar schreiben:

Lädt...
X