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

PyDMXControl.controllers._SerialController   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 60
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 6
eloc 26
dl 0
loc 60
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A SerialController._connect() 0 10 3
A SerialController.__init__() 0 14 1
A SerialController._close() 0 3 1
A SerialController._transmit() 0 12 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 time import sleep
9
from typing import List
10
11
from serial import Serial
12
13
from ._TransmittingController import TransmittingController
14
15
16
class SerialController(TransmittingController):
17
18
    def __init__(self, port, *args, **kwargs):
19
        """
20
        Serial port interface requires port string to establish connection, e.g. 'COM1' for
21
        windows operating systems.
22
23
        Parameters
24
        ----------
25
        port: Serial port string.
26
        """
27
28
        # Store the port and device
29
        self.__port = port
30
        self.__device = None
31
        super().__init__(*args, **kwargs)
32
33
    def _connect(self):
34
        # Try to close if exists
35
        if self.__device is not None:
36
            try:
37
                self.__device.close()
38
            except Exception:
39
                pass
40
41
        # Get new device
42
        self.__device = Serial(port=self.__port, baudrate=250000, bytesize=8, stopbits=2)
43
44
    def _close(self):
45
        self.__device.close()
46
        print("CLOSE: Serial port 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.__device.send_break(100e-6)
58
        sleep(10e-6)
59
        self.__device.write(data)
60