Add support for multiple serial devices
This commit is contained in:
parent
f6c206e0b1
commit
87e337a69d
@ -24,7 +24,8 @@ barcode_server:
|
||||
# (optional) Serial push configuration
|
||||
serial:
|
||||
# URL to send events to using a request
|
||||
path: "/dev/ttyUSB0"
|
||||
pathA: "/dev/ttyUSB0"
|
||||
pathB: "/dev/ttyUSB1"
|
||||
|
||||
# (optional) file push configuration
|
||||
file:
|
||||
@ -62,7 +63,7 @@ barcode_server:
|
||||
|
||||
# A list of regex patterns to match USB device names against
|
||||
devices:
|
||||
- ".*Barcode.*"
|
||||
- ".*ode.*"
|
||||
# A list of absolute file paths to devices
|
||||
device_paths:
|
||||
#- "/dev/input/barcode_scanner"
|
||||
|
@ -50,7 +50,7 @@ def c_run():
|
||||
"""
|
||||
from barcode_server.barcode import BarcodeReader
|
||||
from barcode_server.config import AppConfig
|
||||
from barcode_server.webserver import Webserver
|
||||
from barcode_server.webserver import WebServer
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
@ -64,7 +64,7 @@ def c_run():
|
||||
LOGGER.info(f"Instance ID: {config.INSTANCE_ID.value}")
|
||||
|
||||
barcode_reader = BarcodeReader(config)
|
||||
webserver = Webserver(config, barcode_reader)
|
||||
webserver = WebServer(config, barcode_reader)
|
||||
|
||||
# start prometheus server
|
||||
if config.STATS_PORT.value is not None:
|
||||
|
@ -213,11 +213,20 @@ class AppConfig(ConfigBase):
|
||||
required=True
|
||||
)
|
||||
|
||||
SERIAL_PATH = StringConfigEntry(
|
||||
SERIAL_PATH_A = StringConfigEntry(
|
||||
key_path=[
|
||||
CONFIG_NODE_ROOT,
|
||||
CONFIG_NODE_SERIAL,
|
||||
"path"
|
||||
"pathA"
|
||||
],
|
||||
required=False
|
||||
)
|
||||
|
||||
SERIAL_PATH_B = StringConfigEntry(
|
||||
key_path=[
|
||||
CONFIG_NODE_ROOT,
|
||||
CONFIG_NODE_SERIAL,
|
||||
"pathB"
|
||||
],
|
||||
required=False
|
||||
)
|
||||
|
@ -1,11 +1,14 @@
|
||||
import os
|
||||
import logging
|
||||
# import time as sleep
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
from prometheus_async.aio import time
|
||||
|
||||
from barcode_server.barcode import BarcodeEvent
|
||||
from barcode_server.notifier import BarcodeNotifier
|
||||
from barcode_server.stats import FILE_NOTIFIER_TIME
|
||||
from barcode_server.util import barcode_event_to_json
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -13,8 +16,45 @@ class FileNotifier(BarcodeNotifier):
|
||||
|
||||
def __init__(self, path: str):
|
||||
super().__init__()
|
||||
self.inputDevicePathA = None
|
||||
self.inputDevicePathB = None
|
||||
self.path = path
|
||||
pathObject = Path(path)
|
||||
if not pathObject.exists():
|
||||
pathObject.mkdir(exist_ok=True)
|
||||
|
||||
# def ticks(dt):
|
||||
# return (dt - datetime(1, 1, 1)).total_seconds() * 10000000
|
||||
|
||||
@time(FILE_NOTIFIER_TIME)
|
||||
async def _send_event(self, event: BarcodeEvent):
|
||||
LOGGER.debug(f"Notified {self.path}: {event.barcode}")
|
||||
now = datetime.now()
|
||||
date_time = now.strftime("%Y-%m-%d")
|
||||
weekNumberOfYear = now.strftime("%Y_Week_%U")
|
||||
if self.inputDevicePathA is None:
|
||||
self.inputDevicePathA = event.input_device.path
|
||||
elif self.inputDevicePathB is None:
|
||||
self.inputDevicePathB = event.input_device.path
|
||||
weekPath = f"{self.path}/{weekNumberOfYear}"
|
||||
dateTimePath = f"{weekPath}/{date_time}"
|
||||
if event.input_device.path == self.inputDevicePathA:
|
||||
fullPath = f"{dateTimePath}/A"
|
||||
elif event.input_device.path == self.inputDevicePathB:
|
||||
fullPath = f"{dateTimePath}/B"
|
||||
else:
|
||||
fullPath = f"{dateTimePath}/Z"
|
||||
json = barcode_event_to_json(self.config.INSTANCE_ID.value, event)
|
||||
ticks = int((datetime.utcnow() - datetime(1, 1, 1)).total_seconds() * 10000000)
|
||||
pathObject = Path(weekPath)
|
||||
if not pathObject.exists():
|
||||
pathObject.mkdir(exist_ok=True)
|
||||
pathObject = Path(dateTimePath)
|
||||
if not pathObject.exists():
|
||||
pathObject.mkdir(exist_ok=True)
|
||||
pathObject = Path(fullPath)
|
||||
if not pathObject.exists():
|
||||
pathObject.mkdir(exist_ok=True)
|
||||
f = open(f"{fullPath}/{str(ticks)}.json", 'wb')
|
||||
f.write(json)
|
||||
f.close()
|
||||
LOGGER.debug(f"Notified {fullPath}: {event.barcode}")
|
||||
|
@ -1,6 +1,5 @@
|
||||
import serial
|
||||
import logging
|
||||
# import time as sleep
|
||||
|
||||
from prometheus_async.aio import time
|
||||
|
||||
@ -12,12 +11,25 @@ LOGGER = logging.getLogger(__name__)
|
||||
|
||||
class SerialNotifier(BarcodeNotifier):
|
||||
|
||||
def __init__(self, path: str, usb: serial):
|
||||
def __init__(self, pathA: str, pathB: str):
|
||||
super().__init__()
|
||||
self.path = path
|
||||
self.usb = usb
|
||||
self.pathA = pathA
|
||||
self.pathB = pathB
|
||||
self.inputDevicePathA = None
|
||||
self.inputDevicePathB = None
|
||||
self.usbA = serial.Serial(pathA, 9600, timeout=2)
|
||||
if pathB is not None:
|
||||
self.usbB = serial.Serial(pathB, 9600, timeout=2)
|
||||
|
||||
@time(SERIAL_NOTIFIER_TIME)
|
||||
async def _send_event(self, event: BarcodeEvent):
|
||||
self.usb.write(event.barcode.encode())
|
||||
LOGGER.debug(f"Notified {self.path}: {event.barcode}")
|
||||
if self.inputDevicePathA is None:
|
||||
self.inputDevicePathA = event.input_device.path
|
||||
elif self.inputDevicePathB is None:
|
||||
self.inputDevicePathB = event.input_device.path
|
||||
if event.input_device.path == self.inputDevicePathA:
|
||||
self.usbA.write(event.barcode.encode())
|
||||
LOGGER.debug(f"Notified {self.pathA}: {self.inputDevicePathA}: {event.barcode}")
|
||||
elif event.input_device.path == self.inputDevicePathB:
|
||||
self.usbB.write(event.barcode.encode())
|
||||
LOGGER.debug(f"Notified {self.pathB}: {self.inputDevicePathB}: {event.barcode}")
|
||||
|
@ -27,3 +27,4 @@ WEBSOCKET_NOTIFIER_TIME = NOTIFIER_TIME.labels(type='websocket')
|
||||
HTTP_NOTIFIER_TIME = NOTIFIER_TIME.labels(type='http')
|
||||
SERIAL_NOTIFIER_TIME = NOTIFIER_TIME.labels(type='serial')
|
||||
MQTT_NOTIFIER_TIME = NOTIFIER_TIME.labels(type='mqtt')
|
||||
FILE_NOTIFIER_TIME = NOTIFIER_TIME.labels(type='file')
|
||||
|
@ -15,6 +15,7 @@ from barcode_server.notifier import BarcodeNotifier
|
||||
from barcode_server.notifier.http import HttpNotifier
|
||||
from barcode_server.notifier.mqtt import MQTTNotifier
|
||||
from barcode_server.notifier.serial import SerialNotifier
|
||||
from barcode_server.notifier.file import FileNotifier
|
||||
from barcode_server.notifier.ws import WebsocketNotifier
|
||||
from barcode_server.stats import REST_TIME_DEVICES, WEBSOCKET_CLIENT_COUNT
|
||||
from barcode_server.util import input_device_to_dict
|
||||
@ -23,7 +24,7 @@ LOGGER = logging.getLogger(__name__)
|
||||
routes = web.RouteTableDef()
|
||||
|
||||
|
||||
class Webserver:
|
||||
class WebServer:
|
||||
|
||||
def __init__(self, config: AppConfig, barcode_reader: BarcodeReader):
|
||||
self.config = config
|
||||
@ -35,9 +36,8 @@ class Webserver:
|
||||
self.barcode_reader = barcode_reader
|
||||
self.barcode_reader.add_listener(self.on_barcode)
|
||||
|
||||
self.usb = {}
|
||||
|
||||
self.notifiers: Dict[str, BarcodeNotifier] = {}
|
||||
|
||||
if config.HTTP_URL.value is not None:
|
||||
http_notifier = HttpNotifier(
|
||||
config.HTTP_METHOD.value,
|
||||
@ -58,13 +58,12 @@ class Webserver:
|
||||
)
|
||||
self.notifiers["mqtt"] = mqtt_notifier
|
||||
|
||||
if config.SERIAL_PATH.value is not None:
|
||||
self.usb = serial.Serial(config.SERIAL_PATH.value, 9600, timeout=2)
|
||||
serial_notifier = SerialNotifier(config.SERIAL_PATH.value, self.usb)
|
||||
if config.SERIAL_PATH_A.value is not None:
|
||||
serial_notifier = SerialNotifier(config.SERIAL_PATH_A.value, config.SERIAL_PATH_B.value)
|
||||
self.notifiers["serial"] = serial_notifier
|
||||
|
||||
if config.FILE_PATH.value is not None:
|
||||
file_notifier = SerialNotifier(config.FILE_PATH.value)
|
||||
file_notifier = FileNotifier(config.FILE_PATH.value)
|
||||
self.notifiers["file"] = file_notifier
|
||||
|
||||
async def start(self):
|
||||
|
@ -8,7 +8,7 @@ from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
|
||||
from barcode_server import const
|
||||
from barcode_server.barcode import BarcodeEvent
|
||||
from barcode_server.util import barcode_event_to_json
|
||||
from barcode_server.webserver import Webserver
|
||||
from barcode_server.webserver import WebServer
|
||||
|
||||
|
||||
def create_barcode_event_mock(barcode: str = None):
|
||||
@ -46,7 +46,7 @@ class WebsocketNotifierTest(AioHTTPTestCase):
|
||||
Override the get_app method to return your application.
|
||||
"""
|
||||
barcode_reader = MagicMock()
|
||||
self.webserver = Webserver(self.config, barcode_reader)
|
||||
self.webserver = WebServer(self.config, barcode_reader)
|
||||
app = self.webserver.create_app()
|
||||
runner = aiohttp.web.AppRunner(app)
|
||||
await runner.setup()
|
||||
|
Loading…
x
Reference in New Issue
Block a user