Skip to content

Commit 5fadf47

Browse files
authored
Allow read address in SDK (#257)
- Add ``get_watchable_info`` to the client to read detailed metadata of the watchables. - Variable : Address, bitoffset, bitsize - Alias : target, target_type, gain, offset, min, max - RPV : ID - ``WatchableHandle`` now have a property to returned the detailed information about the watchables - Renamed ``display_path`` to ``server_path`` on the client side. - Renamed ``WatchableConfiguration`` to ``BriefWatchableConfiguration`` and added ``DetailedWatchableConfiguration`` - Cleaned some unit tests
1 parent cc863d1 commit 5fadf47

38 files changed

+1093
-363
lines changed

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
"blaoting" : "bloating",
8888
"blaot" : "bloat",
8989
"uplaod" : "upload",
90+
"sued" : "used",
9091
}
9192
}]
9293
}

scrutiny/gui/components/globals/varlist/varlist_search.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
@dataclass(frozen=True, slots=True)
2828
class SingleResult:
2929
fqn: str
30-
config: sdk.WatchableConfiguration
30+
config: sdk.BriefWatchableConfiguration
3131

3232

3333
@dataclass(frozen=True, slots=True)
@@ -39,7 +39,7 @@ def match(self, candidate: SingleResult) -> bool:
3939

4040

4141
class SearchResultTreeModel(VarListComponentTreeModel):
42-
def get_watchable_extra_columns(self, fqn: str, watchable_config: Optional[sdk.WatchableConfiguration] = None) -> List[QStandardItem]:
42+
def get_watchable_extra_columns(self, fqn: str, watchable_config: Optional[sdk.BriefWatchableConfiguration] = None) -> List[QStandardItem]:
4343
outlist: List[QStandardItem] = [QStandardItem(WatchableRegistry.FQN.parse(fqn).path)]
4444

4545
if watchable_config is not None:

scrutiny/gui/components/globals/varlist/varlist_tree_model.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
NodeSerializableData
2020
)
2121

22-
from scrutiny.sdk import WatchableConfiguration
22+
from scrutiny.sdk import BriefWatchableConfiguration
2323
from scrutiny.tools.typing import *
2424

2525

@@ -28,7 +28,7 @@ class VarListComponentTreeModel(WatchableTreeModel):
2828
Mainly handles drag&drop logic
2929
"""
3030

31-
def get_watchable_extra_columns(self, fqn: str, watchable_config: Optional[WatchableConfiguration] = None) -> List[QStandardItem]:
31+
def get_watchable_extra_columns(self, fqn: str, watchable_config: Optional[BriefWatchableConfiguration] = None) -> List[QStandardItem]:
3232
"""Define the columns to add for a watchable (leaf) row. Called by the parent class"""
3333
if watchable_config is None:
3434
return []

scrutiny/gui/components/locals/continuous_graph/continuous_graph_component.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,7 @@ def get_x(val: RegistryValueUpdate) -> float: # A getter to get the relative
877877
tools.log_exception(self.logger, e, f"Error when receiving data for the chart")
878878
self.stop_acquisition()
879879

880-
def _unwatch_callback(self, watcher_id: Union[str, int], server_path: str, watchable_config: sdk.WatchableConfiguration, registry_id: int) -> None:
880+
def _unwatch_callback(self, watcher_id: Union[str, int], server_path: str, watchable_config: sdk.BriefWatchableConfiguration, registry_id: int) -> None:
881881
# Should we do something? User feedback if the watchable is not available anymore maybe?
882882
pass
883883

scrutiny/gui/components/locals/watch/watch_component.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ def _register_watcher_for_row(self, item: WatchableStandardItem) -> None:
281281
def update_val_closure(watcher_id: Union[str, int], vals: List[RegistryValueUpdate]) -> None:
282282
self._update_val_callback(value_item, watcher_id, vals)
283283

284-
def unwatch_closure(watcher_id: Union[str, int], server_path: str, watchable_config: sdk.WatchableConfiguration, registry_id: int) -> None:
284+
def unwatch_closure(watcher_id: Union[str, int], server_path: str, watchable_config: sdk.BriefWatchableConfiguration, registry_id: int) -> None:
285285
pass
286286

287287
watcher_id = self._get_watcher_id(item)

scrutiny/gui/components/locals/watch/watch_tree_model.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from PySide6.QtGui import (QStandardItem, QPalette, QContextMenuEvent, QDragMoveEvent, QDropEvent,
2323
QDragEnterEvent, QKeyEvent, QStandardItem, QAction)
2424

25-
from scrutiny.sdk import WatchableConfiguration, EmbeddedEnum
25+
from scrutiny.sdk import BriefWatchableConfiguration, EmbeddedEnum
2626
from scrutiny.gui.core.scrutiny_drag_data import ScrutinyDragData, WatchableListDescriptor
2727
from scrutiny.gui.core.watchable_registry import WatchableRegistry
2828
from scrutiny.gui.widgets.watchable_tree import (
@@ -427,7 +427,7 @@ def watchable_item_created(self, item: WatchableStandardItem) -> None:
427427
def itemFromIndex(self, index: Union[QModelIndex, QPersistentModelIndex]) -> BaseWatchableRegistryTreeStandardItem:
428428
return cast(BaseWatchableRegistryTreeStandardItem, super().itemFromIndex(index))
429429

430-
def get_watchable_extra_columns(self, fqn: str = "", watchable_config: Optional[WatchableConfiguration] = None) -> List[QStandardItem]:
430+
def get_watchable_extra_columns(self, fqn: str = "", watchable_config: Optional[BriefWatchableConfiguration] = None) -> List[QStandardItem]:
431431
# We don't use watchable_config here even if we could.
432432
# We update the value/type when an item is available by calling update_row_state
433433
return [ValueStandardItem(), DataTypeStandardItem(), EnumNameStandardItem()]
@@ -773,7 +773,7 @@ def set_unavailable(self, arg_item: WatchableStandardItem) -> None:
773773
elif isinstance(item, EnumNameStandardItem):
774774
item.setText('')
775775

776-
def set_available(self, arg_item: WatchableStandardItem, watchable_config: WatchableConfiguration) -> None:
776+
def set_available(self, arg_item: WatchableStandardItem, watchable_config: BriefWatchableConfiguration) -> None:
777777
"""Make an item in the tree available (normal color)"""
778778
background_color = self._available_palette.color(QPalette.ColorRole.Base)
779779
forground_color = self._available_palette.color(QPalette.ColorRole.Text)

scrutiny/gui/core/qt.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
__all__ = ['make_qt_app']
1111

1212
from PySide6.QtWidgets import QApplication
13+
from PySide6.QtCore import QLocale
1314
from scrutiny.gui.core.threads import QT_THREAD_NAME
1415
from scrutiny.tools.thread_enforcer import register_thread
1516
from scrutiny.gui.tools.invoker import CrossThreadInvoker
@@ -18,6 +19,11 @@
1819

1920
def make_qt_app(args: List[str]) -> QApplication:
2021
register_thread(QT_THREAD_NAME)
22+
loc = QLocale.c() # Forces C-style environment. Decimal points are "."
23+
# Prevent showing/interpreting commas as group separator
24+
loc.setNumberOptions(QLocale.NumberOption.RejectGroupSeparator | QLocale.NumberOption.OmitGroupSeparator)
25+
QLocale.setDefault(loc)
26+
2127
app = QApplication(args)
2228
CrossThreadInvoker.init()
2329

scrutiny/gui/core/server_manager.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ class _Signals(QObject): # QObject required for signals to work
309309
_loaded_sfd: Optional[sdk.SFDInfo]
310310
"""Contains all the info about the actually loaded Scrutiny Firmware Description. ``None`` if not available"""
311311

312-
_partial_watchable_downloaded_data: Dict[sdk.WatchableType, Dict[str, sdk.WatchableConfiguration]]
312+
_partial_watchable_downloaded_data: Dict[sdk.WatchableType, Dict[str, sdk.BriefWatchableConfiguration]]
313313

314314
def __init__(self, watchable_registry: WatchableRegistry, client: Optional[ScrutinyClient] = None) -> None:
315315
super().__init__() # Required for signals to work
@@ -544,11 +544,11 @@ def _thread_handle_download_watchable_logic(self) -> None:
544544
content = {
545545
sdk.WatchableType.RuntimePublishedValue: data.rpv
546546
}
547-
invoke_in_qt_thread_synchronized(lambda: self._registry.write_content(content), timeout=2)
547+
invoke_in_qt_thread_synchronized(lambda: self._registry.write_content(content), timeout=5)
548548
self._signals.registry_changed.emit()
549549
else:
550550
invoke_in_qt_thread_synchronized(lambda: self._registry.clear_content_by_type(
551-
[sdk.WatchableType.RuntimePublishedValue]), timeout=2)
551+
[sdk.WatchableType.RuntimePublishedValue]), timeout=3)
552552
self._thread_state.runtime_watchables_download_request = None # Clear the request.
553553
else:
554554
pass # Downloading
@@ -566,11 +566,11 @@ def _thread_handle_download_watchable_logic(self) -> None:
566566
sdk.WatchableType.Variable: data.var,
567567
sdk.WatchableType.Alias: data.alias,
568568
}
569-
invoke_in_qt_thread_synchronized(lambda: self._registry.write_content(content), timeout=2)
569+
invoke_in_qt_thread_synchronized(lambda: self._registry.write_content(content), timeout=5)
570570
self._signals.registry_changed.emit()
571571
else:
572572
invoke_in_qt_thread_synchronized(lambda: self._registry.clear_content_by_type(
573-
[sdk.WatchableType.Alias, sdk.WatchableType.Variable]), timeout=2)
573+
[sdk.WatchableType.Alias, sdk.WatchableType.Variable]), timeout=3)
574574
self._thread_state.sfd_watchables_download_request = None # Clear the request.
575575
else:
576576
pass # Downloading
@@ -634,11 +634,11 @@ def clear_func() -> None:
634634
if ctx.had_data:
635635
self._signals.registry_changed.emit()
636636

637-
def _make_var_watchable_from_factories(self, var_factories: Dict[str, sdk.VariableFactoryInterface]) -> Dict[str, sdk.WatchableConfiguration]:
637+
def _make_var_watchable_from_factories(self, var_factories: Dict[str, sdk.VariableFactoryInterface]) -> Dict[str, sdk.BriefWatchableConfiguration]:
638638
"""Take the variable factories received from the server and generate all the var watchables from them.
639639
Might drop some of them to avoid bloating the registry with large buffers
640640
"""
641-
outdict: Dict[str, sdk.WatchableConfiguration] = {}
641+
outdict: Dict[str, sdk.BriefWatchableConfiguration] = {}
642642
var_factories_filt: List[sdk.VariableFactoryInterface] = []
643643
# Start by removing var factory that generate too many elements
644644
for access_path, factory in var_factories.items():
@@ -824,15 +824,15 @@ def ui_callback(expected_error: Optional[Exception], unexpected_error: Optional[
824824
raise NotImplementedError(f"Unsupported state: {registration_status.active_state}")
825825

826826
@enforce_thread(QT_THREAD_NAME)
827-
def _qt_registry_watch_callback(self, watcher_id: Union[str, int], server_path: str, watchable_config: sdk.WatchableConfiguration, registry_id: int) -> None:
827+
def _qt_registry_watch_callback(self, watcher_id: Union[str, int], server_path: str, watchable_config: sdk.BriefWatchableConfiguration, registry_id: int) -> None:
828828
"""Called when a gui component register a watcher on the registry"""
829829
# Runs from QT thread
830830
watcher_count = self._registry.node_watcher_count(watchable_config.watchable_type, server_path)
831831
if watcher_count is not None and watcher_count > 0:
832832
self._qt_maybe_request_watch(watchable_config.watchable_type, server_path)
833833

834834
@enforce_thread(QT_THREAD_NAME)
835-
def _qt_registry_unwatch_callback(self, watcher_id: Union[str, int], server_path: str, watchable_config: sdk.WatchableConfiguration, registry_id: int) -> None:
835+
def _qt_registry_unwatch_callback(self, watcher_id: Union[str, int], server_path: str, watchable_config: sdk.BriefWatchableConfiguration, registry_id: int) -> None:
836836
"""Called when a gui component unregister a watcher on the registry"""
837837
# Runs from QT thread
838838
watcher_count = self._registry.node_watcher_count(watchable_config.watchable_type, server_path)

scrutiny/gui/core/watchable_registry.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,20 +119,20 @@ class WatcherNotFoundError(Exception):
119119

120120

121121
WatcherValueUpdateCallback = Callable[[WatcherIdType, List[RegistryValueUpdate]], None]
122-
UnwatchCallback = Callable[[WatcherIdType, str, sdk.WatchableConfiguration, int], None]
123-
GlobalWatchCallback = Callable[[WatcherIdType, str, sdk.WatchableConfiguration, int], None]
124-
GlobalUnwatchCallback = Callable[[WatcherIdType, str, sdk.WatchableConfiguration, int], None]
122+
UnwatchCallback = Callable[[WatcherIdType, str, sdk.BriefWatchableConfiguration, int], None]
123+
GlobalWatchCallback = Callable[[WatcherIdType, str, sdk.BriefWatchableConfiguration, int], None]
124+
GlobalUnwatchCallback = Callable[[WatcherIdType, str, sdk.BriefWatchableConfiguration, int], None]
125125

126126

127127
@dataclass(init=False, slots=True)
128128
class WatchableRegistryEntryNode:
129129
"""Leaf node in the tree that is a single watchable"""
130-
configuration: sdk.WatchableConfiguration
130+
configuration: sdk.BriefWatchableConfiguration
131131
server_path: str
132132
registry_id: int
133133
_watcher_count: int
134134

135-
def __init__(self, registry: "WatchableRegistry", server_path: str, config: sdk.WatchableConfiguration) -> None:
135+
def __init__(self, registry: "WatchableRegistry", server_path: str, config: sdk.BriefWatchableConfiguration) -> None:
136136
self.server_path = server_path
137137
self.configuration = config
138138
self._watcher_count = 0
@@ -244,7 +244,7 @@ def _make_node_id(self) -> int:
244244
return v
245245

246246
@enforce_thread(QT_THREAD_NAME)
247-
def _add_watchable(self, path: str, config: sdk.WatchableConfiguration) -> None:
247+
def _add_watchable(self, path: str, config: sdk.BriefWatchableConfiguration) -> None:
248248
"""Adds a single watchable to the tree storage
249249
250250
:param path: Path to add the node to
@@ -654,7 +654,7 @@ def is_watchable_fqn(self, fqn: str) -> bool:
654654
return isinstance(node, WatchableRegistryEntryNode)
655655

656656
@enforce_thread(QT_THREAD_NAME)
657-
def write_content(self, data: Dict[sdk.WatchableType, Dict[str, sdk.WatchableConfiguration]]) -> None:
657+
def write_content(self, data: Dict[sdk.WatchableType, Dict[str, sdk.BriefWatchableConfiguration]]) -> None:
658658
"""Write content of the given types.
659659
Triggers ``changed``. May trigger ``filled`` if all types have data after calling this function.
660660

scrutiny/gui/gui.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,6 @@ def __init__(self,
8989
def run(self, args: List[str]) -> int:
9090
logger = logging.getLogger(self.__class__.__name__)
9191

92-
loc = QLocale.c() # Forces C-style environment. Decimal points are "."
93-
# Prevent showing/interpreting commas as group separator
94-
loc.setNumberOptions(QLocale.NumberOption.RejectGroupSeparator | QLocale.NumberOption.OmitGroupSeparator)
95-
QLocale.setDefault(loc)
96-
9792
if sys.platform == "win32":
9893
# Tells windows that python process host another application. Enables the QT icon in the task bar
9994
# see https://stackoverflow.com/questions/1551605/how-to-set-applications-taskbar-icon-in-windows-7

0 commit comments

Comments
 (0)