Skip to content
This repository has been archived by the owner on Apr 1, 2024. It is now read-only.

Commit

Permalink
Merge pull request #55 from oresat/eds_changes
Browse files Browse the repository at this point in the history
Eds changes
  • Loading branch information
dmitri-mcguckin authored Apr 2, 2021
2 parents dca4280 + 58e41f7 commit d7b5f3d
Show file tree
Hide file tree
Showing 8 changed files with 3,165 additions and 41 deletions.
2 changes: 1 addition & 1 deletion canopen_monitor/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def main():

# Start the can bus and the curses app
with MagicCANBus(args.interfaces, no_block=args.no_block) as bus, \
App(mt) as app:
App(mt, eds_configs) as app:
while True:
# Bus updates
for message in bus:
Expand Down
68 changes: 53 additions & 15 deletions canopen_monitor/app.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from __future__ import annotations
import curses
import datetime as dt
from easygui import fileopenbox
from shutil import copy
from enum import Enum
from . import APP_NAME, APP_VERSION, APP_LICENSE, APP_AUTHOR, APP_DESCRIPTION, \
APP_URL
APP_URL, CACHE_DIR
from .can import MessageTable, MessageType
from .ui import MessagePane, PopupWindow
from .parse import eds

# Key Constants not defined in curses
# _UBUNTU key constants work in Ubuntu
Expand Down Expand Up @@ -45,17 +48,33 @@ class KeyMap(Enum):
value[2]: curses input value key
"""

F1 = {'name':'F1','description':'Toggle app info menu','key' : curses.KEY_F1}
F2 = {'name':'F2', 'description':'Toggle this menu', 'key': curses.KEY_F2}
UP_ARR = {'name':'Up Arrow', 'description':'Scroll pane up 1 row', 'key':curses.KEY_UP}
DOWN_ARR = {'name':'Down Arrow', 'description':'Scroll pane down 1 row', 'key':curses.KEY_DOWN}
LEFT_ARR = {'name':'Left Arrow', 'description':'Scroll pane left 4 cols', 'key':curses.KEY_LEFT}
RIGHT_ARR = {'name':'Right Arrow', 'description':'Scroll pane right 4 cols', 'key':curses.KEY_RIGHT}
S_UP_ARR = {'name':'Shift + Up Arrow', 'description':'Scroll pane up 16 rows', 'key':KEY_S_UP}
S_DOWN_ARR ={'name':'Shift + Down Arrow', 'description':'Scroll pane down 16 rows', 'key':KEY_S_DOWN}
C_UP_ARR ={'name':'Ctrl + Up Arrow', 'description':'Move pane selection up', 'key':[KEY_C_UP, KEY_C_UP_UBUNTU]}
C_DOWN_ARR ={'name':'Ctrl + Down Arrow', 'description':'Move pane selection down', 'key':[KEY_C_DOWN, KEY_C_DOWN_UBUNTU]}
RESIZE ={'name':'Resize Terminal', 'description':'Reset the dimensions of the app', 'key':curses.KEY_RESIZE}
F1 = {'name': 'F1', 'description': 'Toggle app info menu',
'key': curses.KEY_F1}
F2 = {'name': 'F2', 'description': 'Toggle this menu', 'key': curses.KEY_F2}
F3 = {'name': 'F3', 'description': 'Toggle eds file select',
'key': curses.KEY_F3}
UP_ARR = {'name': 'Up Arrow', 'description': 'Scroll pane up 1 row',
'key': curses.KEY_UP}
DOWN_ARR = {'name': 'Down Arrow', 'description': 'Scroll pane down 1 row',
'key': curses.KEY_DOWN}
LEFT_ARR = {'name': 'Left Arrow', 'description': 'Scroll pane left 4 cols',
'key': curses.KEY_LEFT}
RIGHT_ARR = {'name': 'Right Arrow',
'description': 'Scroll pane right 4 cols',
'key': curses.KEY_RIGHT}
S_UP_ARR = {'name': 'Shift + Up Arrow',
'description': 'Scroll pane up 16 rows', 'key': KEY_S_UP}
S_DOWN_ARR = {'name': 'Shift + Down Arrow',
'description': 'Scroll pane down 16 rows', 'key': KEY_S_DOWN}
C_UP_ARR = {'name': 'Ctrl + Up Arrow',
'description': 'Move pane selection up',
'key': [KEY_C_UP, KEY_C_UP_UBUNTU]}
C_DOWN_ARR = {'name': 'Ctrl + Down Arrow',
'description': 'Move pane selection down',
'key': [KEY_C_DOWN, KEY_C_DOWN_UBUNTU]}
RESIZE = {'name': 'Resize Terminal',
'description': 'Reset the dimensions of the app',
'key': curses.KEY_RESIZE}


class App:
Expand All @@ -71,13 +90,14 @@ class App:
:type selected_pane: MessagePane
"""

def __init__(self: App, message_table: MessageTable):
def __init__(self: App, message_table: MessageTable, eds_configs: dict):
"""
App Initialization function
:param message_table: Reference to shared message table object
:type MessageTable
"""
self.table = message_table
self.eds_configs = eds_configs
self.selected_pane_pos = 0
self.selected_pane = None
self.key_dict = {
Expand All @@ -93,7 +113,8 @@ def __init__(self: App, message_table: MessageTable):
KeyMap.RIGHT_ARR.value['key']: self.right,
KeyMap.RESIZE.value['key']: self.resize,
KeyMap.F1.value['key']: self.f1,
KeyMap.F2.value['key']: self.f2
KeyMap.F2.value['key']: self.f2,
KeyMap.F3.value['key']: self.f3
}

def __enter__(self: App) -> App:
Expand Down Expand Up @@ -269,6 +290,23 @@ def f2(self):
self.info_win.clear()
self.hotkeys_win.toggle()

def f3(self):
"""
Toggles Add File window
:return: None
"""
filepath = fileopenbox(title='Select Object Dictionary Files',
filetypes=[['*.dcf', '*.eds', '*.xdd',
'Object Dictionary Files']],
multiple=False,
default='~/.cache/canopen-monitor/')

if (filepath is not None):
file = eds.load_eds_file(filepath)
copy(filepath, CACHE_DIR)
self.eds_configs[file.node_id] = file


def _handle_keyboard_input(self: App) -> None:
"""
Retrieves keyboard input and calls the associated key function
Expand Down Expand Up @@ -334,7 +372,7 @@ def __draw__footer(self: App) -> None:
:return: None
"""
height, width = self.screen.getmaxyx()
footer = '<F1>: Info, <F2>: Hotkeys'
footer = '<F1>: Info, <F2>: Hotkeys, <F3>: Add OD File'
self.screen.addstr(height - 1, 1, footer)

def draw(self: App, ifaces: [tuple]) -> None:
Expand Down
54 changes: 33 additions & 21 deletions canopen_monitor/parse/eds.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from __future__ import annotations
import string
from re import finditer
from typing import Union
Expand All @@ -16,26 +17,25 @@ def camel_to_snake(old_str: str) -> str:
:return: the camel-cased string
:rtype: str
"""
# Find all groups that contains one or more capital letters followed by one
# or more lowercase letters. The new, camel_cased string will be built
# up along the way.
# Find all groups that contains one or more capital letters followed by
# one or more lowercase letters The new, camel_cased string will be built
# up along the way
new_str = ""
for match in finditer('[A-Z0-9]+[a-z]*', old_str):
span = match.span()
substr = old_str[span[0]:span[1]]
found_submatch = False

# Add a "_" to the newstring to separate the current match group from
# the previous
# It looks like we shouldn't need to worry about getting
# "_strings_like_this", because they don't seem to happen
# the previous It looks like we shouldn't need to worry about getting
# "_strings_like_this", because they don't seem to happen
if (span[0] != 0):
new_str += '_'

# Find all sub-groups of *more than one* capital letters within the
# match group, and seperate them with "_" characters,
# Append the subgroups to the new_str as they are found
# If no subgroups are found, just append the match group to the new_str
# match group, and separate them with "_" characters, Append the
# subgroups to the new_str as they are found If no subgroups are
# found, just append the match group to the new_str
for sub_match in finditer('[A-Z]+', substr):
sub_span = sub_match.span()
sub_substr = old_str[sub_span[0]:sub_span[1]]
Expand All @@ -60,7 +60,7 @@ def __init__(self, data):
# Process all sub-data
for e in data:
# Skip comment lines
if(e[0] == ';'):
if (e[0] == ';'):
continue

# Separate field name from field value
Expand Down Expand Up @@ -98,18 +98,13 @@ def __init__(self, data, sub_id=None):
# Process all sub-data
for e in data:
# Skip commented lines
if(e[0] == ';'):
if (e[0] == ';'):
continue

# Separate field name from field value
key, value = e.split('=')

# Turn number-like objects into numbers
if(value != ''):
if (all(c in string.digits for c in value)):
value = int(value, 10)
elif(all(c in string.hexdigits for c in value)):
value = int(value, 16)
value = convert_value(value)

self.__setattr__(camel_to_snake(key), value)

Expand All @@ -120,12 +115,23 @@ def __getitem__(self, key: int):
return list(filter(lambda x: x.sub_id == key, self.sub_indices))[0]

def __len__(self) -> int:
if(self.sub_indices is None):
if (self.sub_indices is None):
return 1
else:
return 1 + sum(map(lambda x: len(x), self.sub_indices))


def convert_value(value: str) -> Union[int, str]:
# Turn number-like objects into numbers
if (value != ''):
if (all(c in string.digits for c in value)):
return int(value, 10)
elif (all(c in string.hexdigits for c in value)):
return int(value, 16)
else:
return value


class EDS:
def __init__(self, eds_data: [str]):
"""Parse the array of EDS lines into a dictionary of Metadata/Index
Expand Down Expand Up @@ -153,7 +159,13 @@ def __init__(self, eds_data: [str]):
self.__setattr__(camel_to_snake(name),
Metadata(section[1:]))
prev = i + 1
self.node_id = self[0x2101].default_value

if hasattr(self, 'device_commissioning'):
self.node_id = convert_value(self.device_commissioning.node_id)
elif '0x2101' in self.indices.keys():
self.node_id = self['0x2101'].default_value
else:
self.node_id = None

def __len__(self) -> int:
return sum(map(lambda x: len(x), self.indices.values()))
Expand All @@ -165,13 +177,13 @@ def __getitem__(self, key: Union[int, str]) -> Index:

def load_eds_file(filepath: str) -> EDS:
"""Read in the EDS file, grab the raw lines, strip them of all escaped
characters, then serialize into an `EDS` and return the resulpythting
characters, then serialize into an `EDS` and return the resulting
object.
:param filepath: Path to an eds file
:type filepath: str
:return: The succesfully serialized EDS file.
:return: The successfully serialized EDS file.
:rtype: EDS
"""
with open(filepath) as file:
Expand Down
1 change: 0 additions & 1 deletion canopen_monitor/ui/pane.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ def clear(self: Pane) -> None:
"""
self._pad.clear()
self.parent.clear()
# self.refresh()

def clear_line(self: Pane, y: int, style: any = None) -> None:
"""
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
install_requires=[
"pyvit >= 0.2.1",
"psutil >= 5.8.0",
"python-dateutil >= 2.8.1"
"python-dateutil >= 2.8.1",
"easygui >= 0.98.2",
],
extras_require={
"dev": [
Expand Down
Loading

0 comments on commit d7b5f3d

Please sign in to comment.