opengearwire 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,29 @@
1
+ # SPDX-License-Identifier: MIT
2
+ """opengearwire: read openGear frames (Ross OGX and partners) over OGP.
3
+
4
+ Read-only for now. ``Frame`` connects and reads; ``Tree`` holds what was
5
+ read; ``snapshot`` turns it into plain data. ``docs/PROTOCOL.md`` is the
6
+ wire format.
7
+ """
8
+
9
+ __version__ = "0.3.0"
10
+
11
+ from ._protocol import ProtocolError, RemoteError
12
+ from .client import Frame, FrameBusy, FrameError
13
+ from .model import Change, Device, Parameter, Tree, address_of, slot_of
14
+ from .snapshot import snapshot
15
+
16
+ __all__ = [
17
+ "Change",
18
+ "Device",
19
+ "Frame",
20
+ "FrameBusy",
21
+ "FrameError",
22
+ "Parameter",
23
+ "ProtocolError",
24
+ "RemoteError",
25
+ "Tree",
26
+ "address_of",
27
+ "slot_of",
28
+ "snapshot",
29
+ ]
@@ -0,0 +1,134 @@
1
+ # SPDX-License-Identifier: MIT
2
+ """opengearwire HOST COMMAND: read a frame from the command line.
3
+
4
+ opengearwire 192.0.2.10 slots occupied slots and their products
5
+ opengearwire 192.0.2.10 params 4 every parameter of slot 4
6
+ opengearwire 192.0.2.10 read 4 0x0b04 fresh value(s) by OID or name
7
+ opengearwire 192.0.2.10 watch 10 pushed changes for 10 s
8
+ opengearwire 192.0.2.10 snapshot the whole frame as JSON
9
+
10
+ Slot 0 is the frame controller. Every command opens one connection,
11
+ does what it says and closes; nothing is ever written to the frame.
12
+ The frame takes one client at a time: close DashBoard first.
13
+ """
14
+
15
+ import argparse
16
+ import json
17
+ import sys
18
+
19
+ from . import _protocol as P
20
+ from .client import PORT, Frame, FrameError
21
+
22
+
23
+ def _fmt(v) -> str:
24
+ if isinstance(v, list):
25
+ return ", ".join(str(x) for x in v)
26
+ return str(v)
27
+
28
+
29
+ def main(argv=None) -> int:
30
+ ap = argparse.ArgumentParser(prog="opengearwire", description=__doc__.split("\n")[0])
31
+ ap.add_argument("host")
32
+ ap.add_argument("--port", type=int, default=PORT)
33
+ ap.add_argument(
34
+ "--timeout",
35
+ type=float,
36
+ default=5.0,
37
+ help="seconds of silence from the frame before giving up (default 5)",
38
+ )
39
+ ap.add_argument("--json", action="store_true", help="JSON output")
40
+ sub = ap.add_subparsers(dest="cmd", required=True)
41
+ sub.add_parser("slots")
42
+ p = sub.add_parser("params")
43
+ p.add_argument("slot", type=int)
44
+ p = sub.add_parser("read")
45
+ p.add_argument("slot", type=int)
46
+ p.add_argument("keys", nargs="+", help="OIDs (0x0b04) or exact names")
47
+ p = sub.add_parser("watch")
48
+ p.add_argument("seconds", type=float)
49
+ sub.add_parser("snapshot")
50
+ a = ap.parse_args(argv)
51
+
52
+ try:
53
+ with Frame(a.host, a.port, timeout=a.timeout) as f:
54
+ return _run(f, a)
55
+ except (OSError, FrameError, P.ProtocolError) as e:
56
+ print(f"opengearwire: {a.host}: {e}", file=sys.stderr)
57
+ return 1
58
+
59
+
60
+ def _run(f: Frame, a) -> int:
61
+ out = sys.stdout
62
+ if a.cmd == "slots":
63
+ f.discover()
64
+ rows = list(f.identify().items())
65
+ if a.json:
66
+ json.dump([{"slot": s, "product": p} for s, p in rows], out, indent=2)
67
+ out.write("\n")
68
+ else:
69
+ for s, p in rows:
70
+ out.write(f"{s:>3} {p}\n")
71
+ elif a.cmd == "params":
72
+ f.describe([a.slot])
73
+ dev = f.device(a.slot)
74
+ if a.json:
75
+ json.dump(dev.to_dict(), out, indent=2)
76
+ out.write("\n")
77
+ else:
78
+ for o in dev.oids:
79
+ p = dev.params[o]
80
+ d = p.descriptor
81
+ rw = "rw" if d and d.writable else "ro"
82
+ kind = d.type_name if d else "?"
83
+ out.write(f"0x{o:04x} {rw} {kind:9} {p.name!r:32} {_fmt(p.display)}\n")
84
+ elif a.cmd == "read":
85
+ keys = [int(k, 16) if k.lower().startswith("0x") else k for k in a.keys]
86
+ if all(isinstance(k, int) for k in keys):
87
+ f.describe_oids(a.slot, keys) # descriptors decode the values
88
+ else:
89
+ f.describe([a.slot], menus=False) # names need the whole list
90
+ vals = f.read(a.slot, *keys)
91
+ dev = f.device(a.slot)
92
+ rows = [(o, dev.params[o]) for o in vals]
93
+ if a.json:
94
+ json.dump([p.to_dict() for _, p in rows], out, indent=2)
95
+ out.write("\n")
96
+ else:
97
+ for o, p in rows:
98
+ out.write(f"0x{o:04x} {p.name!r}: {_fmt(p.display)}\n")
99
+ elif a.cmd == "watch":
100
+ f.discover()
101
+ for ch in f.watch(a.seconds):
102
+ if a.json:
103
+ out.write(
104
+ json.dumps(
105
+ {
106
+ "slot": ch.slot,
107
+ "oid": f"0x{ch.oid:04x}",
108
+ "name": ch.name,
109
+ "old": ch.old,
110
+ "new": ch.new,
111
+ }
112
+ )
113
+ + "\n"
114
+ )
115
+ else:
116
+ out.write(f"slot {ch.slot} 0x{ch.oid:04x} {ch.name!r}: {ch.old!r} -> {ch.new!r}\n")
117
+ elif a.cmd == "snapshot":
118
+ f.discover()
119
+ f.describe()
120
+ json.dump(f.snapshot(), out, indent=2)
121
+ out.write("\n")
122
+ if f.unanswered:
123
+ print(f"opengearwire: {len(f.unanswered)} request(s) never answered", file=sys.stderr)
124
+ for u in f.unanswered:
125
+ what = u.get("oid") or ", ".join(
126
+ f"{k} {u[k]}" for k in ("menuset", "menu", "object", "offset") if k in u
127
+ )
128
+ name = f" {u['name']!r}" if "name" in u else ""
129
+ print(f" slot {u['slot']} {u['request']} {what}{name}", file=sys.stderr)
130
+ return 0
131
+
132
+
133
+ if __name__ == "__main__":
134
+ sys.exit(main())