Skip to content

Storing state information on ongoing measurement #3

@wementoat

Description

@wementoat

The ICOstate / ICOsystem integration works well for replacing the old network-class and also reduces wrapping code when used in the ICOapi. Thanks for that!

The next big scope would be how this library could handle holding stateful information on an ongoing measurement. This is required as for ICOapi / ICOdaq reconnecting to an ongoing measurement is a requirement and multiple clients connecting to the same API instance and checking on measurements is certainly a valid use case.

Currently, the ICOapi provides the following MeasurementState:

class MeasurementState:
    """
    This class serves as state management for keeping track of ongoing measurements.
    It should never be instantiated outside the corresponding singleton wrapper.
    """

    def __init__(self):
        self.task: asyncio.Task | None = None
        self.clients: List[WebSocket] = []
        self.lock = asyncio.Lock()
        self.running = False
        self.name: str | None = None
        self.start_time: str | None = None
        self.tool_name: str | None = None
        self.instructions: MeasurementInstructions | None = None
        self.stop_flag = False
        self.wait_for_post_meta = False
        self.pre_meta: Metadata | None = None
        self.post_meta: Metadata | None = None

    def __setattr__(self, name: str, value):
        super().__setattr__(name, value)
        asyncio.create_task(get_messenger().push_messenger_update())

    async def reset(self):
        self.task = None
        self.clients = []
        self.lock = asyncio.Lock()
        self.running = False
        self.name = None
        self.start_time = None
        self.tool_name = None
        self.instructions = None
        self.stop_flag = False
        self.wait_for_post_meta = False
        self.pre_meta = None
        self.post_meta = None
        await get_messenger().push_messenger_update()

    def get_status(self):
        return MeasurementStatus(
            running=self.running,
            name=self.name,
            start_time=self.start_time,
            tool_name=self.tool_name,
            instructions=self.instructions
        )

Where the MeasurementStatus is what is actually being communicated to the client and the rest of the class is for the backend logic. It holds WebSocket connections, the asyncio task for cancellation, flags, the lock, etc.

Another big part are the instructions: What are the exact parameters for the measurement?

@dataclass
class MeasurementInstructions:
    name: str | None
    mac: str
    time: int | None
    first: MeasurementInstructionChannel
    second: MeasurementInstructionChannel
    third: MeasurementInstructionChannel
    ift_requested: bool
    ift_channel: str
    ift_window_width: int
    adc: ADCValues | None
    meta: Metadata | None
    wait_for_post_meta: bool = False
    disconnect_after_measurement: bool = False

What is already covered?

We already have information on the currently connected node.

Suggestions

Extend the library with some form of state information on an ongoing measurement. We could add a state like MEASURING or CAPTURING to work with the existing state machine. This would allow a client to just query the state and then request the right information. It would also make collaborative work easier as simple state fields could be implemented quickly.

Any comments are more than welcome.

Sub-issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions