Ankündigung

Einklappen
Keine Ankündigung bisher.

DMX Plugin für DMX512a USB devices

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

  • fmeister
    antwortet
    Plugin soweit fertig

    für die die es Interessiert:

    Code:
    #########################################################################
    # Copyright 2011 KNX-User-Forum e.V.            https://knx-user-forum.de/
    #########################################################################
    #  This file is part of SmartHome.py.   http://smarthome.sourceforge.net/
    #
    #  SmartHome.py 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.
    #
    #  SmartHome.py 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 SmartHome.py. If not, see <http://www.gnu.org/licenses/>.
    #########################################################################
    
    import logging
    import threading
    import serial
    
    logger = logging.getLogger('')
    
    DMXOPEN=chr(126)
    DMXCLOSE=chr(231)
    DMXINIT1=chr(03)+chr(02)+chr(0)+chr(0)+chr(0)
    DMXINIT2=chr(10)+chr(02)+chr(0)+chr(0)+chr(0)
    DMXINTENSITY=chr(6)+chr(1)+chr(2)
    
    class DMX():
        # _dim = 10^((n-1)/(253/3)-1) by JNK from KNX UF
        #_dim = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25, 26, 26, 27, 28, 29, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 50, 51, 52, 54, 55, 57, 58, 60, 62, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 86, 88, 90, 93, 95, 98, 101, 104, 106, 109, 112, 115, 119, 122, 125, 129, 132, 136, 140, 144, 148, 152, 156, 160, 165, 169, 174, 179, 184, 189, 194, 199, 205, 211, 216, 222, 228, 235, 241, 248, 255 ]
    
    
        def __init__(self, smarthome, tty, adapter):
            logger.debug("Init DMX...")
            self._dmxdata=[chr(0)]*513
            self._sh = smarthome
            self._adapter = adapter
            self._is_connected = False
            self._lock = threading.Lock()
    
            try:
                self._port = serial.Serial(tty, 38400, timeout=1)
            except:
                logger.error("Could not open %s." % tty)
                return
            else:
                self._is_connected = True
            if not self._send_nanodmx("C?") and adapter == "nanodmx":
                logger.warning("Could not communicate with dmx adapter.")
                self._is_connected = False
            if adapter == "dmx512a":
                self._port.write(DMXOPEN+DMXINIT1+DMXCLOSE)
                self._port.write(DMXOPEN+DMXINIT2+DMXCLOSE)
    
        def _send_dmx512a(self, data):
            lst = list(data)
            debug = ""
            for element in lst:
                debug += str(ord(element))
                debug += ", "
            logger.debug("_send_dmx512a: %s", debug)
            if not self._is_connected:
                return False
            self._lock.acquire()
            self._port.write(data)
            self._lock.release()
            return True
    
        def _send_nanodmx(self, data):
            if not self._is_connected:
                return False
            self._lock.acquire()
            try:
                self._port.write(data)
                ret = self._port.read(1)
            except:
                logger.warning("Problem sending data to dmx adapter.")
                ret = 'F'
            self._lock.release()
            if ret == 'G':
                return True
            else:
                return False
    
        def run(self):
            self.alive = True
    
        def stop(self):
            self._port.close()
            self.alive = False
    
        def send(self, channel, value):
            logger.debug("update dmx channel {0:03d} {1:03d}".format(channel, int(value)))
    	if self._adapter == "nanodmx":
                 logger.debug("%s", self._adapter)
                 self._send_nanodmx("C{0:03d}L{1:03d}".format(int(channel), int(value)))
    	if self._adapter == "dmx512a":
                 logger.debug("%s", self._adapter)
    	     self._dmxdata[channel]=chr(value)
                 debug = ""
                 for element in self._dmxdata:
                     debug += str(ord(element))
                     debug += ", "
                 logger.debug("send: %s", debug)
    	     sdata=''.join(self._dmxdata)
                 logger.debug("%s", sdata)
    	     self._send_dmx512a(DMXOPEN+DMXINTENSITY+sdata+DMXCLOSE)
    
        def parse_item(self, item):
            if 'dmx_ch' in item.conf:
                channels = item.conf['dmx_ch']
                if isinstance(channels, str):
                    channels = [channels, ]
                channels = map(int, channels)
                item.conf['dmx_ch'] = channels
                return self.update_item
            else:
                return None
    
        def update_item(self, item, caller=None, source=None, dest=None):
            #logger.debug("update dmx channel {0:03d}".format(item.dmx_ch))
            for channel in item.conf['dmx_ch']:
                self.send(channel, item())

    Einen Kommentar schreiben:


  • fmeister
    antwortet
    Zitat von 2ndsky Beitrag anzeigen
    Nein, das Plugin selber bleibt als Instanz im Speicher. Jede Variable die mit self.variablenname angelegt wird ist eine Instanzvariable und somit über die komplette Laufzeit von sh.py verfügbar.
    Okay dann wohl ein Fehler im script, danke für die Info!

    Einen Kommentar schreiben:


  • fmeister
    antwortet
    Zitat von vietgilles Beitrag anzeigen
    es sollte normalerweise so sein, dass das USB/DMX Modul die DMX Daten empfängt, speichert und auf den Bus ausgibt, bis zur nächsten Änderung, dann wird aber nur der Kanal geädert, der sich verändert hat.
    Danke für die Info, mein USB DMX Adapter macht das genau so. Der einzige Unterschied ist das Protokoll. Beim nanoDMX kann man einzelne Kanäle gezielt ändern. Bei meinem muss ich das komplette Array pushen (einmal) - die Wiederholung passiert dann automatisch.

    Einen Kommentar schreiben:


  • 2ndsky
    antwortet
    DMX Plugin für DMX512a USB devices

    Zitat von fmeister Beitrag anzeigen
    Da man keine einzelnen Kanäle aktualisieren kann, brauche ich ein Array dass während der Laufzeit von smarthome.py erhalten bleibt. Soweit ich das nachvollziehen kann, wird das Plugin ausgeführt und danach wieder beendet (was ja auch logisch ist).
    Nein, das Plugin selber bleibt als Instanz im Speicher. Jede Variable die mit self.variablenname angelegt wird ist eine Instanzvariable und somit über die komplette Laufzeit von sh.py verfügbar.

    Einen Kommentar schreiben:


  • vietgilles
    antwortet
    Hi,

    es sollte normalerweise so sein, dass das USB/DMX Modul die DMX Daten empfängt, speichert und auf den Bus ausgibt, bis zur nächsten Änderung, dann wird aber nur der Kanal geädert, der sich verändert hat. Dazu ist das Modul nur da, gleichzeitig entlastet es die USB Schnittstelle (Typ 1.1) und den Rechner. Eine komplette Datenübertragung auf dem DMX Bus mit allen 512 Kanälen dauert 4 Millisekunden, ist also schön schnell.
    Die Datenübertragung auf den DMX Bus erfolgt kontinuierlich, bis zum Abschalten.
    Nicht alle USB/DMX Adapter sind gleich. Man sollte nur die Adapter verwenden, die geprüft wurden, und somit Kompatibel sind. Das trifft nicht auf alle Adapter zu. Es könnte sonst schon mal Probleme bei der Hilfe geben. Hier mal im Forum nachfragen.

    Wichtiger Hinweis ! Nie den Kanal 0 für ein Gerät verwenden, dieser Kanal ist das Start Byte auf dem DMX Bus. Das ist eine beliebte Fehlerquelle und sollte bei der Programmierung abgefangen werden.

    LG
    Martin
    Angehängte Dateien

    Einen Kommentar schreiben:


  • fmeister
    hat ein Thema erstellt DMX Plugin für DMX512a USB devices

    DMX Plugin für DMX512a USB devices

    Hallo,

    ich bin gerade dran das dmx Modul anzupassen, dass auch mein DMX Adapter (DMXKing DMX512a) funktioniert.

    Der verwendet ein völlig anderes Protokoll als die nanodmx dinger.

    Zu meinem Problem: Im DMX512a Protokoll gibt es leider keine Möglichkeit einzelne Kanäle zu modifizieren. Es müssen immer die Kompletten 512 Kanäle (oder zumindest von Kanal 1 bis x durchgehend) geschickt werden. Der integrierte Microcontroller refresht dann automatisch (wie auch beim NanoDMX).

    Da man keine einzelnen Kanäle aktualisieren kann, brauche ich ein Array dass während der Laufzeit von smarthome.py erhalten bleibt. Soweit ich das nachvollziehen kann, wird das Plugin ausgeführt und danach wieder beendet (was ja auch logisch ist).

    Nachdem ich absolut keine python Erfahrung habe: Weiss jemand Rat ?

    Hier noch der Code:

    PS: ich bin auch für Tipps/Feedback jeglicher Art empfänglich

    Code:
    #!/usr/bin/env python
    # vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
    #########################################################################
    # Copyright 2011 KNX-User-Forum e.V.            https://knx-user-forum.de/
    #########################################################################
    #  This file is part of SmartHome.py.   http://smarthome.sourceforge.net/
    #
    #  SmartHome.py 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.
    #
    #  SmartHome.py 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 SmartHome.py. If not, see <http://www.gnu.org/licenses/>.
    #########################################################################
    
    import logging
    import threading
    import serial
    
    logger = logging.getLogger('')
    
    
    class DMX():
        # _dim = 10^((n-1)/(253/3)-1) by JNK from KNX UF
        #_dim = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25, 26, 26, 27, 28, 29, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 50, 51, 52, 54, 55, 57, 58, 60, 62, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 86, 88, 90, 93, 95, 98, 101, 104, 106, 109, 112, 115, 119, 122, 125, 129, 132, 136, 140, 144, 148, 152, 156, 160, 165, 169, 174, 179, 184, 189, 194, 199, 205, 211, 216, 222, 228, 235, 241, 248, 255 ]
    
        self._dmxdata=[chr(0)]*513
    
        def __init__(self, smarthome, tty, adapter):
            self._sh = smarthome
            self._adapter = adapter
            self._is_connected = False
            self._lock = threading.Lock()
    
            try:
                self._port = serial.Serial(tty, 38400, timeout=1)
            except:
                logger.error("Could not open %s." % tty)
                return
            else:
                self._is_connected = True
            if not self._send_nanodmx("C?") and adapter == "nanodmx":
                logger.warning("Could not communicate with dmx adapter.")
                self._is_connected = False
            if adapter == "dmx512a":
                self._dmxopen=chr(126)
                self._dmxclose=chr(231)
                self._dmxinit1=chr(03)+chr(02)+chr(0)+chr(0)+chr(0)
                self._dmxinit2=chr(10)+chr(02)+chr(0)+chr(0)+chr(0)
                self._dmxintensity=chr(6)+chr(1)+chr(2)
                self._port.write(self._dmxopen+self._dmxinit1+self._dmxclose)
                self._port.write(self._dmxopen+self._dmxinit2+self._dmxclose)
    
        def _send_dmx512a(self, data):
            if not self._is_connected:
                return False
            self._lock.acquire()
            self._port.write(data)
            self._lock.release()
            return True
    
        def _send_nanodmx(self, data):
            if not self._is_connected:
                return False
            self._lock.acquire()
            try:
                self._port.write(data)
                ret = self._port.read(1)
            except:
                logger.warning("Problem sending data to dmx adapter.")
                ret = 'F'
            self._lock.release()
            if ret == 'G':
                return True
            else:
                return False
    
        def run(self):
            self.alive = True
    
        def stop(self):
            self._port.close()
            self.alive = False
    
        def send(self, channel, value):
            logger.debug("update dmx channel {0:03d} {1:03d}".format(channel, int(value)))
    	if self._adapter == "nanodmx":
                 self._send_nanodmx("C{0:03d}L{1:03d}".format(int(channel), int(value)))
    	if self._adapter == "dmx512a":
    	     self._dmxdata[channel]=chr(value)
    	     sdata=''.join(self._dmxdata)
    	     self._send_dmx512a(self._dmxopen+self._dmxintensity+sdata+self._dmxclose)
    
        def parse_item(self, item):
            if 'dmx_ch' in item.conf:
                channels = item.conf['dmx_ch']
                if isinstance(channels, str):
                    channels = [channels, ]
                channels = map(int, channels)
                item.conf['dmx_ch'] = channels
                return self.update_item
            else:
                return None
    
        def update_item(self, item, caller=None, source=None, dest=None):
            #logger.debug("update dmx channel {0:03d}".format(item.dmx_ch))
            for channel in item.conf['dmx_ch']:
                self.send(channel, item())
Lädt...
X