Pre-Commit Update & Run

This commit is contained in:
Shaun Eccles-Smith 2021-11-06 18:25:28 +11:00
parent 97529750ec
commit 858f0baeae
10 changed files with 147 additions and 69 deletions

View File

@ -13,19 +13,19 @@ repos:
- id: trailing-whitespace
- id: check-toml
- repo: https://github.com/PyCQA/isort
rev: 5.9.3
rev: 5.10.0
hooks:
- id: isort
- repo: https://gitlab.com/pycqa/flake8
rev: 4.0.1
rev: 3.9.2
hooks:
- id: flake8
- repo: https://github.com/psf/black
rev: 21.9b0 # Replace by any tag/version: https://github.com/psf/black/tags
rev: 21.10b0 # Replace by any tag/version: https://github.com/psf/black/tags
hooks:
- id: black
- repo: https://github.com/asottile/pyupgrade
rev: v2.23.3
rev: v2.29.0
hooks:
- id: pyupgrade
args: [--py38-plus]

View File

@ -1,15 +1,14 @@
import asyncio
import logging
import socket
from abc import abstractmethod
from functools import cached_property
import numpy as np
import voluptuous as vol
import zeroconf
import socket
import serial
import serial.tools.list_ports
import voluptuous as vol
import zeroconf
from ledfx.config import save_config
from ledfx.events import DeviceUpdateEvent, Event
@ -364,12 +363,16 @@ class UDPDevice(NetworkedDevice):
def activate(self):
self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
_LOGGER.info(f"{self._device_type} sender for {self.config['name']} started.")
_LOGGER.info(
f"{self._device_type} sender for {self.config['name']} started."
)
super().activate()
def deactivate(self):
super().deactivate()
_LOGGER.info(f"{self._device_type} sender for {self.config['name']} stopped.")
_LOGGER.info(
f"{self._device_type} sender for {self.config['name']} stopped."
)
self._sock = None
@ -381,6 +384,7 @@ class AvailableCOMPorts:
for p in ports:
available_ports.append(p.device)
@BaseRegistry.no_registration
class SerialDevice(Device):

View File

@ -43,7 +43,9 @@ class AdalightDevice(SerialDevice):
def flush(self, data):
try:
self.serial.write(packets.build_adalight_packet(data, self.color_order))
self.serial.write(
packets.build_adalight_packet(data, self.color_order)
)
except serial.SerialException:
_LOGGER.critical(

View File

@ -56,7 +56,11 @@ class DDPDevice(UDPDevice):
self.frame_count += 1
try:
DDPDevice.send_out(
self._sock, self.destination, self._config["port"], data, self.frame_count
self._sock,
self.destination,
self._config["port"],
data,
self.frame_count,
)
except AttributeError:
self.activate()

View File

@ -11,31 +11,34 @@ Byte Description
4 + n*4 Green Value
5 + n*4 Blue Value
"""
def build_warls_packet(data: np.ndarray, timeout: int, last_frame: np.array):
packet = bytearray([1, (timeout or 1)])
byteData = data.astype(np.dtype("B"))
if last_frame is None or data.shape != last_frame.shape:
last_frame = np.full(data.shape ,np.nan)
'''
last_frame = np.full(data.shape, np.nan)
"""
for i in range(len(byteData)): # loop through byteData
if not np.array_equal(last_bytes[i], byteData[i]): # if index has changed from last sent frame
packet.extend(bytes([i])) # add index as first byte
packet.extend(byteData[i].flatten().tobytes())
''' # do above in numpy
""" # do above in numpy
# get indexes of pixels that have changed
idx=np.flatnonzero(np.any(last_frame!=data, axis=1))
idx = np.flatnonzero(np.any(last_frame != data, axis=1))
# make a new output array
out=np.zeros((len(idx), 4), dtype="B")
out = np.zeros((len(idx), 4), dtype="B")
# first byte of each pixel is the index
out[:,0] = idx
out[:, 0] = idx
# final three bytes are the pixel values
out[:,1:] = byteData[idx]
out[:, 1:] = byteData[idx]
# convert out to bytes to send
packet.extend(out.flatten().tobytes())
return packet
"""
Generic DRGB packet encoding
Max LEDs: 490
@ -47,6 +50,8 @@ Byte Description
4 + n*3 Blue Value
"""
def build_drgb_packet(data: np.ndarray, timeout: int):
packet = bytearray([2, (timeout or 1)])
@ -54,7 +59,8 @@ def build_drgb_packet(data: np.ndarray, timeout: int):
packet.extend(byteData.flatten().tobytes())
return packet
'''
"""
Generic DRGBW packet encoding
Max LEDs: 367
@ -64,20 +70,21 @@ Byte Description
3 + n*3 Green Value
4 + n*3 Blue Value
5 + n*4 White Value
'''
"""
def build_drgbw_packet(data: np.ndarray, timeout: int):
packet = bytearray([3, (timeout or 1)])
byteData = data.astype(np.dtype("B"))
out = np.zeros((len(byteData), 4), dtype="B")
out[:,:3] = byteData
out[:, :3] = byteData
# 4th column is unusued white channel -> 0
packet.extend(out.flatten().tobytes())
# for i in range(len(byteData)):
# packet.extend(byteData[i].flatten().tobytes())
# packet.extend(bytes(0))
# packet.extend(bytes(0))
return packet
@ -91,13 +98,20 @@ Byte Description
5 + n*3 Green Value
6 + n*3 Blue Value
"""
def build_dnrgb_packet(data: np.ndarray, timeout: int, led_start_index: np.uint16):
packet = bytearray([4, (timeout or 1), (led_start_index >> 8),(led_start_index & 0x00ff)]) # high byte, then low byte
def build_dnrgb_packet(
data: np.ndarray, timeout: int, led_start_index: np.uint16
):
packet = bytearray(
[4, (timeout or 1), (led_start_index >> 8), (led_start_index & 0x00FF)]
) # high byte, then low byte
byteData = data.astype(np.dtype("B"))
packet.extend(byteData.flatten().tobytes())
return packet
"""
Generic Adalight serial packet encoding
@ -107,15 +121,25 @@ Byte Description
5 + n*3 Green Value
6 + n*3 Blue Value
"""
def build_adalight_packet(data: np.ndarray, color_order: str):
pixel_length = len(data)
packet = bytearray([ord("A"), ord("d"), ord("a"), (pixel_length >> 8),(pixel_length & 0x00ff)]) # high byte, then low byte
packet.extend([packet[3] ^ packet[4] ^ 0x55]) # checksum
packet = bytearray(
[
ord("A"),
ord("d"),
ord("a"),
(pixel_length >> 8),
(pixel_length & 0x00FF),
]
) # high byte, then low byte
packet.extend([packet[3] ^ packet[4] ^ 0x55]) # checksum
byteData = data.astype(np.dtype("B"))
# if color_order == "RGB": pass
if color_order == "GRB":
byteData[:, [1, 0]] = byteData[:, [0, 1]] # swap columns
byteData[:, [1, 0]] = byteData[:, [0, 1]] # swap columns
elif color_order == "BGR":
byteData[:, [2, 0]] = byteData[:, [0, 2]]
elif color_order == "RBG":

View File

@ -8,13 +8,8 @@ from ledfx.devices import UDPDevice, packets
_LOGGER = logging.getLogger(__name__)
SUPPORTED_PACKETS = [
"DRGB",
"WARLS",
"DRGBW",
"DNRGB",
"adaptive_smallest"
]
SUPPORTED_PACKETS = ["DRGB", "WARLS", "DRGBW", "DNRGB", "adaptive_smallest"]
class UDPRealtimeDevice(UDPDevice):
"""Generic WLED UDP Realtime device support"""
@ -52,12 +47,15 @@ class UDPRealtimeDevice(UDPDevice):
def __init__(self, ledfx, config):
super().__init__(ledfx, config)
self._device_type = "UDP Realtime"
self.last_frame = np.full((config['pixel_count'], 3), -1)
self.last_frame = np.full((config["pixel_count"], 3), -1)
self.last_frame_sent_time = 0
def flush(self, data):
try:
self.choose_and_send_packet(data, self._config["timeout"],)
self.choose_and_send_packet(
data,
self._config["timeout"],
)
self.last_frame = np.copy(data)
except AttributeError:
self.activate()
@ -71,56 +69,100 @@ class UDPRealtimeDevice(UDPDevice):
if self._config["udp_packet_type"] == "DRGB" and frame_size <= 490:
udpData = packets.build_drgb_packet(data, timeout)
self.transmit_packet(udpData, np.array_equal(data, self.last_frame))
self.transmit_packet(
udpData, np.array_equal(data, self.last_frame)
)
elif self._config["udp_packet_type"] == "WARLS" and frame_size <= 255:
udpData = packets.build_warls_packet(data, timeout, self.last_frame)
self.transmit_packet(udpData, np.array_equal(data, self.last_frame))
udpData = packets.build_warls_packet(
data, timeout, self.last_frame
)
self.transmit_packet(
udpData, np.array_equal(data, self.last_frame)
)
elif self._config["udp_packet_type"] == "DRGBW" and frame_size <= 367:
udpData = packets.build_drgbw_packet(data, timeout)
self.transmit_packet(udpData, np.array_equal(data, self.last_frame))
self.transmit_packet(
udpData, np.array_equal(data, self.last_frame)
)
elif self._config["udp_packet_type"] == "DNRGB":
number_of_packets = int(np.ceil(frame_size / 489))
for i in range(number_of_packets):
start_index = i * 489
end_index = start_index + 489
udpData = packets.build_dnrgb_packet(data[start_index:end_index], timeout, start_index)
self.transmit_packet(udpData, np.array_equal(data[start_index:end_index], self.last_frame[start_index:end_index]))
udpData = packets.build_dnrgb_packet(
data[start_index:end_index], timeout, start_index
)
self.transmit_packet(
udpData,
np.array_equal(
data[start_index:end_index],
self.last_frame[start_index:end_index],
),
)
elif self._config["udp_packet_type"] == "adaptive_smallest" and frame_size <= 255:
elif (
self._config["udp_packet_type"] == "adaptive_smallest"
and frame_size <= 255
):
# compare potential size of WARLS packet to DRGB packet
if np.count_nonzero(np.any(data!=self.last_frame, axis=1)) * 4 < len(data) * 3:
udpData = packets.build_warls_packet(data, timeout, self.last_frame)
self.transmit_packet(udpData, np.array_equal(data, self.last_frame))
if (
np.count_nonzero(np.any(data != self.last_frame, axis=1)) * 4
< len(data) * 3
):
udpData = packets.build_warls_packet(
data, timeout, self.last_frame
)
self.transmit_packet(
udpData, np.array_equal(data, self.last_frame)
)
else:
udpData = packets.build_drgb_packet(data, timeout)
self.transmit_packet(udpData, np.array_equal(data, self.last_frame))
self.transmit_packet(
udpData, np.array_equal(data, self.last_frame)
)
else: # fallback
else: # fallback
_LOGGER.warning(
f"UDP packet is configured incorrectly (please choose a packet that supports {self._config['pixel_count']} LEDs): https://kno.wled.ge/interfaces/udp-realtime/#udp-realtime \n Falling back to supported udp packet."
)
if frame_size <= 490: # DRGB
if frame_size <= 490: # DRGB
udpData = packets.build_drgb_packet(data, timeout)
self.transmit_packet(udpData, np.array_equal(data, self.last_frame))
else: #DNRGB
self.transmit_packet(
udpData, np.array_equal(data, self.last_frame)
)
else: # DNRGB
number_of_packets = int(np.ceil(frame_size / 489))
for i in range(number_of_packets):
start_index = i * 489
end_index = start_index + 489
udpData = packets.build_dnrgb_packet(data[start_index:end_index], timeout, start_index)
self.transmit_packet(udpData, np.array_equal(data[start_index:end_index], self.last_frame[start_index:end_index]))
udpData = packets.build_dnrgb_packet(
data[start_index:end_index], timeout, start_index
)
self.transmit_packet(
udpData,
np.array_equal(
data[start_index:end_index],
self.last_frame[start_index:end_index],
),
)
def transmit_packet(self, packet, frame_is_equal_to_last: bool):
timestamp = time.time()
if self._config["minimise_traffic"] and frame_is_equal_to_last:
half_of_timeout = (((self._config["timeout"] * self._config["refresh_rate"]) - 1) // 2) / self._config["refresh_rate"]
if (timestamp > self.last_frame_sent_time + half_of_timeout):
self._sock.sendto(bytes(packet),(self.destination, self._config["port"]))
half_of_timeout = (
((self._config["timeout"] * self._config["refresh_rate"]) - 1)
// 2
) / self._config["refresh_rate"]
if timestamp > self.last_frame_sent_time + half_of_timeout:
self._sock.sendto(
bytes(packet), (self.destination, self._config["port"])
)
self.last_frame_sent_time = timestamp
else:
self._sock.sendto(bytes(packet),(self.destination, self._config["port"]))
self.last_frame_sent_time = timestamp
self._sock.sendto(
bytes(packet), (self.destination, self._config["port"])
)
self.last_frame_sent_time = timestamp

View File

@ -42,7 +42,7 @@ class WLEDDevice(NetworkedDevice):
"ip_address": None,
"pixel_count": None,
"port": 21324,
"udp_packet_type": "DNRGB"
"udp_packet_type": "DNRGB",
},
"DDP": {
"name": None,

View File

@ -94,7 +94,9 @@ class AudioInputSource:
vol.Optional("sample_rate", default=60): int,
vol.Optional("mic_rate", default=MIC_RATE): int,
vol.Optional("fft_size", default=FFT_SIZE): int,
vol.Optional("min_volume", default=0.2): vol.All(vol.Coerce(float), vol.Range(min=0.0, max=10.0)),
vol.Optional("min_volume", default=0.2): vol.All(
vol.Coerce(float), vol.Range(min=0.0, max=10.0)
),
vol.Optional(
"audio_device", default=default_device_index
): AudioInputSource.device_index_validator,

View File

@ -354,4 +354,4 @@ class HSVEffect(Effect):
self.hsv,
int(pixels_to_roll),
axis=0,
)
)

View File

@ -536,7 +536,7 @@ ledfx_presets = {
"mids_colour": "cyan",
"mids_sensitivity": 0.05,
"mirror": True,
"raindrop_animation": "droplet_1.npy"
"raindrop_animation": "droplet_1.npy",
},
"name": "Cold Drops",
},
@ -1033,7 +1033,7 @@ ledfx_presets = {
"config": {
"background_brightness": 1,
"background_color": "black",
"beat_decay": 2,
"beat_decay": 2,
"blur": 6.2,
"brightness": 1,
"color": "blue",
@ -1057,7 +1057,7 @@ ledfx_presets = {
"config": {
"background_brightness": 1,
"background_color": "black",
"beat_decay": 2,
"beat_decay": 2,
"blur": 2.6,
"brightness": 1,
"color": "white",
@ -1080,7 +1080,7 @@ ledfx_presets = {
"config": {
"background_brightness": 1,
"background_color": "black",
"beat_decay": 2,
"beat_decay": 2,
"blur": 2.6,
"brightness": 1,
"color": "white",
@ -1100,7 +1100,7 @@ ledfx_presets = {
"config": {
"background_brightness": 1,
"background_color": "black",
"beat_decay": 2,
"beat_decay": 2,
"blur": 2.6,
"brightness": 1,
"color": "white",