From 689d1cad5dd7b56ab72119bedd6241b0bff34346 Mon Sep 17 00:00:00 2001 From: Olivier Delree Date: Wed, 29 May 2024 12:52:30 +0100 Subject: [PATCH 1/5] add input and reward address attributes to config This allows the config to dictate what ports are presented as options on the main web interface. The previous approach only listed serial ports that were automatically detected. This commit provides the user with the option of providing custom ports through the config, which is useful when debugging on machines that do not have serial ports available. --- src/visiomode/config.py | 6 ++++++ src/visiomode/core.py | 11 +++++++++++ src/visiomode/devices/__init__.py | 17 ++++++++++++++--- .../webpanel/templates/protocols/task.html | 2 +- 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/visiomode/config.py b/src/visiomode/config.py index 23999e1a..bbb61801 100644 --- a/src/visiomode/config.py +++ b/src/visiomode/config.py @@ -25,6 +25,8 @@ "height": 800, "fullscreen": False, "devices": "devices", + "input_device_address": "/dev/ttyS0", + "reward_device_address": "/dev/ttyS0", "config_path": ".visiomode.json", } @@ -46,6 +48,8 @@ class Config: height: Screen height. fullscreen: Fullscreen mode flag. devices: Path to devices directory. + input_device_address: Path to the input device address. + reward_device_address: Path to the device address. config_path: Path to the config. """ @@ -60,6 +64,8 @@ class Config: height: int fullscreen: bool devices: str + input_device_address: str + reward_device_address: str config_path: str _instance = None diff --git a/src/visiomode/core.py b/src/visiomode/core.py index 975fa16c..4cfc939b 100644 --- a/src/visiomode/core.py +++ b/src/visiomode/core.py @@ -185,6 +185,17 @@ def request_listener(self): logging.error("Invalid request - {}".format(request)) continue if request["type"] == "start": + # Update config + conf.Config().input_device_address = ( + request["data"].get("response_address") + or conf.Config().input_device_address + ) + conf.Config().reward_device_address = ( + request["data"].get("reward_address") + or conf.Config().reward_device_address + ) + conf.Config().save() + protocol = protocols.get_protocol(request["data"].pop("protocol")) self.session = models.Session( animal_id=request["data"].pop("animal_id"), diff --git a/src/visiomode/devices/__init__.py b/src/visiomode/devices/__init__.py index 49c872b4..f5f48151 100644 --- a/src/visiomode/devices/__init__.py +++ b/src/visiomode/devices/__init__.py @@ -12,9 +12,20 @@ import visiomode.plugins as plugins -def get_available_devices(): - """Return list of all serial devices connected to the machine.""" - return [dev.device for dev in ports.comports()] +def get_available_devices() -> list[str]: + """ + Return list of all serial devices connected to the machine, with ones defined in the + config prepended. + """ + # Get an ordered set of keys so that options presented to the user are more + # pleasingly organised. + return list( + dict.fromkeys( + [conf.Config().reward_device_address] + + [conf.Config().input_device_address] + + [dev.device for dev in ports.comports()] + ).keys() + ) def get_input_device(profile_id, address=None): diff --git a/src/visiomode/webpanel/templates/protocols/task.html b/src/visiomode/webpanel/templates/protocols/task.html index b307cf74..47b9a039 100644 --- a/src/visiomode/webpanel/templates/protocols/task.html +++ b/src/visiomode/webpanel/templates/protocols/task.html @@ -11,7 +11,7 @@ From 572ad77a720b0f350298b9640bf3a3a52d1fa67d Mon Sep 17 00:00:00 2001 From: Olivier Delree Date: Wed, 29 May 2024 17:36:36 +0100 Subject: [PATCH 2/5] update copyright --- src/visiomode/devices/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/visiomode/devices/__init__.py b/src/visiomode/devices/__init__.py index f5f48151..24be4b8e 100644 --- a/src/visiomode/devices/__init__.py +++ b/src/visiomode/devices/__init__.py @@ -2,6 +2,7 @@ # This file is part of visiomode. # Copyright (c) 2020 Constantinos Eleftheriou +# Copyright (c) 2024 Olivier Delree # Distributed under the terms of the MIT Licence. import os import queue From 5fb1268000b2251811d81a5629c20fa6292d95a1 Mon Sep 17 00:00:00 2001 From: Olivier Delree Date: Tue, 4 Jun 2024 11:56:16 +0100 Subject: [PATCH 3/5] apply black formatting --- src/visiomode/core.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/visiomode/core.py b/src/visiomode/core.py index 4cfc939b..d1077d43 100644 --- a/src/visiomode/core.py +++ b/src/visiomode/core.py @@ -187,12 +187,12 @@ def request_listener(self): if request["type"] == "start": # Update config conf.Config().input_device_address = ( - request["data"].get("response_address") - or conf.Config().input_device_address + request["data"].get("response_address") + or conf.Config().input_device_address ) conf.Config().reward_device_address = ( - request["data"].get("reward_address") - or conf.Config().reward_device_address + request["data"].get("reward_address") + or conf.Config().reward_device_address ) conf.Config().save() From 0d152dacdf54acd4c82c017811b80617fbe96338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Delr=C3=A9e?= Date: Mon, 9 Dec 2024 16:39:44 +0000 Subject: [PATCH 4/5] fix merge conflict --- src/visiomode/core.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/visiomode/core.py b/src/visiomode/core.py index a4d7c642..15397345 100644 --- a/src/visiomode/core.py +++ b/src/visiomode/core.py @@ -195,7 +195,6 @@ def request_listener(self): ) conf.Config().save() - protocol = protocols.get_protocol(request["data"].pop("protocol")) task = tasks.get_task(request["data"].pop("task")) self.session = models.Session( animal_id=request["data"].pop("animal_id"), From 5f2f842a7aeba5defc757938c0ccbd0579c638b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Delr=C3=A9e?= Date: Mon, 9 Dec 2024 16:49:30 +0000 Subject: [PATCH 5/5] obtain default config device addresses from `serial` --- src/visiomode/config.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/visiomode/config.py b/src/visiomode/config.py index 8986ada8..18670f0d 100644 --- a/src/visiomode/config.py +++ b/src/visiomode/config.py @@ -5,12 +5,14 @@ # Copyright (c) 2024 Olivier Delree # Distributed under the terms of the MIT Licence. -import os -import shutil import json import logging +import os +import shutil import typing +import serial.tools.list_ports as ports + logging.basicConfig(level=logging.INFO) DEFAULT_CONFIG = { @@ -25,8 +27,12 @@ "height": 800, "fullscreen": False, "devices": "devices", - "input_device_address": "/dev/ttyS0", - "reward_device_address": "/dev/ttyS0", + "input_device_address": ( + ports.comports()[1] if len(ports.comports()) > 1 else "/dev/ttyS0" + ), + "reward_device_address": ( + ports.comports()[0] if len(ports.comports()) else "/dev/ttyS0" + ), "config_path": ".visiomode.json", }