diff --git a/python/lvmecp/actor/actor.py b/python/lvmecp/actor/actor.py index fa327c0..10047ff 100644 --- a/python/lvmecp/actor/actor.py +++ b/python/lvmecp/actor/actor.py @@ -31,9 +31,6 @@ class ECPActor(LVMActor): """Enclosure actor.""" - _engineering_mode_hearbeat_interval: float = 5 - _engineering_mode_timeout: float = 30 - parser = parser def __init__( @@ -69,6 +66,9 @@ def __init__( self._monitor_dome_task: asyncio.Task | None = None self._engineering_mode: bool = False + self._engineering_mode_hearbeat_interval: float = 5 + self._engineering_mode_started_at: float | None = None + self._engineering_mode_duration: float | None = None self._engineering_mode_task: asyncio.Task | None = None self._last_heartbeat: float | None = None @@ -162,14 +162,19 @@ async def _run_eng_mode(self, timeout: float | None = None): """ - started_at: float = time.time() - if timeout is not None: - self._engineering_mode_timeout = timeout + eng_mode_config = self.config.get("engineering_mode", {}) + default_duration = eng_mode_config.get("default_duration", 300) + + self._engineering_mode_started_at = time.time() + self._engineering_mode_duration = timeout or default_duration + assert self._engineering_mode_duration is not None while True: await self.emit_heartbeat() - if time.time() - started_at > self._engineering_mode_timeout: + elapsed = time.time() - self._engineering_mode_started_at + + if elapsed > self._engineering_mode_duration: self.write("w", text="Engineering mode timed out and was disabled.") await self.engineering_mode(False) return diff --git a/python/lvmecp/actor/commands/engineering.py b/python/lvmecp/actor/commands/engineering.py index f415b5e..200f485 100644 --- a/python/lvmecp/actor/commands/engineering.py +++ b/python/lvmecp/actor/commands/engineering.py @@ -58,9 +58,18 @@ async def status(command: ECPCommand): """Returns the status of the engineering mode.""" enabled = command.actor.is_engineering_mode_enabled() - timeout = command.actor._engineering_mode_timeout + started_at = command.actor._engineering_mode_started_at + duration = command.actor._engineering_mode_duration + + if duration is None or started_at is None: + ends_at = None + else: + ends_at = started_at + duration return command.finish( - engineering_mode_enabled=enabled, - engineering_mode_timeout=timestamp_to_iso(timeout), + engineering_mode={ + "enabled": enabled, + "started_at": timestamp_to_iso(started_at), + "ends_at": timestamp_to_iso(ends_at), + } ) diff --git a/python/lvmecp/etc/lvmecp.yml b/python/lvmecp/etc/lvmecp.yml index 580ebe0..aa1d34f 100644 --- a/python/lvmecp/etc/lvmecp.yml +++ b/python/lvmecp/etc/lvmecp.yml @@ -317,6 +317,9 @@ hvac: address: 12 mode: coil +engineering_mode: + default_duration: 300 + actor: name: lvmecp host: localhost diff --git a/python/lvmecp/etc/schema.json b/python/lvmecp/etc/schema.json index b9b1961..f9cc03d 100644 --- a/python/lvmecp/etc/schema.json +++ b/python/lvmecp/etc/schema.json @@ -26,9 +26,18 @@ "last_heartbeat_set": { "oneOf": [{ "type": "number" }, { "type": "null" }] }, - "engineering_mode_enabled": { "type": "boolean" }, - "engineering_mode_timeout": { - "oneOf": [{ "type": "string" }, { "type": "null" }] + "engineering_mode": { + "type": "object", + "properties": { + "enabled": { "type": "boolean" }, + "started_at": { + "oneOf": [{ "type": "string" }, { "type": "null" }] + }, + "ends_at": { + "oneOf": [{ "type": "string" }, { "type": "null" }] + } + }, + "required": ["enabled", "started_at", "ends_at"] } }, "additionalProperties": true diff --git a/tests/test_command_engineering_mode.py b/tests/test_command_engineering_mode.py index befb7a5..eb71539 100644 --- a/tests/test_command_engineering_mode.py +++ b/tests/test_command_engineering_mode.py @@ -24,7 +24,7 @@ async def test_command_engineering_mode_status(actor: ECPActor): await cmd assert cmd.status.did_succeed - assert cmd.replies.get("engineering_mode_enabled") is False + assert cmd.replies.get("engineering_mode")["enabled"] is False async def test_command_engineering_mode_enable(actor: ECPActor, mocker: MockerFixture):