Passed
Push — master ( d01dda...94e82a )
by Matt
01:53
created

OpenDMXController._connect()   A

Complexity

Conditions 3

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 11
dl 0
loc 14
rs 9.85
c 0
b 0
f 0
cc 3
nop 1
1
"""
2
 *  PyDMXControl: A Python 3 module to control DMX using OpenDMX or uDMX.
3
 *                Featuring fixture profiles, built-in effects and a web control panel.
4
 *  <https://github.com/MattIPv4/PyDMXControl/>
5
 *  Copyright (C) 2022 Matt Cowley (MattIPv4) ([email protected])
6
"""
7
8
from typing import List
9
10
from pyftdi.ftdi import Ftdi
11
12
from ._TransmittingController import TransmittingController
13
14
15
class OpenDMXController(TransmittingController):
16
17
    def __init__(self, *args, **kwargs):
18
        # Device information
19
        self.__ftdi_vendor_id = kwargs.pop("ftdi_vendor_id", 0x0403)
20
        self.__ftdi_product_id = kwargs.pop("ftdi_product_id", 0x6001)
21
        self.__ftdi_serial = kwargs.pop("ftdi_serial", None)
22
23
        # Store the device
24
        self.__ftdi = None
25
26
        # Create the parent controller
27
        super().__init__(*args, **kwargs)
28
29
    def _connect(self):
30
        # Try to close if exists
31
        if self.__ftdi is not None:
32
            try:
33
                self.__ftdi.close()
34
            except Exception:
35
                pass
36
37
        # Get new device
38
        self.__ftdi = Ftdi()
39
        self.__ftdi.open(self.__ftdi_vendor_id, self.__ftdi_product_id, serial=self.__ftdi_serial)
40
        self.__ftdi.reset()
41
        self.__ftdi.set_baudrate(baudrate=250000)
42
        self.__ftdi.set_line_property(bits=8, stopbit=2, parity='N', break_=False)
43
44
    def _close(self):
45
        self.__ftdi.close()
46
        print("CLOSE: OpenDMX closed")
47
48
    def _transmit(self, frame: List[int], first: int):
49
        # Convert to a bytearray and pad the start of the frame
50
        # We're transmitting direct DMX data here, so a frame must start at channel 1, but can end early
51
        data = bytearray(([0] * (first - 1)) + frame)
52
53
        # The first byte in the type, and is `0` for normal DMX data
54
        data.insert(0, 0)
55
56
        # Write
57
        self.__ftdi.set_break(True)
58
        self.__ftdi.set_break(False)
59
        self.__ftdi.write_data(data)
60