bluer-sbc 8.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of bluer-sbc might be problematic. Click here for more details.
- bluer_sbc/.abcli/abcli.sh +12 -0
- bluer_sbc/.abcli/actions.sh +11 -0
- bluer_sbc/.abcli/adafruit_rgb_matrix.sh +14 -0
- bluer_sbc/.abcli/alias.sh +5 -0
- bluer_sbc/.abcli/blue_sbc.sh +11 -0
- bluer_sbc/.abcli/camera.sh +20 -0
- bluer_sbc/.abcli/grove.sh +43 -0
- bluer_sbc/.abcli/hat.sh +22 -0
- bluer_sbc/.abcli/install/adafruit_rgb_matrix.sh +15 -0
- bluer_sbc/.abcli/install/grove.sh +29 -0
- bluer_sbc/.abcli/install/lepton.sh +33 -0
- bluer_sbc/.abcli/install/rpi.sh +65 -0
- bluer_sbc/.abcli/install/scroll_phat_hd.sh +14 -0
- bluer_sbc/.abcli/install/sparkfun_top_phat.sh +33 -0
- bluer_sbc/.abcli/install/template.sh +9 -0
- bluer_sbc/.abcli/install/unicorn_16x16.sh +16 -0
- bluer_sbc/.abcli/lepton.sh +15 -0
- bluer_sbc/.abcli/scroll_phat_hd.sh +14 -0
- bluer_sbc/.abcli/session.sh +39 -0
- bluer_sbc/.abcli/sparkfun_top_phat.sh +27 -0
- bluer_sbc/.abcli/tests/README.sh +8 -0
- bluer_sbc/.abcli/tests/camera.sh +47 -0
- bluer_sbc/.abcli/tests/help.sh +65 -0
- bluer_sbc/.abcli/tests/version.sh +8 -0
- bluer_sbc/.abcli/unicorn_16x16.sh +14 -0
- bluer_sbc/README.py +51 -0
- bluer_sbc/__init__.py +17 -0
- bluer_sbc/__main__.py +16 -0
- bluer_sbc/algo/__init__.py +0 -0
- bluer_sbc/algo/diff.py +81 -0
- bluer_sbc/config.env +30 -0
- bluer_sbc/env.py +35 -0
- bluer_sbc/hardware/__init__.py +38 -0
- bluer_sbc/hardware/adafruit_rgb_matrix.py +30 -0
- bluer_sbc/hardware/display.py +112 -0
- bluer_sbc/hardware/grove.py +104 -0
- bluer_sbc/hardware/hardware.py +58 -0
- bluer_sbc/hardware/hat/__init__.py +0 -0
- bluer_sbc/hardware/hat/__main__.py +91 -0
- bluer_sbc/hardware/hat/abstract.py +136 -0
- bluer_sbc/hardware/hat/prototype.py +161 -0
- bluer_sbc/hardware/screen.py +17 -0
- bluer_sbc/hardware/scroll_phat_hd.py +35 -0
- bluer_sbc/hardware/sparkfun_top_phat/__init__.py +0 -0
- bluer_sbc/hardware/sparkfun_top_phat/__main__.py +51 -0
- bluer_sbc/hardware/sparkfun_top_phat/classes.py +104 -0
- bluer_sbc/hardware/unicorn_16x16.py +44 -0
- bluer_sbc/help/__init__.py +0 -0
- bluer_sbc/help/__main__.py +10 -0
- bluer_sbc/help/adafruit_rgb_matrix.py +23 -0
- bluer_sbc/help/camera.py +71 -0
- bluer_sbc/help/functions.py +52 -0
- bluer_sbc/help/grove.py +59 -0
- bluer_sbc/help/hat.py +56 -0
- bluer_sbc/help/lepton.py +39 -0
- bluer_sbc/help/scroll_phat_hd.py +23 -0
- bluer_sbc/help/session.py +26 -0
- bluer_sbc/help/sparkfun_top_phat.py +26 -0
- bluer_sbc/help/unicorn_16x16.py +23 -0
- bluer_sbc/host.py +11 -0
- bluer_sbc/imager/__init__.py +16 -0
- bluer_sbc/imager/camera/__init__.py +3 -0
- bluer_sbc/imager/camera/__main__.py +69 -0
- bluer_sbc/imager/camera/classes.py +259 -0
- bluer_sbc/imager/camera/constants.py +30 -0
- bluer_sbc/imager/classes.py +25 -0
- bluer_sbc/imager/lepton/__init__.py +3 -0
- bluer_sbc/imager/lepton/__main__.py +51 -0
- bluer_sbc/imager/lepton/classes.py +35 -0
- bluer_sbc/imager/lepton/python2.py +70 -0
- bluer_sbc/logger.py +5 -0
- bluer_sbc/sample.env +1 -0
- bluer_sbc/session/__init__.py +0 -0
- bluer_sbc/session/__main__.py +27 -0
- bluer_sbc/session/classes.py +318 -0
- bluer_sbc/session/functions.py +22 -0
- bluer_sbc/urls.py +1 -0
- bluer_sbc-8.3.1.dist-info/METADATA +58 -0
- bluer_sbc-8.3.1.dist-info/RECORD +82 -0
- bluer_sbc-8.3.1.dist-info/WHEEL +5 -0
- bluer_sbc-8.3.1.dist-info/licenses/LICENSE +121 -0
- bluer_sbc-8.3.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import math
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
from bluer_sbc.hardware.hardware import Hardware
|
|
5
|
+
from bluer_sbc.logger import logger
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Abstract_Hat(Hardware):
|
|
9
|
+
def __init__(self):
|
|
10
|
+
super().__init__()
|
|
11
|
+
|
|
12
|
+
self.switch_pin = -1
|
|
13
|
+
|
|
14
|
+
self.green_switch_pin = -1
|
|
15
|
+
self.red_switch_pin = -1
|
|
16
|
+
self.trigger_pin = -1
|
|
17
|
+
|
|
18
|
+
self.looper_pin = -1 # red led
|
|
19
|
+
self.incoming_pin = -1 # yellow led
|
|
20
|
+
self.data_pin = -1 # green led
|
|
21
|
+
self.outgoing_pin = -1 # blue led
|
|
22
|
+
|
|
23
|
+
self.green_led_pin = -1
|
|
24
|
+
self.red_led_pin = -1
|
|
25
|
+
|
|
26
|
+
self.pin_history = {}
|
|
27
|
+
|
|
28
|
+
def activated(self, pin):
|
|
29
|
+
"""
|
|
30
|
+
is pin activated?
|
|
31
|
+
:param pin: pin number
|
|
32
|
+
:return: True / False
|
|
33
|
+
"""
|
|
34
|
+
if pin in self.input_pins:
|
|
35
|
+
return self.input(pin) == False
|
|
36
|
+
|
|
37
|
+
return False
|
|
38
|
+
|
|
39
|
+
def input(self, pin):
|
|
40
|
+
"""
|
|
41
|
+
read pin input.
|
|
42
|
+
:param pin: pin number
|
|
43
|
+
:return: True / False
|
|
44
|
+
"""
|
|
45
|
+
return True
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def input_pins(self):
|
|
49
|
+
return [
|
|
50
|
+
pin
|
|
51
|
+
for pin in [
|
|
52
|
+
self.switch_pin,
|
|
53
|
+
self.green_switch_pin,
|
|
54
|
+
self.red_switch_pin,
|
|
55
|
+
self.trigger_pin,
|
|
56
|
+
]
|
|
57
|
+
if pin != -1
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
def output(self, pin, output):
|
|
61
|
+
"""
|
|
62
|
+
set pin to output
|
|
63
|
+
:param pin: pin number
|
|
64
|
+
:param output: True / False
|
|
65
|
+
:return: self
|
|
66
|
+
"""
|
|
67
|
+
return self
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def output_pins(self):
|
|
71
|
+
return [
|
|
72
|
+
pin
|
|
73
|
+
for pin in [
|
|
74
|
+
self.looper_pin,
|
|
75
|
+
self.incoming_pin,
|
|
76
|
+
self.data_pin,
|
|
77
|
+
self.outgoing_pin,
|
|
78
|
+
self.green_led_pin,
|
|
79
|
+
self.red_led_pin,
|
|
80
|
+
]
|
|
81
|
+
if pin != -1
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
def pulse(self, pin=None, frequency=None):
|
|
85
|
+
"""
|
|
86
|
+
pulse pin.
|
|
87
|
+
:param pin: pin number / "data" / "incoming" / "loop" / "outputs"
|
|
88
|
+
:param frequency: frequency
|
|
89
|
+
:return: self
|
|
90
|
+
"""
|
|
91
|
+
super().pulse(pin, frequency)
|
|
92
|
+
|
|
93
|
+
if pin == "data":
|
|
94
|
+
pin = self.data_pin
|
|
95
|
+
|
|
96
|
+
if pin == "incoming":
|
|
97
|
+
pin = self.incoming_pin
|
|
98
|
+
|
|
99
|
+
if pin == "loop":
|
|
100
|
+
pin = self.looper_pin
|
|
101
|
+
|
|
102
|
+
if pin == "outputs":
|
|
103
|
+
for index, pin in enumerate(self.output_pins):
|
|
104
|
+
self.pulse(pin, index)
|
|
105
|
+
|
|
106
|
+
return self
|
|
107
|
+
|
|
108
|
+
if pin is None:
|
|
109
|
+
for pin in self.output_pins:
|
|
110
|
+
self.pulse(pin, frequency)
|
|
111
|
+
|
|
112
|
+
return self
|
|
113
|
+
|
|
114
|
+
self.pin_history[pin] = (
|
|
115
|
+
not bool(self.pin_history.get(pin, False))
|
|
116
|
+
if frequency is None
|
|
117
|
+
else (lambda x: x - math.floor(x))(time.time() * (10 + frequency)) >= 0.5
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
return self.output(pin, self.pin_history[pin])
|
|
121
|
+
|
|
122
|
+
def release(self):
|
|
123
|
+
"""
|
|
124
|
+
release self
|
|
125
|
+
:return: self
|
|
126
|
+
"""
|
|
127
|
+
return self
|
|
128
|
+
|
|
129
|
+
def setup(self, pin, what, pull_up_down=None):
|
|
130
|
+
"""
|
|
131
|
+
Set up pin.
|
|
132
|
+
:param pin: pin number
|
|
133
|
+
:param what: "input" / "output"
|
|
134
|
+
:return: self
|
|
135
|
+
"""
|
|
136
|
+
return self
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import time
|
|
2
|
+
|
|
3
|
+
from blueness import module
|
|
4
|
+
from bluer_options import string
|
|
5
|
+
from bluer_options import host
|
|
6
|
+
|
|
7
|
+
from bluer_sbc import NAME
|
|
8
|
+
from bluer_sbc.hardware.hat.abstract import Abstract_Hat
|
|
9
|
+
from bluer_sbc.logger import logger
|
|
10
|
+
|
|
11
|
+
NAME = module.name(__file__, NAME)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Prototype_Hat(Abstract_Hat):
|
|
15
|
+
def __init__(self):
|
|
16
|
+
super().__init__()
|
|
17
|
+
|
|
18
|
+
self.switch_on_time = None
|
|
19
|
+
|
|
20
|
+
self.is_jetson = host.is_jetson()
|
|
21
|
+
self.is_rpi = host.is_rpi()
|
|
22
|
+
|
|
23
|
+
if self.is_rpi:
|
|
24
|
+
import RPi.GPIO as GPIO
|
|
25
|
+
|
|
26
|
+
self.switch_pin = 12
|
|
27
|
+
|
|
28
|
+
self.green_switch_pin = 16
|
|
29
|
+
self.red_switch_pin = 13
|
|
30
|
+
|
|
31
|
+
self.looper_pin = 22 # red led
|
|
32
|
+
self.incoming_pin = 18 # yellow led
|
|
33
|
+
self.data_pin = 36 # green led
|
|
34
|
+
self.outgoing_pin = 40 # blue led
|
|
35
|
+
|
|
36
|
+
self.green_led_pin = 15
|
|
37
|
+
self.red_led_pin = 7
|
|
38
|
+
|
|
39
|
+
GPIO.setmode(GPIO.BOARD) # numbers GPIOs by physical location
|
|
40
|
+
|
|
41
|
+
if self.is_jetson:
|
|
42
|
+
import Jetson.GPIO as GPIO
|
|
43
|
+
|
|
44
|
+
self.switch_pin = 7
|
|
45
|
+
|
|
46
|
+
self.trigger_pin = 12
|
|
47
|
+
self.looper_pin = 29 # red led
|
|
48
|
+
self.incoming_pin = 31 # yellow led
|
|
49
|
+
self.data_pin = 32 # green led
|
|
50
|
+
self.outgoing_pin = 33 # blue led
|
|
51
|
+
|
|
52
|
+
GPIO.setmode(GPIO.BOARD) # numbers GPIOs by physical location
|
|
53
|
+
|
|
54
|
+
# http://razzpisampler.oreilly.com/ch07.html
|
|
55
|
+
for pin in self.input_pins:
|
|
56
|
+
self.setup(pin, "input", GPIO.PUD_UP)
|
|
57
|
+
|
|
58
|
+
for pin in self.output_pins:
|
|
59
|
+
self.setup(pin, "output")
|
|
60
|
+
self.output(pin, False)
|
|
61
|
+
|
|
62
|
+
def clock(self):
|
|
63
|
+
super().clock()
|
|
64
|
+
|
|
65
|
+
if self.activated(self.switch_pin):
|
|
66
|
+
if self.switch_on_time is None:
|
|
67
|
+
self.switch_on_time = time.time()
|
|
68
|
+
logger.info(f"{NAME}: switch_on_time was set.")
|
|
69
|
+
else:
|
|
70
|
+
self.switch_on_time = None
|
|
71
|
+
|
|
72
|
+
if self.switch_on_time is not None:
|
|
73
|
+
self.pulse("outputs")
|
|
74
|
+
|
|
75
|
+
if time.time() - self.switch_on_time > 10:
|
|
76
|
+
self.key_buffer += ["s"]
|
|
77
|
+
|
|
78
|
+
return self
|
|
79
|
+
|
|
80
|
+
def input(self, pin):
|
|
81
|
+
if pin == -1:
|
|
82
|
+
return True
|
|
83
|
+
|
|
84
|
+
if self.is_rpi:
|
|
85
|
+
import RPi.GPIO as GPIO
|
|
86
|
+
elif self.is_jetson:
|
|
87
|
+
import Jetson.GPIO as GPIO
|
|
88
|
+
else:
|
|
89
|
+
return False
|
|
90
|
+
|
|
91
|
+
return GPIO.input(pin) == GPIO.HIGH
|
|
92
|
+
|
|
93
|
+
def output(self, pin, output):
|
|
94
|
+
if pin == -1:
|
|
95
|
+
return self
|
|
96
|
+
|
|
97
|
+
if self.is_rpi:
|
|
98
|
+
import RPi.GPIO as GPIO
|
|
99
|
+
elif self.is_jetson:
|
|
100
|
+
import Jetson.GPIO as GPIO
|
|
101
|
+
else:
|
|
102
|
+
return self
|
|
103
|
+
|
|
104
|
+
GPIO.output(pin, GPIO.HIGH if output else GPIO.LOW)
|
|
105
|
+
return self
|
|
106
|
+
|
|
107
|
+
def release(self):
|
|
108
|
+
if self.is_rpi:
|
|
109
|
+
import RPi.GPIO as GPIO
|
|
110
|
+
elif self.is_jetson:
|
|
111
|
+
import Jetson.GPIO as GPIO
|
|
112
|
+
else:
|
|
113
|
+
return self
|
|
114
|
+
|
|
115
|
+
logger.info(f"{self.__class__.__name__}.release()")
|
|
116
|
+
|
|
117
|
+
GPIO.cleanup()
|
|
118
|
+
|
|
119
|
+
return self
|
|
120
|
+
|
|
121
|
+
def setup(self, pin, what, pull_up_down=None):
|
|
122
|
+
if pin == -1:
|
|
123
|
+
return self
|
|
124
|
+
|
|
125
|
+
if self.is_rpi:
|
|
126
|
+
import RPi.GPIO as GPIO
|
|
127
|
+
elif self.is_jetson:
|
|
128
|
+
import Jetson.GPIO as GPIO
|
|
129
|
+
else:
|
|
130
|
+
return self
|
|
131
|
+
|
|
132
|
+
if what == "output":
|
|
133
|
+
what = GPIO.OUT
|
|
134
|
+
elif what == "input":
|
|
135
|
+
what = GPIO.IN
|
|
136
|
+
else:
|
|
137
|
+
raise NameError(
|
|
138
|
+
f"{self.__class__.__name__}.setup({pin}): unknown what: {what}."
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
if pull_up_down is None:
|
|
142
|
+
GPIO.setup(pin, what)
|
|
143
|
+
else:
|
|
144
|
+
GPIO.setup(pin, what, pull_up_down=pull_up_down)
|
|
145
|
+
|
|
146
|
+
return self
|
|
147
|
+
|
|
148
|
+
def signature(self):
|
|
149
|
+
return super().signature() + (
|
|
150
|
+
[
|
|
151
|
+
"switch:{}".format(
|
|
152
|
+
string.pretty_duration(
|
|
153
|
+
time.time() - self.switch_on_time,
|
|
154
|
+
largest=True,
|
|
155
|
+
short=True,
|
|
156
|
+
)
|
|
157
|
+
)
|
|
158
|
+
]
|
|
159
|
+
if self.switch_on_time is not None
|
|
160
|
+
else []
|
|
161
|
+
)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
|
|
3
|
+
from bluer_sbc.hardware.hardware import Hardware
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Screen(Hardware):
|
|
7
|
+
def __init__(self):
|
|
8
|
+
super().__init__()
|
|
9
|
+
self.size = None
|
|
10
|
+
|
|
11
|
+
self.buffer = None
|
|
12
|
+
|
|
13
|
+
def update_screen(self, image, session, header):
|
|
14
|
+
if self.animated:
|
|
15
|
+
self.buffer = copy.deepcopy(image)
|
|
16
|
+
|
|
17
|
+
return super().update_screen(image, session, header)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import cv2
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
from bluer_sbc.hardware.screen import Screen
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Scroll_Phat_HD(Screen):
|
|
8
|
+
def __init__(self):
|
|
9
|
+
super(Scroll_Phat_HD, self).__init__()
|
|
10
|
+
self.size = (7, 17)
|
|
11
|
+
self.animated = True
|
|
12
|
+
|
|
13
|
+
def update_screen(self, image, session, header):
|
|
14
|
+
import scrollphathd
|
|
15
|
+
|
|
16
|
+
image = cv2.resize(
|
|
17
|
+
image,
|
|
18
|
+
self.size,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
super().update_screen(image, session, header)
|
|
22
|
+
|
|
23
|
+
image = cv2.cvtColor(
|
|
24
|
+
image,
|
|
25
|
+
cv2.COLOR_BGR2GRAY,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
for y in range(0, 17):
|
|
29
|
+
for x in range(0, 7):
|
|
30
|
+
scrollphathd.set_pixel(y, x, image[y, x] / 255.0)
|
|
31
|
+
|
|
32
|
+
time.sleep(0.01)
|
|
33
|
+
scrollphathd.show()
|
|
34
|
+
|
|
35
|
+
return self
|
|
File without changes
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
from blueness import module
|
|
5
|
+
|
|
6
|
+
from bluer_sbc import NAME
|
|
7
|
+
from bluer_sbc.hardware.sparkfun_top_phat.classes import Sparkfun_Top_phat
|
|
8
|
+
from bluer_sbc.logger import logger
|
|
9
|
+
|
|
10
|
+
NAME = module.name(__file__, NAME)
|
|
11
|
+
|
|
12
|
+
parser = argparse.ArgumentParser(NAME)
|
|
13
|
+
parser.add_argument(
|
|
14
|
+
"task",
|
|
15
|
+
type=str,
|
|
16
|
+
default="",
|
|
17
|
+
help="validate_leds",
|
|
18
|
+
)
|
|
19
|
+
args = parser.parse_args()
|
|
20
|
+
|
|
21
|
+
hardware = Sparkfun_Top_phat()
|
|
22
|
+
|
|
23
|
+
success = False
|
|
24
|
+
if args.task == "validate_leds":
|
|
25
|
+
logger.info("loop started (Ctrl+C to stop)")
|
|
26
|
+
offset = 0
|
|
27
|
+
# https://stackoverflow.com/a/18994932/10917551
|
|
28
|
+
try:
|
|
29
|
+
while True:
|
|
30
|
+
for index in range(hardware.pixel_count):
|
|
31
|
+
hardware.pixels[index] = tuple(
|
|
32
|
+
int(thing * hardware.intensity)
|
|
33
|
+
for thing in hardware.colormap[
|
|
34
|
+
(index + offset) % hardware.pixel_count
|
|
35
|
+
][:3]
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
offset += 1
|
|
39
|
+
|
|
40
|
+
hardware.pixels.show()
|
|
41
|
+
time.sleep(0.1)
|
|
42
|
+
except KeyboardInterrupt:
|
|
43
|
+
logger.info("Ctrl+C, stopping.")
|
|
44
|
+
finally:
|
|
45
|
+
hardware.release()
|
|
46
|
+
success = True
|
|
47
|
+
else:
|
|
48
|
+
logger.error(f"-{NAME}: {args.task}: command not found.")
|
|
49
|
+
|
|
50
|
+
if not success:
|
|
51
|
+
logger.error(f"-{NAME}: {args.task}: failed.")
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import cv2
|
|
2
|
+
import time
|
|
3
|
+
from matplotlib import cm
|
|
4
|
+
|
|
5
|
+
from blueness import module
|
|
6
|
+
|
|
7
|
+
from bluer_sbc import NAME
|
|
8
|
+
from bluer_sbc.hardware.screen import Screen
|
|
9
|
+
from bluer_sbc.logger import logger
|
|
10
|
+
|
|
11
|
+
NAME = module.name(__file__, NAME)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Sparkfun_Top_phat(Screen):
|
|
15
|
+
def __init__(self):
|
|
16
|
+
super(Sparkfun_Top_phat, self).__init__()
|
|
17
|
+
self.size = (7, 17)
|
|
18
|
+
self.animated = False
|
|
19
|
+
|
|
20
|
+
import board
|
|
21
|
+
import neopixel
|
|
22
|
+
|
|
23
|
+
# https://learn.sparkfun.com/tutorials/sparkfun-top-phat-hookup-guide/ws2812b-leds
|
|
24
|
+
self.pixel_count = 6
|
|
25
|
+
self.pixels = neopixel.NeoPixel(
|
|
26
|
+
board.D12,
|
|
27
|
+
self.pixel_count,
|
|
28
|
+
auto_write=False,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
self.intensity = 48
|
|
32
|
+
|
|
33
|
+
# https://matplotlib.org/stable/tutorials/colors/colormaps.html
|
|
34
|
+
self.colormap = cm.get_cmap("copper", self.pixel_count)(range(self.pixel_count))
|
|
35
|
+
|
|
36
|
+
self.pulse_cycle = 0
|
|
37
|
+
|
|
38
|
+
# https://github.com/sparkfun/Top_pHAT_Button_Py/blob/main/examples/top_phat_button_ex1.py
|
|
39
|
+
import top_phat_button
|
|
40
|
+
|
|
41
|
+
self.buttons = top_phat_button.ToppHATButton()
|
|
42
|
+
logger.info(f"{NAME}.connection status: {self.buttons.is_connected()}")
|
|
43
|
+
|
|
44
|
+
self.buttons.pressed_interrupt_enable = False
|
|
45
|
+
self.buttons.clicked_interrupt_enable = False
|
|
46
|
+
|
|
47
|
+
def clock(self):
|
|
48
|
+
super().clock()
|
|
49
|
+
|
|
50
|
+
self.buttons.button_pressed # These functions must be called to update button variables to their latest setting
|
|
51
|
+
self.buttons.button_clicked # These functions must be called to update button variables to their latest setting
|
|
52
|
+
|
|
53
|
+
if self.buttons.a_clicked == True:
|
|
54
|
+
logger.info(f"{NAME}: a clicked: update.")
|
|
55
|
+
self.key_buffer += ["u"]
|
|
56
|
+
|
|
57
|
+
if self.buttons.b_clicked == True:
|
|
58
|
+
logger.info(f"{NAME}: b clicked: shutdown.")
|
|
59
|
+
self.key_buffer += ["s"]
|
|
60
|
+
|
|
61
|
+
if self.buttons.center_clicked == True:
|
|
62
|
+
logger.info(f"{NAME}: center clicked.")
|
|
63
|
+
self.key_buffer += [" "]
|
|
64
|
+
|
|
65
|
+
if self.buttons.up_clicked == True:
|
|
66
|
+
logger.info(f"{NAME}: up clicked.")
|
|
67
|
+
self.intensity = min(255, 2 * self.intensity)
|
|
68
|
+
|
|
69
|
+
if self.buttons.down_clicked == True:
|
|
70
|
+
logger.info(f"{NAME}: down clicked.")
|
|
71
|
+
self.intensity = max(1, self.intensity // 2)
|
|
72
|
+
|
|
73
|
+
return self
|
|
74
|
+
|
|
75
|
+
def pulse(self, pin=None, frequency=None):
|
|
76
|
+
super().pulse(pin, frequency)
|
|
77
|
+
|
|
78
|
+
for index in range(self.pixel_count):
|
|
79
|
+
self.pixels[index] = tuple(
|
|
80
|
+
int(thing * self.intensity)
|
|
81
|
+
for thing in self.colormap[
|
|
82
|
+
(index + int(self.pulse_cycle / 10)) % self.pixel_count
|
|
83
|
+
][:3]
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
self.pixels.show()
|
|
87
|
+
|
|
88
|
+
self.pulse_cycle += 1
|
|
89
|
+
|
|
90
|
+
return self
|
|
91
|
+
|
|
92
|
+
def release(self):
|
|
93
|
+
super().release()
|
|
94
|
+
for index in range(self.pixel_count):
|
|
95
|
+
self.pixels[index] = 3 * (0,)
|
|
96
|
+
self.pixels.show()
|
|
97
|
+
time.sleep(0.1)
|
|
98
|
+
|
|
99
|
+
def update_screen(self, image, session, header):
|
|
100
|
+
image = cv2.resize(image, self.size)
|
|
101
|
+
|
|
102
|
+
super().update_screen(image, session, header)
|
|
103
|
+
|
|
104
|
+
return self
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import cv2
|
|
2
|
+
|
|
3
|
+
from bluer_sbc.hardware.screen import Screen
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Unicorn_16x16(Screen):
|
|
7
|
+
def __init__(self):
|
|
8
|
+
super().__init__()
|
|
9
|
+
self.size = (16, 16)
|
|
10
|
+
self.animated = True
|
|
11
|
+
|
|
12
|
+
def release(self):
|
|
13
|
+
super().release()
|
|
14
|
+
|
|
15
|
+
import unicornhathd
|
|
16
|
+
|
|
17
|
+
unicornhathd.off()
|
|
18
|
+
|
|
19
|
+
def update_screen(self, image, session, header):
|
|
20
|
+
import unicornhathd
|
|
21
|
+
|
|
22
|
+
image = cv2.rotate(
|
|
23
|
+
cv2.resize(
|
|
24
|
+
image,
|
|
25
|
+
self.size,
|
|
26
|
+
),
|
|
27
|
+
cv2.ROTATE_90_CLOCKWISE,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
super().update_screen(image, session, header)
|
|
31
|
+
|
|
32
|
+
for x in range(0, 16):
|
|
33
|
+
for y in range(0, 16):
|
|
34
|
+
unicornhathd.set_pixel(
|
|
35
|
+
x,
|
|
36
|
+
y,
|
|
37
|
+
image[x, y, 0],
|
|
38
|
+
image[x, y, 1],
|
|
39
|
+
image[x, y, 2],
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
unicornhathd.show()
|
|
43
|
+
|
|
44
|
+
return self
|
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
|
|
3
|
+
from blue_options.terminal import show_usage, xtra
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def help_validate(
|
|
7
|
+
tokens: List[str],
|
|
8
|
+
mono: bool,
|
|
9
|
+
) -> str:
|
|
10
|
+
return show_usage(
|
|
11
|
+
[
|
|
12
|
+
"@sbc",
|
|
13
|
+
"adafruit_rgb_matrix",
|
|
14
|
+
"validate",
|
|
15
|
+
],
|
|
16
|
+
"validate adafruit_rgb_matrix.",
|
|
17
|
+
mono=mono,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
help_functions = {
|
|
22
|
+
"validate": help_validate,
|
|
23
|
+
}
|
bluer_sbc/help/camera.py
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
|
|
3
|
+
from blue_options.terminal import show_usage
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def help_capture_image(
|
|
7
|
+
tokens: List[str],
|
|
8
|
+
mono: bool,
|
|
9
|
+
) -> str:
|
|
10
|
+
return show_usage(
|
|
11
|
+
[
|
|
12
|
+
"@sbc",
|
|
13
|
+
"camera",
|
|
14
|
+
"capture",
|
|
15
|
+
"image",
|
|
16
|
+
],
|
|
17
|
+
"capture an image.",
|
|
18
|
+
mono=mono,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def help_capture_video(
|
|
23
|
+
tokens: List[str],
|
|
24
|
+
mono: bool,
|
|
25
|
+
) -> str:
|
|
26
|
+
args = [
|
|
27
|
+
"[--length 10]",
|
|
28
|
+
"[--preview 1]",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
return show_usage(
|
|
32
|
+
[
|
|
33
|
+
"@sbc",
|
|
34
|
+
"camera",
|
|
35
|
+
"capture",
|
|
36
|
+
"video",
|
|
37
|
+
]
|
|
38
|
+
+ args,
|
|
39
|
+
"capture a video",
|
|
40
|
+
mono=mono,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def help_preview(
|
|
45
|
+
tokens: List[str],
|
|
46
|
+
mono: bool,
|
|
47
|
+
) -> str:
|
|
48
|
+
args = [
|
|
49
|
+
"[--length 10]",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
return show_usage(
|
|
53
|
+
[
|
|
54
|
+
"@sbc",
|
|
55
|
+
"camera",
|
|
56
|
+
"preview",
|
|
57
|
+
"[-]",
|
|
58
|
+
]
|
|
59
|
+
+ args,
|
|
60
|
+
"preview.",
|
|
61
|
+
mono=mono,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
help_functions = {
|
|
66
|
+
"capture": {
|
|
67
|
+
"image": help_capture_image,
|
|
68
|
+
"video": help_capture_video,
|
|
69
|
+
},
|
|
70
|
+
"preview": help_preview,
|
|
71
|
+
}
|