hid: better error handling

This commit is contained in:
Devaev Maxim
2019-04-07 07:39:05 +03:00
parent f426e13907
commit 6c121bf87f
4 changed files with 35 additions and 21 deletions

View File

@@ -153,7 +153,7 @@ def _get_config_scheme() -> Dict:
"reset_pin": Option(-1, type=valid_gpio_pin),
"reset_delay": Option(0.1, type=valid_float_f01),
"device": Option("", type=valid_abs_path_exists, unpack_as="device_path"),
"device": Option("", type=valid_abs_path, unpack_as="device_path"),
"speed": Option(115200, type=valid_tty_speed),
"read_timeout": Option(2.0, type=valid_float_f01),
"read_retries": Option(10, type=valid_int_f1),

View File

@@ -28,6 +28,7 @@ import multiprocessing.queues
import queue
import struct
import pkgutil
import errno
import time
from typing import Dict
@@ -188,10 +189,11 @@ class Hid(multiprocessing.Process): # pylint: disable=too-many-instance-attribu
self.__unsafe_clear_events()
get_logger().info("Stopping HID daemon ...")
self.__stop_event.set()
self.join()
else:
get_logger().warning("Emergency cleaning up HID events ...")
self.__emergency_clear_events()
if self.exitcode is not None:
self.join()
gpio.write(self.__reset_pin, False)
async def __send_bool_event(self, cls: Any, pressed: Set[str], name: str, state: bool) -> None:
@@ -230,26 +232,40 @@ class Hid(multiprocessing.Process): # pylint: disable=too-many-instance-attribu
get_logger().exception("Can't execute emergency clear HID events")
def run(self) -> None: # pylint: disable=too-many-branches
logger = get_logger(0)
logger.info("Started HID pid=%d", os.getpid())
signal.signal(signal.SIGINT, signal.SIG_IGN)
setproctitle.setproctitle("[hid] " + setproctitle.getproctitle())
try:
with self.__get_serial() as tty:
passed = 0
while not (self.__stop_event.is_set() and self.__events_queue.qsize() == 0):
try:
event = self.__events_queue.get(timeout=0.05)
except queue.Empty:
if passed >= 20: # 20 * 0.05 = 1 sec
self.__process_command(tty, b"\x01\x00\x00\x00\x00") # Ping
passed = 0
while not self.__stop_event.is_set():
try:
with self.__get_serial() as tty:
passed = 0
while not (self.__stop_event.is_set() and self.__events_queue.qsize() == 0):
try:
event = self.__events_queue.get(timeout=0.05)
except queue.Empty:
if passed >= 20: # 20 * 0.05 = 1 sec
self.__process_command(tty, b"\x01\x00\x00\x00\x00") # Ping
passed = 0
else:
passed += 1
else:
passed += 1
else:
self.__process_command(tty, event.make_command())
passed = 0
except Exception:
get_logger().exception("Unhandled exception")
raise
self.__process_command(tty, event.make_command())
passed = 0
except serial.SerialException as err:
if err.errno == errno.ENOENT:
logger.error("Missing HID serial device: %s", self.__device_path)
else:
logger.exception("Unexpected HID error")
except Exception:
logger.exception("Unexpected HID error")
finally:
time.sleep(1)
def __get_serial(self) -> serial.Serial:
return serial.Serial(self.__device_path, self.__speed, timeout=self.__read_timeout)