Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Hims usb detection issues and scroll keys input for Polaris displays #7865

Merged
merged 5 commits into from Feb 9, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
62 changes: 29 additions & 33 deletions source/brailleDisplayDrivers/hims.py
Expand Up @@ -19,9 +19,8 @@
import brailleInput
from baseObject import AutoPropertyObject
import weakref
import time


TIMEOUT = 0.2
BAUD_RATE = 115200
PARITY = serial.PARITY_NONE

Expand Down Expand Up @@ -79,6 +78,18 @@ class BrailleSense(Model):
bluetoothPrefix = "BrailleSense"
numCells = 0 # Either 18 or 32

def _get_keys(self):
keys = super(BrailleSense, self)._get_keys()
keys.update({
0x20<<8: "leftSideScroll",
0x40<<8: "rightSideScroll",
0x01<<16: "leftSideScrollUp",
0x02<<16: "leftSideScrollDown",
0x04<<16: "rightSideScrollUp",
0x08<<16: "rightSideScrollDown",
})
return keys

class BrailleEdge(Model):
deviceId="\x42\x45" # BE
name = "Braille Edge"
Expand Down Expand Up @@ -111,31 +122,12 @@ def _get_keys(self):
class BrailleSense2S(BrailleSense):
"""Braille Sense with one scroll key on both sides.
Also referred to as Braille Sense Classic."""

name = "Braille Sense"
name = "Braille Sense Classic"
deviceId="\x42\x53" # BS

def _get_keys(self):
keys = super(BrailleSense2S, self)._get_keys()
keys.update({
0x20<<8: "leftSideScroll",
0x40<<8: "rightSideScroll",
})
return keys

class BrailleSense4S(BrailleSense):
deviceId="\x4c\x58" # LX

def _get_keys(self):
keys = super(BrailleSense4S, self)._get_keys()
keys.update({
0x01<<16: "leftSideScrollUp",
0x02<<16: "leftSideScrollDown",
0x04<<16: "rightSideScrollUp",
0x08<<16: "rightSideScrollDown",
})
return keys

class SmartBeetle(BrailleSense4S):
"""Subclass for Smart Beetle device, which has the same identifier as the Braille Sense with 4 scroll keys.
However, it is distinguishable by the number of cells.
Expand All @@ -152,9 +144,6 @@ def _get_keys(self):
0x10<<8: "f2",
0x04<<16: "leftSideScroll",
0x08<<16: "rightSideScroll",
# Once in a while, a Beetle sends the wrong key codes for left and right scroll.
0x20<<8: "leftSideScroll",
0x40<<8: "rightSideScroll",
})
return keys

Expand Down Expand Up @@ -200,6 +189,7 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver):
# Translators: The name of a series of braille displays.
description = _("HIMS Braille Sense/Braille EDGE/Smart Beetle/Sync Braille series")
isThreadSafe = True
timeout = 0.2

@classmethod
def check(cls):
Expand Down Expand Up @@ -290,17 +280,21 @@ def __init__(self, port="auto"):
# onReceiveSize based on max packet size according to USB endpoint information.
self._dev = hwIo.Bulk(port, 0, 1, self._onReceive, writeSize=0, onReceiveSize=64)
else:
self._dev = hwIo.Serial(port, baudrate=BAUD_RATE, parity=PARITY, timeout=TIMEOUT, writeTimeout=TIMEOUT, onReceive=self._onReceive)
self._dev = hwIo.Serial(port, baudrate=BAUD_RATE, parity=PARITY, timeout=self.timeout, writeTimeout=self.timeout, onReceive=self._onReceive)
except EnvironmentError:
log.debugWarning("", exc_info=True)
continue

self._sendCellCountRequest()
# Send a cell count request twice, since it seems that the first sent request sometimes doesn't come through
self._sendCellCountRequest()
for i in xrange(3):
# An expected response hasn't arrived yet, so wait for it.
self._dev.waitForRead(TIMEOUT)
self._sendCellCountRequest()
# Wait for an expected response.
if self.isBulk:
# Hims Bulk devices sometimes present themselves to the system while not yet ready.
# For example, when switching the connection mode toggle on the Braille EDGE from Bluetooth to USB,
# the USB device is connected but not yet ready.
# Wait ten times the timeout, which is ugly, but effective.
self._dev.waitForRead(self.timeout*10)
else:
self._dev.waitForRead(self.timeout)
if self.numCells:
break
if not self.numCells:
Expand Down Expand Up @@ -359,7 +353,7 @@ def _sendIdentificationRequests(self, usbId=None, bluetoothPrefix=None):
for id, cls in map:
log.debug("Sending request for id %r"%id)
self._dev.write("\x1c{id}\x1f".format(id=id))
self._dev.waitForRead(TIMEOUT)
self._dev.waitForRead(self.timeout)
if self._model:
log.debug("%s model has been set"%self._model.name)
break
Expand Down Expand Up @@ -490,6 +484,8 @@ def terminate(self):
try:
super(BrailleDisplayDriver, self).terminate()
finally:
# We must sleep before closing the port as not doing this can leave the display in a bad state where it can not be re-initialized.
time.sleep(self.timeout)
# Make sure the device gets closed.
# If it doesn't, we may not be able to re-open it later.
self._dev.close()
Expand Down