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 5, 2023
1 parent 8a1dc3e commit 247f998
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 4 deletions.
50 changes: 47 additions & 3 deletions tcmenu/remote/protocol/tag_val_menu_command_processors.py
@@ -1,7 +1,7 @@
import io
import uuid

from tcmenu.domain.menu_items import AnalogMenuItem
from tcmenu.domain.menu_items import AnalogMenuItem, FloatMenuItem, RuntimeListMenuItem
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 @@ -249,15 +249,59 @@ def _process_text_boot_item(parser: TagValTextParser) -> MenuCommand:

@staticmethod
def _process_float_boot_item(parser: TagValTextParser) -> MenuCommand:
pass
item = 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 = parser.get_value_as_int(TagValMenuFields.KEY_PARENT_ID_FIELD.value)
current_val = 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(
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 = 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 Down
71 changes: 70 additions & 1 deletion test/remote/protocol/test_tag_val_menu_command_protocol.py
Expand Up @@ -3,7 +3,11 @@
from typing import Generic, TypeVar

from tcmenu.remote.commands.dialog_mode import DialogMode
from tcmenu.remote.commands.menu_boot_commands import MenuAnalogBootCommand
from tcmenu.remote.commands.menu_boot_commands import (
MenuAnalogBootCommand,
MenuFloatBootCommand,
MenuRuntimeListBootCommand,
)
from tcmenu.remote.commands.menu_bootstrap_command import MenuBootstrapCommand
from tcmenu.remote.commands.menu_button_type import MenuButtonType
from tcmenu.remote.commands.menu_command import MenuCommand
Expand Down Expand Up @@ -137,6 +141,71 @@ def test_receive_analog_item_no_step():
assert analog.menu_item.visible is True


def test_receive_analog_item_with_step():
command = protocol.from_channel(
to_buffer(
MenuCommandType.ANALOG_BOOT_ITEM.message_field,
"PI=321|ID=1|RO=1|VI=1|AM=255|AO=-180|AD=2|AU=dB|AS=2|NM=Volume|VC=22|\u0002",
)
)

assert type(command) is MenuAnalogBootCommand
analog: MenuAnalogBootCommand = command
assert -180 == analog.menu_item.offset
assert 255 == analog.menu_item.max_value
assert 2 == analog.menu_item.divisor
assert "dB" == analog.menu_item.unit_name
assert 1 == analog.menu_item.id
assert 2 == analog.menu_item.step
assert "Volume" == analog.menu_item.name
assert 321 == analog.sub_menu_id
assert analog.menu_item.read_only is True
assert analog.menu_item.visible is True


def test_receive_float_boot_command():
command = protocol.from_channel(
to_buffer(
MenuCommandType.FLOAT_BOOT_ITEM.message_field,
"PI=2|RO=1|VI=0|NM=menuName|ID=1|FD=5|VC=12.3456|\u0002",
)
)

assert type(command) is MenuFloatBootCommand
float_cmd: MenuFloatBootCommand = command

epsilon = 1e-5
assert abs(12.3456 - float_cmd.current_value) < epsilon

assert 5 == float_cmd.menu_item.num_decimal_places
assert "menuName" == float_cmd.menu_item.name
assert 1 == float_cmd.menu_item.id
assert 2 == float_cmd.sub_menu_id
assert float_cmd.menu_item.read_only is True
assert float_cmd.menu_item.visible is False


def test_receive_runtime_list_boot_command():
command = protocol.from_channel(
to_buffer(
MenuCommandType.RUNTIME_LIST_BOOT.message_field,
"PI=2|RO=1|VI=1|NM=runList|ID=1|NC=3|CA=abc|CB=def|CC=ghi|\u0002",
)
)

assert type(command) is MenuRuntimeListBootCommand
runtime_list_cmd: MenuRuntimeListBootCommand = command
assert "runList" == runtime_list_cmd.menu_item.name
assert 1 == runtime_list_cmd.menu_item.id
assert 2 == runtime_list_cmd.sub_menu_id
assert 3 == len(runtime_list_cmd.current_value)
assert "abc" == runtime_list_cmd.current_value[0]
assert "def" == runtime_list_cmd.current_value[1]
assert "ghi" == runtime_list_cmd.current_value[2]
assert runtime_list_cmd.menu_item.read_only is True
assert runtime_list_cmd.menu_item.visible is True


def to_buffer(message_type: MessageField, s: str) -> io.BytesIO:
buffer = io.BytesIO()
buffer.write(CommandProtocol.TAG_VAL_PROTOCOL.protocol_num)
Expand Down

0 comments on commit 247f998

Please sign in to comment.