This repository has been archived by the owner on Feb 3, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathdivoom_protocol.py
124 lines (98 loc) · 3.78 KB
/
divoom_protocol.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import math
class DivoomAuraBoxProtocol:
"""Creates pattern for divoom aurabox."""
# static values begin and end of protocol
PREFIX = 0x01
POSTFIX = 0x02
SINGLE_IMAGE = [0x39, 0x00, 0x44, 0x00, 0x0a, 0x0a, 0x04] # single image function
ANIMATION = [0x3b, 0x00, 0x49, 0x00, 0x0a, 0x0a, 0x04] # followed by 1-2 bytes of number (invalid byte replacement)
# invalid byte processing
INVALID_BYTES = [0x01, 0x02, 0x03]
INVALID_BYTE_PREFIX = 0x03
def __init__(self):
pass
def contains_invalid_bytes(self, data):
for invalid_byte in self.INVALID_BYTES:
if invalid_byte in data:
return True
return False
def replace_invalid_bytes(self, data):
new_data = []
for d in data:
for inv in self.INVALID_BYTES:
if (d == inv):
new_data.append(self.INVALID_BYTE_PREFIX)
new_data.append(self.replace_byte(inv))
break
else:
new_data.append(d)
return new_data
def replace_invalid_byte(self, data):
new_data = []
for inv in self.INVALID_BYTES:
if (data == inv):
new_data.append(self.INVALID_BYTE_PREFIX)
new_data.append(self.replace_byte(inv))
break
else:
new_data.append(data)
return new_data
def replace_byte(self, data):
return (self.INVALID_BYTE_PREFIX + data)
def create_animation_packages(self, data_array, time_length=0x05):
"""Creates package for predefined animated data that will run unlimited."""
result = []
for i in range(0, len(data_array)):
function = []
function.extend(self.ANIMATION)
function.append(i)
function.append(time_length)
single_package = self.create_package_for_image(function, data_array[i])
result.append(single_package)
return result
def create_time_package(self):
"""Creates package to let the thing show the current time."""
return [0x01, 0x04, 0x00, 0x45, 0x00, 0x49, 0x00, 0x02]
def create_temp_package(self):
"""Creates package to let the thing show the current temperature."""
return [0x01,0x04,0x00,0x45,0x03,0x04,0x4a,0x00,0x02]
def create_bright_package(self):
"""Creates package to display the current content bright."""
return [0x01, 0x04, 0x00, 0x32, 0xd2, 0x08, 0x03, 0x04, 0x02]
def create_dark_package(self):
"""Creates package to display the current content in lower brightness."""
return [0x01, 0x04, 0x00, 0x32, 0x3f, 0x75, 0x00, 0x02]
def create_off_package(self):
"""Creates package to disable the display (setting the brightness to 0)."""
return [0x01, 0x04, 0x00, 0x32, 0x00, 0x36, 0x00, 0x02]
def create_set_time_package(self, hours, minutes, seconds):
function = [0x0b, 0x00, 0x18, 0x11, 0x14, 0x0b, 0x1c]
time = [int(hours), int(minutes), int(seconds), 5]
return self.create_package(function, time)
def create_image_package(self, data):
"""Creates package show a single image."""
return self.create_package_for_image(self.SINGLE_IMAGE, data)
def create_package_for_image(self, function_prefix, data):
# check data has excactly 50 bytes
if (len(data) != 50):
raise Exception('given data has invalid size: ' + str(len(data)))
return self.create_package(function_prefix, data)
def create_package(self, function_prefix, data):
# crc calculation
crc_rel = function_prefix + data
crc = sum(crc_rel)
crc_lowerbytes = crc & 0xFF
crc_upperbytes = crc >> 8
# replace illegal bytes in data
data2 = self.replace_invalid_bytes(data)
function_prefix2 = self.replace_invalid_bytes(function_prefix)
# construct complete package
joined_data = [self.PREFIX] + function_prefix2 + data2
# append lower and upper checksum (with invalid bytes)
lowerbytes = self.replace_invalid_byte(crc_lowerbytes)
joined_data.extend(lowerbytes)
upperbytes = self.replace_invalid_byte(crc_upperbytes)
joined_data.extend(upperbytes)
# end token
joined_data.append(self.POSTFIX)
return joined_data