Skip to content

Commit 686ac02

Browse files
committed
feat: device-status command (API stub)
- Added device-status command (checks IsOnline/IsConnected/State on all objects β€” currently returns empty as CODESYS scripting API v3.5.22.10 does not expose these properties on IScriptObject) - CLI: project device-status [--device <filter>]
1 parent 63d95f2 commit 686ac02

2 files changed

Lines changed: 60 additions & 1 deletion

File tree

β€Žcds_text_sync.pyβ€Ž

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,14 @@ def cmd_project_list_devices():
333333
_project_command("list_devices")
334334

335335

336+
def cmd_device_status(device=""):
337+
"""Check online/connection status of devices."""
338+
params = {}
339+
if device:
340+
params["device"] = device
341+
_project_command("device_status")
342+
343+
336344
def cmd_discover():
337345
"""Discover CODESYS installations and open projects via daemon."""
338346
_project_command("discover")
@@ -422,7 +430,8 @@ def build_parser() -> argparse.ArgumentParser:
422430
p_project.add_argument(
423431
"project_action",
424432
choices=["info", "tree", "read", "open", "close", "list",
425-
"snapshot", "build", "list-devices", "compare"],
433+
"snapshot", "build", "list-devices", "compare",
434+
"device-status"],
426435
help="info - project details\n"
427436
"tree - object tree\n"
428437
"read - read object source\n"
@@ -432,6 +441,7 @@ def build_parser() -> argparse.ArgumentParser:
432441
"snapshot - export full XML snapshot\n"
433442
"build - compile project\n"
434443
"list-devices - enumerate devices\n"
444+
"device-status - check device online/connection status\n"
435445
"compare --against FILE - diff live project vs snapshot",
436446
)
437447
p_project.add_argument("--path", default="",
@@ -442,6 +452,8 @@ def build_parser() -> argparse.ArgumentParser:
442452
help="Tree depth, 0 = unlimited")
443453
p_project.add_argument("--against", default="",
444454
help="Path to snapshot for compare")
455+
p_project.add_argument("--device", default="",
456+
help="Device name filter (for device-status)")
445457
p_exec = subparsers.add_parser(
446458
"exec",
447459
help="Execute command through daemon",
@@ -523,6 +535,8 @@ def main():
523535
cmd_project_list_devices()
524536
elif args.project_action == "compare":
525537
cmd_compare(against=args.against)
538+
elif args.project_action == "device-status":
539+
cmd_device_status(device=args.device)
526540

527541
elif args.command == "discover":
528542
cmd_discover()

β€Žsrc/ide_bridge/ide_daemon.pywβ€Ž

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ class DaemonPipeServer(object):
254254
return self._call_engine_cli_raw(args)
255255
elif method == "discover":
256256
return self._discover()
257+
elif method == "device_status":
258+
return self._device_status(params)
257259
else:
258260
return {"ok": False, "error": "Unknown method: {0}".format(method)}
259261

@@ -736,6 +738,49 @@ class DaemonPipeServer(object):
736738
except Exception as e:
737739
return {"ok": False, "error": "List devices error: {0}".format(e)}
738740

741+
# ── Device Status ────────────────────────────────────────────────
742+
743+
def _device_status(self, params):
744+
"""Check online/connection status of devices."""
745+
project, err = self._get_active_project()
746+
if err:
747+
return err
748+
try:
749+
device_filter = (params.get("device") or "").lower()
750+
all_objs = list(project.get_children(recursive=True))
751+
status_list = []
752+
# Properties to try for each object
753+
status_props = [
754+
'IsOnline', 'IsConnected', 'State', 'Online', 'Connected',
755+
'Status', 'IsActive', 'IsRunning', 'DeviceState',
756+
'get_IsOnline', 'get_IsConnected', 'get_State',
757+
]
758+
for obj in all_objs:
759+
try:
760+
name = self._obj_name(obj)
761+
if not name:
762+
continue
763+
path = self._build_path(obj)
764+
entry = {"name": name, "path": path}
765+
for prop in status_props:
766+
try:
767+
val = getattr(obj, prop)
768+
if val is not None:
769+
if callable(val):
770+
entry[prop] = str(val())
771+
else:
772+
entry[prop] = str(val)
773+
except Exception:
774+
pass
775+
if len(entry) > 2: # has at least one status prop
776+
if not device_filter or device_filter in name.lower():
777+
status_list.append(entry)
778+
except Exception:
779+
pass
780+
return {"ok": True, "data": {"devices": status_list}}
781+
except Exception as e:
782+
return {"ok": False, "error": "Device status error: {0}".format(e)}
783+
739784
# ── Discover ───────────────────────────────────────────────────────
740785

741786
def _discover(self):

0 commit comments

Comments
Β (0)