Skip to content

Commit 3b516ef

Browse files
committed
fix: broken blink implementation and documentation
1 parent 3aafae8 commit 3b516ef

File tree

3 files changed

+57
-15
lines changed

3 files changed

+57
-15
lines changed

busylight/lights/muteme/muteme.py

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,37 @@ def blink(self, color: ColorTuple, blink: Speed = Speed.Slow) -> None:
4444
super().blink(color, blink)
4545
with self.batch_update():
4646
self.command.color = color
47-
self.command.blink = blink.value & 0x2
47+
if blink in [Speed.Slow, Speed.Medium]:
48+
self.command.blink = 2
49+
if blink in [Speed.Fast]:
50+
self.command.blink = 1
4851

49-
@property
50-
def touch(self) -> int:
51-
""" """
52-
raise NotImplementedError("touch")
52+
def touch(self, timeout: int = 100) -> bool:
53+
"""Returns the current state of the touch surface."""
54+
55+
# EJO this is a hack constructed from observing that
56+
# consecutive reads from the device while touched can be:
57+
#
58+
# a = [0, 0, 0, 1]
59+
# b = [0, 0, 0, 0]
60+
#
61+
# Sometimes the order is reversed where b contains the
62+
# actual touch status in the final byte. If we sum each of
63+
# the items in both arrays we should arrive at a valid
64+
# touch status in the final byte regardless of how the
65+
# device was polled. This behavior will probably need to
66+
# be controlled, hopefully the device release_number will
67+
# provide the necessary information to differentiate
68+
# devices that might need different polling strategies.
69+
#
70+
71+
first = self.read_strategy(4, timeout)
72+
second = self.read_strategy(4, timeout)
73+
74+
result = [f + s for f, s in zip(first, second)]
75+
76+
try:
77+
return result[-1] == 1
78+
except IndexError:
79+
pass
80+
return False

busylight/lights/muteme/muteme_impl.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,10 @@ def __init__(self):
6161
self.default = self.value
6262

6363
header = Header(8, 8)
64+
# bit 7 unused?
6465

65-
sleep = SleepField(7, 1)
66-
blink = BlinkField(5, 2)
66+
sleep = SleepField(6, 1)
67+
_blink = BlinkField(5, 1)
6768
dim = DimField(4, 1)
6869

6970
reserved = ReservedField(3, 1)
@@ -95,3 +96,19 @@ def firmware_update(self) -> bool:
9596
def firmware_update(self, value: bool) -> None:
9697
self.reserved = int(bool(value))
9798
self.red = int(bool(value))
99+
100+
@property
101+
def blink(self) -> int:
102+
if self._blink:
103+
return self._blink + self.dim
104+
return 0
105+
106+
@blink.setter
107+
def blink(self, value: int) -> None:
108+
if value == 0:
109+
self._blink = 0
110+
if value == 1:
111+
self._blink = 1
112+
if value == 2:
113+
self._blink = 1
114+
self.dim = 1

docs/devices/muteme.md

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ typedef struct {
5858
unsigned int header:8; /* 08:15 Constant: 0x00 */
5959

6060
unsigned int sleep:1; /* 07:07 Initiates a ten second sleep mode */
61-
unsigned int blink:2; /* 05:06 Blink: off=00 slow=01, fast=10 */
61+
unsgined int pad0:1;
62+
unsigned int blink:1; /* 05:05 Blink */
6263
unsigned int dim:1; /* 04:04 Set is dim, cleared is bright*/
6364
unsigned int reserved:1; /* 03:03 Reserved for future use. */
6465
unsigned int blue:1; /* 02:02 Set is full value blue */
@@ -107,13 +108,9 @@ bright operation when `dim` is cleared.
107108

108109
### Blink Mode
109110

110-
The light can be made to blink at two different speeds by setting the
111-
`blink` field. Valid blink values are:
112-
113-
- 0b00 off
114-
- 0b01 slow
115-
- 0b10 unused state
116-
- 0b11 fast
111+
The light can blink at two different speeds: slow and fast.
112+
Fast blink is indicated by setting blink and clearing dim.
113+
Slow blink is indicated by setting blink and setting dim.
117114

118115
## Observations
119116

0 commit comments

Comments
 (0)