Passed
Push — master ( 9b4b57...27d41b )
by Matt
01:43
created

PyDMXControl.profiles.defaults._Vdim   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 27
eloc 69
dl 0
loc 116
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A Vdim.set_channel() 0 7 2
A Vdim.get_channel_id() 0 7 2
A Vdim.__is_vdim_channel() 0 3 1
A Vdim.set_vdim() 0 11 3
B Vdim.get_channel_value() 0 17 6
A Vdim.__vdim_updated() 0 2 1
B Vdim.get_color() 0 17 6
A Vdim.park() 0 5 1
A Vdim.unpark() 0 6 2
A Vdim._register_channel() 0 8 2
A Vdim.__init__() 0 7 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) 2023 Matt Cowley (MattIPv4) ([email protected])
6
"""
7
8
from datetime import datetime
9
from typing import Union, Tuple, List
10
11
from ._Fixture import Fixture
12
13
14
class Vdim(Fixture):
15
16
    def __init__(self, *args, **kwargs):
17
        super().__init__(*args, **kwargs)
18
19
        self.__vdims = []
20
        self.__vdim = 255
21
        self.__vdim_timestamp = datetime.utcnow()
22
        self.__vdim_parked = False
23
24
    def __vdim_updated(self):
25
        self.__vdim_timestamp = datetime.utcnow()
26
27
    def _register_channel(self, name: str, *, parked: Union[bool, int] = False, vdim: bool = False) -> int:
28
        super_call = super()._register_channel(name, parked=parked)
29
30
        # Register vdim if applicable
31
        if vdim:
32
            self.__vdims.append(super_call)
33
34
        return super_call
35
36
    def __is_vdim_channel(self, channel: Union[str, int]) -> bool:
37
        return str(channel).lower().strip() in ["dimmer", "vdim", "dim", "d"] \
38
               or str(channel) == str(self.next_channel - 1)
39
40
    def get_channel_id(self, channel: Union[str, int]) -> int:
41
        # Look for vdim channel
42
        if self.__is_vdim_channel(channel):
43
            return self.next_channel - 1
44
45
        # Get normal channel
46
        return super().get_channel_id(channel)
47
48
    def get_channel_value(self, channel: Union[str, int], apply_vdim: bool = True, apply_parking: bool = True) -> Tuple[int, datetime]:
49
        # Look for vdim channel
50
        if self.__is_vdim_channel(channel):
51
            return (self.__vdim if (not apply_parking) or (self.__vdim_parked is False) else self.__vdim_parked), self.__vdim_timestamp
52
53
        # Get normal channel
54
        super_call = super().get_channel_value(channel, apply_parking)
55
        new_val = super_call[0]
56
        new_time = super_call[1]
57
58
        # Apply vdim if applicable
59
        if apply_vdim and self.get_channel_id(channel) in self.__vdims:
60
            new_val = int(new_val * (self.__vdim / 255))
61
            if self.__vdim_timestamp > new_time:
62
                new_time = self.__vdim_timestamp
63
64
        return new_val, new_time
65
66
    def set_channel(self, channel: Union[str, int], value: int) -> Fixture:
67
        # Allow setting of vdim
68
        if self.__is_vdim_channel(channel):
69
            return self.set_vdim(value)
70
71
        # Set normal channel
72
        return super().set_channel(channel, value)
73
74
    def set_vdim(self, value: int) -> Fixture:
75
        # Update the vdim value
76
        if not self._valid_channel_value(value, 'vdim'):
77
            return self
78
        self.__vdim = value
79
80
        # If not parked, bump the timestamp
81
        if self.__vdim_parked is False:
82
            self.__vdim_updated()
83
84
        return self
85
86
    def get_color(self) -> Union[None, List[int]]:
87
        if not self.has_channel('r') or not self.has_channel('g') or not self.has_channel('b'):
88
            return None
89
90
        color = [
91
            self.get_channel_value('r', False, False)[0],
92
            self.get_channel_value('g', False, False)[0],
93
            self.get_channel_value('b', False, False)[0],
94
        ]
95
96
        if self.has_channel('w'):
97
            color.append(self.get_channel_value('w', False, False)[0])
98
99
            if self.has_channel('a'):
100
                color.append(self.get_channel_value('a', False, False)[0])
101
102
        return color
103
104
    def park(self) -> Fixture:
105
        self.__vdim_parked = self.__vdim
106
        self.__vdim_updated()
107
108
        return super().park()
109
110
    def unpark(self) -> Fixture:
111
        if self.__vdim_parked is not False:
112
            self.__vdim_parked = False
113
            self.__vdim_updated()
114
115
        return super().unpark()
116