Skip to content

Commit

Permalink
Further extend parser
Browse files Browse the repository at this point in the history
  • Loading branch information
vzahradnik committed Sep 6, 2023
1 parent 8a1dc3e commit 1d50f61
Show file tree
Hide file tree
Showing 5 changed files with 318 additions and 15 deletions.
4 changes: 4 additions & 0 deletions tcmenu/domain/edit_item_type.py
Expand Up @@ -39,3 +39,7 @@ class EditItemType(Enum):
@property
def message_id(self):
return self._value_

@staticmethod
def from_id(item_id: int):
return EditItemType(item_id) if item_id in (item.value for item in EditItemType) else EditItemType.PLAIN_TEXT
2 changes: 1 addition & 1 deletion tcmenu/remote/commands/command_factory.py
Expand Up @@ -226,7 +226,7 @@ def new_menu_text_boot_command(

@staticmethod
def new_menu_large_item_boot_command(
parent_id: int, item: EditableLargeNumberMenuItem, current_value: int
parent_id: int, item: EditableLargeNumberMenuItem, current_value: float
) -> MenuLargeNumBootCommand:
"""
Create a new large number bootstrap command.
Expand Down
122 changes: 109 additions & 13 deletions tcmenu/remote/protocol/tag_val_menu_command_processors.py
@@ -1,7 +1,15 @@
import io
import uuid

from tcmenu.domain.menu_items import AnalogMenuItem
from tcmenu.domain.edit_item_type import EditItemType
from tcmenu.domain.menu_items import (
AnalogMenuItem,
FloatMenuItem,
RuntimeListMenuItem,
EditableTextMenuItem,
EnumMenuItem,
EditableLargeNumberMenuItem,
)
from tcmenu.remote.commands.command_factory import CommandFactory
from tcmenu.remote.commands.dialog_mode import DialogMode
from tcmenu.remote.commands.menu_acknowledgement_command import MenuAcknowledgementCommand
Expand Down Expand Up @@ -178,8 +186,8 @@ def add_handlers_to_protocol(proto: "ConfigurableProtocolConverter"):

@staticmethod
def _process_join(parser: TagValTextParser) -> MenuCommand:
uuid_str = parser.get_value(TagValMenuFields.KEY_UUID_FIELD.value, "")
uuid_val = uuid.UUID(uuid_str) if len(uuid_str) > 0 else uuid.uuid4()
uuid_str: str = parser.get_value(TagValMenuFields.KEY_UUID_FIELD.value, "")
uuid_val: uuid.UUID = uuid.UUID(uuid_str) if len(uuid_str) > 0 else uuid.uuid4()

return MenuJoinCommand(
my_name=parser.get_value(TagValMenuFields.KEY_NAME_FIELD.value),
Expand All @@ -205,7 +213,7 @@ def _process_bootstrap(parser: TagValTextParser) -> MenuCommand:

@staticmethod
def _process_analog_boot_item(parser: TagValTextParser) -> MenuCommand:
item = AnalogMenuItem(
item: AnalogMenuItem = AnalogMenuItem(
id=parser.get_value_as_int(TagValMenuFields.KEY_ID_FIELD.value),
divisor=parser.get_value_as_int(TagValMenuFields.KEY_ANALOG_DIVISOR_FIELD.value),
max_value=parser.get_value_as_int(TagValMenuFields.KEY_ANALOG_MAX_FIELD.value),
Expand All @@ -218,8 +226,8 @@ def _process_analog_boot_item(parser: TagValTextParser) -> MenuCommand:
visible=parser.get_value_as_int(TagValMenuFields.KEY_VISIBLE_FIELD.value, 1) != 0,
)

parent_id = parser.get_value_as_int(TagValMenuFields.KEY_PARENT_ID_FIELD.value)
current_val = parser.get_value_as_int(TagValMenuFields.KEY_CURRENT_VAL.value)
parent_id: int = parser.get_value_as_int(TagValMenuFields.KEY_PARENT_ID_FIELD.value)
current_val: int = parser.get_value_as_int(TagValMenuFields.KEY_CURRENT_VAL.value)

return CommandFactory.new_analog_boot_command(parent_id=parent_id, item=item, current_value=current_val)

Expand All @@ -229,35 +237,121 @@ def _process_sub_menu_boot_item(parser: TagValTextParser) -> MenuCommand:

@staticmethod
def _process_enum_boot_item(parser: TagValTextParser) -> MenuCommand:
pass
choices: tuple[str, ...] = TagValMenuCommandProcessors._choices_from_msg(parser)
item: EnumMenuItem = EnumMenuItem(
id=parser.get_value_as_int(TagValMenuFields.KEY_ID_FIELD.value),
eeprom_address=parser.get_value_as_int(TagValMenuFields.KEY_EEPROM_FIELD.value, 0),
name=parser.get_value(TagValMenuFields.KEY_NAME_FIELD.value),
read_only=parser.get_value_as_int(TagValMenuFields.KEY_READONLY_FIELD.value) != 0,
visible=parser.get_value_as_int(TagValMenuFields.KEY_VISIBLE_FIELD.value, 1) != 0,
enum_entries=choices,
)

parent_id: int = parser.get_value_as_int(TagValMenuFields.KEY_PARENT_ID_FIELD.value)
current_val: int = parser.get_value_as_int(TagValMenuFields.KEY_CURRENT_VAL.value)

return CommandFactory.new_menu_enum_boot_command(parent_id=parent_id, item=item, current_value=current_val)

@staticmethod
def _process_boolean_boot_item(parser: TagValTextParser) -> MenuCommand:
pass

@staticmethod
def _process_large_num_boot_item(parser: TagValTextParser) -> MenuCommand:
pass
item: EditableLargeNumberMenuItem = EditableLargeNumberMenuItem(
id=parser.get_value_as_int(TagValMenuFields.KEY_ID_FIELD.value),
eeprom_address=parser.get_value_as_int(TagValMenuFields.KEY_EEPROM_FIELD.value, 0),
name=parser.get_value(TagValMenuFields.KEY_NAME_FIELD.value),
read_only=parser.get_value_as_int(TagValMenuFields.KEY_READONLY_FIELD.value) != 0,
visible=parser.get_value_as_int(TagValMenuFields.KEY_VISIBLE_FIELD.value, 1) != 0,
decimal_places=parser.get_value_as_int(TagValMenuFields.KEY_FLOAT_DECIMAL_PLACES.value),
negative_allowed=parser.get_value_as_int(TagValMenuFields.KEY_NEGATIVE_ALLOWED.value, 1) != 0,
digits_allowed=parser.get_value_as_int(TagValMenuFields.KEY_MAX_LENGTH.value),
)

parent_id: int = parser.get_value_as_int(TagValMenuFields.KEY_PARENT_ID_FIELD.value)
current_val: str = parser.get_value(TagValMenuFields.KEY_CURRENT_VAL.value).replace("[", "").replace("]", "")

return CommandFactory.new_menu_large_item_boot_command(
parent_id=parent_id, item=item, current_value=float(current_val)
)

@staticmethod
def _process_item_change(parser: TagValTextParser) -> MenuCommand:
pass

@staticmethod
def _process_text_boot_item(parser: TagValTextParser) -> MenuCommand:
pass
item: EditableTextMenuItem = EditableTextMenuItem(
id=parser.get_value_as_int(TagValMenuFields.KEY_ID_FIELD.value),
eeprom_address=parser.get_value_as_int(TagValMenuFields.KEY_EEPROM_FIELD.value, 0),
name=parser.get_value(TagValMenuFields.KEY_NAME_FIELD.value),
read_only=parser.get_value_as_int(TagValMenuFields.KEY_READONLY_FIELD.value) != 0,
visible=parser.get_value_as_int(TagValMenuFields.KEY_VISIBLE_FIELD.value, 1) != 0,
item_type=EditItemType.from_id(parser.get_value_as_int(TagValMenuFields.KEY_EDIT_TYPE.value)),
text_length=parser.get_value_as_int(TagValMenuFields.KEY_MAX_LENGTH.value),
)

parent_id: int = parser.get_value_as_int(TagValMenuFields.KEY_PARENT_ID_FIELD.value)
current_val: str = parser.get_value(TagValMenuFields.KEY_CURRENT_VAL.value)

return CommandFactory.new_menu_text_boot_command(parent_id=parent_id, item=item, current_value=current_val)

@staticmethod
def _process_float_boot_item(parser: TagValTextParser) -> MenuCommand:
pass
item: FloatMenuItem = FloatMenuItem(
id=parser.get_value_as_int(TagValMenuFields.KEY_ID_FIELD.value),
eeprom_address=parser.get_value_as_int(TagValMenuFields.KEY_EEPROM_FIELD.value, 0),
name=parser.get_value(TagValMenuFields.KEY_NAME_FIELD.value),
read_only=parser.get_value_as_int(TagValMenuFields.KEY_READONLY_FIELD.value) != 0,
visible=parser.get_value_as_int(TagValMenuFields.KEY_VISIBLE_FIELD.value, 1) != 0,
num_decimal_places=parser.get_value_as_int(TagValMenuFields.KEY_FLOAT_DECIMAL_PLACES.value),
)

parent_id: int = parser.get_value_as_int(TagValMenuFields.KEY_PARENT_ID_FIELD.value)
current_val: str = parser.get_value(TagValMenuFields.KEY_CURRENT_VAL.value)

return CommandFactory.new_menu_float_boot_command(
parent_id=parent_id, item=item, current_value=float(current_val)
)

@staticmethod
def _process_action_boot_item(parser: TagValTextParser) -> MenuCommand:
pass

@staticmethod
def _process_runtime_list_boot_item(parser: TagValTextParser) -> MenuCommand:
pass
item: RuntimeListMenuItem = RuntimeListMenuItem(
id=parser.get_value_as_int(TagValMenuFields.KEY_ID_FIELD.value),
eeprom_address=parser.get_value_as_int(TagValMenuFields.KEY_EEPROM_FIELD.value, 0),
name=parser.get_value(TagValMenuFields.KEY_NAME_FIELD.value),
read_only=parser.get_value_as_int(TagValMenuFields.KEY_READONLY_FIELD.value) != 0,
visible=parser.get_value_as_int(TagValMenuFields.KEY_VISIBLE_FIELD.value, 1) != 0,
initial_rows=parser.get_value_as_int(TagValMenuFields.KEY_NO_OF_CHOICES.value),
)

parent_id: int = parser.get_value_as_int(TagValMenuFields.KEY_PARENT_ID_FIELD.value)
choices: tuple[str, ...] = TagValMenuCommandProcessors._choices_from_msg(parser)

return CommandFactory.new_runtime_list_boot_command(parent_id=parent_id, item=item, current_value=choices)

@staticmethod
def _choices_from_msg(parser: TagValTextParser) -> tuple[str, ...]:
choices: list[str] = []
no_of_items: int = parser.get_value_as_int(TagValMenuFields.KEY_NO_OF_CHOICES.value)

for i in range(0, no_of_items):
key_name: str = TagValMenuFields.KEY_PREPEND_NAMECHOICE.value + chr(i + ord("A"))
key_val: str = TagValMenuFields.KEY_PREPEND_CHOICE.value + chr(i + ord("A"))
key_text: str = parser.get_value(key_name, "")
val_text: str = parser.get_value(key_val, "")

if len(key_text) == 0:
choices.append(val_text)
else:
choices.append(f"{key_text}\t{val_text}")

return tuple(choices)

@staticmethod
def _process_runtime_rgb_color_item(parser: TagValTextParser) -> MenuCommand:
Expand All @@ -277,8 +371,10 @@ def _process_pairing_request(parser: TagValTextParser) -> MenuCommand:

@staticmethod
def _process_dialog_update(parser: TagValTextParser) -> MenuCommand:
cor = parser.get_value(TagValMenuFields.KEY_CORRELATION_FIELD.value, "")
correlation_id = CorrelationId.EMPTY_CORRELATION if len(cor) == 0 else CorrelationId.from_string(cor)
cor: str = parser.get_value(TagValMenuFields.KEY_CORRELATION_FIELD.value, "")
correlation_id: CorrelationId = (
CorrelationId.EMPTY_CORRELATION if len(cor) == 0 else CorrelationId.from_string(cor)
)

return CommandFactory.new_dialog_command(
mode=DialogMode.from_string(parser.get_value(TagValMenuFields.KEY_MODE_FIELD.value)),
Expand Down
29 changes: 29 additions & 0 deletions test/domain/test_edit_item_type.py
@@ -0,0 +1,29 @@
from tcmenu.domain.edit_item_type import EditItemType


def test_enum_values():
assert EditItemType.PLAIN_TEXT.value == 0
assert EditItemType.IP_ADDRESS.value == 1
assert EditItemType.TIME_24H.value == 2
assert EditItemType.TIME_12H.value == 3
assert EditItemType.TIME_24_HUNDREDS.value == 4
assert EditItemType.GREGORIAN_DATE.value == 5
assert EditItemType.TIME_DURATION_SECONDS.value == 6
assert EditItemType.TIME_DURATION_HUNDREDS.value == 7
assert EditItemType.TIME_24H_HHMM.value == 8
assert EditItemType.TIME_12H_HHMM.value == 9


def test_edit_type_from_id():
assert EditItemType.PLAIN_TEXT == EditItemType.from_id(0)
assert EditItemType.IP_ADDRESS == EditItemType.from_id(1)
assert EditItemType.TIME_24H == EditItemType.from_id(2)
assert EditItemType.TIME_12H == EditItemType.from_id(3)
assert EditItemType.TIME_24_HUNDREDS == EditItemType.from_id(4)
assert EditItemType.GREGORIAN_DATE == EditItemType.from_id(5)
assert EditItemType.TIME_DURATION_SECONDS == EditItemType.from_id(6)
assert EditItemType.TIME_DURATION_HUNDREDS == EditItemType.from_id(7)
assert EditItemType.TIME_24H_HHMM == EditItemType.from_id(8)
assert EditItemType.TIME_12H_HHMM == EditItemType.from_id(9)
assert EditItemType.PLAIN_TEXT == EditItemType.from_id(10)
assert EditItemType.PLAIN_TEXT == EditItemType.from_id(100)

0 comments on commit 1d50f61

Please sign in to comment.