Skip to content
5 changes: 3 additions & 2 deletions src/controller/cli/help_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,9 @@ def execute(self, args: Namespace) -> bool:
self.context.print("\tload <show file> -- Load the provided show file and make it the current one")
self.context.print("\tfiltermsg <scene id> <filter id> <key> <value> -- Update the parameter <key> of "
"\n\t\tfilter <filter id> from scene <scene id> to value <value>.")
self.context.print("select-scene <scene id> -- switch to scene with ID <scene id>")
self.context.print("commit [--select-default-scene] -- apply the current loaded show file to fish")
self.context.print("\tselect-scene <scene id> -- switch to scene with ID <scene id>")
self.context.print("\tcommit [--select-default-scene] -- apply the current loaded show file to fish")
self.content.print("\treadymode <enable|abort|commit|query> -- Control the ready mode state.")
case "delay":
self.context.print("delay the execution of the macro by the specified amount of milliseconds")
case "fish":
Expand Down
20 changes: 20 additions & 0 deletions src/controller/cli/show_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

from typing import TYPE_CHECKING
from unittest import case

from controller.cli.command import Command
from controller.file.read import read_document
Expand Down Expand Up @@ -62,6 +63,11 @@ def configure_parser(self, parser: argparse.ArgumentParser) -> None:
filtercmd_parser.add_argument("parameterkey", help="The key of the parameter to update")
filtercmd_parser.add_argument("parametervalue", help="The value to transmit")

readymode_parser: ArgumentParser = subparsers.add_parser("readymode", help="Ready mode controls",
exit_on_error=False)
readymode_parser.add_argument("action", type=str, help="The action to perform",
choices=["enable", "abort", "commit", "query"])

def execute(self, args: Namespace) -> bool:
"""Execute the showctl command based on parsed arguments.

Expand Down Expand Up @@ -89,4 +95,18 @@ def execute(self, args: Namespace) -> bool:
args.sceneid, args.filterid, args.parameterkey, args.parametervalue, enque=True
)
return True
case "readymode":
match args.action:
case "enable":
self.context.network_manager.enter_readymode(send_immediately=False)
return True
case "abort":
self.context.network_manager.abort_readymode(send_immediately=False)
return True
case "commit":
self.context.network_manager.commit_readymode(send_immediately=False)
return True
case "query":
self.context.print(str(self.context.network_manager.in_readymode))
return True
return False
69 changes: 64 additions & 5 deletions src/controller/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import numpy as np
from PySide6 import QtCore, QtNetwork
from PySide6.QtCore import QTimer

import proto.Console_pb2
import proto.DirectMode_pb2
Expand Down Expand Up @@ -83,12 +84,57 @@ def __init__(self) -> None:
self._broadcaster.change_active_scene.connect(self.enter_scene)

x_touch.XTouchMessages(self._broadcaster, self.button_msg_to_x_touch)
self._gui_update_ready_queue: list[proto.FilterMode_pb2.update_parameter] = []
self._in_ready_wait_mode: bool = False

@property
def is_running(self) -> bool:
"""Check if the Fish socket is already running."""
return self._is_running

def enter_readymode(self, send_immediately: bool = True) -> None:
"""Enter the readymode."""
if self._in_ready_wait_mode:
return
self._in_ready_wait_mode = True
self._broadcaster.switched_gui_wait_mode.emit(True)
msg = proto.RealTimeControl_pb2.readymode_update()
msg.cause = proto.RealTimeControl_pb2.ReadymodeUpdateCause.RUC_ENTERED
self._enqueue_message(msg.SerializeToString(), proto.MessageTypes_pb2.MSGT_READYMODE_UPDATE)
if send_immediately:
self.push_messages()

@property
def in_readymode(self) -> bool:
"""Returns true if the ready mode is in progress."""
return self._in_ready_wait_mode

def abort_readymode(self, send_immediately: bool = True) -> None:
"""Abort the ready mode."""
if self._in_ready_wait_mode:
self._in_ready_wait_mode = False
self._broadcaster.switched_gui_wait_mode.emit(False)
self._gui_update_ready_queue.clear()
msg = proto.RealTimeControl_pb2.readymode_update()
msg.cause = proto.RealTimeControl_pb2.ReadymodeUpdateCause.RUC_ABORTED
self._enqueue_message(msg.SerializeToString(), proto.MessageTypes_pb2.MSGT_READYMODE_UPDATE)
if send_immediately:
self.push_messages()

def commit_readymode(self, send_immediately: bool = True) -> None:
"""Commit the ready mode."""
if self._in_ready_wait_mode:
self._in_ready_wait_mode = False
self._broadcaster.switched_gui_wait_mode.emit(False)
for msg in self._gui_update_ready_queue:
self._send_with_format(msg.SerializeToString(), proto.MessageTypes_pb2.MSGT_UPDATE_PARAMETER)
self._gui_update_ready_queue.clear()
msg = proto.RealTimeControl_pb2.readymode_update()
msg.cause = proto.RealTimeControl_pb2.ReadymodeUpdateCause.RUC_COMMITED
self._enqueue_message(msg.SerializeToString(), proto.MessageTypes_pb2.MSGT_READYMODE_UPDATE)
if send_immediately:
self.push_messages()

def change_server_name(self, name: str) -> None:
"""Change Fish socket name.

Expand Down Expand Up @@ -243,10 +289,20 @@ def _on_ready_read(self) -> None:
message: proto.Events_pb2.event_sender = proto.Events_pb2.event()
message.ParseFromString(bytes(msg))
self._broadcaster.fish_event_received.emit(message)
case proto.MessageTypes_pb2.MSGT_READYMODE_UPDATE:
msg_p: proto.RealTimeControl_pb2.readymode_update = proto.RealTimeControl_pb2.readymode_update()
msg_p.ParseFromString(bytes(msg))
match msg_p.cause:
case proto.RealTimeControl_pb2.RUC_COMMITED:
self.commit_readymode(False)
case proto.RealTimeControl_pb2.RUC_ABORTED:
self.abort_readymode(False)
case proto.RealTimeControl_pb2.RUC_ENTERED:
self.enter_readymode(False)
case _:
logger.warning("Received not implemented message type: %s", msg_type)
except:
logger.error("Failed to parse message.")
except Exception as e:
logger.exception("Failed to parse message.", exc_info=e, stack_info=True)
self.push_messages()

def _fish_update(self, msg: proto.RealTimeControl_pb2.current_state_update) -> None:
Expand Down Expand Up @@ -491,10 +547,13 @@ def send_gui_update_to_fish(self, scene_id: int, filter_id: str, key: str, value
msg.scene_id = scene_id
msg.parameter_key = key
msg.parameter_value = value
if enque:
self._enqueue_message(msg.SerializeToString(), proto.MessageTypes_pb2.MSGT_UPDATE_PARAMETER)
if self._in_ready_wait_mode:
self._gui_update_ready_queue.append(msg)
else:
self._send_with_format(msg.SerializeToString(), proto.MessageTypes_pb2.MSGT_UPDATE_PARAMETER)
if enque:
self._enqueue_message(msg.SerializeToString(), proto.MessageTypes_pb2.MSGT_UPDATE_PARAMETER)
else:
self._send_with_format(msg.SerializeToString(), proto.MessageTypes_pb2.MSGT_UPDATE_PARAMETER)

def send_event_sender_update(self, msg: proto.Events_pb2.event_sender, push_direct: bool = False) -> None:
"""Send event that Sender has updated to Fish."""
Expand Down
2 changes: 2 additions & 0 deletions src/model/broadcaster.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ class Broadcaster(QtCore.QObject, metaclass=QObjectSingletonMeta):
#################################################################
update_filter_parameter: QtCore.Signal = QtCore.Signal(proto.FilterMode_pb2.update_parameter)
active_scene_switched: QtCore.Signal = QtCore.Signal(int)
switched_gui_wait_mode: QtCore.Signal = QtCore.Signal(bool)
"""Signal is supplied with true if the state is now in wait mode."""
#################################################################
select_column_id: QtCore.Signal = QtCore.Signal(str)
log_message: QtCore.Signal = QtCore.Signal(str)
Expand Down
Loading